[snmp1-cvs] CVS snmp1
jriise
jriise at common-lisp.net
Sun Jan 21 02:25:03 UTC 2007
Update of /project/snmp1/cvsroot/snmp1
In directory clnet:/tmp/cvs-serv11926
Modified Files:
ber.lisp snmp.lisp
Log Message:
Documentations strings for all functions
--- /project/snmp1/cvsroot/snmp1/ber.lisp 2007/01/20 15:55:08 1.2
+++ /project/snmp1/cvsroot/snmp1/ber.lisp 2007/01/21 02:25:02 1.3
@@ -53,22 +53,31 @@
(loop for (id value) in tag-list do
(setf (gethash id tag->octet) value)
(setf (gethash value octet->tag) id))
- (defun encode-tag (tag) (gethash tag tag->octet))
- (defun decode-tag (octet) (gethash octet octet->tag))
+ (defun encode-tag (tag)
+ "Convert a symbolic tag value to an octet"
+ (gethash tag tag->octet))
+ (defun decode-tag (octet)
+ "Convert a tag octest to its symbolic value"
+ (gethash octet octet->tag))
)
(defun container-type-p (tag)
+ "Returns true if the tag is one of the container tags"
(member tag (list :sequence :get :getnext :response :set :trap)))
(defun integer-type-p (tag)
+ "Returns true if the tag is one of the ineger type tags"
(member tag (list :integer :counter :gauge :timeticks)))
(defun octet-string-type-p (tag)
+ "Returns true if tag is one of the tags that encode octet strings"
(member tag (list :octet-string :opaque :ipaddress)))
(defun object-identifier-type-p (tag)
+ "Return true if the tag is :object-identitier"
(member tag (list :object-identifier)))
(defun null-type-p (tag)
+ "Returns true if the tag is :null"
(member tag (list :null)))
(defun decode-length (from-array pos)
@@ -163,7 +172,10 @@
(defun ber-decode-object-identifier-value (buffer start end)
- ;; return array of subidentifiers
+ "Decodes part of the octet string array and returns an array of subidentifiers
+Each subidentifier can be one or more octets. Each octet that has its seventh
+bit set, continues to the next octet. The first octet is special, as it
+ecodes the two first subidentifiers."
(let ((result (make-array 20 :adjustable t :fill-pointer 0)))
;; first and second oid are special
@@ -191,7 +203,10 @@
result))
(defun ber-encode-integer-value (value to-array)
- "Push value as integer"
+ "Push value as integer to the tail oof the array. Every bit of
+each octet is used, but we must make sure that the first octet
+is less than 128 for positive numbers, as the 7.th bit in the
+first octet signals a negative number"
(let ((numbytes (ceiling (1+ (integer-length value)) 8)))
(loop for pos from (1- numbytes) downto 0
do (vector-push-extend (ldb (byte 8 (* pos 8)) value) to-array))
@@ -199,13 +214,18 @@
(defun ber-encode-octet-string-value (value to-array)
- "Push value as octet-string"
+ "Push value as octet-string. If the value is a string,
+the result mitht be longer, depending on the current external
+format"
(when (typep value 'string) (setf value (string-to-octets value)))
(loop for octet across value do (vector-push-extend octet to-array))
to-array)
(defun ber-encode-object-identifier-value (in-value to-array)
- "Push value as octet-string Return to-array"
+ "Push value as octet-string Return to-array. The first two
+subidentifers go into one octet. Most other subidentifiers go into
+one octet each. If a subidentifier is greater than 127, several
+octets are usec"
(let ((value (if (stringp in-value) (oid-string-to-oid in-value) in-value)))
;; first and second subidentifier compressed into one octet
(vector-push-extend (+ (* 40 (aref value 0)) (aref value 1)) to-array)
@@ -223,14 +243,17 @@
(defun ber-encode (what &optional buffer)
- ;; always one tag, but may be a container
+ "Encode a single tag and value, or recursively encode a sequence.
+Example of input is '(:sequence (:object-identifier #(1 3 4 5 6)) (:integer 42))
+Normally, this function is called on the complete snmp message, which is such
+sequence"
(unless buffer (setf buffer (make-array 50 :element-type '(unsigned-byte 8) :fill-pointer 0)))
(let ((tag (first what))
(encoded-tag (encode-tag (first what)))
(start-pos (fill-pointer buffer)))
(vector-push-extend encoded-tag buffer)
;; unfortunately we don't know length of length at this time.
- ;; Guess length of length is 1, set length to 0 for now
+ ;; Guess length of length is 1, reserve an octet by pushing a zero to the buffer.
(vector-push-extend 0 buffer)
(cond
((container-type-p tag)
@@ -243,9 +266,9 @@
;; if length is 127 or less, we can place it directly in the reserved octet
(if (< length-of-value 128)
(setf (aref buffer (+ start-pos 1)) length-of-value)
+ ;; our guess was wrong, now we have to move the value some places to the right
(let ((length-of-length (ceiling (1+ (integer-length length-of-value)) 8)))
(setf (aref buffer (+ start-pos 1)) (logior #b10000000 (ldb (byte 8 0) length-of-length )))
- ;; now we have to move the value some places to the right
(adjust-array buffer #1=(+ length-of-length (fill-pointer buffer)) :fill-pointer #1#)
(loop
for to-pos from (1- (fill-pointer buffer)) downto (+ start-pos length-of-length 2)
@@ -260,8 +283,10 @@
buffer)
(defun ber-decode (buffer &optional (input-start 0) input-end (level 0))
- ;; the buffer is a single tag, possibly a sequence containing one or more tags
- ;; resurn the buffer in list form and length of buffer that is used as second value
+ "the buffer is an octet string vector received from the net. It normally start with
+a sequence containing the rest of the message. When a sequence tag is found, the
+function calls itself recursively to decode the contents.
+Resurn the buffer in list form and length of buffer that is used as second value"
(when (null buffer) (return-from ber-decode))
(unless input-end (setf input-end (length buffer)))
(let* ((start input-start)
--- /project/snmp1/cvsroot/snmp1/snmp.lisp 2007/01/20 15:55:08 1.2
+++ /project/snmp1/cvsroot/snmp1/snmp.lisp 2007/01/21 02:25:03 1.3
@@ -18,19 +18,35 @@
|#
(in-package "SNMP1")
-(defparameter *community* "public")
-(defparameter *agent-ip* #(127 0 0 1))
-(defparameter *agent-port* 161)
-(defparameter *wait* 1)
-(defparameter *retries* 3)
+(defparameter *community* "public"
+ "The default community string used. Assign your own value to this dynamic
+variable before you call any snmp functions")
+(defparameter *agent-ip* #(127 0 0 1)
+ "The default ip address of the snmp agent you want to communicate with.
+Assign your own value to this before you call any of the snmp functions.
+The ip-address can be in any form; dotted quad, integer array or a single
+number")
+(defparameter *agent-port* 161
+ "The default udp port where the agent listens for incoming calls. Change this
+if the snmp-agent you try to communicate with listens on another port. Normally
+the agent listens on the default port")
+(defparameter *wait* 1
+ "This is the number of seconds we wait for an snmp agent to answer before
+we try again or give up. The time can also be specified with a float.")
+(defparameter *retries* 3
+ "The maximum number of times we retry a communication with the agent")
(defun ip-string-to-ip-octets (dotted-quad)
+ "Conversion of ip, example 127.0.0.1 as string to #(127 0 0 1). There
+is also a from any form to ip octets conversion function"
(let ((list (split-sequence:split-sequence #\. dotted-quad))
(vector (make-array 4)))
(loop for n from 0 for component in list do (setf (aref vector n) (parse-integer component)))
vector))
(defun ip-string-to-numeric (dotted-quad)
+ "Convert for example 80.68.86.115 as string to a single integer 1346655859. Did
+you know that you can paste this integer directly into a web browser?"
(let ((octets (ip-string-to-ip-octets dotted-quad))
(ip-numeric 0))
(loop for octet across octets do
@@ -38,26 +54,32 @@
ip-numeric))
(defun ip-numeric-to-ip-octets (ip-numeric)
+ "Convert an ip address expressed as a single intger, to its
+octet array form"
(apply #'vector (reverse (loop for x from 1 to 4
collect (ldb (byte 8 0) ip-numeric)
do (setf ip-numeric (truncate ip-numeric 256))))))
(defun ip-octets-to-ip-string (ip-octets)
+ "Convert an ip adress, example #(127 0 0 1) to its strign form 127.0.0.1"
(format nil "~{~d.~d.~d.~d~}" (loop for o across ip-octets collect o)))
(defun ip-numeric (ip-some-form)
+ "Convert an ip adress in any of the three forms to a single integer"
(typecase ip-some-form
(simple-vector (ip-string-to-numeric (ip-octets-to-ip-string ip-some-form)))
(string (ip-string-to-numeric ip-some-form))
(otherwise ip-some-form)))
(defun ip-octets (ip-some-form)
+ "Convert an ip adress in any of the three forms to an array of four integers"
(typecase ip-some-form
(integer (ip-numeric-to-ip-octets ip-some-form))
(string (ip-string-to-ip-octets ip-some-form))
(otherwise ip-some-form)))
(defun ip-string (ip-some-form)
+ "Convert an ip adress in any of the three forms to the dotted quad string form"
(typecase ip-some-form
(simple-vector (ip-octets-to-ip-string ip-some-form))
(integer (ip-octets-to-ip-string (ip-numeric-to-ip-octets ip-some-form)))
@@ -75,12 +97,17 @@
(defun pdu-from-message (decoded-message)
+ "Extract the Protocol Data Unit from a decoded message"
(fourth decoded-message))
(defun value-from-encoding (encoding)
+ "Extract the value from a single encoding, example (:integer 5) produces 5"
(second encoding))
(defun request-id (decoded-message)
+ "Extract the request identifier from a message. We can validate the integrity
+of a response by checking that the recieved request-id is the same we used
+in he corresponding get/set"
(value-from-encoding (second (pdu-from-message decoded-message))))
;; (defun nreplace-request-id (new-value decoded-message)
@@ -91,9 +118,12 @@
;; )
(defun varbind-list% (decoded-pdu)
+ "Return the sequence containing all the variable bindings. Note that the input
+here is the pdu part of the message, not the whole message"
(fifth decoded-pdu))
(defun varbind-list (message)
+ "Return the sequence containing all the variable bindings from a message"
(varbind-list% (pdu-from-message message)))
;; (defun oid-and-value (varbind)
@@ -108,12 +138,14 @@
(push :sequence vars)))
(defun varbind-to-triple (varbind)
+ "Reduce a varbind sequence to a list of oid, type and value"
(let ((requested-oid (second (second varbind)))
(tag (first (third varbind)))
(value (second (third varbind))))
(list requested-oid tag value)))
(defun triples-from-decoded-message (decoded-message)
+ "Return the varbinds in a message as a list of oid, type and value triples"
(let ((varbind-list (varbind-list decoded-message)))
(loop for pair in (cdr varbind-list) collect (varbind-to-triple pair))))
@@ -124,7 +156,8 @@
;; ))
(defun udp-send-and-receive (host port timeout repetitions message)
- "send one pqcket and receive one packet"
+ "send one pqcket and receive one packet. Do timeouts and retries.
+This function is specific to sbcl"
(let ((socket (make-instance 'sb-bsd-sockets:inet-socket :protocol :udp :type :datagram))
result
(recvbuf (make-array 2000 :element-type '(unsigned-byte 8))))
@@ -203,6 +236,8 @@
(t oid)))
(defun snmp-get- (oid)
+ "Request a single value from the agent, but do not transform the
+result. Resultt is a triple of object identifier, type and value"
(let ((triple-list (snmp-get-many- (list (oid-basic-form oid)))))
(first triple-list)))
@@ -281,6 +316,9 @@
(defun translate-triple (triple)
+ "Translate object identifiers in the triple to its symbolic form,
+translacte octet strings to strings, and enumerator integers to
+symbolic form"
(let ((translated-oid (symbolic-oid-from-oid (first triple)))
(tag (second triple))
(value (third triple)))
@@ -306,10 +344,18 @@
(defun snmp-get-many (oid-list)
+ "Request one or more values from the agent, parmater is a list of object
+identifiers"
(let ((triple-list (snmp-get-many- (mapcar #'oid-basic-form oid-list))))
(loop for triple in triple-list collect (translate-triple triple))))
(defun snmp-get-many-safe- (oid-list identifying-oid in-identifier)
+ "This version of snmp-get takes a list of oid's as ususal, but prepends
+the list with the oid in the identifying-oid parameter, and thecks the
+returned value with in-identifier parameter. The identifying oid can be
+the serial number of the agent device. If the serial number is not as
+expected, nil is returned. This version of the function does not translate
+the result"
(let ((result+identifier (snmp-get-many- (mapcar #'oid-basic-form (cons identifying-oid oid-list)))))
(let* ((read-identifier-triple (translate-triple (first result+identifier)))
(result (rest result+identifier)))
@@ -317,6 +363,11 @@
result))))
(defun snmp-get-many-safe (oid-list identifying-oid in-identifier)
+ "This version of snmp-get takes a list of oid's as ususal, but prepends
+the list with the oid in the identifying-oid parameter, and thecks the
+returned value with in-identifier parameter. The identifying oid can be
+the serial number of the agent device. If the serial number is not as
+expected, nil is returned"
(let ((result+identifier (snmp-get-many- (mapcar #'oid-basic-form (cons identifying-oid oid-list)))))
(let ((read-identifier-triple (translate-triple (first result+identifier)))
(result (rest result+identifier)))
More information about the Snmp1-cvs
mailing list