#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