Subversion Repositories f9daq

Rev

Blame | Last modification | View Log | RSS feed

#ifndef _NETSNMPLIB_H
#define _NETSNMPLIB_H


#define false 0;
#define true  1;


#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>


#include <net-snmp/net-snmp-config.h>


/*
 * Basic system type definitions, taken from the BSD file sys/types.h.
 */

typedef unsigned char   u_char;
typedef unsigned short  u_short;
typedef unsigned int    u_int;
typedef unsigned long   u_long;

#include <net-snmp/library/asn1.h>
#include <net-snmp/library/snmp.h>


#define SNMP_VERSION_2c    1
typedef void *HSNMP;   // SNMP handle (like FILE)



/*
 *  For the initial release, this will just refer to the
 *  relevant UCD header files.
 *    In due course, the types and structures relevant to the
 *  Net-SNMP API will be identified, and defined here directly.
 *
 *  But for the time being, this header file is primarily a placeholder,
 *  to allow application writers to adopt the new header file names.
 */


typedef union {
  long           *integer;
  u_char         *string;
  oid            *objid;
  u_char         *bitstring;
  struct counter64 *counter64;
#ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES
  float          *floatVal;
  double         *doubleVal;
  /*
   * t_union *unionVal;
   */

#endif                          /* NETSNMP_WITH_OPAQUE_SPECIAL_TYPES */
} netsnmp_vardata;


/** @typedef struct variable_list netsnmp_variable_list
 * Typedefs the variable_list struct into netsnmp_variable_list */

/** @struct variable_list
 * The netsnmp variable list binding structure, it's typedef'd to
 * netsnmp_variable_list.
 */

typedef struct variable_list {
  /** NULL for last variable */
  struct variable_list *next_variable;
  /** Object identifier of variable */
  oid            *name;
  /** number of subid's in name */
  size_t          name_length;
  /** ASN type of variable */
  u_char          type;
  /** value of variable */
  netsnmp_vardata val;
  /** the length of the value to be copied into buf */
  size_t          val_len;
  /** 90 percentile < 24. */
  oid             name_loc[MAX_OID_LEN];
  /** 90 percentile < 40. */
  u_char          buf[40];
  /** (Opaque) hook for additional data */
  void           *data;
  /** callback to free above */
  void            (*dataFreeHook)(void *);
  int             index;
} netsnmp_variable_list;

/** @typedef struct snmp_pdu to netsnmp_pdu
 * Typedefs the snmp_pdu struct into netsnmp_pdu */

/** @struct snmp_pdu
 * The snmp protocol data unit.
 */

typedef struct snmp_pdu {

#define non_repeaters errstat
#define max_repetitions errindex

  /*
   * Protocol-version independent fields
   */

  /** snmp version */
  long            version;
  /** Type of this PDU */
  int             command;
  /** Request id - note: not incremented on retries */
  long            reqid;
  /** Message id for V3 messages note: incremented for each retry */
  long            msgid;
  /** Unique ID for incoming transactions */
  long            transid;
  /** Session id for AgentX messages */
  long            sessid;
  /** Error status (non_repeaters in GetBulk) */
  long            errstat;
  /** Error index (max_repetitions in GetBulk) */
  long            errindex;
  /** Uptime */
  u_long          time;
  u_long          flags;

  int             securityModel;
  /** noAuthNoPriv, authNoPriv, authPriv */
  int             securityLevel;
  int             msgParseModel;

  /**
   * Transport-specific opaque data.  This replaces the IP-centric address
   * field.
   */


  void           *transport_data;
  int             transport_data_length;

  /**
   * The actual transport domain.  This SHOULD NOT BE FREE()D.
   */


  const oid      *tDomain;
  size_t          tDomainLen;

  netsnmp_variable_list *variables;


  /*
   * SNMPv1 & SNMPv2c fields
   */

  /** community for outgoing requests. */
  u_char         *community;
  /** length of community name. */
  size_t          community_len;

  /*
   * Trap information
   */

  /** System OID */
  oid            *enterprise;
  size_t          enterprise_length;
  /** trap type */
  long            trap_type;
  /** specific type */
  long            specific_type;
  /** This is ONLY used for v1 TRAPs  */
  unsigned char   agent_addr[4];

  /*
   *  SNMPv3 fields
   */

  /** context snmpEngineID */
  u_char         *contextEngineID;
  /** Length of contextEngineID */
  size_t          contextEngineIDLen;
  /** authoritative contextName */
  char           *contextName;
  /** Length of contextName */
  size_t          contextNameLen;
  /** authoritative snmpEngineID for security */
  u_char         *securityEngineID;
  /** Length of securityEngineID */
  size_t          securityEngineIDLen;
  /** on behalf of this principal */
  char           *securityName;
  /** Length of securityName. */
  size_t          securityNameLen;

  /*
   * AgentX fields
   *      (also uses SNMPv1 community field)
   */

  int             priority;
  int             range_subid;

  void           *securityStateRef;
} netsnmp_pdu;


