Author: ctian Date: Thu Mar 29 09:51:13 2007 New Revision: 1
Added: branches/ tags/ trunk/ trunk/README trunk/classes.lisp trunk/constants.lisp trunk/copyright trunk/net-snmp.asd trunk/package.lisp trunk/snmp-api.lisp trunk/typedefs.lisp Log: Initial commit into common-lisp.net SVN repository.
Added: trunk/README ============================================================================== --- (empty file) +++ trunk/README Thu Mar 29 09:51:13 2007 @@ -0,0 +1,24 @@ +;;; -*- Mode: Lisp -*- + +;;; Common Lisp Interface for Net-SNMP (cl-net-snmp) + +;;; Author: Chun Tian (binghe) binghe.lisp@gmail.com +;;; NetEase.com, Inc. (http://corp.netease.com) + +;;; This package only support: +;;; * Version: SNMPv1, SNMPv2c +;;; * PDU Type: GET +;;; * Just print the result to stdout... + +;;; I use the CFFI for portable CL support, see http://common-lisp.net/project/cffi/ +;;; Known work on: SBCL and CLISP + +;;; Sample usage: + +(defun test () + (let ((s (make-instance 'snmp:snmp-session + :peername "localhost" + :community "public" + :version snmp:+snmp-version-2c+))) + (snmp:snmp-msg-get s "sysDescr.0") + (snmp:snmp-msg-get "localhost" ".1.3.6.1.2.1.1.1.0")))
Added: trunk/classes.lisp ============================================================================== --- (empty file) +++ trunk/classes.lisp Thu Mar 29 09:51:13 2007 @@ -0,0 +1,75 @@ +(in-package :org.net-snmp) + +(defclass snmp-session () + ((peername :reader snmp-peername + :initarg :peername + :type string + :initform "localhost") + (version :reader snmp-version + :initarg :version + :type integer + :initform +snmp-version-2c+) + (community :reader snmp-community + :initarg :community + :type string + :initform "public") + c-session)) + +(defmethod shared-initialize :after ((instance snmp-session) slot-names &rest initargs) + (declare (ignore slot-names initargs)) + (with-slots (peername version community c-session) instance + (progn + (setf c-session (foreign-alloc 'c-snmp-session)) + (c-snmp-session-init c-session) + (with-foreign-slots ((c-peername c-version c-community c-community-len) + c-session c-snmp-session) + (setf c-peername (foreign-string-alloc peername) + c-version version + c-community (foreign-string-alloc community) + c-community-len (length community)))))) + +(defclass oid () + ((name :type string :reader oid-name :initarg :name) + (length :type integer :reader oid-length) + c-oids + c-oid-len)) + +(defmethod shared-initialize :after ((instance oid) slot-names &rest initargs) + (declare (ignore slot-names initargs)) + (with-slots (name length c-oids c-oid-len) instance + (progn + (setf c-oids (foreign-alloc 'c-oid :count +max-oid-len+) + c-oid-len (foreign-alloc 'c-size-type :initial-element +max-oid-len+)) + (if (eq (elt name 0) #.) + (c-read-objid name c-oids c-oid-len) + (c-get-node name c-oids c-oid-len)) + (setf length (mem-ref c-oid-len 'c-size-type))))) + +(defmethod snmp-msg-get ((s snmp-session) (o oid)) + (let ((ss (c-snmp-open (slot-value s 'c-session))) + (pdu (c-snmp-pdu-create +snmp-msg-get+)) + (response (foreign-alloc :pointer :initial-element (null-pointer)))) + (progn + (c-snmp-add-null-var pdu + (slot-value o 'c-oids) + (mem-ref (slot-value o 'c-oid-len) 'c-size-type)) + (let ((status (c-snmp-synch-response ss pdu response))) + (if (and (= status +snmp-stat-success+) + (= (foreign-slot-value (mem-aref response :pointer) 'c-snmp-pdu 'c-errstat) + +snmp-err-noerror+)) + (let ((vars (foreign-slot-value (mem-aref response :pointer) + 'c-snmp-pdu 'c-variables))) + (c-print-variable (foreign-slot-value vars 'c-variable-list 'c-name) + (foreign-slot-value vars 'c-variable-list 'c-name-length) + vars)) + nil)) + (c-snmp-pdu-free (mem-aref response :pointer)) + (c-snmp-close ss) + nil))) + +(defmethod snmp-msg-get ((s snmp-session) (o string)) + (snmp-msg-get s (make-instance 'oid :name o))) + +(defmethod snmp-msg-get ((s string) (o string)) + (snmp-msg-get (make-instance 'snmp-session :peername s) o)) +
Added: trunk/constants.lisp ============================================================================== --- (empty file) +++ trunk/constants.lisp Thu Mar 29 09:51:13 2007 @@ -0,0 +1,83 @@ +(in-package :org.net-snmp) + +(eval-when (:compile-toplevel :load-toplevel :execute) + ;;; from asn1.h + (defconstant +min-oid-len+ 2) + (defconstant +max-oid-len+ 128) + ;;; from snmp_api.h + (defconstant +usm-auth-ku-len+ 32) + (defconstant +usm-priv-ku-len+ 32)) + +(defconstant +asn-boolean+ #x01) +(defconstant +asn-integer+ #x02) +(defconstant +asn-bit-str+ #x03) +(defconstant +asn-octet-str+ #x04) +(defconstant +asn-null+ #x05) +(defconstant +asn-object-id+ #x06) +(defconstant +asn-sequence+ #x10) +(defconstant +asn-set+ #x11) + +(defconstant +asn-universal+ #b00000000) +(defconstant +asn-application+ #b01000000) +(defconstant +asn-context+ #b10000000) +(defconstant +asn-private+ #b11000000) + +(defconstant +asn-primitive+ #b00000000) +(defconstant +asn-constructor+ #b00100000) + +;;; from snmp.h +(defconstant +snmp-version-1+ 0) +(defconstant +snmp-version-2c+ 1) +(defconstant +snmp-version-3+ 3) + +(defconstant +snmp-sec-model-any+ 0) +(defconstant +snmp-sec-model-snmpv1+ 1) +(defconstant +snmp-sec-model-snmpv2c+ 2) +(defconstant +snmp-sec-model-usm+ 3) + +(defconstant +snmp-sec-level-noauth+ 1) +(defconstant +snmp-sec-level-authnopriv+ 2) +(defconstant +snmp-sec-level-authpriv+ 3) + +;; PDU types in SNMPv1, SNMPsec, SNMPv2p, SNMPv2c, SNMPv2u, SNMPv2*, and SNMPv3 +(defconstant +snmp-msg-get+ + (logior +asn-context+ +asn-constructor+ 0)) + +(defconstant +snmp-msg-getnext+ + (logior +asn-context+ +asn-constructor+ 1)) + +(defconstant +snmp-msg-response+ + (logior +asn-context+ +asn-constructor+ 2)) + +(defconstant +snmp-msg-set+ + (logior +asn-context+ +asn-constructor+ 3)) + +;; PDU types in SNMPv1 and SNMPsec +(defconstant +snmp-msg-trap+ + (logior +asn-context+ +asn-constructor+ 4)) + +;; PDU types in SNMPv2p, SNMPv2c, SNMPv2u, SNMPv2*, and SNMPv3 +(defconstant +snmp-msg-getbulk+ + (logior +asn-context+ +asn-constructor+ 5)) + +(defconstant +snmp-msg-inform+ + (logior +asn-context+ +asn-constructor+ 6)) + +(defconstant +snmp-msg-trap2+ + (logior +asn-context+ +asn-constructor+ 7)) + +;; PDU types in SNMPv2u, SNMPv2*, and SNMPv3 +(defconstant +snmp-msg-report+ + (logior +asn-context+ +asn-constructor+ 8)) + +;;; from snmp_client.h +(defconstant +snmp-stat-success+ 0) +(defconstant +snmp-stat-error+ 1) +(defconstant +snmp-stat-timeout+ 2) + +(defconstant +snmp-err-noerror+ 0) +(defconstant +snmp-err-toobig+ 1) +(defconstant +snmp-err-nosuchname+ 2) +(defconstant +snmp-err-badvalue+ 3) +(defconstant +snmp-err-readonly+ 4) +(defconstant +snmp-err-generr+ 5)
Added: trunk/copyright ============================================================================== --- (empty file) +++ trunk/copyright Thu Mar 29 09:51:13 2007 @@ -0,0 +1,25 @@ +;;; Copyright (c) 2007, Chun Tian (binghe). All rights reserved. + +;;; Redistribution and use in source and binary forms, with or without +;;; modification, are permitted provided that the following conditions +;;; are met: + +;;; * Redistributions of source code must retain the above copyright +;;; notice, this list of conditions and the following disclaimer. + +;;; * Redistributions in binary form must reproduce the above +;;; copyright notice, this list of conditions and the following +;;; disclaimer in the documentation and/or other materials +;;; provided with the distribution. + +;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED +;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Added: trunk/net-snmp.asd ============================================================================== --- (empty file) +++ trunk/net-snmp.asd Thu Mar 29 09:51:13 2007 @@ -0,0 +1,17 @@ +;;;; -*- Mode: Lisp -*- + +(defpackage :net-snmp-system + (:use :cl :asdf)) + +(in-package :net-snmp-system) + +(defsystem net-snmp + :description "Common Lisp interface for Net-SNMP" + :version "0.01" + :author "Chun Tian (binghe)" + :depends-on (:cffi) + :components ((:file "package") + (:file "constants" :depends-on ("package")) + (:file "typedefs" :depends-on ("package")) + (:file "snmp-api" :depends-on ("constants" "typedefs")) + (:file "classes" :depends-on ("snmp-api"))))
Added: trunk/package.lisp ============================================================================== --- (empty file) +++ trunk/package.lisp Thu Mar 29 09:51:13 2007 @@ -0,0 +1,27 @@ +(in-package :net-snmp-system) + +(defpackage :org.net-snmp + (:nicknames :snmp) + (:use :cl :cffi) + (:export + ;; class + snmp-session oid + ;; method + snmp-msg-get + ;; constants + +snmp-version-1+ + +snmp-version-2c+)) + +(in-package :org.net-snmp) + +(eval-when (:compile-toplevel :load-toplevel :execute) + (define-foreign-library libssl + (:unix (:or "libssl.so.0.9.8" "libssl.so")) + (t (:default "libssl"))) + + (define-foreign-library libsnmp + (:unix (:or "libsnmp.so.15" "libsnmp.so")) + (t (:default "libsnmp"))) + + (use-foreign-library libssl) + (use-foreign-library libsnmp))
Added: trunk/snmp-api.lisp ============================================================================== --- (empty file) +++ trunk/snmp-api.lisp Thu Mar 29 09:51:13 2007 @@ -0,0 +1,77 @@ +(in-package :org.net-snmp) + +;;(defcvar ("usmHMACMD5AuthProtocol" *c-usm-hmac-md5-auth-protocol*) :pointer) + +(eval-when (:compile-toplevel :load-toplevel) + (defcfun ("init_snmp" c-snmp-init) :void (type :string))) + +(eval-when (:load-toplevel :execute) + (progn (c-snmp-init "snmpapp") + (format t "c-snmp-init called.~%"))) + +;;; +;;; Initializes the session structure. +;;; May perform one time minimal library initialization. +;;; No MIB file processing is done via this call. +;;; +(defcfun ("snmp_sess_init" c-snmp-session-init) :void (session :pointer)) + +;;; +;;; netsnmp_session *snmp_open(session) +;;; netsnmp_session *session; +;;; +;;; Sets up the session with the snmp_session information provided +;;; by the user. Then opens and binds the necessary UDP port. +;;; A handle to the created session is returned (this is different than +;;; the pointer passed to snmp_open()). On any error, NULL is returned +;;; and snmp_errno is set to the appropriate error code. +;;; +(defcfun ("snmp_open" c-snmp-open) :pointer (session :pointer)) + +;;; +;;; int snmp_close(session) +;;; netsnmp_session *session; +;;; +;;; Close the input session. Frees all data allocated for the session, +;;; dequeues any pending requests, and closes any sockets allocated for +;;; the session. Returns 0 on error, 1 otherwise. +;;; +;;; snmp_close_sessions() does the same thing for all open sessions +;;; +(defcfun ("snmp_close" c-snmp-close) :int (session :pointer)) +(defcfun ("snmp_close_sessions" c-snmp-close-sessions) :int) + +(defcfun ("snmp_perror" c-snmp-perror) :void (prog-string :string)) +(defcfun ("snmp_errstring" c-snmp-errstring) :string (errstat :int)) +(defcfun ("snmp_sess_perror" c-snmp-session-perror) :void + (prog-string :string) (ss :pointer)) + +(defcfun ("snmp_pdu_create" c-snmp-pdu-create) :pointer (command :int)) +(defcfun ("snmp_free_pdu" c-snmp-pdu-free) :void (pdu :pointer)) +(defcfun ("snmp_pdu_type" c-snmp-pdu-type) :string (type :int)) + +(defcfun ("read_objid" c-read-objid) :int + (str :string) + (oid :pointer) + (size :pointer)) + +(defcfun ("get_node" c-get-node) :int + (str :string) + (oid :pointer) + (size :pointer)) + +(defcfun ("snmp_add_null_var" c-snmp-add-null-var) :pointer + (pdu :pointer) + (oid :pointer) + (size :ulong)) + +(defcfun ("snmp_synch_response" c-snmp-synch-response) :int + (session :pointer) + (pdu :pointer) + (pdu* :pointer)) + +(defcfun ("print_variable" c-print-variable) :void + (objid :pointer) + (objidlen :ulong) + (variable :pointer)) +
Added: trunk/typedefs.lisp ============================================================================== --- (empty file) +++ trunk/typedefs.lisp Thu Mar 29 09:51:13 2007 @@ -0,0 +1,252 @@ +(in-package :org.net-snmp) + +(defctype c-size-type :long) + +(defcstruct c-snmp-pdu + "The snmp protocol data unit." + ;; + ;; Protocol-version independent fields + ;; + ;; snmp version + (c-version :long) + ;; Type of this PDU + (c-command :int) + ;; Request id - note: not incremented on retries + (c-reqid :long) + ;; Message id for V3 messages note: incremented for each retry + (c-msgid :long) + ;; Unique ID for incoming transactions + (c-transid :long) + ;; Session id for AgentX messages + (c-sessid :long) + ;; Error status (non_repeaters in GetBulk) + (c-errstat :long) + ;; Error index (max_repetitions in GetBulk) + (c-errindex :long) + ;; Uptime + (c-time :ulong) + (c-flags :ulong) + + (c-security-model :int) + ;; noAuthNoPriv, authNoPriv, authPriv + (c-security-level :int) + (c-msg-parse-model :int) + + ;; + ;; Transport-specific opaque data. This replaces the IP-centric address + ;; field. + ;; + + (c-transport-data :pointer) + (c-transport-data-length :int) + + ;; + ;; The actual transport domain. This SHOULD NOT BE FREE()D. + ;; + + (c-t-domain :pointer) + (c-t-domain-len c-size-type) + + (c-variables :pointer) + + ;; + ;; SNMPv1 & SNMPv2c fields + ;; + ;; community for outgoing requests. + (c-community :pointer) + ;; length of community name. + (c-community-len c-size-type) + + ;; + ;; Trap information + ;; + ;; System OID + (c-enterprise :pointer) + (c-enterprise-length c-size-type) + ;; trap type + (c-trap-type :long) + ;; specific type + (c-specific-type :long) + ;; This is ONLY used for v1 TRAPs + (c-agent-addr :pointer) + + ;; + ;; SNMPv3 fields + ;; + ;; context snmpEngineID + (c-context-engine-id :pointer) + ;; Length of contextEngineID + (c-context-engine-id-len c-size-type) + ;; authoritative contextName + (c-context-name :string) + ;; Length of contextName + (c-context-name-len c-size-type) + ;; authoritative snmpEngineID for security + (c-security-engine-id :pointer) + ;; Length of securityEngineID + (c-security-engine-id-len c-size-type) + ;; on behalf of this principal + (c-security-name :string) + ;; Length of securityName. + (c-security-name-len c-size-type) + + ;; + ;; AgentX fields + ;; (also uses SNMPv1 community field) + ;; + (c-priority :int) + (c-range-subid :int) + + (c-security-state-ref :pointer)) + +(defctype c-netsnmp-pdu c-snmp-pdu) +(defctype c-netsnmp-callback :pointer) +(defctype c-authenticator :pointer) + +(defmacro def-snmp-session () + `(defcstruct c-snmp-session + "The snmp session structure." + ;; + ;; Protocol-version independent fields + ;; + ;; snmp version + (c-version :long) + ;; Number of retries before timeout. + (c-retries :int) + ;; Number of uS until first timeout, then exponential backoff + (c-timeout :long) + (c-flags :ulong) + (c-subsession :pointer) + (c-next :pointer) + ;; Domain name or dotted IP address of default peer + (c-peername :string) + ;; UDP port number of peer. + (c-remote-port :ushort) + ;; My Domain name or dotted IP address, 0 for default + (c-localname :string) + ;; My UDP port number, 0 for default, picked randomly + (c-local-port :ushort) + ;; + ;; Authentication function or NULL if null authentication is used + ;; + (c-authenticator c-authenticator) + ;; Function to interpret incoming data + (c-callback c-netsnmp-callback) + ;; + ;; Pointer to data that the callback function may consider important + ;; + (c-callback-magic :pointer) + ;; copy of system errno + (c-system-errno :int) + ;; copy of library errno + (c-system-snmp-errno :int) + ;; Session id - AgentX only + (c-sessid :long) + ;; + ;; SNMPv1 & SNMPv2c fields + ;; + ;; community for outgoing requests. + (c-community :pointer) + ;; Length of community name. + (c-community-len c-size-type) + ;; Largest message to try to receive. + (c-rcv-msg-max-size c-size-type) + ;; Largest message to try to send. + (c-snd-msg-max-size c-size-type) + ;; + ;; SNMPv3 fields + ;; + ;; are we the authoritative engine? + (c-is-authoritative :uchar) + ;; authoritative snmpEngineID + (c-context-engine-id :pointer) + ;; Length of contextEngineID + (c-context-engine-id-len c-size-type) + ;; initial engineBoots for remote engine + (c-engine-boots :uint) + ;; initial engineTime for remote engine + (c-engine-time :uint) + ;; authoritative contextName + (c-context-name :string) + ;; Length of contextName + (c-context-name-len c-size-type) + ;; authoritative snmpEngineID + (c-security-engine-id :pointer) + ;; Length of contextEngineID + (c-security-engine-id-len c-size-type) + ;; on behalf of this principal + (c-security-name :string) + ;; Length of securityName. + (c-security-name-len c-size-type) + ;; auth protocol oid + (c-security-auth-proto :pointer) + ;; Length of auth protocol oid + (c-security-auth-proto-len c-size-type) + ;; Ku for auth protocol XXX + (c-security-auth-key :uchar :count ,+usm-auth-ku-len+) + ;; Length of Ku for auth protocol + (c-security-auth-key-len c-size-type) + ;; Kul for auth protocol + (c-security-auth-local-key :pointer) + ;; Length of Kul for auth protocol XXX + (c-security-auth-local-key-len c-size-type) + ;; priv protocol oid + (c-security-priv-proto :pointer) + ;; Length of priv protocol oid + (c-security-priv-proto-len c-size-type) + ;; Ku for privacy protocol XXX + (c-security-priv-key :uchar :count ,+usm-priv-ku-len+) + ;; Length of Ku for priv protocol + (c-security-priv-key-len c-size-type) + ;; Kul for priv protocol + (c-security-priv-local-key :pointer) + ;; Length of Kul for priv protocol XXX + (c-security-priv-local-key-len c-size-type) + ;; snmp security model, v1, v2c, usm + (c-security-model :int) + ;; noAuthNoPriv, authNoPriv, authPriv + (c-security-level :int) + ;; target param name + (c-param-name :string) + ;; + ;; security module specific + ;; + (c-security-info :pointer) + ;; + ;; use as you want data + ;; + (c-myvoid :pointer))) + +(defctype c-oid :ulong) + +(defctype c-netsnmp-vardata :pointer) + +(defmacro def-variable-list () + `(defcstruct c-variable-list + ;; NULL for last variable + (c-next-variable :pointer) + ;; Object identifier of variable + (c-name :pointer) + ;; number of subid's in name + (c-name-length c-size-type) + ;; ASN type of variable + (c-type :uchar) + ;; value of variable + (c-val c-netsnmp-vardata) + ;; the length of the value to be copied into buf + (c-val-len c-size-type) + ;; 90 percentile < 24. + (c-name-loc c-oid :count ,+max-oid-len+) + ;; 90 percentile < 40. + (c-buf :uchar :count 40) + ;; (Opaque) hook for additional data + (c-data :pointer) + ;; callback to free above + (c-data-free-hook :pointer) + (c-index :int))) + +(eval-when (:compile-toplevel :load-toplevel :execute) + (def-snmp-session) + (def-variable-list)) + +(defctype c-netsnmp-session c-snmp-session)
cl-net-snmp-cvs@common-lisp.net