struct snmp_session;
typedef struct snmp_session netsnmp_session;


#define USM_AUTH_KU_LEN     32
#define USM_PRIV_KU_LEN     32


typedef int     (*netsnmp_callback) (int, netsnmp_session *, int,
                                     netsnmp_pdu *, void *);

/** @struct snmp_session
 * The snmp session structure.
 */

struct snmp_session {
  /*
   * Protocol-version independent fields
   */

  /** snmp version */
  long            version;
  /** Number of retries before timeout. */
  int             retries;
  /** Number of uS until first timeout, then exponential backoff */
  long            timeout;
  u_long          flags;
  struct snmp_session *subsession;
  struct snmp_session *next;

  /** name or address of default peer (may include transport specifier and/or port number) */
  char           *peername;
  /** UDP port number of peer. (NO LONGER USED - USE peername INSTEAD) */
  u_short         remote_port;
  /** My Domain name or dotted IP address, 0 for default */
  char           *localname;
  /** My UDP port number, 0 for default, picked randomly */
  u_short         local_port;
  /**
   * Authentication function or NULL if null authentication is used
   */

  u_char         *(*authenticator) (u_char *, size_t *, u_char *, size_t);
  /** Function to interpret incoming data */
  netsnmp_callback callback;
  /**
   * Pointer to data that the callback function may consider important
   */

  void           *callback_magic;
  /** copy of system errno */
  int             s_errno;
  /** copy of library errno */
  int             s_snmp_errno;
  /** Session id - AgentX only */
  long            sessid;

  /*
   * SNMPv1 & SNMPv2c fields
   */

  /** community for outgoing requests. */
  u_char         *community;
  /** Length of community name. */
  size_t          community_len;
  /**  Largest message to try to receive.  */
  size_t          rcvMsgMaxSize;
  /**  Largest message to try to send.  */
  size_t          sndMsgMaxSize;

  /*
   * SNMPv3 fields
   */

  /** are we the authoritative engine? */
  u_char          isAuthoritative;
  /** authoritative snmpEngineID */
  u_char         *contextEngineID;
  /** Length of contextEngineID */
  size_t          contextEngineIDLen;
  /** initial engineBoots for remote engine */
  u_int           engineBoots;
  /** initial engineTime for remote engine */
  u_int           engineTime;
  /** authoritative contextName */
  char           *contextName;
  /** Length of contextName */
  size_t          contextNameLen;
  /** authoritative snmpEngineID */
  u_char         *securityEngineID;
  /** Length of contextEngineID */
  size_t          securityEngineIDLen;
  /** on behalf of this principal */
  char           *securityName;
  /** Length of securityName. */
  size_t          securityNameLen;

  /** auth protocol oid */
  oid            *securityAuthProto;
  /** Length of auth protocol oid */
  size_t          securityAuthProtoLen;
  /** Ku for auth protocol XXX */
  u_char          securityAuthKey[USM_AUTH_KU_LEN];
  /** Length of Ku for auth protocol */
  size_t          securityAuthKeyLen;
  /** Kul for auth protocol */
  u_char          *securityAuthLocalKey;
  /** Length of Kul for auth protocol XXX */
  size_t          securityAuthLocalKeyLen;

  /** priv protocol oid */
  oid            *securityPrivProto;
  /** Length of priv protocol oid */
  size_t          securityPrivProtoLen;
  /** Ku for privacy protocol XXX */
  u_char          securityPrivKey[USM_PRIV_KU_LEN];
  /** Length of Ku for priv protocol */
  size_t          securityPrivKeyLen;
  /** Kul for priv protocol */
  u_char          *securityPrivLocalKey;
  /** Length of Kul for priv protocol XXX */
  size_t          securityPrivLocalKeyLen;

  /** snmp security model, v1, v2c, usm */
  int             securityModel;
  /** noAuthNoPriv, authNoPriv, authPriv */
  int             securityLevel;
  /** target param name */
  char           *paramName;

  /**
   * security module specific
   */

  void           *securityInfo;

  /**
   * use as you want data
   *
   *     used by 'SNMP_FLAGS_RESP_CALLBACK' handling in the agent
   * XXX: or should we add a new field into this structure?
   */

  void           *myvoid;
};


/**
 * Structure for holding a set of file descriptors, similar to fd_set.
 *
 * This structure however can hold so-called large file descriptors
 * (>= FD_SETSIZE or 1024) on Unix systems or more than FD_SETSIZE (64)
 * sockets on Windows systems.
 *
 * It is safe to allocate this structure on the stack.
 *
 * This structure must be initialized by calling netsnmp_large_fd_set_init()
 * and must be cleaned up via netsnmp_large_fd_set_cleanup(). If this last
 * function is not called this may result in a memory leak.
 */

typedef struct netsnmp_large_fd_set_s {
  /** Maximum set size. */
  unsigned        lfs_setsize;
  /**
   * Points to lfs_set if lfs_setsize <= FD_SETSIZE, and otherwise
   * to dynamically allocated memory.
   */

  fd_set         *lfs_setptr;
  /** File descriptor / socket set data if lfs_setsize <= FD_SETSIZE. */
  fd_set          lfs_set;
} netsnmp_large_fd_set;


/*
     * A tree in the format of the tree structure of the MIB.
     */

struct tree {
  struct tree    *child_list;     /* list of children of this node */
  struct tree    *next_peer;      /* Next node in list of peers */
  struct tree    *next;   /* Next node in hashed list of names */
  struct tree    *parent;
  char           *label;  /* This node's textual name */
  u_long          subid;  /* This node's integer subidentifier */
  int             modid;  /* The module containing this node */
  int             number_modules;
  int            *module_list;    /* To handle multiple modules */
  int             tc_index;       /* index into tclist (-1 if NA) */
  int             type;   /* This node's object type */
  int             access; /* This nodes access */
  int             status; /* This nodes status */
  struct enum_list *enums;        /* (optional) list of enumerated integers */
  struct range_list *ranges;
  struct index_list *indexes;
  char           *augments;
  struct varbind_list *varbinds;
  char           *hint;
  char           *units;
  int             (*printomat) (u_char **, size_t *, size_t *, int,
                                const netsnmp_variable_list *,
                                const struct enum_list *, const char *,
                                const char *);
  void            (*printer) (char *, const netsnmp_variable_list *, const struct enum_list *, const char *, const char *);   /* Value printing function */
  char           *description;    /* description (a quoted string) */
  char           *reference;    /* references (a quoted string) */
  int             reported;       /* 1=report started in print_subtree... */
  char           *defaultValue;
};




netsnmp_pdu    *snmp_pdu_create(int type);
netsnmp_pdu    *snmp_clone_pdu(netsnmp_pdu *pdu);
netsnmp_pdu    *snmp_fix_pdu(  netsnmp_pdu *pdu, int idx);
void            snmp_free_pdu( netsnmp_pdu *pdu);


void            init_snmp(const char *);
void            init_mib(void);
int             get_node(const char *, oid *, size_t *);
void            snmp_sess_init(netsnmp_session *);
struct tree    *read_module(const char *);



/* Creation */
netsnmp_variable_list *
snmp_pdu_add_variable(netsnmp_pdu *pdu,
                      const oid *name, size_t name_length,
                      u_char type,
                      const void *value, size_t len);
netsnmp_variable_list *
snmp_varlist_add_variable(netsnmp_variable_list **varlist,
                          const oid *name, size_t name_length,
                          u_char type,
                          const void *value, size_t len);
netsnmp_variable_list *
snmp_add_null_var(netsnmp_pdu *pdu,
                  const oid *name, size_t name_length);
netsnmp_variable_list *
snmp_clone_varbind(netsnmp_variable_list *varlist);

/* Setting Values */
int             snmp_set_var_value(netsnmp_variable_list *var,
                                   const void *value, size_t len);
int             snmp_set_var_objid(netsnmp_variable_list *var,
                                   const oid *name, size_t name_length);
int             snmp_set_var_typed_value(netsnmp_variable_list *var,
    u_char type,
    const void *value, size_t len);
int             snmp_set_var_typed_integer(netsnmp_variable_list *var,
    u_char type, long val);

/* Output */
void            print_variable(const oid *objid, size_t objidlen,
                               const netsnmp_variable_list *variable);
void           fprint_variable(FILE *fp,
                               const oid *objid, size_t objidlen,
                               const netsnmp_variable_list *variable);
int           snprint_variable(char *buf, size_t buf_len,
                               const oid *objid, size_t objidlen,
                               const netsnmp_variable_list *variable);

void             print_value(const oid *objid, size_t objidlen,
                             const netsnmp_variable_list *variable);
void            fprint_value(FILE *fp,
                             const oid *objid, size_t objidlen,
                             const netsnmp_variable_list *variable);
int            snprint_value(char *buf, size_t buf_len,
                             const oid *objid, size_t objidlen,
                             const netsnmp_variable_list *variable);

/* Deletion */
void            snmp_free_var(    netsnmp_variable_list *var);     /* frees just this one */
void            snmp_free_varbind(netsnmp_variable_list *varlist); /* frees all in list */



void            snmp_sess_init(netsnmp_session *);

/*
 * 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.
 */

netsnmp_session *snmp_open(netsnmp_session *);

/*
 * 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
 */

int             snmp_close(netsnmp_session *);
int             snmp_close_sessions(void);


/*
 * int snmp_send(session, pdu)
 *     netsnmp_session *session;
 *     netsnmp_pdu      *pdu;
 *
 * Sends the input pdu on the session after calling snmp_build to create
 * a serialized packet.  If necessary, set some of the pdu data from the
 * session defaults.  Add a request corresponding to this pdu to the list
 * of outstanding requests on this session, then send the pdu.
 * Returns the request id of the generated packet if applicable, otherwise 1.
 * On any error, 0 is returned.
 * The pdu is freed by snmp_send() unless a failure occured.
 */

int             snmp_send(netsnmp_session *, netsnmp_pdu *);

/*
 * int snmp_async_send(session, pdu, callback, cb_data)
 *     netsnmp_session *session;
 *     netsnmp_pdu      *pdu;
 *     netsnmp_callback callback;
 *     void   *cb_data;
 *
 * Sends the input pdu on the session after calling snmp_build to create
 * a serialized packet.  If necessary, set some of the pdu data from the
 * session defaults.  Add a request corresponding to this pdu to the list
 * of outstanding requests on this session and store callback and data,
 * then send the pdu.
 * Returns the request id of the generated packet if applicable, otherwise 1.
 * On any error, 0 is returned.
 * The pdu is freed by snmp_send() unless a failure occured.
 */

int             snmp_async_send(netsnmp_session *, netsnmp_pdu *,
                                netsnmp_callback, void *);


/*
 * void snmp_read(fdset)
 *     fd_set  *fdset;
 *
 * Checks to see if any of the fd's set in the fdset belong to
 * snmp.  Each socket with it's fd set has a packet read from it
 * and snmp_parse is called on the packet received.  The resulting pdu
 * is passed to the callback routine for that session.  If the callback
 * routine returns successfully, the pdu and it's request are deleted.
 */

void            snmp_read(fd_set *);

/*
 * snmp_read2() is similar to snmp_read(), but accepts a pointer to a
 * large file descriptor set instead of a pointer to a regular file
 * descriptor set.
 */

void            snmp_read2(netsnmp_large_fd_set *);


int             snmp_synch_response(netsnmp_session *, netsnmp_pdu *,
                                    netsnmp_pdu **);

/*
 * int snmp_select_info(numfds, fdset, timeout, block)
 * int *numfds;
 * fd_set   *fdset;
 * struct timeval *timeout;
 * int *block;
 *
 * Returns info about what snmp requires from a select statement.
 * numfds is the number of fds in the list that are significant.
 * All file descriptors opened for SNMP are OR'd into the fdset.
 * If activity occurs on any of these file descriptors, snmp_read
 * should be called with that file descriptor set.
 *
 * The timeout is the latest time that SNMP can wait for a timeout.  The
 * select should be done with the minimum time between timeout and any other
 * timeouts necessary.  This should be checked upon each invocation of select.
 * If a timeout is received, snmp_timeout should be called to check if the
 * timeout was for SNMP.  (snmp_timeout is idempotent)
 *
 * Block is 1 if the select is requested to block indefinitely, rather than
 * time out.  If block is input as 1, the timeout value will be treated as
 * undefined, but it must be available for setting in snmp_select_info.  On
 * return, if block is true, the value of timeout will be undefined.
 *
 * snmp_select_info returns the number of open sockets.  (i.e. The number
 * of sessions open)
 */

int             snmp_select_info(int *, fd_set *, struct timeval *,
                                 int *);

/*
 * snmp_select_info2() is similar to snmp_select_info(), but accepts a
 * pointer to a large file descriptor set instead of a pointer to a
 * regular file descriptor set.
 */

int             snmp_select_info2(int *, netsnmp_large_fd_set *,
                                  struct timeval *, int *);


/*
 * void snmp_timeout();
 *
 * snmp_timeout should be called whenever the timeout from snmp_select_info
 * expires, but it is idempotent, so snmp_timeout can be polled (probably a
 * cpu expensive proposition).  snmp_timeout checks to see if any of the
 * sessions have an outstanding request that has timed out.  If it finds one
 * (or more), and that pdu has more retries available, a new packet is formed
 * from the pdu and is resent.  If there are no more retries available, the
 * callback for the session is used to alert the user of the timeout.
 */


void            snmp_timeout(void);

/*
 * snmp_error - return error data
 * Inputs :  address of errno, address of snmp_errno, address of string
 * Caller must free the string returned after use.
 */

void            snmp_error(netsnmp_session *, int *, int *, char **);

/*
 * single session API.
 *
 * These functions perform similar actions as snmp_XX functions,
 * but operate on a single session only.
 *
 * Synopsis:

 void * sessp;
 netsnmp_session session, *ss;
 netsnmp_pdu *pdu, *response;

 snmp_sess_init(&session);
 session.retries = ...
 session.remote_port = ...
 sessp = snmp_sess_open(&session);
 ss = snmp_sess_session(sessp);
 if (ss == NULL)
 exit(1);
 ...
 if (ss->community) free(ss->community);
 ss->community = strdup(gateway);
 ss->community_len = strlen(gateway);
 ...
 snmp_sess_synch_response(sessp, pdu, &response);
 ...
 snmp_sess_close(sessp);

 * See also:
 * snmp_sess_synch_response, in snmp_client.h.

 * Notes:
 *  1. Invoke snmp_sess_session after snmp_sess_open.
 *  2. snmp_sess_session return value is an opaque pointer.
 *  3. Do NOT free memory returned by snmp_sess_session.
 *  4. Replace snmp_send(ss,pdu) with snmp_sess_send(sessp,pdu)
 */


void           *snmp_sess_open(netsnmp_session *);
void           *snmp_sess_pointer(netsnmp_session *);
netsnmp_session *snmp_sess_session(void *);


/*
 * use return value from snmp_sess_open as void * parameter
 */


int             snmp_sess_send(void *, netsnmp_pdu *);
int             snmp_sess_async_send(void *, netsnmp_pdu *,
                                     netsnmp_callback, void *);
int             snmp_sess_select_info(void *, int *, fd_set *,
                                      struct timeval *, int *);
int             snmp_sess_select_info2(void *, int *,
                                       netsnmp_large_fd_set *,
                                       struct timeval *, int *);
/*
 * Returns 0 if success, -1 if fail.
 */

int             snmp_sess_read(void *, fd_set *);
/*
 * Similar to snmp_sess_read(), but accepts a pointer to a large file
 * descriptor set instead of a pointer to a file descriptor set.
 */

int             snmp_sess_read2(void *,
                                netsnmp_large_fd_set *);
void            snmp_sess_timeout(void *);
int             snmp_sess_close(void *);

int             snmp_sess_synch_response(void *, netsnmp_pdu *, netsnmp_pdu **);


struct snmp_pdu;
struct snmp_session;
struct variable_list;

struct synch_state {
  int             waiting;
  int             status;
  /*
   * status codes
   */

#define STAT_SUCCESS  0
#define STAT_ERROR  1
#define STAT_TIMEOUT 2
  int             reqid;
  netsnmp_pdu    *pdu;
};

void            snmp_replace_var_types(netsnmp_variable_list *vbl,
                                       u_char old_type,
                                       u_char new_type);
void            snmp_reset_var_buffers(netsnmp_variable_list *var);
void            snmp_reset_var_types(netsnmp_variable_list *vbl,
                                     u_char new_type);
int             count_varbinds(netsnmp_variable_list *var_ptr);
int             count_varbinds_of_type(netsnmp_variable_list *var_ptr,
                                       u_char type);
netsnmp_variable_list *find_varbind_of_type(netsnmp_variable_list *
    var_ptr, u_char type);
netsnmp_variable_list *find_varbind_in_list(netsnmp_variable_list *vblist,
    oid *name, size_t len);

netsnmp_pdu    *snmp_split_pdu(netsnmp_pdu *, int skipCount,
                               int copyCount);

unsigned long   snmp_varbind_len(netsnmp_pdu *pdu);
int             snmp_clone_var(netsnmp_variable_list *,
                               netsnmp_variable_list *);
const char     *snmp_errstring(int);
int             snmp_synch_response_cb(netsnmp_session *,
                                       netsnmp_pdu *, netsnmp_pdu **,
                                       snmp_callback);
int             snmp_clone_mem(void **, const void *, unsigned);


void              netsnmp_query_set_default_session(netsnmp_session *);
netsnmp_session *netsnmp_query_get_default_session( void );
int netsnmp_query_get(     netsnmp_variable_list *, netsnmp_session *);
int netsnmp_query_getnext( netsnmp_variable_list *, netsnmp_session *);
int netsnmp_query_walk(    netsnmp_variable_list *, netsnmp_session *);
int netsnmp_query_set(     netsnmp_variable_list *, netsnmp_session *);

void            snmp_sess_perror(const char *prog_string,
                                 netsnmp_session *ss);
const char     *snmp_pdu_type(int type);

#endif