]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
gindent
authorwessels <>
Fri, 21 Nov 1997 08:58:57 +0000 (08:58 +0000)
committerwessels <>
Fri, 21 Nov 1997 08:58:57 +0000 (08:58 +0000)
21 files changed:
include/asn1.h
include/md5.h
include/parse.h
include/snmp.h
include/snmp_api.h
include/snmp_client.h
include/snmp_impl.h
include/snmp_util.h
include/snmp_vars.h
include/splay.h
lib/snprintf.c
lib/splay.c
snmplib/asn1.c
snmplib/mib.c
snmplib/parse.c
snmplib/snmp_api.c
src/acl.cc
src/client.cc
src/enums.h
src/main.cc
src/protos.h

index 979c39b3aeb76d2fdec82390b15c08e0f4196638..8fd4456866fbeb5ee47da0b1dc5948f24b8728d2 100644 (file)
@@ -32,18 +32,18 @@ SOFTWARE.
 
 #undef _ANSI_ARGS_
 #if (defined(__STDC__) && ! defined(NO_PROTOTYPE)) || defined(USE_PROTOTYPE)
-# define _ANSI_ARGS_(x) x
+#define _ANSI_ARGS_(x) x
 #else
-# define _ANSI_ARGS_(x) ()
+#define _ANSI_ARGS_(x) ()
 #endif
 
 #include <sys/types.h>
 
 #ifndef EIGHTBIT_SUBIDS
-typedef u_long oid;
+typedef u_long oid;
 #define MAX_SUBID   0xFFFFFFFF
 #else
-typedef u_char oid;
+typedef u_char oid;
 #define MAX_SUBID   0xFF
 #endif
 
@@ -92,108 +92,108 @@ typedef long int32;
 struct counter64 {
     u_int32 high;
     u_int32 low;
-  };
-
-
-extern u_char  *asn_parse_int _ANSI_ARGS_((u_char *data,
-                       int *datalength,
-                       u_char *type,
-                       long *intp,
-                       int intsize));
-
-extern u_char  *asn_build_int _ANSI_ARGS_((u_char *data,
-                       int *datalength,
-                       u_char type,
-                       long *intp,
-                       int intsize));
-
-extern u_char  *asn_parse_unsigned_int _ANSI_ARGS_((u_char *data,
-                       int *datalength,
-                       u_char *type,
-                       u_long *intp,
-                       int intsize));
-
-extern u_char  *asn_build_unsigned_int _ANSI_ARGS_((u_char *data,
-                       int *datalength,
-                       u_char type,
-                       u_long *intp,
-                       int intsize));
-
-extern u_char  *asn_parse_string _ANSI_ARGS_((u_char *data,
-                       int *datalength,
-                       u_char *type,
-                       u_char *string,
-                       int *len));
-
-extern u_char  *asn_build_string _ANSI_ARGS_((u_char *data,
-                       int *datalength,
-                       u_char type,
-                       u_char *str,
-                       int len));
-
-extern u_char  *asn_parse_header _ANSI_ARGS_((u_char *data,
-                       int *datalength,
-                       u_char *type));
-
-extern u_char  *asn_build_header _ANSI_ARGS_((u_char *data,
-                       int *datalength,
-                       u_char type,
-                       int len));
-
-extern u_char  *asn_build_sequence _ANSI_ARGS_((u_char *data,
-                       int *datalength,
-                       u_char type,
-                       int len));
-
-extern u_char  *asn_parse_length _ANSI_ARGS_((u_char *data,
-                       u_long *eln));
-
-extern u_char  *asn_build_length _ANSI_ARGS_((u_char *data,
-                       int *datalength,
-                       int len));
-
-extern u_char  *asn_parse_objid _ANSI_ARGS_((
-                       u_char *data,
-                       int *datalength,
-                       u_char *type,
-                       oid *objid, 
-                       int *objidlength));
-
-extern u_char  *asn_build_objid _ANSI_ARGS_((u_char *data,
-                       int *datalength,
-                       u_char type,
-                       oid *objid, 
-                       int objidlength));
-
-extern u_char  *asn_parse_null _ANSI_ARGS_((u_char *data,
-                       int *datalength,
-                       u_char *type));
-
-extern u_char  *asn_build_null _ANSI_ARGS_((u_char *data,
-                       int *datalength,
-                       u_char type));
-extern u_char  *asn_parse_bitstring _ANSI_ARGS_((u_char *data,
-                       int *datalength,
-                       u_char *type,
-                       u_char *str,
-                       int *len));
-
-extern u_char  *asn_build_bitstring _ANSI_ARGS_((u_char *data,
-                       int *datalength,
-                       u_char type,
-                       u_char *str,
-                       int len));
-
-extern u_char  *asn_parse_unsigned_int64 _ANSI_ARGS_((u_char *data,
-                       int *datalength,
-                       u_char *type,
-                       struct counter64 *cp,
-                       int cp_size));
-
-extern u_char  *asn_build_unsigned_int64 _ANSI_ARGS_((u_char *data,
-                       int *datalength,
-                       u_char type,
-                       struct counter64 *cp,
-                       int cp_size));
+};
+
+
+extern u_char *asn_parse_int _ANSI_ARGS_((u_char * data,
+       int *datalength,
+       u_char * type,
+       long *intp,
+       int intsize));
+
+extern u_char *asn_build_int _ANSI_ARGS_((u_char * data,
+       int *datalength,
+       u_char type,
+       long *intp,
+       int intsize));
+
+extern u_char *asn_parse_unsigned_int _ANSI_ARGS_((u_char * data,
+       int *datalength,
+       u_char * type,
+       u_long * intp,
+       int intsize));
+
+extern u_char *asn_build_unsigned_int _ANSI_ARGS_((u_char * data,
+       int *datalength,
+       u_char type,
+       u_long * intp,
+       int intsize));
+
+extern u_char *asn_parse_string _ANSI_ARGS_((u_char * data,
+       int *datalength,
+       u_char * type,
+       u_char * string,
+       int *len));
+
+extern u_char *asn_build_string _ANSI_ARGS_((u_char * data,
+       int *datalength,
+       u_char type,
+       u_char * str,
+       int len));
+
+extern u_char *asn_parse_header _ANSI_ARGS_((u_char * data,
+       int *datalength,
+       u_char * type));
+
+extern u_char *asn_build_header _ANSI_ARGS_((u_char * data,
+       int *datalength,
+       u_char type,
+       int len));
+
+extern u_char *asn_build_sequence _ANSI_ARGS_((u_char * data,
+       int *datalength,
+       u_char type,
+       int len));
+
+extern u_char *asn_parse_length _ANSI_ARGS_((u_char * data,
+       u_long * eln));
+
+extern u_char *asn_build_length _ANSI_ARGS_((u_char * data,
+       int *datalength,
+       int len));
+
+extern u_char *asn_parse_objid _ANSI_ARGS_((
+       u_char * data,
+       int *datalength,
+       u_char * type,
+       oid * objid,
+       int *objidlength));
+
+extern u_char *asn_build_objid _ANSI_ARGS_((u_char * data,
+       int *datalength,
+       u_char type,
+       oid * objid,
+       int objidlength));
+
+extern u_char *asn_parse_null _ANSI_ARGS_((u_char * data,
+       int *datalength,
+       u_char * type));
+
+extern u_char *asn_build_null _ANSI_ARGS_((u_char * data,
+       int *datalength,
+       u_char type));
+extern u_char *asn_parse_bitstring _ANSI_ARGS_((u_char * data,
+       int *datalength,
+       u_char * type,
+       u_char * str,
+       int *len));
+
+extern u_char *asn_build_bitstring _ANSI_ARGS_((u_char * data,
+       int *datalength,
+       u_char type,
+       u_char * str,
+       int len));
+
+extern u_char *asn_parse_unsigned_int64 _ANSI_ARGS_((u_char * data,
+       int *datalength,
+       u_char * type,
+       struct counter64 * cp,
+       int cp_size));
+
+extern u_char *asn_build_unsigned_int64 _ANSI_ARGS_((u_char * data,
+       int *datalength,
+       u_char type,
+       struct counter64 * cp,
+       int cp_size));
 
 #endif
index 37d1d3453950d8347b7147b132de630254162643..7e71b5d78c8737fc90fc6454767f3c8cd82ab82a 100644 (file)
@@ -4,9 +4,9 @@
  */
 
 /* PROTOTYPES should be set to one if and only if the compiler supports
-  function argument prototyping.
-The following makes PROTOTYPES default to 0 if it has not already
-  been defined with C compiler flags.
* function argument prototyping.
+ * The following makes PROTOTYPES default to 0 if it has not already
* been defined with C compiler flags.
  */
 #ifndef PROTOTYPES
 #define PROTOTYPES 0
@@ -22,8 +22,8 @@ typedef unsigned short int UINT2;
 typedef unsigned long int UINT4;
 
 /* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
-If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
-  returns an empty list.
+ * If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
* returns an empty list.
  */
 #if PROTOTYPES
 #define PROTO_LIST(list) list
@@ -35,36 +35,35 @@ If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
  */
 
 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
-rights reserved.
-
-License to copy and use this software is granted provided that it
-is identified as the "RSA Data Security, Inc. MD5 Message-Digest
-Algorithm" in all material mentioning or referencing this software
-or this function.
-
-License is also granted to make and use derivative works provided
-that such works are identified as "derived from the RSA Data
-Security, Inc. MD5 Message-Digest Algorithm" in all material
-mentioning or referencing the derived work.
-
-RSA Data Security, Inc. makes no representations concerning either
-the merchantability of this software or the suitability of this
-software for any particular purpose. It is provided "as is"
-without express or implied warranty of any kind.
-
-These notices must be retained in any copies of any part of this
-documentation and/or software.
+ * rights reserved.
+ * 
+ * License to copy and use this software is granted provided that it
+ * is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+ * Algorithm" in all material mentioning or referencing this software
+ * or this function.
+ * 
+ * License is also granted to make and use derivative works provided
+ * that such works are identified as "derived from the RSA Data
+ * Security, Inc. MD5 Message-Digest Algorithm" in all material
+ * mentioning or referencing the derived work.
+ * 
+ * RSA Data Security, Inc. makes no representations concerning either
+ * the merchantability of this software or the suitability of this
+ * software for any particular purpose. It is provided "as is"
+ * without express or implied warranty of any kind.
+ * 
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
  */
 
 /* MD5 context. */
 typedef struct {
-  UINT4 state[4];                                   /* state (ABCD) */
-  UINT4 count[2];        /* number of bits, modulo 2^64 (lsb first) */
-  unsigned char buffer[64];                         /* input buffer */
+    UINT4 state[4];            /* state (ABCD) */
+    UINT4 count[2];            /* number of bits, modulo 2^64 (lsb first) */
+    unsigned char buffer[64];  /* input buffer */
 } MD5_CTX;
 
-void MD5Init PROTO_LIST ((MD5_CTX *));
+void MD5Init PROTO_LIST((MD5_CTX *));
 void MD5Update PROTO_LIST
-  ((MD5_CTX *, unsigned char *, unsigned int));
-void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));
-
+          ((MD5_CTX *, unsigned char *, unsigned int));
+void MD5Final PROTO_LIST((unsigned char[16], MD5_CTX *));
index 67a251260e09a743b6de9a07c5661763b2a2b2fc..4343e7557627585125f23157e1df5c0dfda394c5 100644 (file)
@@ -30,9 +30,9 @@ SOFTWARE.
 
 #undef _ANSI_ARGS_
 #if (defined(__STDC__) && ! defined(NO_PROTOTYPE)) || defined(USE_PROTOTYPE)
-# define _ANSI_ARGS_(x) x
+#define _ANSI_ARGS_(x) x
 #else
-# define _ANSI_ARGS_(x) ()
+#define _ANSI_ARGS_(x) ()
 #endif
 
 
@@ -47,7 +47,7 @@ SOFTWARE.
  */
 struct enum_list {
     struct enum_list *next;
-    int        value;
+    int value;
     char *label;
 };
 
@@ -56,13 +56,13 @@ struct enum_list {
  */
 struct node {
     struct node *next;
-    char label[MAXLABEL]; /* This node's (unique) textual name */
-    u_long  subid;  /* This node's integer subidentifier */
-    char parent[MAXLABEL];/* The parent's textual name */
-    int type;      /* The type of object this represents */
+    char label[MAXLABEL];      /* This node's (unique) textual name */
+    u_long subid;              /* This node's integer subidentifier */
+    char parent[MAXLABEL];     /* The parent's textual name */
+    int type;                  /* The type of object this represents */
     struct enum_list *enums;   /* (optional) list of enumerated integers
-(otherwise NULL) */
-    char *description; /* description (a quoted string) */
+                                * (otherwise NULL) */
+    char *description;         /* description (a quoted string) */
 };
 
 /*
@@ -72,13 +72,13 @@ struct tree {
     struct tree *child_list;   /* list of children of this node */
     struct tree *next_peer;    /* Next node in list of peers */
     struct tree *parent;
-    char label[MAXLABEL];              /* This node's textual name */
+    char label[MAXLABEL];      /* This node's textual name */
     u_long subid;              /* This node's integer subidentifier */
     int type;                  /* This node's object type */
     struct enum_list *enums;   /* (optional) list of enumerated integers
-(otherwise NULL) */
-    void (*printer)();     /* Value printing function */
-    char *description; /* description (a quoted string) */
+                                * (otherwise NULL) */
+    void (*printer) ();                /* Value printing function */
+    char *description;         /* description (a quoted string) */
 };
 
 /* non-aggregate types for tree end nodes */
index d3b47c38ea8b9165488d08e51632576de131a7dd..fc43bd618b49db0a3abf1b5487076e9375f7ab24 100644 (file)
@@ -113,35 +113,35 @@ SOFTWARE.
 
 
 typedef struct _conf_if_list {
-  char *name;
-  int type;
-  int speed;
-  struct _conf_if_list *next;
+    char *name;
+    int type;
+    int speed;
+    struct _conf_if_list *next;
 } conf_if_list;
 
 extern conf_if_list *if_list;
 
 #ifndef SQUID_SNMP
-/*extern void init_snmp();*/
-
-extern int read_objid (char *input,
-                                  oid *output,
-                                  int  *out_len);
-
-extern void sprint_objid (char *buf,oid *id,int idlen);
-extern void print_objid (oid *id,
-                                    int idlen);
-void snmp_add_null_var (struct snmp_pdu *,
-                                          oid *,
-                                          int);
-extern void xdump (u_char *cp,
-                              int length,
-                              char *prefix);
-
-extern void snmp_synch_setup (struct snmp_session *session);
-
-extern int snmp_synch_response (struct snmp_session *ss,
-                                           struct snmp_pdu *pdu,
-                                           struct snmp_pdu **response);
+/*extern void init_snmp(); */
+
+extern int read_objid(char *input,
+    oid * output,
+    int *out_len);
+
+extern void sprint_objid(char *buf, oid * id, int idlen);
+extern void print_objid(oid * id,
+    int idlen);
+void snmp_add_null_var(struct snmp_pdu *,
+    oid *,
+    int);
+extern void xdump(u_char * cp,
+    int length,
+    char *prefix);
+
+extern void snmp_synch_setup(struct snmp_session *session);
+
+extern int snmp_synch_response(struct snmp_session *ss,
+    struct snmp_pdu *pdu,
+    struct snmp_pdu **response);
 #endif
 #endif
index 336aa5cf6b7c0f4d75234cc80763db02dc9dc9c6..c8bbbd8ca850913a74fc46a9da7ce89313135529 100644 (file)
@@ -30,9 +30,9 @@ SOFTWARE.
 
 #undef _ANSI_ARGS_
 #if (defined(__STDC__) && ! defined(NO_PROTOTYPE)) || defined(USE_PROTOTYPE)
-# define _ANSI_ARGS_(x) x
+#define _ANSI_ARGS_(x) x
 #else
-# define _ANSI_ARGS_(x) ()
+#define _ANSI_ARGS_(x) ()
 #endif
 
 
@@ -50,62 +50,62 @@ typedef int ssize_t;
 typedef struct sockaddr_in ipaddr;
 
 typedef struct {
-    u_char     securityModel;
-    u_char     qoS;
-    u_char     agentID[12];
-    u_long     agentBoots;
-    int                agentTime;
-    int                MMS;
-    int                userLen;
-    u_char     userName[16];
-    int                authLen;
-    u_char     authDigest[16];
-    u_char     *authDigestPtr;
-    int                contextLen;
-    u_char     contextSelector[40];
+    u_char securityModel;
+    u_char qoS;
+    u_char agentID[12];
+    u_long agentBoots;
+    int agentTime;
+    int MMS;
+    int userLen;
+    u_char userName[16];
+    int authLen;
+    u_char authDigest[16];
+    u_char *authDigestPtr;
+    int contextLen;
+    u_char contextSelector[40];
 } Parameters;
 
 struct snmp_session {
-    int            retries;            /* Number of retries before timeout. */
-    long    timeout;           /* Number of uS until first timeout, then exponential backoff */
-    char    *peername;         /* Domain name or dotted IP address of default peer */
+    int retries;               /* Number of retries before timeout. */
+    long timeout;              /* Number of uS until first timeout, then exponential backoff */
+    char *peername;            /* Domain name or dotted IP address of default peer */
     u_short remote_port;       /* UDP port number of peer. */
-    u_short local_port;        /* My UDP port number, 0 for default, picked randomly */
+    u_short local_port;                /* My UDP port number, 0 for default, picked randomly */
 
     /* Authentication function or NULL if null authentication is used */
-    int    (*authenticator)();
-    int            (*callback)();      /* Function to interpret incoming data */
+    int (*authenticator) ();
+    int (*callback) ();                /* Function to interpret incoming data */
 
     /* Pointer to data that the callback function may consider important */
-    void    *callback_magic;
+    void *callback_magic;
 
-    int                version;        /* SNMP version number */
+    int version;               /* SNMP version number */
 
     /* fields to support SNMPv1 community model */
-    int                community_len;
-    u_char      *community;
+    int community_len;
+    u_char *community;
 
     /* the private keys to use for user-based security */
-    u_char     authKey[16];
-    u_char     privKey[16];
+    u_char authKey[16];
+    u_char privKey[16];
 
     /* fields to support user-based security model in SNMPv2 */
-    Parameters params;
-
-    u_char     qoS;
-    u_char     agentID[16];
-    u_long     agentBoots;
-    int                agentTime;              /* the agentTime value */
-    int                agentClock;             /* the running agentClock */
-    int                userLen;
-    u_char     userName[32];
-    int                MMS;
-    int                contextLen;
-    u_char     contextSelector[64];
+    Parameters params;
+
+    u_char qoS;
+    u_char agentID[16];
+    u_long agentBoots;
+    int agentTime;             /* the agentTime value */
+    int agentClock;            /* the running agentClock */
+    int userLen;
+    u_char userName[32];
+    int MMS;
+    int contextLen;
+    u_char contextSelector[64];
 
     /* misc stuff */
-    int                readView;
-    int                writeView;
+    int readView;
+    int writeView;
 };
 
 /*
@@ -134,55 +134,55 @@ struct snmp_session {
 extern int snmp_errno;
 /* Error return values */
 #define SNMPERR_GENERR         -1
-#define SNMPERR_BAD_LOCPORT    -2  /* local port was already in use */
+#define SNMPERR_BAD_LOCPORT    -2      /* local port was already in use */
 #define SNMPERR_BAD_ADDRESS    -3
 #define SNMPERR_BAD_SESSION    -4
 #define SNMPERR_TOO_LONG       -5
 
 
 struct snmp_pdu {
-    ipaddr  address;   /* Address of peer */
+    ipaddr address;            /* Address of peer */
 
-    int            command;    /* Type of this PDU */
+    int command;               /* Type of this PDU */
 
     Parameters params;
 
-    u_long  reqid;     /* Request id */
-    u_long  errstat;   /* Error status */
-    u_long  errindex;  /* Error index */
+    u_long reqid;              /* Request id */
+    u_long errstat;            /* Error status */
+    u_long errindex;           /* Error index */
 
     /* Trap information */
-    oid            *enterprise;/* System OID */
-    int            enterprise_length;
-    ipaddr  agent_addr;        /* address of object generating trap */
-    int            trap_type;  /* trap type */
-    int            specific_type;  /* specific type */
-    u_long  time;      /* Uptime */
+    oid *enterprise;           /* System OID */
+    int enterprise_length;
+    ipaddr agent_addr;         /* address of object generating trap */
+    int trap_type;             /* trap type */
+    int specific_type;         /* specific type */
+    u_long time;               /* Uptime */
 
     struct variable_list *variables;
 };
 
 
 struct variable_list {
-    struct variable_list *next_variable;    /* NULL for last variable */
-    oid            *name;  /* Object identifier of variable */
-    int            name_length;    /* number of subid's in name */
-    u_char  type;   /* ASN type of variable */
-    union { /* value of variable */
-       long    *integer;
-       u_char  *string;
-       oid     *objid;
-       u_char  *bitstring;
+    struct variable_list *next_variable;       /* NULL for last variable */
+    oid *name;                 /* Object identifier of variable */
+    int name_length;           /* number of subid's in name */
+    u_char type;               /* ASN type of variable */
+    union {                    /* value of variable */
+       long *integer;
+       u_char *string;
+       oid *objid;
+       u_char *bitstring;
        struct counter64 *counter64;
 
     } val;
-    int            val_len;
+    int val_len;
 };
 
 #ifndef SQUID_SNMP
 /*
  * struct snmp_session *snmp_open(session)
- *     struct snmp_session *session;
+ *      struct snmp_session *session;
  * 
  * Sets up the session with the snmp_session information provided
  * by the user.  Then opens and binds the necessary UDP port.
@@ -190,7 +190,7 @@ struct variable_list {
  * the pointer passed to snmp_open()).  On any error, NULL is returned
  * and snmp_errno is set to the appropriate error code.
  */
-struct snmp_session *snmp_open _ANSI_ARGS_((struct snmp_session *session));
+struct snmp_session *snmp_open _ANSI_ARGS_((struct snmp_session * session));
 
 /*
  * int snmp_close(session)
@@ -200,13 +200,13 @@ struct snmp_session *snmp_open _ANSI_ARGS_((struct snmp_session *session));
  * dequeues any pending requests, and closes any sockets allocated for
  * the session.  Returns 0 on error, 1 otherwise.
  */
-int snmp_close _ANSI_ARGS_((struct snmp_session *session));
+int snmp_close _ANSI_ARGS_((struct snmp_session * session));
 
 
 /*
  * int snmp_send(session, pdu)
  *     struct snmp_session *session;
- *     struct snmp_pdu *pdu;
+ *     struct snmp_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
@@ -216,8 +216,8 @@ int snmp_close _ANSI_ARGS_((struct snmp_session *session));
  * On any error, 0 is returned.
  * The pdu is freed by snmp_send() unless a failure occured.
  */
-int snmp_send _ANSI_ARGS_((struct snmp_session *session,
-                          struct snmp_pdu *pdu));
+int snmp_send _ANSI_ARGS_((struct snmp_session * session,
+       struct snmp_pdu * pdu));
 
 
 /*
@@ -230,7 +230,7 @@ int snmp_send _ANSI_ARGS_((struct snmp_session *session,
  * 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  *fdset);
+void snmp_read(fd_set * fdset);
 
 
 /*
@@ -240,7 +240,7 @@ void snmp_read (fd_set  *fdset);
  * 
  * Frees the pdu and any malloc'd data associated with it.
  */
-void snmp_free_pdu (struct snmp_pdu *pdu);
+void snmp_free_pdu(struct snmp_pdu *pdu);
 
 /*
  * int snmp_select_info(numfds, fdset, timeout, block)
@@ -269,9 +269,9 @@ void snmp_free_pdu (struct snmp_pdu *pdu);
  * snmp_select_info returns the number of open sockets.  (i.e. The number of sessions open)
  */
 int snmp_select_info _ANSI_ARGS_((int *numfds,
-                                 fd_set *fdset,
-                                 struct timeval *timeout,
-                                 int *block));
+       fd_set * fdset,
+       struct timeval * timeout,
+       int *block));
 
 /*
  * void snmp_timeout();
@@ -291,10 +291,10 @@ void snmp_timeout _ANSI_ARGS_((void));
  * This routine must be supplied by the application:
  *
  * u_char *authenticator(pdu, length, community, community_len)
- * u_char *pdu;                The rest of the PDU to be authenticated
- * int *length;                The length of the PDU (updated by the authenticator)
- * u_char *community;  The community name to authenticate under.
- * int community_len   The length of the community name.
+ * u_char *pdu;         The rest of the PDU to be authenticated
+ * int *length;         The length of the PDU (updated by the authenticator)
+ * u_char *community;   The community name to authenticate under.
+ * int  community_len   The length of the community name.
  *
  * Returns the authenticated pdu, or NULL if authentication failed.
  * If null authentication is used, the authenticator in snmp_session can be
@@ -307,9 +307,9 @@ void snmp_timeout _ANSI_ARGS_((void));
  * int callback(operation, session, reqid, pdu, magic)
  * int operation;
  * struct snmp_session *session;    The session authenticated under.
- * int reqid;                      The request id of this pdu (0 for TRAP)
- * struct snmp_pdu *pdu;           The pdu information.
- * void *magic                     A link to the data for this routine.
+ * int reqid;                       The request id of this pdu (0 for TRAP)
+ * struct snmp_pdu *pdu;            The pdu information.
+ * void *magic                      A link to the data for this routine.
  *
  * Returns 1 if request was successful, 0 if it should be kept pending.
  * Any data in the pdu must be copied because it will be freed elsewhere.
index b1b9249e23a149dcb26c6e78abe79a611358bcb6..6517520bef767588d9f78fc2f425870f05eff71d 100644 (file)
@@ -29,15 +29,15 @@ SOFTWARE.
 
 #undef _ANSI_ARGS_
 #if (defined(__STDC__) && ! defined(NO_PROTOTYPE)) || defined(USE_PROTOTYPE)
-# define _ANSI_ARGS_(x) x
+#define _ANSI_ARGS_(x) x
 #else
-# define _ANSI_ARGS_(x) ()
+#define _ANSI_ARGS_(x) ()
 #endif
 
 
 
 struct synch_state {
-    int        waiting;
+    int waiting;
     int status;
 /* status codes */
 #define STAT_SUCCESS   0
@@ -51,8 +51,8 @@ extern struct synch_state snmp_synch_state;
 
 extern struct snmp_pdu *snmp_pdu_create _ANSI_ARGS_((int cmd));
 
-extern struct snmp_pdu *snmp_fix_pdu _ANSI_ARGS_((struct snmp_pdu *pdu,
-                                                 int cmd));
+extern struct snmp_pdu *snmp_fix_pdu _ANSI_ARGS_((struct snmp_pdu * pdu,
+       int cmd));
 extern char *snmp_errstring _ANSI_ARGS_((int errstat));
 
 #endif
index 46a96c7d2e19654b7191729d191fb3126d6b24cf..22205dbc0a0bdd4a99a3a2650937d47d10ac66ad 100644 (file)
@@ -31,9 +31,9 @@ SOFTWARE.
 
 #undef _ANSI_ARGS_
 #if (defined(__STDC__) && ! defined(NO_PROTOTYPE)) || defined(USE_PROTOTYPE)
-# define _ANSI_ARGS_(x) x
+#define _ANSI_ARGS_(x) x
 #else
-# define _ANSI_ARGS_(x) ()
+#define _ANSI_ARGS_(x) ()
 #endif
 
 
@@ -55,7 +55,7 @@ SOFTWARE.
 #define BUILD_ERROR    -2
 
 #define SID_MAX_LEN    200
-#define MAX_NAME_LEN   64  /* number of subid's in a objid */
+#define MAX_NAME_LEN   64      /* number of subid's in a objid */
 
 #ifndef NULL
 #define NULL 0
@@ -77,9 +77,9 @@ SOFTWARE.
 #define ACTION      3
 #define FREE        4
 
-#define RONLY  0xAAAA  /* read access for everyone */
-#define RWRITE 0xAABA  /* add write access for community private */
-#define NOACCESS 0x0000        /* no access for anybody */
+#define RONLY  0xAAAA          /* read access for everyone */
+#define RWRITE 0xAABA          /* add write access for community private */
+#define NOACCESS 0x0000                /* no access for anybody */
 
 #define INTEGER            ASN_INTEGER
 #define STRING     ASN_OCTET_STR
@@ -103,35 +103,35 @@ SOFTWARE.
 #define ERROR(string)
 #endif
 
-/* from snmp.c*/
-extern u_char  sid[];  /* size SID_MAX_LEN */
-
-extern u_char *snmp_parse_var_op _ANSI_ARGS_((u_char *data,
-                                             oid *var_name,
-                                             int *var_name_len,
-                                             u_char *var_val_type,
-                                             int *var_val_len,
-                                             u_char **var_val, 
-                                             int *listlength));
-
-extern u_char *snmp_build_var_op _ANSI_ARGS_((u_char *data,
-                                             oid *var_name,
-                                             int *var_name_len,
-                                             u_char var_val_type,
-                                             int var_val_len,
-                                             u_char *var_val,
-                                             int *listlength));
-
-extern u_char *snmp_auth_parse _ANSI_ARGS_((u_char *data,
-                                           int *length,
-                                           u_char *sid,
-                                           int *slen,
-                                           long *version));
-
-extern u_char *snmp_auth_build _ANSI_ARGS_((u_char *data,
-                                           int *length,
-                                           struct snmp_session *session,
-                                           int is_agent,
-                                           int messagelen));
+/* from snmp.c */
+extern u_char sid[];           /* size SID_MAX_LEN */
+
+extern u_char *snmp_parse_var_op _ANSI_ARGS_((u_char * data,
+       oid * var_name,
+       int *var_name_len,
+       u_char * var_val_type,
+       int *var_val_len,
+       u_char ** var_val,
+       int *listlength));
+
+extern u_char *snmp_build_var_op _ANSI_ARGS_((u_char * data,
+       oid * var_name,
+       int *var_name_len,
+       u_char var_val_type,
+       int var_val_len,
+       u_char * var_val,
+       int *listlength));
+
+extern u_char *snmp_auth_parse _ANSI_ARGS_((u_char * data,
+       int *length,
+       u_char * sid,
+       int *slen,
+       long *version));
+
+extern u_char *snmp_auth_build _ANSI_ARGS_((u_char * data,
+       int *length,
+       struct snmp_session * session,
+       int is_agent,
+       int messagelen));
 
 #endif
index d9be9146ff91a9a090f5f2d79da93a17e80a9734..2b927fd22fd361ab1a70240fed93b8f527ea6490 100644 (file)
@@ -4,9 +4,9 @@
 
 #undef _ANSI_ARGS_
 #if (defined(__STDC__) && ! defined(NO_PROTOTYPE)) || defined(USE_PROTOTYPE)
-# define _ANSI_ARGS_(x) x
+#define _ANSI_ARGS_(x) x
 #else
-# define _ANSI_ARGS_(x) ()
+#define _ANSI_ARGS_(x) ()
 #endif
 
 
@@ -20,55 +20,55 @@ extern void snmp_alarm _ANSI_ARGS_((int ival, void (*handler) (void)));
  * service for filedescriptors:
  */
 
-extern void fd_add _ANSI_ARGS_((int fd, void (*func)(int fd)));
+extern void fd_add _ANSI_ARGS_((int fd, void (*func) (int fd)));
 extern void fd_service _ANSI_ARGS_((void));
 
 
 /* ---------------------------------------------------------------------- */
 
 /*
-**  SNMP Agent extension for Spacer-Controler Management
-**
-**  Copyright (c) 1997 FT/CNET/DES/GRL Olivier Montanuy
-** 
-*/
+ * **  SNMP Agent extension for Spacer-Controler Management
+ * **
+ * **  Copyright (c) 1997 FT/CNET/DES/GRL Olivier Montanuy
+ * ** 
+ */
 /*
-** Function to safely copy a string, and ensure the last
-** character is always '\0'.
-*/
+ * ** Function to safely copy a string, and ensure the last
+ * ** character is always '\0'.
+ */
 void
 strcpy_safe _ANSI_ARGS_((char *str, int str_len, char *val));
 
 
 /*
-** Function to get IP address of this agent
-** WARNING: this scans all interfaces (slow)
-*/
-u_long 
+ * ** Function to get IP address of this agent
+ * ** WARNING: this scans all interfaces (slow)
+ */
+u_long
 Util_local_ip_address _ANSI_ARGS_((void));
 
 /*
-** Function to get the current time in seconds
-*/
-long 
+ * ** Function to get the current time in seconds
+ */
+long
 Util_time_now _ANSI_ARGS_((void));
 
 /*
-** Function to determine how long the agent has been running
-*  (WARNING: this seems rather slow)
-*/
-long 
-Util_time_running();
+ * ** Function to determine how long the agent has been running
+ * *  (WARNING: this seems rather slow)
+ */
+long
+     Util_time_running();
 
 /*
-** Read data from file
-*/
+ * ** Read data from file
+ */
 int
 Util_file_read _ANSI_ARGS_((char *file, int offset, char *data, int dataSz));
 
 /*
-** Write data into file
-*/
+ * ** Write data into file
+ */
 int
 Util_file_write _ANSI_ARGS_((char *file, int offset, char *data, int dataSz));
 
index 9a468907caa92fb464a83851a71b37998f6ed4a1..7ff8e55fcb47bc1807a97dc03e943fb07ac0837b 100644 (file)
@@ -31,35 +31,35 @@ PERFORMANCE OF THIS SOFTWARE.
 
 #undef _ANSI_ARGS_
 #if (defined(__STDC__) && ! defined(NO_PROTOTYPE)) || defined(USE_PROTOTYPE)
-# define _ANSI_ARGS_(x) x
+#define _ANSI_ARGS_(x) x
 #else
-# define _ANSI_ARGS_(x) ()
+#define _ANSI_ARGS_(x) ()
 #endif
 
 
-u_char *var_system();
-u_char *var_ifEntry();
-u_char *var_atEntry();
-u_char *var_ip();
-u_char *var_ipAddrEntry();
-u_char *var_ipRouteEntry();
-u_char *var_icmp();
-u_char *var_tcp();
-u_char *var_udp();
+u_char *var_system();
+u_char *var_ifEntry();
+u_char *var_atEntry();
+u_char *var_ip();
+u_char *var_ipAddrEntry();
+u_char *var_ipRouteEntry();
+u_char *var_icmp();
+u_char *var_tcp();
+u_char *var_udp();
 #ifdef linux
-u_char *var_snmp();
-u_char *var_id();
+u_char *var_snmp();
+u_char *var_id();
 #endif
-u_char *var_process();
-u_char *var_event();
-u_char  *var_capture();
-u_char *var_demo();
-u_char *var_snmpStats();
-u_char *var_usecStats();
-u_char *var_usecAgent();
-u_char *var_orEntry();
-u_char *var_rwstats();
-u_char *getStatPtr();
+u_char *var_process();
+u_char *var_event();
+u_char *var_capture();
+u_char *var_demo();
+u_char *var_snmpStats();
+u_char *var_usecStats();
+u_char *var_usecAgent();
+u_char *var_orEntry();
+u_char *var_rwstats();
+u_char *getStatPtr();
 
 extern long long_return;
 extern u_char return_buf[];
@@ -257,32 +257,33 @@ extern u_char return_buf[];
 
 #ifdef linux
 struct inpcb {
-        struct  inpcb *inp_next;        /* pointers to other pcb's */
-        struct  in_addr inp_faddr;      /* foreign host table entry */
-        u_short inp_fport;              /* foreign port */
-        struct  in_addr inp_laddr;      /* local host table entry */
-        u_short inp_lport;              /* local port */
-       int     inp_state;
-       int     uid;                    /* owner of the connection */
+    struct inpcb *inp_next;    /* pointers to other pcb's */
+    struct in_addr inp_faddr;  /* foreign host table entry */
+    u_short inp_fport;         /* foreign port */
+    struct in_addr inp_laddr;  /* local host table entry */
+    u_short inp_lport;         /* local port */
+    int inp_state;
+    int uid;                   /* owner of the connection */
 };
+
 #endif
 
-extern void TCP_Scan_Init ();
-extern int TCP_Scan_Next ();
+extern void TCP_Scan_Init();
+extern int TCP_Scan_Next();
 
 
 struct variable {
-    u_char         magic;          /* passed to function as a hint */
-    char           type;           /* type of variable */
+    u_char magic;              /* passed to function as a hint */
+    char type;                 /* type of variable */
 /* See important comment in snmp_vars.c relating to acl */
-    u_short        acl;            /* access control list for variable */
-    u_char         *(*findVar)();  /* function that finds variable */
-    u_char         namelen;        /* length of above */
-    oid                    name[32];       /* object identifier of variable */
+    u_short acl;               /* access control list for variable */
+    u_char *(*findVar) ();     /* function that finds variable */
+    u_char namelen;            /* length of above */
+    oid name[32];              /* object identifier of variable */
 };
 
-extern int compare ();
-extern void Interface_Scan_Init ();
-extern int Interface_Scan_Next ();
+extern int compare();
+extern void Interface_Scan_Init();
+extern int Interface_Scan_Next();
 
 #endif
index f1d22fa2d13c72ca5db1b7fdb49132971c8df90a..460aa10b084841182e953f536227b78f6af62390 100644 (file)
@@ -5,10 +5,10 @@ typedef struct _splay_node {
     struct _splay_node *right;
 } splayNode;
 
-typedef int SPCMP (const void *, splayNode *);
+typedef int SPCMP(const void *, splayNode *);
 
 extern int splayLastResult;
 
 splayNode *splay_insert(void *, splayNode *, SPCMP *);
-splayNode *splay_splay(const void *, splayNode *, SPCMP);
+splayNode *splay_splay(const void *, splayNode *, SPCMP *);
 void splay_destroy(splayNode *, void (*)(void *));
index 75bbbd1629e52619ed54b5b6f60a45f0b16bbc21..5f3be08af64d85cc338599a61693c0664f696c58 100644 (file)
@@ -1,3 +1,4 @@
+
 /* ====================================================================
  * Copyright (c) 1995-1997 The Apache Group.  All rights reserved.
  *
index 72b439950a3f9ef915fe5ea314c0e6952969797a..5fca86d90f8e084fe315973394c98fbcaad77950 100644 (file)
@@ -17,7 +17,7 @@
 int splayLastResult = 0;
 
 splayNode *
-splay_insert(void *data, splayNode * top, SPCMP *compare)
+splay_insert(void *data, splayNode * top, SPCMP * compare)
 {
     splayNode *new = xcalloc(sizeof(splayNode), 1);
     new->data = data;
@@ -44,7 +44,7 @@ splay_insert(void *data, splayNode * top, SPCMP *compare)
 }
 
 splayNode *
-splay_splay(const void *data, splayNode * top, SPCMP *compare)
+splay_splay(const void *data, splayNode * top, SPCMP * compare)
 {
     splayNode N;
     splayNode *l;
index 55d60721e171d564f5f497dfd44f27963610ad90..cb520f104f0bb57f70f948e33f66c7441cd1d9ac 100644 (file)
@@ -71,41 +71,41 @@ SOFTWARE.
  */
 u_char *
 asn_parse_int(data, datalength, type, intp, intsize)
-    u_char  *data;       /* IN - pointer to start of object */
-    int            *datalength;  /* IN/OUT - number of valid bytes left in buffer */
-    u_char  *type;       /* OUT - asn type of object */
-    long    *intp;       /* IN/OUT - pointer to start of output buffer */
-    int     intsize;      /* IN - size of output buffer */
+     u_char *data;             /* IN - pointer to start of object */
+     int *datalength;          /* IN/OUT - number of valid bytes left in buffer */
+     u_char *type;             /* OUT - asn type of object */
+     long *intp;               /* IN/OUT - pointer to start of output buffer */
+     int intsize;              /* IN - size of output buffer */
 {
 /*
  * ASN.1 integer ::= 0x02 asnlength byte {byte}*
  */
     u_char *bufp = data;
-    u_long         asn_length;
-    long   value = 0;
+    u_long asn_length;
+    long value = 0;
 
-    if (intsize != sizeof (long)){
+    if (intsize != sizeof(long)) {
        ERROR("not long");
        return NULL;
     }
     *type = *bufp++;
     bufp = asn_parse_length(bufp, &asn_length);
-    if (bufp == NULL){
+    if (bufp == NULL) {
        ERROR("bad length");
        return NULL;
     }
-    if (asn_length + (bufp - data) > *datalength){
+    if (asn_length + (bufp - data) > *datalength) {
        ERROR("overflow of message");
        return NULL;
     }
-    if (asn_length > intsize){
+    if (asn_length > intsize) {
        ERROR("I don't support such large integers");
        return NULL;
     }
-    *datalength -= (int)asn_length + (bufp - data);
+    *datalength -= (int) asn_length + (bufp - data);
     if (*bufp & 0x80)
-       value = -1; /* integer is negative */
-    while(asn_length--)
+       value = -1;             /* integer is negative */
+    while (asn_length--)
        value = (value << 8) | *bufp++;
     *intp = value;
     return bufp;
@@ -124,42 +124,42 @@ asn_parse_int(data, datalength, type, intp, intsize)
  */
 u_char *
 asn_parse_unsigned_int(data, datalength, type, intp, intsize)
-    u_char         *data;      /* IN - pointer to start of object */
-    int            *datalength;/* IN/OUT - number of valid bytes left in buffer */
-    u_char                 *type;      /* OUT - asn type of object */
-    u_long                 *intp;      /* IN/OUT - pointer to start of output buffer */
-    int                            intsize;    /* IN - size of output buffer */
+     u_char *data;             /* IN - pointer to start of object */
+     int *datalength;          /* IN/OUT - number of valid bytes left in buffer */
+     u_char *type;             /* OUT - asn type of object */
+     u_long *intp;             /* IN/OUT - pointer to start of output buffer */
+     int intsize;              /* IN - size of output buffer */
 {
 /*
  * ASN.1 integer ::= 0x02 asnlength byte {byte}*
  */
     u_char *bufp = data;
-    u_long         asn_length;
+    u_long asn_length;
     u_long value = 0;
 
-    if (intsize != sizeof (long)){
+    if (intsize != sizeof(long)) {
        ERROR("not long");
        return NULL;
     }
     *type = *bufp++;
     bufp = asn_parse_length(bufp, &asn_length);
-    if (bufp == NULL){
+    if (bufp == NULL) {
        ERROR("bad length");
        return NULL;
     }
-    if (asn_length + (bufp - data) > *datalength){
+    if (asn_length + (bufp - data) > *datalength) {
        ERROR("overflow of message");
        return NULL;
     }
     if ((asn_length > (intsize + 1)) ||
-       ((asn_length == intsize + 1) && *bufp != 0x00)){
+       ((asn_length == intsize + 1) && *bufp != 0x00)) {
        ERROR("I don't support such large integers");
        return NULL;
     }
-    *datalength -= (int)asn_length + (bufp - data);
+    *datalength -= (int) asn_length + (bufp - data);
     if (*bufp & 0x80)
-       value = -1; /* integer is negative */
-    while(asn_length--)
+       value = -1;             /* integer is negative */
+    while (asn_length--)
        value = (value << 8) | *bufp++;
     *intp = value;
     return bufp;
@@ -178,11 +178,11 @@ asn_parse_unsigned_int(data, datalength, type, intp, intsize)
  */
 u_char *
 asn_build_int(data, datalength, type, intp, intsize)
-    u_char *data;      /* IN - pointer to start of output buffer */
-    int    *datalength;/* IN/OUT - number of valid bytes left in buffer */
-    u_char         type;       /* IN - asn type of object */
-    long   *intp;      /* IN - pointer to start of long integer */
-    int    intsize;    /* IN - size of *intp */
+     u_char *data;             /* IN - pointer to start of output buffer */
+     int *datalength;          /* IN/OUT - number of valid bytes left in buffer */
+     u_char type;              /* IN - asn type of object */
+     long *intp;               /* IN - pointer to start of long integer */
+     int intsize;              /* IN - size of *intp */
 {
 /*
  * ASN.1 integer ::= 0x02 asnlength byte {byte}*
@@ -191,7 +191,7 @@ asn_build_int(data, datalength, type, intp, intsize)
     long integer;
     u_long mask;
 
-    if (intsize != sizeof (long)) {
+    if (intsize != sizeof(long)) {
        ERROR("not long");
        return NULL;
     }
@@ -204,8 +204,8 @@ asn_build_int(data, datalength, type, intp, intsize)
      */
     mask = 0x1FF << ((8 * (sizeof(int32) - 1)) - 1);
     /* mask is 0xFF800000 on a big-endian machine */
-    while((((integer & mask) == 0) || ((integer & mask) == mask))
-         && intsize > 1){
+    while ((((integer & mask) == 0) || ((integer & mask) == mask))
+       && intsize > 1) {
        intsize--;
        integer <<= 8;
     }
@@ -217,8 +217,8 @@ asn_build_int(data, datalength, type, intp, intsize)
     *datalength -= intsize;
     mask = 0xFF << (8 * (sizeof(int32) - 1));
     /* mask is 0xFF000000 on a big-endian machine */
-    while(intsize--){
-       *data++ = (u_char)((integer & mask) >> (8 * (sizeof(int32) - 1)));
+    while (intsize--) {
+       *data++ = (u_char) ((integer & mask) >> (8 * (sizeof(int32) - 1)));
        integer <<= 8;
     }
     return data;
@@ -237,11 +237,11 @@ asn_build_int(data, datalength, type, intp, intsize)
  */
 u_char *
 asn_build_unsigned_int(data, datalength, type, intp, intsize)
-    u_char *data;      /* IN - pointer to start of output buffer */
-    int    *datalength;/* IN/OUT - number of valid bytes left in buffer */
-    u_char         type;       /* IN - asn type of object */
-    u_long *intp;      /* IN - pointer to start of long integer */
-    int    intsize;    /* IN - size of *intp */
+     u_char *data;             /* IN - pointer to start of output buffer */
+     int *datalength;          /* IN/OUT - number of valid bytes left in buffer */
+     u_char type;              /* IN - asn type of object */
+     u_long *intp;             /* IN - pointer to start of long integer */
+     int intsize;              /* IN - size of *intp */
 {
 /*
  * ASN.1 integer ::= 0x02 asnlength byte {byte}*
@@ -251,14 +251,14 @@ asn_build_unsigned_int(data, datalength, type, intp, intsize)
     u_long mask;
     int add_null_byte = 0;
 
-    if (intsize != sizeof (long)) {
+    if (intsize != sizeof(long)) {
        ERROR("not long");
        return NULL;
     }
     integer = *intp;
     mask = 0xFF << (8 * (sizeof(int32) - 1));
     /* mask is 0xFF000000 on a big-endian machine */
-    if ((u_char)((integer & mask) >> (8 * (sizeof(int32) - 1))) & 0x80){
+    if ((u_char) ((integer & mask) >> (8 * (sizeof(int32) - 1))) & 0x80) {
        /* if MSB is set */
        add_null_byte = 1;
        intsize++;
@@ -270,7 +270,7 @@ asn_build_unsigned_int(data, datalength, type, intp, intsize)
      */
     mask = 0x1FF << ((8 * (sizeof(int32) - 1)) - 1);
     /* mask is 0xFF800000 on a big-endian machine */
-    while((((integer & mask) == 0) || ((integer & mask) == mask)) && intsize > 1){
+    while ((((integer & mask) == 0) || ((integer & mask) == mask)) && intsize > 1) {
        intsize--;
        integer <<= 8;
     }
@@ -280,14 +280,14 @@ asn_build_unsigned_int(data, datalength, type, intp, intsize)
     if (*datalength < intsize)
        return NULL;
     *datalength -= intsize;
-    if (add_null_byte == 1){
+    if (add_null_byte == 1) {
        *data++ = '\0';
        intsize--;
     }
     mask = 0xFF << (8 * (sizeof(int32) - 1));
     /* mask is 0xFF000000 on a big-endian machine */
-    while(intsize--){
-       *data++ = (u_char)((integer & mask) >> (8 * (sizeof(int32) - 1)));
+    while (intsize--) {
+       *data++ = (u_char) ((integer & mask) >> (8 * (sizeof(int32) - 1)));
        integer <<= 8;
     }
     return data;
@@ -308,11 +308,11 @@ asn_build_unsigned_int(data, datalength, type, intp, intsize)
  */
 u_char *
 asn_parse_string(data, datalength, type, string, strlength)
-    u_char         *data;          /* IN - pointer to start of object */
-    int    *datalength;    /* IN/OUT - number of valid bytes left in buffer */
-    u_char         *type;          /* OUT - asn type of object */
-    u_char         *string;        /* IN/OUT - pointer to start of output buffer */
-    int    *strlength;     /* IN/OUT - size of output buffer */
+     u_char *data;             /* IN - pointer to start of object */
+     int *datalength;          /* IN/OUT - number of valid bytes left in buffer */
+     u_char *type;             /* OUT - asn type of object */
+     u_char *string;           /* IN/OUT - pointer to start of output buffer */
+     int *strlength;           /* IN/OUT - size of output buffer */
 {
 /*
  * ASN.1 octet string ::= primstring | cmpdstring
@@ -320,23 +320,23 @@ asn_parse_string(data, datalength, type, string, strlength)
  * cmpdstring ::= 0x24 asnlength string {string}*
  */
     u_char *bufp = data;
-    u_long         asn_length;
+    u_long asn_length;
 
     *type = *bufp++;
     bufp = asn_parse_length(bufp, &asn_length);
     if (bufp == NULL)
        return NULL;
-    if (asn_length + (bufp - data) > *datalength){
+    if (asn_length + (bufp - data) > *datalength) {
        ERROR("overflow of message");
        return NULL;
     }
-    if (asn_length > *strlength){
+    if (asn_length > *strlength) {
        ERROR("I don't support such long strings");
        return NULL;
     }
-    bcopy((char *)bufp, (char *)string, (int)asn_length);
-    *strlength = (int)asn_length;
-    *datalength -= (int)asn_length + (bufp - data);
+    bcopy((char *) bufp, (char *) string, (int) asn_length);
+    *strlength = (int) asn_length;
+    *datalength -= (int) asn_length + (bufp - data);
     return bufp + asn_length;
 }
 
@@ -353,11 +353,11 @@ asn_parse_string(data, datalength, type, string, strlength)
  */
 u_char *
 asn_build_string(data, datalength, type, string, strlength)
-    u_char         *data;          /* IN - pointer to start of object */
-    int    *datalength;    /* IN/OUT - number of valid bytes left in buffer */
-    u_char         type;           /* IN - ASN type of string */
-    u_char         *string;        /* IN - pointer to start of input buffer */
-    int    strlength;      /* IN - size of input buffer */
+     u_char *data;             /* IN - pointer to start of object */
+     int *datalength;          /* IN/OUT - number of valid bytes left in buffer */
+     u_char type;              /* IN - ASN type of string */
+     u_char *string;           /* IN - pointer to start of input buffer */
+     int strlength;            /* IN - size of input buffer */
 {
 /*
  * ASN.1 octet string ::= primstring | cmpdstring
@@ -370,7 +370,7 @@ asn_build_string(data, datalength, type, string, strlength)
        return NULL;
     if (*datalength < strlength)
        return NULL;
-    bcopy((char *)string, (char *)data, strlength);
+    bcopy((char *) string, (char *) data, strlength);
     *datalength -= strlength;
     return data + strlength;
 }
@@ -387,9 +387,9 @@ asn_build_string(data, datalength, type, string, strlength)
  */
 u_char *
 asn_parse_header(data, datalength, type)
-    u_char         *data;      /* IN - pointer to start of object */
-    int                    *datalength;/* IN/OUT - number of valid bytes left in buffer */
-    u_char         *type;      /* OUT - ASN type of object */
+     u_char *data;             /* IN - pointer to start of object */
+     int *datalength;          /* IN/OUT - number of valid bytes left in buffer */
+     u_char *type;             /* OUT - ASN type of object */
 {
     u_char *bufp = data;
     int header_len;
@@ -398,9 +398,8 @@ asn_parse_header(data, datalength, type)
     if (*datalength <= 0) {
        return NULL;
     }
-
     /* this only works on data types < 30, i.e. no extension octets */
-    if (IS_EXTENSION_ID(*bufp)){
+    if (IS_EXTENSION_ID(*bufp)) {
        ERROR("can't process ID >= 30");
        return NULL;
     }
@@ -409,11 +408,11 @@ asn_parse_header(data, datalength, type)
     if (bufp == NULL)
        return NULL;
     header_len = bufp - data;
-    if (header_len + asn_length > *datalength){
+    if (header_len + asn_length > *datalength) {
        ERROR("asn length too long");
        return NULL;
     }
-    *datalength = (int)asn_length;
+    *datalength = (int) asn_length;
     return bufp;
 }
 
@@ -432,17 +431,17 @@ asn_parse_header(data, datalength, type)
  */
 u_char *
 asn_build_header(data, datalength, type, length)
-    u_char *data;      /* IN - pointer to start of object */
-    int                    *datalength;/* IN/OUT - number of valid bytes left in buffer */
-    u_char         type;       /* IN - ASN type of object */
-    int                    length;     /* IN - length of object */
+     u_char *data;             /* IN - pointer to start of object */
+     int *datalength;          /* IN/OUT - number of valid bytes left in buffer */
+     u_char type;              /* IN - ASN type of object */
+     int length;               /* IN - length of object */
 {
     if (*datalength < 1)
        return NULL;
     *data++ = type;
     (*datalength)--;
     return asn_build_length(data, datalength, length);
-    
+
 }
 
 /*
@@ -460,20 +459,20 @@ asn_build_header(data, datalength, type, length)
  */
 u_char *
 asn_build_sequence(data, datalength, type, length)
-    u_char *data;      /* IN - pointer to start of object */
-    int                    *datalength;/* IN/OUT - number of valid bytes left in buffer */
-    u_char         type;       /* IN - ASN type of object */
-    int                    length;     /* IN - length of object */
+     u_char *data;             /* IN - pointer to start of object */
+     int *datalength;          /* IN/OUT - number of valid bytes left in buffer */
+     u_char type;              /* IN - ASN type of object */
+     int length;               /* IN - length of object */
 {
     *datalength -= 4;
-    if (*datalength < 0){
+    if (*datalength < 0) {
        *datalength += 4;       /* fix up before punting */
        return NULL;
     }
     *data++ = type;
-    *data++ = (u_char)(0x02 | ASN_LONG_LEN);
-    *data++ = (u_char)((length >> 8) & 0xFF);
-    *data++ = (u_char)(length & 0xFF);
+    *data++ = (u_char) (0x02 | ASN_LONG_LEN);
+    *data++ = (u_char) ((length >> 8) & 0xFF);
+    *data++ = (u_char) (length & 0xFF);
     return data;
 }
 
@@ -487,63 +486,63 @@ asn_build_sequence(data, datalength, type, length)
  */
 u_char *
 asn_parse_length(data, length)
-    u_char  *data;     /* IN - pointer to start of length field */
-    u_long  *length;   /* OUT - value of length field */
+     u_char *data;             /* IN - pointer to start of length field */
+     u_long *length;           /* OUT - value of length field */
 {
     u_char lengthbyte = *data;
 
     *length = 0;
-    if (lengthbyte & ASN_LONG_LEN){
+    if (lengthbyte & ASN_LONG_LEN) {
        lengthbyte &= ~ASN_LONG_LEN;    /* turn MSb off */
-       if (lengthbyte == 0){
+       if (lengthbyte == 0) {
            ERROR("We don't support indefinite lengths");
            return NULL;
        }
-       if (lengthbyte > sizeof(long)){
+       if (lengthbyte > sizeof(long)) {
            ERROR("we can't support data lengths that long");
            return NULL;
        }
-       bcopy((char *)data + 1, (char *)length, (int)lengthbyte);
+       bcopy((char *) data + 1, (char *) length, (int) lengthbyte);
        /* XXX: is this useable on a 64bit platform ? */
        *length = ntohl(*length);
-       *length >>= (8 * ((sizeof (*length)) - lengthbyte));
+       *length >>= (8 * ((sizeof(*length)) - lengthbyte));
        return data + lengthbyte + 1;
-    } else { /* short asnlength */
-       *length = (long)lengthbyte;
+    } else {                   /* short asnlength */
+       *length = (long) lengthbyte;
        return data + 1;
     }
 }
 
 u_char *
 asn_build_length(data, datalength, length)
-    u_char *data;      /* IN - pointer to start of object */
-    int                    *datalength;/* IN/OUT - number of valid bytes left in buffer */
-    int    length;     /* IN - length of object */
+     u_char *data;             /* IN - pointer to start of object */
+     int *datalength;          /* IN/OUT - number of valid bytes left in buffer */
+     int length;               /* IN - length of object */
 {
-    u_char    *start_data = data;
+    u_char *start_data = data;
 
     /* no indefinite lengths sent */
-    if (length < 0x80){
-       if (*datalength < 1){
+    if (length < 0x80) {
+       if (*datalength < 1) {
            ERROR("build_length");
            return NULL;
-       }           
-       *data++ = (u_char)length;
-    } else if (length <= 0xFF){
-       if (*datalength < 2){
+       }
+       *data++ = (u_char) length;
+    } else if (length <= 0xFF) {
+       if (*datalength < 2) {
            ERROR("build_length");
            return NULL;
-       }           
-       *data++ = (u_char)(0x01 | ASN_LONG_LEN);
-       *data++ = (u_char)length;
-    } else { /* 0xFF < length <= 0xFFFF */
-       if (*datalength < 3){
+       }
+       *data++ = (u_char) (0x01 | ASN_LONG_LEN);
+       *data++ = (u_char) length;
+    } else {                   /* 0xFF < length <= 0xFFFF */
+       if (*datalength < 3) {
            ERROR("build_length");
            return NULL;
-       }           
-       *data++ = (u_char)(0x02 | ASN_LONG_LEN);
-       *data++ = (u_char)((length >> 8) & 0xFF);
-       *data++ = (u_char)(length & 0xFF);
+       }
+       *data++ = (u_char) (0x02 | ASN_LONG_LEN);
+       *data++ = (u_char) ((length >> 8) & 0xFF);
+       *data++ = (u_char) (length & 0xFF);
     }
     *datalength -= (data - start_data);
     return data;
@@ -564,11 +563,11 @@ asn_build_length(data, datalength, length)
  */
 u_char *
 asn_parse_objid(data, datalength, type, objid, objidlength)
-    u_char         *data;          /* IN - pointer to start of object */
-    int                    *datalength;    /* IN/OUT - number of valid bytes left in buffer */
-    u_char         *type;          /* OUT - ASN type of object */
-    oid                    *objid;         /* IN/OUT - pointer to start of output buffer */
-    int                    *objidlength;     /* IN/OUT - number of sub-id's in objid */
+     u_char *data;             /* IN - pointer to start of object */
+     int *datalength;          /* IN/OUT - number of valid bytes left in buffer */
+     u_char *type;             /* OUT - ASN type of object */
+     oid *objid;               /* IN/OUT - pointer to start of output buffer */
+     int *objidlength;         /* IN/OUT - number of sub-id's in objid */
 {
 /*
  * ASN.1 objid ::= 0x06 asnlength subidentifier {subidentifier}*
@@ -579,54 +578,54 @@ asn_parse_objid(data, datalength, type, objid, objidlength)
     u_char *bufp = data;
     oid *oidp = objid + 1;
     u_long subidentifier;
-    long   length;
-    u_long         asn_length;
+    long length;
+    u_long asn_length;
 
     *type = *bufp++;
     bufp = asn_parse_length(bufp, &asn_length);
     if (bufp == NULL)
        return NULL;
-    if (asn_length + (bufp - data) > *datalength){
+    if (asn_length + (bufp - data) > *datalength) {
        ERROR("overflow of message");
        return NULL;
     }
-    *datalength -= (int)asn_length + (bufp - data);
+    *datalength -= (int) asn_length + (bufp - data);
 
     /* Handle invalid object identifier encodings of the form 06 00 robustly */
     if (asn_length == 0)
        objid[0] = objid[1] = 0;
 
     length = asn_length;
-    (*objidlength)--;  /* account for expansion of first byte */
-    while (length > 0 && (*objidlength)-- > 0){
+    (*objidlength)--;          /* account for expansion of first byte */
+    while (length > 0 && (*objidlength)-- > 0) {
        subidentifier = 0;
-       do {    /* shift and add in low order 7 bits */
-           subidentifier = (subidentifier << 7) + (*(u_char *)bufp & ~ASN_BIT8);
+       do {                    /* shift and add in low order 7 bits */
+           subidentifier = (subidentifier << 7) + (*(u_char *) bufp & ~ASN_BIT8);
            length--;
-       } while (*(u_char *)bufp++ & ASN_BIT8); /* last byte has high bit clear */
-       if (subidentifier > (u_long)MAX_SUBID){
+       } while (*(u_char *) bufp++ & ASN_BIT8);        /* last byte has high bit clear */
+       if (subidentifier > (u_long) MAX_SUBID) {
            ERROR("subidentifier too long");
            return NULL;
        }
-       *oidp++ = (oid)subidentifier;
+       *oidp++ = (oid) subidentifier;
     }
 
     /*
      * The first two subidentifiers are encoded into the first component
      * with the value (X * 40) + Y, where:
-     * X is the value of the first subidentifier.
+     *  X is the value of the first subidentifier.
      *  Y is the value of the second subidentifier.
      */
-    subidentifier = (u_long)objid[1];
-    if (subidentifier == 0x2B){
+    subidentifier = (u_long) objid[1];
+    if (subidentifier == 0x2B) {
        objid[0] = 1;
        objid[1] = 3;
     } else {
-       objid[1] = (u_char)(subidentifier % 40);
-       objid[0] = (u_char)((subidentifier - objid[1]) / 40);
+       objid[1] = (u_char) (subidentifier % 40);
+       objid[0] = (u_char) ((subidentifier - objid[1]) / 40);
     }
 
-    *objidlength = (int)(oidp - objid);
+    *objidlength = (int) (oidp - objid);
     return bufp;
 }
 
@@ -643,11 +642,11 @@ asn_parse_objid(data, datalength, type, objid, objidlength)
  */
 u_char *
 asn_build_objid(data, datalength, type, objid, objidlength)
-    u_char *data;          /* IN - pointer to start of object */
-    int                    *datalength;    /* IN/OUT - number of valid bytes left in buffer */
-    u_char         type;           /* IN - ASN type of object */
-    oid                    *objid;         /* IN - pointer to start of input buffer */
-    int                    objidlength;    /* IN - number of sub-id's in objid */
+     u_char *data;             /* IN - pointer to start of object */
+     int *datalength;          /* IN/OUT - number of valid bytes left in buffer */
+     u_char type;              /* IN - ASN type of object */
+     oid *objid;               /* IN - pointer to start of input buffer */
+     int objidlength;          /* IN - number of sub-id's in objid */
 {
 /*
  * ASN.1 objid ::= 0x06 asnlength subidentifier {subidentifier}*
@@ -658,11 +657,11 @@ asn_build_objid(data, datalength, type, objid, objidlength)
     u_char buf[MAX_OID_LEN];
     u_char *bp = buf;
     oid *op = objid;
-    int    asnlength;
+    int asnlength;
     u_long subid, mask, testmask;
     int bits, testbits;
 
-    if (objidlength < 2){
+    if (objidlength < 2) {
        *bp++ = 0;
        objidlength = 0;
     } else {
@@ -671,29 +670,29 @@ asn_build_objid(data, datalength, type, objid, objidlength)
        op += 2;
     }
 
-    while(objidlength-- > 0){
+    while (objidlength-- > 0) {
        subid = *op++;
-       if (subid < 127){ /* off by one? */
+       if (subid < 127) {      /* off by one? */
            *bp++ = subid;
        } else {
-           mask = 0x7F; /* handle subid == 0 case */
+           mask = 0x7F;        /* handle subid == 0 case */
            bits = 0;
            /* testmask *MUST* !!!! be of an unsigned type */
-           for(testmask = 0x7F, testbits = 0; testmask != 0;
-               testmask <<= 7, testbits += 7){
-               if (subid & testmask){  /* if any bits set */
+           for (testmask = 0x7F, testbits = 0; testmask != 0;
+               testmask <<= 7, testbits += 7) {
+               if (subid & testmask) {         /* if any bits set */
                    mask = testmask;
                    bits = testbits;
                }
            }
            /* mask can't be zero here */
-           for(;mask != 0x7F; mask >>= 7, bits -= 7){
+           for (; mask != 0x7F; mask >>= 7, bits -= 7) {
                /* fix a mask that got truncated above */
-               if (mask == 0x1E00000)  
+               if (mask == 0x1E00000)
                    mask = 0xFE00000;
-               *bp++ = (u_char)(((subid & mask) >> bits) | ASN_BIT8);
+               *bp++ = (u_char) (((subid & mask) >> bits) | ASN_BIT8);
            }
-           *bp++ = (u_char)(subid & mask);
+           *bp++ = (u_char) (subid & mask);
        }
     }
     asnlength = bp - buf;
@@ -702,7 +701,7 @@ asn_build_objid(data, datalength, type, objid, objidlength)
        return NULL;
     if (*datalength < asnlength)
        return NULL;
-    bcopy((char *)buf, (char *)data, asnlength);
+    bcopy((char *) buf, (char *) data, asnlength);
     *datalength -= asnlength;
     return data + asnlength;
 }
@@ -719,21 +718,21 @@ asn_build_objid(data, datalength, type, objid, objidlength)
  */
 u_char *
 asn_parse_null(data, datalength, type)
-    u_char         *data;          /* IN - pointer to start of object */
-    int                    *datalength;    /* IN/OUT - number of valid bytes left in buffer */
-    u_char         *type;          /* OUT - ASN type of object */
+     u_char *data;             /* IN - pointer to start of object */
+     int *datalength;          /* IN/OUT - number of valid bytes left in buffer */
+     u_char *type;             /* OUT - ASN type of object */
 {
 /*
  * ASN.1 null ::= 0x05 0x00
  */
-    u_char   *bufp = data;
-    u_long         asn_length;
+    u_char *bufp = data;
+    u_long asn_length;
 
     *type = *bufp++;
     bufp = asn_parse_length(bufp, &asn_length);
     if (bufp == NULL)
        return NULL;
-    if (asn_length != 0){
+    if (asn_length != 0) {
        ERROR("Malformed NULL");
        return NULL;
     }
@@ -754,9 +753,9 @@ asn_parse_null(data, datalength, type)
  */
 u_char *
 asn_build_null(data, datalength, type)
-    u_char         *data;          /* IN - pointer to start of object */
-    int                    *datalength;    /* IN/OUT - number of valid bytes left in buffer */
-    u_char         type;           /* IN - ASN type of object */
+     u_char *data;             /* IN - pointer to start of object */
+     int *datalength;          /* IN/OUT - number of valid bytes left in buffer */
+     u_char type;              /* IN - ASN type of object */
 {
 /*
  * ASN.1 null ::= 0x05 0x00
@@ -778,41 +777,41 @@ asn_build_null(data, datalength, type)
  */
 u_char *
 asn_parse_bitstring(data, datalength, type, string, strlength)
-    u_char         *data;          /* IN - pointer to start of object */
-    int    *datalength;    /* IN/OUT - number of valid bytes left in buffer */
-    u_char         *type;          /* OUT - asn type of object */
-    u_char         *string;        /* IN/OUT - pointer to start of output buffer */
-    int    *strlength;     /* IN/OUT - size of output buffer */
+     u_char *data;             /* IN - pointer to start of object */
+     int *datalength;          /* IN/OUT - number of valid bytes left in buffer */
+     u_char *type;             /* OUT - asn type of object */
+     u_char *string;           /* IN/OUT - pointer to start of output buffer */
+     int *strlength;           /* IN/OUT - size of output buffer */
 {
 /*
  * bitstring ::= 0x03 asnlength unused {byte}*
  */
     u_char *bufp = data;
-    u_long         asn_length;
+    u_long asn_length;
 
     *type = *bufp++;
     bufp = asn_parse_length(bufp, &asn_length);
     if (bufp == NULL)
        return NULL;
-    if (asn_length + (bufp - data) > *datalength){
+    if (asn_length + (bufp - data) > *datalength) {
        ERROR("overflow of message");
        return NULL;
     }
-    if (asn_length > *strlength){
+    if (asn_length > *strlength) {
        ERROR("I don't support such long bitstrings");
        return NULL;
     }
-    if (asn_length < 1){
+    if (asn_length < 1) {
        ERROR("Invalid bitstring");
        return NULL;
     }
-    if (/** *bufp < 0 || **/ *bufp > 7){
+    if ( /** *bufp < 0 || **/ *bufp > 7) {
        ERROR("Invalid bitstring");
        return NULL;
     }
-    bcopy((char *)bufp, (char *)string, (int)asn_length);
-    *strlength = (int)asn_length;
-    *datalength -= (int)asn_length + (bufp - data);
+    bcopy((char *) bufp, (char *) string, (int) asn_length);
+    *strlength = (int) asn_length;
+    *datalength -= (int) asn_length + (bufp - data);
     return bufp + asn_length;
 }
 
@@ -830,16 +829,16 @@ asn_parse_bitstring(data, datalength, type, string, strlength)
  */
 u_char *
 asn_build_bitstring(data, datalength, type, string, strlength)
-    u_char         *data;          /* IN - pointer to start of object */
-    int    *datalength;    /* IN/OUT - number of valid bytes left in buffer */
-    u_char         type;           /* IN - ASN type of string */
-    u_char         *string;        /* IN - pointer to start of input buffer */
-    int    strlength;      /* IN - size of input buffer */
+     u_char *data;             /* IN - pointer to start of object */
+     int *datalength;          /* IN/OUT - number of valid bytes left in buffer */
+     u_char type;              /* IN - ASN type of string */
+     u_char *string;           /* IN - pointer to start of input buffer */
+     int strlength;            /* IN - size of input buffer */
 {
 /*
  * ASN.1 bit string ::= 0x03 asnlength unused {byte}*
  */
-    if (strlength < 1 || /** *string < 0 || **/ *string > 7){
+    if (strlength < 1 || /** *string < 0 || **/ *string > 7) {
        ERROR("Building invalid bitstring");
        return NULL;
     }
@@ -848,7 +847,7 @@ asn_build_bitstring(data, datalength, type, string, strlength)
        return NULL;
     if (*datalength < strlength)
        return NULL;
-    bcopy((char *)string, (char *)data, strlength);
+    bcopy((char *) string, (char *) data, strlength);
     *datalength -= strlength;
     return data + strlength;
 }
@@ -867,45 +866,45 @@ asn_build_bitstring(data, datalength, type, string, strlength)
  */
 u_char *
 asn_parse_unsigned_int64(data, datalength, type, cp, countersize)
-    u_char         *data;      /* IN - pointer to start of object */
-    int            *datalength;/* IN/OUT - number of valid bytes left in buffer */
-    u_char                 *type;      /* OUT - asn type of object */
-    struct counter64       *cp;        /* IN/OUT -pointer to counter struct */
-    int                            countersize;/* IN - size of output buffer */
+     u_char *data;             /* IN - pointer to start of object */
+     int *datalength;          /* IN/OUT - number of valid bytes left in buffer */
+     u_char *type;             /* OUT - asn type of object */
+     struct counter64 *cp;     /* IN/OUT -pointer to counter struct */
+     int countersize;          /* IN - size of output buffer */
 {
 /*
  * ASN.1 integer ::= 0x02 asnlength byte {byte}*
  */
     u_char *bufp = data;
-    u_long         asn_length;
+    u_long asn_length;
     u_long low = 0, high = 0;
     int intsize = 4;
-    
-    if (countersize != sizeof(struct counter64)){
+
+    if (countersize != sizeof(struct counter64)) {
        ERROR("not counter64 size");
        return NULL;
     }
     *type = *bufp++;
     bufp = asn_parse_length(bufp, &asn_length);
-    if (bufp == NULL){
+    if (bufp == NULL) {
        ERROR("bad length");
        return NULL;
     }
-    if (asn_length + (bufp - data) > *datalength){
+    if (asn_length + (bufp - data) > *datalength) {
        ERROR("overflow of message");
        return NULL;
     }
     if ((asn_length > (intsize * 2 + 1)) ||
-       ((asn_length == (intsize * 2) + 1) && *bufp != 0x00)){
+       ((asn_length == (intsize * 2) + 1) && *bufp != 0x00)) {
        ERROR("I don't support such large integers");
        return NULL;
     }
-    *datalength -= (int)asn_length + (bufp - data);
-    if (*bufp & 0x80){
-       low = -1; /* integer is negative */
+    *datalength -= (int) asn_length + (bufp - data);
+    if (*bufp & 0x80) {
+       low = -1;               /* integer is negative */
        high = -1;
     }
-    while(asn_length--){
+    while (asn_length--) {
        high = (high << 8) | ((low & 0xFF000000) >> 24);
        low = (low << 8) | *bufp++;
     }
@@ -927,11 +926,11 @@ asn_parse_unsigned_int64(data, datalength, type, cp, countersize)
  */
 u_char *
 asn_build_unsigned_int64(data, datalength, type, cp, countersize)
-    u_char *data;      /* IN - pointer to start of output buffer */
-    int    *datalength;/* IN/OUT - number of valid bytes left in buffer */
-    u_char         type;       /* IN - asn type of object */
-    struct counter64 *cp;      /* IN - pointer to counter struct */
-    int    countersize; /* IN - size of *intp */
+     u_char *data;             /* IN - pointer to start of output buffer */
+     int *datalength;          /* IN/OUT - number of valid bytes left in buffer */
+     u_char type;              /* IN - asn type of object */
+     struct counter64 *cp;     /* IN - pointer to counter struct */
+     int countersize;          /* IN - size of *intp */
 {
 /*
  * ASN.1 integer ::= 0x02 asnlength byte {byte}*
@@ -942,7 +941,7 @@ asn_build_unsigned_int64(data, datalength, type, cp, countersize)
     int add_null_byte = 0;
     int intsize;
 
-    if (countersize != sizeof (struct counter64)) {
+    if (countersize != sizeof(struct counter64)) {
        ERROR("not counter64 size");
        return NULL;
     }
@@ -951,7 +950,7 @@ asn_build_unsigned_int64(data, datalength, type, cp, countersize)
     high = cp->high;
     mask = 0xFF << (8 * (sizeof(int32) - 1));
     /* mask is 0xFF000000 on a big-endian machine */
-    if ((u_char)((high & mask) >> (8 * (sizeof(int32) - 1))) & 0x80) {
+    if ((u_char) ((high & mask) >> (8 * (sizeof(int32) - 1))) & 0x80) {
        /* if MSB is set */
        add_null_byte = 1;
        intsize++;
@@ -964,8 +963,8 @@ asn_build_unsigned_int64(data, datalength, type, cp, countersize)
      */
     mask2 = 0x1FF << ((8 * (sizeof(int32) - 1)) - 1);
     /* mask2 is 0xFF800000 on a big-endian machine */
-    while((((high & mask2) == 0) || ((high & mask2) == mask2))
-         && intsize > 1){
+    while ((((high & mask2) == 0) || ((high & mask2) == mask2))
+       && intsize > 1) {
        intsize--;
        high = (high << 8)
            | ((low & mask) >> (8 * (sizeof(int32) - 1)));
@@ -977,18 +976,16 @@ asn_build_unsigned_int64(data, datalength, type, cp, countersize)
     if (*datalength < intsize)
        return NULL;
     *datalength -= intsize;
-    if (add_null_byte == 1){
+    if (add_null_byte == 1) {
        *data++ = '\0';
        intsize--;
     }
-    while(intsize--){
-       *data++ = (u_char)((high & mask) >> (8 * (sizeof(int32) - 1)));
+    while (intsize--) {
+       *data++ = (u_char) ((high & mask) >> (8 * (sizeof(int32) - 1)));
        high = (high << 8)
            | ((low & mask) >> (8 * (sizeof(int32) - 1)));
        low <<= 8;
-       
+
     }
     return data;
 }
-
-
index 98a0f8a90850bd1e6f9cf23f0066a8ab970784c5..11e168f35083a98cc7cb65d7e2345add0190471c 100644 (file)
@@ -1,3 +1,4 @@
+
 /**********************************************************************
        Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University
 
@@ -19,20 +20,9 @@ WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 SOFTWARE.
 ******************************************************************/
-#include <stdio.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <sys/time.h>
 
 #include "squid.h"
 
-#ifdef linux
-#include <stdlib.h>
-#include <string.h>
-#endif
-
-
 #include "asn1.h"
 #include "snmp.h"
 #include "snmp_impl.h"
@@ -54,10 +44,10 @@ static struct tree *get_symbol();
 
 static char *
 uptimeString(timeticks, buf)
-    u_long timeticks;
-    char *buf;
+     u_long timeticks;
+     char *buf;
 {
-    int        seconds, minutes, hours, days;
+    int seconds, minutes, hours, days;
 
     timeticks /= 100;
     days = timeticks / (60 * 60 * 24);
@@ -69,24 +59,24 @@ uptimeString(timeticks, buf)
     minutes = timeticks / 60;
     seconds = timeticks % 60;
 
-    if (days == 0){
-       snprintf(buf,32, "%d:%02d:%02d", hours, minutes, seconds);
+    if (days == 0) {
+       snprintf(buf, 32, "%d:%02d:%02d", hours, minutes, seconds);
     } else if (days == 1) {
-       snprintf(buf,32,  "%d day, %d:%02d:%02d", days, hours, minutes, seconds);
+       snprintf(buf, 32, "%d day, %d:%02d:%02d", days, hours, minutes, seconds);
     } else {
-       snprintf(buf,32, "%d days, %d:%02d:%02d", days, hours, minutes, seconds);
+       snprintf(buf, 32, "%d days, %d:%02d:%02d", days, hours, minutes, seconds);
     }
     return buf;
 }
 
 static void
 sprint_hexstring(buf, cp, len)
-    char *buf;
-    u_char  *cp;
-    int            len;
+     char *buf;
+     u_char *cp;
+     int len;
 {
 
-    for(; len >= 16; len -= 16){
+    for (; len >= 16; len -= 16) {
        sprintf(buf, "%02X %02X %02X %02X %02X %02X %02X %02X ", cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
        buf += strlen(buf);
        cp += 8;
@@ -94,7 +84,7 @@ sprint_hexstring(buf, cp, len)
        buf += strlen(buf);
        cp += 8;
     }
-    for(; len > 0; len--){
+    for (; len > 0; len--) {
        sprintf(buf, "%02X ", *cp++);
        buf += strlen(buf);
     }
@@ -103,14 +93,14 @@ sprint_hexstring(buf, cp, len)
 
 static void
 sprint_asciistring(buf, cp, len)
-    char *buf;
-    u_char  *cp;
-    int            len;
+     char *buf;
+     u_char *cp;
+     int len;
 {
-    int        x;
+    int x;
 
-    for(x = 0; x < len; x++){
-       if (isprint(*cp)){
+    for (x = 0; x < len; x++) {
+       if (isprint(*cp)) {
            *buf++ = *cp++;
        } else {
            *buf++ = '.';
@@ -127,32 +117,32 @@ sprint_asciistring(buf, cp, len)
 #ifdef UNUSED
 int
 read_rawobjid(input, output, out_len)
-    char *input;
-    oid *output;
-    int        *out_len;
+     char *input;
+     oid *output;
+     int *out_len;
 {
-    char    buf[12], *cp;
-    oid            *op = output;
-    u_long  subid;
+    char buf[12], *cp;
+    oid *op = output;
+    u_long subid;
 
-    while(*input != '\0'){
+    while (*input != '\0') {
        if (!isdigit(*input))
            break;
        cp = buf;
-       while(isdigit(*input))
+       while (isdigit(*input))
            *cp++ = *input++;
        *cp = '\0';
        subid = atoi(buf);
-       if(subid > MAX_SUBID){
+       if (subid > MAX_SUBID) {
            fprintf(stderr, "sub-identifier too large: %s\n", buf);
            return 0;
        }
-       if((*out_len)-- <= 0){
+       if ((*out_len)-- <= 0) {
            fprintf(stderr, "object identifier too long\n");
            return 0;
        }
        *op++ = subid;
-       if(*input++ != '.')
+       if (*input++ != '.')
            break;
     }
     *out_len = op - output;
@@ -164,49 +154,49 @@ read_rawobjid(input, output, out_len)
 #endif /* UNUSED */
 
 /*
-  0
-  < 4
-  hex
-
-  0 ""
-  < 4 hex Hex: oo oo oo
-  < 4     "fgh" Hex: oo oo oo
-  > 4 hex Hex: oo oo oo oo oo oo oo oo
-  > 4     "this is a test"
-
 */
* 0
* < 4
* hex
+ * 
* 0 ""
* < 4 hex Hex: oo oo oo
* < 4     "fgh" Hex: oo oo oo
* > 4 hex Hex: oo oo oo oo oo oo oo oo
* > 4     "this is a test"
+ * 
+ */
 static void
 sprint_octet_string(buf, var, enums)
-    char *buf;
-    struct variable_list *var;
-    struct enum_list       *enums;
+     char *buf;
+     struct variable_list *var;
+     struct enum_list *enums;
 {
     int hex, x;
     u_char *cp;
 
-    if (var->type != ASN_OCTET_STR){
+    if (var->type != ASN_OCTET_STR) {
        sprintf(buf, "Wrong Type (should be OCTET STRING): ");
        buf += strlen(buf);
-       sprint_by_type(buf, var, (struct enum_list *)NULL);
+       sprint_by_type(buf, var, (struct enum_list *) NULL);
        return;
     }
     hex = 0;
-    for(cp = var->val.string, x = 0; x < var->val_len; x++, cp++){
+    for (cp = var->val.string, x = 0; x < var->val_len; x++, cp++) {
        if (!(isprint(*cp) || isspace(*cp)))
            hex = 1;
     }
-    if (var->val_len == 0){
+    if (var->val_len == 0) {
        strcpy(buf, "\"\"");
        return;
     }
-    if (!hex){
+    if (!hex) {
        *buf++ = '"';
        sprint_asciistring(buf, var->val.string, var->val_len);
        buf += strlen(buf);
        *buf++ = '"';
        *buf = '\0';
     }
-    if (hex || var->val_len <= 4){
+    if (hex || var->val_len <= 4) {
        sprintf(buf, " Hex: ");
        buf += strlen(buf);
        sprint_hexstring(buf, var->val.string, var->val_len);
@@ -215,15 +205,15 @@ sprint_octet_string(buf, var, enums)
 
 static void
 sprint_opaque(buf, var, enums)
-    char *buf;
-    struct variable_list *var;
-    struct enum_list       *enums;
+     char *buf;
+     struct variable_list *var;
+     struct enum_list *enums;
 {
 
-    if (var->type != OPAQUE){
+    if (var->type != OPAQUE) {
        sprintf(buf, "Wrong Type (should be Opaque): ");
        buf += strlen(buf);
-       sprint_by_type(buf, var, (struct enum_list *)NULL);
+       sprint_by_type(buf, var, (struct enum_list *) NULL);
        return;
     }
     sprintf(buf, "OPAQUE: ");
@@ -233,55 +223,55 @@ sprint_opaque(buf, var, enums)
 
 static void
 sprint_object_identifier(buf, var, enums)
-    char *buf;
-    struct variable_list *var;
-    struct enum_list       *enums;
+     char *buf;
+     struct variable_list *var;
+     struct enum_list *enums;
 {
-    if (var->type != ASN_OBJECT_ID){
+    if (var->type != ASN_OBJECT_ID) {
        sprintf(buf, "Wrong Type (should be OBJECT IDENTIFIER): ");
        buf += strlen(buf);
-       sprint_by_type(buf, var, (struct enum_list *)NULL);
+       sprint_by_type(buf, var, (struct enum_list *) NULL);
        return;
     }
     sprintf(buf, "OID: ");
     buf += strlen(buf);
-    sprint_objid(buf, (oid *)(var->val.objid), var->val_len / sizeof(oid));
+    sprint_objid(buf, (oid *) (var->val.objid), var->val_len / sizeof(oid));
 }
 
 static void
 sprint_timeticks(buf, var, enums)
-    char *buf;
-    struct variable_list *var;
-    struct enum_list       *enums;
+     char *buf;
+     struct variable_list *var;
+     struct enum_list *enums;
 {
     char timebuf[32];
 
-    if (var->type != TIMETICKS){
+    if (var->type != TIMETICKS) {
        sprintf(buf, "Wrong Type (should be Timeticks): ");
        buf += strlen(buf);
-       sprint_by_type(buf, var, (struct enum_list *)NULL);
+       sprint_by_type(buf, var, (struct enum_list *) NULL);
        return;
     }
-    sprintf(buf, "Timeticks: (%ld) %s", *(u_long *)(var->val.integer), 
-           uptimeString(*(u_long *)(var->val.integer), timebuf));
+    sprintf(buf, "Timeticks: (%ld) %s", *(u_long *) (var->val.integer),
+       uptimeString(*(u_long *) (var->val.integer), timebuf));
 }
 
 static void
 sprint_integer(buf, var, enums)
-    char *buf;
-    struct variable_list *var;
-    struct enum_list       *enums;
+     char *buf;
+     struct variable_list *var;
+     struct enum_list *enums;
 {
-    char    *enum_string = NULL;
+    char *enum_string = NULL;
 
-    if (var->type != ASN_INTEGER){
+    if (var->type != ASN_INTEGER) {
        sprintf(buf, "Wrong Type (should be INTEGER): ");
        buf += strlen(buf);
-       sprint_by_type(buf, var, (struct enum_list *)NULL);
+       sprint_by_type(buf, var, (struct enum_list *) NULL);
        return;
     }
     for (; enums; enums = enums->next)
-       if (enums->value == *var->val.integer){
+       if (enums->value == *var->val.integer) {
            enum_string = enums->label;
            break;
        }
@@ -293,20 +283,20 @@ sprint_integer(buf, var, enums)
 
 static void
 sprint_uinteger(buf, var, enums)
-    char *buf;
-    struct variable_list *var;
-    struct enum_list       *enums;
+     char *buf;
+     struct variable_list *var;
+     struct enum_list *enums;
 {
-    char    *enum_string = NULL;
+    char *enum_string = NULL;
 
-    if (var->type != UINTEGER){
+    if (var->type != UINTEGER) {
        sprintf(buf, "Wrong Type (should be UInteger32): ");
        buf += strlen(buf);
-       sprint_by_type(buf, var, (struct enum_list *)NULL);
+       sprint_by_type(buf, var, (struct enum_list *) NULL);
        return;
     }
     for (; enums; enums = enums->next)
-       if (enums->value == *var->val.integer){
+       if (enums->value == *var->val.integer) {
            enum_string = enums->label;
            break;
        }
@@ -318,14 +308,14 @@ sprint_uinteger(buf, var, enums)
 
 static void
 sprint_gauge(buf, var, enums)
-    char *buf;
-    struct variable_list *var;
-    struct enum_list       *enums;
+     char *buf;
+     struct variable_list *var;
+     struct enum_list *enums;
 {
-    if (var->type != GAUGE){
+    if (var->type != GAUGE) {
        sprintf(buf, "Wrong Type (should be Gauge): ");
        buf += strlen(buf);
-       sprint_by_type(buf, var, (struct enum_list *)NULL);
+       sprint_by_type(buf, var, (struct enum_list *) NULL);
        return;
     }
     sprintf(buf, "Gauge: %lu", *var->val.integer);
@@ -333,14 +323,14 @@ sprint_gauge(buf, var, enums)
 
 static void
 sprint_counter(buf, var, enums)
-    char *buf;
-    struct variable_list *var;
-    struct enum_list       *enums;
+     char *buf;
+     struct variable_list *var;
+     struct enum_list *enums;
 {
-    if (var->type != COUNTER){
+    if (var->type != COUNTER) {
        sprintf(buf, "Wrong Type (should be Counter): ");
        buf += strlen(buf);
-       sprint_by_type(buf, var, (struct enum_list *)NULL);
+       sprint_by_type(buf, var, (struct enum_list *) NULL);
        return;
     }
     sprintf(buf, "%lu", *var->val.integer);
@@ -348,18 +338,18 @@ sprint_counter(buf, var, enums)
 
 static void
 sprint_networkaddress(buf, var, enums)
-    char *buf;
-    struct variable_list *var;
-    struct enum_list       *enums;
+     char *buf;
+     struct variable_list *var;
+     struct enum_list *enums;
 {
     int x, len;
     u_char *cp;
 
     sprintf(buf, "Network Address: ");
     buf += strlen(buf);
-    cp = var->val.string;    
+    cp = var->val.string;
     len = var->val_len;
-    for(x = 0; x < len; x++){
+    for (x = 0; x < len; x++) {
        sprintf(buf, "%02X", *cp++);
        buf += strlen(buf);
        if (x < (len - 1))
@@ -369,33 +359,33 @@ sprint_networkaddress(buf, var, enums)
 
 static void
 sprint_ipaddress(buf, var, enums)
-    char *buf;
-    struct variable_list *var;
-    struct enum_list       *enums;
+     char *buf;
+     struct variable_list *var;
+     struct enum_list *enums;
 {
     u_char *ip;
 
-    if (var->type != IPADDRESS){
+    if (var->type != IPADDRESS) {
        sprintf(buf, "Wrong Type (should be Ipaddress): ");
        buf += strlen(buf);
-       sprint_by_type(buf, var, (struct enum_list *)NULL);
+       sprint_by_type(buf, var, (struct enum_list *) NULL);
        return;
     }
     ip = var->val.string;
-    sprintf(buf, "IpAddress: %d.%d.%d.%d",ip[0], ip[1], ip[2], ip[3]);
+    sprintf(buf, "IpAddress: %d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
 }
 
 #if 0
 static void
 sprint_unsigned_short(buf, var, enums)
-    char *buf;
-    struct variable_list *var;
-    struct enum_list       *enums;
+     char *buf;
+     struct variable_list *var;
+     struct enum_list *enums;
 {
-    if (var->type != ASN_INTEGER){
+    if (var->type != ASN_INTEGER) {
        sprintf(buf, "Wrong Type (should be INTEGER): ");
        buf += strlen(buf);
-       sprint_by_type(buf, var, (struct enum_list *)NULL);
+       sprint_by_type(buf, var, (struct enum_list *) NULL);
        return;
     }
     sprintf(buf, "INT: %lu", *var->val.integer);
@@ -404,14 +394,14 @@ sprint_unsigned_short(buf, var, enums)
 
 static void
 sprint_null(buf, var, enums)
-    char *buf;
-    struct variable_list *var;
-    struct enum_list       *enums;
+     char *buf;
+     struct variable_list *var;
+     struct enum_list *enums;
 {
-    if (var->type != ASN_NULL){
+    if (var->type != ASN_NULL) {
        sprintf(buf, "Wrong Type (should be NULL): ");
        buf += strlen(buf);
-       sprint_by_type(buf, var, (struct enum_list *)NULL);
+       sprint_by_type(buf, var, (struct enum_list *) NULL);
        return;
     }
     sprintf(buf, "NULL");
@@ -419,18 +409,18 @@ sprint_null(buf, var, enums)
 
 static void
 sprint_bitstring(buf, var, enums)
-    char *buf;
-    struct variable_list *var;
-    struct enum_list       *enums;
+     char *buf;
+     struct variable_list *var;
+     struct enum_list *enums;
 {
     int len, bit;
     u_char *cp;
     char *enum_string;
 
-    if (var->type != ASN_BIT_STR){
+    if (var->type != ASN_BIT_STR) {
        sprintf(buf, "Wrong Type (should be BIT STRING): ");
        buf += strlen(buf);
-       sprint_by_type(buf, var, (struct enum_list *)NULL);
+       sprint_by_type(buf, var, (struct enum_list *) NULL);
        return;
     }
     sprintf(buf, "BIT_STRING: ");
@@ -439,12 +429,12 @@ sprint_bitstring(buf, var, enums)
     buf += strlen(buf);
 
     cp = var->val.bitstring + 1;
-    for(len = 0; len < var->val_len - 1; len++){
-       for(bit = 0; bit < 8; bit++){
-           if (*cp & (0x80 >> bit)){
+    for (len = 0; len < var->val_len - 1; len++) {
+       for (bit = 0; bit < 8; bit++) {
+           if (*cp & (0x80 >> bit)) {
                enum_string = NULL;
                for (; enums; enums = enums->next)
-                   if (enums->value == (len * 8) + bit){
+                   if (enums->value == (len * 8) + bit) {
                        enum_string = enums->label;
                        break;
                    }
@@ -455,20 +445,20 @@ sprint_bitstring(buf, var, enums)
                buf += strlen(buf);
            }
        }
-       cp ++;      
+       cp++;
     }
 }
 
 static void
 sprint_nsapaddress(buf, var, enums)
-    char *buf;
-    struct variable_list *var;
-    struct enum_list       *enums;
+     char *buf;
+     struct variable_list *var;
+     struct enum_list *enums;
 {
-    if (var->type != NSAP){
+    if (var->type != NSAP) {
        sprintf(buf, "Wrong Type (should be NsapAddress): ");
        buf += strlen(buf);
-       sprint_by_type(buf, var, (struct enum_list *)NULL);
+       sprint_by_type(buf, var, (struct enum_list *) NULL);
        return;
     }
     sprintf(buf, "NsapAddress: ");
@@ -478,33 +468,33 @@ sprint_nsapaddress(buf, var, enums)
 
 static void
 sprint_counter64(buf, var, enums)
-    char *buf;
-    struct variable_list *var;
-    struct enum_list       *enums;
+     char *buf;
+     struct variable_list *var;
+     struct enum_list *enums;
 {
-    if (var->type != COUNTER64){
+    if (var->type != COUNTER64) {
        sprintf(buf, "Wrong Type (should be Counter64): ");
        buf += strlen(buf);
-       sprint_by_type(buf, var, (struct enum_list *)NULL);
+       sprint_by_type(buf, var, (struct enum_list *) NULL);
        return;
     }
 /* XXX */
     sprintf(buf, "Counter64: ");
     buf += strlen(buf);
-    
+
     sprint_hexstring(buf, &var->val.counter64->high,
-                    sizeof(var->val.counter64->high));
+       sizeof(var->val.counter64->high));
     buf += strlen(buf);
     sprint_hexstring(buf, &var->val.counter64->low,
-                    sizeof(var->val.counter64->low));
+       sizeof(var->val.counter64->low));
 }
 
 
 static void
 sprint_unknowntype(buf, var, enums)
-    char *buf;
-    struct variable_list *var;
-    struct enum_list       *enums;
+     char *buf;
+     struct variable_list *var;
+     struct enum_list *enums;
 {
 /*    sprintf(buf, "Variable has bad type"); */
     sprint_by_type(buf, var, NULL);
@@ -512,59 +502,60 @@ sprint_unknowntype(buf, var, enums)
 
 static void
 sprint_badtype(buf, var, enums)
-    char *buf;
-    struct variable_list *var;
-    struct enum_list       *enums;
+     char *buf;
+     struct variable_list *var;
+     struct enum_list *enums;
 {
     sprintf(buf, "Variable has bad type");
 }
 
 static void
 sprint_by_type(buf, var, enums)
-    char *buf;
-    struct variable_list *var;
-    struct enum_list       *enums;
+     char *buf;
+     struct variable_list *var;
+     struct enum_list *enums;
 {
-    switch (var->type){
-       case ASN_INTEGER:
-           sprint_integer(buf, var, enums);
-           break;
-       case ASN_OCTET_STR:
-           sprint_octet_string(buf, var, enums);
-           break;
-       case OPAQUE:
-           sprint_opaque(buf, var, enums);
-           break;
-       case ASN_OBJECT_ID:
-           sprint_object_identifier(buf, var, enums);
-           break;
-       case TIMETICKS:
-           sprint_timeticks(buf, var, enums);
-           break;
-       case GAUGE:
-           sprint_gauge(buf, var, enums);
-           break;
-       case COUNTER:
-           sprint_counter(buf, var, enums);
-           break;
-       case IPADDRESS:
-           sprint_ipaddress(buf, var, enums);
-           break;
-       case ASN_NULL:
-           sprint_null(buf, var, enums);
-           break;
-       case UINTEGER:
-           sprint_uinteger(buf, var, enums);
-           break;
-       default:
-           sprint_badtype(buf, var, enums);
-           break;
+    switch (var->type) {
+    case ASN_INTEGER:
+       sprint_integer(buf, var, enums);
+       break;
+    case ASN_OCTET_STR:
+       sprint_octet_string(buf, var, enums);
+       break;
+    case OPAQUE:
+       sprint_opaque(buf, var, enums);
+       break;
+    case ASN_OBJECT_ID:
+       sprint_object_identifier(buf, var, enums);
+       break;
+    case TIMETICKS:
+       sprint_timeticks(buf, var, enums);
+       break;
+    case GAUGE:
+       sprint_gauge(buf, var, enums);
+       break;
+    case COUNTER:
+       sprint_counter(buf, var, enums);
+       break;
+    case IPADDRESS:
+       sprint_ipaddress(buf, var, enums);
+       break;
+    case ASN_NULL:
+       sprint_null(buf, var, enums);
+       break;
+    case UINTEGER:
+       sprint_uinteger(buf, var, enums);
+       break;
+    default:
+       sprint_badtype(buf, var, enums);
+       break;
     }
 }
 
 struct tree *get_symbol();
 
-oid RFC1213_MIB[] = { 1, 3, 6, 1, 2, 1 };
+oid RFC1213_MIB[] =
+{1, 3, 6, 1, 2, 1};
 unsigned char RFC1213_MIB_text[] = ".iso.org.dod.internet.mgmt.mib-2";
 unsigned char EXPERIMENTAL_MIB_text[] = ".iso.org.dod.internet.experimental";
 unsigned char PRIVATE_MIB_text[] = ".iso.org.dod.internet.private";
@@ -588,26 +579,24 @@ init_mib()
     if (!Mib)
        Mib = read_mib("mib.txt");
 #ifdef MIBFILEPATH
-    if (!Mib)
-      {
-       char tmp [1024];
-       sprintf (tmp, "%s/mib.txt", MIBFILEPATH);
+    if (!Mib) {
+       char tmp[1024];
+       sprintf(tmp, "%s/mib.txt", MIBFILEPATH);
        Mib = read_mib(tmp);
-      }
+    }
 #endif
     if (!Mib)
        Mib = read_mib("/etc/mib.txt");
-    if (!Mib){
+    if (!Mib) {
        fprintf(stderr, "Couldn't find mib file\n");
        exit(2);
     }
     prefix = getenv("PREFIX");
-    if (! prefix) {
-      prefix = Standard_Prefix;
+    if (!prefix) {
+       prefix = Standard_Prefix;
     }
-
     /* save prefix: */
-    snmp_new_prefix (prefix);
+    snmp_new_prefix(prefix);
 
     if (getenv("SUFFIX"))
        Suffix = TRUE;
@@ -626,82 +615,84 @@ init_mib()
  */
 
 char *
-snmp_new_prefix (char *prefix) 
+snmp_new_prefix(char *prefix)
 {
-  char *lastchar;
-  int  plen;
-
-  if (prefix) {
-    lastchar = ".";   
-    if (*prefix == '.') { prefix++; }
-    if ((plen = strlen (prefix))) {
-      lastchar = prefix + plen - 1; 
-    }
-    strncpy (Prefix, prefix, sizeof (Prefix) - 2);
-    Prefix [sizeof (Prefix) - 2] = 0;
-    if (*lastchar != '.') {
-      Prefix [plen++] = '.';
-      Prefix [plen] = 0;
+    char *lastchar;
+    int plen;
+
+    if (prefix) {
+       lastchar = ".";
+       if (*prefix == '.') {
+           prefix++;
+       }
+       if ((plen = strlen(prefix))) {
+           lastchar = prefix + plen - 1;
+       }
+       strncpy(Prefix, prefix, sizeof(Prefix) - 2);
+       Prefix[sizeof(Prefix) - 2] = 0;
+       if (*lastchar != '.') {
+           Prefix[plen++] = '.';
+           Prefix[plen] = 0;
+       }
+       return Prefix;
     }
-    return Prefix;
-  }
-  return (char *)NULL;
+    return (char *) NULL;
 }
 
 
 
 static void
 set_functions(subtree)
-    struct tree *subtree;
+     struct tree *subtree;
 {
-    for(; subtree; subtree = subtree->next_peer){
-       switch(subtree->type){
-           case TYPE_OBJID:
-               subtree->printer = sprint_object_identifier;
-               break;
-           case TYPE_OCTETSTR:
-               subtree->printer = sprint_octet_string;
-               break;
-           case TYPE_INTEGER:
-               subtree->printer = sprint_integer;
-               break;
-           case TYPE_NETADDR:
-               subtree->printer = sprint_networkaddress;
-               break;
-           case TYPE_IPADDR:
-               subtree->printer = sprint_ipaddress;
-               break;
-           case TYPE_COUNTER:
-               subtree->printer = sprint_counter;
-               break;
-           case TYPE_GAUGE:
-               subtree->printer = sprint_gauge;
-               break;
-           case TYPE_TIMETICKS:
-               subtree->printer = sprint_timeticks;
-               break;
-           case TYPE_OPAQUE:
-               subtree->printer = sprint_opaque;
-               break;
-           case TYPE_NULL:
-               subtree->printer = sprint_null;
-               break;
-           case TYPE_BITSTRING:
-               subtree->printer = sprint_bitstring;
-               break;
-           case TYPE_NSAPADDRESS:
-               subtree->printer = sprint_nsapaddress;
-               break;
-           case TYPE_COUNTER64:
-               subtree->printer = sprint_counter64;
-               break;
-           case TYPE_UINTEGER:
-               subtree->printer = sprint_uinteger;
-               break;
-           case TYPE_OTHER:
-           default:
-               subtree->printer = sprint_unknowntype;
-               break;
+    for (; subtree; subtree = subtree->next_peer) {
+       switch (subtree->type) {
+       case TYPE_OBJID:
+           subtree->printer = sprint_object_identifier;
+           break;
+       case TYPE_OCTETSTR:
+           subtree->printer = sprint_octet_string;
+           break;
+       case TYPE_INTEGER:
+           subtree->printer = sprint_integer;
+           break;
+       case TYPE_NETADDR:
+           subtree->printer = sprint_networkaddress;
+           break;
+       case TYPE_IPADDR:
+           subtree->printer = sprint_ipaddress;
+           break;
+       case TYPE_COUNTER:
+           subtree->printer = sprint_counter;
+           break;
+       case TYPE_GAUGE:
+           subtree->printer = sprint_gauge;
+           break;
+       case TYPE_TIMETICKS:
+           subtree->printer = sprint_timeticks;
+           break;
+       case TYPE_OPAQUE:
+           subtree->printer = sprint_opaque;
+           break;
+       case TYPE_NULL:
+           subtree->printer = sprint_null;
+           break;
+       case TYPE_BITSTRING:
+           subtree->printer = sprint_bitstring;
+           break;
+       case TYPE_NSAPADDRESS:
+           subtree->printer = sprint_nsapaddress;
+           break;
+       case TYPE_COUNTER64:
+           subtree->printer = sprint_counter64;
+           break;
+       case TYPE_UINTEGER:
+           subtree->printer = sprint_uinteger;
+           break;
+       case TYPE_OTHER:
+       default:
+           subtree->printer = sprint_unknowntype;
+           break;
        }
        set_functions(subtree->child_list);
     }
@@ -715,7 +706,7 @@ main(argc, argv)
      char *argv[];
 {
     oid objid[64];
-    int objidlen = sizeof (objid);
+    int objidlen = sizeof(objid);
     int count;
     struct variable variable;
 
@@ -726,31 +717,31 @@ main(argc, argv)
     variable.val.integer = 3;
     variable.val_len = 4;
     for (argc--; argc; argc--, argv++) {
-       objidlen = sizeof (objid);
+       objidlen = sizeof(objid);
        printf("read_objid(%s) = %d\n",
-              argv[1], read_objid(argv[1], objid, &objidlen));
-       for(count = 0; count < objidlen; count++)
+           argv[1], read_objid(argv[1], objid, &objidlen));
+       for (count = 0; count < objidlen; count++)
            printf("%d.", objid[count]);
        printf("\n");
        print_variable(objid, objidlen, &variable);
     }
 }
 
-#endif testing
+#endif /* testing */
 
 
 #if 0
 static struct tree *
 find_rfc1213_mib(root)
-    struct tree *root;
+     struct tree *root;
 {
     oid *op = RFC1213_MIB;
     struct tree *tp;
     int len;
 
-    for(len = sizeof(RFC1213_MIB)/sizeof(oid); len; len--, op++){
-       for(tp = root; tp; tp = tp->next_peer){
-           if (tp->subid == *op){
+    for (len = sizeof(RFC1213_MIB) / sizeof(oid); len; len--, op++) {
+       for (tp = root; tp; tp = tp->next_peer) {
+           if (tp->subid == *op) {
                root = tp->child_list;
                break;
            }
@@ -762,31 +753,32 @@ find_rfc1213_mib(root)
 }
 #endif
 
-int read_objid(input, output, out_len)
-    char *input;
-    oid *output;
-    int        *out_len;   /* number of subid's in "output" */
+int 
+read_objid(input, output, out_len)
+     char *input;
+     oid *output;
+     int *out_len;             /* number of subid's in "output" */
 {
     struct tree *root = Mib;
     oid *op = output;
     char buf[512];
 
-    bzero (buf, sizeof(buf));
+    bzero(buf, sizeof(buf));
 
     if (*input == '.')
        input++;
     else {
-        strcpy(buf, Prefix);
+       strcpy(buf, Prefix);
        strcat(buf, input);
        input = buf;
     }
 
-    if (root == NULL){
+    if (root == NULL) {
        fprintf(stderr, "Mib not initialized.  Exiting.\n");
        exit(1);
     }
     if ((*out_len =
-        parse_subtree(root, input, output, out_len)) == 0)
+           parse_subtree(root, input, output, out_len)) == 0)
        return (0);
     *out_len += output - op;
 
@@ -794,10 +786,11 @@ int read_objid(input, output, out_len)
 }
 
 #ifdef notdef
-int read_objid(input, output, out_len)
-    char *input;
-    oid *output;
-    int        *out_len;   /* number of subid's in "output" */
+int 
+read_objid(input, output, out_len)
+     char *input;
+     oid *output;
+     int *out_len;             /* number of subid's in "output" */
 {
     struct tree *root = Mib;
     oid *op = output;
@@ -807,7 +800,7 @@ int read_objid(input, output, out_len)
        input++;
     else {
        root = find_rfc1213_mib(root);
-       for (i = 0; i < sizeof (RFC1213_MIB)/sizeof(oid); i++) {
+       for (i = 0; i < sizeof(RFC1213_MIB) / sizeof(oid); i++) {
            if ((*out_len)-- > 0)
                *output++ = RFC1213_MIB[i];
            else {
@@ -817,12 +810,12 @@ int read_objid(input, output, out_len)
        }
     }
 
-    if (root == NULL){
+    if (root == NULL) {
        fprintf(stderr, "Mib not initialized.  Exiting.\n");
        exit(1);
     }
     if ((*out_len =
-        parse_subtree(root, input, output, out_len)) == 0)
+           parse_subtree(root, input, output, out_len)) == 0)
        return (0);
     *out_len += output - op;
 
@@ -832,10 +825,10 @@ int read_objid(input, output, out_len)
 
 static int
 parse_subtree(subtree, input, output, out_len)
-    struct tree *subtree;
-    char *input;
-    oid        *output;
-    int        *out_len;   /* number of subid's */
+     struct tree *subtree;
+     char *input;
+     oid *output;
+     int *out_len;             /* number of subid's */
 {
     char buf[128], *to = buf;
     u_long subid = 0;
@@ -862,13 +855,12 @@ parse_subtree(subtree, input, output, out_len)
                goto found;
        }
        tp = NULL;
-    }
-    else {
+    } else {
        /*
         * Read the name into a buffer.
         */
        while ((*input != '\0') &&
-              (*input != '.')) {
+           (*input != '.')) {
            *to++ = *input++;
        }
        *to = '\0';
@@ -892,13 +884,12 @@ parse_subtree(subtree, input, output, out_len)
        }
     }
 
-found:
-    if(subid > (u_long)MAX_SUBID){
+  found:
+    if (subid > (u_long) MAX_SUBID) {
        fprintf(stderr, "sub-identifier too large: %s\n", buf);
        return (0);
     }
-
-    if ((*out_len)-- <= 0){
+    if ((*out_len)-- <= 0) {
        fprintf(stderr, "object identifier too long\n");
        return (0);
     }
@@ -907,31 +898,30 @@ found:
     if (*input != '.')
        return (1);
     if ((*out_len =
-        parse_subtree(tp ? tp->child_list : NULL, ++input, output, out_len)) == 0)
+           parse_subtree(tp ? tp->child_list : NULL, ++input, output, out_len)) == 0)
        return (0);
     return (++*out_len);
 }
 
 void
 sprint_objid(buf, objid, objidlen)
-    char *buf;
-    oid            *objid;
-    int            objidlen;   /* number of subidentifiers */
+     char *buf;
+     oid *objid;
+     int objidlen;             /* number of subidentifiers */
 {
-    char    tempbuf[2048], *cp;
-    struct tree    *subtree = Mib;
+    char tempbuf[2048], *cp;
+    struct tree *subtree = Mib;
 
-    *tempbuf = '.';    /* this is a fully qualified name */
+    *tempbuf = '.';            /* this is a fully qualified name */
     get_symbol(objid, objidlen, subtree, tempbuf + 1);
-    if (Suffix){
-       for(cp =tempbuf; *cp; cp++)
-           ;
-       while(cp >= tempbuf){
+    if (Suffix) {
+       for (cp = tempbuf; *cp; cp++);
+       while (cp >= tempbuf) {
            if (isalpha(*cp))
                break;
            cp--;
        }
-       while(cp >= tempbuf){
+       while (cp >= tempbuf) {
            if (*cp == '.')
                break;
            cp--;
@@ -942,30 +932,30 @@ sprint_objid(buf, objid, objidlen)
 
     } else {
        cp = tempbuf;
-       if ((strlen(tempbuf) > strlen((char *)RFC1213_MIB_text))
-           && !bcmp(tempbuf, (char *)RFC1213_MIB_text,
-                    strlen((char *)RFC1213_MIB_text))){
+       if ((strlen(tempbuf) > strlen((char *) RFC1213_MIB_text))
+           && !bcmp(tempbuf, (char *) RFC1213_MIB_text,
+               strlen((char *) RFC1213_MIB_text))) {
            cp += sizeof(RFC1213_MIB_text);
        }
-       if ((strlen(tempbuf) > strlen((char *)EXPERIMENTAL_MIB_text))
+       if ((strlen(tempbuf) > strlen((char *) EXPERIMENTAL_MIB_text))
            && !bcmp(tempbuf, (char *) EXPERIMENTAL_MIB_text,
-                    strlen((char *)EXPERIMENTAL_MIB_text))){
-            cp += sizeof(EXPERIMENTAL_MIB_text);
+               strlen((char *) EXPERIMENTAL_MIB_text))) {
+           cp += sizeof(EXPERIMENTAL_MIB_text);
        }
-       if ((strlen(tempbuf) > strlen((char *)PRIVATE_MIB_text))
+       if ((strlen(tempbuf) > strlen((char *) PRIVATE_MIB_text))
            && !bcmp(tempbuf, (char *) PRIVATE_MIB_text,
-                    strlen((char *)PRIVATE_MIB_text))){
-            cp += sizeof(PRIVATE_MIB_text);
+               strlen((char *) PRIVATE_MIB_text))) {
+           cp += sizeof(PRIVATE_MIB_text);
        }
-       if ((strlen(tempbuf) > strlen((char *)PARTY_MIB_text))
+       if ((strlen(tempbuf) > strlen((char *) PARTY_MIB_text))
            && !bcmp(tempbuf, (char *) PARTY_MIB_text,
-                    strlen((char *)PARTY_MIB_text))){
-            cp += sizeof(PARTY_MIB_text);
+               strlen((char *) PARTY_MIB_text))) {
+           cp += sizeof(PARTY_MIB_text);
        }
-       if ((strlen(tempbuf) > strlen((char *)SECRETS_MIB_text))
+       if ((strlen(tempbuf) > strlen((char *) SECRETS_MIB_text))
            && !bcmp(tempbuf, (char *) SECRETS_MIB_text,
-                    strlen((char *)SECRETS_MIB_text))){
-            cp += sizeof(SECRETS_MIB_text);
+               strlen((char *) SECRETS_MIB_text))) {
+           cp += sizeof(SECRETS_MIB_text);
        }
     }
     strcpy(buf, cp);
@@ -974,10 +964,10 @@ sprint_objid(buf, objid, objidlen)
 
 void
 print_objid(objid, objidlen)
-    oid            *objid;
-    int            objidlen;   /* number of subidentifiers */
+     oid *objid;
+     int objidlen;             /* number of subidentifiers */
 {
-    char    buf[256];
+    char buf[256];
 
     sprint_objid(buf, objid, objidlen);
     printf("%s\n", buf);
@@ -986,11 +976,11 @@ print_objid(objid, objidlen)
 
 void
 print_variable(objid, objidlen, variable)
-    oid     *objid;
-    int            objidlen;
-    struct  variable_list *variable;
+     oid *objid;
+     int objidlen;
+     struct variable_list *variable;
 {
-    char    buf[2048];
+    char buf[2048];
 
     sprint_variable(buf, objid, objidlen, variable);
     printf("%s", buf);
@@ -998,13 +988,13 @@ print_variable(objid, objidlen, variable)
 
 static void
 sprint_variable(buf, objid, objidlen, variable)
-    char *buf;
-    oid     *objid;
-    int            objidlen;
-    struct  variable_list *variable;
+     char *buf;
+     oid *objid;
+     int objidlen;
+     struct variable_list *variable;
 {
-    char    tempbuf[2048];
-    struct tree    *subtree = Mib;
+    char tempbuf[2048];
+    struct tree *subtree = Mib;
 
     sprint_objid(buf, objid, objidlen);
     buf += strlen(buf);
@@ -1018,11 +1008,11 @@ sprint_variable(buf, objid, objidlen, variable)
     else if (variable->type == SNMP_ENDOFMIBVIEW)
        sprintf(buf, "No more variables left in this MIB View\n");
     else {
-       *tempbuf = '.'; /* this is a fully qualified name */
+       *tempbuf = '.';         /* this is a fully qualified name */
        subtree = get_symbol(objid, objidlen, subtree, tempbuf + 1);
        buf += strlen(buf);
        if (subtree->printer)
-           (*subtree->printer)(buf, variable, subtree->enums);
+           (*subtree->printer) (buf, variable, subtree->enums);
        else {
            sprint_by_type(buf, variable, subtree->enums);
        }
@@ -1032,13 +1022,13 @@ sprint_variable(buf, objid, objidlen, variable)
 
 void
 sprint_value(buf, objid, objidlen, variable)
-    char *buf;
-    oid     *objid;
-    int            objidlen;
-    struct  variable_list *variable;
+     char *buf;
+     oid *objid;
+     int objidlen;
+     struct variable_list *variable;
 {
-    char    tempbuf[2048];
-    struct tree    *subtree = Mib;
+    char tempbuf[2048];
+    struct tree *subtree = Mib;
 
     if (variable->type == SNMP_NOSUCHOBJECT)
        sprintf(buf, "No Such Object available on this agent\n");
@@ -1049,7 +1039,7 @@ sprint_value(buf, objid, objidlen, variable)
     else {
        subtree = get_symbol(objid, objidlen, subtree, tempbuf);
        if (subtree->printer)
-           (*subtree->printer)(buf, variable, subtree->enums);
+           (*subtree->printer) (buf, variable, subtree->enums);
        else {
            sprint_by_type(buf, variable, subtree->enums);
        }
@@ -1058,11 +1048,11 @@ sprint_value(buf, objid, objidlen, variable)
 
 void
 print_value(objid, objidlen, variable)
-    oid     *objid;
-    int            objidlen;
-    struct  variable_list *variable;
+     oid *objid;
+     int objidlen;
+     struct variable_list *variable;
 {
-    char    tempbuf[2048];
+    char tempbuf[2048];
 
     sprint_value(tempbuf, objid, objidlen, variable);
     printf("%s\n", tempbuf);
@@ -1070,38 +1060,38 @@ print_value(objid, objidlen, variable)
 
 static struct tree *
 get_symbol(objid, objidlen, subtree, buf)
-    oid            *objid;
-    int            objidlen;
-    struct tree    *subtree;
-    char    *buf;
+     oid *objid;
+     int objidlen;
+     struct tree *subtree;
+     char *buf;
 {
-    struct tree    *return_tree = NULL;
+    struct tree *return_tree = NULL;
 
-    for(; subtree; subtree = subtree->next_peer){
-       if (*objid == subtree->subid){
+    for (; subtree; subtree = subtree->next_peer) {
+       if (*objid == subtree->subid) {
            strcpy(buf, subtree->label);
            goto found;
        }
     }
 
     /* subtree not found */
-    while(objidlen--){ /* output rest of name, uninterpreted */
+    while (objidlen--) {       /* output rest of name, uninterpreted */
        sprintf(buf, "%lu.", *objid++);
-       while(*buf)
+       while (*buf)
            buf++;
     }
-    *(buf - 1) = '\0'; /* remove trailing dot */
+    *(buf - 1) = '\0';         /* remove trailing dot */
     return NULL;
 
-found:
-    if (objidlen > 1){
-       while(*buf)
+  found:
+    if (objidlen > 1) {
+       while (*buf)
            buf++;
        *buf++ = '.';
        *buf = '\0';
        return_tree = get_symbol(objid + 1, objidlen - 1, subtree->child_list,
-                                buf);
-    } 
+           buf);
+    }
     if (return_tree != NULL)
        return return_tree;
     else
@@ -1111,11 +1101,11 @@ found:
 
 static int
 lc_cmp(s1, s2)
-    char *s1, *s2;
+     char *s1, *s2;
 {
     char c1, c2;
 
-    while(*s1 && *s2){
+    while (*s1 && *s2) {
        if (isupper(*s1))
            c1 = tolower(*s1);
        else
@@ -1142,42 +1132,42 @@ lc_cmp(s1, s2)
  */
 static struct tree *
 get_tree(objid, objidlen, subtree)
-    oid     *objid;
-    int     objidlen;
-    struct tree    *subtree;
+     oid *objid;
+     int objidlen;
+     struct tree *subtree;
 {
-    struct tree    *return_tree = NULL;
+    struct tree *return_tree = NULL;
 
-    for(; subtree; subtree = subtree->next_peer){
-        if (*objid == subtree->subid)
-            goto found;
+    for (; subtree; subtree = subtree->next_peer) {
+       if (*objid == subtree->subid)
+           goto found;
     }
 
     return NULL;
 
-found:
+  found:
     if (objidlen > 1)
-        return_tree = get_tree(objid + 1, objidlen - 1, subtree->child_list);
+       return_tree = get_tree(objid + 1, objidlen - 1, subtree->child_list);
     if (return_tree != NULL)
-        return return_tree;
+       return return_tree;
     else
-        return subtree;
+       return subtree;
 }
 
 
 #if 0
 static char *
 get_description(objid, objidlen)
-    oid     *objid;
-    int     objidlen;   /* number of subidentifiers */
+     oid *objid;
+     int objidlen;             /* number of subidentifiers */
 {
-    struct tree    *subtree = Mib;
+    struct tree *subtree = Mib;
 
     subtree = get_tree(objid, objidlen, subtree);
     if (subtree)
-        return (subtree->description);
+       return (subtree->description);
     else
-        return NULL;
+       return NULL;
 }
 #endif
 
@@ -1185,27 +1175,27 @@ get_description(objid, objidlen)
 #if 0
 static void
 print_description(objid, objidlen)
-    oid     *objid;
-    int     objidlen;   /* number of subidentifiers */
+     oid *objid;
+     int objidlen;             /* number of subidentifiers */
 {
     char *desc = get_description(objid, objidlen);
 
     if (desc && desc[0] != '\0')
-        printf("Description: \"%s\"\n", desc);
+       printf("Description: \"%s\"\n", desc);
     else
-        printf("No description\n");
+       printf("No description\n");
 }
 #endif
 
 
 static struct tree *
 find_node(name, subtree)
-    char *name;
-    struct tree *subtree;
+     char *name;
+     struct tree *subtree;
 {
     struct tree *tp, *ret;
 
-    for(tp = subtree; tp; tp = tp->next_peer){
+    for (tp = subtree; tp; tp = tp->next_peer) {
        if (!strcasecmp(name, tp->label))
            return tp;
        ret = find_node(name, tp->child_list);
@@ -1219,16 +1209,16 @@ find_node(name, subtree)
 #if 0
 static int
 get_node(name, objid, objidlen)
-    char *name;
-    oid *objid;
-    int *objidlen;
+     char *name;
+     oid *objid;
+     int *objidlen;
 {
     struct tree *tp;
     oid newname[64], *op;
 
     tp = find_node(name, Mib);
-    if (tp){
-       for(op = newname + 63; op >= newname; op--){
+    if (tp) {
+       for (op = newname + 63; op >= newname; op--) {
            *op = tp->subid;
            tp = tp->parent;
            if (tp == NULL)
@@ -1243,6 +1233,6 @@ get_node(name, objid, objidlen)
        return 0;
     }
 
-    
+
 }
 #endif
index dc1b239b1d43e3f6e9d449921a8b22afc64a7fab..a01870f287cb8f948be1cf15b1ba6d76eb83a5a5 100644 (file)
@@ -49,7 +49,7 @@ struct subid {
 
 /* use large token buffer in case of very long tokens: */
 #define MAXTC  1024
-struct tc {    /* textual conventions */
+struct tc {                    /* textual conventions */
     int type;
     char descriptor[MAXTOKEN];
     struct enum_list *enums;
@@ -61,7 +61,7 @@ int Line = 1;
 
 #define SYNTAX_MASK    0x80
 /* types of tokens
- Tokens wiht the SYNTAX_MASK bit set are syntax tokens */
Tokens wiht the SYNTAX_MASK bit set are syntax tokens */
 #define        CONTINUE    -1
 #define ENDOFFILE   0
 #define LABEL      1
@@ -78,7 +78,7 @@ int Line = 1;
 #define OPAQUE     (12 | SYNTAX_MASK)
 #define NUL        (13 | SYNTAX_MASK)
 #define SEQUENCE    14
-#define OF         15  /* SEQUENCE OF */
+#define OF         15          /* SEQUENCE OF */
 #define OBJTYPE            16
 #define ACCESS     17
 #define READONLY    18
@@ -126,85 +126,86 @@ int Line = 1;
 #define SEMI        60
 
 struct tok {
-       char *name;                     /* token name */
-       int len;                        /* length not counting nul */
-       int token;                      /* value */
-       int hash;                       /* hash of name */
-       struct tok *next;               /* pointer to next in hash table */
+    char *name;                        /* token name */
+    int len;                   /* length not counting nul */
+    int token;                 /* value */
+    int hash;                  /* hash of name */
+    struct tok *next;          /* pointer to next in hash table */
 };
 
 
-struct tok tokens[] = {
-       { "obsolete", sizeof ("obsolete")-1, OBSOLETE },
-       { "Opaque", sizeof ("Opaque")-1, OPAQUE },
-/*     { "recommended", sizeof("recommended")-1, RECOMMENDED },  */
-       { "optional", sizeof ("optional")-1, OPTIONAL },
-       { "LAST-UPDATED", sizeof ("LAST-UPDATED")-1, LASTUPDATED },
-       { "ORGANIZATION", sizeof ("ORGANIZATION")-1, ORGANIZATION },
-       { "CONTACT-INFO", sizeof ("CONTACT-INFO")-1, CONTACTINFO },
-       { "MODULE-IDENTITY", sizeof ("MODULE-IDENTITY")-1, MODULEIDENTITY },
-       { "MODULE-COMPLIANCE", sizeof ("MODULE-COMPLIANCE")-1, COMPLIANCE },
-        { "DEFINITIONS", sizeof("DEFINITIONS")-1, DEFINITIONS},
-        { "END", sizeof("END")-1, END},
-        { ";", sizeof(";")-1, SEMI},
-       { "AUGMENTS", sizeof ("AUGMENTS")-1, AUGMENTS },
-       { "not-accessible", sizeof ("not-accessible")-1, NOACCESS },
-       { "write-only", sizeof ("write-only")-1, WRITEONLY },
-       { "NsapAddress", sizeof("NsapAddress")-1, NSAPADDRESS},
-       { "UNITS", sizeof("Units")-1, UNITS},
-       { "REFERENCE", sizeof("REFERENCE")-1, REFERENCE},
-       { "NUM-ENTRIES", sizeof("NUM-ENTRIES")-1, NUM_ENTRIES},
-       { "BITSTRING", sizeof("BitString")-1, BITSTRING},
-       { "BIT", sizeof("BIT")-1, CONTINUE},
-       { "Counter64", sizeof("Counter64")-1, COUNTER64},
-       { "TimeTicks", sizeof ("TimeTicks")-1, TIMETICKS },
-       { "NOTIFICATION-TYPE", sizeof ("NOTIFICATION-TYPE")-1, NOTIFTYPE },
-       { "OBJECT-GROUP", sizeof ("OBJECT-GROUP")-1, OBJGROUP },
-       { "OBJECTIDENTIFIER", sizeof ("OBJECTIDENTIFIER")-1, OBJID },
+struct tok tokens[] =
+{
+    {"obsolete", sizeof("obsolete") - 1, OBSOLETE},
+    {"Opaque", sizeof("Opaque") - 1, OPAQUE},
+/*      { "recommended", sizeof("recommended")-1, RECOMMENDED },  */
+    {"optional", sizeof("optional") - 1, OPTIONAL},
+    {"LAST-UPDATED", sizeof("LAST-UPDATED") - 1, LASTUPDATED},
+    {"ORGANIZATION", sizeof("ORGANIZATION") - 1, ORGANIZATION},
+    {"CONTACT-INFO", sizeof("CONTACT-INFO") - 1, CONTACTINFO},
+    {"MODULE-IDENTITY", sizeof("MODULE-IDENTITY") - 1, MODULEIDENTITY},
+    {"MODULE-COMPLIANCE", sizeof("MODULE-COMPLIANCE") - 1, COMPLIANCE},
+    {"DEFINITIONS", sizeof("DEFINITIONS") - 1, DEFINITIONS},
+    {"END", sizeof("END") - 1, END},
+    {";", sizeof(";") - 1, SEMI},
+    {"AUGMENTS", sizeof("AUGMENTS") - 1, AUGMENTS},
+    {"not-accessible", sizeof("not-accessible") - 1, NOACCESS},
+    {"write-only", sizeof("write-only") - 1, WRITEONLY},
+    {"NsapAddress", sizeof("NsapAddress") - 1, NSAPADDRESS},
+    {"UNITS", sizeof("Units") - 1, UNITS},
+    {"REFERENCE", sizeof("REFERENCE") - 1, REFERENCE},
+    {"NUM-ENTRIES", sizeof("NUM-ENTRIES") - 1, NUM_ENTRIES},
+    {"BITSTRING", sizeof("BitString") - 1, BITSTRING},
+    {"BIT", sizeof("BIT") - 1, CONTINUE},
+    {"Counter64", sizeof("Counter64") - 1, COUNTER64},
+    {"TimeTicks", sizeof("TimeTicks") - 1, TIMETICKS},
+    {"NOTIFICATION-TYPE", sizeof("NOTIFICATION-TYPE") - 1, NOTIFTYPE},
+    {"OBJECT-GROUP", sizeof("OBJECT-GROUP") - 1, OBJGROUP},
+    {"OBJECTIDENTIFIER", sizeof("OBJECTIDENTIFIER") - 1, OBJID},
        /*
         * This CONTINUE appends the next word onto OBJECT,
         * hopefully matching OBJECTIDENTIFIER above.
         */
-       { "OBJECT", sizeof ("OBJECT")-1, CONTINUE },
-       { "NetworkAddress", sizeof ("NetworkAddress")-1, NETADDR },
-       { "Gauge", sizeof ("Gauge")-1, GAUGE },
-       { "read-write", sizeof ("read-write")-1, READWRITE },
-       { "read-create", sizeof ("read-create")-1, READCREATE },
-       { "OCTETSTRING", sizeof ("OCTETSTRING")-1, OCTETSTR },
-       { "OCTET", sizeof ("OCTET")-1, -1 },
-       { "OF", sizeof ("OF")-1, OF },
-       { "SEQUENCE", sizeof ("SEQUENCE")-1, SEQUENCE },
-       { "NULL", sizeof ("NULL")-1, NUL },
-       { "IpAddress", sizeof ("IpAddress")-1, IPADDR },
-       { "UInteger32", sizeof ("UInteger32")-1, UINTEGER32 },
-       { "INTEGER", sizeof ("INTEGER")-1, INTEGER },
-       { "Counter", sizeof ("Counter")-1, COUNTER },
-       { "read-only", sizeof ("read-only")-1, READONLY },
-        { "DESCRIPTION", sizeof ("DESCRIPTION")-1, DESCRIPTION },
-        { "INDEX", sizeof ("INDEX")-1, INDEX },
-        { "DEFVAL", sizeof ("DEFVAL")-1, DEFVAL },
-        { "deprecated", sizeof ("deprecated")-1, DEPRECATED },
-        { "SIZE", sizeof ("SIZE")-1, SIZE },
-       { "MAX-ACCESS", sizeof ("MAX-ACCESS")-1, ACCESS },
-       { "ACCESS", sizeof ("ACCESS")-1, ACCESS },
-       { "mandatory", sizeof ("mandatory")-1, MANDATORY },
-       { "current", sizeof ("current")-1, CURRENT },
-       { "STATUS", sizeof ("STATUS")-1, STATUS },
-       { "SYNTAX", sizeof ("SYNTAX")-1, SYNTAX },
-       { "OBJECT-TYPE", sizeof ("OBJECT-TYPE")-1, OBJTYPE },
-       { "{", sizeof ("{")-1, LEFTBRACKET },
-       { "}", sizeof ("}")-1, RIGHTBRACKET },
-       { "::=", sizeof ("::=")-1, EQUALS },
-       { "(", sizeof ("(")-1, LEFTPAREN },
-       { ")", sizeof (")")-1, RIGHTPAREN },
-       { ",", sizeof (",")-1, COMMA },
-       { NULL }
+    {"OBJECT", sizeof("OBJECT") - 1, CONTINUE},
+    {"NetworkAddress", sizeof("NetworkAddress") - 1, NETADDR},
+    {"Gauge", sizeof("Gauge") - 1, GAUGE},
+    {"read-write", sizeof("read-write") - 1, READWRITE},
+    {"read-create", sizeof("read-create") - 1, READCREATE},
+    {"OCTETSTRING", sizeof("OCTETSTRING") - 1, OCTETSTR},
+    {"OCTET", sizeof("OCTET") - 1, -1},
+    {"OF", sizeof("OF") - 1, OF},
+    {"SEQUENCE", sizeof("SEQUENCE") - 1, SEQUENCE},
+    {"NULL", sizeof("NULL") - 1, NUL},
+    {"IpAddress", sizeof("IpAddress") - 1, IPADDR},
+    {"UInteger32", sizeof("UInteger32") - 1, UINTEGER32},
+    {"INTEGER", sizeof("INTEGER") - 1, INTEGER},
+    {"Counter", sizeof("Counter") - 1, COUNTER},
+    {"read-only", sizeof("read-only") - 1, READONLY},
+    {"DESCRIPTION", sizeof("DESCRIPTION") - 1, DESCRIPTION},
+    {"INDEX", sizeof("INDEX") - 1, INDEX},
+    {"DEFVAL", sizeof("DEFVAL") - 1, DEFVAL},
+    {"deprecated", sizeof("deprecated") - 1, DEPRECATED},
+    {"SIZE", sizeof("SIZE") - 1, SIZE},
+    {"MAX-ACCESS", sizeof("MAX-ACCESS") - 1, ACCESS},
+    {"ACCESS", sizeof("ACCESS") - 1, ACCESS},
+    {"mandatory", sizeof("mandatory") - 1, MANDATORY},
+    {"current", sizeof("current") - 1, CURRENT},
+    {"STATUS", sizeof("STATUS") - 1, STATUS},
+    {"SYNTAX", sizeof("SYNTAX") - 1, SYNTAX},
+    {"OBJECT-TYPE", sizeof("OBJECT-TYPE") - 1, OBJTYPE},
+    {"{", sizeof("{") - 1, LEFTBRACKET},
+    {"}", sizeof("}") - 1, RIGHTBRACKET},
+    {"::=", sizeof("::=") - 1, EQUALS},
+    {"(", sizeof("(") - 1, LEFTPAREN},
+    {")", sizeof(")") - 1, RIGHTPAREN},
+    {",", sizeof(",") - 1, COMMA},
+    {NULL}
 };
 
 #define        HASHSIZE        32
 #define        BUCKET(x)       (x & 0x01F)
 
-struct tok     *buckets[HASHSIZE];
+struct tok *buckets[HASHSIZE];
 
 static void do_subtree();
 static int get_token();
@@ -214,21 +215,21 @@ static int tossObjectIdentifier();
 static void
 hash_init()
 {
-       struct tok      *tp;
-       char    *cp;
-       int     h;
-       int     b;
-
-       bzero((char *)buckets, sizeof(buckets));
-       for (tp = tokens; tp->name; tp++) {
-               for (h = 0, cp = tp->name; *cp; cp++)
-                       h += *cp;
-               tp->hash = h;
-               b = BUCKET(h);
-               if (buckets[b])
-                   tp->next = buckets[b]; /* BUG ??? */
-               buckets[b] = tp;
-       }
+    struct tok *tp;
+    char *cp;
+    int h;
+    int b;
+
+    bzero((char *) buckets, sizeof(buckets));
+    for (tp = tokens; tp->name; tp++) {
+       for (h = 0, cp = tp->name; *cp; cp++)
+           h += *cp;
+       tp->hash = h;
+       b = BUCKET(h);
+       if (buckets[b])
+           tp->next = buckets[b];      /* BUG ??? */
+       buckets[b] = tp;
+    }
 }
 
 #define NHASHSIZE    128
@@ -239,42 +240,42 @@ void
 init_node_hash(nodes)
      struct node *nodes;
 {
-     struct node *np, *nextp;
-     char *cp;
-     int hash;
-
-     bzero((char *)nbuckets,sizeof(nbuckets));
-     for(np = nodes; np;){
-         nextp = np->next;
-         hash = 0;
-        for(cp = np->parent; *cp; cp++)
-            hash += *cp;
-        np->next = nbuckets[NBUCKET(hash)];
-        nbuckets[NBUCKET(hash)] = np;
-        np = nextp;
-     }
+    struct node *np, *nextp;
+    char *cp;
+    int hash;
+
+    bzero((char *) nbuckets, sizeof(nbuckets));
+    for (np = nodes; np;) {
+       nextp = np->next;
+       hash = 0;
+       for (cp = np->parent; *cp; cp++)
+           hash += *cp;
+       np->next = nbuckets[NBUCKET(hash)];
+       nbuckets[NBUCKET(hash)] = np;
+       np = nextp;
+    }
 }
 
 static char *
 Malloc(num)
-    unsigned num;
+     unsigned num;
 {
 #ifndef linux
-    charcalloc();
+    char *calloc();
 #endif
-    
+
     /* this is to fix (what seems to be) a problem with the IBM RT C
-       library malloc */
+     * library malloc */
     if (num < 16)
        num = 16;
-    return (char *)calloc(1, num);
+    return (char *) calloc(1, num);
 }
 
 static void
 print_error(string, token, type)
-    char *string;
-    char *token;
-    int type;
+     char *string;
+     char *token;
+     int type;
 {
     if (type == ENDOFFILE)
        fprintf(stderr, "%s(EOF): On or around line %d\n", string, Line);
@@ -286,22 +287,22 @@ print_error(string, token, type)
 
 #ifdef TEST
 print_subtree(tree, count)
-    struct tree *tree;
-    int count;
+     struct tree *tree;
+     int count;
 {
     struct tree *tp;
     int i;
 
-    for(i = 0; i < count; i++)
+    for (i = 0; i < count; i++)
        printf("  ");
     printf("Children of %s:\n", tree->label);
     count++;
-    for(tp = tree->child_list; tp; tp = tp->next_peer){
-       for(i = 0; i < count; i++)
+    for (tp = tree->child_list; tp; tp = tp->next_peer) {
+       for (i = 0; i < count; i++)
            printf("  ");
        printf("%s\n", tp->label);
     }
-    for(tp = tree->child_list; tp; tp = tp->next_peer){
+    for (tp = tree->child_list; tp; tp = tp->next_peer) {
        print_subtree(tp, count);
     }
 }
@@ -314,71 +315,71 @@ build_translation_table()
 {
     int count;
 
-    for(count = 0; count < 256; count++){
-       switch(count){
-           case OBJID:
-               translation_table[count] = TYPE_OBJID;
-               break;
-           case OCTETSTR:
-               translation_table[count] = TYPE_OCTETSTR;
-               break;
-           case INTEGER:
-               translation_table[count] = TYPE_INTEGER;
-               break;
-           case NETADDR:
-               translation_table[count] = TYPE_IPADDR;
-               break;
-           case IPADDR:
-               translation_table[count] = TYPE_IPADDR;
-               break;
-           case COUNTER:
-               translation_table[count] = TYPE_COUNTER;
-               break;
-           case GAUGE:
-               translation_table[count] = TYPE_GAUGE;
-               break;
-           case TIMETICKS:
-               translation_table[count] = TYPE_TIMETICKS;
-               break;
-           case OPAQUE:
-               translation_table[count] = TYPE_OPAQUE;
-               break;
-           case NUL:
-               translation_table[count] = TYPE_NULL;
-               break;
-           case COUNTER64:
-               translation_table[count] = TYPE_COUNTER64;
-               break;
-           case BITSTRING:
-               translation_table[count] = TYPE_BITSTRING;
-               break;
-           case NSAPADDRESS:
-               translation_table[count] = TYPE_NSAPADDRESS;
-               break;
-           case UINTEGER32:
-               translation_table[count] = TYPE_UINTEGER;
-               break;
-           default:
-               translation_table[count] = TYPE_OTHER;
-               break;
+    for (count = 0; count < 256; count++) {
+       switch (count) {
+       case OBJID:
+           translation_table[count] = TYPE_OBJID;
+           break;
+       case OCTETSTR:
+           translation_table[count] = TYPE_OCTETSTR;
+           break;
+       case INTEGER:
+           translation_table[count] = TYPE_INTEGER;
+           break;
+       case NETADDR:
+           translation_table[count] = TYPE_IPADDR;
+           break;
+       case IPADDR:
+           translation_table[count] = TYPE_IPADDR;
+           break;
+       case COUNTER:
+           translation_table[count] = TYPE_COUNTER;
+           break;
+       case GAUGE:
+           translation_table[count] = TYPE_GAUGE;
+           break;
+       case TIMETICKS:
+           translation_table[count] = TYPE_TIMETICKS;
+           break;
+       case OPAQUE:
+           translation_table[count] = TYPE_OPAQUE;
+           break;
+       case NUL:
+           translation_table[count] = TYPE_NULL;
+           break;
+       case COUNTER64:
+           translation_table[count] = TYPE_COUNTER64;
+           break;
+       case BITSTRING:
+           translation_table[count] = TYPE_BITSTRING;
+           break;
+       case NSAPADDRESS:
+           translation_table[count] = TYPE_NSAPADDRESS;
+           break;
+       case UINTEGER32:
+           translation_table[count] = TYPE_UINTEGER;
+           break;
+       default:
+           translation_table[count] = TYPE_OTHER;
+           break;
        }
     }
 }
 
 static struct tree *
 build_tree(nodes)
-    struct node *nodes;
+     struct node *nodes;
 {
     struct node *np;
     struct tree *tp, *lasttp;
     int bucket, nodes_left = 0;
-    
+
     build_translation_table();
     /* grow tree from this root node */
     init_node_hash(nodes);
 
     /* build root node */
-    tp = (struct tree *)Malloc(sizeof(struct tree));
+    tp = (struct tree *) Malloc(sizeof(struct tree));
     tp->parent = NULL;
     tp->next_peer = NULL;
     tp->child_list = NULL;
@@ -392,7 +393,7 @@ build_tree(nodes)
     lasttp = tp;
 
     /* build root node */
-    tp = (struct tree *)Malloc(sizeof(struct tree));
+    tp = (struct tree *) Malloc(sizeof(struct tree));
     tp->parent = NULL;
     tp->next_peer = lasttp;
     tp->child_list = NULL;
@@ -406,7 +407,7 @@ build_tree(nodes)
     lasttp = tp;
 
     /* build root node */
-    tp = (struct tree *)Malloc(sizeof(struct tree));
+    tp = (struct tree *) Malloc(sizeof(struct tree));
     tp->parent = NULL;
     tp->next_peer = lasttp;
     tp->child_list = NULL;
@@ -423,20 +424,20 @@ build_tree(nodes)
     print_subtree(tp, 0);
 #endif /* TEST */
     /* If any nodes are left, the tree is probably inconsistent */
-    for(bucket = 0; bucket < NHASHSIZE; bucket++){
-        if (nbuckets[bucket]){
+    for (bucket = 0; bucket < NHASHSIZE; bucket++) {
+       if (nbuckets[bucket]) {
            nodes_left = 1;
            break;
        }
     }
-    if (nodes_left){
+    if (nodes_left) {
        fprintf(stderr, "The mib description doesn't seem to be consistent.\n");
        fprintf(stderr, "Some nodes couldn't be linked under the \"iso\" tree.\n");
        fprintf(stderr, "these nodes are left:\n");
-       for(bucket = 0; bucket < NHASHSIZE; bucket++){
-           for(np = nbuckets[bucket]; np; np = np->next)
-               fprintf(stderr, "%s ::= { %s %ld } (%d)\n", np->label,
-                       np->parent, np->subid, np->type);
+       for (bucket = 0; bucket < NHASHSIZE; bucket++) {
+           for (np = nbuckets[bucket]; np; np = np->next)
+               fprintf(stderr, "%s ::= { %s %ld } (%d)\n", np->label,
+                   np->parent, np->subid, np->type);
        }
     }
     return tp;
@@ -448,8 +449,8 @@ build_tree(nodes)
  */
 static void
 do_subtree(root, nodes)
-    struct tree *root;
-    struct node **nodes;
+     struct tree *root;
+     struct node **nodes;
 {
     struct tree *tp;
     struct tree *peer = NULL;
@@ -457,19 +458,19 @@ do_subtree(root, nodes)
     struct node *oldnp = NULL, *child_list = NULL, *childp = NULL;
     char *cp;
     int hash;
-    
+
     tp = root;
     hash = 0;
-    for(cp = tp->label; *cp; cp++)
-        hash += *cp;
+    for (cp = tp->label; *cp; cp++)
+       hash += *cp;
     headp = &nbuckets[NBUCKET(hash)];
     /*
      * Search each of the nodes for one whose parent is root, and
      * move each into a separate list.
      */
-    for(np = *headp; np; np = np->next){
-       if ((*tp->label != *np->parent) || strcmp(tp->label, np->parent)){
-           if ((*tp->label == *np->label) && !strcmp(tp->label, np->label)){
+    for (np = *headp; np; np = np->next) {
+       if ((*tp->label != *np->parent) || strcmp(tp->label, np->parent)) {
+           if ((*tp->label == *np->label) && !strcmp(tp->label, np->label)) {
                /* if there is another node with the same label, assume that
                 * any children after this point in the list belong to the other node.
                 * This adds some scoping to the table and allows vendors to
@@ -479,17 +480,17 @@ do_subtree(root, nodes)
            }
            oldnp = np;
        } else {
-           if (child_list == NULL){
-               child_list = childp = np;   /* first entry in child list */
+           if (child_list == NULL) {
+               child_list = childp = np;       /* first entry in child list */
            } else {
                childp->next = np;
                childp = np;
            }
            /* take this node out of the node list */
-           if (oldnp == NULL){
-               *headp = np->next;  /* fix root of node list */
+           if (oldnp == NULL) {
+               *headp = np->next;      /* fix root of node list */
            } else {
-               oldnp->next = np->next; /* link around this node */
+               oldnp->next = np->next;         /* link around this node */
            }
        }
     }
@@ -498,8 +499,8 @@ do_subtree(root, nodes)
     /*
      * Take each element in the child list and place it into the tree.
      */
-    for(np = child_list; np; np = np->next){
-       tp = (struct tree *)Malloc(sizeof(struct tree));
+    for (np = child_list; np; np = np->next) {
+       tp = (struct tree *) Malloc(sizeof(struct tree));
        tp->parent = root;
        tp->next_peer = NULL;
        tp->child_list = NULL;
@@ -508,21 +509,21 @@ do_subtree(root, nodes)
        tp->type = translation_table[np->type];
        tp->enums = np->enums;
        np->enums = NULL;       /* so we don't free them later */
-       tp->description = np->description; /* steals memory from np */
-       np->description = NULL; /* so we don't free it later */
-       if (root->child_list == NULL){
+       tp->description = np->description;      /* steals memory from np */
+       np->description = NULL; /* so we don't free it later */
+       if (root->child_list == NULL) {
            root->child_list = tp;
        } else {
            peer->next_peer = tp;
        }
        peer = tp;
-/*     if (tp->type == TYPE_OTHER) */
-           do_subtree(tp, nodes);      /* recurse on this child if it isn't
-                                          an end node */
+/*      if (tp->type == TYPE_OTHER) */
+       do_subtree(tp, nodes);  /* recurse on this child if it isn't
+                                * an end node */
     }
     /* free all nodes that were copied into tree */
     oldnp = NULL;
-    for(np = child_list; np; np = np->next){
+    for (np = child_list; np; np = np->next) {
        if (oldnp)
            free(oldnp);
        oldnp = np;
@@ -539,41 +540,41 @@ do_subtree(root, nodes)
  * Returns NULL on error.
  */
 static int
-getoid(fp, oid,  length)
-    FILE *fp;
-    struct subid *oid; /* an array of subids */
-    int length;            /* the length of the array */
+getoid(fp, oid, length)
+     FILE *fp;
+     struct subid *oid;                /* an array of subids */
+     int length;               /* the length of the array */
 {
     int count;
     int type;
     char token[MAXTOKEN];
     char *cp;
 
-    if ((type = get_token(fp, token)) != LEFTBRACKET){
+    if ((type = get_token(fp, token)) != LEFTBRACKET) {
        print_error("Expected \"{\"", token, type);
        return 0;
     }
     type = get_token(fp, token);
-    for(count = 0; count < length; count++, oid++){
+    for (count = 0; count < length; count++, oid++) {
        oid->label = 0;
        oid->subid = -1;
-       if (type == RIGHTBRACKET){
+       if (type == RIGHTBRACKET) {
            return count;
-       } else if (type != LABEL && type != NUMBER){
+       } else if (type != LABEL && type != NUMBER) {
            print_error("Not valid for object identifier", token, type);
            return 0;
        }
-       if (type == LABEL){
+       if (type == LABEL) {
            /* this entry has a label */
-           cp = (char *)Malloc((unsigned)strlen(token) + 1);
+           cp = (char *) Malloc((unsigned) strlen(token) + 1);
            strcpy(cp, token);
            oid->label = cp;
            type = get_token(fp, token);
-           if (type == LEFTPAREN){
+           if (type == LEFTPAREN) {
                type = get_token(fp, token);
-               if (type == NUMBER){
+               if (type == NUMBER) {
                    oid->subid = atoi(token);
-                   if ((type = get_token(fp, token)) != RIGHTPAREN){
+                   if ((type = get_token(fp, token)) != RIGHTPAREN) {
                        print_error("Unexpected a closing parenthesis", token, type);
                        return 0;
                    }
@@ -597,17 +598,17 @@ getoid(fp, oid,  length)
 
 static void
 free_node(np)
-    struct node *np;
+     struct node *np;
 {
     struct enum_list *ep, *tep;
 
     ep = np->enums;
-    while(ep){
+    while (ep) {
        tep = ep;
        ep = ep->next;
-       free((char *)tep);
+       free((char *) tep);
     }
-    free((char *)np);
+    free((char *) np);
 }
 
 /*
@@ -618,8 +619,8 @@ free_node(np)
  */
 static struct node *
 parse_objectid(fp, name)
-    FILE *fp;
-    char *name;
+     FILE *fp;
+     char *name;
 {
     int type;
     char token[MAXTOKEN];
@@ -630,21 +631,21 @@ parse_objectid(fp, name)
     struct node *np, *root, *oldnp = NULL;
 
     type = get_token(fp, token);
-    if (type != EQUALS){
+    if (type != EQUALS) {
        print_error("Bad format", token, type);
        return 0;
     }
-    if ((length = getoid(fp, oid, 32)) != 0){
-       np = root = (struct node *)Malloc(sizeof(struct node));
-       bzero((char *)np, sizeof(struct node));
+    if ((length = getoid(fp, oid, 32)) != 0) {
+       np = root = (struct node *) Malloc(sizeof(struct node));
+       bzero((char *) np, sizeof(struct node));
        /*
         * For each parent-child subid pair in the subid array,
         * create a node and link it into the node list.
         */
-       for(count = 0, op = oid, nop=oid+1; count < (length - 2); count++,
-           op++, nop++){
+       for (count = 0, op = oid, nop = oid + 1; count < (length - 2); count++,
+           op++, nop++) {
            /* every node must have parent's name and child's name or number */
-           if (op->label && (nop->label || (nop->subid != -1))){
+           if (op->label && (nop->label || (nop->subid != -1))) {
                strcpy(np->parent, op->label);
                if (nop->label)
                    strcpy(np->label, nop->label);
@@ -653,28 +654,28 @@ parse_objectid(fp, name)
                np->type = 0;
                np->enums = 0;
                /* set up next entry */
-               np->next = (struct node *)Malloc(sizeof(*np->next));
-               bzero((char *)np->next, sizeof(struct node));
+               np->next = (struct node *) Malloc(sizeof(*np->next));
+               bzero((char *) np->next, sizeof(struct node));
                oldnp = np;
                np = np->next;
            }
        }
-       np->next = (struct node *)NULL;
+       np->next = (struct node *) NULL;
        /*
         * The above loop took care of all but the last pair.  This pair is taken
         * care of here.  The name for this node is taken from the label for this
         * entry.
         * np still points to an unused entry.
         */
-       if (count == (length - 2)){
-           if (op->label){
+       if (count == (length - 2)) {
+           if (op->label) {
                strcpy(np->parent, op->label);
                strcpy(np->label, name);
                if (nop->subid != -1)
                    np->subid = nop->subid;
                else
                    print_error("Warning: This entry is pretty silly",
-                               np->label, type);
+                       np->label, type);
            } else {
                free_node(np);
                if (oldnp)
@@ -683,36 +684,36 @@ parse_objectid(fp, name)
                    return NULL;
            }
        } else {
-           print_error("Missing end of oid", (char *)NULL, type);
-           free_node(np);   /* the last node allocated wasn't used */
+           print_error("Missing end of oid", (char *) NULL, type);
+           free_node(np);      /* the last node allocated wasn't used */
            if (oldnp)
                oldnp->next = NULL;
            return NULL;
        }
        /* free the oid array */
-       for(count = 0, op = oid; count < length; count++, op++){
+       for (count = 0, op = oid; count < length; count++, op++) {
            if (op->label)
                free(op->label);
            op->label = 0;
        }
        return root;
     } else {
-       print_error("Bad object identifier", (char *)NULL, type);
+       print_error("Bad object identifier", (char *) NULL, type);
        return 0;
     }
 }
 
 static int
 get_tc(descriptor, ep)
-    char *descriptor;
-    struct enum_list **ep;
+     char *descriptor;
+     struct enum_list **ep;
 {
     int i;
 
-    for(i = 0; i < MAXTC; i++){
+    for (i = 0; i < MAXTC; i++) {
        if (tclist[i].type == 0)
            break;
-       if (!strcmp(descriptor, tclist[i].descriptor)){
+       if (!strcmp(descriptor, tclist[i].descriptor)) {
            *ep = tclist[i].enums;
            return tclist[i].type;
        }
@@ -726,21 +727,21 @@ get_tc(descriptor, ep)
  */
 static int
 parse_asntype(fp, name, ntype, ntoken)
-    FILE *fp;
-    char *name;
-    int *ntype;
-    char *ntoken;
+     FILE *fp;
+     char *name;
+     int *ntype;
+     char *ntoken;
 {
     int type, i;
     char token[MAXTOKEN];
     struct enum_list *ep = 0;
     struct tc *tcp;
     int level;
-    
+
     type = get_token(fp, token);
-    if (type == SEQUENCE){
-       while((type = get_token(fp, token)) != ENDOFFILE){
-           if (type == RIGHTBRACKET){
+    if (type == SEQUENCE) {
+       while ((type = get_token(fp, token)) != ENDOFFILE) {
+           if (type == RIGHTBRACKET) {
                *ntype = get_token(fp, ntoken);
                return 1;
            }
@@ -748,48 +749,48 @@ parse_asntype(fp, name, ntype, ntoken)
        print_error("Expected \"}\"", token, type);
        return 0;
     } else {
-       if (!strcmp(token, "TEXTUAL-CONVENTION")){
+       if (!strcmp(token, "TEXTUAL-CONVENTION")) {
            while (type != SYNTAX)
                type = get_token(fp, token);
            type = get_token(fp, token);
        }
        /* textual convention */
-       for(i = 0; i < MAXTC; i++){
+       for (i = 0; i < MAXTC; i++) {
            if (tclist[i].type == 0)
                break;
        }
-       if (i == MAXTC){
+       if (i == MAXTC) {
            print_error("No more textual conventions possible.", token, type);
            return 0;
        }
        tcp = &tclist[i];
        strcpy(tcp->descriptor, name);
-       if (!(type & SYNTAX_MASK)){
+       if (!(type & SYNTAX_MASK)) {
            print_error("Textual convention doesn't map to real type.", token,
-                       type);
+               type);
            return 0;
        }
        tcp->type = type;
        *ntype = get_token(fp, ntoken);
-       if (*ntype == LEFTPAREN){
+       if (*ntype == LEFTPAREN) {
            level = 1;
            /* don't record any constraints for now */
-           while(level > 0){
+           while (level > 0) {
                *ntype = get_token(fp, ntoken);
                if (*ntype == LEFTPAREN)
                    level++;
                if (*ntype == RIGHTPAREN)
-                   level--;            
+                   level--;
            }
            *ntype = get_token(fp, ntoken);
        } else if (*ntype == LEFTBRACKET) {
            /* if there is an enumeration list, parse it */
-           while((type = get_token(fp, token)) != ENDOFFILE){
+           while ((type = get_token(fp, token)) != ENDOFFILE) {
                if (type == RIGHTBRACKET)
                    break;
-               if (type == LABEL){
+               if (type == LABEL) {
                    /* this is an enumerated label */
-                   if (tcp->enums == 0){
+                   if (tcp->enums == 0) {
                        ep = tcp->enums = (struct enum_list *)
                            Malloc(sizeof(struct enum_list));
                    } else {
@@ -800,30 +801,30 @@ parse_asntype(fp, name, ntype, ntoken)
                    ep->next = 0;
                    /* a reasonable approximation for the length */
                    ep->label =
-                       (char *)Malloc((unsigned)strlen(token) + 1);
+                       (char *) Malloc((unsigned) strlen(token) + 1);
                    strcpy(ep->label, token);
                    type = get_token(fp, token);
-                   if (type != LEFTPAREN){
+                   if (type != LEFTPAREN) {
                        print_error("Expected \"(\"", token, type);
                        /* free_node(np); */
                        return 0;
                    }
                    type = get_token(fp, token);
-                   if (type != NUMBER){
+                   if (type != NUMBER) {
                        print_error("Expected integer", token, type);
                        /* free_node(np); */
                        return 0;
                    }
                    ep->value = atoi(token);
                    type = get_token(fp, token);
-                   if (type != RIGHTPAREN){
+                   if (type != RIGHTPAREN) {
                        print_error("Expected \")\"", token, type);
                        /* free_node(np); */
                        return 0;
                    }
                }
            }
-           if (type == ENDOFFILE){
+           if (type == ENDOFFILE) {
                print_error("Expected \"}\"", token, type);
                /* free_node(np); */
                return 0;
@@ -841,8 +842,8 @@ parse_asntype(fp, name, ntype, ntoken)
  */
 static struct node *
 parse_objecttype(fp, name)
-    FILE *fp;
-    char *name;
+     FILE *fp;
+     char *name;
 {
     int type;
     char token[MAXTOKEN];
@@ -855,19 +856,19 @@ parse_objecttype(fp, name)
     struct enum_list *ep = 0;
 
     type = get_token(fp, token);
-    if (type != SYNTAX){
+    if (type != SYNTAX) {
        print_error("Bad format for OBJECT TYPE", token, type);
        return 0;
     }
-    np = (struct node *)Malloc(sizeof(struct node));
+    np = (struct node *) Malloc(sizeof(struct node));
     np->next = 0;
     np->enums = 0;
-    np->description = NULL;        /* default to an empty description */
+    np->description = NULL;    /* default to an empty description */
     type = get_token(fp, token);
-    if (type == LABEL){
+    if (type == LABEL) {
        tctype = get_tc(token, &(np->enums));
 #if 0
-       if (tctype == LABEL){
+       if (tctype == LABEL) {
            print_error("No known translation for type", token, type);
            return 0;
        }
@@ -876,173 +877,172 @@ parse_objecttype(fp, name)
     }
     np->type = type;
     nexttype = get_token(fp, nexttoken);
-    switch(type){
-       case SEQUENCE:
-           strcpy(syntax, token);
-           if (nexttype == OF){
-               strcat(syntax, " ");
-               strcat(syntax, nexttoken);
-               nexttype = get_token(fp, nexttoken);
-               strcat(syntax, " ");
-               strcat(syntax, nexttoken);
-               nexttype = get_token(fp, nexttoken);
-           }
-           break;
-       case INTEGER:
-       case UINTEGER32:
-           strcpy(syntax, token);
-           if (nexttype == LEFTBRACKET) {
-               /* if there is an enumeration list, parse it */
-               while((type = get_token(fp, token)) != ENDOFFILE){
-                   if (type == RIGHTBRACKET)
-                       break;
-                   if (type == LABEL){
-                       /* this is an enumerated label */
-                       if (np->enums == 0){
-                           ep = np->enums = (struct enum_list *)
-                                       Malloc(sizeof(struct enum_list));
-                       } else {
-                           ep->next = (struct enum_list *)
-                                       Malloc(sizeof(struct enum_list));
-                           ep = ep->next;
-                       }
-                       ep->next = 0;
-                       /* a reasonable approximation for the length */
-                       ep->label =
-                           (char *)Malloc((unsigned)strlen(token) + 1);
-                       strcpy(ep->label, token);
-                       type = get_token(fp, token);
-                       if (type != LEFTPAREN){
-                           print_error("Expected \"(\"", token, type);
-                           free_node(np);
-                           return 0;
-                       }
-                       type = get_token(fp, token);
-                       if (type != NUMBER){
-                           print_error("Expected integer", token, type);
-                           free_node(np);
-                           return 0;
-                       }
-                       ep->value = atoi(token);
-                       type = get_token(fp, token);
-                       if (type != RIGHTPAREN){
-                           print_error("Expected \")\"", token, type);
-                           free_node(np);
-                           return 0;
-                       }
+    switch (type) {
+    case SEQUENCE:
+       strcpy(syntax, token);
+       if (nexttype == OF) {
+           strcat(syntax, " ");
+           strcat(syntax, nexttoken);
+           nexttype = get_token(fp, nexttoken);
+           strcat(syntax, " ");
+           strcat(syntax, nexttoken);
+           nexttype = get_token(fp, nexttoken);
+       }
+       break;
+    case INTEGER:
+    case UINTEGER32:
+       strcpy(syntax, token);
+       if (nexttype == LEFTBRACKET) {
+           /* if there is an enumeration list, parse it */
+           while ((type = get_token(fp, token)) != ENDOFFILE) {
+               if (type == RIGHTBRACKET)
+                   break;
+               if (type == LABEL) {
+                   /* this is an enumerated label */
+                   if (np->enums == 0) {
+                       ep = np->enums = (struct enum_list *)
+                           Malloc(sizeof(struct enum_list));
+                   } else {
+                       ep->next = (struct enum_list *)
+                           Malloc(sizeof(struct enum_list));
+                       ep = ep->next;
+                   }
+                   ep->next = 0;
+                   /* a reasonable approximation for the length */
+                   ep->label =
+                       (char *) Malloc((unsigned) strlen(token) + 1);
+                   strcpy(ep->label, token);
+                   type = get_token(fp, token);
+                   if (type != LEFTPAREN) {
+                       print_error("Expected \"(\"", token, type);
+                       free_node(np);
+                       return 0;
+                   }
+                   type = get_token(fp, token);
+                   if (type != NUMBER) {
+                       print_error("Expected integer", token, type);
+                       free_node(np);
+                       return 0;
+                   }
+                   ep->value = atoi(token);
+                   type = get_token(fp, token);
+                   if (type != RIGHTPAREN) {
+                       print_error("Expected \")\"", token, type);
+                       free_node(np);
+                       return 0;
                    }
                }
-               if (type == ENDOFFILE){
-                   print_error("Expected \"}\"", token, type);
-                   free_node(np);
-                   return 0;
+           }
+           if (type == ENDOFFILE) {
+               print_error("Expected \"}\"", token, type);
+               free_node(np);
+               return 0;
+           }
+           nexttype = get_token(fp, nexttoken);
+       } else if (nexttype == LEFTPAREN) {
+           /* ignore the "constrained integer" for now */
+           nexttype = get_token(fp, nexttoken);
+           nexttype = get_token(fp, nexttoken);
+           nexttype = get_token(fp, nexttoken);
+       }
+       break;
+    case BITSTRING:
+       strcpy(syntax, token);
+       if (nexttype == LEFTBRACKET) {
+           /* if there is an enumeration list, parse it */
+           while ((type = get_token(fp, token)) != ENDOFFILE) {
+               if (type == RIGHTBRACKET)
+                   break;
+               if (type == LABEL) {
+                   /* this is an enumerated label */
+                   if (np->enums == 0) {
+                       ep = np->enums = (struct enum_list *)
+                           Malloc(sizeof(struct enum_list));
+                   } else {
+                       ep->next = (struct enum_list *)
+                           Malloc(sizeof(struct enum_list));
+                       ep = ep->next;
+                   }
+                   ep->next = 0;
+                   /* a reasonable approximation for the length */
+                   ep->label =
+                       (char *) Malloc((unsigned) strlen(token) + 1);
+                   strcpy(ep->label, token);
+                   type = get_token(fp, token);
+                   if (type != LEFTPAREN) {
+                       print_error("Expected \"(\"", token, type);
+                       free_node(np);
+                       return 0;
+                   }
+                   type = get_token(fp, token);
+                   if (type != NUMBER) {
+                       print_error("Expected integer", token, type);
+                       free_node(np);
+                       return 0;
+                   }
+                   ep->value = atoi(token);
+                   type = get_token(fp, token);
+                   if (type != RIGHTPAREN) {
+                       print_error("Expected \")\"", token, type);
+                       free_node(np);
+                       return 0;
+                   }
                }
-               nexttype = get_token(fp, nexttoken);
-           } else if (nexttype == LEFTPAREN){
-               /* ignore the "constrained integer" for now */
-               nexttype = get_token(fp, nexttoken);
-               nexttype = get_token(fp, nexttoken);
-               nexttype = get_token(fp, nexttoken);
            }
-           break;
-       case BITSTRING:
-           strcpy(syntax, token);
-           if (nexttype == LEFTBRACKET) {
-               /* if there is an enumeration list, parse it */
-               while((type = get_token(fp, token)) != ENDOFFILE){
-                   if (type == RIGHTBRACKET)
+           if (type == ENDOFFILE) {
+               print_error("Expected \"}\"", token, type);
+               free_node(np);
+               return 0;
+           }
+           nexttype = get_token(fp, nexttoken);
+       } else if (nexttype == LEFTPAREN) {
+           /* ignore the "constrained integer" for now */
+           nexttype = get_token(fp, nexttoken);
+           nexttype = get_token(fp, nexttoken);
+           nexttype = get_token(fp, nexttoken);
+       }
+       break;
+    case OCTETSTR:
+       strcpy(syntax, token);
+       /* ignore the "constrained octet string" for now */
+       if (nexttype == LEFTPAREN) {
+           nexttype = get_token(fp, nexttoken);
+           if (nexttype == SIZE) {
+               nexttype = get_token(fp, nexttoken);
+               if (nexttype == LEFTPAREN) {
+                   nexttype = get_token(fp, nexttoken);        /* 0..255 */
+                   nexttype = get_token(fp, nexttoken);        /* ) */
+                   nexttype = get_token(fp, nexttoken);        /* ) */
+                   if (nexttype == RIGHTPAREN) {
+                       nexttype = get_token(fp, nexttoken);
                        break;
-                   if (type == LABEL){
-                       /* this is an enumerated label */
-                       if (np->enums == 0){
-                           ep = np->enums = (struct enum_list *)
-                                       Malloc(sizeof(struct enum_list));
-                       } else {
-                           ep->next = (struct enum_list *)
-                                       Malloc(sizeof(struct enum_list));
-                           ep = ep->next;
-                       }
-                       ep->next = 0;
-                       /* a reasonable approximation for the length */
-                       ep->label =
-                           (char *)Malloc((unsigned)strlen(token) + 1);
-                       strcpy(ep->label, token);
-                       type = get_token(fp, token);
-                       if (type != LEFTPAREN){
-                           print_error("Expected \"(\"", token, type);
-                           free_node(np);
-                           return 0;
-                       }
-                       type = get_token(fp, token);
-                       if (type != NUMBER){
-                           print_error("Expected integer", token, type);
-                           free_node(np);
-                           return 0;
-                       }
-                       ep->value = atoi(token);
-                       type = get_token(fp, token);
-                       if (type != RIGHTPAREN){
-                           print_error("Expected \")\"", token, type);
-                           free_node(np);
-                           return 0;
-                       }
                    }
                }
-               if (type == ENDOFFILE){
-                   print_error("Expected \"}\"", token, type);
-                   free_node(np);
-                   return 0;
-               }
-               nexttype = get_token(fp, nexttoken);
-           } else if (nexttype == LEFTPAREN){
-               /* ignore the "constrained integer" for now */
-               nexttype = get_token(fp, nexttoken);
-               nexttype = get_token(fp, nexttoken);
-               nexttype = get_token(fp, nexttoken);
            }
-           break;
-       case OCTETSTR:
-           strcpy(syntax, token);
-            /* ignore the "constrained octet string" for now */
-            if (nexttype == LEFTPAREN) {
-                nexttype = get_token(fp, nexttoken);
-                if (nexttype == SIZE) {
-                    nexttype = get_token(fp, nexttoken);
-                    if (nexttype == LEFTPAREN) {
-                        nexttype = get_token(fp, nexttoken); /* 0..255 */
-                        nexttype = get_token(fp, nexttoken); /* ) */
-                        nexttype = get_token(fp, nexttoken); /* ) */
-                        if (nexttype == RIGHTPAREN)
-                        {
-                            nexttype = get_token(fp, nexttoken);
-                            break;
-                        }
-                    }
-                }
-                print_error("Bad syntax", token, type);
-                free_node(np);
-                return 0;
-            }
-           break;
-       case OBJID:
-       case NETADDR:
-       case IPADDR:
-       case COUNTER:
-       case GAUGE:
-       case TIMETICKS:
-       case OPAQUE:
-       case NUL:
-       case LABEL:
-       case NSAPADDRESS:
-       case COUNTER64:
-           strcpy(syntax, token);
-           break;
-       default:
            print_error("Bad syntax", token, type);
            free_node(np);
            return 0;
+       }
+       break;
+    case OBJID:
+    case NETADDR:
+    case IPADDR:
+    case COUNTER:
+    case GAUGE:
+    case TIMETICKS:
+    case OPAQUE:
+    case NUL:
+    case LABEL:
+    case NSAPADDRESS:
+    case COUNTER64:
+       strcpy(syntax, token);
+       break;
+    default:
+       print_error("Bad syntax", token, type);
+       free_node(np);
+       return 0;
     }
-    if (nexttype == UNITS){
+    if (nexttype == UNITS) {
        type = get_token(fp, token);
        if (type != QUOTESTRING) {
            print_error("Bad DESCRIPTION", token, type);
@@ -1051,26 +1051,26 @@ parse_objecttype(fp, name)
        }
        nexttype = get_token(fp, nexttoken);
     }
-    if (nexttype != ACCESS){
+    if (nexttype != ACCESS) {
        print_error("Should be ACCESS", nexttoken, nexttype);
        free_node(np);
        return 0;
     }
     type = get_token(fp, token);
     if (type != READONLY && type != READWRITE && type != WRITEONLY
-       && type != NOACCESS && type != READCREATE){
+       && type != NOACCESS && type != READCREATE) {
        print_error("Bad access type", nexttoken, nexttype);
        free_node(np);
        return 0;
     }
     type = get_token(fp, token);
-    if (type != STATUS){
+    if (type != STATUS) {
        print_error("Should be STATUS", token, nexttype);
        free_node(np);
        return 0;
     }
     type = get_token(fp, token);
-    if (type != MANDATORY && type != CURRENT && type != OPTIONAL && type != OBSOLETE && type != DEPRECATED){
+    if (type != MANDATORY && type != CURRENT && type != OPTIONAL && type != OBSOLETE && type != DEPRECATED) {
        print_error("Bad status", token, type);
        free_node(np);
        return 0;
@@ -1080,55 +1080,55 @@ parse_objecttype(fp, name)
      */
     type = get_token(fp, token);
     while (type != EQUALS) {
-      switch (type) {
-        case DESCRIPTION:
-          type = get_token(fp, token);
-          if (type != QUOTESTRING) {
-              print_error("Bad DESCRIPTION", token, type);
-              free_node(np);
-              return 0;
-          }
+       switch (type) {
+       case DESCRIPTION:
+           type = get_token(fp, token);
+           if (type != QUOTESTRING) {
+               print_error("Bad DESCRIPTION", token, type);
+               free_node(np);
+               return 0;
+           }
 #ifdef TEST
-printf("Description== \"%.50s\"\n", quoted_string_buffer);
+           printf("Description== \"%.50s\"\n", quoted_string_buffer);
 #endif
-         np->description = quoted_string_buffer;
-         quoted_string_buffer = (char *)calloc(1, MAXQUOTESTR);
-          break;
+           np->description = quoted_string_buffer;
+           quoted_string_buffer = (char *) calloc(1, MAXQUOTESTR);
+           break;
 
        case REFERENCE:
-         type = get_token(fp, token);
-         if (type != QUOTESTRING) {
-             print_error("Bad DESCRIPTION", token, type);
-             free_node(np);
-             return 0;
-         }
-         break;
-        case INDEX:
-        case DEFVAL:
+           type = get_token(fp, token);
+           if (type != QUOTESTRING) {
+               print_error("Bad DESCRIPTION", token, type);
+               free_node(np);
+               return 0;
+           }
+           break;
+       case INDEX:
+       case DEFVAL:
        case AUGMENTS:
        case NUM_ENTRIES:
-          if (tossObjectIdentifier(fp) != OBJID) {
-              print_error("Bad Object Identifier", token, type);
-              free_node(np);
-              return 0;
-          }
-          break;
-
-        default:
-          print_error("Bad format of optional clauses", token,type);
-          free_node(np);
-          return 0;
-
-      }
-      type = get_token(fp, token);
+           if (tossObjectIdentifier(fp) != OBJID) {
+               print_error("Bad Object Identifier", token, type);
+               free_node(np);
+               return 0;
+           }
+           break;
+
+       default:
+           print_error("Bad format of optional clauses", token, type);
+           free_node(np);
+           return 0;
+
+       }
+       type = get_token(fp, token);
     }
-    if (type != EQUALS){
+    if (type != EQUALS) {
        print_error("Bad format", token, type);
        free_node(np);
        return 0;
     }
     length = getoid(fp, oid, 32);
-    if (length > 1 && length <= 32){
+    if (length > 1 && length <= 32) {
        /* just take the last pair in the oid list */
        if (oid[length - 2].label)
            strncpy(np->parent, oid[length - 2].label, MAXLABEL);
@@ -1138,12 +1138,12 @@ printf("Description== \"%.50s\"\n", quoted_string_buffer);
        else
            print_error("Warning: This entry is pretty silly", np->label, type);
     } else {
-       print_error("No end to oid", (char *)NULL, type);
+       print_error("No end to oid", (char *) NULL, type);
        free_node(np);
        np = 0;
     }
     /* free oid array */
-    for(count = 0; count < length; count++){
+    for (count = 0; count < length; count++) {
        if (oid[count].label)
            free(oid[count].label);
        oid[count].label = 0;
@@ -1158,8 +1158,8 @@ printf("Description== \"%.50s\"\n", quoted_string_buffer);
  */
 static struct node *
 parse_objectgroup(fp, name)
-    FILE *fp;
-    char *name;
+     FILE *fp;
+     char *name;
 {
     int type;
     char token[MAXTOKEN];
@@ -1167,36 +1167,36 @@ parse_objectgroup(fp, name)
     struct subid oid[32];
     struct node *np;
 
-    np = (struct node *)Malloc(sizeof(struct node));
+    np = (struct node *) Malloc(sizeof(struct node));
     np->type = 0;
     np->next = 0;
     np->enums = 0;
-    np->description = NULL;        /* default to an empty description */
+    np->description = NULL;    /* default to an empty description */
     type = get_token(fp, token);
     while (type != EQUALS) {
-      switch (type) {
-        case DESCRIPTION:
-          type = get_token(fp, token);
-          if (type != QUOTESTRING) {
-              print_error("Bad DESCRIPTION", token, type);
-              free_node(np);
-              return 0;
-          }
+       switch (type) {
+       case DESCRIPTION:
+           type = get_token(fp, token);
+           if (type != QUOTESTRING) {
+               print_error("Bad DESCRIPTION", token, type);
+               free_node(np);
+               return 0;
+           }
 #ifdef TEST
-printf("Description== \"%.50s\"\n", quoted_string_buffer);
+           printf("Description== \"%.50s\"\n", quoted_string_buffer);
 #endif
-         np->description = quoted_string_buffer;
-         quoted_string_buffer = (char *)calloc(1, MAXQUOTESTR);
-          break;
-
-        default:
-         /* NOTHING */
-         break;
-      }
-      type = get_token(fp, token);
+           np->description = quoted_string_buffer;
+           quoted_string_buffer = (char *) calloc(1, MAXQUOTESTR);
+           break;
+
+       default:
+           /* NOTHING */
+           break;
+       }
+       type = get_token(fp, token);
     }
     length = getoid(fp, oid, 32);
-    if (length > 1 && length <= 32){
+    if (length > 1 && length <= 32) {
        /* just take the last pair in the oid list */
        if (oid[length - 2].label)
            strncpy(np->parent, oid[length - 2].label, MAXLABEL);
@@ -1206,12 +1206,12 @@ printf("Description== \"%.50s\"\n", quoted_string_buffer);
        else
            print_error("Warning: This entry is pretty silly", np->label, type);
     } else {
-       print_error("No end to oid", (char *)NULL, type);
+       print_error("No end to oid", (char *) NULL, type);
        free_node(np);
        np = 0;
     }
     /* free oid array */
-    for(count = 0; count < length; count++){
+    for (count = 0; count < length; count++) {
        if (oid[count].label)
            free(oid[count].label);
        oid[count].label = 0;
@@ -1225,8 +1225,8 @@ printf("Description== \"%.50s\"\n", quoted_string_buffer);
  */
 static struct node *
 parse_notificationDefinition(fp, name)
-    FILE *fp;
-    char *name;
+     FILE *fp;
+     char *name;
 {
     int type;
     char token[MAXTOKEN];
@@ -1234,36 +1234,36 @@ parse_notificationDefinition(fp, name)
     struct subid oid[32];
     struct node *np;
 
-    np = (struct node *)Malloc(sizeof(struct node));
+    np = (struct node *) Malloc(sizeof(struct node));
     np->type = 0;
     np->next = 0;
     np->enums = 0;
-    np->description = NULL;        /* default to an empty description */
+    np->description = NULL;    /* default to an empty description */
     type = get_token(fp, token);
     while (type != EQUALS) {
-      switch (type) {
-        case DESCRIPTION:
-          type = get_token(fp, token);
-          if (type != QUOTESTRING) {
-              print_error("Bad DESCRIPTION", token, type);
-              free_node(np);
-              return 0;
-          }
+       switch (type) {
+       case DESCRIPTION:
+           type = get_token(fp, token);
+           if (type != QUOTESTRING) {
+               print_error("Bad DESCRIPTION", token, type);
+               free_node(np);
+               return 0;
+           }
 #ifdef TEST
-printf("Description== \"%.50s\"\n", quoted_string_buffer);
+           printf("Description== \"%.50s\"\n", quoted_string_buffer);
 #endif
-         np->description = quoted_string_buffer;
-         quoted_string_buffer = (char *)calloc(1, MAXQUOTESTR);
-          break;
-
-        default:
-         /* NOTHING */
-         break;
-      }
-      type = get_token(fp, token);
+           np->description = quoted_string_buffer;
+           quoted_string_buffer = (char *) calloc(1, MAXQUOTESTR);
+           break;
+
+       default:
+           /* NOTHING */
+           break;
+       }
+       type = get_token(fp, token);
     }
     length = getoid(fp, oid, 32);
-    if (length > 1 && length <= 32){
+    if (length > 1 && length <= 32) {
        /* just take the last pair in the oid list */
        if (oid[length - 2].label)
            strncpy(np->parent, oid[length - 2].label, MAXLABEL);
@@ -1273,12 +1273,12 @@ printf("Description== \"%.50s\"\n", quoted_string_buffer);
        else
            print_error("Warning: This entry is pretty silly", np->label, type);
     } else {
-       print_error("No end to oid", (char *)NULL, type);
+       print_error("No end to oid", (char *) NULL, type);
        free_node(np);
        np = 0;
     }
     /* free oid array */
-    for(count = 0; count < length; count++){
+    for (count = 0; count < length; count++) {
        if (oid[count].label)
            free(oid[count].label);
        oid[count].label = 0;
@@ -1292,8 +1292,8 @@ printf("Description== \"%.50s\"\n", quoted_string_buffer);
  */
 static struct node *
 parse_compliance(fp, name)
-    FILE *fp;
-    char *name;
+     FILE *fp;
+     char *name;
 {
     int type;
     char token[MAXTOKEN];
@@ -1301,17 +1301,17 @@ parse_compliance(fp, name)
     struct subid oid[32];
     struct node *np;
 
-    np = (struct node *)Malloc(sizeof(struct node));
+    np = (struct node *) Malloc(sizeof(struct node));
     np->type = 0;
     np->next = 0;
     np->enums = 0;
-    np->description = NULL;        /* default to an empty description */
+    np->description = NULL;    /* default to an empty description */
     type = get_token(fp, token);
     while (type != EQUALS) {
        type = get_token(fp, token);
     }
     length = getoid(fp, oid, 32);
-    if (length > 1 && length <= 32){
+    if (length > 1 && length <= 32) {
        /* just take the last pair in the oid list */
        if (oid[length - 2].label)
            strncpy(np->parent, oid[length - 2].label, MAXLABEL);
@@ -1321,12 +1321,12 @@ parse_compliance(fp, name)
        else
            print_error("Warning: This entry is pretty silly", np->label, type);
     } else {
-       print_error("No end to oid", (char *)NULL, type);
+       print_error("No end to oid", (char *) NULL, type);
        free_node(np);
        np = 0;
     }
     /* free oid array */
-    for(count = 0; count < length; count++){
+    for (count = 0; count < length; count++) {
        if (oid[count].label)
            free(oid[count].label);
        oid[count].label = 0;
@@ -1342,8 +1342,8 @@ parse_compliance(fp, name)
  */
 static struct node *
 parse_moduleIdentity(fp, name)
-    FILE *fp;
-    char *name;
+     FILE *fp;
+     char *name;
 {
     int type;
     char token[MAXTOKEN];
@@ -1351,17 +1351,17 @@ parse_moduleIdentity(fp, name)
     struct subid oid[32];
     struct node *np;
 
-    np = (struct node *)Malloc(sizeof(struct node));
+    np = (struct node *) Malloc(sizeof(struct node));
     np->type = 0;
     np->next = 0;
     np->enums = 0;
-    np->description = NULL;        /* default to an empty description */
+    np->description = NULL;    /* default to an empty description */
     type = get_token(fp, token);
     while (type != EQUALS) {
        type = get_token(fp, token);
     }
     length = getoid(fp, oid, 32);
-    if (length > 1 && length <= 32){
+    if (length > 1 && length <= 32) {
        /* just take the last pair in the oid list */
        if (oid[length - 2].label)
            strncpy(np->parent, oid[length - 2].label, MAXLABEL);
@@ -1371,12 +1371,12 @@ parse_moduleIdentity(fp, name)
        else
            print_error("Warning: This entry is pretty silly", np->label, type);
     } else {
-       print_error("No end to oid", (char *)NULL, type);
+       print_error("No end to oid", (char *) NULL, type);
        free_node(np);
        np = 0;
     }
     /* free oid array */
-    for(count = 0; count < length; count++){
+    for (count = 0; count < length; count++) {
        if (oid[count].label)
            free(oid[count].label);
        oid[count].label = 0;
@@ -1384,21 +1384,22 @@ parse_moduleIdentity(fp, name)
     return np;
 }
 
-int parse_mib_header(fp, name)
-    FILE *fp;
-    char *name;
+int 
+parse_mib_header(fp, name)
+     FILE *fp;
+     char *name;
 {
     int type = DEFINITIONS;
     char token[MAXTOKEN];
-    
+
     /* This probably isn't good enough.  If there is no
-       imports clause we can't go around waiting (forever) for a semicolon.
-       We need to check for semi following an EXPORTS clause or an IMPORTS
-       clause of both.  Look for BEGIN; in my initial MIBs to see those
-       that I needed to hack to get to parse because they didn't have
-       an IMPORTS or and EXPORTS clause.
-       */
-    while(type != SEMI && type != ENDOFFILE){
+     * imports clause we can't go around waiting (forever) for a semicolon.
+     * We need to check for semi following an EXPORTS clause or an IMPORTS
+     * clause of both.  Look for BEGIN; in my initial MIBs to see those
+     * that I needed to hack to get to parse because they didn't have
+     * an IMPORTS or and EXPORTS clause.
+     */
+    while (type != SEMI && type != ENDOFFILE) {
        type = get_token(fp, token);
     }
     return (type == SEMI);
@@ -1412,32 +1413,32 @@ int parse_mib_header(fp, name)
  */
 static struct node *
 parse(fp)
-    FILE *fp;
+     FILE *fp;
 {
     char token[MAXTOKEN];
     char name[MAXTOKEN];
-    int        type = 1;
+    int type = 1;
 #define BETWEEN_MIBS         1
 #define IN_MIB                2
     int state = BETWEEN_MIBS;
     struct node *np = 0, *root = NULL;
 
     hash_init();
-    quoted_string_buffer = (char *)calloc(1, MAXQUOTESTR);  /* free this later */
+    quoted_string_buffer = (char *) calloc(1, MAXQUOTESTR);    /* free this later */
     bzero(tclist, 64 * sizeof(struct tc));
 
-    while(type != ENDOFFILE){
+    while (type != ENDOFFILE) {
        type = get_token(fp, token);
-skipget:
-       if (type == END){
-           if (state != IN_MIB){
-               print_error("Error, end before start of MIB.", (char *)NULL, type);
+      skipget:
+       if (type == END) {
+           if (state != IN_MIB) {
+               print_error("Error, end before start of MIB.", (char *) NULL, type);
                return NULL;
            }
            state = BETWEEN_MIBS;
            continue;
-       } else if (type != LABEL){
-           if (type == ENDOFFILE){
+       } else if (type != LABEL) {
+           if (type == ENDOFFILE) {
                return root;
            }
            print_error(token, "is a reserved word", type);
@@ -1445,163 +1446,163 @@ skipget:
        }
        strncpy(name, token, MAXTOKEN);
        type = get_token(fp, token);
-       if (type == DEFINITIONS){
-           if (state != BETWEEN_MIBS){
-               print_error("Error, nested MIBS.", (char *)NULL, type);
+       if (type == DEFINITIONS) {
+           if (state != BETWEEN_MIBS) {
+               print_error("Error, nested MIBS.", (char *) NULL, type);
                return NULL;
            }
            state = IN_MIB;
-           if (!parse_mib_header(fp, name)){
-               print_error("Bad parse of module header", (char *)NULL, type);
+           if (!parse_mib_header(fp, name)) {
+               print_error("Bad parse of module header", (char *) NULL, type);
                return NULL;
            }
-       } else if (type == OBJTYPE){
-           if (root == NULL){
+       } else if (type == OBJTYPE) {
+           if (root == NULL) {
                /* first link in chain */
                np = root = parse_objecttype(fp, name);
-               if (np == NULL){
-                   print_error("Bad parse of object type", (char *)NULL,
-                               type);
+               if (np == NULL) {
+                   print_error("Bad parse of object type", (char *) NULL,
+                       type);
                    return NULL;
                }
            } else {
                np->next = parse_objecttype(fp, name);
-               if (np->next == NULL){
-                   print_error("Bad parse of objecttype", (char *)NULL,
-                               type);
+               if (np->next == NULL) {
+                   print_error("Bad parse of objecttype", (char *) NULL,
+                       type);
                    return NULL;
                }
            }
            /* now find end of chain */
-           while(np->next)
+           while (np->next)
                np = np->next;
-       } else if (type == OBJGROUP){
-           if (root == NULL){
+       } else if (type == OBJGROUP) {
+           if (root == NULL) {
                /* first link in chain */
                np = root = parse_objectgroup(fp, name);
-               if (np == NULL){
-                   print_error("Bad parse of object group", (char *)NULL,
-                               type);
+               if (np == NULL) {
+                   print_error("Bad parse of object group", (char *) NULL,
+                       type);
                    return NULL;
                }
            } else {
                np->next = parse_objectgroup(fp, name);
-               if (np->next == NULL){
-                   print_error("Bad parse of objectgroup", (char *)NULL,
-                               type);
+               if (np->next == NULL) {
+                   print_error("Bad parse of objectgroup", (char *) NULL,
+                       type);
                    return NULL;
                }
            }
            /* now find end of chain */
-           while(np->next)
+           while (np->next)
                np = np->next;
-       } else if (type == NOTIFTYPE){
-           if (root == NULL){
+       } else if (type == NOTIFTYPE) {
+           if (root == NULL) {
                /* first link in chain */
                np = root = parse_notificationDefinition(fp, name);
-               if (np == NULL){
+               if (np == NULL) {
                    print_error("Bad parse of notification definition",
-                               (char *)NULL, type);
+                       (char *) NULL, type);
                    return NULL;
                }
            } else {
                np->next = parse_notificationDefinition(fp, name);
-               if (np->next == NULL){
+               if (np->next == NULL) {
                    print_error("Bad parse of notification definition",
-                               (char *)NULL, type);
+                       (char *) NULL, type);
                    return NULL;
                }
            }
            /* now find end of chain */
-           while(np->next)
+           while (np->next)
                np = np->next;
-       } else if (type == COMPLIANCE){
-           if (root == NULL){
+       } else if (type == COMPLIANCE) {
+           if (root == NULL) {
                /* first link in chain */
                np = root = parse_compliance(fp, name);
-               if (np == NULL){
-                   print_error("Bad parse of module compliance", (char *)NULL,
-                               type);
+               if (np == NULL) {
+                   print_error("Bad parse of module compliance", (char *) NULL,
+                       type);
                    return NULL;
                }
            } else {
                np->next = parse_compliance(fp, name);
-               if (np->next == NULL){
-                   print_error("Bad parse of module compliance", (char *)NULL,
-                               type);
+               if (np->next == NULL) {
+                   print_error("Bad parse of module compliance", (char *) NULL,
+                       type);
                    return NULL;
                }
            }
            /* now find end of chain */
-           while(np->next)
+           while (np->next)
                np = np->next;
-       } else if (type == MODULEIDENTITY){
-           if (root == NULL){
+       } else if (type == MODULEIDENTITY) {
+           if (root == NULL) {
                /* first link in chain */
                np = root = parse_moduleIdentity(fp, name);
-               if (np == NULL){
-                   print_error("Bad parse of module identity", (char *)NULL,
-                               type);
+               if (np == NULL) {
+                   print_error("Bad parse of module identity", (char *) NULL,
+                       type);
                    return NULL;
                }
            } else {
                np->next = parse_moduleIdentity(fp, name);
-               if (np->next == NULL){
-                   print_error("Bad parse of module identity", (char *)NULL,
-                               type);
+               if (np->next == NULL) {
+                   print_error("Bad parse of module identity", (char *) NULL,
+                       type);
                    return NULL;
                }
            }
            /* now find end of chain */
-           while(np->next)
+           while (np->next)
                np = np->next;
-       } else if (type == OBJID){
-           if (root == NULL){
+       } else if (type == OBJID) {
+           if (root == NULL) {
                /* first link in chain */
                np = root = parse_objectid(fp, name);
-               if (np == NULL){
-                   print_error("Bad parse of object id", (char *)NULL, type);
+               if (np == NULL) {
+                   print_error("Bad parse of object id", (char *) NULL, type);
                    return NULL;
                }
            } else {
                np->next = parse_objectid(fp, name);
-               if (np->next == NULL){
-                   print_error("Bad parse of object type", (char *)NULL,
-                               type);
+               if (np->next == NULL) {
+                   print_error("Bad parse of object type", (char *) NULL,
+                       type);
                    return NULL;
                }
            }
            /* now find end of chain */
-           while(np->next)
+           while (np->next)
                np = np->next;
-       } else if (type == EQUALS){
-           if (!parse_asntype(fp, name, &type, token)){
+       } else if (type == EQUALS) {
+           if (!parse_asntype(fp, name, &type, token)) {
                print_error("Bad parse of ASN type definition.", NULL, EQUALS);
                return NULL;
            }
            goto skipget;
-       } else if (type == ENDOFFILE){
+       } else if (type == ENDOFFILE) {
            break;
        } else {
-           print_error("Bad operator", (char *)NULL, type);
+           print_error("Bad operator", (char *) NULL, type);
            return NULL;
        }
     }
 #ifdef TEST
-{
-    struct enum_list *ep;
-    
-    for(np = root; np; np = np->next){
-       printf("%s ::= { %s %d } (%d)\n", np->label, np->parent, np->subid,
+    {
+       struct enum_list *ep;
+
+       for (np = root; np; np = np->next) {
+           printf("%s ::= { %s %d } (%d)\n", np->label, np->parent, np->subid,
                np->type);
-       if (np->enums){
-           printf("Enums: \n");
-           for(ep = np->enums; ep; ep = ep->next){
-               printf("%s(%d)\n", ep->label, ep->value);
+           if (np->enums) {
+               printf("Enums: \n");
+               for (ep = np->enums; ep; ep = ep->next) {
+                   printf("%s(%d)\n", ep->label, ep->value);
+               }
            }
        }
     }
-}
 #endif /* TEST */
     return root;
 }
@@ -1612,8 +1613,8 @@ skipget:
  */
 static int
 get_token(fp, token)
-    FILE *fp;
-    char *token;
+     FILE *fp;
+     char *token;
 {
     static char last = ' ';
     int ch;
@@ -1624,7 +1625,7 @@ get_token(fp, token)
     *cp = 0;
     ch = last;
     /* skip all white space */
-    while(isspace(ch) && ch != -1){
+    while (isspace(ch) && ch != -1) {
        ch = getc(fp);
        if (ch == '\n')
            Line++;
@@ -1634,7 +1635,6 @@ get_token(fp, token)
     } else if (ch == '"') {
        return parseQuoteString(fp, token);
     }
-
     /*
      * Accumulate characters until end of token is found.  Then attempt to
      * match this token as a reserved word.  If a match is found, return the
@@ -1644,8 +1644,8 @@ get_token(fp, token)
        if (ch == '\n')
            Line++;
        if (isspace(ch) || ch == '(' || ch == ')' || ch == '{' || ch == '}' ||
-           ch == ',' || ch == ';'){
-           if (!isspace(ch) && *token == 0){
+           ch == ',' || ch == ';') {
+           if (!isspace(ch) && *token == 0) {
                hash += ch;
                *cp++ = ch;
                last = ' ';
@@ -1656,19 +1656,18 @@ get_token(fp, token)
 
            for (tp = buckets[BUCKET(hash)]; tp; tp = tp->next) {
                if ((tp->hash == hash) && (strcmp(tp->name, token) == 0))
-                       break;
+                   break;
            }
-           if (tp){
+           if (tp) {
                if (tp->token == CONTINUE)
                    continue;
                return (tp->token);
            }
-
-           if (token[0] == '-' && token[1] == '-'){
+           if (token[0] == '-' && token[1] == '-') {
                /* strip comment */
-               if (ch != '\n'){
+               if (ch != '\n') {
                    while ((ch = getc(fp)) != -1)
-                       if (ch == '\n'){
+                       if (ch == '\n') {
                            Line++;
                            break;
                        }
@@ -1676,9 +1675,9 @@ get_token(fp, token)
                if (ch == -1)
                    return ENDOFFILE;
                last = ch;
-               return get_token(fp, token);            
+               return get_token(fp, token);
            }
-           for(cp = token; *cp; cp++)
+           for (cp = token; *cp; cp++)
                if (!isdigit(*cp))
                    return LABEL;
            return NUMBER;
@@ -1688,14 +1687,14 @@ get_token(fp, token)
            if (ch == '\n')
                Line++;
        }
-    
+
     } while ((ch = getc(fp)) != -1);
     return ENDOFFILE;
 }
 
 struct tree *
 read_mib(filename)
-    char *filename;
+     char *filename;
 {
     FILE *fp;
     struct node *nodes;
@@ -1705,7 +1704,7 @@ read_mib(filename)
     if (fp == NULL)
        return NULL;
     nodes = parse(fp);
-    if (!nodes){
+    if (!nodes) {
        fprintf(stderr, "Mib table is bad.  Exiting\n");
        exit(1);
     }
@@ -1717,15 +1716,15 @@ read_mib(filename)
 
 #ifdef TEST
 main(argc, argv)
-    int argc;
-    char *argv[];
+     int argc;
+     char *argv[];
 {
     FILE *fp;
     struct node *nodes;
     struct tree *tp;
 
     fp = fopen("mib.txt", "r");
-    if (fp == NULL){
+    if (fp == NULL) {
        fprintf(stderr, "open failed\n");
        return 1;
     }
@@ -1739,22 +1738,21 @@ main(argc, argv)
 
 static int
 parseQuoteString(fp, token)
-    FILE *fp;
-    char *token;
+     FILE *fp;
+     char *token;
 {
     int ch;
 
     ch = ' ';
-    *token = '\0';                      /* make the token empty */
+    *token = '\0';             /* make the token empty */
 
-    while(ch != -1) {
-        ch = getc(fp);
+    while (ch != -1) {
+       ch = getc(fp);
        if (ch == '\n')
            Line++;
        else if (ch == '"') {
-            return QUOTESTRING;
-        }
-
+           return QUOTESTRING;
+       }
     }
 
     return 0;
@@ -1766,30 +1764,30 @@ parseQuoteString(fp, token)
  */
 static int
 tossObjectIdentifier(fp)
-    FILE *fp;
+     FILE *fp;
 {
     int ch;
 
-        ch = getc(fp);
+    ch = getc(fp);
 /*    ch = last; = ' '? */
     /* skip all white space */
-    while(isspace(ch) && ch != -1){
-        ch = getc(fp);
-        if (ch == '\n')
-            Line++;
+    while (isspace(ch) && ch != -1) {
+       ch = getc(fp);
+       if (ch == '\n')
+           Line++;
     }
     if (ch != '{')
-        return 0;
+       return 0;
 
-    while(ch != -1) {
-        ch = getc(fp);
+    while (ch != -1) {
+       ch = getc(fp);
 
-        if (ch == '\n')
-            Line++;
-        else if (ch == '}')
-            return OBJID;
+       if (ch == '\n')
+           Line++;
+       else if (ch == '}')
+           return OBJID;
     }
 
-/*    last = ch;*/
+/*    last = ch; */
     return 0;
 }
index 65646b1c7f38b24e73279b249bf8cbe765b82f80..187a9ff92718cd6e640142eb08724ddc1fbfb4d4 100644 (file)
@@ -1,3 +1,5 @@
+
+
 /***********************************************************
        Copyright 1989 by Carnegie Mellon University
 
@@ -11,6 +13,20428 @@ supporting documentation, and that the name of CMU not be
 used in advertising or publicity pertaining to distribution of the
 software without specific, written prior permission.  
 
+CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+******************************************************************/
+/*
+ * snmp_api.c - API for access to snmp.
+ */
+#define DEBUG_SNMPTRACE                0       /* set to 1 to print all SNMP actions */
+#define DEBUG_SNMPFULLDUMP     0       /* set to 1 to dump all SNMP packets */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#ifdef linux
+#include <arpa/inet.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#endif
+
+
+#include "asn1.h"
+#include "snmp.h"
+#include "snmp_impl.h"
+#include "snmp_api.h"
+#include "snmp_client.h"
+
+#define PACKET_LENGTH  4500
+
+#ifndef BSD4_3
+#define BSD4_2
+#endif
+
+#if !defined(BSD4_3) && !defined(linux) && !defined(sun)
+
+typedef long fd_mask;
+#define NFDBITS        (sizeof(fd_mask) * NBBY)        /* bits per mask */
+
+#define        FD_SET(n, p)    ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+#define        FD_CLR(n, p)    ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+#define        FD_ISSET(n, p)  ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+#define FD_ZERO(p)     bzero((char *)(p), sizeof(*(p)))
+#endif
+
+oid default_enterprise[] =
+{1, 3, 6, 1, 4, 1, 3, 1, 1};   /* enterprises.cmu.systems.cmuSNMP */
+
+#define DEFAULT_COMMUNITY   "public"
+#define DEFAULT_REMPORT            SNMP_PORT
+#define DEFAULT_ENTERPRISE  default_enterprise
+#define DEFAULT_TIME       0
+#define DEFAULT_MMS        1389        /* large, randomly picked for testing purposes */
+
+/*
+ * Internal information about the state of the snmp session.
+ */
+struct snmp_internal_session {
+    int sd;                    /* socket descriptor for this connection */
+    ipaddr addr;               /* address of connected peer */
+    struct request_list *requests;     /* Info about outstanding requests */
+};
+
+/*
+ * A list of all the outstanding requests for a particular session.
+ */
+struct request_list {
+    struct request_list *next_request;
+    u_long request_id;         /* request id */
+    int retries;               /* Number of retries */
+    u_long timeout;            /* length to wait for timeout */
+    struct timeval time;       /* Time this request was made */
+    struct timeval expire;     /* time this request is due to expire */
+    struct snmp_pdu *pdu;      /* The pdu for this request (saved so it can be retransmitted */
+};
+
+/*
+ * The list of active/open sessions.
+ */
+struct session_list {
+    struct session_list *next;
+    struct snmp_session *session;
+    struct snmp_internal_session *internal;
+};
+
+struct session_list *Sessions = NULL;
+
+u_long Reqid = 0;
+int snmp_errno = 0;
+
+char *api_errors[4] =
+{
+    "Unknown session",
+    "Unknown host",
+    "Invalid local port",
+    "Unknown Error"
+};
+
+
+void sync_with_agent();
+int parse_app_community_string();
+void snmp_synch_setup();
+int snmp_synch_response();
+void md5Digest();
+
+
+static char *
+api_errstring(snmp_errnumber)
+     int snmp_errnumber;
+{
+    if (snmp_errnumber <= SNMPERR_BAD_SESSION && snmp_errnumber >= SNMPERR_GENERR) {
+       return api_errors[snmp_errnumber + 4];
+    } else {
+       return "Unknown Error";
+    }
+}
+
+#if 0
+/*
+ * Gets initial request ID for all transactions.
+ */
+static void
+init_snmp()
+{
+    struct timeval tv;
+
+    gettimeofday(&tv, (struct timezone *) 0);
+    srandom(tv.tv_sec ^ tv.tv_usec);
+    Reqid = random();
+}
+
+#endif
+
+
+/*
+ * Dump snmp packet to stdout:
+ */
+static void
+snmp_print_packet(packet, length, addr, code)
+     char *packet;
+     int length;
+     ipaddr addr;
+     int code;
+{
+    if (length < 0) {
+       return;
+    }
+    if (code <= 0) {           /* received */
+       printf("\nReceived %4d bytes from ", length);
+    } else {                   /* sending */
+       printf("\nSending  %4d bytes to   ", length);
+    }
+    printf("%s:", inet_ntoa(addr.sin_addr));
+#if DEBUG_SNMPFULLDUMP
+    for (count = 0; count < length; count++) {
+       if ((count & 15) == 0) {
+           printf("\n  ");
+       }
+       printf("%02X ", (int) (packet[count] & 255));
+    }
+#endif
+    fflush(stdout);
+}
+
+#if DEBUG_SNMPTRACE
+/*
+ * Print request
+ */
+#define TRACE_SEND   (0)
+#define TRACE_RECV   (1)
+#define TRACE_TIMEOUT (2)
+static void
+snmp_print_trace(slp, rp, code)
+     struct session_list *slp;
+     struct request_list *rp;
+     int code;
+{
+    int reqid = 0, retries = 1;
+    if (rp) {
+       reqid = rp->request_id;
+       retries = rp->retries;
+    }
+    printf("\n Session %2d  ReqId %4d  ", slp->internal->sd, reqid);
+    switch (code) {
+    case TRACE_SEND:
+       printf("send pdu (%d)", retries);
+       break;
+    case TRACE_RECV:
+       printf("recv pdu");
+       break;
+    case TRACE_TIMEOUT:
+       printf("time out");
+       break;
+    }
+    fflush(stdout);
+}
+#endif /* DEBUG_SNMPTRACE */
+
+
+
+
+/*
+ * 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.
+ */
+struct snmp_session *
+snmp_open(session)
+     struct snmp_session *session;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp;
+    u_char *cp;
+    int sd;
+    u_long addr;
+    struct sockaddr_in me;
+    struct hostent *hp;
+    struct servent *servp;
+    extern int check_received_pkt();
+
+    /* Copy session structure and link into list */
+    slp = (struct session_list *) calloc(1, sizeof(struct session_list));
+    slp->internal = isp = (struct snmp_internal_session *) calloc(1, sizeof(struct snmp_internal_session));
+    bzero((char *) isp, sizeof(struct snmp_internal_session));
+    slp->internal->sd = -1;    /* mark it not set */
+    slp->session = (struct snmp_session *) calloc(1, sizeof(struct snmp_session));
+    bcopy((char *) session, (char *) slp->session, sizeof(struct snmp_session));
+    session = slp->session;
+    /* now link it in. */
+    slp->next = Sessions;
+    Sessions = slp;
+
+    /*
+     * session now points to the new structure that still contains pointers to
+     * data allocated elsewhere.  Some of this data is copied to space malloc'd
+     * here, and the pointer replaced with the new one.
+     */
+
+    if (session->peername != NULL) {
+       cp = (u_char *) calloc(1, (unsigned) strlen(session->peername) + 1);
+       strcpy((char *) cp, session->peername);
+       session->peername = (char *) cp;
+    }
+    if (session->retries == SNMP_DEFAULT_RETRIES)
+       session->retries = SNMP_API_DEFAULT_RETRIES;
+    if (session->timeout == SNMP_DEFAULT_TIMEOUT)
+       session->timeout = SNMP_API_DEFAULT_TIMEOUT;
+    if (session->MMS == 0)
+       session->MMS = DEFAULT_MMS;
+    isp->requests = NULL;
+
+
+    /* Fill in defaults if necessary */
+    if (session->community_len != SNMP_DEFAULT_COMMUNITY_LEN) {
+       if (*session->community == '+') {
+           session->community_len--;
+           cp = (u_char *) calloc(1, (unsigned) session->community_len);
+           bcopy((char *) session->community + 1, (char *) cp,
+               session->community_len);
+           session->version = SNMP_VERSION_2C;
+       } else {
+           cp = (u_char *) calloc(1, (unsigned) session->community_len);
+           bcopy((char *) session->community, (char *) cp,
+               session->community_len);
+       }
+
+    } else {
+       session->community_len = strlen(DEFAULT_COMMUNITY);
+       cp = (u_char *) calloc(1, (unsigned) session->community_len);
+       bcopy((char *) DEFAULT_COMMUNITY, (char *) cp, session->community_len);
+    }
+
+    /* Set up connections */
+    sd = socket(AF_INET, SOCK_DGRAM, 0);
+    if (sd < 0) {
+       perror("socket");
+       snmp_errno = SNMPERR_GENERR;
+       if (!snmp_close(session)) {
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+           exit(1);
+       }
+       return 0;
+    }
+    isp->sd = sd;
+
+    if (session->peername != SNMP_DEFAULT_PEERNAME) {
+       if ((addr = inet_addr(session->peername)) != -1) {
+           bcopy((char *) &addr, (char *) &isp->addr.sin_addr, sizeof(isp->addr.sin_addr));
+       } else {
+           hp = gethostbyname(session->peername);
+           if (hp == NULL) {
+               fprintf(stderr, "unknown host: %s\n", session->peername);
+               snmp_errno = SNMPERR_BAD_ADDRESS;
+               if (!snmp_close(session)) {
+                   fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+                   exit(2);
+               }
+               return 0;
+           } else {
+               bcopy((char *) hp->h_addr, (char *) &isp->addr.sin_addr, hp->h_length);
+           }
+       }
+       isp->addr.sin_family = AF_INET;
+       if (session->remote_port == SNMP_DEFAULT_REMPORT) {
+           /*servp = getservbyname("snmp", "udp"); */
+           servp = NULL;
+           if (servp != NULL) {
+               isp->addr.sin_port = servp->s_port;
+           } else {
+               isp->addr.sin_port = htons(SNMP_PORT);
+           }
+       } else {
+           isp->addr.sin_port = htons(session->remote_port);
+       }
+    } else {
+       isp->addr.sin_addr.s_addr = SNMP_DEFAULT_ADDRESS;
+    }
+
+    me.sin_family = AF_INET;
+    me.sin_addr.s_addr = INADDR_ANY;
+    me.sin_port = htons(session->local_port);
+    if (bind(sd, (struct sockaddr *) &me, sizeof(me)) != 0) {
+       perror("bind");
+       snmp_errno = SNMPERR_BAD_LOCPORT;
+       if (!snmp_close(session)) {
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n",
+               api_errstring(snmp_errno));
+           exit(3);
+       }
+       return 0;
+    }
+    if (*cp == '/') {
+       session->authenticator = check_received_pkt;
+       sync_with_agent(session);
+       parse_app_community_string(session);
+       session->qoS |= USEC_QOS_GENREPORT;
+    }
+    /* replace comm pointer with pointer to new data: */
+    session->community = cp;
+
+    return session;
+}
+
+void
+sync_with_agent(session)
+     struct snmp_session *session;
+{
+    struct snmp_pdu *pdu, *response = 0;
+    int status;
+
+    session->qoS = USEC_QOS_GENREPORT;
+    session->userLen = 6;
+    session->version = SNMP_VERSION_2;
+    strcpy(session->userName, "public");
+
+    snmp_synch_setup(session);
+    pdu = snmp_pdu_create(GET_REQ_MSG);
+    status = snmp_synch_response(session, pdu, &response);
+
+    if (status == STAT_SUCCESS) {
+       memcpy(session->agentID, response->params.agentID, 12);
+
+       /* save the clocks -- even though they are not authentic */
+       session->agentBoots = response->params.agentBoots;
+       session->agentTime = response->params.agentTime;
+       session->agentClock = response->params.agentTime - time(NULL);
+
+    } else {
+       if (status == STAT_TIMEOUT) {
+           printf("No Response from %s\n", session->peername);
+       } else {                /* status == STAT_ERROR */
+           printf("An error occurred, Quitting\n");
+       }
+       exit(-1);
+    }
+
+    /** freed to early: 
+      snmp_free_pdu(pdu);
+      if (response) snmp_free_pdu(response);
+     **/
+}
+#if 1/***/ BUG_SNMPTRACE */cked for testing purposes */e key!  replace...
+     */
+ * \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 1\ 1\0\0\0\0\0\0\0\19\7fÿ¯ùsnmplib/snmp_api.c\0c\0\0.h\0\0\0\18\7fÿ°\85\10\0<Ðlib/snmp_api.c~\0~\0\0ñ\0\0\0\18\7fÿ±\1e\10\0\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\0\0\0\18\7fÿ±«\10\0=\10\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\0\0\0\18\7fÿ²\1d\10\0=0\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\0\0\0\18\7fÿ²\8a\10\0=P\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\0\0\0\18\7fÿ³
+\10\0=p\7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\0\0\0\18\7fÿ³\82\0\0\0\ 1\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\0\0\0Á\7fÿ³ù\0\0\0\10\7fÿ´\10\10\0\0%\0\19\0\15\0\0\10\0D(\0\0\0\10\7fÿ´_\10\0\0\0\ 2\\0\0\0\0\10\0\0\0\0\10\7fÿ´©\10\0=\98\0\0\ 24\0\0\0\0\10\0\0\0\0\10\7fÿ´ø\10\0\0\0\ 2H\0\0\0\0\10\0\0\0\0\10\7fÿµB\10\0>\10\7fÿµ]\7fÿµm\7fÿµz\0\0\0\10\7fÿµ \10\0>(\7fÿµ·\7fÿµÉ\7fÿµÖ\0\0\0\10\7fÿµï\10\0>@\7fÿ¶\12\7fÿ¶ \7fÿ¶4\0\0\0\10\7fÿ¶P\0\0\0\ 1\7fÿ¶r\7fÿ¶~\7fÿ¶\88\0\0\00\7fÿ¶\9f\10\0\7fÿ¶·\0\0\0\0\7fÿ¶Ù\10\0\89è\7fÿ·\ 1\0\0\0\0\7fÿ·#\7fÿ·/\7fÿ·>\10\0>X\7fÿ·V\0\0\03\0\0\0\0/usr/people/wessels/.indent.pro\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\ 1\0\0\0\0\7fÿ¯è\7fÿ¯ù\7fÿ°\f\7fÿ°\e\7fÿ°.\7fÿ°?\7fÿ°M\7fÿ°[\7fÿ°p\7fÿ°\85\7fÿ°\95\7fÿ°£\7fÿ°²\7fÿ°Å\7fÿ°Û\7fÿ°ñ\7fÿ±
+\7fÿ±\1e\7fÿ±2\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\7fÿ±\99\7fÿ±«\7fÿ±º\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\7fÿ²\ f\7fÿ²\1d\7fÿ²2\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\7fÿ²\7f\7fÿ²\8a\7fÿ²\99\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\7fÿ²ö\7fÿ³
+\7fÿ³ \7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\7fÿ³s\7fÿ³\82\7fÿ³\91\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\7fÿ³ç\7fÿ³ù\7fÿ´\ 4\7fÿ´\10\7fÿ´\1e\7fÿ´)\7fÿ´3\7fÿ´C\7fÿ´O\7fÿ´_\7fÿ´k\7fÿ´t\7fÿ´\81\7fÿ´\8f\7fÿ´\9f\7fÿ´©\7fÿ´·\7fÿ´Å\7fÿ´Ò\7fÿ´Ý\7fÿ´í\7fÿ´ø\7fÿµ\ 3\7fÿµ\10\7fÿµ\1d\7fÿµ)\7fÿµ7\7fÿµB\7fÿµM\7fÿµ]\7fÿµm\7fÿµz\7fÿµ\89\7fÿµ \7fÿµ«\7fÿµ·\7fÿµÉ\7fÿµÖ\7fÿµâ\7fÿµï\7fÿ¶\ 3\7fÿ¶\12\7fÿ¶ \7fÿ¶4\7fÿ¶?\7fÿ¶P\7fÿ¶b\7fÿ¶r\7fÿ¶~\7fÿ¶\88\7fÿ¶\94\7fÿ¶\9f\7fÿ¶«\7fÿ¶·\7fÿ¶É\7fÿ¶Ù\7fÿ¶í\7fÿ·\ 1\7fÿ·\15\7fÿ·#\7fÿ·/\7fÿ·>\7fÿ·L\7fÿ·V\7fÿ·f\7fÿ·q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0@    \0\0\0\0
+
+/***********************************************************
+       Copyright 1989 by Carnegie Mellon University
+
+                      All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the name of CMU not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+******************************************************************/
+/*
+ * snmp_api.c - API for access to snmp.
+ */
+#define DEBUG_SNMPTRACE                0       /* set to 1 to print all SNMP actions */
+#define DEBUG_SNMPFULLDUMP     0       /* set to 1 to dump all SNMP packets */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#ifdef linux
+#include <arpa/inet.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#endif
+
+
+#include "asn1.h"
+#include "snmp.h"
+#include "snmp_impl.h"
+#include "snmp_api.h"
+#include "snmp_client.h"
+
+#define PACKET_LENGTH  4500
+
+#ifndef BSD4_3
+#define BSD4_2
+#endif
+
+#if !defined(BSD4_3) && !defined(linux) && !defined(sun)
+
+typedef long fd_mask;
+#define NFDBITS        (sizeof(fd_mask) * NBBY)        /* bits per mask */
+
+#define        FD_SET(n, p)    ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+#define        FD_CLR(n, p)    ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+#define        FD_ISSET(n, p)  ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+#define FD_ZERO(p)     bzero((char *)(p), sizeof(*(p)))
+#endif
+
+oid default_enterprise[] =
+{1, 3, 6, 1, 4, 1, 3, 1, 1};   /* enterprises.cmu.systems.cmuSNMP */
+
+#define DEFAULT_COMMUNITY   "public"
+#define DEFAULT_REMPORT            SNMP_PORT
+#define DEFAULT_ENTERPRISE  default_enterprise
+#define DEFAULT_TIME       0
+#define DEFAULT_MMS        1389        /* large, randomly picked for testing purposes */
+
+/*
+ * Internal information about the state of the snmp session.
+ */
+struct snmp_internal_session {
+    int sd;                    /* socket descriptor for this connection */
+    ipaddr addr;               /* address of connected peer */
+    struct request_list *requests;     /* Info about outstanding requests */
+};
+
+/*
+ * A list of all the outstanding requests for a particular session.
+ */
+struct request_list {
+    struct request_list *next_request;
+    u_long request_id;         /* request id */
+    int retries;               /* Number of retries */
+    u_long timeout;            /* length to wait for timeout */
+    struct timeval time;       /* Time this request was made */
+    struct timeval expire;     /* time this request is due to expire */
+    struct snmp_pdu *pdu;      /* The pdu for this request (saved so it can be retransmitted */
+};
+
+/*
+ * The list of active/open sessions.
+ */
+struct session_list {
+    struct session_list *next;
+    struct snmp_session *session;
+    struct snmp_internal_session *internal;
+};
+
+struct session_list *Sessions = NULL;
+
+u_long Reqid = 0;
+int snmp_errno = 0;
+
+char *api_errors[4] =
+{
+    "Unknown session",
+    "Unknown host",
+    "Invalid local port",
+    "Unknown Error"
+};
+
+
+void sync_with_agent();
+int parse_app_community_string();
+void snmp_synch_setup();
+int snmp_synch_response();
+void md5Digest();
+
+
+static char *
+api_errstring(snmp_errnumber)
+     int snmp_errnumber;
+{
+    if (snmp_errnumber <= SNMPERR_BAD_SESSION && snmp_errnumber >= SNMPERR_GENERR) {
+       return api_errors[snmp_errnumber + 4];
+    } else {
+       return "Unknown Error";
+    }
+}
+
+#if 0
+/*
+ * Gets initial request ID for all transactions.
+ */
+static void
+init_snmp()
+{
+    struct timeval tv;
+
+    gettimeofday(&tv, (struct timezone *) 0);
+    srandom(tv.tv_sec ^ tv.tv_usec);
+    Reqid = random();
+}
+
+#endif
+
+
+/*
+ * Dump snmp packet to stdout:
+ */
+static void
+snmp_print_packet(packet, length, addr, code)
+     char *packet;
+     int length;
+     ipaddr addr;
+     int code;
+{
+    if (length < 0) {
+       return;
+    }
+    if (code <= 0) {           /* received */
+       printf("\nReceived %4d bytes from ", length);
+    } else {                   /* sending */
+       printf("\nSending  %4d bytes to   ", length);
+    }
+    printf("%s:", inet_ntoa(addr.sin_addr));
+#if DEBUG_SNMPFULLDUMP
+    for (count = 0; count < length; count++) {
+       if ((count & 15) == 0) {
+           printf("\n  ");
+       }
+       printf("%02X ", (int) (packet[count] & 255));
+    }
+#endif
+    fflush(stdout);
+}
+
+#if DEBUG_SNMPTRACE
+/*
+ * Print request
+ */
+#define TRACE_SEND   (0)
+#define TRACE_RECV   (1)
+#define TRACE_TIMEOUT (2)
+static void
+snmp_print_trace(slp, rp, code)
+     struct session_list *slp;
+     struct request_list *rp;
+     int code;
+{
+    int reqid = 0, retries = 1;
+    if (rp) {
+       reqid = rp->request_id;
+       retries = rp->retries;
+    }
+    printf("\n Session %2d  ReqId %4d  ", slp->internal->sd, reqid);
+    switch (code) {
+    case TRACE_SEND:
+       printf("send pdu (%d)", retries);
+       break;
+    case TRACE_RECV:
+       printf("recv pdu");
+       break;
+    case TRACE_TIMEOUT:
+       printf("time out");
+       break;
+    }
+    fflush(stdout);
+}
+#endif /* DEBUG_SNMPTRACE */
+
+
+
+
+/*
+ * 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.
+ */
+struct snmp_session *
+snmp_open(session)
+     struct snmp_session *session;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp;
+    u_char *cp;
+    int sd;
+    u_long addr;
+    struct sockaddr_in me;
+    struct hostent *hp;
+    struct servent *servp;
+    extern int check_received_pkt();
+
+    /* Copy session structure and link into list */
+    slp = (struct session_list *) calloc(1, sizeof(struct session_list));
+    slp->internal = isp = (struct snmp_internal_session *) calloc(1, sizeof(struct snmp_internal_session));
+    bzero((char *) isp, sizeof(struct snmp_internal_session));
+    slp->internal->sd = -1;    /* mark it not set */
+    slp->session = (struct snmp_session *) calloc(1, sizeof(struct snmp_session));
+    bcopy((char *) session, (char *) slp->session, sizeof(struct snmp_session));
+    session = slp->session;
+    /* now link it in. */
+    slp->next = Sessions;
+    Sessions = slp;
+
+    /*
+     * session now points to the new structure that still contains pointers to
+     * data allocated elsewhere.  Some of this data is copied to space malloc'd
+     * here, and the pointer replaced with the new one.
+     */
+
+    if (session->peername != NULL) {
+       cp = (u_char *) calloc(1, (unsigned) strlen(session->peername) + 1);
+       strcpy((char *) cp, session->peername);
+       session->peername = (char *) cp;
+    }
+    if (session->retries == SNMP_DEFAULT_RETRIES)
+       session->retries = SNMP_API_DEFAULT_RETRIES;
+    if (session->timeout == SNMP_DEFAULT_TIMEOUT)
+       session->timeout = SNMP_API_DEFAULT_TIMEOUT;
+    if (session->MMS == 0)
+       session->MMS = DEFAULT_MMS;
+    isp->requests = NULL;
+
+
+    /* Fill in defaults if necessary */
+    if (session->community_len != SNMP_DEFAULT_COMMUNITY_LEN) {
+       if (*session->community == '+') {
+           session->community_len--;
+           cp = (u_char *) calloc(1, (unsigned) session->community_len);
+           bcopy((char *) session->community + 1, (char *) cp,
+               session->community_len);
+           session->version = SNMP_VERSION_2C;
+       } else {
+           cp = (u_char *) calloc(1, (unsigned) session->community_len);
+           bcopy((char *) session->community, (char *) cp,
+               session->community_len);
+       }
+
+    } else {
+       session->community_len = strlen(DEFAULT_COMMUNITY);
+       cp = (u_char *) calloc(1, (unsigned) session->community_len);
+       bcopy((char *) DEFAULT_COMMUNITY, (char *) cp, session->community_len);
+    }
+
+    /* Set up connections */
+    sd = socket(AF_INET, SOCK_DGRAM, 0);
+    if (sd < 0) {
+       perror("socket");
+       snmp_errno = SNMPERR_GENERR;
+       if (!snmp_close(session)) {
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+           exit(1);
+       }
+       return 0;
+    }
+    isp->sd = sd;
+
+    if (session->peername != SNMP_DEFAULT_PEERNAME) {
+       if ((addr = inet_addr(session->peername)) != -1) {
+           bcopy((char *) &addr, (char *) &isp->addr.sin_addr, sizeof(isp->addr.sin_addr));
+       } else {
+           hp = gethostbyname(session->peername);
+           if (hp == NULL) {
+               fprintf(stderr, "unknown host: %s\n", session->peername);
+               snmp_errno = SNMPERR_BAD_ADDRESS;
+               if (!snmp_close(session)) {
+                   fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+                   exit(2);
+               }
+               return 0;
+           } else {
+               bcopy((char *) hp->h_addr, (char *) &isp->addr.sin_addr, hp->h_length);
+           }
+       }
+       isp->addr.sin_family = AF_INET;
+       if (session->remote_port == SNMP_DEFAULT_REMPORT) {
+           /*servp = getservbyname("snmp", "udp"); */
+           servp = NULL;
+           if (servp != NULL) {
+               isp->addr.sin_port = servp->s_port;
+           } else {
+               isp->addr.sin_port = htons(SNMP_PORT);
+           }
+       } else {
+           isp->addr.sin_port = htons(session->remote_port);
+       }
+    } else {
+       isp->addr.sin_addr.s_addr = SNMP_DEFAULT_ADDRESS;
+    }
+
+    me.sin_family = AF_INET;
+    me.sin_addr.s_addr = INADDR_ANY;
+    me.sin_port = htons(session->local_port);
+    if (bind(sd, (struct sockaddr *) &me, sizeof(me)) != 0) {
+       perror("bind");
+       snmp_errno = SNMPERR_BAD_LOCPORT;
+       if (!snmp_close(session)) {
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n",
+               api_errstring(snmp_errno));
+           exit(3);
+       }
+       return 0;
+    }
+    if (*cp == '/') {
+       session->authenticator = check_received_pkt;
+       sync_with_agent(session);
+       parse_app_community_string(session);
+       session->qoS |= USEC_QOS_GENREPORT;
+    }
+    /* replace comm pointer with pointer to new data: */
+    session->community = cp;
+
+    return session;
+}
+
+void
+sync_with_agent(session)
+     struct snmp_session *session;
+{
+    struct snmp_pdu *pdu, *response = 0;
+    int status;
+
+    session->qoS = USEC_QOS_GENREPORT;
+    session->userLen = 6;
+    session->version = SNMP_VERSION_2;
+    strcpy(session->userName, "public");
+
+    snmp_synch_setup(session);
+    pdu = snmp_pdu_create(GET_REQ_MSG);
+    status = snmp_synch_response(session, pdu, &response);
+
+    if (status == STAT_SUCCESS) {
+       memcpy(session->agentID, response->params.agentID, 12);
+
+       /* save the clocks -- even though they are not authentic */
+       session->agentBoots = response->params.agentBoots;
+       session->agentTime = response->params.agentTime;
+       session->agentClock = response->params.agentTime - time(NULL);
+
+    } else {
+       if (status == STAT_TIMEOUT) {
+           printf("No Response from %s\n", session->peername);
+       } else {                /* status == STAT_ERROR */
+           printf("An error occurred, Quitting\n");
+       }
+       exit(-1);
+    }
+
+    /** freed to early: 
+      snmp_free_pdu(pdu);
+      if (response) snmp_free_pdu(response);
+     **/
+}
+ring(fp, token)
+     FILE *fp;
+     char *token;
+{
+    int ch;
+
+    ch = ' ';
+    *token = '\0';             /* make the token empty */
+
+    while (ch != -1) {
+       ch = getc(fp);
+       if (ch == '\n')
+           Line++;
+       else if (ch == '"') {
+           return QUOTESTRING;
+       }
+    }
+
+    return 0;
+}
+
+/*
+ * This routine parses a string like  { blah blah blah } and returns OBJID if
+ * it is well formed, and NULL if not.
+ */
+static int
+tossObjectIdentifier(fp)
+     FILE *fp;
+{
+    int ch;
+
+    ch = getc(fp);
+/*    ch = last; = ' '? */
+    /* skip all white space */
+    while (isspace(ch) && ch != -1) {
+       ch = getc(fp);
+       if (ch == '\n')
+           Line++;
+    }
+    if (ch != '{')
+       return 0;
+
+    while (ch != -1) {
+       ch = getc(fp);
+
+       if (ch == '\n')
+           Line++;
+       else if (ch == '}')
+           return OBJID;
+    }
+
+/*    last = ch; */
+    return 0;
+}
+rn 0;
+    }
+    /*
+     * Optional parts of the OBJECT-TYPE macro
+     */
+    type = get_token(fp, token);
+    while (type != EQUALS) {
+       switch (type) {
+       case DESCRIPTION:
+           type = get_token(fp, token);
+           if (type != QUOTESTRING) {
+               print_error("Bad DESCRIPTION", token, type);
+               free_node(np);
+               return 0;
+           }
+#ifdef TEST
+           printf("Description== \"%.50s\"\n", quoted_string_buffer);
+#endif
+           np->description = quoted_string_buffer;
+           quoted_string_buffer = (char *) calloc(1, MAXQUOTESTR);
+           break;
+
+       case REFERENCE:
+           type = get_token(fp, token);
+           if (type != QUOTESTRING) {
+               print_error("Bad DESCRIPTION", token, type);
+               free_node(np);
+               return 0;
+           }
+           break;
+       case INDEX:
+       case DEFVAL:
+       case AUGMENTS:
+       case NUM_ENTRIES:
+           if (tossObjectIdentifier(fp) != OBJID) {
+               print_error("Bad Object Identifier", token, type);
+               free_node(np);
+               return 0;
+           }
+           break;
+
+       default:
+           print_error("Bad format of optional clauses", token, type);
+           free_node(np);
+           return 0;
+
+       }
+       type = get_token(fp, token);
+    }
+    if (type != EQUALS) {
+       print_error("Bad format", token, type);
+       free_node(np);
+       return 0;
+    }
+    length = getoid(fp, oid, 32);
+    if (length > 1 && length <= 32) {
+       /* just take the last pair in the oid list */
+       if (oid[length - 2].label)
+           strncpy(np->parent, oid[length - 2].label, MAXLABEL);
+       strcpy(np->label, name);
+       if (oid[length - 1].subid != -1)
+           np->subid = oid[length - 1].subid;
+       else
+           print_error("Warning: This entry is pretty silly", np->label, type);
+    } else {
+       print_error("No end to oid", (char *) NULL, type);
+       free_node(np);
+       np = 0;
+    }
+    /* free oid array */
+    for (count = 0; count < length; count++) {
+       if (oid[count].label)
+           free(oid[count].label);
+       oid[count].label = 0;
+    }
+    return np;
+}
+
+
+/*
+ * Parses an OBJECT GROUP macro.
+ * Returns 0 on error.
+ */
+static struct node *
+parse_objectgroup(fp, name)
+     FILE *fp;
+     char *name;
+{
+    int type;
+    char token[MAXTOKEN];
+    int count, length;
+    struct subid oid[32];
+    struct node *np;
+
+    np = (struct node *) Malloc(sizeof(struct node));
+    np->type = 0;
+    np->next = 0;
+    np->enums = 0;
+    np->description = NULL;    /* default to an empty description */
+    type = get_token(fp, token);
+    while (type != EQUALS) {
+       switch (type) {
+       case DESCRIPTION:
+           type = get_token(fp, token);
+           if (type != QUOTESTRING) {
+               print_error("Bad DESCRIPTION", token, type);
+               free_node(np);
+               return 0;
+           }
+#ifdef TEST
+           printf("Description== \"%.50s\"\n", quoted_string_buffer);
+#endif
+           np->description = quoted_string_buffer;
+           quoted_string_buffer = (char *) calloc(1, MAXQUOTESTR);
+           break;
+
+       default:
+           /* NOTHING */
+           break;
+       }
+       type = get_token(fp, token);
+    }
+    length = getoid(fp, oid, 32);
+    if (length > 1 && length <= 32) {
+       /* just take the last pair in the oid list */
+       if (oid[length - 2].label)
+           strncpy(np->parent, oid[length - 2].label, MAXLABEL);
+       strcpy(np->label, name);
+       if (oid[length - 1].subid != -1)
+           np->subid = oid[length - 1].subid;
+       else
+           print_error("Warning: This entry is pretty silly", np->label, type);
+    } else {
+       print_error("No end to oid", (char *) NULL, type);
+       free_node(np);
+       np = 0;
+    }
+    /* free oid array */
+    for (count = 0; count < length; count++) {
+       if (oid[count].label)
+           free(oid[count].label);
+       oid[count].label = 0;
+    }
+    return np;
+}
+
+/*
+ * Parses a NOTIFICATION-TYPE macro.
+ * Returns 0 on error.
+ */
+static struct node *
+parse_notificationDefinition(fp, name)
+     FILE *fp;
+     char *name;
+{
+    int type;
+    char token[MAXTOKEN];
+    int count, length;
+    struct subid oid[32];
+    struct node *np;
+
+    np = (struct node *) Malloc(sizeof(struct node));
+    np->type = 0;
+    np->next = 0;
+    np->enums = 0;
+    np->description = NULL;    /* default to an empty description */
+    type = get_token(fp, token);
+    while (type != EQUALS) {
+       switch (type) {
+       case DESCRIPTION:
+           type = get_token(fp, token);
+           if (type != QUOTESTRING) {
+               print_error("Bad DESCRIPTION", token, type);
+               free_node(np);
+               return 0;
+           }
+#ifdef TEST
+           printf("Description== \"%.50s\"\n", quoted_string_buffer);
+#endif
+           np->description = quoted_string_buffer;
+           quoted_string_buffer = (char *) calloc(1, MAXQUOTESTR);
+           break;
+
+       default:
+           /\10\0BÐ+= m\0\0
+È      /* \0\0\0\0*/ B\10\04¨NMPT\10\ 1^h */c\0\0\0\0for testing purposes */e key!  replace...
+     */
+ * \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 1\ 1\0\0\0\0\0\0\0\19\7fÿ¯ùsnmplib/snmp_api.c\0c\0\0.h\0\0\0\18\7fÿ°\85\10\0<Ðlib/snmp_api.c~\0~\0\0ñ\0\0\0\18\7fÿ±\1e\10\0\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\0\0\0\18\7fÿ±«\10\0=\10\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\0\0\0\18\7fÿ²\1d\10\0=0\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\0\0\0\18\7fÿ²\8a\10\0=P\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\0\0\0\18\7fÿ³
+\10\0=p\7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\0\0\0\18\7fÿ³\82\0\0\0\ 1\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\0\0\0Á\7fÿ³ù\0\0\0\10\7fÿ´\10\10\0\0%\0\19\0\15\0\0\10\0D(\0\0\0\10\7fÿ´_\10\0\0\0\ 2\\0\0\0\0\10\0\0\0\0\10\7fÿ´©\10\0=\98\0\0\ 24\0\0\0\0\10\0\0\0\0\10\7fÿ´ø\10\0\0\0\ 2H\0\0\0\0\10\0\0\0\0\10\7fÿµB\10\0>\10\7fÿµ]\7fÿµm\7fÿµz\0\0\0\10\7fÿµ \10\0>(\7fÿµ·\7fÿµÉ\7fÿµÖ\0\0\0\10\7fÿµï\10\0>@\7fÿ¶\12\7fÿ¶ \7fÿ¶4\0\0\0\10\7fÿ¶P\0\0\0\ 1\7fÿ¶r\7fÿ¶~\7fÿ¶\88\0\0\00\7fÿ¶\9f\10\0\7fÿ¶·\0\0\0\0\7fÿ¶Ù\10\0\89è\7fÿ·\ 1\0\0\0\0\7fÿ·#\7fÿ·/\7fÿ·>\10\0>X\7fÿ·V\0\0\03\0\0\0\0/usr/people/wessels/.indent.pro\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\ 1\0\0\0\0\7fÿ¯è\7fÿ¯ù\7fÿ°\f\7fÿ°\e\7fÿ°.\7fÿ°?\7fÿ°M\7fÿ°[\7fÿ°p\7fÿ°\85\7fÿ°\95\7fÿ°£\7fÿ°²\7fÿ°Å\7fÿ°Û\7fÿ°ñ\7fÿ±
+\7fÿ±\1e\7fÿ±2\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\7fÿ±\99\7fÿ±«\7fÿ±º\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\7fÿ²\ f\7fÿ²\1d\7fÿ²2\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\7fÿ²\7f\7fÿ²\8a\7fÿ²\99\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\7fÿ²ö\7fÿ³
+\7fÿ³ \7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\7fÿ³s\7fÿ³\82\7fÿ³\91\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\7fÿ³ç\7fÿ³ù\7fÿ´\ 4\7fÿ´\10\7fÿ´\1e\7fÿ´)\7fÿ´3\7fÿ´C\7fÿ´O\7fÿ´_\7fÿ´k\7fÿ´t\7fÿ´\81\7fÿ´\8f\7fÿ´\9f\7fÿ´©\7fÿ´·\7fÿ´Å\7fÿ´Ò\7fÿ´Ý\7fÿ´í\7fÿ´ø\7fÿµ\ 3\7fÿµ\10\7fÿµ\1d\7fÿµ)\7fÿµ7\7fÿµB\7fÿµM\7fÿµ]\7fÿµm\7fÿµz\7fÿµ\89\7fÿµ \7fÿµ«\7fÿµ·\7fÿµÉ\7fÿµÖ\7fÿµâ\7fÿµï\7fÿ¶\ 3\7fÿ¶\12\7fÿ¶ \7fÿ¶4\7fÿ¶?\7fÿ¶P\7fÿ¶b\7fÿ¶r\7fÿ¶~\7fÿ¶\88\7fÿ¶\94\7fÿ¶\9f\7fÿ¶«\7fÿ¶·\7fÿ¶É\7fÿ¶Ù\7fÿ¶í\7fÿ·\ 1\7fÿ·\15\7fÿ·#\7fÿ·/\7fÿ·>\7fÿ·L\7fÿ·V\7fÿ·f\7fÿ·q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\0\0\0°\0\0\0\ 4\0\0\0\0\0\0\0\b\10\0>X\0\0\0\f\10\0\0\0\0\10\0\0\0\0\0\0\0\14\0\0\0\14\0\0\0\14\0\0\0\18\0\0\0\18\0\0\0\18\0\0\0\1c\0\0\0\1c\0\0\0\1c\0\0\0\1c\0\0\0 \0\0\0 \0\0\0 \0\0\0$\0\0\0\v\0\0\0\e\0\0\0\19\0\0\0\v\0\0\0\e\0\0\0@\0\0\0\0\0\0\0\0\0\0\0\0\10\0,\b\0\0\0\1a\10\02\88\0\0\0\1a\0\0\0\0\0\0\0\1a\10\0\85\b\0\0\0\0\10\0>X\0\0\0\0\0\0\0\0\0\0\0\0\10\0\82à\0\0\0\0\0\0\ 1C\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e0\0\0\0\v\0\0\0\e\0\0\0\18\0\0\0\v\0\0\0\1a\0\0\0\17\0\0\0\v\0\0\0 \0\0\0\0\10\0\8d¸ude/snmp_groupvars.h~\0\0\b\0\0\0\b\0\0\0 \0\0\0\0\10\0\8dàude/snmp_groupvars.h\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8eX\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e\80\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e¨\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8eÐ\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\0\0\0\ 1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\84©\0\0\0\0/***********************************************************
+       Copyright 1989 by Carnegie Mellon University
+
+                      All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the name of CMU not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+******************************************************************/
+/*
+ * snmp_api.c - API for access to snmp.
+ */
+#define DEBUG_SNMPTRACE                0 /* set to 1 to print all SNMP actions */
+#define DEBUG_SNMPFULLDUMP     0 /* set to 1 to dump all SNMP packets */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#ifdef linux
+#include <arpa/inet.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#endif
+
+
+#include "asn1.h"
+#include "snmp.h"
+#include "snmp_impl.h"
+#include "snmp_api.h"
+#include "snmp_client.h"
+
+#define PACKET_LENGTH  4500
+
+#ifndef BSD4_3
+#define BSD4_2
+#endif
+
+#if !defined(BSD4_3) && !defined(linux) && !defined(sun)
+
+typedef long   fd_mask;
+#define NFDBITS        (sizeof(fd_mask) * NBBY)        /* bits per mask */
+
+#define        FD_SET(n, p)    ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+#define        FD_CLR(n, p)    ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+#define        FD_ISSET(n, p)  ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+#define FD_ZERO(p)     bzero((char *)(p), sizeof(*(p)))
+#endif
+
+oid default_enterprise[] = {1, 3, 6, 1, 4, 1, 3, 1, 1}; /* enterprises.cmu.systems.cmuSNMP */
+
+#define DEFAULT_COMMUNITY   "public"
+#define DEFAULT_REMPORT            SNMP_PORT
+#define DEFAULT_ENTERPRISE  default_enterprise
+#define DEFAULT_TIME       0
+#define DEFAULT_MMS        1389 /* large, randomly picked for testing purposes */
+
+/*
+ * Internal information about the state of the snmp session.
+ */
+struct snmp_internal_session {
+    int            sd;         /* socket descriptor for this connection */
+    ipaddr  addr;      /* address of connected peer */
+    struct request_list *requests;/* Info about outstanding requests */
+};
+
+/*
+ * A list of all the outstanding requests for a particular session.
+ */
+struct request_list {
+    struct request_list *next_request;
+    u_long  request_id;        /* request id */
+    int            retries;    /* Number of retries */
+    u_long timeout;    /* length to wait for timeout */
+    struct timeval time; /* Time this request was made */
+    struct timeval expire;  /* time this request is due to expire */
+    struct snmp_pdu *pdu;   /* The pdu for this request (saved so it can be retransmitted */
+};
+
+/*
+ * The list of active/open sessions.
+ */
+struct session_list {
+    struct session_list *next;
+    struct snmp_session *session;
+    struct snmp_internal_session *internal;
+};
+
+struct session_list *Sessions = NULL;
+
+u_long Reqid = 0;
+int snmp_errno = 0;
+
+char *api_errors[4] = {
+    "Unknown session",
+    "Unknown host",
+    "Invalid local port",
+    "Unknown Error"
+};
+
+
+void sync_with_agent();
+int parse_app_community_string();
+void snmp_synch_setup();
+int snmp_synch_response();
+void md5Digest();
+
+
+static char *
+api_errstring(snmp_errnumber)
+    int        snmp_errnumber;
+{
+    if (snmp_errnumber <= SNMPERR_BAD_SESSION && snmp_errnumber >= SNMPERR_GENERR){
+       return api_errors[snmp_errnumber + 4];
+    } else {
+       return "Unknown Error";
+    }
+}
+
+#if 0
+/*
+ * Gets initial request ID for all transactions.
+ */
+static void
+init_snmp(){
+    struct timeval tv;
+
+    gettimeofday(&tv, (struct timezone *)0);
+    srandom(tv.tv_sec ^ tv.tv_usec);
+    Reqid = random();
+}
+#endif
+
+
+/*
+ * Dump snmp packet to stdout:
+ */
+static void
+snmp_print_packet(packet, length, addr, code)
+  char *packet; 
+  int length; 
+  ipaddr addr; 
+  int code;
+{
+  if(length < 0) {
+    return;
+  }
+  if (code <= 0) { /* received */
+    printf("\nReceived %4d bytes from ", length);
+  }
+  else { /* sending */
+    printf("\nSending  %4d bytes to   ", length);
+  }
+  printf("%s:", inet_ntoa(addr.sin_addr));
+#if DEBUG_SNMPFULLDUMP
+  for (count = 0; count < length; count++) {
+    if ((count & 15) == 0) {
+      printf("\n  ");
+    }
+    printf("%02X ", (int)(packet[count]&255));
+  }
+#endif
+  fflush(stdout);
+}
+
+#if DEBUG_SNMPTRACE
+/*
+ * Print request
+ */
+#define TRACE_SEND   (0)
+#define TRACE_RECV   (1)
+#define TRACE_TIMEOUT (2)
+static void
+snmp_print_trace(slp, rp, code)
+  struct session_list *slp;
+  struct request_list *rp;
+  int code;
+{
+  int reqid=0, retries=1;
+  if( rp ){
+    reqid = rp->request_id;
+    retries = rp->retries;
+  }  
+  printf("\n Session %2d  ReqId %4d  ", slp->internal->sd, reqid);
+  switch(code)
+    { 
+    case TRACE_SEND:    printf("send pdu (%d)", retries);break; 
+    case TRACE_RECV:    printf("recv pdu");break; 
+    case TRACE_TIMEOUT: printf("time out");break; 
+    }
+  fflush(stdout);
+}
+#endif /* DEBUG_SNMPTRACE */
+
+
+
+
+/*
+ * 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.
+ */
+struct snmp_session *
+snmp_open(session)
+    struct snmp_session *session;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp;
+    u_char *cp;
+    int sd;
+    u_long addr;
+    struct sockaddr_in me;
+    struct hostent *hp;
+    struct servent *servp;
+    extern int check_received_pkt();
+
+    /* Copy session structure and link into list */
+    slp = (struct session_list *)calloc(1, sizeof(struct session_list));
+    slp->internal = isp = (struct snmp_internal_session *)calloc(1, sizeof(struct snmp_internal_session));
+    bzero((char *)isp, sizeof(struct snmp_internal_session));
+    slp->internal->sd = -1; /* mark it not set */
+    slp->session = (struct snmp_session *)calloc(1, sizeof(struct snmp_session));
+    bcopy((char *)session, (char *)slp->session, sizeof(struct snmp_session));
+    session = slp->session;
+    /* now link it in. */
+    slp->next = Sessions;
+    Sessions = slp;
+
+    /*
+     * session now points to the new structure that still contains pointers to
+     * data allocated elsewhere.  Some of this data is copied to space malloc'd
+     * here, and the pointer replaced with the new one.
+     */
+
+    if (session->peername != NULL){
+       cp = (u_char *)calloc(1, (unsigned)strlen(session->peername) + 1);
+       strcpy((char *)cp, session->peername);
+       session->peername = (char *)cp;
+    }
+
+    if (session->retries == SNMP_DEFAULT_RETRIES)
+       session->retries = SNMP_API_DEFAULT_RETRIES;
+    if (session->timeout == SNMP_DEFAULT_TIMEOUT)
+       session->timeout = SNMP_API_DEFAULT_TIMEOUT;
+    if (session->MMS == 0 )
+       session->MMS = DEFAULT_MMS;
+    isp->requests = NULL;
+
+
+    /* Fill in defaults if necessary */
+    if (session->community_len != SNMP_DEFAULT_COMMUNITY_LEN){
+       if( *session->community == '+' ) {
+               session->community_len--;
+               cp = (u_char *) calloc(1, (unsigned) session->community_len);
+               bcopy((char *) session->community+1, (char *)cp,
+                     session->community_len);
+               session->version = SNMP_VERSION_2C;
+       } else {
+               cp = (u_char *) calloc(1, (unsigned) session->community_len);
+               bcopy((char *) session->community, (char *) cp, 
+                     session->community_len);
+       }
+
+    } else {
+       session->community_len = strlen(DEFAULT_COMMUNITY);
+       cp = (u_char *)calloc(1, (unsigned)session->community_len);
+       bcopy((char *)DEFAULT_COMMUNITY, (char *)cp, session->community_len);
+    }
+
+    /* Set up connections */
+    sd = socket(AF_INET, SOCK_DGRAM, 0);
+    if (sd < 0){
+       perror("socket");
+       snmp_errno = SNMPERR_GENERR;
+       if (!snmp_close(session)){
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+           exit(1);
+       }
+       return 0;
+    }
+    isp->sd = sd;
+
+    if (session->peername != SNMP_DEFAULT_PEERNAME){
+       if ((addr = inet_addr(session->peername)) != -1){
+           bcopy((char *)&addr, (char *)&isp->addr.sin_addr, sizeof(isp->addr.sin_addr));
+       } else {
+           hp = gethostbyname(session->peername);
+           if (hp == NULL){
+               fprintf(stderr, "unknown host: %s\n", session->peername);
+               snmp_errno = SNMPERR_BAD_ADDRESS;
+               if (!snmp_close(session)){
+                   fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+                   exit(2);
+               }
+               return 0;
+           } else {
+               bcopy((char *)hp->h_addr, (char *)&isp->addr.sin_addr, hp->h_length);
+           }
+       }
+       isp->addr.sin_family = AF_INET;
+       if (session->remote_port == SNMP_DEFAULT_REMPORT){
+           /*servp = getservbyname("snmp", "udp");*/
+           servp=NULL;
+           if (servp != NULL){
+               isp->addr.sin_port = servp->s_port;
+           } else {
+               isp->addr.sin_port = htons(SNMP_PORT);
+           }
+       } else {
+           isp->addr.sin_port = htons(session->remote_port);
+       }
+    } else {
+       isp->addr.sin_addr.s_addr = SNMP_DEFAULT_ADDRESS;
+    }
+
+    me.sin_family = AF_INET;
+    me.sin_addr.s_addr = INADDR_ANY;
+    me.sin_port = htons(session->local_port);
+    if (bind(sd, (struct sockaddr *)&me, sizeof(me)) != 0){
+       perror("bind");
+       snmp_errno = SNMPERR_BAD_LOCPORT;
+       if (! snmp_close(session)){
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n", 
+                   api_errstring(snmp_errno));
+           exit(3);
+       }
+       return 0;
+    }
+
+    if( *cp == '/' ) {
+       session->authenticator = check_received_pkt;
+       sync_with_agent(session);
+       parse_app_community_string( session );
+       session->qoS |= USEC_QOS_GENREPORT;
+    }
+
+    /* replace comm pointer with pointer to new data: */
+    session->community = cp;   
+
+    return session;
+}
+
+void
+sync_with_agent( session )
+struct snmp_session *session;
+{
+    struct snmp_pdu *pdu, *response = 0;
+    int status;
+
+    session->qoS = USEC_QOS_GENREPORT;
+    session->userLen = 6;
+    session->version = SNMP_VERSION_2;
+    strcpy( session->userName, "public" );
+
+    snmp_synch_setup(session);
+    pdu = snmp_pdu_create(GET_REQ_MSG);
+    status = snmp_synch_response(session, pdu, &response);
+
+    if (status == STAT_SUCCESS){
+       memcpy( session->agentID, response->params.agentID, 12 );
+
+       /* save the clocks -- even though they are not authentic */
+       session->agentBoots = response->params.agentBoots;
+       session->agentTime = response->params.agentTime;
+       session->agentClock = response->params.agentTime - time(NULL);
+
+    } else {
+           if (status == STAT_TIMEOUT){
+               printf("No Response from %s\n", session->peername);
+           } else {    /* status == STAT_ERROR */
+               printf("An error occurred, Quitting\n");
+           }
+           exit( -1 );
+    }
+
+    /** freed to early: 
+      snmp_free_pdu(pdu);
+      if (response) snmp_free_pdu(response);
+     **/
+}
+#if 1 /***/
+/*
+ * Unlink one element from input request list,
+ * then free it and it's pdu.
+ */
+static void
+free_one_request(isp, orp)
+     struct snmp_internal_session *isp;
+     struct request_list *orp;
+{
+    struct request_list *rp;
+    if (!orp)
+       return;
+    if (isp->requests == orp) {
+       isp->requests = orp->next_request;      /* unlink head */
+    } else {
+       for (rp = isp->requests; rp; rp = rp->next_request) {
+           if (rp->next_request == orp) {
+               rp->next_request = orp->next_request;   /* unlink element */
+               break;
+           }
+       }
+    }
+    if (orp->pdu != NULL) {
+       snmp_free_pdu(orp->pdu);
+    }
+    free((char *) orp);
+}
+
+#endif/***/ BUG_SNMPTRACE */cked for testing purposes */e key!  replace...
+     */
+ * \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 1\ 1\0\0\0\0\0\0\0\19\7fÿ¯ùsnmplib/snmp_api.c\0c\0\0.h\0\0\0\18\7fÿ°\85\10\0<Ðlib/snmp_api.c~\0~\0\0ñ\0\0\0\18\7fÿ±\1e\10\0\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\0\0\0\18\7fÿ±«\10\0=\10\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\0\0\0\18\7fÿ²\1d\10\0=0\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\0\0\0\18\7fÿ²\8a\10\0=P\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\0\0\0\18\7fÿ³
+\10\0=p\7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\0\0\0\18\7fÿ³\82\0\0\0\ 1\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\0\0\0Á\7fÿ³ù\0\0\0\10\7fÿ´\10\10\0\0%\0\19\0\15\0\0\10\0D(\0\0\0\10\7fÿ´_\10\0\0\0\ 2\\0\0\0\0\10\0\0\0\0\10\7fÿ´©\10\0=\98\0\0\ 24\0\0\0\0\10\0\0\0\0\10\7fÿ´ø\10\0\0\0\ 2H\0\0\0\0\10\0\0\0\0\10\7fÿµB\10\0>\10\7fÿµ]\7fÿµm\7fÿµz\0\0\0\10\7fÿµ \10\0>(\7fÿµ·\7fÿµÉ\7fÿµÖ\0\0\0\10\7fÿµï\10\0>@\7fÿ¶\12\7fÿ¶ \7fÿ¶4\0\0\0\10\7fÿ¶P\0\0\0\ 1\7fÿ¶r\7fÿ¶~\7fÿ¶\88\0\0\00\7fÿ¶\9f\10\0\7fÿ¶·\0\0\0\0\7fÿ¶Ù\0\0\0\0\7fÿ·\ 1\0\0\0\0\7fÿ·#\7fÿ·/\7fÿ·>\10\0>X\7fÿ·V\0\0\03\0\0\0\0/usr/people/wessels/.indent.pro\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\ 1\0\0\0\0\7fÿ¯è\7fÿ¯ù\7fÿ°\f\7fÿ°\e\7fÿ°.\7fÿ°?\7fÿ°M\7fÿ°[\7fÿ°p\7fÿ°\85\7fÿ°\95\7fÿ°£\7fÿ°²\7fÿ°Å\7fÿ°Û\7fÿ°ñ\7fÿ±
+\7fÿ±\1e\7fÿ±2\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\7fÿ±\99\7fÿ±«\7fÿ±º\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\7fÿ²\ f\7fÿ²\1d\7fÿ²2\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\7fÿ²\7f\7fÿ²\8a\7fÿ²\99\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\7fÿ²ö\7fÿ³
+\7fÿ³ \7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\7fÿ³s\7fÿ³\82\7fÿ³\91\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\7fÿ³ç\7fÿ³ù\7fÿ´\ 4\7fÿ´\10\7fÿ´\1e\7fÿ´)\7fÿ´3\7fÿ´C\7fÿ´O\7fÿ´_\7fÿ´k\7fÿ´t\7fÿ´\81\7fÿ´\8f\7fÿ´\9f\7fÿ´©\7fÿ´·\7fÿ´Å\7fÿ´Ò\7fÿ´Ý\7fÿ´í\7fÿ´ø\7fÿµ\ 3\7fÿµ\10\7fÿµ\1d\7fÿµ)\7fÿµ7\7fÿµB\7fÿµM\7fÿµ]\7fÿµm\7fÿµz\7fÿµ\89\7fÿµ \7fÿµ«\7fÿµ·\7fÿµÉ\7fÿµÖ\7fÿµâ\7fÿµï\7fÿ¶\ 3\7fÿ¶\12\7fÿ¶ \7fÿ¶4\7fÿ¶?\7fÿ¶P\7fÿ¶b\7fÿ¶r\7fÿ¶~\7fÿ¶\88\7fÿ¶\94\7fÿ¶\9f\7fÿ¶«\7fÿ¶·\7fÿ¶É\7fÿ¶Ù\7fÿ¶í\7fÿ·\ 1\7fÿ·\15\7fÿ·#\7fÿ·/\7fÿ·>\7fÿ·L\7fÿ·V\7fÿ·f\7fÿ·q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0@    \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\0\0\0°\0\0\0\ 4\0\0\0\0\0\0\0\b\10\0>X\0\0\0\f\10\0\0\0\0\10\0\0\0\0\0\0\0\14\0\0\0\14\0\0\0\14\0\0\0\18\0\0\0\18\0\0\0\18\0\0\0\1c\0\0\0\1c\0\0\0\1c\0\0\0\1c\0\0\0 \0\0\0 \0\0\0 \0\0\0$\0\0\0\v\0\0\0\e\0\0\0\19\0\0\0\v\0\0\0\e\0\0\0@\0\0\0\0\0\0\0\0\0\0\0\0\10\0,\b\0\0\0\1a\10\02\88\0\0\0\1a\0\0\0\0\0\0\0\1a\10\0\85\b\0\0\0\0\10\0>X\0\0\0\0\0\0\0\0\0\0\0\0\10\0\82à\0\0\0\0\0\0\ 1C\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e0\0\0\0\v\0\0\0\e\0\0\0\18\0\0\0\v\0\0\0\1a\0\0\0\17\0\0\0\v\0\0\0 \0\0\0\0\10\0\8d¸ude/snmp_groupvars.h~\0\0\b\0\0\0\b\0\0\0 \0\0\0\0\10\0\8dàude/snmp_groupvars.h\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8eX\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e\80\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e¨\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8eÐ\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\0\0\0\ 1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\84©\0\0\0\0/***********************************************************
+       Copyright 1989 by Carnegie Mellon University
+
+                      All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the name of CMU not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+******************************************************************/
+/*
+ * snmp_api.c - API for access to snmp.
+ */
+#define DEBUG_SNMPTRACE                0 /* set to 1 to print all SNMP actions */
+#define DEBUG_SNMPFULLDUMP     0 /* set to 1 to dump all SNMP packets */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#ifdef linux
+#include <arpa/inet.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#endif
+
+
+#include "asn1.h"
+#include "snmp.h"
+#include "snmp_impl.h"
+#include "snmp_api.h"
+#include "snmp_client.h"
+
+#define PACKET_LENGTH  4500
+
+#ifndef BSD4_3
+#define BSD4_2
+#endif
+
+#if !defined(BSD4_3) && !defined(linux) && !defined(sun)
+
+typedef long   fd_mask;
+#define NFDBITS        (sizeof(fd_mask) * NBBY)        /* bits per mask */
+
+#define        FD_SET(n, p)    ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+#define        FD_CLR(n, p)    ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+#define        FD_ISSET(n, p)  ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+#define FD_ZERO(p)     bzero((char *)(p), sizeof(*(p)))
+#endif
+
+oid default_enterprise[] = {1, 3, 6, 1, 4, 1, 3, 1, 1}; /* enterprises.cmu.systems.cmuSNMP */
+
+#define DEFAULT_COMMUNITY   "public"
+#define DEFAULT_REMPORT            SNMP_PORT
+#define DEFAULT_ENTERPRISE  default_enterprise
+#define DEFAULT_TIME       0
+#define DEFAULT_MMS        1389 /* large, randomly picked for testing purposes */
+
+/*
+ * Internal information about the state of the snmp session.
+ */
+struct snmp_internal_session {
+    int            sd;         /* socket descriptor for this connection */
+    ipaddr  addr;      /* address of connected peer */
+    struct request_list *requests;/* Info about outstanding requests */
+};
+
+/*
+ * A list of all the outstanding requests for a particular session.
+ */
+struct request_list {
+    struct request_list *next_request;
+    u_long  request_id;        /* request id */
+    int            retries;    /* Number of retries */
+    u_long timeout;    /* length to wait for timeout */
+    struct timeval time; /* Time this request was made */
+    struct timeval expire;  /* time this request is due to expire */
+    struct snmp_pdu *pdu;   /* The pdu for this request (saved so it can be retransmitted */
+};
+
+/*
+ * The list of active/open sessions.
+ */
+struct session_list {
+    struct session_list *next;
+    struct snmp_session *session;
+    struct snmp_internal_session *internal;
+};
+
+struct session_list *Sessions = NULL;
+
+u_long Reqid = 0;
+int snmp_errno = 0;
+
+char *api_errors[4] = {
+    "Unknown session",
+    "Unknown host",
+    "Invalid local port",
+    "Unknown Error"
+};
+
+
+void sync_with_agent();
+int parse_app_community_string();
+void snmp_synch_setup();
+int snmp_synch_response();
+void md5Digest();
+
+
+static char *
+api_errstring(snmp_errnumber)
+    int        snmp_errnumber;
+{
+    if (snmp_errnumber <= SNMPERR_BAD_SESSION && snmp_errnumber >= SNMPERR_GENERR){
+       return api_errors[snmp_errnumber + 4];
+    } else {
+       return "Unknown Error";
+    }
+}
+
+#if 0
+/*
+ * Gets initial request ID for all transactions.
+ */
+static void
+init_snmp(){
+    struct timeval tv;
+
+    gettimeofday(&tv, (struct timezone *)0);
+    srandom(tv.tv_sec ^ tv.tv_usec);
+    Reqid = random();
+}
+#endif
+
+
+/*
+ * Dump snmp packet to stdout:
+ */
+static void
+snmp_print_packet(packet, length, addr, code)
+  char *packet; 
+  int length; 
+  ipaddr addr; 
+  int code;
+{
+  if(length < 0) {
+    return;
+  }
+  if (code <= 0) { /* received */
+    printf("\nReceived %4d bytes from ", length);
+  }
+  else { /* sending */
+    printf("\nSending  %4d bytes to   ", length);
+  }
+  printf("%s:", inet_ntoa(addr.sin_addr));
+#if DEBUG_SNMPFULLDUMP
+  for (count = 0; count < length; count++) {
+    if ((count & 15) == 0) {
+      printf("\n  ");
+    }
+    printf("%02X ", (int)(packet[count]&255));
+  }
+#endif
+  fflush(stdout);
+}
+
+#if DEBUG_SNMPTRACE
+/*
+ * Print request
+ */
+#define TRACE_SEND   (0)
+#define TRACE_RECV   (1)
+#define TRACE_TIMEOUT (2)
+static void
+snmp_print_trace(slp, rp, code)
+  struct session_list *slp;
+  struct request_list *rp;
+  int code;
+{
+  int reqid=0, retries=1;
+  if( rp ){
+    reqid = rp->request_id;
+    retries = rp->retries;
+  }  
+  printf("\n Session %2d  ReqId %4d  ", slp->internal->sd, reqid);
+  switch(code)
+    { 
+    case TRACE_SEND:    printf("send pdu (%d)", retries);break; 
+    case TRACE_RECV:    printf("recv pdu");break; 
+    case TRACE_TIMEOUT: printf("time out");break; 
+    }
+  fflush(stdout);
+}
+#endif /* DEBUG_SNMPTRACE */
+
+
+
+
+/*
+ * 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.
+ */
+struct snmp_session *
+snmp_open(session)
+    struct snmp_session *session;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp;
+    u_char *cp;
+    int sd;
+    u_long addr;
+    struct sockaddr_in me;
+    struct hostent *hp;
+    struct servent *servp;
+    extern int check_received_pkt();
+
+    /* Copy session structure and link into list */
+    slp = (struct session_list *)calloc(1, sizeof(struct session_list));
+    slp->internal = isp = (struct snmp_internal_session *)calloc(1, sizeof(struct snmp_internal_session));
+    bzero((char *)isp, sizeof(struct snmp_internal_session));
+    slp->internal->sd = -1; /* mark it not set */
+    slp->session = (struct snmp_session *)calloc(1, sizeof(struct snmp_session));
+    bcopy((char *)session, (char *)slp->session, sizeof(struct snmp_session));
+    session = slp->session;
+    /* now link it in. */
+    slp->next = Sessions;
+    Sessions = slp;
+
+    /*
+     * session now points to the new structure that still contains pointers to
+     * data allocated elsewhere.  Some of this data is copied to space malloc'd
+     * here, and the pointer replaced with the new one.
+     */
+
+    if (session->peername != NULL){
+       cp = (u_char *)calloc(1, (unsigned)strlen(session->peername) + 1);
+       strcpy((char *)cp, session->peername);
+       session->peername = (char *)cp;
+    }
+
+    if (session->retries == SNMP_DEFAULT_RETRIES)
+       session->retries = SNMP_API_DEFAULT_RETRIES;
+    if (session->timeout == SNMP_DEFAULT_TIMEOUT)
+       session->timeout = SNMP_API_DEFAULT_TIMEOUT;
+    if (session->MMS == 0 )
+       session->MMS = DEFAULT_MMS;
+    isp->requests = NULL;
+
+
+    /* Fill in defaults if necessary */
+    if (session->community_len != SNMP_DEFAULT_COMMUNITY_LEN){
+       if( *session->community == '+' ) {
+               session->community_len--;
+               cp = (u_char *) calloc(1, (unsigned) session->community_len);
+               bcopy((char *) session->community+1, (char *)cp,
+                     session->community_len);
+               session->version = SNMP_VERSION_2C;
+       } else {
+               cp = (u_char *) calloc(1, (unsigned) session->community_len);
+               bcopy((char *) session->community, (char *) cp, 
+                     session->community_len);
+       }
+
+    } else {
+       session->community_len = strlen(DEFAULT_COMMUNITY);
+       cp = (u_char *)calloc(1, (unsigned)session->community_len);
+       bcopy((char *)DEFAULT_COMMUNITY, (char *)cp, session->community_len);
+    }
+
+    /* Set up connections */
+    sd = socket(AF_INET, SOCK_DGRAM, 0);
+    if (sd < 0){
+       perror("socket");
+       snmp_errno = SNMPERR_GENERR;
+       if (!snmp_close(session)){
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+           exit(1);
+       }
+       return 0;
+    }
+    isp->sd = sd;
+
+    if (session->peername != SNMP_DEFAULT_PEERNAME){
+       if ((addr = inet_addr(session->peername)) != -1){
+           bcopy((char *)&addr, (char *)&isp->addr.sin_addr, sizeof(isp->addr.sin_addr));
+       } else {
+           hp = gethostbyname(session->peername);
+           if (hp == NULL){
+               fprintf(stderr, "unknown host: %s\n", session->peername);
+               snmp_errno = SNMPERR_BAD_ADDRESS;
+               if (!snmp_close(session)){
+                   fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+                   exit(2);
+               }
+               return 0;
+           } else {
+               bcopy((char *)hp->h_addr, (char *)&isp->addr.sin_addr, hp->h_length);
+           }
+       }
+       isp->addr.sin_family = AF_INET;
+       if (session->remote_port == SNMP_DEFAULT_REMPORT){
+           /*servp = getservbyname("snmp", "udp");*/
+           servp=NULL;
+           if (servp != NULL){
+               isp->addr.sin_port = servp->s_port;
+           } else {
+               isp->addr.sin_port = htons(SNMP_PORT);
+           }
+       } else {
+           isp->addr.sin_port = htons(session->remote_port);
+       }
+    } else {
+       isp->addr.sin_addr.s_addr = SNMP_DEFAULT_ADDRESS;
+    }
+
+    me.sin_family = AF_INET;
+    me.sin_addr.s_addr = INADDR_ANY;
+    me.sin_port = htons(session->local_port);
+    if (bind(sd, (struct sockaddr *)&me, sizeof(me)) != 0){
+       perror("bind");
+       snmp_errno = SNMPERR_BAD_LOCPORT;
+       if (! snmp_close(session)){
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n", 
+                   api_errstring(snmp_errno));
+           exit(3);
+       }
+       return 0;
+    }
+
+    if( *cp == '/' ) {
+       session->authenticator = check_received_pkt;
+       sync_with_agent(session);
+       parse_app_community_string( session );
+       session->qoS |= USEC_QOS_GENREPORT;
+    }
+
+    /* replace comm pointer with pointer to new data: */
+    session->community = cp;   
+
+    return session;
+}
+
+void
+sync_with_agent( session )
+struct snmp_session *session;
+{
+    struct snmp_pdu *pdu, *response = 0;
+    int status;
+
+    session->qoS = USEC_QOS_GENREPORT;
+    session->userLen = 6;
+    session->version = SNMP_VERSION_2;
+    strcpy( session->userName, "public" );
+
+    snmp_synch_setup(session);
+    pdu = snmp_pdu_create(GET_REQ_MSG);
+    status = snmp_synch_response(session, pdu, &response);
+
+    if (status == STAT_SUCCESS){
+       memcpy( session->agentID, response->params.agentID, 12 );
+
+       /* save the clocks -- even though they are not authentic */
+       session->agentBoots = response->params.agentBoots;
+       session->agentTime = response->params.agentTime;
+       session->agentClock = response->params.agentTime - time(NULL);
+
+    } else {
+           if (status == STAT_TIMEOUT){
+               printf("No Response from %s\n", session->peername);
+           } else {    /* status == STAT_ERROR */
+               printf("An error occurred, Quitting\n");
+           }
+           exit( -1 );
+    }
+
+    /** freed to early: 
+      snmp_free_pdu(pdu);
+      if (response) snmp_free_pdu(response);
+     **/
+}
+#if 1 /***/
+/*
+ * Unlink one element from input request list,
+ * then free it and it's pdu.
+ */
+static void
+free_one_request(isp, orp)
+     struct snmp_internal_session *isp;
+     struct request_list *orp;
+{
+    struct request_list *rp;
+    if (!orp)
+       return;
+    if (isp->requests == orp) {
+       isp->requests = orp->next_request;      /* unlink head */
+    } else {
+       for (rp = isp->requests; rp; rp = rp->next_request) {
+           if (rp->next_request == orp) {
+               rp->next_request = orp->next_request;   /* unlink element */
+               break;
+           }
+       }
+    }
+    if (orp->pdu != NULL) {
+       snmp_free_pdu(orp->pdu);
+    }
+    free((char *) orp);
+}
+ oid list */
+       if (oid[length - 2].label)
+           strncpy(np->parent, oid[length - 2].label, MAXLABEL);
+       strcpy(np->label, name);
+       if (oid[length - 1].subid != -1)
+           np->subid = oid[length - 1].subid;
+       else
+           print_error("Warning: This entry is pretty silly", np->label, type);
+    } else {
+       print_error("No end to oid", (char *) NULL, type);
+       free_node(np);
+       np = 0;
+    }
+    /* free oid array */
+    for (count = 0; count < length; count++) {
+       if (oid[count].label)
+           free(oid[count].label);
+       oid[count].label = 0;
+    }
+    return np;
+}
+
+/*
+ * Parses a NOTIFICATION-TYPE macro.
+ * Returns 0 on error.
+ */
+static struct node *
+parse_notificationDefinition(fp, name)
+     FILE *fp;
+     char *name;
+{
+    int type;
+    char token[MAXTOKEN];
+    int count, length;
+    struct subid oid[32];
+    struct node *np;
+
+    np = (struct node *) Malloc(sizeof(struct node));
+    np->type = 0;
+    np->next = 0;
+    np->enums = 0;
+    np->description = NULL;    /* default to an empty description */
+    type = get_token(fp, token);
+    while (type != EQUALS) {
+       switch (type) {
+       case DESCRIPTION:
+           type = get_token(fp, token);
+           if (type != QUOTESTRING) {
+               print_error("Bad DESCRIPTION", token, type);
+               free_node(np);
+               return 0;
+           }
+#ifdef TEST
+           printf("Description== \"%.50s\"\n", quoted_string_buffer);
+#endif
+           np->description = quoted_string_buffer;
+           quoted_string_buffer = (char *) calloc(1, MAXQUOTESTR);
+           break;
+
+       default:
+           /\10\0BÐ+= m\0\0
+È      /* \0\0\0\0*/ B\10\04¨NMPT\10\ 1^h */c\0\0\0\0for testing purposes */e key!  replace...
+     */
+ * \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 1\ 1\0\0\0\0\0\0\0\19\7fÿ¯ùsnmplib/snmp_api.c\0c\0\0.h\0\0\0\18\7fÿ°\85\10\0<Ðlib/snmp_api.c~\0~\0\0ñ\0\0\0\18\7fÿ±\1e\10\0\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\0\0\0\18\7fÿ±«\10\0=\10\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\0\0\0\18\7fÿ²\1d\10\0=0\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\0\0\0\18\7fÿ²\8a\10\0=P\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\0\0\0\18\7fÿ³
+\10\0=p\7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\0\0\0\18\7fÿ³\82\0\0\0\ 1\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\0\0\0Á\7fÿ³ù\0\0\0\10\7fÿ´\10\10\0\0%\0\19\0\15\0\0\10\0D(\0\0\0\10\7fÿ´_\10\0\0\0\ 2\\0\0\0\0\10\0\0\0\0\10\7fÿ´©\10\0=\98\0\0\ 24\0\0\0\0\10\0\0\0\0\10\7fÿ´ø\10\0\0\0\ 2H\0\0\0\0\10\0\0\0\0\10\7fÿµB\10\0>\10\7fÿµ]\7fÿµm\7fÿµz\0\0\0\10\7fÿµ \10\0>(\7fÿµ·\7fÿµÉ\7fÿµÖ\0\0\0\10\7fÿµï\10\0>@\7fÿ¶\12\7fÿ¶ \7fÿ¶4\0\0\0\10\7fÿ¶P\0\0\0\ 1\7fÿ¶r\7fÿ¶~\7fÿ¶\88\0\0\00\7fÿ¶\9f\10\0\7fÿ¶·\0\0\0\0\7fÿ¶Ù\10\0\89è\7fÿ·\ 1\0\0\0\0\7fÿ·#\7fÿ·/\7fÿ·>\10\0>X\7fÿ·V\0\0\03\0\0\0\0/usr/people/wessels/.indent.pro\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\ 1\0\0\0\0\7fÿ¯è\7fÿ¯ù\7fÿ°\f\7fÿ°\e\7fÿ°.\7fÿ°?\7fÿ°M\7fÿ°[\7fÿ°p\7fÿ°\85\7fÿ°\95\7fÿ°£\7fÿ°²\7fÿ°Å\7fÿ°Û\7fÿ°ñ\7fÿ±
+\7fÿ±\1e\7fÿ±2\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\7fÿ±\99\7fÿ±«\7fÿ±º\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\7fÿ²\ f\7fÿ²\1d\7fÿ²2\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\7fÿ²\7f\7fÿ²\8a\7fÿ²\99\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\7fÿ²ö\7fÿ³
+\7fÿ³ \7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\7fÿ³s\7fÿ³\82\7fÿ³\91\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\7fÿ³ç\7fÿ³ù\7fÿ´\ 4\7fÿ´\10\7fÿ´\1e\7fÿ´)\7fÿ´3\7fÿ´C\7fÿ´O\7fÿ´_\7fÿ´k\7fÿ´t\7fÿ´\81\7fÿ´\8f\7fÿ´\9f\7fÿ´©\7fÿ´·\7fÿ´Å\7fÿ´Ò\7fÿ´Ý\7fÿ´í\7fÿ´ø\7fÿµ\ 3\7fÿµ\10\7fÿµ\1d\7fÿµ)\7fÿµ7\7fÿµB\7fÿµM\7fÿµ]\7fÿµm\7fÿµz\7fÿµ\89\7fÿµ \7fÿµ«\7fÿµ·\7fÿµÉ\7fÿµÖ\7fÿµâ\7fÿµï\7fÿ¶\ 3\7fÿ¶\12\7fÿ¶ \7fÿ¶4\7fÿ¶?\7fÿ¶P\7fÿ¶b\7fÿ¶r\7fÿ¶~\7fÿ¶\88\7fÿ¶\94\7fÿ¶\9f\7fÿ¶«\7fÿ¶·\7fÿ¶É\7fÿ¶Ù\7fÿ¶í\7fÿ·\ 1\7fÿ·\15\7fÿ·#\7fÿ·/\7fÿ·>\7fÿ·L\7fÿ·V\7fÿ·f\7fÿ·q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\10\0BÐ+= m\0\0
+È      /* \0\0\0\0*/ B\10\04¨NMPT\10\ 1\97X */c\0\0\0\0for testing purposes */e key!  replace...
+     */
+ * \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 1\ 1\0\0\0\0\0\0\0\19\7fÿ¯ùsnmplib/snmp_api.c\0c\0\0.h\0\0\0\18\7fÿ°\85\10\0<Ðlib/snmp_api.c~\0~\0\0ñ\0\0\0\18\7fÿ±\1e\10\0\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\0\0\0\18\7fÿ±«\10\0=\10\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\0\0\0\18\7fÿ²\1d\10\0=0\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\0\0\0\18\7fÿ²\8a\10\0=P\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\0\0\0\18\7fÿ³
+\10\0=p\7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\0\0\0\18\7fÿ³\82\0\0\0\ 1\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\0\0\0Á\7fÿ³ù\0\0\0\10\7fÿ´\10\10\0\0%\0\19\0\15\0\0\10\0D(\0\0\0\10\7fÿ´_\10\0\0\0\ 2\\0\0\0\0\10\0\0\0\0\10\7fÿ´©\10\0=\98\0\0\ 24\0\0\0\0\10\0\0\0\0\10\7fÿ´ø\10\0\0\0\ 2H\0\0\0\0\10\0\0\0\0\10\7fÿµB\10\0>\10\7fÿµ]\7fÿµm\7fÿµz\0\0\0\10\7fÿµ \10\0>(\7fÿµ·\7fÿµÉ\7fÿµÖ\0\0\0\10\7fÿµï\10\0>@\7fÿ¶\12\7fÿ¶ \7fÿ¶4\0\0\0\10\7fÿ¶P\0\0\0\ 1\7fÿ¶r\7fÿ¶~\7fÿ¶\88\0\0\00\7fÿ¶\9f\10\0\7fÿ¶·\0\0\0\0\7fÿ¶Ù\10\0\89è\7fÿ·\ 1\0\0\0\0\7fÿ·#\7fÿ·/\7fÿ·>\10\0>X\7fÿ·V\0\0\03\0\0\0\0/usr/people/wessels/.indent.pro\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\ 1\0\0\0\0\7fÿ¯è\7fÿ¯ù\7fÿ°\f\7fÿ°\e\7fÿ°.\7fÿ°?\7fÿ°M\7fÿ°[\7fÿ°p\7fÿ°\85\7fÿ°\95\7fÿ°£\7fÿ°²\7fÿ°Å\7fÿ°Û\7fÿ°ñ\7fÿ±
+\7fÿ±\1e\7fÿ±2\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\7fÿ±\99\7fÿ±«\7fÿ±º\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\7fÿ²\ f\7fÿ²\1d\7fÿ²2\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\7fÿ²\7f\7fÿ²\8a\7fÿ²\99\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\7fÿ²ö\7fÿ³
+\7fÿ³ \7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\7fÿ³s\7fÿ³\82\7fÿ³\91\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\7fÿ³ç\7fÿ³ù\7fÿ´\ 4\7fÿ´\10\7fÿ´\1e\7fÿ´)\7fÿ´3\7fÿ´C\7fÿ´O\7fÿ´_\7fÿ´k\7fÿ´t\7fÿ´\81\7fÿ´\8f\7fÿ´\9f\7fÿ´©\7fÿ´·\7fÿ´Å\7fÿ´Ò\7fÿ´Ý\7fÿ´í\7fÿ´ø\7fÿµ\ 3\7fÿµ\10\7fÿµ\1d\7fÿµ)\7fÿµ7\7fÿµB\7fÿµM\7fÿµ]\7fÿµm\7fÿµz\7fÿµ\89\7fÿµ \7fÿµ«\7fÿµ·\7fÿµÉ\7fÿµÖ\7fÿµâ\7fÿµï\7fÿ¶\ 3\7fÿ¶\12\7fÿ¶ \7fÿ¶4\7fÿ¶?\7fÿ¶P\7fÿ¶b\7fÿ¶r\7fÿ¶~\7fÿ¶\88\7fÿ¶\94\7fÿ¶\9f\7fÿ¶«\7fÿ¶·\7fÿ¶É\7fÿ¶Ù\7fÿ¶í\7fÿ·\ 1\7fÿ·\15\7fÿ·#\7fÿ·/\7fÿ·>\7fÿ·L\7fÿ·V\7fÿ·f\7fÿ·q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\0\0\0°\0\0\0\ 4\0\0\0\0\0\0\0\b\10\0>X\0\0\0\f\10\0\0\0\0\10\0\0\0\0\0\0\0\14\0\0\0\14\0\0\0\14\0\0\0\18\0\0\0\18\0\0\0\18\0\0\0\1c\0\0\0\1c\0\0\0\1c\0\0\0\1c\0\0\0 \0\0\0 \0\0\0 \0\0\0$\0\0\0\v\0\0\0\e\0\0\0\19\0\0\0\v\0\0\0\e\0\0\0@\0\0\0\0\0\0\0\0\0\0\0\0\10\0,\b\0\0\0\1a\10\02\88\0\0\0\1a\0\0\0\0\0\0\0\1a\10\0\85\b\0\0\0\0\10\0>X\0\0\0\0\0\0\0\0\0\0\0\0\10\0\82à\0\0\0\0\0\0\ 1C\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e0\0\0\0\v\0\0\0\e\0\0\0\18\0\0\0\v\0\0\0\1a\0\0\0\17\0\0\0\v\0\0\0 \0\0\0\0\10\0\8d¸ude/snmp_groupvars.h~\0\0\b\0\0\0\b\0\0\0 \0\0\0\0\10\0\8dàude/snmp_groupvars.h\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8eX\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e\80\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e¨\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8eÐ\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\0\0\0\ 1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\84©\0\0\0\0/***********************************************************
+       Copyright 1989 by Carnegie Mellon University
+
+                      All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the name of CMU not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+******************************************************************/
+/*
+ * snmp_api.c - API for access to snmp.
+ */
+#define DEBUG_SNMPTRACE                0 /* set to 1 to print all SNMP actions */
+#define DEBUG_SNMPFULLDUMP     0 /* set to 1 to dump all SNMP packets */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#ifdef linux
+#include <arpa/inet.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#endif
+
+
+#include "asn1.h"
+#include "snmp.h"
+#include "snmp_impl.h"
+#include "snmp_api.h"
+#include "snmp_client.h"
+
+#define PACKET_LENGTH  4500
+
+#ifndef BSD4_3
+#define BSD4_2
+#endif
+
+#if !defined(BSD4_3) && !defined(linux) && !defined(sun)
+
+typedef long   fd_mask;
+#define NFDBITS        (sizeof(fd_mask) * NBBY)        /* bits per mask */
+
+#define        FD_SET(n, p)    ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+#define        FD_CLR(n, p)    ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+#define        FD_ISSET(n, p)  ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+#define FD_ZERO(p)     bzero((char *)(p), sizeof(*(p)))
+#endif
+
+oid default_enterprise[] = {1, 3, 6, 1, 4, 1, 3, 1, 1}; /* enterprises.cmu.systems.cmuSNMP */
+
+#define DEFAULT_COMMUNITY   "public"
+#define DEFAULT_REMPORT            SNMP_PORT
+#define DEFAULT_ENTERPRISE  default_enterprise
+#define DEFAULT_TIME       0
+#define DEFAULT_MMS        1389 /* large, randomly picked for testing purposes */
+
+/*
+ * Internal information about the state of the snmp session.
+ */
+struct snmp_internal_session {
+    int            sd;         /* socket descriptor for this connection */
+    ipaddr  addr;      /* address of connected peer */
+    struct request_list *requests;/* Info about outstanding requests */
+};
+
+/*
+ * A list of all the outstanding requests for a particular session.
+ */
+struct request_list {
+    struct request_list *next_request;
+    u_long  request_id;        /* request id */
+    int            retries;    /* Number of retries */
+    u_long timeout;    /* length to wait for timeout */
+    struct timeval time; /* Time this request was made */
+    struct timeval expire;  /* time this request is due to expire */
+    struct snmp_pdu *pdu;   /* The pdu for this request (saved so it can be retransmitted */
+};
+
+/*
+ * The list of active/open sessions.
+ */
+struct session_list {
+    struct session_list *next;
+    struct snmp_session *session;
+    struct snmp_internal_session *internal;
+};
+
+struct session_list *Sessions = NULL;
+
+u_long Reqid = 0;
+int snmp_errno = 0;
+
+char *api_errors[4] = {
+    "Unknown session",
+    "Unknown host",
+    "Invalid local port",
+    "Unknown Error"
+};
+
+
+void sync_with_agent();
+int parse_app_community_string();
+void snmp_synch_setup();
+int snmp_synch_response();
+void md5Digest();
+
+
+static char *
+api_errstring(snmp_errnumber)
+    int        snmp_errnumber;
+{
+    if (snmp_errnumber <= SNMPERR_BAD_SESSION && snmp_errnumber >= SNMPERR_GENERR){
+       return api_errors[snmp_errnumber + 4];
+    } else {
+       return "Unknown Error";
+    }
+}
+
+#if 0
+/*
+ * Gets initial request ID for all transactions.
+ */
+static void
+init_snmp(){
+    struct timeval tv;
+
+    gettimeofday(&tv, (struct timezone *)0);
+    srandom(tv.tv_sec ^ tv.tv_usec);
+    Reqid = random();
+}
+#endif
+
+
+/*
+ * Dump snmp packet to stdout:
+ */
+static void
+snmp_print_packet(packet, length, addr, code)
+  char *packet; 
+  int length; 
+  ipaddr addr; 
+  int code;
+{
+  if(length < 0) {
+    return;
+  }
+  if (code <= 0) { /* received */
+    printf("\nReceived %4d bytes from ", length);
+  }
+  else { /* sending */
+    printf("\nSending  %4d bytes to   ", length);
+  }
+  printf("%s:", inet_ntoa(addr.sin_addr));
+#if DEBUG_SNMPFULLDUMP
+  for (count = 0; count < length; count++) {
+    if ((count & 15) == 0) {
+      printf("\n  ");
+    }
+    printf("%02X ", (int)(packet[count]&255));
+  }
+#endif
+  fflush(stdout);
+}
+
+#if DEBUG_SNMPTRACE
+/*
+ * Print request
+ */
+#define TRACE_SEND   (0)
+#define TRACE_RECV   (1)
+#define TRACE_TIMEOUT (2)
+static void
+snmp_print_trace(slp, rp, code)
+  struct session_list *slp;
+  struct request_list *rp;
+  int code;
+{
+  int reqid=0, retries=1;
+  if( rp ){
+    reqid = rp->request_id;
+    retries = rp->retries;
+  }  
+  printf("\n Session %2d  ReqId %4d  ", slp->internal->sd, reqid);
+  switch(code)
+    { 
+    case TRACE_SEND:    printf("send pdu (%d)", retries);break; 
+    case TRACE_RECV:    printf("recv pdu");break; 
+    case TRACE_TIMEOUT: printf("time out");break; 
+    }
+  fflush(stdout);
+}
+#endif /* DEBUG_SNMPTRACE */
+
+
+
+
+/*
+ * 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.
+ */
+struct snmp_session *
+snmp_open(session)
+    struct snmp_session *session;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp;
+    u_char *cp;
+    int sd;
+    u_long addr;
+    struct sockaddr_in me;
+    struct hostent *hp;
+    struct servent *servp;
+    extern int check_received_pkt();
+
+    /* Copy session structure and link into list */
+    slp = (struct session_list *)calloc(1, sizeof(struct session_list));
+    slp->internal = isp = (struct snmp_internal_session *)calloc(1, sizeof(struct snmp_internal_session));
+    bzero((char *)isp, sizeof(struct snmp_internal_session));
+    slp->internal->sd = -1; /* mark it not set */
+    slp->session = (struct snmp_session *)calloc(1, sizeof(struct snmp_session));
+    bcopy((char *)session, (char *)slp->session, sizeof(struct snmp_session));
+    session = slp->session;
+    /* now link it in. */
+    slp->next = Sessions;
+    Sessions = slp;
+
+    /*
+     * session now points to the new structure that still contains pointers to
+     * data allocated elsewhere.  Some of this data is copied to space malloc'd
+     * here, and the pointer replaced with the new one.
+     */
+
+    if (session->peername != NULL){
+       cp = (u_char *)calloc(1, (unsigned)strlen(session->peername) + 1);
+       strcpy((char *)cp, session->peername);
+       session->peername = (char *)cp;
+    }
+
+    if (session->retries == SNMP_DEFAULT_RETRIES)
+       session->retries = SNMP_API_DEFAULT_RETRIES;
+    if (session->timeout == SNMP_DEFAULT_TIMEOUT)
+       session->timeout = SNMP_API_DEFAULT_TIMEOUT;
+    if (session->MMS == 0 )
+       session->MMS = DEFAULT_MMS;
+    isp->requests = NULL;
+
+
+    /* Fill in defaults if necessary */
+    if (session->community_len != SNMP_DEFAULT_COMMUNITY_LEN){
+       if( *session->community == '+' ) {
+               session->community_len--;
+               cp = (u_char *) calloc(1, (unsigned) session->community_len);
+               bcopy((char *) session->community+1, (char *)cp,
+                     session->community_len);
+               session->version = SNMP_VERSION_2C;
+       } else {
+               cp = (u_char *) calloc(1, (unsigned) session->community_len);
+               bcopy((char *) session->community, (char *) cp, 
+                     session->community_len);
+       }
+
+    } else {
+       session->community_len = strlen(DEFAULT_COMMUNITY);
+       cp = (u_char *)calloc(1, (unsigned)session->community_len);
+       bcopy((char *)DEFAULT_COMMUNITY, (char *)cp, session->community_len);
+    }
+
+    /* Set up connections */
+    sd = socket(AF_INET, SOCK_DGRAM, 0);
+    if (sd < 0){
+       perror("socket");
+       snmp_errno = SNMPERR_GENERR;
+       if (!snmp_close(session)){
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+           exit(1);
+       }
+       return 0;
+    }
+    isp->sd = sd;
+
+    if (session->peername != SNMP_DEFAULT_PEERNAME){
+       if ((addr = inet_addr(session->peername)) != -1){
+           bcopy((char *)&addr, (char *)&isp->addr.sin_addr, sizeof(isp->addr.sin_addr));
+       } else {
+           hp = gethostbyname(session->peername);
+           if (hp == NULL){
+               fprintf(stderr, "unknown host: %s\n", session->peername);
+               snmp_errno = SNMPERR_BAD_ADDRESS;
+               if (!snmp_close(session)){
+                   fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+                   exit(2);
+               }
+               return 0;
+           } else {
+               bcopy((char *)hp->h_addr, (char *)&isp->addr.sin_addr, hp->h_length);
+           }
+       }
+       isp->addr.sin_family = AF_INET;
+       if (session->remote_port == SNMP_DEFAULT_REMPORT){
+           /*servp = getservbyname("snmp", "udp");*/
+           servp=NULL;
+           if (servp != NULL){
+               isp->addr.sin_port = servp->s_port;
+           } else {
+               isp->addr.sin_port = htons(SNMP_PORT);
+           }
+       } else {
+           isp->addr.sin_port = htons(session->remote_port);
+       }
+    } else {
+       isp->addr.sin_addr.s_addr = SNMP_DEFAULT_ADDRESS;
+    }
+
+    me.sin_family = AF_INET;
+    me.sin_addr.s_addr = INADDR_ANY;
+    me.sin_port = htons(session->local_port);
+    if (bind(sd, (struct sockaddr *)&me, sizeof(me)) != 0){
+       perror("bind");
+       snmp_errno = SNMPERR_BAD_LOCPORT;
+       if (! snmp_close(session)){
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n", 
+                   api_errstring(snmp_errno));
+           exit(3);
+       }
+       return 0;
+    }
+
+    if( *cp == '/' ) {
+       session->authenticator = check_received_pkt;
+       sync_with_agent(session);
+       parse_app_community_string( session );
+       session->qoS |= USEC_QOS_GENREPORT;
+    }
+
+    /* replace comm pointer with pointer to new data: */
+    session->community = cp;   
+
+    return session;
+}
+
+void
+sync_with_agent( session )
+struct snmp_session *session;
+{
+    struct snmp_pdu *pdu, *response = 0;
+    int status;
+
+    session->qoS = USEC_QOS_GENREPORT;
+    session->userLen = 6;
+    session->version = SNMP_VERSION_2;
+    strcpy( session->userName, "public" );
+
+    snmp_synch_setup(session);
+    pdu = snmp_pdu_create(GET_REQ_MSG);
+    status = snmp_synch_response(session, pdu, &response);
+
+    if (status == STAT_SUCCESS){
+       memcpy( session->agentID, response->params.agentID, 12 );
+
+       /* save the clocks -- even though they are not authentic */
+       session->agentBoots = response->params.agentBoots;
+       session->agentTime = response->params.agentTime;
+       session->agentClock = response->params.agentTime - time(NULL);
+
+    } else {
+           if (status == STAT_TIMEOUT){
+               printf("No Response from %s\n", session->peername);
+           } else {    /* status == STAT_ERROR */
+               printf("An error occurred, Quitting\n");
+           }
+           exit( -1 );
+    }
+
+    /** freed to early: 
+      snmp_free_pdu(pdu);
+      if (response) snmp_free_pdu(response);
+     **/
+}
+#if 1 /***/
+/*
+ * Unlink one element from input request list,
+ * then free it and it's pdu.
+ */
+static void
+free_one_request(isp, orp)
+    struct snmp_internal_session *isp;
+    struct request_list *orp;
+{
+    struct request_list *rp;
+    if(! orp) return;
+    if(isp->requests == orp){ 
+      isp->requests = orp->next_request; /* unlink head */
+    }
+    else{
+      for(rp = isp->requests; rp; rp = rp->next_request){
+        if(rp->next_request == orp){ 
+         rp->next_request = orp->next_request; /* unlink element */
+         break;
+        }
+      }
+    }
+    if (orp->pdu != NULL){
+      snmp_free_pdu(orp->pdu);
+    }
+    free((char *)orp);
+}
+#endif /***/
+/*
+ * Free each element in the input request list.
+ */
+static void
+free_request_list(rp)
+     struct request_list *rp;
+{
+    struct request_list *orp;
+
+    while (rp) {
+       orp = rp;
+       rp = rp->next_request;
+       if (orp->pdu != NULL)
+           snmp_free_pdu(orp->pdu);
+       free((char *) orp);
+    }
+}
+
+/*
+ * 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.
+ */
+int
+snmp_close(session)
+     struct snmp_session *session;
+{
+    struct session_list *slp = NULL, *oslp = NULL;
+
+    if (Sessions->session == session) {                /* If first entry */
+       slp = Sessions;
+       Sessions = slp->next;
+    } else {
+       for (slp = Sessions; slp; slp = slp->next) {
+           if (slp->session == session) {
+               if (oslp)       /* if we found entry that points here */
+                   oslp->next = slp->next;     /* link around this entry */
+               break;
+           }
+           oslp = slp;
+       }
+    }
+    /* If we found the session, free all data associated with it */
+    if (slp) {
+       if (slp->session->community != NULL)
+           free((char *) slp->session->community);
+       if (slp->session->peername != NULL)
+           free((char *) slp->session->peername);
+       free((char *) slp->session);
+       if (slp->internal->sd != -1)
+           close(slp->internal->sd);
+       free_request_list(slp->internal->requests);
+       free((char *) slp->internal);
+       free((char *) slp);
+    } else {
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    return 1;
+}
+
+/*
+ * Takes a session and a pdu and serializes the ASN PDU into the area
+ * pointed to by packet.  out_length is the size of the data area available.
+ * Returns the length of the completed packet in out_length.  If any errors
+ * occur, -1 is returned.  If all goes well, 0 is returned.
+ */
+int
+snmp_build(session, pdu, packet, out_length, is_agent)
+     struct snmp_session *session;
+     struct snmp_pdu *pdu;
+     u_char *packet;
+     int *out_length;
+     int is_agent;
+{
+    u_char buf[PACKET_LENGTH];
+    u_char *cp;
+    struct variable_list *vp;
+    int length;
+    int totallength;
+
+    length = *out_length;
+    cp = packet;
+    for (vp = pdu->variables; vp; vp = vp->next_variable) {
+       cp = snmp_build_var_op(cp, vp->name, &vp->name_length, vp->type, vp->val_len, (u_char *) vp->val.string, &length);
+       if (cp == NULL)
+           return -1;
+    }
+    totallength = cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR), totallength);
+    if (cp == NULL)
+       return -1;
+    bcopy((char *) packet, (char *) cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+    if (pdu->command != TRP_REQ_MSG) {
+       /* request id */
+       cp = asn_build_int(packet, &length,
+           (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+           (long *) &pdu->reqid, sizeof(pdu->reqid));
+       if (cp == NULL)
+           return -1;
+       /* error status */
+       cp = asn_build_int(cp, &length,
+           (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+           (long *) &pdu->errstat, sizeof(pdu->errstat));
+       if (cp == NULL)
+           return -1;
+       /* error index */
+       cp = asn_build_int(cp, &length,
+           (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+           (long *) &pdu->errindex, sizeof(pdu->errindex));
+       if (cp == NULL)
+           return -1;
+    } else {                   /* this is a trap message */
+       /* enterprise */
+       cp = asn_build_objid(packet, &length,
+           (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID),
+           (oid *) pdu->enterprise, pdu->enterprise_length);
+       if (cp == NULL)
+           return -1;
+       /* agent-addr */
+       cp = asn_build_string(cp, &length, (u_char) IPADDRESS,
+           (u_char *) & pdu->agent_addr.sin_addr.s_addr, sizeof(pdu->agent_addr.sin_addr.s_addr));
+       if (cp == NULL)
+           return -1;
+       /* generic trap */
+       cp = asn_build_int(cp, &length,
+           (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+           (long *) &pdu->trap_type, sizeof(pdu->trap_type));
+       if (cp == NULL)
+           return -1;
+       /* specific trap */
+       cp = asn_build_int(cp, &length,
+           (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+           (long *) &pdu->specific_type, sizeof(pdu->specific_type));
+       if (cp == NULL)
+           return -1;
+       /* timestamp  */
+       cp = asn_build_int(cp, &length, (u_char) TIMETICKS,
+           (long *) &pdu->time, sizeof(pdu->time));
+       if (cp == NULL)
+           return -1;
+    }
+    if (length < totallength)
+       return -1;
+    bcopy((char *) buf, (char *) cp, totallength);
+    totallength += cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char) pdu->command, totallength);
+    if (cp == NULL)
+       return -1;
+    if (length < totallength)
+       return -1;
+    bcopy((char *) packet, (char *) cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+
+    cp = snmp_auth_build(packet, &length, session, is_agent, totallength);
+    if (cp == NULL)
+       return -1;
+    if ((*out_length - (cp - packet)) < totallength)
+       return -1;
+    bcopy((char *) buf, (char *) cp, totallength);
+    totallength += cp - packet;
+    *out_length = totallength;
+
+    if (session->qoS & USEC_QOS_AUTH)
+       md5Digest(packet, totallength, cp - (session->contextLen + 16),
+           cp - (session->contextLen + 16));
+
+    return 0;
+}
+
+/*
+ * Parses the packet received on the input session, and places the data into
+ * the input pdu.  length is the length of the input packet.  If any errors
+ * are encountered, -1 is returned.  Otherwise, a 0 is returned.
+ */
+static int
+snmp_parse(session, pdu, data, length)
+     struct snmp_session *session;
+     struct snmp_pdu *pdu;
+     u_char *data;
+     int length;
+{
+    u_char msg_type;
+    u_char type;
+    u_char *var_val;
+    long version;
+    int len, four;
+    u_char community[256];
+    int community_length = 256;
+    struct variable_list *vp = 0;
+    oid objid[MAX_NAME_LEN], *op;
+    u_char *origdata = data;
+    int origlength = length;
+    int ret = 0;
+    u_char *save_data;
+
+    /* authenticates message and returns length if valid */
+    data = snmp_auth_parse(data, &length, community, &community_length, &version);
+    if (data == NULL)
+       return -1;
+
+    if (version != SNMP_VERSION_1 && version != SNMP_VERSION_2C && version != SNMP_VERSION_2) {
+       fprintf(stderr, "Wrong version: %ld\n", version);
+       return -1;
+    }
+    save_data = data;
+
+    data = asn_parse_header(data, &length, &msg_type);
+    if (data == NULL)
+       return -1;
+    pdu->command = msg_type;
+
+    if (session->authenticator) {
+       ret = session->authenticator(origdata, origlength, save_data - community_length,
+           community_length, session, pdu);
+       if (ret < 0)
+           return ret;
+    }
+    if (pdu->command != TRP_REQ_MSG) {
+       data = asn_parse_int(data, &length, &type, (long *) &pdu->reqid, sizeof(pdu->reqid));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *) &pdu->errstat, sizeof(pdu->errstat));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *) &pdu->errindex, sizeof(pdu->errindex));
+       if (data == NULL)
+           return -1;
+    } else {
+       pdu->enterprise_length = MAX_NAME_LEN;
+       data = asn_parse_objid(data, &length, &type, objid, &pdu->enterprise_length);
+       if (data == NULL)
+           return -1;
+       pdu->enterprise = (oid *) calloc(1, pdu->enterprise_length * sizeof(oid));
+       bcopy((char *) objid, (char *) pdu->enterprise, pdu->enterprise_length * sizeof(oid));
+
+       four = 4;
+       data = asn_parse_string(data, &length, &type, (u_char *) & pdu->agent_addr.sin_addr.s_addr, &four);
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *) &pdu->trap_type, sizeof(pdu->trap_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *) &pdu->specific_type, sizeof(pdu->specific_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *) &pdu->time, sizeof(pdu->time));
+       if (data == NULL)
+           return -1;
+    }
+    data = asn_parse_header(data, &length, &type);
+    if (data == NULL)
+       return -1;
+    if (type != (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR))
+       return -1;
+    while ((int) length > 0) {
+       if (pdu->variables == NULL) {
+           pdu->variables = vp = (struct variable_list *) calloc(1, sizeof(struct variable_list));
+       } else {
+           vp->next_variable = (struct variable_list *) calloc(1, sizeof(struct variable_list));
+           vp = vp->next_variable;
+       }
+       vp->next_variable = NULL;
+       vp->val.string = NULL;
+       vp->name = NULL;
+       vp->name_length = MAX_NAME_LEN;
+       data = snmp_parse_var_op(data, objid, &vp->name_length, &vp->type, &vp->val_len, &var_val, (int *) &length);
+       if (data == NULL)
+           return -1;
+       op = (oid *) calloc(1, (unsigned) vp->name_length * sizeof(oid));
+       bcopy((char *) objid, (char *) op, vp->name_length * sizeof(oid));
+       vp->name = op;
+
+       len = PACKET_LENGTH;
+       switch ((short) vp->type) {
+       case ASN_INTEGER:
+           vp->val.integer = (long *) calloc(1, sizeof(long));
+           vp->val_len = sizeof(long);
+           asn_parse_int(var_val, &len, &vp->type, (long *) vp->val.integer, sizeof(vp->val.integer));
+           break;
+       case COUNTER:
+       case GAUGE:
+       case TIMETICKS:
+       case UINTEGER:
+           vp->val.integer = (long *) calloc(1, sizeof(unsigned long));
+           vp->val_len = sizeof(unsigned long);
+           asn_parse_unsigned_int(var_val, &len, &vp->type, (unsigned long *) vp->val.integer, sizeof(vp->val.integer));
+           break;
+       case COUNTER64:
+           vp->val.counter64 = (struct counter64 *) calloc(1, sizeof(struct counter64));
+           vp->val_len = sizeof(struct counter64);
+           asn_parse_unsigned_int64(var_val, &len, &vp->type,
+               (struct counter64 *) vp->val.counter64,
+               sizeof(*vp->val.counter64));
+           break;
+       case ASN_OCTET_STR:
+       case IPADDRESS:
+       case OPAQUE:
+       case NSAP:
+           vp->val.string = (u_char *) calloc(1, (unsigned) vp->val_len);
+           asn_parse_string(var_val, &len, &vp->type, vp->val.string, &vp->val_len);
+           break;
+       case ASN_OBJECT_ID:
+           vp->val_len = MAX_NAME_LEN;
+           asn_parse_objid(var_val, &len, &vp->type, objid, &vp->val_len);
+           vp->val_len *= sizeof(oid);
+           vp->val.objid = (oid *) calloc(1, (unsigned) vp->val_len);
+           bcopy((char *) objid, (char *) vp->val.objid, vp->val_len);
+           break;
+       case SNMP_NOSUCHOBJECT:
+       case SNMP_NOSUCHINSTANCE:
+       case SNMP_ENDOFMIBVIEW:
+       case ASN_NULL:
+           break;
+       default:
+           fprintf(stderr, "bad type returned (%x)\n", vp->type);
+           break;
+       }
+    }
+    return ret;
+}
+
+/*
+ * 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(session, pdu)
+     struct snmp_session *session;
+     struct snmp_pdu *pdu;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp = NULL;
+    u_char packet[PACKET_LENGTH];
+    int length = PACKET_LENGTH;
+    struct request_list *rp;
+    struct timeval tv;
+
+    for (slp = Sessions; slp; slp = slp->next) {
+       if (slp->session == session) {
+           isp = slp->internal;
+           break;
+       }
+    }
+
+    if (!pdu) {
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+    if (isp == NULL) {
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG
+       || pdu->command == GET_RSP_MSG || pdu->command == SET_REQ_MSG
+       || pdu->command == GETBULK_REQ_MSG) {
+       if (pdu->reqid == SNMP_DEFAULT_REQID)
+           pdu->reqid = ++Reqid;
+       if (pdu->errstat == SNMP_DEFAULT_ERRSTAT)
+           pdu->errstat = 0;
+       if (pdu->errindex == SNMP_DEFAULT_ERRINDEX)
+           pdu->errindex = 0;
+    } else {
+       /* fill in trap defaults */
+       pdu->reqid = 1;         /* give a bogus non-error reqid for traps */
+       if (pdu->enterprise_length == SNMP_DEFAULT_ENTERPRISE_LENGTH) {
+           pdu->enterprise = (oid *) calloc(1, sizeof(DEFAULT_ENTERPRISE));
+           bcopy((char *) DEFAULT_ENTERPRISE, (char *) pdu->enterprise, sizeof(DEFAULT_ENTERPRISE));
+           pdu->enterprise_length = sizeof(DEFAULT_ENTERPRISE) / sizeof(oid);
+       }
+       if (pdu->time == SNMP_DEFAULT_TIME)
+           pdu->time = DEFAULT_TIME;
+    }
+    if (pdu->address.sin_addr.s_addr == SNMP_DEFAULT_ADDRESS) {
+       if (isp->addr.sin_addr.s_addr != SNMP_DEFAULT_ADDRESS) {
+           bcopy((char *) &isp->addr, (char *) &pdu->address, sizeof(pdu->address));
+       } else {
+           fprintf(stderr, "No remote IP address specified\n");
+           snmp_errno = SNMPERR_BAD_ADDRESS;
+           return 0;
+       }
+    }
+    if (snmp_build(session, pdu, packet, &length, 0) < 0) {
+       fprintf(stderr, "Error building packet\n");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+#if 1/***/ if we found entry that points here */
+ oslp e key!  replace...
+     */
+ * \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 1\ 1\0\0\0\0\0\0\0\19\7fÿ¯ùsnmplib/snmp_api.c\0c\0\0.h\0\0\0\18\7fÿ°\85\10\0<Ðlib/snmp_api.c~\0~\0\0ñ\0\0\0\18\7fÿ±\1e\10\0\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\0\0\0\18\7fÿ±«\10\0=\10\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\0\0\0\18\7fÿ²\1d\10\0=0\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\0\0\0\18\7fÿ²\8a\10\0=P\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\0\0\0\18\7fÿ³
+\10\0=p\7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\0\0\0\18\7fÿ³\82\0\0\0\ 1\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\0\0\0Á\7fÿ³ù\0\0\0\10\7fÿ´\10\10\0\0%\0\19\0\15\0\0\10\0D(\0\0\0\10\7fÿ´_\10\0\0\0\ 2\\0\0\0\0\10\0\0\0\0\10\7fÿ´©\10\0=\98\0\0\ 24\0\0\0\0\10\0\0\0\0\10\7fÿ´ø\10\0\0\0\ 2H\0\0\0\0\10\0\0\0\0\10\7fÿµB\10\0>\10\7fÿµ]\7fÿµm\7fÿµz\0\0\0\10\7fÿµ \10\0>(\7fÿµ·\7fÿµÉ\7fÿµÖ\0\0\0\10\7fÿµï\10\0>@\7fÿ¶\12\7fÿ¶ \7fÿ¶4\0\0\0\10\7fÿ¶P\0\0\0\ 1\7fÿ¶r\7fÿ¶~\7fÿ¶\88\0\0\00\7fÿ¶\9f\0\0\0\0\7fÿ¶·\0\0\0\0\7fÿ¶Ù\10\0\82à\7fÿ·\ 1\0\0\0\0\7fÿ·#\7fÿ·/\7fÿ·>\10\0>X\7fÿ·V\0\0\03\0\0\0\0/usr/people/wessels/.indent.pro\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\ 1\0\0\0\0\7fÿ¯è\7fÿ¯ù\7fÿ°\f\7fÿ°\e\7fÿ°.\7fÿ°?\7fÿ°M\7fÿ°[\7fÿ°p\7fÿ°\85\7fÿ°\95\7fÿ°£\7fÿ°²\7fÿ°Å\7fÿ°Û\7fÿ°ñ\7fÿ±
+\7fÿ±\1e\7fÿ±2\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\7fÿ±\99\7fÿ±«\7fÿ±º\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\7fÿ²\ f\7fÿ²\1d\7fÿ²2\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\7fÿ²\7f\7fÿ²\8a\7fÿ²\99\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\7fÿ²ö\7fÿ³
+\7fÿ³ \7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\7fÿ³s\7fÿ³\82\7fÿ³\91\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\7fÿ³ç\7fÿ³ù\7fÿ´\ 4\7fÿ´\10\7fÿ´\1e\7fÿ´)\7fÿ´3\7fÿ´C\7fÿ´O\7fÿ´_\7fÿ´k\7fÿ´t\7fÿ´\81\7fÿ´\8f\7fÿ´\9f\7fÿ´©\7fÿ´·\7fÿ´Å\7fÿ´Ò\7fÿ´Ý\7fÿ´í\7fÿ´ø\7fÿµ\ 3\7fÿµ\10\7fÿµ\1d\7fÿµ)\7fÿµ7\7fÿµB\7fÿµM\7fÿµ]\7fÿµm\7fÿµz\7fÿµ\89\7fÿµ \7fÿµ«\7fÿµ·\7fÿµÉ\7fÿµÖ\7fÿµâ\7fÿµï\7fÿ¶\ 3\7fÿ¶\12\7fÿ¶ \7fÿ¶4\7fÿ¶?\7fÿ¶P\7fÿ¶b\7fÿ¶r\7fÿ¶~\7fÿ¶\88\7fÿ¶\94\7fÿ¶\9f\7fÿ¶«\7fÿ¶·\7fÿ¶É\7fÿ¶Ù\7fÿ¶í\7fÿ·\ 1\7fÿ·\15\7fÿ·#\7fÿ·/\7fÿ·>\7fÿ·L\7fÿ·V\7fÿ·f\7fÿ·q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0@    \0\0\0\0reqid, sizeof(pdu->reqid));
+       if (cp == NULL)
+           return -1;
+       /* error status */
+       cp = asn_build_int(cp, &length,
+           (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+           (long *) &pdu->errstat, sizeof(pdu->errstat));
+       if (cp == NULL)
+           return -1;
+       /* error index */
+       cp = asn_build_int(cp, &length,
+           (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+           (long *) &pdu->errindex, sizeof(pdu->errindex));
+       if (cp == NULL)
+           return -1;
+    } else {                   /* this is a trap message */
+       /* enterprise */
+       cp = asn_build_objid(packet, &length,
+           (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID),
+           (oid *) pdu->enterprise, pdu->enterprise_length);
+       if (cp == NULL)
+           return -1;
+       /* agent-addr */
+       cp = asn_build_string(cp, &length, (u_char) IPADDRESS,
+           (u_char *) & pdu->agent_addr.sin_addr.s_addr, sizeof(pdu->agent_addr.sin_addr.s_addr));
+       if (cp == NULL)
+           return -1;
+       /* generic trap */
+       cp = asn_build_int(cp, &length,
+           (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+           (long *) &pdu->trap_type, sizeof(pdu->trap_type));
+       if (cp == NULL)
+           return -1;
+       /* specific trap */
+       cp = asn_build_int(cp, &length,
+           (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+           (long *) &pdu->specific_type, sizeof(pdu->specific_type));
+       if (cp == NULL)
+           return -1;
+       /* timestamp  */
+       cp = asn_build_int(cp, &length, (u_char) TIMETICKS,
+           (long *) &pdu->time, sizeof(pdu->time));
+       if (cp == NULL)
+           return -1;
+    }
+    if (length < totallength)
+       return -1;
+    bcopy((char *) buf, (char *) cp, totallength);
+    totallength += cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char) pdu->command, totallength);
+    if (cp == NULL)
+       return -1;
+    if (length < totallength)
+       return -1;
+    bcopy((char *) packet, (char *) cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+
+    cp = snmp_auth_build(packet, &length, session, is_agent, totallength);
+    if (cp == NULL)
+       return -1;
+    if ((*out_length - (cp - packet)) < totallength)
+       return -1;
+    bcopy((char *) buf, (char *) cp, totallength);
+    totallength += cp - packet;
+    *out_length = totallength;
+
+    if (session->qoS & USEC_QOS_AUTH)
+       md5Digest(packet, totallength, cp - (session->contextLen + 16),
+           cp - (session->contextLen + 16));
+
+    return 0;
+}
+
+/*
+ * Parses the packet received on the input session, and places the data into
+ * the input pdu.  length is the length of the input packet.  If any errors
+ * are encountered, -1 is returned.  Otherwise, a 0 is returned.
+ */
+static int
+snmp_parse(session, pdu, data, length)
+     struct snmp_session *session;
+     struct snmp_pdu *pdu;
+     u_char *data;
+     int length;
+{
+    u_char msg_type;
+    u_char type;
+    u_char *var_val;
+    long version;
+    int len, four;
+    u_char community[256];
+    int community_length = 256;
+    struct variable_list *vp = 0;
+    oid objid[MAX_NAME_LEN], *op;
+    u_char *origdata = data;
+    int origlength = length;
+    int ret = 0;
+    u_char *save_data;
+
+    /* authenticates message and returns length if valid */
+    data = snmp_auth_parse(data, &length, community, &community_length, &version);
+    if (data == NULL)
+       return -1;
+
+    if (version != SNMP_VERSION_1 && version != SNMP_VERSION_2C && version != SNMP_VERSION_2) {
+       fprintf(stderr, "Wrong version: %ld\n", version);
+       return -1;
+    }
+    save_data = data;
+
+    data = asn_parse_header(data, &length, &msg_type);
+    if (data == NULL)
+       return -1;
+    pdu->command = msg_type;
+
+    if (session->authenticator) {
+       ret = session->authenticator(origdata, origlength, save_data - community_length,
+           community_length, session, pdu);
+       if (ret < 0)
+           return ret;
+    }
+    if (pdu->command != TRP_REQ_MSG) {
+       data = asn_parse_int(data, &length, &type, (long *) &pdu->reqid, sizeof(pdu->reqid));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *) &pdu->errstat, sizeof(pdu->errstat));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *) &pdu->errindex, sizeof(pdu->errindex));
+       if (data == NULL)
+           return -1;
+    } else {
+       pdu->enterprise_length = MAX_NAME_LEN;
+       data = asn_parse_objid(data, &length, &type, objid, &pdu->enterprise_length);
+       if (data == NULL)
+           return -1;
+       pdu->enterprise = (oid *) calloc(1, pdu->enterprise_length * sizeof(oid));
+       bcopy((char *) objid, (char *) pdu->enterprise, pdu->enterprise_length * sizeof(oid));
+
+       four = 4;
+       data = asn_parse_string(data, &length, &type, (u_char *) & pdu->agent_addr.sin_addr.s_addr, &four);
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *) &pdu->trap_type, sizeof(pdu->trap_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *) &pdu->specific_type, sizeof(pdu->specific_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *) &pdu->time, sizeof(pdu->time));
+       if (data == NULL)
+           return -1;
+    }
+    data = asn_parse_header(data, &length, &type);
+    if (data == NULL)
+       return -1;
+    if (type != (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR))
+       return -1;
+    while ((int) length > 0) {
+       if (pdu->variables == NULL) {
+           pdu->variables = vp = (struct variable_list *) calloc(1, sizeof(struct variable_list));
+       } else {
+           vp->next_variable = (struct variable_list *) calloc(1, sizeof(struct variable_list));
+           vp = vp->next_variable;
+       }
+       vp->next_variable = NULL;
+       vp->val.string = NULL;
+       vp->name = NULL;
+       vp->name_length = MAX_NAME_LEN;
+       data = snmp_parse_var_op(data, objid, &vp->name_length, &vp->type, &vp->val_len, &var_val, (int *) &length);
+       if (data == NULL)
+           return -1;
+       op = (oid *) calloc(1, (unsigned) vp->name_length * sizeof(oid));
+       bcopy((char *) objid, (char *) op, vp->name_length * sizeof(oid));
+       vp->name = op;
+
+       len = PACKET_LENGTH;
+       switch ((short) vp->type) {
+       case ASN_INTEGER:
+           vp->val.integer = (long *) calloc(1, sizeof(long));
+           vp->val_len = sizeof(long);
+           asn_parse_int(var_val, &len, &vp->type, (long *) vp->val.integer, sizeof(vp->val.integer));
+           break;
+       case COUNTER:
+       case GAUGE:
+       case TIMETICKS:
+       case UINTEGER:
+           vp->val.integer = (long *) calloc(1, sizeof(unsigned long));
+           vp->val_len = sizeof(unsigned long);
+           asn_parse_unsigned_int(var_val, &len, &vp->type, (unsigned long *) vp->val.integer, sizeof(vp->val.integer));
+           break;
+       case COUNTER64:
+           vp->val.counter64 = (struct counter64 *) calloc(1, sizeof(struct counter64));
+           vp->val_len = sizeof(struct counter64);
+           asn_parse_unsigned_int64(var_val, &len, &vp->type,
+               (struct counter64 *) vp->val.counter64,
+               sizeof(*vp->val.counter64));
+           break;
+       case ASN_OCTET_STR:
+       case IPADDRESS:
+       case OPAQUE:
+       case NSAP:
+           vp->val.string = (u_char *) calloc(1, (unsigned) vp->val_len);
+           asn_parse_string(var_val, &len, &vp->type, vp->val.string, &vp->val_len);
+           break;
+       case ASN_OBJECT_ID:
+           vp->val_len = MAX_NAME_LEN;
+           asn_parse_objid(var_val, &len, &vp->type, objid, &vp->val_len);
+           vp->val_len *= sizeof(oid);
+           vp->val.objid = (oid *) calloc(1, (unsigned) vp->val_len);
+           bcopy((char *) objid, (char *) vp->val.objid, vp->val_len);
+           break;
+       case SNMP_NOSUCHOBJECT:
+       case SNMP_NOSUCHINSTANCE:
+       case SNMP_ENDOFMIBVIEW:
+       case ASN_NULL:
+           break;
+       default:
+           fprintf(stderr, "bad type returned (%x)\n", vp->type);
+           break;
+       }
+    }
+    return ret;
+}
+
+/*
+ * 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(session, pdu)
+     struct snmp_session *session;
+     struct snmp_pdu *pdu;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp = NULL;
+    u_char packet[PACKET_LENGTH];
+    int length = PACKET_LENGTH;
+    struct request_list *rp;
+    struct timeval tv;
+
+    for (slp = Sessions; slp; slp = slp->next) {
+       if (slp->session == session) {
+           isp = slp->internal;
+           break;
+       }
+    }
+
+    if (!pdu) {
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+    if (isp == NULL) {
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG
+       || pdu->command == GET_RSP_MSG || pdu->command == SET_REQ_MSG
+       || pdu->command == GETBULK_REQ_MSG) {
+       if (pdu->reqid == SNMP_DEFAULT_REQID)
+           pdu->reqid = ++Reqid;
+       if (pdu->errstat == SNMP_DEFAULT_ERRSTAT)
+           pdu->errstat = 0;
+       if (pdu->errindex == SNMP_DEFAULT_ERRINDEX)
+           pdu->errindex = 0;
+    } else {
+       /* fill in trap defaults */
+       pdu->reqid = 1;         /* give a bogus non-error reqid for traps */
+       if (pdu->enterprise_length == SNMP_DEFAULT_ENTERPRISE_LENGTH) {
+           pdu->enterprise = (oid *) calloc(1, sizeof(DEFAULT_ENTERPRISE));
+           bcopy((char *) DEFAULT_ENTERPRISE, (char *) pdu->enterprise, sizeof(DEFAULT_ENTERPRISE));
+           pdu->enterprise_length = sizeof(DEFAULT_ENTERPRISE) / sizeof(oid);
+       }
+       if (pdu->time == SNMP_DEFAULT_TIME)
+           pdu->time = DEFAULT_TIME;
+    }
+    if (pdu->address.sin_addr.s_addr == SNMP_DEFAULT_ADDRESS) {
+       if (isp->addr.sin_addr.s_addr != SNMP_DEFAULT_ADDRESS) {
+           bcopy((char *) &isp->addr, (char *) &pdu->address, sizeof(pdu->address));
+       } else {
+           fprintf(stderr, "No remote IP address specified\n");
+           snmp_errno = SNMPERR_BAD_ADDRESS;
+           return 0;
+       }
+    }
+    if (snmp_build(session, pdu, packet, &length, 0) < 0) {
+       fprintf(stderr, "Error building packet\n");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+community_len);
+       bcopy((char *)DEFAULT_COMMUNITY, (char *)cp, session->community_len);
+    }
+
+    /* Set up connections */
+    sd = socket(AF_INET, SOCK_DGRAM, 0);
+    if (sd < 0){
+       perror("socket");
+       snmp_errno = SNMPERR_GENERR;
+       if (!snmp_close(session)){
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+           exit(1);
+       }
+       return 0;
+    }
+    isp->sd = sd;
+
+    if (session->peername != SNMP_DEFAULT_PEERNAME){
+       if ((addr = inet_addr(session->peername)) != -1){
+           bcopy((char *)&addr, (char *)&isp->addr.sin_addr, sizeof(isp->addr.sin_addr));
+       } else {
+           hp = gethostbyname(session->peername);
+           if (hp == NULL){
+               fprintf(stderr, "unknown host: %s\n", session->peername);
+               snmp_errno = SNMPERR_BAD_ADDRESS;
+               if (!snmp_close(session)){
+                   fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+                   exit(2);
+               }
+               return 0;
+           } else {
+               bcopy((char *)hp->h_addr, (char *)&isp->addr.sin_addr, hp->h_length);
+           }
+       }
+       isp->addr.sin_family = AF_INET;
+       if (session->remote_port == SNMP_DEFAULT_REMPORT){
+           /*servp = getservbyname("snmp", "udp");*/
+           servp=NULL;
+           if (servp != NULL){
+               isp->addr.sin_port = servp->s_port;
+           } else {
+               isp->addr.sin_port = htons(SNMP_PORT);
+           }
+       } else {
+           isp->addr.sin_port = htons(session->remote_port);
+       }
+    } else {
+       isp->addr.sin_addr.s_addr = SNMP_DEFAULT_ADDRESS;
+    }
+
+    me.sin_family = AF_INET;
+    me.sin_addr.s_addr = INADDR_ANY;
+    me.sin_port = htons(session->local_port);
+    if (bind(sd, (struct sockaddr *)&me, sizeof(me)) != 0){
+       perror("bind");
+       snmp_errno = SNMPERR_BAD_LOCPORT;
+       if (! snmp_close(session)){
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n", 
+                   api_errstring(snmp_errno));
+           exit(3);
+       }
+       return 0;
+    }
+
+    if( *cp == '/' ) {
+       session->authenticator = check_received_pkt;
+       sync_with_agent(session);
+       parse_app_community_string( session );
+       session->qoS |= USEC_QOS_GENREPORT;
+    }
+
+    /* replace comm pointer with pointer to new data: */
+    session->community = cp;   
+
+    return session;
+}
+
+void
+sync_with_agent( session )
+struct snmp_session *session;
+{
+    struct snmp_pdu *pdu, *response = 0;
+    int status;
+
+    session->qoS = USEC_QOS_GENREPORT;
+    session->userLen = 6;
+    session->version = SNMP_VERSION_2;
+    strcpy( session->userName, "public" );
+
+    snmp_synch_setup(session);
+    pdu = snmp_pdu_create(GET_REQ_MSG);
+    status = snmp_synch_response(session, pdu, &response);
+
+    if (status == STAT_SUCCESS){
+       memcpy( session->agentID, response->params.agentID, 12 );
+
+       /* save the clocks -- even though they are not authentic */
+       session->agentBoots = response->params.agentBoots;
+       session->agentTime = response->params.agentTime;
+       session->agentClock = response->params.agentTime - time(NULL);
+
+    } else {
+           if (status == STAT_TIMEOUT){
+               printf("No Response from %s\n", session->peername);
+           } else {    /* status == STAT_ERROR */
+               printf("An error occurred, Quitting\n");
+           }
+           exit( -1 );
+    }
+
+    /** freed to early: 
+      snmp_free_pdu(pdu);
+      if (response) snmp_free_pdu(response);
+     **/
+}
+#if 1 /***/
+/*
+ * Unlink one element from input request list,
+ * then free it and it's pdu.
+ */
+static void
+free_one_request(isp, orp)
+    struct snmp_internal_session *isp;
+    struct request_list *orp;
+{
+    struct request_list *rp;
+    if(! orp) return;
+    if(isp->requests == orp){ 
+      isp->requests = orp->next_request; /* unlink head */
+    }
+    else{
+      for(rp = isp->requests; rp; rp = rp->next_request){
+        if(rp->next_request == orp){ 
+         rp->next_request = orp->next_request; /* unlink element */
+         break;
+        }
+      }
+    }
+    if (orp->pdu != NULL){
+      snmp_free_pdu(orp->pdu);
+    }
+    free((char *)orp);
+}
+#endif /***/
+/*
+ * Free each element in the input request list.
+ */
+static void
+free_request_list(rp)
+     struct request_list *rp;
+{
+    struct request_list *orp;
+
+    while (rp) {
+       orp = rp;
+       rp = rp->next_request;
+       if (orp->pdu != NULL)
+           snmp_free_pdu(orp->pdu);
+       free((char *) orp);
+    }
+}
+
+/*
+ * 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.
+ */
+int
+snmp_close(session)
+     struct snmp_session *session;
+{
+    struct session_list *slp = NULL, *oslp = NULL;
+
+    if (Sessions->session == session) {                /* If first entry */
+       slp = Sessions;
+       Sessions = slp->next;
+    } else {
+       for (slp = Sessions; slp; slp = slp->next) {
+           if (slp->session == session) {
+               if (oslp)       /* if we found entry that points here */
+                   oslp->next = slp->next;     /* link around this entry */
+               break;
+           }
+           oslp = slp;
+       }
+    }
+    /* If we found the session, free all data associated with it */
+    if (slp) {
+       if (slp->session->community != NULL)
+           free((char *) slp->session->community);
+       if (slp->session->peername != NULL)
+           free((char *) slp->session->peername);
+       free((char *) slp->session);
+       if (slp->internal->sd != -1)
+           close(slp->internal->sd);
+       free_request_list(slp->internal->requests);
+       free((char *) slp->internal);
+       free((char *) slp);
+    } else {
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    return 1;
+}
+
+/*
+ * Takes a session and a pdu and serializes the ASN PDU into the area
+ * pointed to by packet.  out_length is the size of the data area available.
+ * Returns the length of the completed packet in out_length.  If any errors
+ * occur, -1 is returned.  If all goes well, 0 is returned.
+ */
+int
+snmp_build(session, pdu, packet, out_length, is_agent)
+     struct snmp_session *session;
+     struct snmp_pdu *pdu;
+     u_char *packet;
+     int *out_length;
+     int is_agent;
+{
+    u_char buf[PACKET_LENGTH];
+    u_char *cp;
+    struct variable_list *vp;
+    int length;
+    int totallength;
+
+    length = *out_length;
+    cp = packet;
+    for (vp = pdu->variables; vp; vp = vp->next_variable) {
+       cp = snmp_build_var_op(cp, vp->name, &vp->name_length, vp->type, vp->val_len, (u_char *) vp->val.string, &length);
+       if (cp == NULL)
+           return -1;
+    }
+    totallength = cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR), totallength);
+    if (cp == NULL)
+       return -1;
+    bcopy((char *) packet, (char *) cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+    if (pdu->command != TRP_REQ_MSG) {
+       /* request id */
+       cp = asn_build_int(packet, &length,
+           (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+           (long *) &pdu->\10\0BÐ+= m\0\0
+È      /* \10\0>X*/ B\10\04¨NMPT\10\ 1\98à */c\0\0\0\0for testing purposes */e key!  replace...
+     */
+ * \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 1\ 1\0\0\0\0\0\0\0\19\7fÿ¯ùsnmplib/snmp_api.c\0c\0\0.h\0\0\0\18\7fÿ°\85\10\0<Ðlib/snmp_api.c~\0~\0\0ñ\0\0\0\18\7fÿ±\1e\10\0\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\0\0\0\18\7fÿ±«\10\0=\10\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\0\0\0\18\7fÿ²\1d\10\0=0\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\0\0\0\18\7fÿ²\8a\10\0=P\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\0\0\0\18\7fÿ³
+\10\0=p\7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\0\0\0\18\7fÿ³\82\0\0\0\ 1\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\0\0\0Á\7fÿ³ù\0\0\0\10\7fÿ´\10\10\0\0%\0\19\0\15\0\0\10\0D(\0\0\0\10\7fÿ´_\10\0\0\0\ 2\\0\0\0\0\10\0\0\0\0\10\7fÿ´©\10\0=\98\0\0\ 24\0\0\0\0\10\0\0\0\0\10\7fÿ´ø\10\0\0\0\ 2H\0\0\0\0\10\0\0\0\0\10\7fÿµB\10\0>\10\7fÿµ]\7fÿµm\7fÿµz\0\0\0\10\7fÿµ \10\0>(\7fÿµ·\7fÿµÉ\7fÿµÖ\0\0\0\10\7fÿµï\10\0>@\7fÿ¶\12\7fÿ¶ \7fÿ¶4\0\0\0\10\7fÿ¶P\0\0\0\ 1\7fÿ¶r\7fÿ¶~\7fÿ¶\88\0\0\00\7fÿ¶\9f\10\0\7fÿ¶·\0\0\0\0\7fÿ¶Ù\10\0\89è\7fÿ·\ 1\0\0\0\0\7fÿ·#\7fÿ·/\7fÿ·>\10\0>X\7fÿ·V\0\0\03\0\0\0\0/usr/people/wessels/.indent.pro\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\ 1\0\0\0\0\7fÿ¯è\7fÿ¯ù\7fÿ°\f\7fÿ°\e\7fÿ°.\7fÿ°?\7fÿ°M\7fÿ°[\7fÿ°p\7fÿ°\85\7fÿ°\95\7fÿ°£\7fÿ°²\7fÿ°Å\7fÿ°Û\7fÿ°ñ\7fÿ±
+\7fÿ±\1e\7fÿ±2\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\7fÿ±\99\7fÿ±«\7fÿ±º\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\7fÿ²\ f\7fÿ²\1d\7fÿ²2\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\7fÿ²\7f\7fÿ²\8a\7fÿ²\99\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\7fÿ²ö\7fÿ³
+\7fÿ³ \7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\7fÿ³s\7fÿ³\82\7fÿ³\91\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\7fÿ³ç\7fÿ³ù\7fÿ´\ 4\7fÿ´\10\7fÿ´\1e\7fÿ´)\7fÿ´3\7fÿ´C\7fÿ´O\7fÿ´_\7fÿ´k\7fÿ´t\7fÿ´\81\7fÿ´\8f\7fÿ´\9f\7fÿ´©\7fÿ´·\7fÿ´Å\7fÿ´Ò\7fÿ´Ý\7fÿ´í\7fÿ´ø\7fÿµ\ 3\7fÿµ\10\7fÿµ\1d\7fÿµ)\7fÿµ7\7fÿµB\7fÿµM\7fÿµ]\7fÿµm\7fÿµz\7fÿµ\89\7fÿµ \7fÿµ«\7fÿµ·\7fÿµÉ\7fÿµÖ\7fÿµâ\7fÿµï\7fÿ¶\ 3\7fÿ¶\12\7fÿ¶ \7fÿ¶4\7fÿ¶?\7fÿ¶P\7fÿ¶b\7fÿ¶r\7fÿ¶~\7fÿ¶\88\7fÿ¶\94\7fÿ¶\9f\7fÿ¶«\7fÿ¶·\7fÿ¶É\7fÿ¶Ù\7fÿ¶í\7fÿ·\ 1\7fÿ·\15\7fÿ·#\7fÿ·/\7fÿ·>\7fÿ·L\7fÿ·V\7fÿ·f\7fÿ·q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\0\0\0°\0\0\0\ 4\0\0\0\0\0\0\0\b\10\0>X\0\0\0\f\10\0\0\0\0\10\0\0\0\0\0\0\0\14\0\0\0\14\0\0\0\14\0\0\0\18\0\0\0\18\0\0\0\18\0\0\0\1c\0\0\0\1c\0\0\0\1c\0\0\0\1c\0\0\0 \0\0\0 \0\0\0 \0\0\0$\0\0\0\v\0\0\0\e\0\0\0\19\0\0\0\v\0\0\0\e\0\0\0@\0\0\0\0\0\0\0\0\0\0\0\0\10\0,\b\0\0\0\1a\10\02\88\0\0\0\1a\0\0\0\0\0\0\0\1a\10\0\85\b\0\0\0\0\10\0>X\0\0\0\0\0\0\0\0\0\0\0\0\10\0\82à\0\0\0\0\0\0\ 1C\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e0\0\0\0\v\0\0\0\e\0\0\0\18\0\0\0\v\0\0\0\1a\0\0\0\17\0\0\0\v\0\0\0 \0\0\0\0\10\0\8d¸ude/snmp_groupvars.h~\0\0\b\0\0\0\b\0\0\0 \0\0\0\0\10\0\8dàude/snmp_groupvars.h\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8eX\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e\80\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e¨\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8eÐ\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\0\0\0\ 1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\84©\0\0\0\0/***********************************************************
+       Copyright 1989 by Carnegie Mellon University
+
+                      All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the name of CMU not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+******************************************************************/
+/*
+ * snmp_api.c - API for access to snmp.
+ */
+#define DEBUG_SNMPTRACE                0 /* set to 1 to print all SNMP actions */
+#define DEBUG_SNMPFULLDUMP     0 /* set to 1 to dump all SNMP packets */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#ifdef linux
+#include <arpa/inet.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#endif
+
+
+#include "asn1.h"
+#include "snmp.h"
+#include "snmp_impl.h"
+#include "snmp_api.h"
+#include "snmp_client.h"
+
+#define PACKET_LENGTH  4500
+
+#ifndef BSD4_3
+#define BSD4_2
+#endif
+
+#if !defined(BSD4_3) && !defined(linux) && !defined(sun)
+
+typedef long   fd_mask;
+#define NFDBITS        (sizeof(fd_mask) * NBBY)        /* bits per mask */
+
+#define        FD_SET(n, p)    ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+#define        FD_CLR(n, p)    ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+#define        FD_ISSET(n, p)  ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+#define FD_ZERO(p)     bzero((char *)(p), sizeof(*(p)))
+#endif
+
+oid default_enterprise[] = {1, 3, 6, 1, 4, 1, 3, 1, 1}; /* enterprises.cmu.systems.cmuSNMP */
+
+#define DEFAULT_COMMUNITY   "public"
+#define DEFAULT_REMPORT            SNMP_PORT
+#define DEFAULT_ENTERPRISE  default_enterprise
+#define DEFAULT_TIME       0
+#define DEFAULT_MMS        1389 /* large, randomly picked for testing purposes */
+
+/*
+ * Internal information about the state of the snmp session.
+ */
+struct snmp_internal_session {
+    int            sd;         /* socket descriptor for this connection */
+    ipaddr  addr;      /* address of connected peer */
+    struct request_list *requests;/* Info about outstanding requests */
+};
+
+/*
+ * A list of all the outstanding requests for a particular session.
+ */
+struct request_list {
+    struct request_list *next_request;
+    u_long  request_id;        /* request id */
+    int            retries;    /* Number of retries */
+    u_long timeout;    /* length to wait for timeout */
+    struct timeval time; /* Time this request was made */
+    struct timeval expire;  /* time this request is due to expire */
+    struct snmp_pdu *pdu;   /* The pdu for this request (saved so it can be retransmitted */
+};
+
+/*
+ * The list of active/open sessions.
+ */
+struct session_list {
+    struct session_list *next;
+    struct snmp_session *session;
+    struct snmp_internal_session *internal;
+};
+
+struct session_list *Sessions = NULL;
+
+u_long Reqid = 0;
+int snmp_errno = 0;
+
+char *api_errors[4] = {
+    "Unknown session",
+    "Unknown host",
+    "Invalid local port",
+    "Unknown Error"
+};
+
+
+void sync_with_agent();
+int parse_app_community_string();
+void snmp_synch_setup();
+int snmp_synch_response();
+void md5Digest();
+
+
+static char *
+api_errstring(snmp_errnumber)
+    int        snmp_errnumber;
+{
+    if (snmp_errnumber <= SNMPERR_BAD_SESSION && snmp_errnumber >= SNMPERR_GENERR){
+       return api_errors[snmp_errnumber + 4];
+    } else {
+       return "Unknown Error";
+    }
+}
+
+#if 0
+/*
+ * Gets initial request ID for all transactions.
+ */
+static void
+init_snmp(){
+    struct timeval tv;
+
+    gettimeofday(&tv, (struct timezone *)0);
+    srandom(tv.tv_sec ^ tv.tv_usec);
+    Reqid = random();
+}
+#endif
+
+
+/*
+ * Dump snmp packet to stdout:
+ */
+static void
+snmp_print_packet(packet, length, addr, code)
+  char *packet; 
+  int length; 
+  ipaddr addr; 
+  int code;
+{
+  if(length < 0) {
+    return;
+  }
+  if (code <= 0) { /* received */
+    printf("\nReceived %4d bytes from ", length);
+  }
+  else { /* sending */
+    printf("\nSending  %4d bytes to   ", length);
+  }
+  printf("%s:", inet_ntoa(addr.sin_addr));
+#if DEBUG_SNMPFULLDUMP
+  for (count = 0; count < length; count++) {
+    if ((count & 15) == 0) {
+      printf("\n  ");
+    }
+    printf("%02X ", (int)(packet[count]&255));
+  }
+#endif
+  fflush(stdout);
+}
+
+#if DEBUG_SNMPTRACE
+/*
+ * Print request
+ */
+#define TRACE_SEND   (0)
+#define TRACE_RECV   (1)
+#define TRACE_TIMEOUT (2)
+static void
+snmp_print_trace(slp, rp, code)
+  struct session_list *slp;
+  struct request_list *rp;
+  int code;
+{
+  int reqid=0, retries=1;
+  if( rp ){
+    reqid = rp->request_id;
+    retries = rp->retries;
+  }  
+  printf("\n Session %2d  ReqId %4d  ", slp->internal->sd, reqid);
+  switch(code)
+    { 
+    case TRACE_SEND:    printf("send pdu (%d)", retries);break; 
+    case TRACE_RECV:    printf("recv pdu");break; 
+    case TRACE_TIMEOUT: printf("time out");break; 
+    }
+  fflush(stdout);
+}
+#endif /* DEBUG_SNMPTRACE */
+
+
+
+
+/*
+ * 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.
+ */
+struct snmp_session *
+snmp_open(session)
+    struct snmp_session *session;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp;
+    u_char *cp;
+    int sd;
+    u_long addr;
+    struct sockaddr_in me;
+    struct hostent *hp;
+    struct servent *servp;
+    extern int check_received_pkt();
+
+    /* Copy session structure and link into list */
+    slp = (struct session_list *)calloc(1, sizeof(struct session_list));
+    slp->internal = isp = (struct snmp_internal_session *)calloc(1, sizeof(struct snmp_internal_session));
+    bzero((char *)isp, sizeof(struct snmp_internal_session));
+    slp->internal->sd = -1; /* mark it not set */
+    slp->session = (struct snmp_session *)calloc(1, sizeof(struct snmp_session));
+    bcopy((char *)session, (char *)slp->session, sizeof(struct snmp_session));
+    session = slp->session;
+    /* now link it in. */
+    slp->next = Sessions;
+    Sessions = slp;
+
+    /*
+     * session now points to the new structure that still contains pointers to
+     * data allocated elsewhere.  Some of this data is copied to space malloc'd
+     * here, and the pointer replaced with the new one.
+     */
+
+    if (session->peername != NULL){
+       cp = (u_char *)calloc(1, (unsigned)strlen(session->peername) + 1);
+       strcpy((char *)cp, session->peername);
+       session->peername = (char *)cp;
+    }
+
+    if (session->retries == SNMP_DEFAULT_RETRIES)
+       session->retries = SNMP_API_DEFAULT_RETRIES;
+    if (session->timeout == SNMP_DEFAULT_TIMEOUT)
+       session->timeout = SNMP_API_DEFAULT_TIMEOUT;
+    if (session->MMS == 0 )
+       session->MMS = DEFAULT_MMS;
+    isp->requests = NULL;
+
+
+    /* Fill in defaults if necessary */
+    if (session->community_len != SNMP_DEFAULT_COMMUNITY_LEN){
+       if( *session->community == '+' ) {
+               session->community_len--;
+               cp = (u_char *) calloc(1, (unsigned) session->community_len);
+               bcopy((char *) session->community+1, (char *)cp,
+                     session->community_len);
+               session->version = SNMP_VERSION_2C;
+       } else {
+               cp = (u_char *) calloc(1, (unsigned) session->community_len);
+               bcopy((char *) session->community, (char *) cp, 
+                     session->community_len);
+       }
+
+    } else {
+       session->community_len = strlen(DEFAULT_COMMUNITY);
+       cp = (u_char *)calloc(1, (unsigned)session->community_len);
+       bcopy((char *)DEFAULT_COMMUNITY, (char *)cp, session->community_len);
+    }
+
+    /* Set up connections */
+    sd = socket(AF_INET, SOCK_DGRAM, 0);
+    if (sd < 0){
+       perror("socket");
+       snmp_errno = SNMPERR_GENERR;
+       if (!snmp_close(session)){
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+           exit(1);
+       }
+       return 0;
+    }
+    isp->sd = sd;
+
+    if (session->peername != SNMP_DEFAULT_PEERNAME){
+       if ((addr = inet_addr(session->peername)) != -1){
+           bcopy((char *)&addr, (char *)&isp->addr.sin_addr, sizeof(isp->addr.sin_addr));
+       } else {
+           hp = gethostbyname(session->peername);
+           if (hp == NULL){
+               fprintf(stderr, "unknown host: %s\n", session->peername);
+               snmp_errno = SNMPERR_BAD_ADDRESS;
+               if (!snmp_close(session)){
+                   fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+                   exit(2);
+               }
+               return 0;
+           } else {
+               bcopy((char *)hp->h_addr, (char *)&isp->addr.sin_addr, hp->h_length);
+           }
+       }
+       isp->addr.sin_family = AF_INET;
+       if (session->remote_port == SNMP_DEFAULT_REMPORT){
+           /*servp = getservbyname("snmp", "udp");*/
+           servp=NULL;
+           if (servp != NULL){
+               isp->addr.sin_port = servp->s_port;
+           } else {
+               isp->addr.sin_port = htons(SNMP_PORT);
+           }
+       } else {
+           isp->addr.sin_port = htons(session->remote_port);
+       }
+    } else {
+       isp->addr.sin_addr.s_addr = SNMP_DEFAULT_ADDRESS;
+    }
+
+    me.sin_family = AF_INET;
+    me.sin_addr.s_addr = INADDR_ANY;
+    me.sin_port = htons(session->local_port);
+    if (bind(sd, (struct sockaddr *)&me, sizeof(me)) != 0){
+       perror("bind");
+       snmp_errno = SNMPERR_BAD_LOCPORT;
+       if (! snmp_close(session)){
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n", 
+                   api_errstring(snmp_errno));
+           exit(3);
+       }
+       return 0;
+    }
+
+    if( *cp == '/' ) {
+       session->authenticator = check_received_pkt;
+       sync_with_agent(session);
+       parse_app_community_string( session );
+       session->qoS |= USEC_QOS_GENREPORT;
+    }
+
+    /* replace comm pointer with pointer to new data: */
+    session->community = cp;   
+
+    return session;
+}
+
+void
+sync_with_agent( session )
+struct snmp_session *session;
+{
+    struct snmp_pdu *pdu, *response = 0;
+    int status;
+
+    session->qoS = USEC_QOS_GENREPORT;
+    session->userLen = 6;
+    session->version = SNMP_VERSION_2;
+    strcpy( session->userName, "public" );
+
+    snmp_synch_setup(session);
+    pdu = snmp_pdu_create(GET_REQ_MSG);
+    status = snmp_synch_response(session, pdu, &response);
+
+    if (status == STAT_SUCCESS){
+       memcpy( session->agentID, response->params.agentID, 12 );
+
+       /* save the clocks -- even though they are not authentic */
+       session->agentBoots = response->params.agentBoots;
+       session->agentTime = response->params.agentTime;
+       session->agentClock = response->params.agentTime - time(NULL);
+
+    } else {
+           if (status == STAT_TIMEOUT){
+               printf("No Response from %s\n", session->peername);
+           } else {    /* status == STAT_ERROR */
+               printf("An error occurred, Quitting\n");
+           }
+           exit( -1 );
+    }
+
+    /** freed to early: 
+      snmp_free_pdu(pdu);
+      if (response) snmp_free_pdu(response);
+     **/
+}
+#if 1 /***/
+/*
+ * Unlink one element from input request list,
+ * then free it and it's pdu.
+ */
+static void
+free_one_request(isp, orp)
+    struct snmp_internal_session *isp;
+    struct request_list *orp;
+{
+    struct request_list *rp;
+    if(! orp) return;
+    if(isp->requests == orp){ 
+      isp->requests = orp->next_request; /* unlink head */
+    }
+    else{
+      for(rp = isp->requests; rp; rp = rp->next_request){
+        if(rp->next_request == orp){ 
+         rp->next_request = orp->next_request; /* unlink element */
+         break;
+        }
+      }
+    }
+    if (orp->pdu != NULL){
+      snmp_free_pdu(orp->pdu);
+    }
+    free((char *)orp);
+}
+#endif /***/
+/*
+ * Free each element in the input request list.
+ */
+static void
+free_request_list(rp)
+    struct request_list *rp;
+{
+    struct request_list *orp;
+
+    while(rp){
+       orp = rp;
+       rp = rp->next_request;
+       if (orp->pdu != NULL)
+           snmp_free_pdu(orp->pdu);
+       free((char *)orp);
+    }
+}
+
+/*
+ * 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.
+ */
+int 
+snmp_close(session)
+    struct snmp_session *session;
+{
+    struct session_list *slp = NULL, *oslp = NULL;
+
+    if (Sessions->session == session){ /* If first entry */
+       slp = Sessions;
+       Sessions = slp->next;
+    } else {
+       for(slp = Sessions; slp; slp = slp->next){
+           if (slp->session == session){
+               if (oslp)   /* if we found entry that points here */
+                   oslp->next = slp->next;     /* link around this entry */
+               break;
+           }
+           oslp = slp;
+       }
+    }
+    /* If we found the session, free all data associated with it */
+    if (slp){
+       if (slp->session->community != NULL)
+           free((char *)slp->session->community);
+       if(slp->session->peername != NULL)
+           free((char *)slp->session->peername);
+       free((char *)slp->session);
+       if (slp->internal->sd != -1)
+           close(slp->internal->sd);
+       free_request_list(slp->internal->requests);
+       free((char *)slp->internal);
+       free((char *)slp);
+    } else {
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    return 1;
+}
+
+/*
+ * Takes a session and a pdu and serializes the ASN PDU into the area
+ * pointed to by packet.  out_length is the size of the data area available.
+ * Returns the length of the completed packet in out_length.  If any errors
+ * occur, -1 is returned.  If all goes well, 0 is returned.
+ */
+int
+snmp_build(session, pdu, packet, out_length, is_agent)
+    struct snmp_session        *session;
+    struct snmp_pdu    *pdu;
+    u_char     *packet;
+    int                        *out_length;
+    int                         is_agent;
+{
+    u_char  buf[PACKET_LENGTH];
+    u_char  *cp;
+    struct variable_list *vp;
+    int            length;
+    int            totallength;
+
+    length = *out_length;
+    cp = packet;
+    for(vp = pdu->variables; vp; vp = vp->next_variable){
+       cp = snmp_build_var_op(cp, vp->name, &vp->name_length, vp->type, vp->val_len, (u_char *)vp->val.string, &length);
+       if (cp == NULL)
+           return -1;
+    }
+    totallength = cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR), totallength);
+    if (cp == NULL)
+       return -1;
+    bcopy((char *)packet, (char *)cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+    if (pdu->command != TRP_REQ_MSG){
+       /* request id */
+       cp = asn_build_int(packet, &length,
+           (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+           (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (cp == NULL)
+           return -1;
+       /* error status */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (cp == NULL)
+           return -1;
+       /* error index */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (cp == NULL)
+           return -1;
+    } else {   /* this is a trap message */
+       /* enterprise */
+       cp = asn_build_objid(packet, &length,
+           (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID),
+           (oid *)pdu->enterprise, pdu->enterprise_length);
+       if (cp == NULL)
+           return -1;
+       /* agent-addr */
+       cp = asn_build_string(cp, &length, (u_char)IPADDRESS,
+               (u_char *)&pdu->agent_addr.sin_addr.s_addr, sizeof(pdu->agent_addr.sin_addr.s_addr));
+       if (cp == NULL)
+           return -1;
+       /* generic trap */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (cp == NULL)
+           return -1;
+       /* specific trap */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (cp == NULL)
+           return -1;
+       /* timestamp  */
+       cp = asn_build_int(cp, &length, (u_char)TIMETICKS,
+               (long *)&pdu->time, sizeof(pdu->time));
+       if (cp == NULL)
+           return -1;
+    }
+    if (length < totallength)
+       return -1;
+    bcopy((char *)buf, (char *)cp, totallength);
+    totallength += cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char)pdu->command, totallength);
+    if (cp == NULL)
+       return -1;
+    if (length < totallength)
+       return -1;
+    bcopy((char *)packet, (char *)cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+
+    cp = snmp_auth_build( packet, &length, session, is_agent, totallength );
+    if (cp == NULL)
+       return -1;
+    if ((*out_length - (cp - packet)) < totallength)
+       return -1;
+    bcopy((char *)buf, (char *)cp, totallength);
+    totallength += cp - packet;
+    *out_length = totallength;
+
+    if( session->qoS & USEC_QOS_AUTH )
+           md5Digest( packet, totallength, cp - (session->contextLen + 16),
+               cp - (session->contextLen + 16) );
+
+    return 0;
+}
+
+/*
+ * Parses the packet received on the input session, and places the data into
+ * the input pdu.  length is the length of the input packet.  If any errors
+ * are encountered, -1 is returned.  Otherwise, a 0 is returned.
+ */
+static int
+snmp_parse(session, pdu, data, length)
+    struct snmp_session *session;
+    struct snmp_pdu *pdu;
+    u_char  *data;
+    int            length;
+{
+    u_char  msg_type;
+    u_char  type;
+    u_char  *var_val;
+    long    version;
+    int            len, four;
+    u_char community[256];
+    int community_length = 256;
+    struct variable_list *vp = 0;
+    oid            objid[MAX_NAME_LEN], *op;
+    u_char  *origdata = data;
+    int      origlength = length;
+    int      ret = 0;
+    u_char  *save_data;
+
+    /* authenticates message and returns length if valid */
+    data = snmp_auth_parse(data, &length, community, &community_length, &version);
+    if (data == NULL)
+       return -1;
+
+   if( version != SNMP_VERSION_1 && version != SNMP_VERSION_2C && version != SNMP_VERSION_2 ) {
+           fprintf(stderr, "Wrong version: %ld\n", version);
+           return -1;
+    }
+
+    save_data = data;
+
+    data = asn_parse_header(data, &length, &msg_type);
+    if (data == NULL)
+       return -1;
+    pdu->command = msg_type;
+
+    if( session->authenticator ) {
+       ret = session->authenticator( origdata, origlength, save_data - community_length, 
+               community_length, session, pdu );
+       if( ret < 0 ) return ret;
+    }
+
+    if (pdu->command != TRP_REQ_MSG){
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (data == NULL)
+           return -1;
+    } else {
+       pdu->enterprise_length = MAX_NAME_LEN;
+       data = asn_parse_objid(data, &length, &type, objid, &pdu->enterprise_length);
+       if (data == NULL)
+           return -1;
+       pdu->enterprise = (oid *)calloc(1, pdu->enterprise_length * sizeof(oid));
+       bcopy((char *)objid, (char *)pdu->enterprise, pdu->enterprise_length * sizeof(oid));
+
+       four = 4;
+       data = asn_parse_string(data, &length, &type, (u_char *)&pdu->agent_addr.sin_addr.s_addr, &four);
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->time, sizeof(pdu->time));
+       if (data == NULL)
+           return -1;
+    }
+    data = asn_parse_header(data, &length, &type);
+    if (data == NULL)
+       return -1;
+    if (type != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR))
+       return -1;
+    while((int)length > 0){
+       if (pdu->variables == NULL){
+           pdu->variables = vp = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+       } else {
+           vp->next_variable = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+           vp = vp->next_variable;
+       }
+       vp->next_variable = NULL;
+       vp->val.string = NULL;
+       vp->name = NULL;
+       vp->name_length = MAX_NAME_LEN;
+       data = snmp_parse_var_op(data, objid, &vp->name_length, &vp->type, &vp->val_len, &var_val, (int *)&length);
+       if (data == NULL)
+           return -1;
+       op = (oid *)calloc(1, (unsigned)vp->name_length * sizeof(oid));
+       bcopy((char *)objid, (char *)op, vp->name_length * sizeof(oid));
+       vp->name = op;
+
+       len = PACKET_LENGTH;
+       switch((short)vp->type){
+           case ASN_INTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(long));
+               vp->val_len = sizeof(long);
+               asn_parse_int(var_val, &len, &vp->type, (long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER:
+           case GAUGE:
+           case TIMETICKS:
+           case UINTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(unsigned long));
+               vp->val_len = sizeof(unsigned long);
+               asn_parse_unsigned_int(var_val, &len, &vp->type, (unsigned long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER64:
+               vp->val.counter64 = (struct counter64 *)calloc(1,  sizeof(struct counter64) );
+               vp->val_len = sizeof(struct counter64);
+               asn_parse_unsigned_int64(var_val, &len, &vp->type,
+                                        (struct counter64 *)vp->val.counter64,
+                                        sizeof(*vp->val.counter64));
+               break;
+           case ASN_OCTET_STR:
+           case IPADDRESS:
+           case OPAQUE:
+           case NSAP:
+               vp->val.string = (u_char *)calloc(1, (unsigned)vp->val_len);
+               asn_parse_string(var_val, &len, &vp->type, vp->val.string, &vp->val_len);
+               break;
+           case ASN_OBJECT_ID:
+               vp->val_len = MAX_NAME_LEN;
+               asn_parse_objid(var_val, &len, &vp->type, objid, &vp->val_len);
+               vp->val_len *= sizeof(oid);
+               vp->val.objid = (oid *)calloc(1, (unsigned)vp->val_len);
+               bcopy((char *)objid, (char *)vp->val.objid, vp->val_len);
+               break;
+            case SNMP_NOSUCHOBJECT:
+            case SNMP_NOSUCHINSTANCE:
+            case SNMP_ENDOFMIBVIEW:
+           case ASN_NULL:
+               break;
+           default:
+               fprintf(stderr, "bad type returned (%x)\n", vp->type);
+               break;
+       }
+    }
+    return ret;
+}
+
+/*
+ * 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(session, pdu)
+    struct snmp_session *session;
+    struct snmp_pdu    *pdu;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp = NULL;
+    u_char  packet[PACKET_LENGTH];
+    int length = PACKET_LENGTH;
+    struct request_list *rp;
+    struct timeval tv;
+
+    for(slp = Sessions; slp; slp = slp->next){
+       if (slp->session == session){
+           isp = slp->internal;
+           break;
+       }
+    }
+
+    if (! pdu) {
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+
+    if (isp == NULL){
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG
+       || pdu->command == GET_RSP_MSG || pdu->command == SET_REQ_MSG 
+       || pdu->command == GETBULK_REQ_MSG ){
+       if (pdu->reqid == SNMP_DEFAULT_REQID)
+           pdu->reqid = ++Reqid;
+       if (pdu->errstat == SNMP_DEFAULT_ERRSTAT)
+           pdu->errstat = 0;
+       if (pdu->errindex == SNMP_DEFAULT_ERRINDEX)
+           pdu->errindex = 0;
+    } else {
+       /* fill in trap defaults */
+       pdu->reqid = 1; /* give a bogus non-error reqid for traps */
+       if (pdu->enterprise_length == SNMP_DEFAULT_ENTERPRISE_LENGTH){
+           pdu->enterprise = (oid *)calloc(1, sizeof(DEFAULT_ENTERPRISE));
+           bcopy((char *)DEFAULT_ENTERPRISE, (char *)pdu->enterprise, sizeof(DEFAULT_ENTERPRISE));
+           pdu->enterprise_length = sizeof(DEFAULT_ENTERPRISE)/sizeof(oid);
+       }
+       if (pdu->time == SNMP_DEFAULT_TIME)
+           pdu->time = DEFAULT_TIME;
+    }
+    if (pdu->address.sin_addr.s_addr == SNMP_DEFAULT_ADDRESS){
+       if (isp->addr.sin_addr.s_addr != SNMP_DEFAULT_ADDRESS){
+           bcopy((char *)&isp->addr, (char *)&pdu->address, sizeof(pdu->address));
+       } else {
+           fprintf(stderr, "No remote IP address specified\n");
+           snmp_errno = SNMPERR_BAD_ADDRESS;
+           return 0;
+       }
+    }
+       
+
+    if (snmp_build(session, pdu, packet, &length, 0) < 0){
+       fprintf(stderr, "Error building packet\n");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+#if 1 /***/
+       if (snmp_dump_packet) {
+       snmp_print_packet(packet, length, pdu->address, 1);
+    }
+#endif/***/ if we found entry that points here */
+ oslp e key!  replace...
+     */
+ * \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 1\ 1\0\0\0\0\0\0\0\19\7fÿ¯ùsnmplib/snmp_api.c\0c\0\0.h\0\0\0\18\7fÿ°\85\10\0<Ðlib/snmp_api.c~\0~\0\0ñ\0\0\0\18\7fÿ±\1e\10\0\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\0\0\0\18\7fÿ±«\10\0=\10\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\0\0\0\18\7fÿ²\1d\10\0=0\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\0\0\0\18\7fÿ²\8a\10\0=P\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\0\0\0\18\7fÿ³
+\10\0=p\7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\0\0\0\18\7fÿ³\82\0\0\0\ 1\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\0\0\0Á\7fÿ³ù\0\0\0\10\7fÿ´\10\10\0\0%\0\19\0\15\0\0\10\0D(\0\0\0\10\7fÿ´_\10\0\0\0\ 2\\0\0\0\0\10\0\0\0\0\10\7fÿ´©\10\0=\98\0\0\ 24\0\0\0\0\10\0\0\0\0\10\7fÿ´ø\10\0\0\0\ 2H\0\0\0\0\10\0\0\0\0\10\7fÿµB\10\0>\10\7fÿµ]\7fÿµm\7fÿµz\0\0\0\10\7fÿµ \10\0>(\7fÿµ·\7fÿµÉ\7fÿµÖ\0\0\0\10\7fÿµï\10\0>@\7fÿ¶\12\7fÿ¶ \7fÿ¶4\0\0\0\10\7fÿ¶P\0\0\0\ 1\7fÿ¶r\7fÿ¶~\7fÿ¶\88\0\0\00\7fÿ¶\9f\10\0\82à\7fÿ¶·\0\0\0\0\7fÿ¶Ù\10\0\7fÿ·\ 1\0\0\0\0\7fÿ·#\7fÿ·/\7fÿ·>\10\0>X\7fÿ·V\0\0\03\0\0\0\0/usr/people/wessels/.indent.pro\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\ 1\0\0\0\0\7fÿ¯è\7fÿ¯ù\7fÿ°\f\7fÿ°\e\7fÿ°.\7fÿ°?\7fÿ°M\7fÿ°[\7fÿ°p\7fÿ°\85\7fÿ°\95\7fÿ°£\7fÿ°²\7fÿ°Å\7fÿ°Û\7fÿ°ñ\7fÿ±
+\7fÿ±\1e\7fÿ±2\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\7fÿ±\99\7fÿ±«\7fÿ±º\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\7fÿ²\ f\7fÿ²\1d\7fÿ²2\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\7fÿ²\7f\7fÿ²\8a\7fÿ²\99\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\7fÿ²ö\7fÿ³
+\7fÿ³ \7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\7fÿ³s\7fÿ³\82\7fÿ³\91\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\7fÿ³ç\7fÿ³ù\7fÿ´\ 4\7fÿ´\10\7fÿ´\1e\7fÿ´)\7fÿ´3\7fÿ´C\7fÿ´O\7fÿ´_\7fÿ´k\7fÿ´t\7fÿ´\81\7fÿ´\8f\7fÿ´\9f\7fÿ´©\7fÿ´·\7fÿ´Å\7fÿ´Ò\7fÿ´Ý\7fÿ´í\7fÿ´ø\7fÿµ\ 3\7fÿµ\10\7fÿµ\1d\7fÿµ)\7fÿµ7\7fÿµB\7fÿµM\7fÿµ]\7fÿµm\7fÿµz\7fÿµ\89\7fÿµ \7fÿµ«\7fÿµ·\7fÿµÉ\7fÿµÖ\7fÿµâ\7fÿµï\7fÿ¶\ 3\7fÿ¶\12\7fÿ¶ \7fÿ¶4\7fÿ¶?\7fÿ¶P\7fÿ¶b\7fÿ¶r\7fÿ¶~\7fÿ¶\88\7fÿ¶\94\7fÿ¶\9f\7fÿ¶«\7fÿ¶·\7fÿ¶É\7fÿ¶Ù\7fÿ¶í\7fÿ·\ 1\7fÿ·\15\7fÿ·#\7fÿ·/\7fÿ·>\7fÿ·L\7fÿ·V\7fÿ·f\7fÿ·q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0@    \0\0\0\0 snmp_pdu *pdu;
+    u_char  *data;
+    int            length;
+{
+    u_char  msg_type;
+    u_char  type;
+    u_char  *var_val;
+    long    version;
+    int            len, four;
+    u_char community[256];
+    int community_length = 256;
+    struct variable_list *vp = 0;
+    oid            objid[MAX_NAME_LEN], *op;
+    u_char  *origdata = data;
+    int      origlength = length;
+    int      ret = 0;
+    u_char  *save_data;
+
+    /* authenticates message and returns length if valid */
+    data = snmp_auth_parse(data, &length, community, &community_length, &version);
+    if (data == NULL)
+       return -1;
+
+   if( version != SNMP_VERSION_1 && version != SNMP_VERSION_2C && version != SNMP_VERSION_2 ) {
+           fprintf(stderr, "Wrong version: %ld\n", version);
+           return -1;
+    }
+
+    save_data = data;
+
+    data = asn_parse_header(data, &length, &msg_type);
+    if (data == NULL)
+       return -1;
+    pdu->command = msg_type;
+
+    if( session->authenticator ) {
+       ret = session->authenticator( origdata, origlength, save_data - community_length, 
+               community_length, session, pdu );
+       if( ret < 0 ) return ret;
+    }
+
+    if (pdu->command != TRP_REQ_MSG){
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (data == NULL)
+           return -1;
+    } else {
+       pdu->enterprise_length = MAX_NAME_LEN;
+       data = asn_parse_objid(data, &length, &type, objid, &pdu->enterprise_length);
+       if (data == NULL)
+           return -1;
+       pdu->enterprise = (oid *)calloc(1, pdu->enterprise_length * sizeof(oid));
+       bcopy((char *)objid, (char *)pdu->enterprise, pdu->enterprise_length * sizeof(oid));
+
+       four = 4;
+       data = asn_parse_string(data, &length, &type, (u_char *)&pdu->agent_addr.sin_addr.s_addr, &four);
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->time, sizeof(pdu->time));
+       if (data == NULL)
+           return -1;
+    }
+    data = asn_parse_header(data, &length, &type);
+    if (data == NULL)
+       return -1;
+    if (type != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR))
+       return -1;
+    while((int)length > 0){
+       if (pdu->variables == NULL){
+           pdu->variables = vp = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+       } else {
+           vp->next_variable = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+           vp = vp->next_variable;
+       }
+       vp->next_variable = NULL;
+       vp->val.string = NULL;
+       vp->name = NULL;
+       vp->name_length = MAX_NAME_LEN;
+       data = snmp_parse_var_op(data, objid, &vp->name_length, &vp->type, &vp->val_len, &var_val, (int *)&length);
+       if (data == NULL)
+           return -1;
+       op = (oid *)calloc(1, (unsigned)vp->name_length * sizeof(oid));
+       bcopy((char *)objid, (char *)op, vp->name_length * sizeof(oid));
+       vp->name = op;
+
+       len = PACKET_LENGTH;
+       switch((short)vp->type){
+           case ASN_INTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(long));
+               vp->val_len = sizeof(long);
+               asn_parse_int(var_val, &len, &vp->type, (long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER:
+           case GAUGE:
+           case TIMETICKS:
+           case UINTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(unsigned long));
+               vp->val_len = sizeof(unsigned long);
+               asn_parse_unsigned_int(var_val, &len, &vp->type, (unsigned long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER64:
+               vp->val.counter64 = (struct counter64 *)calloc(1,  sizeof(struct counter64) );
+               vp->val_len = sizeof(struct counter64);
+               asn_parse_unsigned_int64(var_val, &len, &vp->type,
+                                        (struct counter64 *)vp->val.counter64,
+                                        sizeof(*vp->val.counter64));
+               break;
+           case ASN_OCTET_STR:
+           case IPADDRESS:
+           case OPAQUE:
+           case NSAP:
+               vp->val.string = (u_char *)calloc(1, (unsigned)vp->val_len);
+               asn_parse_string(var_val, &len, &vp->type, vp->val.string, &vp->val_len);
+               break;
+           case ASN_OBJECT_ID:
+               vp->val_len = MAX_NAME_LEN;
+               asn_parse_objid(var_val, &len, &vp->type, objid, &vp->val_len);
+               vp->val_len *= sizeof(oid);
+               vp->val.objid = (oid *)calloc(1, (unsigned)vp->val_len);
+               bcopy((char *)objid, (char *)vp->val.objid, vp->val_len);
+               break;
+            case SNMP_NOSUCHOBJECT:
+            case SNMP_NOSUCHINSTANCE:
+            case SNMP_ENDOFMIBVIEW:
+           case ASN_NULL:
+               break;
+           default:
+               fprintf(stderr, "bad type returned (%x)\n", vp->type);
+               break;
+       }
+    }
+    return ret;
+}
+
+/*
+ * 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(session, pdu)
+    struct snmp_session *session;
+    struct snmp_pdu    *pdu;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp = NULL;
+    u_char  packet[PACKET_LENGTH];
+    int length = PACKET_LENGTH;
+    struct request_list *rp;
+    struct timeval tv;
+
+    for(slp = Sessions; slp; slp = slp->next){
+       if (slp->session == session){
+           isp = slp->internal;
+           break;
+       }
+    }
+
+    if (! pdu) {
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+
+    if (isp == NULL){
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG
+       || pdu->command == GET_RSP_MSG || pdu->command == SET_REQ_MSG 
+       || pdu->command == GETBULK_REQ_MSG ){
+       if (pdu->reqid == SNMP_DEFAULT_REQID)
+           pdu->reqid = ++Reqid;
+       if (pdu->errstat == SNMP_DEFAULT_ERRSTAT)
+           pdu->errstat = 0;
+       if (pdu->errindex == SNMP_DEFAULT_ERRINDEX)
+           pdu->errindex = 0;
+    } else {
+       /* fill in trap defaults */
+       pdu->reqid = 1; /* give a bogus non-error reqid for traps */
+       if (pdu->enterprise_length == SNMP_DEFAULT_ENTERPRISE_LENGTH){
+           pdu->enterprise = (oid *)calloc(1, sizeof(DEFAULT_ENTERPRISE));
+           bcopy((char *)DEFAULT_ENTERPRISE, (char *)pdu->enterprise, sizeof(DEFAULT_ENTERPRISE));
+           pdu->enterprise_length = sizeof(DEFAULT_ENTERPRISE)/sizeof(oid);
+       }
+       if (pdu->time == SNMP_DEFAULT_TIME)
+           pdu->time = DEFAULT_TIME;
+    }
+    if (pdu->address.sin_addr.s_addr == SNMP_DEFAULT_ADDRESS){
+       if (isp->addr.sin_addr.s_addr != SNMP_DEFAULT_ADDRESS){
+           bcopy((char *)&isp->addr, (char *)&pdu->address, sizeof(pdu->address));
+       } else {
+           fprintf(stderr, "No remote IP address specified\n");
+           snmp_errno = SNMPERR_BAD_ADDRESS;
+           return 0;
+       }
+    }
+       
+
+    if (snmp_build(session, pdu, packet, &length, 0) < 0){
+       fprintf(stderr, "Error building packet\n");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+#if 1 /***/
+       if (snmp_dump_packet) {
+       snmp_print_packet(packet, length, pdu->address, 1);
+    }
+MUNITY, (char *)cp, session->community_len);
+    }
+
+    /* Set up connections */
+    sd = socket(AF_INET, SOCK_DGRAM, 0);
+    if (sd < 0){
+       perror("socket");
+       snmp_errno = SNMPERR_GENERR;
+       if (!snmp_close(session)){
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+           exit(1);
+       }
+       return 0;
+    }
+    isp->sd = sd;
+
+    if (session->peername != SNMP_DEFAULT_PEERNAME){
+       if ((addr = inet_addr(session->peername)) != -1){
+           bcopy((char *)&addr, (char *)&isp->addr.sin_addr, sizeof(isp->addr.sin_addr));
+       } else {
+           hp = gethostbyname(session->peername);
+           if (hp == NULL){
+               fprintf(stderr, "unknown host: %s\n", session->peername);
+               snmp_errno = SNMPERR_BAD_ADDRESS;
+               if (!snmp_close(session)){
+                   fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+                   exit(2);
+               }
+               return 0;
+           } else {
+               bcopy((char *)hp->h_addr, (char *)&isp->addr.sin_addr, hp->h_length);
+           }
+       }
+       isp->addr.sin_family = AF_INET;
+       if (session->remote_port == SNMP_DEFAULT_REMPORT){
+           /*servp = getservbyname("snmp", "udp");*/
+           servp=NULL;
+           if (servp != NULL){
+               isp->addr.sin_port = servp->s_port;
+           } else {
+               isp->addr.sin_port = htons(SNMP_PORT);
+           }
+       } else {
+           isp->addr.sin_port = htons(session->remote_port);
+       }
+    } else {
+       isp->addr.sin_addr.s_addr = SNMP_DEFAULT_ADDRESS;
+    }
+
+    me.sin_family = AF_INET;
+    me.sin_addr.s_addr = INADDR_ANY;
+    me.sin_port = htons(session->local_port);
+    if (bind(sd, (struct sockaddr *)&me, sizeof(me)) != 0){
+       perror("bind");
+       snmp_errno = SNMPERR_BAD_LOCPORT;
+       if (! snmp_close(session)){
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n", 
+                   api_errstring(snmp_errno));
+           exit(3);
+       }
+       return 0;
+    }
+
+    if( *cp == '/' ) {
+       session->authenticator = check_received_pkt;
+       sync_with_agent(session);
+       parse_app_community_string( session );
+       session->qoS |= USEC_QOS_GENREPORT;
+    }
+
+    /* replace comm pointer with pointer to new data: */
+    session->community = cp;   
+
+    return session;
+}
+
+void
+sync_with_agent( session )
+struct snmp_session *session;
+{
+    struct snmp_pdu *pdu, *response = 0;
+    int status;
+
+    session->qoS = USEC_QOS_GENREPORT;
+    session->userLen = 6;
+    session->version = SNMP_VERSION_2;
+    strcpy( session->userName, "public" );
+
+    snmp_synch_setup(session);
+    pdu = snmp_pdu_create(GET_REQ_MSG);
+    status = snmp_synch_response(session, pdu, &response);
+
+    if (status == STAT_SUCCESS){
+       memcpy( session->agentID, response->params.agentID, 12 );
+
+       /* save the clocks -- even though they are not authentic */
+       session->agentBoots = response->params.agentBoots;
+       session->agentTime = response->params.agentTime;
+       session->agentClock = response->params.agentTime - time(NULL);
+
+    } else {
+           if (status == STAT_TIMEOUT){
+               printf("No Response from %s\n", session->peername);
+           } else {    /* status == STAT_ERROR */
+               printf("An error occurred, Quitting\n");
+           }
+           exit( -1 );
+    }
+
+    /** freed to early: 
+      snmp_free_pdu(pdu);
+      if (response) snmp_free_pdu(response);
+     **/
+}
+#if 1 /***/
+/*
+ * Unlink one element from input request list,
+ * then free it and it's pdu.
+ */
+static void
+free_one_request(isp, orp)
+    struct snmp_internal_session *isp;
+    struct request_list *orp;
+{
+    struct request_list *rp;
+    if(! orp) return;
+    if(isp->requests == orp){ 
+      isp->requests = orp->next_request; /* unlink head */
+    }
+    else{
+      for(rp = isp->requests; rp; rp = rp->next_request){
+        if(rp->next_request == orp){ 
+         rp->next_request = orp->next_request; /* unlink element */
+         break;
+        }
+      }
+    }
+    if (orp->pdu != NULL){
+      snmp_free_pdu(orp->pdu);
+    }
+    free((char *)orp);
+}
+#endif /***/
+/*
+ * Free each element in the input request list.
+ */
+static void
+free_request_list(rp)
+    struct request_list *rp;
+{
+    struct request_list *orp;
+
+    while(rp){
+       orp = rp;
+       rp = rp->next_request;
+       if (orp->pdu != NULL)
+           snmp_free_pdu(orp->pdu);
+       free((char *)orp);
+    }
+}
+
+/*
+ * 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.
+ */
+int 
+snmp_close(session)
+    struct snmp_session *session;
+{
+    struct session_list *slp = NULL, *oslp = NULL;
+
+    if (Sessions->session == session){ /* If first entry */
+       slp = Sessions;
+       Sessions = slp->next;
+    } else {
+       for(slp = Sessions; slp; slp = slp->next){
+           if (slp->session == session){
+               if (oslp)   /* if we found entry that points here */
+                   oslp->next = slp->next;     /* link around this entry */
+               break;
+           }
+           oslp = slp;
+       }
+    }
+    /* If we found the session, free all data associated with it */
+    if (slp){
+       if (slp->session->community != NULL)
+           free((char *)slp->session->community);
+       if(slp->session->peername != NULL)
+           free((char *)slp->session->peername);
+       free((char *)slp->session);
+       if (slp->internal->sd != -1)
+           close(slp->internal->sd);
+       free_request_list(slp->internal->requests);
+       free((char *)slp->internal);
+       free((char *)slp);
+    } else {
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    return 1;
+}
+
+/*
+ * Takes a session and a pdu and serializes the ASN PDU into the area
+ * pointed to by packet.  out_length is the size of the data area available.
+ * Returns the length of the completed packet in out_length.  If any errors
+ * occur, -1 is returned.  If all goes well, 0 is returned.
+ */
+int
+snmp_build(session, pdu, packet, out_length, is_agent)
+    struct snmp_session        *session;
+    struct snmp_pdu    *pdu;
+    u_char     *packet;
+    int                        *out_length;
+    int                         is_agent;
+{
+    u_char  buf[PACKET_LENGTH];
+    u_char  *cp;
+    struct variable_list *vp;
+    int            length;
+    int            totallength;
+
+    length = *out_length;
+    cp = packet;
+    for(vp = pdu->variables; vp; vp = vp->next_variable){
+       cp = snmp_build_var_op(cp, vp->name, &vp->name_length, vp->type, vp->val_len, (u_char *)vp->val.string, &length);
+       if (cp == NULL)
+           return -1;
+    }
+    totallength = cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR), totallength);
+    if (cp == NULL)
+       return -1;
+    bcopy((char *)packet, (char *)cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+    if (pdu->command != TRP_REQ_MSG){
+       /* request id */
+       cp = asn_build_int(packet, &length,
+           (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+           (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (cp == NULL)
+           return -1;
+       /* error status */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (cp == NULL)
+           return -1;
+       /* error index */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (cp == NULL)
+           return -1;
+    } else {   /* this is a trap message */
+       /* enterprise */
+       cp = asn_build_objid(packet, &length,
+           (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID),
+           (oid *)pdu->enterprise, pdu->enterprise_length);
+       if (cp == NULL)
+           return -1;
+       /* agent-addr */
+       cp = asn_build_string(cp, &length, (u_char)IPADDRESS,
+               (u_char *)&pdu->agent_addr.sin_addr.s_addr, sizeof(pdu->agent_addr.sin_addr.s_addr));
+       if (cp == NULL)
+           return -1;
+       /* generic trap */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (cp == NULL)
+           return -1;
+       /* specific trap */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (cp == NULL)
+           return -1;
+       /* timestamp  */
+       cp = asn_build_int(cp, &length, (u_char)TIMETICKS,
+               (long *)&pdu->time, sizeof(pdu->time));
+       if (cp == NULL)
+           return -1;
+    }
+    if (length < totallength)
+       return -1;
+    bcopy((char *)buf, (char *)cp, totallength);
+    totallength += cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char)pdu->command, totallength);
+    if (cp == NULL)
+       return -1;
+    if (length < totallength)
+       return -1;
+    bcopy((char *)packet, (char *)cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+
+    cp = snmp_auth_build( packet, &length, session, is_agent, totallength );
+    if (cp == NULL)
+       return -1;
+    if ((*out_length - (cp - packet)) < totallength)
+       return -1;
+    bcopy((char *)buf, (char *)cp, totallength);
+    totallength += cp - packet;
+    *out_length = totallength;
+
+    if( session->qoS & USEC_QOS_AUTH )
+           md5Digest( packet, totallength, cp - (session->contextLen + 16),
+               cp - (session->contextLen + 16) );
+
+    return 0;
+}
+
+/*
+ * Parses the packet received on the input session, and places the data into
+ * the input pdu.  length is the length of the input packet.  If any errors
+ * are encountered, -1 is returned.  Otherwise, a 0 is returned.
+ */
+static int
+snmp_parse(session, pdu, data, length)
+    struct snmp_session *session;
+    struct\10\0BÐ+= m\0\0
+È      /* \0\0\0\0*/ B\10\0>XNMPT\10\ 1Ê  */c\0\0\0\0for testing purposes */e key!  replace...
+     */
+ * \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 1\ 1\0\0\0\0\0\0\0\19\7fÿ¯ùsnmplib/snmp_api.c\0c\0\0.h\0\0\0\18\7fÿ°\85\10\0<Ðlib/snmp_api.c~\0~\0\0ñ\0\0\0\18\7fÿ±\1e\10\0\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\0\0\0\18\7fÿ±«\10\0=\10\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\0\0\0\18\7fÿ²\1d\10\0=0\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\0\0\0\18\7fÿ²\8a\10\0=P\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\0\0\0\18\7fÿ³
+\10\0=p\7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\0\0\0\18\7fÿ³\82\0\0\0\ 1\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\0\0\0Á\7fÿ³ù\0\0\0\10\7fÿ´\10\10\0\0%\0\19\0\15\0\0\10\0D(\0\0\0\10\7fÿ´_\10\0\0\0\ 2\\0\0\0\0\10\0\0\0\0\10\7fÿ´©\10\0=\98\0\0\ 24\0\0\0\0\10\0\0\0\0\10\7fÿ´ø\10\0\0\0\ 2H\0\0\0\0\10\0\0\0\0\10\7fÿµB\10\0>\10\7fÿµ]\7fÿµm\7fÿµz\0\0\0\10\7fÿµ \10\0>(\7fÿµ·\7fÿµÉ\7fÿµÖ\0\0\0\10\7fÿµï\10\0>@\7fÿ¶\12\7fÿ¶ \7fÿ¶4\0\0\0\10\7fÿ¶P\0\0\0\ 1\7fÿ¶r\7fÿ¶~\7fÿ¶\88\0\0\00\7fÿ¶\9f\10\0\7fÿ¶·\0\0\0\0\7fÿ¶Ù\10\0\89è\7fÿ·\ 1\0\0\0\0\7fÿ·#\7fÿ·/\7fÿ·>\10\0>X\7fÿ·V\0\0\03\0\0\0\0/usr/people/wessels/.indent.pro\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\ 1\0\0\0\0\7fÿ¯è\7fÿ¯ù\7fÿ°\f\7fÿ°\e\7fÿ°.\7fÿ°?\7fÿ°M\7fÿ°[\7fÿ°p\7fÿ°\85\7fÿ°\95\7fÿ°£\7fÿ°²\7fÿ°Å\7fÿ°Û\7fÿ°ñ\7fÿ±
+\7fÿ±\1e\7fÿ±2\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\7fÿ±\99\7fÿ±«\7fÿ±º\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\7fÿ²\ f\7fÿ²\1d\7fÿ²2\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\7fÿ²\7f\7fÿ²\8a\7fÿ²\99\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\7fÿ²ö\7fÿ³
+\7fÿ³ \7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\7fÿ³s\7fÿ³\82\7fÿ³\91\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\7fÿ³ç\7fÿ³ù\7fÿ´\ 4\7fÿ´\10\7fÿ´\1e\7fÿ´)\7fÿ´3\7fÿ´C\7fÿ´O\7fÿ´_\7fÿ´k\7fÿ´t\7fÿ´\81\7fÿ´\8f\7fÿ´\9f\7fÿ´©\7fÿ´·\7fÿ´Å\7fÿ´Ò\7fÿ´Ý\7fÿ´í\7fÿ´ø\7fÿµ\ 3\7fÿµ\10\7fÿµ\1d\7fÿµ)\7fÿµ7\7fÿµB\7fÿµM\7fÿµ]\7fÿµm\7fÿµz\7fÿµ\89\7fÿµ \7fÿµ«\7fÿµ·\7fÿµÉ\7fÿµÖ\7fÿµâ\7fÿµï\7fÿ¶\ 3\7fÿ¶\12\7fÿ¶ \7fÿ¶4\7fÿ¶?\7fÿ¶P\7fÿ¶b\7fÿ¶r\7fÿ¶~\7fÿ¶\88\7fÿ¶\94\7fÿ¶\9f\7fÿ¶«\7fÿ¶·\7fÿ¶É\7fÿ¶Ù\7fÿ¶í\7fÿ·\ 1\7fÿ·\15\7fÿ·#\7fÿ·/\7fÿ·>\7fÿ·L\7fÿ·V\7fÿ·f\7fÿ·q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\0\0\0°\0\0\0\ 4\0\0\0\0\0\0\0\b\10\0>X\0\0\0\f\10\0\0\0\0\10\0\0\0\0\0\0\0\14\0\0\0\14\0\0\0\14\0\0\0\18\0\0\0\18\0\0\0\18\0\0\0\1c\0\0\0\1c\0\0\0\1c\0\0\0\1c\0\0\0 \0\0\0 \0\0\0 \0\0\0$\0\0\0\v\0\0\0\e\0\0\0\19\0\0\0\v\0\0\0\e\0\0\0@\0\0\0\0\0\0\0\0\0\0\0\0\10\0,\b\0\0\0\1a\10\02\88\0\0\0\1a\0\0\0\0\0\0\0\1a\10\0\85\b\0\0\0\0\10\0>X\0\0\0\0\0\0\0\0\0\0\0\0\10\0\82à\0\0\0\0\0\0\ 1C\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e0\0\0\0\v\0\0\0\e\0\0\0\18\0\0\0\v\0\0\0\1a\0\0\0\17\0\0\0\v\0\0\0 \0\0\0\0\10\0\8d¸ude/snmp_groupvars.h~\0\0\b\0\0\0\b\0\0\0 \0\0\0\0\10\0\8dàude/snmp_groupvars.h\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8eX\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e\80\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e¨\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8eÐ\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\0\0\0\ 1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\84©\0\0\0\0/***********************************************************
+       Copyright 1989 by Carnegie Mellon University
+
+                      All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the name of CMU not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+******************************************************************/
+/*
+ * snmp_api.c - API for access to snmp.
+ */
+#define DEBUG_SNMPTRACE                0 /* set to 1 to print all SNMP actions */
+#define DEBUG_SNMPFULLDUMP     0 /* set to 1 to dump all SNMP packets */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#ifdef linux
+#include <arpa/inet.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#endif
+
+
+#include "asn1.h"
+#include "snmp.h"
+#include "snmp_impl.h"
+#include "snmp_api.h"
+#include "snmp_client.h"
+
+#define PACKET_LENGTH  4500
+
+#ifndef BSD4_3
+#define BSD4_2
+#endif
+
+#if !defined(BSD4_3) && !defined(linux) && !defined(sun)
+
+typedef long   fd_mask;
+#define NFDBITS        (sizeof(fd_mask) * NBBY)        /* bits per mask */
+
+#define        FD_SET(n, p)    ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+#define        FD_CLR(n, p)    ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+#define        FD_ISSET(n, p)  ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+#define FD_ZERO(p)     bzero((char *)(p), sizeof(*(p)))
+#endif
+
+oid default_enterprise[] = {1, 3, 6, 1, 4, 1, 3, 1, 1}; /* enterprises.cmu.systems.cmuSNMP */
+
+#define DEFAULT_COMMUNITY   "public"
+#define DEFAULT_REMPORT            SNMP_PORT
+#define DEFAULT_ENTERPRISE  default_enterprise
+#define DEFAULT_TIME       0
+#define DEFAULT_MMS        1389 /* large, randomly picked for testing purposes */
+
+/*
+ * Internal information about the state of the snmp session.
+ */
+struct snmp_internal_session {
+    int            sd;         /* socket descriptor for this connection */
+    ipaddr  addr;      /* address of connected peer */
+    struct request_list *requests;/* Info about outstanding requests */
+};
+
+/*
+ * A list of all the outstanding requests for a particular session.
+ */
+struct request_list {
+    struct request_list *next_request;
+    u_long  request_id;        /* request id */
+    int            retries;    /* Number of retries */
+    u_long timeout;    /* length to wait for timeout */
+    struct timeval time; /* Time this request was made */
+    struct timeval expire;  /* time this request is due to expire */
+    struct snmp_pdu *pdu;   /* The pdu for this request (saved so it can be retransmitted */
+};
+
+/*
+ * The list of active/open sessions.
+ */
+struct session_list {
+    struct session_list *next;
+    struct snmp_session *session;
+    struct snmp_internal_session *internal;
+};
+
+struct session_list *Sessions = NULL;
+
+u_long Reqid = 0;
+int snmp_errno = 0;
+
+char *api_errors[4] = {
+    "Unknown session",
+    "Unknown host",
+    "Invalid local port",
+    "Unknown Error"
+};
+
+
+void sync_with_agent();
+int parse_app_community_string();
+void snmp_synch_setup();
+int snmp_synch_response();
+void md5Digest();
+
+
+static char *
+api_errstring(snmp_errnumber)
+    int        snmp_errnumber;
+{
+    if (snmp_errnumber <= SNMPERR_BAD_SESSION && snmp_errnumber >= SNMPERR_GENERR){
+       return api_errors[snmp_errnumber + 4];
+    } else {
+       return "Unknown Error";
+    }
+}
+
+#if 0
+/*
+ * Gets initial request ID for all transactions.
+ */
+static void
+init_snmp(){
+    struct timeval tv;
+
+    gettimeofday(&tv, (struct timezone *)0);
+    srandom(tv.tv_sec ^ tv.tv_usec);
+    Reqid = random();
+}
+#endif
+
+
+/*
+ * Dump snmp packet to stdout:
+ */
+static void
+snmp_print_packet(packet, length, addr, code)
+  char *packet; 
+  int length; 
+  ipaddr addr; 
+  int code;
+{
+  if(length < 0) {
+    return;
+  }
+  if (code <= 0) { /* received */
+    printf("\nReceived %4d bytes from ", length);
+  }
+  else { /* sending */
+    printf("\nSending  %4d bytes to   ", length);
+  }
+  printf("%s:", inet_ntoa(addr.sin_addr));
+#if DEBUG_SNMPFULLDUMP
+  for (count = 0; count < length; count++) {
+    if ((count & 15) == 0) {
+      printf("\n  ");
+    }
+    printf("%02X ", (int)(packet[count]&255));
+  }
+#endif
+  fflush(stdout);
+}
+
+#if DEBUG_SNMPTRACE
+/*
+ * Print request
+ */
+#define TRACE_SEND   (0)
+#define TRACE_RECV   (1)
+#define TRACE_TIMEOUT (2)
+static void
+snmp_print_trace(slp, rp, code)
+  struct session_list *slp;
+  struct request_list *rp;
+  int code;
+{
+  int reqid=0, retries=1;
+  if( rp ){
+    reqid = rp->request_id;
+    retries = rp->retries;
+  }  
+  printf("\n Session %2d  ReqId %4d  ", slp->internal->sd, reqid);
+  switch(code)
+    { 
+    case TRACE_SEND:    printf("send pdu (%d)", retries);break; 
+    case TRACE_RECV:    printf("recv pdu");break; 
+    case TRACE_TIMEOUT: printf("time out");break; 
+    }
+  fflush(stdout);
+}
+#endif /* DEBUG_SNMPTRACE */
+
+
+
+
+/*
+ * 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.
+ */
+struct snmp_session *
+snmp_open(session)
+    struct snmp_session *session;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp;
+    u_char *cp;
+    int sd;
+    u_long addr;
+    struct sockaddr_in me;
+    struct hostent *hp;
+    struct servent *servp;
+    extern int check_received_pkt();
+
+    /* Copy session structure and link into list */
+    slp = (struct session_list *)calloc(1, sizeof(struct session_list));
+    slp->internal = isp = (struct snmp_internal_session *)calloc(1, sizeof(struct snmp_internal_session));
+    bzero((char *)isp, sizeof(struct snmp_internal_session));
+    slp->internal->sd = -1; /* mark it not set */
+    slp->session = (struct snmp_session *)calloc(1, sizeof(struct snmp_session));
+    bcopy((char *)session, (char *)slp->session, sizeof(struct snmp_session));
+    session = slp->session;
+    /* now link it in. */
+    slp->next = Sessions;
+    Sessions = slp;
+
+    /*
+     * session now points to the new structure that still contains pointers to
+     * data allocated elsewhere.  Some of this data is copied to space malloc'd
+     * here, and the pointer replaced with the new one.
+     */
+
+    if (session->peername != NULL){
+       cp = (u_char *)calloc(1, (unsigned)strlen(session->peername) + 1);
+       strcpy((char *)cp, session->peername);
+       session->peername = (char *)cp;
+    }
+
+    if (session->retries == SNMP_DEFAULT_RETRIES)
+       session->retries = SNMP_API_DEFAULT_RETRIES;
+    if (session->timeout == SNMP_DEFAULT_TIMEOUT)
+       session->timeout = SNMP_API_DEFAULT_TIMEOUT;
+    if (session->MMS == 0 )
+       session->MMS = DEFAULT_MMS;
+    isp->requests = NULL;
+
+
+    /* Fill in defaults if necessary */
+    if (session->community_len != SNMP_DEFAULT_COMMUNITY_LEN){
+       if( *session->community == '+' ) {
+               session->community_len--;
+               cp = (u_char *) calloc(1, (unsigned) session->community_len);
+               bcopy((char *) session->community+1, (char *)cp,
+                     session->community_len);
+               session->version = SNMP_VERSION_2C;
+       } else {
+               cp = (u_char *) calloc(1, (unsigned) session->community_len);
+               bcopy((char *) session->community, (char *) cp, 
+                     session->community_len);
+       }
+
+    } else {
+       session->community_len = strlen(DEFAULT_COMMUNITY);
+       cp = (u_char *)calloc(1, (unsigned)session->community_len);
+       bcopy((char *)DEFAULT_COMMUNITY, (char *)cp, session->community_len);
+    }
+
+    /* Set up connections */
+    sd = socket(AF_INET, SOCK_DGRAM, 0);
+    if (sd < 0){
+       perror("socket");
+       snmp_errno = SNMPERR_GENERR;
+       if (!snmp_close(session)){
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+           exit(1);
+       }
+       return 0;
+    }
+    isp->sd = sd;
+
+    if (session->peername != SNMP_DEFAULT_PEERNAME){
+       if ((addr = inet_addr(session->peername)) != -1){
+           bcopy((char *)&addr, (char *)&isp->addr.sin_addr, sizeof(isp->addr.sin_addr));
+       } else {
+           hp = gethostbyname(session->peername);
+           if (hp == NULL){
+               fprintf(stderr, "unknown host: %s\n", session->peername);
+               snmp_errno = SNMPERR_BAD_ADDRESS;
+               if (!snmp_close(session)){
+                   fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+                   exit(2);
+               }
+               return 0;
+           } else {
+               bcopy((char *)hp->h_addr, (char *)&isp->addr.sin_addr, hp->h_length);
+           }
+       }
+       isp->addr.sin_family = AF_INET;
+       if (session->remote_port == SNMP_DEFAULT_REMPORT){
+           /*servp = getservbyname("snmp", "udp");*/
+           servp=NULL;
+           if (servp != NULL){
+               isp->addr.sin_port = servp->s_port;
+           } else {
+               isp->addr.sin_port = htons(SNMP_PORT);
+           }
+       } else {
+           isp->addr.sin_port = htons(session->remote_port);
+       }
+    } else {
+       isp->addr.sin_addr.s_addr = SNMP_DEFAULT_ADDRESS;
+    }
+
+    me.sin_family = AF_INET;
+    me.sin_addr.s_addr = INADDR_ANY;
+    me.sin_port = htons(session->local_port);
+    if (bind(sd, (struct sockaddr *)&me, sizeof(me)) != 0){
+       perror("bind");
+       snmp_errno = SNMPERR_BAD_LOCPORT;
+       if (! snmp_close(session)){
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n", 
+                   api_errstring(snmp_errno));
+           exit(3);
+       }
+       return 0;
+    }
+
+    if( *cp == '/' ) {
+       session->authenticator = check_received_pkt;
+       sync_with_agent(session);
+       parse_app_community_string( session );
+       session->qoS |= USEC_QOS_GENREPORT;
+    }
+
+    /* replace comm pointer with pointer to new data: */
+    session->community = cp;   
+
+    return session;
+}
+
+void
+sync_with_agent( session )
+struct snmp_session *session;
+{
+    struct snmp_pdu *pdu, *response = 0;
+    int status;
+
+    session->qoS = USEC_QOS_GENREPORT;
+    session->userLen = 6;
+    session->version = SNMP_VERSION_2;
+    strcpy( session->userName, "public" );
+
+    snmp_synch_setup(session);
+    pdu = snmp_pdu_create(GET_REQ_MSG);
+    status = snmp_synch_response(session, pdu, &response);
+
+    if (status == STAT_SUCCESS){
+       memcpy( session->agentID, response->params.agentID, 12 );
+
+       /* save the clocks -- even though they are not authentic */
+       session->agentBoots = response->params.agentBoots;
+       session->agentTime = response->params.agentTime;
+       session->agentClock = response->params.agentTime - time(NULL);
+
+    } else {
+           if (status == STAT_TIMEOUT){
+               printf("No Response from %s\n", session->peername);
+           } else {    /* status == STAT_ERROR */
+               printf("An error occurred, Quitting\n");
+           }
+           exit( -1 );
+    }
+
+    /** freed to early: 
+      snmp_free_pdu(pdu);
+      if (response) snmp_free_pdu(response);
+     **/
+}
+#if 1 /***/
+/*
+ * Unlink one element from input request list,
+ * then free it and it's pdu.
+ */
+static void
+free_one_request(isp, orp)
+    struct snmp_internal_session *isp;
+    struct request_list *orp;
+{
+    struct request_list *rp;
+    if(! orp) return;
+    if(isp->requests == orp){ 
+      isp->requests = orp->next_request; /* unlink head */
+    }
+    else{
+      for(rp = isp->requests; rp; rp = rp->next_request){
+        if(rp->next_request == orp){ 
+         rp->next_request = orp->next_request; /* unlink element */
+         break;
+        }
+      }
+    }
+    if (orp->pdu != NULL){
+      snmp_free_pdu(orp->pdu);
+    }
+    free((char *)orp);
+}
+#endif /***/
+/*
+ * Free each element in the input request list.
+ */
+static void
+free_request_list(rp)
+    struct request_list *rp;
+{
+    struct request_list *orp;
+
+    while(rp){
+       orp = rp;
+       rp = rp->next_request;
+       if (orp->pdu != NULL)
+           snmp_free_pdu(orp->pdu);
+       free((char *)orp);
+    }
+}
+
+/*
+ * 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.
+ */
+int 
+snmp_close(session)
+    struct snmp_session *session;
+{
+    struct session_list *slp = NULL, *oslp = NULL;
+
+    if (Sessions->session == session){ /* If first entry */
+       slp = Sessions;
+       Sessions = slp->next;
+    } else {
+       for(slp = Sessions; slp; slp = slp->next){
+           if (slp->session == session){
+               if (oslp)   /* if we found entry that points here */
+                   oslp->next = slp->next;     /* link around this entry */
+               break;
+           }
+           oslp = slp;
+       }
+    }
+    /* If we found the session, free all data associated with it */
+    if (slp){
+       if (slp->session->community != NULL)
+           free((char *)slp->session->community);
+       if(slp->session->peername != NULL)
+           free((char *)slp->session->peername);
+       free((char *)slp->session);
+       if (slp->internal->sd != -1)
+           close(slp->internal->sd);
+       free_request_list(slp->internal->requests);
+       free((char *)slp->internal);
+       free((char *)slp);
+    } else {
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    return 1;
+}
+
+/*
+ * Takes a session and a pdu and serializes the ASN PDU into the area
+ * pointed to by packet.  out_length is the size of the data area available.
+ * Returns the length of the completed packet in out_length.  If any errors
+ * occur, -1 is returned.  If all goes well, 0 is returned.
+ */
+int
+snmp_build(session, pdu, packet, out_length, is_agent)
+    struct snmp_session        *session;
+    struct snmp_pdu    *pdu;
+    u_char     *packet;
+    int                        *out_length;
+    int                         is_agent;
+{
+    u_char  buf[PACKET_LENGTH];
+    u_char  *cp;
+    struct variable_list *vp;
+    int            length;
+    int            totallength;
+
+    length = *out_length;
+    cp = packet;
+    for(vp = pdu->variables; vp; vp = vp->next_variable){
+       cp = snmp_build_var_op(cp, vp->name, &vp->name_length, vp->type, vp->val_len, (u_char *)vp->val.string, &length);
+       if (cp == NULL)
+           return -1;
+    }
+    totallength = cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR), totallength);
+    if (cp == NULL)
+       return -1;
+    bcopy((char *)packet, (char *)cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+    if (pdu->command != TRP_REQ_MSG){
+       /* request id */
+       cp = asn_build_int(packet, &length,
+           (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+           (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (cp == NULL)
+           return -1;
+       /* error status */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (cp == NULL)
+           return -1;
+       /* error index */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (cp == NULL)
+           return -1;
+    } else {   /* this is a trap message */
+       /* enterprise */
+       cp = asn_build_objid(packet, &length,
+           (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID),
+           (oid *)pdu->enterprise, pdu->enterprise_length);
+       if (cp == NULL)
+           return -1;
+       /* agent-addr */
+       cp = asn_build_string(cp, &length, (u_char)IPADDRESS,
+               (u_char *)&pdu->agent_addr.sin_addr.s_addr, sizeof(pdu->agent_addr.sin_addr.s_addr));
+       if (cp == NULL)
+           return -1;
+       /* generic trap */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (cp == NULL)
+           return -1;
+       /* specific trap */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (cp == NULL)
+           return -1;
+       /* timestamp  */
+       cp = asn_build_int(cp, &length, (u_char)TIMETICKS,
+               (long *)&pdu->time, sizeof(pdu->time));
+       if (cp == NULL)
+           return -1;
+    }
+    if (length < totallength)
+       return -1;
+    bcopy((char *)buf, (char *)cp, totallength);
+    totallength += cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char)pdu->command, totallength);
+    if (cp == NULL)
+       return -1;
+    if (length < totallength)
+       return -1;
+    bcopy((char *)packet, (char *)cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+
+    cp = snmp_auth_build( packet, &length, session, is_agent, totallength );
+    if (cp == NULL)
+       return -1;
+    if ((*out_length - (cp - packet)) < totallength)
+       return -1;
+    bcopy((char *)buf, (char *)cp, totallength);
+    totallength += cp - packet;
+    *out_length = totallength;
+
+    if( session->qoS & USEC_QOS_AUTH )
+           md5Digest( packet, totallength, cp - (session->contextLen + 16),
+               cp - (session->contextLen + 16) );
+
+    return 0;
+}
+
+/*
+ * Parses the packet received on the input session, and places the data into
+ * the input pdu.  length is the length of the input packet.  If any errors
+ * are encountered, -1 is returned.  Otherwise, a 0 is returned.
+ */
+static int
+snmp_parse(session, pdu, data, length)
+    struct snmp_session *session;
+    struct snmp_pdu *pdu;
+    u_char  *data;
+    int            length;
+{
+    u_char  msg_type;
+    u_char  type;
+    u_char  *var_val;
+    long    version;
+    int            len, four;
+    u_char community[256];
+    int community_length = 256;
+    struct variable_list *vp = 0;
+    oid            objid[MAX_NAME_LEN], *op;
+    u_char  *origdata = data;
+    int      origlength = length;
+    int      ret = 0;
+    u_char  *save_data;
+
+    /* authenticates message and returns length if valid */
+    data = snmp_auth_parse(data, &length, community, &community_length, &version);
+    if (data == NULL)
+       return -1;
+
+   if( version != SNMP_VERSION_1 && version != SNMP_VERSION_2C && version != SNMP_VERSION_2 ) {
+           fprintf(stderr, "Wrong version: %ld\n", version);
+           return -1;
+    }
+
+    save_data = data;
+
+    data = asn_parse_header(data, &length, &msg_type);
+    if (data == NULL)
+       return -1;
+    pdu->command = msg_type;
+
+    if( session->authenticator ) {
+       ret = session->authenticator( origdata, origlength, save_data - community_length, 
+               community_length, session, pdu );
+       if( ret < 0 ) return ret;
+    }
+
+    if (pdu->command != TRP_REQ_MSG){
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (data == NULL)
+           return -1;
+    } else {
+       pdu->enterprise_length = MAX_NAME_LEN;
+       data = asn_parse_objid(data, &length, &type, objid, &pdu->enterprise_length);
+       if (data == NULL)
+           return -1;
+       pdu->enterprise = (oid *)calloc(1, pdu->enterprise_length * sizeof(oid));
+       bcopy((char *)objid, (char *)pdu->enterprise, pdu->enterprise_length * sizeof(oid));
+
+       four = 4;
+       data = asn_parse_string(data, &length, &type, (u_char *)&pdu->agent_addr.sin_addr.s_addr, &four);
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->time, sizeof(pdu->time));
+       if (data == NULL)
+           return -1;
+    }
+    data = asn_parse_header(data, &length, &type);
+    if (data == NULL)
+       return -1;
+    if (type != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR))
+       return -1;
+    while((int)length > 0){
+       if (pdu->variables == NULL){
+           pdu->variables = vp = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+       } else {
+           vp->next_variable = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+           vp = vp->next_variable;
+       }
+       vp->next_variable = NULL;
+       vp->val.string = NULL;
+       vp->name = NULL;
+       vp->name_length = MAX_NAME_LEN;
+       data = snmp_parse_var_op(data, objid, &vp->name_length, &vp->type, &vp->val_len, &var_val, (int *)&length);
+       if (data == NULL)
+           return -1;
+       op = (oid *)calloc(1, (unsigned)vp->name_length * sizeof(oid));
+       bcopy((char *)objid, (char *)op, vp->name_length * sizeof(oid));
+       vp->name = op;
+
+       len = PACKET_LENGTH;
+       switch((short)vp->type){
+           case ASN_INTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(long));
+               vp->val_len = sizeof(long);
+               asn_parse_int(var_val, &len, &vp->type, (long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER:
+           case GAUGE:
+           case TIMETICKS:
+           case UINTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(unsigned long));
+               vp->val_len = sizeof(unsigned long);
+               asn_parse_unsigned_int(var_val, &len, &vp->type, (unsigned long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER64:
+               vp->val.counter64 = (struct counter64 *)calloc(1,  sizeof(struct counter64) );
+               vp->val_len = sizeof(struct counter64);
+               asn_parse_unsigned_int64(var_val, &len, &vp->type,
+                                        (struct counter64 *)vp->val.counter64,
+                                        sizeof(*vp->val.counter64));
+               break;
+           case ASN_OCTET_STR:
+           case IPADDRESS:
+           case OPAQUE:
+           case NSAP:
+               vp->val.string = (u_char *)calloc(1, (unsigned)vp->val_len);
+               asn_parse_string(var_val, &len, &vp->type, vp->val.string, &vp->val_len);
+               break;
+           case ASN_OBJECT_ID:
+               vp->val_len = MAX_NAME_LEN;
+               asn_parse_objid(var_val, &len, &vp->type, objid, &vp->val_len);
+               vp->val_len *= sizeof(oid);
+               vp->val.objid = (oid *)calloc(1, (unsigned)vp->val_len);
+               bcopy((char *)objid, (char *)vp->val.objid, vp->val_len);
+               break;
+            case SNMP_NOSUCHOBJECT:
+            case SNMP_NOSUCHINSTANCE:
+            case SNMP_ENDOFMIBVIEW:
+           case ASN_NULL:
+               break;
+           default:
+               fprintf(stderr, "bad type returned (%x)\n", vp->type);
+               break;
+       }
+    }
+    return ret;
+}
+
+/*
+ * 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(session, pdu)
+    struct snmp_session *session;
+    struct snmp_pdu    *pdu;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp = NULL;
+    u_char  packet[PACKET_LENGTH];
+    int length = PACKET_LENGTH;
+    struct request_list *rp;
+    struct timeval tv;
+
+    for(slp = Sessions; slp; slp = slp->next){
+       if (slp->session == session){
+           isp = slp->internal;
+           break;
+       }
+    }
+
+    if (! pdu) {
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+
+    if (isp == NULL){
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG
+       || pdu->command == GET_RSP_MSG || pdu->command == SET_REQ_MSG 
+       || pdu->command == GETBULK_REQ_MSG ){
+       if (pdu->reqid == SNMP_DEFAULT_REQID)
+           pdu->reqid = ++Reqid;
+       if (pdu->errstat == SNMP_DEFAULT_ERRSTAT)
+           pdu->errstat = 0;
+       if (pdu->errindex == SNMP_DEFAULT_ERRINDEX)
+           pdu->errindex = 0;
+    } else {
+       /* fill in trap defaults */
+       pdu->reqid = 1; /* give a bogus non-error reqid for traps */
+       if (pdu->enterprise_length == SNMP_DEFAULT_ENTERPRISE_LENGTH){
+           pdu->enterprise = (oid *)calloc(1, sizeof(DEFAULT_ENTERPRISE));
+           bcopy((char *)DEFAULT_ENTERPRISE, (char *)pdu->enterprise, sizeof(DEFAULT_ENTERPRISE));
+           pdu->enterprise_length = sizeof(DEFAULT_ENTERPRISE)/sizeof(oid);
+       }
+       if (pdu->time == SNMP_DEFAULT_TIME)
+           pdu->time = DEFAULT_TIME;
+    }
+    if (pdu->address.sin_addr.s_addr == SNMP_DEFAULT_ADDRESS){
+       if (isp->addr.sin_addr.s_addr != SNMP_DEFAULT_ADDRESS){
+           bcopy((char *)&isp->addr, (char *)&pdu->address, sizeof(pdu->address));
+       } else {
+           fprintf(stderr, "No remote IP address specified\n");
+           snmp_errno = SNMPERR_BAD_ADDRESS;
+           return 0;
+       }
+    }
+       
+
+    if (snmp_build(session, pdu, packet, &length, 0) < 0){
+       fprintf(stderr, "Error building packet\n");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+#if 1 /***/
+    if (snmp_dump_packet){
+      snmp_print_packet(packet, length, pdu->address, 1);
+    }
+#endif /***/
+
+       gettimeofday(&tv, (struct timezone *) 0);
+    if (sendto(isp->sd, (char *) packet, length, 0, (struct sockaddr *) &pdu->address, sizeof(pdu->address)) < 0) {
+       perror("sendto");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG
+       || pdu->command == SET_REQ_MSG || pdu->command == GETBULK_REQ_MSG) {
+       /* set up to expect a response */
+       rp = (struct request_list *) calloc(1, sizeof(struct request_list));
+#if 1/***/ if we found entry that points here */
+ oslp e key!  replace...
+     */
+ * \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 1\ 1\0\0\0\0\0\0\0\19\7fÿ¯ùsnmplib/snmp_api.c\0c\0\0.h\0\0\0\18\7fÿ°\85\10\0<Ðlib/snmp_api.c~\0~\0\0ñ\0\0\0\18\7fÿ±\1e\10\0\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\0\0\0\18\7fÿ±«\10\0=\10\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\0\0\0\18\7fÿ²\1d\10\0=0\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\0\0\0\18\7fÿ²\8a\10\0=P\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\0\0\0\18\7fÿ³
+\10\0=p\7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\0\0\0\18\7fÿ³\82\0\0\0\ 1\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\0\0\0Á\7fÿ³ù\0\0\0\10\7fÿ´\10\10\0\0%\0\19\0\15\0\0\10\0D(\0\0\0\10\7fÿ´_\10\0\0\0\ 2\\0\0\0\0\10\0\0\0\0\10\7fÿ´©\10\0=\98\0\0\ 24\0\0\0\0\10\0\0\0\0\10\7fÿ´ø\10\0\0\0\ 2H\0\0\0\0\10\0\0\0\0\10\7fÿµB\10\0>\10\7fÿµ]\7fÿµm\7fÿµz\0\0\0\10\7fÿµ \10\0>(\7fÿµ·\7fÿµÉ\7fÿµÖ\0\0\0\10\7fÿµï\10\0>@\7fÿ¶\12\7fÿ¶ \7fÿ¶4\0\0\0\10\7fÿ¶P\0\0\0\ 1\7fÿ¶r\7fÿ¶~\7fÿ¶\88\0\0\00\7fÿ¶\9f\0\0\0\0\7fÿ¶·\0\0\0\0\7fÿ¶Ù\10\0\7fÿ·\ 1\0\0\0\0\7fÿ·#\7fÿ·/\7fÿ·>\10\0>X\7fÿ·V\0\0\03\0\0\0\0/usr/people/wessels/.indent.pro\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\ 1\0\0\0\0\7fÿ¯è\7fÿ¯ù\7fÿ°\f\7fÿ°\e\7fÿ°.\7fÿ°?\7fÿ°M\7fÿ°[\7fÿ°p\7fÿ°\85\7fÿ°\95\7fÿ°£\7fÿ°²\7fÿ°Å\7fÿ°Û\7fÿ°ñ\7fÿ±
+\7fÿ±\1e\7fÿ±2\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\7fÿ±\99\7fÿ±«\7fÿ±º\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\7fÿ²\ f\7fÿ²\1d\7fÿ²2\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\7fÿ²\7f\7fÿ²\8a\7fÿ²\99\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\7fÿ²ö\7fÿ³
+\7fÿ³ \7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\7fÿ³s\7fÿ³\82\7fÿ³\91\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\7fÿ³ç\7fÿ³ù\7fÿ´\ 4\7fÿ´\10\7fÿ´\1e\7fÿ´)\7fÿ´3\7fÿ´C\7fÿ´O\7fÿ´_\7fÿ´k\7fÿ´t\7fÿ´\81\7fÿ´\8f\7fÿ´\9f\7fÿ´©\7fÿ´·\7fÿ´Å\7fÿ´Ò\7fÿ´Ý\7fÿ´í\7fÿ´ø\7fÿµ\ 3\7fÿµ\10\7fÿµ\1d\7fÿµ)\7fÿµ7\7fÿµB\7fÿµM\7fÿµ]\7fÿµm\7fÿµz\7fÿµ\89\7fÿµ \7fÿµ«\7fÿµ·\7fÿµÉ\7fÿµÖ\7fÿµâ\7fÿµï\7fÿ¶\ 3\7fÿ¶\12\7fÿ¶ \7fÿ¶4\7fÿ¶?\7fÿ¶P\7fÿ¶b\7fÿ¶r\7fÿ¶~\7fÿ¶\88\7fÿ¶\94\7fÿ¶\9f\7fÿ¶«\7fÿ¶·\7fÿ¶É\7fÿ¶Ù\7fÿ¶í\7fÿ·\ 1\7fÿ·\15\7fÿ·#\7fÿ·/\7fÿ·>\7fÿ·L\7fÿ·V\7fÿ·f\7fÿ·q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0@    \0\0\0\0ables == NULL){
+           pdu->variables = vp = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+       } else {
+           vp->next_variable = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+           vp = vp->next_variable;
+       }
+       vp->next_variable = NULL;
+       vp->val.string = NULL;
+       vp->name = NULL;
+       vp->name_length = MAX_NAME_LEN;
+       data = snmp_parse_var_op(data, objid, &vp->name_length, &vp->type, &vp->val_len, &var_val, (int *)&length);
+       if (data == NULL)
+           return -1;
+       op = (oid *)calloc(1, (unsigned)vp->name_length * sizeof(oid));
+       bcopy((char *)objid, (char *)op, vp->name_length * sizeof(oid));
+       vp->name = op;
+
+       len = PACKET_LENGTH;
+       switch((short)vp->type){
+           case ASN_INTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(long));
+               vp->val_len = sizeof(long);
+               asn_parse_int(var_val, &len, &vp->type, (long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER:
+           case GAUGE:
+           case TIMETICKS:
+           case UINTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(unsigned long));
+               vp->val_len = sizeof(unsigned long);
+               asn_parse_unsigned_int(var_val, &len, &vp->type, (unsigned long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER64:
+               vp->val.counter64 = (struct counter64 *)calloc(1,  sizeof(struct counter64) );
+               vp->val_len = sizeof(struct counter64);
+               asn_parse_unsigned_int64(var_val, &len, &vp->type,
+                                        (struct counter64 *)vp->val.counter64,
+                                        sizeof(*vp->val.counter64));
+               break;
+           case ASN_OCTET_STR:
+           case IPADDRESS:
+           case OPAQUE:
+           case NSAP:
+               vp->val.string = (u_char *)calloc(1, (unsigned)vp->val_len);
+               asn_parse_string(var_val, &len, &vp->type, vp->val.string, &vp->val_len);
+               break;
+           case ASN_OBJECT_ID:
+               vp->val_len = MAX_NAME_LEN;
+               asn_parse_objid(var_val, &len, &vp->type, objid, &vp->val_len);
+               vp->val_len *= sizeof(oid);
+               vp->val.objid = (oid *)calloc(1, (unsigned)vp->val_len);
+               bcopy((char *)objid, (char *)vp->val.objid, vp->val_len);
+               break;
+            case SNMP_NOSUCHOBJECT:
+            case SNMP_NOSUCHINSTANCE:
+            case SNMP_ENDOFMIBVIEW:
+           case ASN_NULL:
+               break;
+           default:
+               fprintf(stderr, "bad type returned (%x)\n", vp->type);
+               break;
+       }
+    }
+    return ret;
+}
+
+/*
+ * 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(session, pdu)
+    struct snmp_session *session;
+    struct snmp_pdu    *pdu;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp = NULL;
+    u_char  packet[PACKET_LENGTH];
+    int length = PACKET_LENGTH;
+    struct request_list *rp;
+    struct timeval tv;
+
+    for(slp = Sessions; slp; slp = slp->next){
+       if (slp->session == session){
+           isp = slp->internal;
+           break;
+       }
+    }
+
+    if (! pdu) {
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+
+    if (isp == NULL){
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG
+       || pdu->command == GET_RSP_MSG || pdu->command == SET_REQ_MSG 
+       || pdu->command == GETBULK_REQ_MSG ){
+       if (pdu->reqid == SNMP_DEFAULT_REQID)
+           pdu->reqid = ++Reqid;
+       if (pdu->errstat == SNMP_DEFAULT_ERRSTAT)
+           pdu->errstat = 0;
+       if (pdu->errindex == SNMP_DEFAULT_ERRINDEX)
+           pdu->errindex = 0;
+    } else {
+       /* fill in trap defaults */
+       pdu->reqid = 1; /* give a bogus non-error reqid for traps */
+       if (pdu->enterprise_length == SNMP_DEFAULT_ENTERPRISE_LENGTH){
+           pdu->enterprise = (oid *)calloc(1, sizeof(DEFAULT_ENTERPRISE));
+           bcopy((char *)DEFAULT_ENTERPRISE, (char *)pdu->enterprise, sizeof(DEFAULT_ENTERPRISE));
+           pdu->enterprise_length = sizeof(DEFAULT_ENTERPRISE)/sizeof(oid);
+       }
+       if (pdu->time == SNMP_DEFAULT_TIME)
+           pdu->time = DEFAULT_TIME;
+    }
+    if (pdu->address.sin_addr.s_addr == SNMP_DEFAULT_ADDRESS){
+       if (isp->addr.sin_addr.s_addr != SNMP_DEFAULT_ADDRESS){
+           bcopy((char *)&isp->addr, (char *)&pdu->address, sizeof(pdu->address));
+       } else {
+           fprintf(stderr, "No remote IP address specified\n");
+           snmp_errno = SNMPERR_BAD_ADDRESS;
+           return 0;
+       }
+    }
+       
+
+    if (snmp_build(session, pdu, packet, &length, 0) < 0){
+       fprintf(stderr, "Error building packet\n");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+#if 1 /***/
+    if (snmp_dump_packet){
+      snmp_print_packet(packet, length, pdu->address, 1);
+    }
+#endif /***/
+
+       gettimeofday(&tv, (struct timezone *) 0);
+    if (sendto(isp->sd, (char *) packet, length, 0, (struct sockaddr *) &pdu->address, sizeof(pdu->address)) < 0) {
+       perror("sendto");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG
+       || pdu->command == SET_REQ_MSG || pdu->command == GETBULK_REQ_MSG) {
+       /* set up to expect a response */
+       rp = (struct request_list *) calloc(1, sizeof(struct request_list));
+ar *)&isp->addr.sin_addr, sizeof(isp->addr.sin_addr));
+       } else {
+           hp = gethostbyname(session->peername);
+           if (hp == NULL){
+               fprintf(stderr, "unknown host: %s\n", session->peername);
+               snmp_errno = SNMPERR_BAD_ADDRESS;
+               if (!snmp_close(session)){
+                   fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+                   exit(2);
+               }
+               return 0;
+           } else {
+               bcopy((char *)hp->h_addr, (char *)&isp->addr.sin_addr, hp->h_length);
+           }
+       }
+       isp->addr.sin_family = AF_INET;
+       if (session->remote_port == SNMP_DEFAULT_REMPORT){
+           /*servp = getservbyname("snmp", "udp");*/
+           servp=NULL;
+           if (servp != NULL){
+               isp->addr.sin_port = servp->s_port;
+           } else {
+               isp->addr.sin_port = htons(SNMP_PORT);
+           }
+       } else {
+           isp->addr.sin_port = htons(session->remote_port);
+       }
+    } else {
+       isp->addr.sin_addr.s_addr = SNMP_DEFAULT_ADDRESS;
+    }
+
+    me.sin_family = AF_INET;
+    me.sin_addr.s_addr = INADDR_ANY;
+    me.sin_port = htons(session->local_port);
+    if (bind(sd, (struct sockaddr *)&me, sizeof(me)) != 0){
+       perror("bind");
+       snmp_errno = SNMPERR_BAD_LOCPORT;
+       if (! snmp_close(session)){
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n", 
+                   api_errstring(snmp_errno));
+           exit(3);
+       }
+       return 0;
+    }
+
+    if( *cp == '/' ) {
+       session->authenticator = check_received_pkt;
+       sync_with_agent(session);
+       parse_app_community_string( session );
+       session->qoS |= USEC_QOS_GENREPORT;
+    }
+
+    /* replace comm pointer with pointer to new data: */
+    session->community = cp;   
+
+    return session;
+}
+
+void
+sync_with_agent( session )
+struct snmp_session *session;
+{
+    struct snmp_pdu *pdu, *response = 0;
+    int status;
+
+    session->qoS = USEC_QOS_GENREPORT;
+    session->userLen = 6;
+    session->version = SNMP_VERSION_2;
+    strcpy( session->userName, "public" );
+
+    snmp_synch_setup(session);
+    pdu = snmp_pdu_create(GET_REQ_MSG);
+    status = snmp_synch_response(session, pdu, &response);
+
+    if (status == STAT_SUCCESS){
+       memcpy( session->agentID, response->params.agentID, 12 );
+
+       /* save the clocks -- even though they are not authentic */
+       session->agentBoots = response->params.agentBoots;
+       session->agentTime = response->params.agentTime;
+       session->agentClock = response->params.agentTime - time(NULL);
+
+    } else {
+           if (status == STAT_TIMEOUT){
+               printf("No Response from %s\n", session->peername);
+           } else {    /* status == STAT_ERROR */
+               printf("An error occurred, Quitting\n");
+           }
+           exit( -1 );
+    }
+
+    /** freed to early: 
+      snmp_free_pdu(pdu);
+      if (response) snmp_free_pdu(response);
+     **/
+}
+#if 1 /***/
+/*
+ * Unlink one element from input request list,
+ * then free it and it's pdu.
+ */
+static void
+free_one_request(isp, orp)
+    struct snmp_internal_session *isp;
+    struct request_list *orp;
+{
+    struct request_list *rp;
+    if(! orp) return;
+    if(isp->requests == orp){ 
+      isp->requests = orp->next_request; /* unlink head */
+    }
+    else{
+      for(rp = isp->requests; rp; rp = rp->next_request){
+        if(rp->next_request == orp){ 
+         rp->next_request = orp->next_request; /* unlink element */
+         break;
+        }
+      }
+    }
+    if (orp->pdu != NULL){
+      snmp_free_pdu(orp->pdu);
+    }
+    free((char *)orp);
+}
+#endif /***/
+/*
+ * Free each element in the input request list.
+ */
+static void
+free_request_list(rp)
+    struct request_list *rp;
+{
+    struct request_list *orp;
+
+    while(rp){
+       orp = rp;
+       rp = rp->next_request;
+       if (orp->pdu != NULL)
+           snmp_free_pdu(orp->pdu);
+       free((char *)orp);
+    }
+}
+
+/*
+ * 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.
+ */
+int 
+snmp_close(session)
+    struct snmp_session *session;
+{
+    struct session_list *slp = NULL, *oslp = NULL;
+
+    if (Sessions->session == session){ /* If first entry */
+       slp = Sessions;
+       Sessions = slp->next;
+    } else {
+       for(slp = Sessions; slp; slp = slp->next){
+           if (slp->session == session){
+               if (oslp)   /* if we found entry that points here */
+                   oslp->next = slp->next;     /* link around this entry */
+               break;
+           }
+           oslp = slp;
+       }
+    }
+    /* If we found the session, free all data associated with it */
+    if (slp){
+       if (slp->session->community != NULL)
+           free((char *)slp->session->community);
+       if(slp->session->peername != NULL)
+           free((char *)slp->session->peername);
+       free((char *)slp->session);
+       if (slp->internal->sd != -1)
+           close(slp->internal->sd);
+       free_request_list(slp->internal->requests);
+       free((char *)slp->internal);
+       free((char *)slp);
+    } else {
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    return 1;
+}
+
+/*
+ * Takes a session and a pdu and serializes the ASN PDU into the area
+ * pointed to by packet.  out_length is the size of the data area available.
+ * Returns the length of the completed packet in out_length.  If any errors
+ * occur, -1 is returned.  If all goes well, 0 is returned.
+ */
+int
+snmp_build(session, pdu, packet, out_length, is_agent)
+    struct snmp_session        *session;
+    struct snmp_pdu    *pdu;
+    u_char     *packet;
+    int                        *out_length;
+    int                         is_agent;
+{
+    u_char  buf[PACKET_LENGTH];
+    u_char  *cp;
+    struct variable_list *vp;
+    int            length;
+    int            totallength;
+
+    length = *out_length;
+    cp = packet;
+    for(vp = pdu->variables; vp; vp = vp->next_variable){
+       cp = snmp_build_var_op(cp, vp->name, &vp->name_length, vp->type, vp->val_len, (u_char *)vp->val.string, &length);
+       if (cp == NULL)
+           return -1;
+    }
+    totallength = cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR), totallength);
+    if (cp == NULL)
+       return -1;
+    bcopy((char *)packet, (char *)cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+    if (pdu->command != TRP_REQ_MSG){
+       /* request id */
+       cp = asn_build_int(packet, &length,
+           (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+           (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (cp == NULL)
+           return -1;
+       /* error status */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (cp == NULL)
+           return -1;
+       /* error index */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (cp == NULL)
+           return -1;
+    } else {   /* this is a trap message */
+       /* enterprise */
+       cp = asn_build_objid(packet, &length,
+           (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID),
+           (oid *)pdu->enterprise, pdu->enterprise_length);
+       if (cp == NULL)
+           return -1;
+       /* agent-addr */
+       cp = asn_build_string(cp, &length, (u_char)IPADDRESS,
+               (u_char *)&pdu->agent_addr.sin_addr.s_addr, sizeof(pdu->agent_addr.sin_addr.s_addr));
+       if (cp == NULL)
+           return -1;
+       /* generic trap */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (cp == NULL)
+           return -1;
+       /* specific trap */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (cp == NULL)
+           return -1;
+       /* timestamp  */
+       cp = asn_build_int(cp, &length, (u_char)TIMETICKS,
+               (long *)&pdu->time, sizeof(pdu->time));
+       if (cp == NULL)
+           return -1;
+    }
+    if (length < totallength)
+       return -1;
+    bcopy((char *)buf, (char *)cp, totallength);
+    totallength += cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char)pdu->command, totallength);
+    if (cp == NULL)
+       return -1;
+    if (length < totallength)
+       return -1;
+    bcopy((char *)packet, (char *)cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+
+    cp = snmp_auth_build( packet, &length, session, is_agent, totallength );
+    if (cp == NULL)
+       return -1;
+    if ((*out_length - (cp - packet)) < totallength)
+       return -1;
+    bcopy((char *)buf, (char *)cp, totallength);
+    totallength += cp - packet;
+    *out_length = totallength;
+
+    if( session->qoS & USEC_QOS_AUTH )
+           md5Digest( packet, totallength, cp - (session->contextLen + 16),
+               cp - (session->contextLen + 16) );
+
+    return 0;
+}
+
+/*
+ * Parses the packet received on the input session, and places the data into
+ * the input pdu.  length is the length of the input packet.  If any errors
+ * are encountered, -1 is returned.  Otherwise, a 0 is returned.
+ */
+static int
+snmp_parse(session, pdu, data, length)
+    struct snmp_session *session;
+    struct snmp_pdu *pdu;
+    u_char  *data;
+    int            length;
+{
+    u_char  msg_type;
+    u_char  type;
+    u_char  *var_val;
+    long    version;
+    int            len, four;
+    u_char community[256];
+    int community_length = 256;
+    struct variable_list *vp = 0;
+    oid            objid[MAX_NAME_LEN], *op;
+    u_char  *origdata = data;
+    int      origlength = length;
+    int      ret = 0;
+    u_char  *save_data;
+
+    /* authenticates message and returns length if valid */
+    data = snmp_auth_parse(data, &length, community, &community_length, &version);
+    if (data == NULL)
+       return -1;
+
+   if( version != SNMP_VERSION_1 && version != SNMP_VERSION_2C && version != SNMP_VERSION_2 ) {
+           fprintf(stderr, "Wrong version: %ld\n", version);
+           return -1;
+    }
+
+    save_data = data;
+
+    data = asn_parse_header(data, &length, &msg_type);
+    if (data == NULL)
+       return -1;
+    pdu->command = msg_type;
+
+    if( session->authenticator ) {
+       ret = session->authenticator( origdata, origlength, save_data - community_length, 
+               community_length, session, pdu );
+       if( ret < 0 ) return ret;
+    }
+
+    if (pdu->command != TRP_REQ_MSG){
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (data == NULL)
+           return -1;
+    } else {
+       pdu->enterprise_length = MAX_NAME_LEN;
+       data = asn_parse_objid(data, &length, &type, objid, &pdu->enterprise_length);
+       if (data == NULL)
+           return -1;
+       pdu->enterprise = (oid *)calloc(1, pdu->enterprise_length * sizeof(oid));
+       bcopy((char *)objid, (char *)pdu->enterprise, pdu->enterprise_length * sizeof(oid));
+
+       four = 4;
+       data = asn_parse_string(data, &length, &type, (u_char *)&pdu->agent_addr.sin_addr.s_addr, &four);
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->time, sizeof(pdu->time));
+       if (data == NULL)
+           return -1;
+    }
+    data = asn_parse_header(data, &length, &type);
+    if (data == NULL)
+       return -1;
+    if (type != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR))
+       return -1;
+    while((int)length > 0){
+       if (pdu->vari\10\0BÐ+= m\0\0
+È      /* \10\04¨*/ B\0\0\0\0NMPT\10\ 1Ê  */c\0\0\0\0for testing purposes */e key!  replace...
+     */
+ * \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 1\ 1\0\0\0\0\0\0\0\19\7fÿ¯ùsnmplib/snmp_api.c\0c\0\0.h\0\0\0\18\7fÿ°\85\10\0<Ðlib/snmp_api.c~\0~\0\0ñ\0\0\0\18\7fÿ±\1e\10\0\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\0\0\0\18\7fÿ±«\10\0=\10\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\0\0\0\18\7fÿ²\1d\10\0=0\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\0\0\0\18\7fÿ²\8a\10\0=P\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\0\0\0\18\7fÿ³
+\10\0=p\7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\0\0\0\18\7fÿ³\82\0\0\0\ 1\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\0\0\0Á\7fÿ³ù\0\0\0\10\7fÿ´\10\10\0\0%\0\19\0\15\0\0\10\0D(\0\0\0\10\7fÿ´_\10\0\0\0\ 2\\0\0\0\0\10\0\0\0\0\10\7fÿ´©\10\0=\98\0\0\ 24\0\0\0\0\10\0\0\0\0\10\7fÿ´ø\10\0\0\0\ 2H\0\0\0\0\10\0\0\0\0\10\7fÿµB\10\0>\10\7fÿµ]\7fÿµm\7fÿµz\0\0\0\10\7fÿµ \10\0>(\7fÿµ·\7fÿµÉ\7fÿµÖ\0\0\0\10\7fÿµï\10\0>@\7fÿ¶\12\7fÿ¶ \7fÿ¶4\0\0\0\10\7fÿ¶P\0\0\0\ 1\7fÿ¶r\7fÿ¶~\7fÿ¶\88\0\0\00\7fÿ¶\9f\10\0\7fÿ¶·\0\0\0\0\7fÿ¶Ù\10\0\89è\7fÿ·\ 1\0\0\0\0\7fÿ·#\7fÿ·/\7fÿ·>\10\0>X\7fÿ·V\0\0\03\0\0\0\0/usr/people/wessels/.indent.pro\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\ 1\0\0\0\0\7fÿ¯è\7fÿ¯ù\7fÿ°\f\7fÿ°\e\7fÿ°.\7fÿ°?\7fÿ°M\7fÿ°[\7fÿ°p\7fÿ°\85\7fÿ°\95\7fÿ°£\7fÿ°²\7fÿ°Å\7fÿ°Û\7fÿ°ñ\7fÿ±
+\7fÿ±\1e\7fÿ±2\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\7fÿ±\99\7fÿ±«\7fÿ±º\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\7fÿ²\ f\7fÿ²\1d\7fÿ²2\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\7fÿ²\7f\7fÿ²\8a\7fÿ²\99\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\7fÿ²ö\7fÿ³
+\7fÿ³ \7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\7fÿ³s\7fÿ³\82\7fÿ³\91\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\7fÿ³ç\7fÿ³ù\7fÿ´\ 4\7fÿ´\10\7fÿ´\1e\7fÿ´)\7fÿ´3\7fÿ´C\7fÿ´O\7fÿ´_\7fÿ´k\7fÿ´t\7fÿ´\81\7fÿ´\8f\7fÿ´\9f\7fÿ´©\7fÿ´·\7fÿ´Å\7fÿ´Ò\7fÿ´Ý\7fÿ´í\7fÿ´ø\7fÿµ\ 3\7fÿµ\10\7fÿµ\1d\7fÿµ)\7fÿµ7\7fÿµB\7fÿµM\7fÿµ]\7fÿµm\7fÿµz\7fÿµ\89\7fÿµ \7fÿµ«\7fÿµ·\7fÿµÉ\7fÿµÖ\7fÿµâ\7fÿµï\7fÿ¶\ 3\7fÿ¶\12\7fÿ¶ \7fÿ¶4\7fÿ¶?\7fÿ¶P\7fÿ¶b\7fÿ¶r\7fÿ¶~\7fÿ¶\88\7fÿ¶\94\7fÿ¶\9f\7fÿ¶«\7fÿ¶·\7fÿ¶É\7fÿ¶Ù\7fÿ¶í\7fÿ·\ 1\7fÿ·\15\7fÿ·#\7fÿ·/\7fÿ·>\7fÿ·L\7fÿ·V\7fÿ·f\7fÿ·q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\0\0\0°\0\0\0\ 4\0\0\0\0\0\0\0\b\10\0>X\0\0\0\f\10\0\0\0\0\10\0\0\0\0\0\0\0\14\0\0\0\14\0\0\0\14\0\0\0\18\0\0\0\18\0\0\0\18\0\0\0\1c\0\0\0\1c\0\0\0\1c\0\0\0\1c\0\0\0 \0\0\0 \0\0\0 \0\0\0$\0\0\0\v\0\0\0\e\0\0\0\19\0\0\0\v\0\0\0\e\0\0\0@\0\0\0\0\0\0\0\0\0\0\0\0\10\0,\b\0\0\0\1a\10\02\88\0\0\0\1a\0\0\0\0\0\0\0\1a\10\0\85\b\0\0\0\0\10\0>X\0\0\0\0\0\0\0\0\0\0\0\0\10\0\82à\0\0\0\0\0\0\ 1C\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e0\0\0\0\v\0\0\0\e\0\0\0\18\0\0\0\v\0\0\0\1a\0\0\0\17\0\0\0\v\0\0\0 \0\0\0\0\10\0\8d¸ude/snmp_groupvars.h~\0\0\b\0\0\0\b\0\0\0 \0\0\0\0\10\0\8dàude/snmp_groupvars.h\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8eX\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e\80\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e¨\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8eÐ\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\0\0\0\ 1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\84©\0\0\0\0/***********************************************************
+       Copyright 1989 by Carnegie Mellon University
+
+                      All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the name of CMU not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+******************************************************************/
+/*
+ * snmp_api.c - API for access to snmp.
+ */
+#define DEBUG_SNMPTRACE                0 /* set to 1 to print all SNMP actions */
+#define DEBUG_SNMPFULLDUMP     0 /* set to 1 to dump all SNMP packets */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#ifdef linux
+#include <arpa/inet.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#endif
+
+
+#include "asn1.h"
+#include "snmp.h"
+#include "snmp_impl.h"
+#include "snmp_api.h"
+#include "snmp_client.h"
+
+#define PACKET_LENGTH  4500
+
+#ifndef BSD4_3
+#define BSD4_2
+#endif
+
+#if !defined(BSD4_3) && !defined(linux) && !defined(sun)
+
+typedef long   fd_mask;
+#define NFDBITS        (sizeof(fd_mask) * NBBY)        /* bits per mask */
+
+#define        FD_SET(n, p)    ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+#define        FD_CLR(n, p)    ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+#define        FD_ISSET(n, p)  ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+#define FD_ZERO(p)     bzero((char *)(p), sizeof(*(p)))
+#endif
+
+oid default_enterprise[] = {1, 3, 6, 1, 4, 1, 3, 1, 1}; /* enterprises.cmu.systems.cmuSNMP */
+
+#define DEFAULT_COMMUNITY   "public"
+#define DEFAULT_REMPORT            SNMP_PORT
+#define DEFAULT_ENTERPRISE  default_enterprise
+#define DEFAULT_TIME       0
+#define DEFAULT_MMS        1389 /* large, randomly picked for testing purposes */
+
+/*
+ * Internal information about the state of the snmp session.
+ */
+struct snmp_internal_session {
+    int            sd;         /* socket descriptor for this connection */
+    ipaddr  addr;      /* address of connected peer */
+    struct request_list *requests;/* Info about outstanding requests */
+};
+
+/*
+ * A list of all the outstanding requests for a particular session.
+ */
+struct request_list {
+    struct request_list *next_request;
+    u_long  request_id;        /* request id */
+    int            retries;    /* Number of retries */
+    u_long timeout;    /* length to wait for timeout */
+    struct timeval time; /* Time this request was made */
+    struct timeval expire;  /* time this request is due to expire */
+    struct snmp_pdu *pdu;   /* The pdu for this request (saved so it can be retransmitted */
+};
+
+/*
+ * The list of active/open sessions.
+ */
+struct session_list {
+    struct session_list *next;
+    struct snmp_session *session;
+    struct snmp_internal_session *internal;
+};
+
+struct session_list *Sessions = NULL;
+
+u_long Reqid = 0;
+int snmp_errno = 0;
+
+char *api_errors[4] = {
+    "Unknown session",
+    "Unknown host",
+    "Invalid local port",
+    "Unknown Error"
+};
+
+
+void sync_with_agent();
+int parse_app_community_string();
+void snmp_synch_setup();
+int snmp_synch_response();
+void md5Digest();
+
+
+static char *
+api_errstring(snmp_errnumber)
+    int        snmp_errnumber;
+{
+    if (snmp_errnumber <= SNMPERR_BAD_SESSION && snmp_errnumber >= SNMPERR_GENERR){
+       return api_errors[snmp_errnumber + 4];
+    } else {
+       return "Unknown Error";
+    }
+}
+
+#if 0
+/*
+ * Gets initial request ID for all transactions.
+ */
+static void
+init_snmp(){
+    struct timeval tv;
+
+    gettimeofday(&tv, (struct timezone *)0);
+    srandom(tv.tv_sec ^ tv.tv_usec);
+    Reqid = random();
+}
+#endif
+
+
+/*
+ * Dump snmp packet to stdout:
+ */
+static void
+snmp_print_packet(packet, length, addr, code)
+  char *packet; 
+  int length; 
+  ipaddr addr; 
+  int code;
+{
+  if(length < 0) {
+    return;
+  }
+  if (code <= 0) { /* received */
+    printf("\nReceived %4d bytes from ", length);
+  }
+  else { /* sending */
+    printf("\nSending  %4d bytes to   ", length);
+  }
+  printf("%s:", inet_ntoa(addr.sin_addr));
+#if DEBUG_SNMPFULLDUMP
+  for (count = 0; count < length; count++) {
+    if ((count & 15) == 0) {
+      printf("\n  ");
+    }
+    printf("%02X ", (int)(packet[count]&255));
+  }
+#endif
+  fflush(stdout);
+}
+
+#if DEBUG_SNMPTRACE
+/*
+ * Print request
+ */
+#define TRACE_SEND   (0)
+#define TRACE_RECV   (1)
+#define TRACE_TIMEOUT (2)
+static void
+snmp_print_trace(slp, rp, code)
+  struct session_list *slp;
+  struct request_list *rp;
+  int code;
+{
+  int reqid=0, retries=1;
+  if( rp ){
+    reqid = rp->request_id;
+    retries = rp->retries;
+  }  
+  printf("\n Session %2d  ReqId %4d  ", slp->internal->sd, reqid);
+  switch(code)
+    { 
+    case TRACE_SEND:    printf("send pdu (%d)", retries);break; 
+    case TRACE_RECV:    printf("recv pdu");break; 
+    case TRACE_TIMEOUT: printf("time out");break; 
+    }
+  fflush(stdout);
+}
+#endif /* DEBUG_SNMPTRACE */
+
+
+
+
+/*
+ * 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.
+ */
+struct snmp_session *
+snmp_open(session)
+    struct snmp_session *session;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp;
+    u_char *cp;
+    int sd;
+    u_long addr;
+    struct sockaddr_in me;
+    struct hostent *hp;
+    struct servent *servp;
+    extern int check_received_pkt();
+
+    /* Copy session structure and link into list */
+    slp = (struct session_list *)calloc(1, sizeof(struct session_list));
+    slp->internal = isp = (struct snmp_internal_session *)calloc(1, sizeof(struct snmp_internal_session));
+    bzero((char *)isp, sizeof(struct snmp_internal_session));
+    slp->internal->sd = -1; /* mark it not set */
+    slp->session = (struct snmp_session *)calloc(1, sizeof(struct snmp_session));
+    bcopy((char *)session, (char *)slp->session, sizeof(struct snmp_session));
+    session = slp->session;
+    /* now link it in. */
+    slp->next = Sessions;
+    Sessions = slp;
+
+    /*
+     * session now points to the new structure that still contains pointers to
+     * data allocated elsewhere.  Some of this data is copied to space malloc'd
+     * here, and the pointer replaced with the new one.
+     */
+
+    if (session->peername != NULL){
+       cp = (u_char *)calloc(1, (unsigned)strlen(session->peername) + 1);
+       strcpy((char *)cp, session->peername);
+       session->peername = (char *)cp;
+    }
+
+    if (session->retries == SNMP_DEFAULT_RETRIES)
+       session->retries = SNMP_API_DEFAULT_RETRIES;
+    if (session->timeout == SNMP_DEFAULT_TIMEOUT)
+       session->timeout = SNMP_API_DEFAULT_TIMEOUT;
+    if (session->MMS == 0 )
+       session->MMS = DEFAULT_MMS;
+    isp->requests = NULL;
+
+
+    /* Fill in defaults if necessary */
+    if (session->community_len != SNMP_DEFAULT_COMMUNITY_LEN){
+       if( *session->community == '+' ) {
+               session->community_len--;
+               cp = (u_char *) calloc(1, (unsigned) session->community_len);
+               bcopy((char *) session->community+1, (char *)cp,
+                     session->community_len);
+               session->version = SNMP_VERSION_2C;
+       } else {
+               cp = (u_char *) calloc(1, (unsigned) session->community_len);
+               bcopy((char *) session->community, (char *) cp, 
+                     session->community_len);
+       }
+
+    } else {
+       session->community_len = strlen(DEFAULT_COMMUNITY);
+       cp = (u_char *)calloc(1, (unsigned)session->community_len);
+       bcopy((char *)DEFAULT_COMMUNITY, (char *)cp, session->community_len);
+    }
+
+    /* Set up connections */
+    sd = socket(AF_INET, SOCK_DGRAM, 0);
+    if (sd < 0){
+       perror("socket");
+       snmp_errno = SNMPERR_GENERR;
+       if (!snmp_close(session)){
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+           exit(1);
+       }
+       return 0;
+    }
+    isp->sd = sd;
+
+    if (session->peername != SNMP_DEFAULT_PEERNAME){
+       if ((addr = inet_addr(session->peername)) != -1){
+           bcopy((char *)&addr, (char *)&isp->addr.sin_addr, sizeof(isp->addr.sin_addr));
+       } else {
+           hp = gethostbyname(session->peername);
+           if (hp == NULL){
+               fprintf(stderr, "unknown host: %s\n", session->peername);
+               snmp_errno = SNMPERR_BAD_ADDRESS;
+               if (!snmp_close(session)){
+                   fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+                   exit(2);
+               }
+               return 0;
+           } else {
+               bcopy((char *)hp->h_addr, (char *)&isp->addr.sin_addr, hp->h_length);
+           }
+       }
+       isp->addr.sin_family = AF_INET;
+       if (session->remote_port == SNMP_DEFAULT_REMPORT){
+           /*servp = getservbyname("snmp", "udp");*/
+           servp=NULL;
+           if (servp != NULL){
+               isp->addr.sin_port = servp->s_port;
+           } else {
+               isp->addr.sin_port = htons(SNMP_PORT);
+           }
+       } else {
+           isp->addr.sin_port = htons(session->remote_port);
+       }
+    } else {
+       isp->addr.sin_addr.s_addr = SNMP_DEFAULT_ADDRESS;
+    }
+
+    me.sin_family = AF_INET;
+    me.sin_addr.s_addr = INADDR_ANY;
+    me.sin_port = htons(session->local_port);
+    if (bind(sd, (struct sockaddr *)&me, sizeof(me)) != 0){
+       perror("bind");
+       snmp_errno = SNMPERR_BAD_LOCPORT;
+       if (! snmp_close(session)){
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n", 
+                   api_errstring(snmp_errno));
+           exit(3);
+       }
+       return 0;
+    }
+
+    if( *cp == '/' ) {
+       session->authenticator = check_received_pkt;
+       sync_with_agent(session);
+       parse_app_community_string( session );
+       session->qoS |= USEC_QOS_GENREPORT;
+    }
+
+    /* replace comm pointer with pointer to new data: */
+    session->community = cp;   
+
+    return session;
+}
+
+void
+sync_with_agent( session )
+struct snmp_session *session;
+{
+    struct snmp_pdu *pdu, *response = 0;
+    int status;
+
+    session->qoS = USEC_QOS_GENREPORT;
+    session->userLen = 6;
+    session->version = SNMP_VERSION_2;
+    strcpy( session->userName, "public" );
+
+    snmp_synch_setup(session);
+    pdu = snmp_pdu_create(GET_REQ_MSG);
+    status = snmp_synch_response(session, pdu, &response);
+
+    if (status == STAT_SUCCESS){
+       memcpy( session->agentID, response->params.agentID, 12 );
+
+       /* save the clocks -- even though they are not authentic */
+       session->agentBoots = response->params.agentBoots;
+       session->agentTime = response->params.agentTime;
+       session->agentClock = response->params.agentTime - time(NULL);
+
+    } else {
+           if (status == STAT_TIMEOUT){
+               printf("No Response from %s\n", session->peername);
+           } else {    /* status == STAT_ERROR */
+               printf("An error occurred, Quitting\n");
+           }
+           exit( -1 );
+    }
+
+    /** freed to early: 
+      snmp_free_pdu(pdu);
+      if (response) snmp_free_pdu(response);
+     **/
+}
+#if 1 /***/
+/*
+ * Unlink one element from input request list,
+ * then free it and it's pdu.
+ */
+static void
+free_one_request(isp, orp)
+    struct snmp_internal_session *isp;
+    struct request_list *orp;
+{
+    struct request_list *rp;
+    if(! orp) return;
+    if(isp->requests == orp){ 
+      isp->requests = orp->next_request; /* unlink head */
+    }
+    else{
+      for(rp = isp->requests; rp; rp = rp->next_request){
+        if(rp->next_request == orp){ 
+         rp->next_request = orp->next_request; /* unlink element */
+         break;
+        }
+      }
+    }
+    if (orp->pdu != NULL){
+      snmp_free_pdu(orp->pdu);
+    }
+    free((char *)orp);
+}
+#endif /***/
+/*
+ * Free each element in the input request list.
+ */
+static void
+free_request_list(rp)
+    struct request_list *rp;
+{
+    struct request_list *orp;
+
+    while(rp){
+       orp = rp;
+       rp = rp->next_request;
+       if (orp->pdu != NULL)
+           snmp_free_pdu(orp->pdu);
+       free((char *)orp);
+    }
+}
+
+/*
+ * 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.
+ */
+int 
+snmp_close(session)
+    struct snmp_session *session;
+{
+    struct session_list *slp = NULL, *oslp = NULL;
+
+    if (Sessions->session == session){ /* If first entry */
+       slp = Sessions;
+       Sessions = slp->next;
+    } else {
+       for(slp = Sessions; slp; slp = slp->next){
+           if (slp->session == session){
+               if (oslp)   /* if we found entry that points here */
+                   oslp->next = slp->next;     /* link around this entry */
+               break;
+           }
+           oslp = slp;
+       }
+    }
+    /* If we found the session, free all data associated with it */
+    if (slp){
+       if (slp->session->community != NULL)
+           free((char *)slp->session->community);
+       if(slp->session->peername != NULL)
+           free((char *)slp->session->peername);
+       free((char *)slp->session);
+       if (slp->internal->sd != -1)
+           close(slp->internal->sd);
+       free_request_list(slp->internal->requests);
+       free((char *)slp->internal);
+       free((char *)slp);
+    } else {
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    return 1;
+}
+
+/*
+ * Takes a session and a pdu and serializes the ASN PDU into the area
+ * pointed to by packet.  out_length is the size of the data area available.
+ * Returns the length of the completed packet in out_length.  If any errors
+ * occur, -1 is returned.  If all goes well, 0 is returned.
+ */
+int
+snmp_build(session, pdu, packet, out_length, is_agent)
+    struct snmp_session        *session;
+    struct snmp_pdu    *pdu;
+    u_char     *packet;
+    int                        *out_length;
+    int                         is_agent;
+{
+    u_char  buf[PACKET_LENGTH];
+    u_char  *cp;
+    struct variable_list *vp;
+    int            length;
+    int            totallength;
+
+    length = *out_length;
+    cp = packet;
+    for(vp = pdu->variables; vp; vp = vp->next_variable){
+       cp = snmp_build_var_op(cp, vp->name, &vp->name_length, vp->type, vp->val_len, (u_char *)vp->val.string, &length);
+       if (cp == NULL)
+           return -1;
+    }
+    totallength = cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR), totallength);
+    if (cp == NULL)
+       return -1;
+    bcopy((char *)packet, (char *)cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+    if (pdu->command != TRP_REQ_MSG){
+       /* request id */
+       cp = asn_build_int(packet, &length,
+           (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+           (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (cp == NULL)
+           return -1;
+       /* error status */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (cp == NULL)
+           return -1;
+       /* error index */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (cp == NULL)
+           return -1;
+    } else {   /* this is a trap message */
+       /* enterprise */
+       cp = asn_build_objid(packet, &length,
+           (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID),
+           (oid *)pdu->enterprise, pdu->enterprise_length);
+       if (cp == NULL)
+           return -1;
+       /* agent-addr */
+       cp = asn_build_string(cp, &length, (u_char)IPADDRESS,
+               (u_char *)&pdu->agent_addr.sin_addr.s_addr, sizeof(pdu->agent_addr.sin_addr.s_addr));
+       if (cp == NULL)
+           return -1;
+       /* generic trap */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (cp == NULL)
+           return -1;
+       /* specific trap */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (cp == NULL)
+           return -1;
+       /* timestamp  */
+       cp = asn_build_int(cp, &length, (u_char)TIMETICKS,
+               (long *)&pdu->time, sizeof(pdu->time));
+       if (cp == NULL)
+           return -1;
+    }
+    if (length < totallength)
+       return -1;
+    bcopy((char *)buf, (char *)cp, totallength);
+    totallength += cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char)pdu->command, totallength);
+    if (cp == NULL)
+       return -1;
+    if (length < totallength)
+       return -1;
+    bcopy((char *)packet, (char *)cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+
+    cp = snmp_auth_build( packet, &length, session, is_agent, totallength );
+    if (cp == NULL)
+       return -1;
+    if ((*out_length - (cp - packet)) < totallength)
+       return -1;
+    bcopy((char *)buf, (char *)cp, totallength);
+    totallength += cp - packet;
+    *out_length = totallength;
+
+    if( session->qoS & USEC_QOS_AUTH )
+           md5Digest( packet, totallength, cp - (session->contextLen + 16),
+               cp - (session->contextLen + 16) );
+
+    return 0;
+}
+
+/*
+ * Parses the packet received on the input session, and places the data into
+ * the input pdu.  length is the length of the input packet.  If any errors
+ * are encountered, -1 is returned.  Otherwise, a 0 is returned.
+ */
+static int
+snmp_parse(session, pdu, data, length)
+    struct snmp_session *session;
+    struct snmp_pdu *pdu;
+    u_char  *data;
+    int            length;
+{
+    u_char  msg_type;
+    u_char  type;
+    u_char  *var_val;
+    long    version;
+    int            len, four;
+    u_char community[256];
+    int community_length = 256;
+    struct variable_list *vp = 0;
+    oid            objid[MAX_NAME_LEN], *op;
+    u_char  *origdata = data;
+    int      origlength = length;
+    int      ret = 0;
+    u_char  *save_data;
+
+    /* authenticates message and returns length if valid */
+    data = snmp_auth_parse(data, &length, community, &community_length, &version);
+    if (data == NULL)
+       return -1;
+
+   if( version != SNMP_VERSION_1 && version != SNMP_VERSION_2C && version != SNMP_VERSION_2 ) {
+           fprintf(stderr, "Wrong version: %ld\n", version);
+           return -1;
+    }
+
+    save_data = data;
+
+    data = asn_parse_header(data, &length, &msg_type);
+    if (data == NULL)
+       return -1;
+    pdu->command = msg_type;
+
+    if( session->authenticator ) {
+       ret = session->authenticator( origdata, origlength, save_data - community_length, 
+               community_length, session, pdu );
+       if( ret < 0 ) return ret;
+    }
+
+    if (pdu->command != TRP_REQ_MSG){
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (data == NULL)
+           return -1;
+    } else {
+       pdu->enterprise_length = MAX_NAME_LEN;
+       data = asn_parse_objid(data, &length, &type, objid, &pdu->enterprise_length);
+       if (data == NULL)
+           return -1;
+       pdu->enterprise = (oid *)calloc(1, pdu->enterprise_length * sizeof(oid));
+       bcopy((char *)objid, (char *)pdu->enterprise, pdu->enterprise_length * sizeof(oid));
+
+       four = 4;
+       data = asn_parse_string(data, &length, &type, (u_char *)&pdu->agent_addr.sin_addr.s_addr, &four);
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->time, sizeof(pdu->time));
+       if (data == NULL)
+           return -1;
+    }
+    data = asn_parse_header(data, &length, &type);
+    if (data == NULL)
+       return -1;
+    if (type != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR))
+       return -1;
+    while((int)length > 0){
+       if (pdu->variables == NULL){
+           pdu->variables = vp = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+       } else {
+           vp->next_variable = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+           vp = vp->next_variable;
+       }
+       vp->next_variable = NULL;
+       vp->val.string = NULL;
+       vp->name = NULL;
+       vp->name_length = MAX_NAME_LEN;
+       data = snmp_parse_var_op(data, objid, &vp->name_length, &vp->type, &vp->val_len, &var_val, (int *)&length);
+       if (data == NULL)
+           return -1;
+       op = (oid *)calloc(1, (unsigned)vp->name_length * sizeof(oid));
+       bcopy((char *)objid, (char *)op, vp->name_length * sizeof(oid));
+       vp->name = op;
+
+       len = PACKET_LENGTH;
+       switch((short)vp->type){
+           case ASN_INTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(long));
+               vp->val_len = sizeof(long);
+               asn_parse_int(var_val, &len, &vp->type, (long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER:
+           case GAUGE:
+           case TIMETICKS:
+           case UINTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(unsigned long));
+               vp->val_len = sizeof(unsigned long);
+               asn_parse_unsigned_int(var_val, &len, &vp->type, (unsigned long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER64:
+               vp->val.counter64 = (struct counter64 *)calloc(1,  sizeof(struct counter64) );
+               vp->val_len = sizeof(struct counter64);
+               asn_parse_unsigned_int64(var_val, &len, &vp->type,
+                                        (struct counter64 *)vp->val.counter64,
+                                        sizeof(*vp->val.counter64));
+               break;
+           case ASN_OCTET_STR:
+           case IPADDRESS:
+           case OPAQUE:
+           case NSAP:
+               vp->val.string = (u_char *)calloc(1, (unsigned)vp->val_len);
+               asn_parse_string(var_val, &len, &vp->type, vp->val.string, &vp->val_len);
+               break;
+           case ASN_OBJECT_ID:
+               vp->val_len = MAX_NAME_LEN;
+               asn_parse_objid(var_val, &len, &vp->type, objid, &vp->val_len);
+               vp->val_len *= sizeof(oid);
+               vp->val.objid = (oid *)calloc(1, (unsigned)vp->val_len);
+               bcopy((char *)objid, (char *)vp->val.objid, vp->val_len);
+               break;
+            case SNMP_NOSUCHOBJECT:
+            case SNMP_NOSUCHINSTANCE:
+            case SNMP_ENDOFMIBVIEW:
+           case ASN_NULL:
+               break;
+           default:
+               fprintf(stderr, "bad type returned (%x)\n", vp->type);
+               break;
+       }
+    }
+    return ret;
+}
+
+/*
+ * 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(session, pdu)
+    struct snmp_session *session;
+    struct snmp_pdu    *pdu;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp = NULL;
+    u_char  packet[PACKET_LENGTH];
+    int length = PACKET_LENGTH;
+    struct request_list *rp;
+    struct timeval tv;
+
+    for(slp = Sessions; slp; slp = slp->next){
+       if (slp->session == session){
+           isp = slp->internal;
+           break;
+       }
+    }
+
+    if (! pdu) {
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+
+    if (isp == NULL){
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG
+       || pdu->command == GET_RSP_MSG || pdu->command == SET_REQ_MSG 
+       || pdu->command == GETBULK_REQ_MSG ){
+       if (pdu->reqid == SNMP_DEFAULT_REQID)
+           pdu->reqid = ++Reqid;
+       if (pdu->errstat == SNMP_DEFAULT_ERRSTAT)
+           pdu->errstat = 0;
+       if (pdu->errindex == SNMP_DEFAULT_ERRINDEX)
+           pdu->errindex = 0;
+    } else {
+       /* fill in trap defaults */
+       pdu->reqid = 1; /* give a bogus non-error reqid for traps */
+       if (pdu->enterprise_length == SNMP_DEFAULT_ENTERPRISE_LENGTH){
+           pdu->enterprise = (oid *)calloc(1, sizeof(DEFAULT_ENTERPRISE));
+           bcopy((char *)DEFAULT_ENTERPRISE, (char *)pdu->enterprise, sizeof(DEFAULT_ENTERPRISE));
+           pdu->enterprise_length = sizeof(DEFAULT_ENTERPRISE)/sizeof(oid);
+       }
+       if (pdu->time == SNMP_DEFAULT_TIME)
+           pdu->time = DEFAULT_TIME;
+    }
+    if (pdu->address.sin_addr.s_addr == SNMP_DEFAULT_ADDRESS){
+       if (isp->addr.sin_addr.s_addr != SNMP_DEFAULT_ADDRESS){
+           bcopy((char *)&isp->addr, (char *)&pdu->address, sizeof(pdu->address));
+       } else {
+           fprintf(stderr, "No remote IP address specified\n");
+           snmp_errno = SNMPERR_BAD_ADDRESS;
+           return 0;
+       }
+    }
+       
+
+    if (snmp_build(session, pdu, packet, &length, 0) < 0){
+       fprintf(stderr, "Error building packet\n");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+#if 1 /***/
+    if (snmp_dump_packet){
+      snmp_print_packet(packet, length, pdu->address, 1);
+    }
+#endif /***/
+
+    gettimeofday(&tv, (struct timezone *)0);
+    if (sendto(isp->sd, (char *)packet, length, 0, (struct sockaddr *)&pdu->address, sizeof(pdu->address)) < 0){
+       perror("sendto");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG 
+     || pdu->command == SET_REQ_MSG || pdu->command == GETBULK_REQ_MSG ){
+       /* set up to expect a response */
+       rp = (struct request_list *)calloc(1, sizeof(struct request_list));
+#if 1 /***/
+           if (!rp) {
+           fprintf(stderr, "Out of memory!\n");
+           snmp_errno = SNMPERR_GENERR;
+           return 0;
+       }
+#endif/***/ if we found entry that points here */
+ oslp e key!  replace...
+     */
+ * \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 1\ 1\0\0\0\0\0\0\0\19\7fÿ¯ùsnmplib/snmp_api.c\0c\0\0.h\0\0\0\18\7fÿ°\85\10\0<Ðlib/snmp_api.c~\0~\0\0ñ\0\0\0\18\7fÿ±\1e\10\0\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\0\0\0\18\7fÿ±«\10\0=\10\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\0\0\0\18\7fÿ²\1d\10\0=0\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\0\0\0\18\7fÿ²\8a\10\0=P\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\0\0\0\18\7fÿ³
+\10\0=p\7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\0\0\0\18\7fÿ³\82\0\0\0\ 1\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\0\0\0Á\7fÿ³ù\0\0\0\10\7fÿ´\10\10\0\0%\0\19\0\15\0\0\10\0D(\0\0\0\10\7fÿ´_\10\0\0\0\ 2\\0\0\0\0\10\0\0\0\0\10\7fÿ´©\10\0=\98\0\0\ 24\0\0\0\0\10\0\0\0\0\10\7fÿ´ø\10\0\0\0\ 2H\0\0\0\0\10\0\0\0\0\10\7fÿµB\10\0>\10\7fÿµ]\7fÿµm\7fÿµz\0\0\0\10\7fÿµ \10\0>(\7fÿµ·\7fÿµÉ\7fÿµÖ\0\0\0\10\7fÿµï\10\0>@\7fÿ¶\12\7fÿ¶ \7fÿ¶4\0\0\0\10\7fÿ¶P\0\0\0\ 1\7fÿ¶r\7fÿ¶~\7fÿ¶\88\0\0\00\7fÿ¶\9f\0\0\0\0\7fÿ¶·\0\0\0\0\7fÿ¶Ù\10\0\82à\7fÿ·\ 1\0\0\0\0\7fÿ·#\7fÿ·/\7fÿ·>\10\0>X\7fÿ·V\0\0\03\0\0\0\0/usr/people/wessels/.indent.pro\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\ 1\0\0\0\0\7fÿ¯è\7fÿ¯ù\7fÿ°\f\7fÿ°\e\7fÿ°.\7fÿ°?\7fÿ°M\7fÿ°[\7fÿ°p\7fÿ°\85\7fÿ°\95\7fÿ°£\7fÿ°²\7fÿ°Å\7fÿ°Û\7fÿ°ñ\7fÿ±
+\7fÿ±\1e\7fÿ±2\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\7fÿ±\99\7fÿ±«\7fÿ±º\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\7fÿ²\ f\7fÿ²\1d\7fÿ²2\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\7fÿ²\7f\7fÿ²\8a\7fÿ²\99\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\7fÿ²ö\7fÿ³
+\7fÿ³ \7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\7fÿ³s\7fÿ³\82\7fÿ³\91\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\7fÿ³ç\7fÿ³ù\7fÿ´\ 4\7fÿ´\10\7fÿ´\1e\7fÿ´)\7fÿ´3\7fÿ´C\7fÿ´O\7fÿ´_\7fÿ´k\7fÿ´t\7fÿ´\81\7fÿ´\8f\7fÿ´\9f\7fÿ´©\7fÿ´·\7fÿ´Å\7fÿ´Ò\7fÿ´Ý\7fÿ´í\7fÿ´ø\7fÿµ\ 3\7fÿµ\10\7fÿµ\1d\7fÿµ)\7fÿµ7\7fÿµB\7fÿµM\7fÿµ]\7fÿµm\7fÿµz\7fÿµ\89\7fÿµ \7fÿµ«\7fÿµ·\7fÿµÉ\7fÿµÖ\7fÿµâ\7fÿµï\7fÿ¶\ 3\7fÿ¶\12\7fÿ¶ \7fÿ¶4\7fÿ¶?\7fÿ¶P\7fÿ¶b\7fÿ¶r\7fÿ¶~\7fÿ¶\88\7fÿ¶\94\7fÿ¶\9f\7fÿ¶«\7fÿ¶·\7fÿ¶É\7fÿ¶Ù\7fÿ¶í\7fÿ·\ 1\7fÿ·\15\7fÿ·#\7fÿ·/\7fÿ·>\7fÿ·L\7fÿ·V\7fÿ·f\7fÿ·q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0@    \0\0\0\0e SNMP_ENDOFMIBVIEW:
+           case ASN_NULL:
+               break;
+           default:
+               fprintf(stderr, "bad type returned (%x)\n", vp->type);
+               break;
+       }
+    }
+    return ret;
+}
+
+/*
+ * 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(session, pdu)
+    struct snmp_session *session;
+    struct snmp_pdu    *pdu;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp = NULL;
+    u_char  packet[PACKET_LENGTH];
+    int length = PACKET_LENGTH;
+    struct request_list *rp;
+    struct timeval tv;
+
+    for(slp = Sessions; slp; slp = slp->next){
+       if (slp->session == session){
+           isp = slp->internal;
+           break;
+       }
+    }
+
+    if (! pdu) {
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+
+    if (isp == NULL){
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG
+       || pdu->command == GET_RSP_MSG || pdu->command == SET_REQ_MSG 
+       || pdu->command == GETBULK_REQ_MSG ){
+       if (pdu->reqid == SNMP_DEFAULT_REQID)
+           pdu->reqid = ++Reqid;
+       if (pdu->errstat == SNMP_DEFAULT_ERRSTAT)
+           pdu->errstat = 0;
+       if (pdu->errindex == SNMP_DEFAULT_ERRINDEX)
+           pdu->errindex = 0;
+    } else {
+       /* fill in trap defaults */
+       pdu->reqid = 1; /* give a bogus non-error reqid for traps */
+       if (pdu->enterprise_length == SNMP_DEFAULT_ENTERPRISE_LENGTH){
+           pdu->enterprise = (oid *)calloc(1, sizeof(DEFAULT_ENTERPRISE));
+           bcopy((char *)DEFAULT_ENTERPRISE, (char *)pdu->enterprise, sizeof(DEFAULT_ENTERPRISE));
+           pdu->enterprise_length = sizeof(DEFAULT_ENTERPRISE)/sizeof(oid);
+       }
+       if (pdu->time == SNMP_DEFAULT_TIME)
+           pdu->time = DEFAULT_TIME;
+    }
+    if (pdu->address.sin_addr.s_addr == SNMP_DEFAULT_ADDRESS){
+       if (isp->addr.sin_addr.s_addr != SNMP_DEFAULT_ADDRESS){
+           bcopy((char *)&isp->addr, (char *)&pdu->address, sizeof(pdu->address));
+       } else {
+           fprintf(stderr, "No remote IP address specified\n");
+           snmp_errno = SNMPERR_BAD_ADDRESS;
+           return 0;
+       }
+    }
+       
+
+    if (snmp_build(session, pdu, packet, &length, 0) < 0){
+       fprintf(stderr, "Error building packet\n");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+#if 1 /***/
+    if (snmp_dump_packet){
+      snmp_print_packet(packet, length, pdu->address, 1);
+    }
+#endif /***/
+
+    gettimeofday(&tv, (struct timezone *)0);
+    if (sendto(isp->sd, (char *)packet, length, 0, (struct sockaddr *)&pdu->address, sizeof(pdu->address)) < 0){
+       perror("sendto");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG 
+     || pdu->command == SET_REQ_MSG || pdu->command == GETBULK_REQ_MSG ){
+       /* set up to expect a response */
+       rp = (struct request_list *)calloc(1, sizeof(struct request_list));
+#if 1 /***/
+           if (!rp) {
+           fprintf(stderr, "Out of memory!\n");
+           snmp_errno = SNMPERR_GENERR;
+           return 0;
+       }
+ULL){
+               fprintf(stderr, "unknown host: %s\n", session->peername);
+               snmp_errno = SNMPERR_BAD_ADDRESS;
+               if (!snmp_close(session)){
+                   fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+                   exit(2);
+               }
+               return 0;
+           } else {
+               bcopy((char *)hp->h_addr, (char *)&isp->addr.sin_addr, hp->h_length);
+           }
+       }
+       isp->addr.sin_family = AF_INET;
+       if (session->remote_port == SNMP_DEFAULT_REMPORT){
+           /*servp = getservbyname("snmp", "udp");*/
+           servp=NULL;
+           if (servp != NULL){
+               isp->addr.sin_port = servp->s_port;
+           } else {
+               isp->addr.sin_port = htons(SNMP_PORT);
+           }
+       } else {
+           isp->addr.sin_port = htons(session->remote_port);
+       }
+    } else {
+       isp->addr.sin_addr.s_addr = SNMP_DEFAULT_ADDRESS;
+    }
+
+    me.sin_family = AF_INET;
+    me.sin_addr.s_addr = INADDR_ANY;
+    me.sin_port = htons(session->local_port);
+    if (bind(sd, (struct sockaddr *)&me, sizeof(me)) != 0){
+       perror("bind");
+       snmp_errno = SNMPERR_BAD_LOCPORT;
+       if (! snmp_close(session)){
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n", 
+                   api_errstring(snmp_errno));
+           exit(3);
+       }
+       return 0;
+    }
+
+    if( *cp == '/' ) {
+       session->authenticator = check_received_pkt;
+       sync_with_agent(session);
+       parse_app_community_string( session );
+       session->qoS |= USEC_QOS_GENREPORT;
+    }
+
+    /* replace comm pointer with pointer to new data: */
+    session->community = cp;   
+
+    return session;
+}
+
+void
+sync_with_agent( session )
+struct snmp_session *session;
+{
+    struct snmp_pdu *pdu, *response = 0;
+    int status;
+
+    session->qoS = USEC_QOS_GENREPORT;
+    session->userLen = 6;
+    session->version = SNMP_VERSION_2;
+    strcpy( session->userName, "public" );
+
+    snmp_synch_setup(session);
+    pdu = snmp_pdu_create(GET_REQ_MSG);
+    status = snmp_synch_response(session, pdu, &response);
+
+    if (status == STAT_SUCCESS){
+       memcpy( session->agentID, response->params.agentID, 12 );
+
+       /* save the clocks -- even though they are not authentic */
+       session->agentBoots = response->params.agentBoots;
+       session->agentTime = response->params.agentTime;
+       session->agentClock = response->params.agentTime - time(NULL);
+
+    } else {
+           if (status == STAT_TIMEOUT){
+               printf("No Response from %s\n", session->peername);
+           } else {    /* status == STAT_ERROR */
+               printf("An error occurred, Quitting\n");
+           }
+           exit( -1 );
+    }
+
+    /** freed to early: 
+      snmp_free_pdu(pdu);
+      if (response) snmp_free_pdu(response);
+     **/
+}
+#if 1 /***/
+/*
+ * Unlink one element from input request list,
+ * then free it and it's pdu.
+ */
+static void
+free_one_request(isp, orp)
+    struct snmp_internal_session *isp;
+    struct request_list *orp;
+{
+    struct request_list *rp;
+    if(! orp) return;
+    if(isp->requests == orp){ 
+      isp->requests = orp->next_request; /* unlink head */
+    }
+    else{
+      for(rp = isp->requests; rp; rp = rp->next_request){
+        if(rp->next_request == orp){ 
+         rp->next_request = orp->next_request; /* unlink element */
+         break;
+        }
+      }
+    }
+    if (orp->pdu != NULL){
+      snmp_free_pdu(orp->pdu);
+    }
+    free((char *)orp);
+}
+#endif /***/
+/*
+ * Free each element in the input request list.
+ */
+static void
+free_request_list(rp)
+    struct request_list *rp;
+{
+    struct request_list *orp;
+
+    while(rp){
+       orp = rp;
+       rp = rp->next_request;
+       if (orp->pdu != NULL)
+           snmp_free_pdu(orp->pdu);
+       free((char *)orp);
+    }
+}
+
+/*
+ * 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.
+ */
+int 
+snmp_close(session)
+    struct snmp_session *session;
+{
+    struct session_list *slp = NULL, *oslp = NULL;
+
+    if (Sessions->session == session){ /* If first entry */
+       slp = Sessions;
+       Sessions = slp->next;
+    } else {
+       for(slp = Sessions; slp; slp = slp->next){
+           if (slp->session == session){
+               if (oslp)   /* if we found entry that points here */
+                   oslp->next = slp->next;     /* link around this entry */
+               break;
+           }
+           oslp = slp;
+       }
+    }
+    /* If we found the session, free all data associated with it */
+    if (slp){
+       if (slp->session->community != NULL)
+           free((char *)slp->session->community);
+       if(slp->session->peername != NULL)
+           free((char *)slp->session->peername);
+       free((char *)slp->session);
+       if (slp->internal->sd != -1)
+           close(slp->internal->sd);
+       free_request_list(slp->internal->requests);
+       free((char *)slp->internal);
+       free((char *)slp);
+    } else {
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    return 1;
+}
+
+/*
+ * Takes a session and a pdu and serializes the ASN PDU into the area
+ * pointed to by packet.  out_length is the size of the data area available.
+ * Returns the length of the completed packet in out_length.  If any errors
+ * occur, -1 is returned.  If all goes well, 0 is returned.
+ */
+int
+snmp_build(session, pdu, packet, out_length, is_agent)
+    struct snmp_session        *session;
+    struct snmp_pdu    *pdu;
+    u_char     *packet;
+    int                        *out_length;
+    int                         is_agent;
+{
+    u_char  buf[PACKET_LENGTH];
+    u_char  *cp;
+    struct variable_list *vp;
+    int            length;
+    int            totallength;
+
+    length = *out_length;
+    cp = packet;
+    for(vp = pdu->variables; vp; vp = vp->next_variable){
+       cp = snmp_build_var_op(cp, vp->name, &vp->name_length, vp->type, vp->val_len, (u_char *)vp->val.string, &length);
+       if (cp == NULL)
+           return -1;
+    }
+    totallength = cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR), totallength);
+    if (cp == NULL)
+       return -1;
+    bcopy((char *)packet, (char *)cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+    if (pdu->command != TRP_REQ_MSG){
+       /* request id */
+       cp = asn_build_int(packet, &length,
+           (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+           (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (cp == NULL)
+           return -1;
+       /* error status */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (cp == NULL)
+           return -1;
+       /* error index */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (cp == NULL)
+           return -1;
+    } else {   /* this is a trap message */
+       /* enterprise */
+       cp = asn_build_objid(packet, &length,
+           (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID),
+           (oid *)pdu->enterprise, pdu->enterprise_length);
+       if (cp == NULL)
+           return -1;
+       /* agent-addr */
+       cp = asn_build_string(cp, &length, (u_char)IPADDRESS,
+               (u_char *)&pdu->agent_addr.sin_addr.s_addr, sizeof(pdu->agent_addr.sin_addr.s_addr));
+       if (cp == NULL)
+           return -1;
+       /* generic trap */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (cp == NULL)
+           return -1;
+       /* specific trap */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (cp == NULL)
+           return -1;
+       /* timestamp  */
+       cp = asn_build_int(cp, &length, (u_char)TIMETICKS,
+               (long *)&pdu->time, sizeof(pdu->time));
+       if (cp == NULL)
+           return -1;
+    }
+    if (length < totallength)
+       return -1;
+    bcopy((char *)buf, (char *)cp, totallength);
+    totallength += cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char)pdu->command, totallength);
+    if (cp == NULL)
+       return -1;
+    if (length < totallength)
+       return -1;
+    bcopy((char *)packet, (char *)cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+
+    cp = snmp_auth_build( packet, &length, session, is_agent, totallength );
+    if (cp == NULL)
+       return -1;
+    if ((*out_length - (cp - packet)) < totallength)
+       return -1;
+    bcopy((char *)buf, (char *)cp, totallength);
+    totallength += cp - packet;
+    *out_length = totallength;
+
+    if( session->qoS & USEC_QOS_AUTH )
+           md5Digest( packet, totallength, cp - (session->contextLen + 16),
+               cp - (session->contextLen + 16) );
+
+    return 0;
+}
+
+/*
+ * Parses the packet received on the input session, and places the data into
+ * the input pdu.  length is the length of the input packet.  If any errors
+ * are encountered, -1 is returned.  Otherwise, a 0 is returned.
+ */
+static int
+snmp_parse(session, pdu, data, length)
+    struct snmp_session *session;
+    struct snmp_pdu *pdu;
+    u_char  *data;
+    int            length;
+{
+    u_char  msg_type;
+    u_char  type;
+    u_char  *var_val;
+    long    version;
+    int            len, four;
+    u_char community[256];
+    int community_length = 256;
+    struct variable_list *vp = 0;
+    oid            objid[MAX_NAME_LEN], *op;
+    u_char  *origdata = data;
+    int      origlength = length;
+    int      ret = 0;
+    u_char  *save_data;
+
+    /* authenticates message and returns length if valid */
+    data = snmp_auth_parse(data, &length, community, &community_length, &version);
+    if (data == NULL)
+       return -1;
+
+   if( version != SNMP_VERSION_1 && version != SNMP_VERSION_2C && version != SNMP_VERSION_2 ) {
+           fprintf(stderr, "Wrong version: %ld\n", version);
+           return -1;
+    }
+
+    save_data = data;
+
+    data = asn_parse_header(data, &length, &msg_type);
+    if (data == NULL)
+       return -1;
+    pdu->command = msg_type;
+
+    if( session->authenticator ) {
+       ret = session->authenticator( origdata, origlength, save_data - community_length, 
+               community_length, session, pdu );
+       if( ret < 0 ) return ret;
+    }
+
+    if (pdu->command != TRP_REQ_MSG){
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (data == NULL)
+           return -1;
+    } else {
+       pdu->enterprise_length = MAX_NAME_LEN;
+       data = asn_parse_objid(data, &length, &type, objid, &pdu->enterprise_length);
+       if (data == NULL)
+           return -1;
+       pdu->enterprise = (oid *)calloc(1, pdu->enterprise_length * sizeof(oid));
+       bcopy((char *)objid, (char *)pdu->enterprise, pdu->enterprise_length * sizeof(oid));
+
+       four = 4;
+       data = asn_parse_string(data, &length, &type, (u_char *)&pdu->agent_addr.sin_addr.s_addr, &four);
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->time, sizeof(pdu->time));
+       if (data == NULL)
+           return -1;
+    }
+    data = asn_parse_header(data, &length, &type);
+    if (data == NULL)
+       return -1;
+    if (type != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR))
+       return -1;
+    while((int)length > 0){
+       if (pdu->variables == NULL){
+           pdu->variables = vp = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+       } else {
+           vp->next_variable = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+           vp = vp->next_variable;
+       }
+       vp->next_variable = NULL;
+       vp->val.string = NULL;
+       vp->name = NULL;
+       vp->name_length = MAX_NAME_LEN;
+       data = snmp_parse_var_op(data, objid, &vp->name_length, &vp->type, &vp->val_len, &var_val, (int *)&length);
+       if (data == NULL)
+           return -1;
+       op = (oid *)calloc(1, (unsigned)vp->name_length * sizeof(oid));
+       bcopy((char *)objid, (char *)op, vp->name_length * sizeof(oid));
+       vp->name = op;
+
+       len = PACKET_LENGTH;
+       switch((short)vp->type){
+           case ASN_INTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(long));
+               vp->val_len = sizeof(long);
+               asn_parse_int(var_val, &len, &vp->type, (long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER:
+           case GAUGE:
+           case TIMETICKS:
+           case UINTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(unsigned long));
+               vp->val_len = sizeof(unsigned long);
+               asn_parse_unsigned_int(var_val, &len, &vp->type, (unsigned long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER64:
+               vp->val.counter64 = (struct counter64 *)calloc(1,  sizeof(struct counter64) );
+               vp->val_len = sizeof(struct counter64);
+               asn_parse_unsigned_int64(var_val, &len, &vp->type,
+                                        (struct counter64 *)vp->val.counter64,
+                                        sizeof(*vp->val.counter64));
+               break;
+           case ASN_OCTET_STR:
+           case IPADDRESS:
+           case OPAQUE:
+           case NSAP:
+               vp->val.string = (u_char *)calloc(1, (unsigned)vp->val_len);
+               asn_parse_string(var_val, &len, &vp->type, vp->val.string, &vp->val_len);
+               break;
+           case ASN_OBJECT_ID:
+               vp->val_len = MAX_NAME_LEN;
+               asn_parse_objid(var_val, &len, &vp->type, objid, &vp->val_len);
+               vp->val_len *= sizeof(oid);
+               vp->val.objid = (oid *)calloc(1, (unsigned)vp->val_len);
+               bcopy((char *)objid, (char *)vp->val.objid, vp->val_len);
+               break;
+            case SNMP_NOSUCHOBJECT:
+            case SNMP_NOSUCHINSTANCE:
+            cas\10\0BÐ+= m\0\0
+È      /* \10\0>X*/ B\10\04¨NMPT\10\ 1˰ */c\0\0\0\0for testing purposes */e key!  replace...
+     */
+ * \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 1\ 1\0\0\0\0\0\0\0\19\7fÿ¯ùsnmplib/snmp_api.c\0c\0\0.h\0\0\0\18\7fÿ°\85\10\0<Ðlib/snmp_api.c~\0~\0\0ñ\0\0\0\18\7fÿ±\1e\10\0\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\0\0\0\18\7fÿ±«\10\0=\10\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\0\0\0\18\7fÿ²\1d\10\0=0\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\0\0\0\18\7fÿ²\8a\10\0=P\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\0\0\0\18\7fÿ³
+\10\0=p\7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\0\0\0\18\7fÿ³\82\0\0\0\ 1\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\0\0\0Á\7fÿ³ù\0\0\0\10\7fÿ´\10\10\0\0%\0\19\0\15\0\0\10\0D(\0\0\0\10\7fÿ´_\10\0\0\0\ 2\\0\0\0\0\10\0\0\0\0\10\7fÿ´©\10\0=\98\0\0\ 24\0\0\0\0\10\0\0\0\0\10\7fÿ´ø\10\0\0\0\ 2H\0\0\0\0\10\0\0\0\0\10\7fÿµB\10\0>\10\7fÿµ]\7fÿµm\7fÿµz\0\0\0\10\7fÿµ \10\0>(\7fÿµ·\7fÿµÉ\7fÿµÖ\0\0\0\10\7fÿµï\10\0>@\7fÿ¶\12\7fÿ¶ \7fÿ¶4\0\0\0\10\7fÿ¶P\0\0\0\ 1\7fÿ¶r\7fÿ¶~\7fÿ¶\88\0\0\00\7fÿ¶\9f\10\0\7fÿ¶·\0\0\0\0\7fÿ¶Ù\10\0\89è\7fÿ·\ 1\0\0\0\0\7fÿ·#\7fÿ·/\7fÿ·>\10\0>X\7fÿ·V\0\0\03\0\0\0\0/usr/people/wessels/.indent.pro\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\ 1\0\0\0\0\7fÿ¯è\7fÿ¯ù\7fÿ°\f\7fÿ°\e\7fÿ°.\7fÿ°?\7fÿ°M\7fÿ°[\7fÿ°p\7fÿ°\85\7fÿ°\95\7fÿ°£\7fÿ°²\7fÿ°Å\7fÿ°Û\7fÿ°ñ\7fÿ±
+\7fÿ±\1e\7fÿ±2\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\7fÿ±\99\7fÿ±«\7fÿ±º\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\7fÿ²\ f\7fÿ²\1d\7fÿ²2\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\7fÿ²\7f\7fÿ²\8a\7fÿ²\99\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\7fÿ²ö\7fÿ³
+\7fÿ³ \7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\7fÿ³s\7fÿ³\82\7fÿ³\91\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\7fÿ³ç\7fÿ³ù\7fÿ´\ 4\7fÿ´\10\7fÿ´\1e\7fÿ´)\7fÿ´3\7fÿ´C\7fÿ´O\7fÿ´_\7fÿ´k\7fÿ´t\7fÿ´\81\7fÿ´\8f\7fÿ´\9f\7fÿ´©\7fÿ´·\7fÿ´Å\7fÿ´Ò\7fÿ´Ý\7fÿ´í\7fÿ´ø\7fÿµ\ 3\7fÿµ\10\7fÿµ\1d\7fÿµ)\7fÿµ7\7fÿµB\7fÿµM\7fÿµ]\7fÿµm\7fÿµz\7fÿµ\89\7fÿµ \7fÿµ«\7fÿµ·\7fÿµÉ\7fÿµÖ\7fÿµâ\7fÿµï\7fÿ¶\ 3\7fÿ¶\12\7fÿ¶ \7fÿ¶4\7fÿ¶?\7fÿ¶P\7fÿ¶b\7fÿ¶r\7fÿ¶~\7fÿ¶\88\7fÿ¶\94\7fÿ¶\9f\7fÿ¶«\7fÿ¶·\7fÿ¶É\7fÿ¶Ù\7fÿ¶í\7fÿ·\ 1\7fÿ·\15\7fÿ·#\7fÿ·/\7fÿ·>\7fÿ·L\7fÿ·V\7fÿ·f\7fÿ·q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\0\0\0°\0\0\0\ 4\0\0\0\0\0\0\0\b\10\0>X\0\0\0\f\10\0\0\0\0\10\0\0\0\0\0\0\0\14\0\0\0\14\0\0\0\14\0\0\0\18\0\0\0\18\0\0\0\18\0\0\0\1c\0\0\0\1c\0\0\0\1c\0\0\0\1c\0\0\0 \0\0\0 \0\0\0 \0\0\0$\0\0\0\v\0\0\0\e\0\0\0\19\0\0\0\v\0\0\0\e\0\0\0@\0\0\0\0\0\0\0\0\0\0\0\0\10\0,\b\0\0\0\1a\10\02\88\0\0\0\1a\0\0\0\0\0\0\0\1a\10\0\85\b\0\0\0\0\10\0>X\0\0\0\0\0\0\0\0\0\0\0\0\10\0\82à\0\0\0\0\0\0\ 1C\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e0\0\0\0\v\0\0\0\e\0\0\0\18\0\0\0\v\0\0\0\1a\0\0\0\17\0\0\0\v\0\0\0 \0\0\0\0\10\0\8d¸ude/snmp_groupvars.h~\0\0\b\0\0\0\b\0\0\0 \0\0\0\0\10\0\8dàude/snmp_groupvars.h\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8eX\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e\80\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e¨\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8eÐ\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\0\0\0\ 1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\84©\0\0\0\0/***********************************************************
+       Copyright 1989 by Carnegie Mellon University
+
+                      All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the name of CMU not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+******************************************************************/
+/*
+ * snmp_api.c - API for access to snmp.
+ */
+#define DEBUG_SNMPTRACE                0 /* set to 1 to print all SNMP actions */
+#define DEBUG_SNMPFULLDUMP     0 /* set to 1 to dump all SNMP packets */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#ifdef linux
+#include <arpa/inet.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#endif
+
+
+#include "asn1.h"
+#include "snmp.h"
+#include "snmp_impl.h"
+#include "snmp_api.h"
+#include "snmp_client.h"
+
+#define PACKET_LENGTH  4500
+
+#ifndef BSD4_3
+#define BSD4_2
+#endif
+
+#if !defined(BSD4_3) && !defined(linux) && !defined(sun)
+
+typedef long   fd_mask;
+#define NFDBITS        (sizeof(fd_mask) * NBBY)        /* bits per mask */
+
+#define        FD_SET(n, p)    ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+#define        FD_CLR(n, p)    ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+#define        FD_ISSET(n, p)  ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+#define FD_ZERO(p)     bzero((char *)(p), sizeof(*(p)))
+#endif
+
+oid default_enterprise[] = {1, 3, 6, 1, 4, 1, 3, 1, 1}; /* enterprises.cmu.systems.cmuSNMP */
+
+#define DEFAULT_COMMUNITY   "public"
+#define DEFAULT_REMPORT            SNMP_PORT
+#define DEFAULT_ENTERPRISE  default_enterprise
+#define DEFAULT_TIME       0
+#define DEFAULT_MMS        1389 /* large, randomly picked for testing purposes */
+
+/*
+ * Internal information about the state of the snmp session.
+ */
+struct snmp_internal_session {
+    int            sd;         /* socket descriptor for this connection */
+    ipaddr  addr;      /* address of connected peer */
+    struct request_list *requests;/* Info about outstanding requests */
+};
+
+/*
+ * A list of all the outstanding requests for a particular session.
+ */
+struct request_list {
+    struct request_list *next_request;
+    u_long  request_id;        /* request id */
+    int            retries;    /* Number of retries */
+    u_long timeout;    /* length to wait for timeout */
+    struct timeval time; /* Time this request was made */
+    struct timeval expire;  /* time this request is due to expire */
+    struct snmp_pdu *pdu;   /* The pdu for this request (saved so it can be retransmitted */
+};
+
+/*
+ * The list of active/open sessions.
+ */
+struct session_list {
+    struct session_list *next;
+    struct snmp_session *session;
+    struct snmp_internal_session *internal;
+};
+
+struct session_list *Sessions = NULL;
+
+u_long Reqid = 0;
+int snmp_errno = 0;
+
+char *api_errors[4] = {
+    "Unknown session",
+    "Unknown host",
+    "Invalid local port",
+    "Unknown Error"
+};
+
+
+void sync_with_agent();
+int parse_app_community_string();
+void snmp_synch_setup();
+int snmp_synch_response();
+void md5Digest();
+
+
+static char *
+api_errstring(snmp_errnumber)
+    int        snmp_errnumber;
+{
+    if (snmp_errnumber <= SNMPERR_BAD_SESSION && snmp_errnumber >= SNMPERR_GENERR){
+       return api_errors[snmp_errnumber + 4];
+    } else {
+       return "Unknown Error";
+    }
+}
+
+#if 0
+/*
+ * Gets initial request ID for all transactions.
+ */
+static void
+init_snmp(){
+    struct timeval tv;
+
+    gettimeofday(&tv, (struct timezone *)0);
+    srandom(tv.tv_sec ^ tv.tv_usec);
+    Reqid = random();
+}
+#endif
+
+
+/*
+ * Dump snmp packet to stdout:
+ */
+static void
+snmp_print_packet(packet, length, addr, code)
+  char *packet; 
+  int length; 
+  ipaddr addr; 
+  int code;
+{
+  if(length < 0) {
+    return;
+  }
+  if (code <= 0) { /* received */
+    printf("\nReceived %4d bytes from ", length);
+  }
+  else { /* sending */
+    printf("\nSending  %4d bytes to   ", length);
+  }
+  printf("%s:", inet_ntoa(addr.sin_addr));
+#if DEBUG_SNMPFULLDUMP
+  for (count = 0; count < length; count++) {
+    if ((count & 15) == 0) {
+      printf("\n  ");
+    }
+    printf("%02X ", (int)(packet[count]&255));
+  }
+#endif
+  fflush(stdout);
+}
+
+#if DEBUG_SNMPTRACE
+/*
+ * Print request
+ */
+#define TRACE_SEND   (0)
+#define TRACE_RECV   (1)
+#define TRACE_TIMEOUT (2)
+static void
+snmp_print_trace(slp, rp, code)
+  struct session_list *slp;
+  struct request_list *rp;
+  int code;
+{
+  int reqid=0, retries=1;
+  if( rp ){
+    reqid = rp->request_id;
+    retries = rp->retries;
+  }  
+  printf("\n Session %2d  ReqId %4d  ", slp->internal->sd, reqid);
+  switch(code)
+    { 
+    case TRACE_SEND:    printf("send pdu (%d)", retries);break; 
+    case TRACE_RECV:    printf("recv pdu");break; 
+    case TRACE_TIMEOUT: printf("time out");break; 
+    }
+  fflush(stdout);
+}
+#endif /* DEBUG_SNMPTRACE */
+
+
+
+
+/*
+ * 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.
+ */
+struct snmp_session *
+snmp_open(session)
+    struct snmp_session *session;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp;
+    u_char *cp;
+    int sd;
+    u_long addr;
+    struct sockaddr_in me;
+    struct hostent *hp;
+    struct servent *servp;
+    extern int check_received_pkt();
+
+    /* Copy session structure and link into list */
+    slp = (struct session_list *)calloc(1, sizeof(struct session_list));
+    slp->internal = isp = (struct snmp_internal_session *)calloc(1, sizeof(struct snmp_internal_session));
+    bzero((char *)isp, sizeof(struct snmp_internal_session));
+    slp->internal->sd = -1; /* mark it not set */
+    slp->session = (struct snmp_session *)calloc(1, sizeof(struct snmp_session));
+    bcopy((char *)session, (char *)slp->session, sizeof(struct snmp_session));
+    session = slp->session;
+    /* now link it in. */
+    slp->next = Sessions;
+    Sessions = slp;
+
+    /*
+     * session now points to the new structure that still contains pointers to
+     * data allocated elsewhere.  Some of this data is copied to space malloc'd
+     * here, and the pointer replaced with the new one.
+     */
+
+    if (session->peername != NULL){
+       cp = (u_char *)calloc(1, (unsigned)strlen(session->peername) + 1);
+       strcpy((char *)cp, session->peername);
+       session->peername = (char *)cp;
+    }
+
+    if (session->retries == SNMP_DEFAULT_RETRIES)
+       session->retries = SNMP_API_DEFAULT_RETRIES;
+    if (session->timeout == SNMP_DEFAULT_TIMEOUT)
+       session->timeout = SNMP_API_DEFAULT_TIMEOUT;
+    if (session->MMS == 0 )
+       session->MMS = DEFAULT_MMS;
+    isp->requests = NULL;
+
+
+    /* Fill in defaults if necessary */
+    if (session->community_len != SNMP_DEFAULT_COMMUNITY_LEN){
+       if( *session->community == '+' ) {
+               session->community_len--;
+               cp = (u_char *) calloc(1, (unsigned) session->community_len);
+               bcopy((char *) session->community+1, (char *)cp,
+                     session->community_len);
+               session->version = SNMP_VERSION_2C;
+       } else {
+               cp = (u_char *) calloc(1, (unsigned) session->community_len);
+               bcopy((char *) session->community, (char *) cp, 
+                     session->community_len);
+       }
+
+    } else {
+       session->community_len = strlen(DEFAULT_COMMUNITY);
+       cp = (u_char *)calloc(1, (unsigned)session->community_len);
+       bcopy((char *)DEFAULT_COMMUNITY, (char *)cp, session->community_len);
+    }
+
+    /* Set up connections */
+    sd = socket(AF_INET, SOCK_DGRAM, 0);
+    if (sd < 0){
+       perror("socket");
+       snmp_errno = SNMPERR_GENERR;
+       if (!snmp_close(session)){
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+           exit(1);
+       }
+       return 0;
+    }
+    isp->sd = sd;
+
+    if (session->peername != SNMP_DEFAULT_PEERNAME){
+       if ((addr = inet_addr(session->peername)) != -1){
+           bcopy((char *)&addr, (char *)&isp->addr.sin_addr, sizeof(isp->addr.sin_addr));
+       } else {
+           hp = gethostbyname(session->peername);
+           if (hp == NULL){
+               fprintf(stderr, "unknown host: %s\n", session->peername);
+               snmp_errno = SNMPERR_BAD_ADDRESS;
+               if (!snmp_close(session)){
+                   fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+                   exit(2);
+               }
+               return 0;
+           } else {
+               bcopy((char *)hp->h_addr, (char *)&isp->addr.sin_addr, hp->h_length);
+           }
+       }
+       isp->addr.sin_family = AF_INET;
+       if (session->remote_port == SNMP_DEFAULT_REMPORT){
+           /*servp = getservbyname("snmp", "udp");*/
+           servp=NULL;
+           if (servp != NULL){
+               isp->addr.sin_port = servp->s_port;
+           } else {
+               isp->addr.sin_port = htons(SNMP_PORT);
+           }
+       } else {
+           isp->addr.sin_port = htons(session->remote_port);
+       }
+    } else {
+       isp->addr.sin_addr.s_addr = SNMP_DEFAULT_ADDRESS;
+    }
+
+    me.sin_family = AF_INET;
+    me.sin_addr.s_addr = INADDR_ANY;
+    me.sin_port = htons(session->local_port);
+    if (bind(sd, (struct sockaddr *)&me, sizeof(me)) != 0){
+       perror("bind");
+       snmp_errno = SNMPERR_BAD_LOCPORT;
+       if (! snmp_close(session)){
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n", 
+                   api_errstring(snmp_errno));
+           exit(3);
+       }
+       return 0;
+    }
+
+    if( *cp == '/' ) {
+       session->authenticator = check_received_pkt;
+       sync_with_agent(session);
+       parse_app_community_string( session );
+       session->qoS |= USEC_QOS_GENREPORT;
+    }
+
+    /* replace comm pointer with pointer to new data: */
+    session->community = cp;   
+
+    return session;
+}
+
+void
+sync_with_agent( session )
+struct snmp_session *session;
+{
+    struct snmp_pdu *pdu, *response = 0;
+    int status;
+
+    session->qoS = USEC_QOS_GENREPORT;
+    session->userLen = 6;
+    session->version = SNMP_VERSION_2;
+    strcpy( session->userName, "public" );
+
+    snmp_synch_setup(session);
+    pdu = snmp_pdu_create(GET_REQ_MSG);
+    status = snmp_synch_response(session, pdu, &response);
+
+    if (status == STAT_SUCCESS){
+       memcpy( session->agentID, response->params.agentID, 12 );
+
+       /* save the clocks -- even though they are not authentic */
+       session->agentBoots = response->params.agentBoots;
+       session->agentTime = response->params.agentTime;
+       session->agentClock = response->params.agentTime - time(NULL);
+
+    } else {
+           if (status == STAT_TIMEOUT){
+               printf("No Response from %s\n", session->peername);
+           } else {    /* status == STAT_ERROR */
+               printf("An error occurred, Quitting\n");
+           }
+           exit( -1 );
+    }
+
+    /** freed to early: 
+      snmp_free_pdu(pdu);
+      if (response) snmp_free_pdu(response);
+     **/
+}
+#if 1 /***/
+/*
+ * Unlink one element from input request list,
+ * then free it and it's pdu.
+ */
+static void
+free_one_request(isp, orp)
+    struct snmp_internal_session *isp;
+    struct request_list *orp;
+{
+    struct request_list *rp;
+    if(! orp) return;
+    if(isp->requests == orp){ 
+      isp->requests = orp->next_request; /* unlink head */
+    }
+    else{
+      for(rp = isp->requests; rp; rp = rp->next_request){
+        if(rp->next_request == orp){ 
+         rp->next_request = orp->next_request; /* unlink element */
+         break;
+        }
+      }
+    }
+    if (orp->pdu != NULL){
+      snmp_free_pdu(orp->pdu);
+    }
+    free((char *)orp);
+}
+#endif /***/
+/*
+ * Free each element in the input request list.
+ */
+static void
+free_request_list(rp)
+    struct request_list *rp;
+{
+    struct request_list *orp;
+
+    while(rp){
+       orp = rp;
+       rp = rp->next_request;
+       if (orp->pdu != NULL)
+           snmp_free_pdu(orp->pdu);
+       free((char *)orp);
+    }
+}
+
+/*
+ * 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.
+ */
+int 
+snmp_close(session)
+    struct snmp_session *session;
+{
+    struct session_list *slp = NULL, *oslp = NULL;
+
+    if (Sessions->session == session){ /* If first entry */
+       slp = Sessions;
+       Sessions = slp->next;
+    } else {
+       for(slp = Sessions; slp; slp = slp->next){
+           if (slp->session == session){
+               if (oslp)   /* if we found entry that points here */
+                   oslp->next = slp->next;     /* link around this entry */
+               break;
+           }
+           oslp = slp;
+       }
+    }
+    /* If we found the session, free all data associated with it */
+    if (slp){
+       if (slp->session->community != NULL)
+           free((char *)slp->session->community);
+       if(slp->session->peername != NULL)
+           free((char *)slp->session->peername);
+       free((char *)slp->session);
+       if (slp->internal->sd != -1)
+           close(slp->internal->sd);
+       free_request_list(slp->internal->requests);
+       free((char *)slp->internal);
+       free((char *)slp);
+    } else {
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    return 1;
+}
+
+/*
+ * Takes a session and a pdu and serializes the ASN PDU into the area
+ * pointed to by packet.  out_length is the size of the data area available.
+ * Returns the length of the completed packet in out_length.  If any errors
+ * occur, -1 is returned.  If all goes well, 0 is returned.
+ */
+int
+snmp_build(session, pdu, packet, out_length, is_agent)
+    struct snmp_session        *session;
+    struct snmp_pdu    *pdu;
+    u_char     *packet;
+    int                        *out_length;
+    int                         is_agent;
+{
+    u_char  buf[PACKET_LENGTH];
+    u_char  *cp;
+    struct variable_list *vp;
+    int            length;
+    int            totallength;
+
+    length = *out_length;
+    cp = packet;
+    for(vp = pdu->variables; vp; vp = vp->next_variable){
+       cp = snmp_build_var_op(cp, vp->name, &vp->name_length, vp->type, vp->val_len, (u_char *)vp->val.string, &length);
+       if (cp == NULL)
+           return -1;
+    }
+    totallength = cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR), totallength);
+    if (cp == NULL)
+       return -1;
+    bcopy((char *)packet, (char *)cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+    if (pdu->command != TRP_REQ_MSG){
+       /* request id */
+       cp = asn_build_int(packet, &length,
+           (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+           (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (cp == NULL)
+           return -1;
+       /* error status */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (cp == NULL)
+           return -1;
+       /* error index */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (cp == NULL)
+           return -1;
+    } else {   /* this is a trap message */
+       /* enterprise */
+       cp = asn_build_objid(packet, &length,
+           (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID),
+           (oid *)pdu->enterprise, pdu->enterprise_length);
+       if (cp == NULL)
+           return -1;
+       /* agent-addr */
+       cp = asn_build_string(cp, &length, (u_char)IPADDRESS,
+               (u_char *)&pdu->agent_addr.sin_addr.s_addr, sizeof(pdu->agent_addr.sin_addr.s_addr));
+       if (cp == NULL)
+           return -1;
+       /* generic trap */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (cp == NULL)
+           return -1;
+       /* specific trap */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (cp == NULL)
+           return -1;
+       /* timestamp  */
+       cp = asn_build_int(cp, &length, (u_char)TIMETICKS,
+               (long *)&pdu->time, sizeof(pdu->time));
+       if (cp == NULL)
+           return -1;
+    }
+    if (length < totallength)
+       return -1;
+    bcopy((char *)buf, (char *)cp, totallength);
+    totallength += cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char)pdu->command, totallength);
+    if (cp == NULL)
+       return -1;
+    if (length < totallength)
+       return -1;
+    bcopy((char *)packet, (char *)cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+
+    cp = snmp_auth_build( packet, &length, session, is_agent, totallength );
+    if (cp == NULL)
+       return -1;
+    if ((*out_length - (cp - packet)) < totallength)
+       return -1;
+    bcopy((char *)buf, (char *)cp, totallength);
+    totallength += cp - packet;
+    *out_length = totallength;
+
+    if( session->qoS & USEC_QOS_AUTH )
+           md5Digest( packet, totallength, cp - (session->contextLen + 16),
+               cp - (session->contextLen + 16) );
+
+    return 0;
+}
+
+/*
+ * Parses the packet received on the input session, and places the data into
+ * the input pdu.  length is the length of the input packet.  If any errors
+ * are encountered, -1 is returned.  Otherwise, a 0 is returned.
+ */
+static int
+snmp_parse(session, pdu, data, length)
+    struct snmp_session *session;
+    struct snmp_pdu *pdu;
+    u_char  *data;
+    int            length;
+{
+    u_char  msg_type;
+    u_char  type;
+    u_char  *var_val;
+    long    version;
+    int            len, four;
+    u_char community[256];
+    int community_length = 256;
+    struct variable_list *vp = 0;
+    oid            objid[MAX_NAME_LEN], *op;
+    u_char  *origdata = data;
+    int      origlength = length;
+    int      ret = 0;
+    u_char  *save_data;
+
+    /* authenticates message and returns length if valid */
+    data = snmp_auth_parse(data, &length, community, &community_length, &version);
+    if (data == NULL)
+       return -1;
+
+   if( version != SNMP_VERSION_1 && version != SNMP_VERSION_2C && version != SNMP_VERSION_2 ) {
+           fprintf(stderr, "Wrong version: %ld\n", version);
+           return -1;
+    }
+
+    save_data = data;
+
+    data = asn_parse_header(data, &length, &msg_type);
+    if (data == NULL)
+       return -1;
+    pdu->command = msg_type;
+
+    if( session->authenticator ) {
+       ret = session->authenticator( origdata, origlength, save_data - community_length, 
+               community_length, session, pdu );
+       if( ret < 0 ) return ret;
+    }
+
+    if (pdu->command != TRP_REQ_MSG){
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (data == NULL)
+           return -1;
+    } else {
+       pdu->enterprise_length = MAX_NAME_LEN;
+       data = asn_parse_objid(data, &length, &type, objid, &pdu->enterprise_length);
+       if (data == NULL)
+           return -1;
+       pdu->enterprise = (oid *)calloc(1, pdu->enterprise_length * sizeof(oid));
+       bcopy((char *)objid, (char *)pdu->enterprise, pdu->enterprise_length * sizeof(oid));
+
+       four = 4;
+       data = asn_parse_string(data, &length, &type, (u_char *)&pdu->agent_addr.sin_addr.s_addr, &four);
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->time, sizeof(pdu->time));
+       if (data == NULL)
+           return -1;
+    }
+    data = asn_parse_header(data, &length, &type);
+    if (data == NULL)
+       return -1;
+    if (type != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR))
+       return -1;
+    while((int)length > 0){
+       if (pdu->variables == NULL){
+           pdu->variables = vp = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+       } else {
+           vp->next_variable = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+           vp = vp->next_variable;
+       }
+       vp->next_variable = NULL;
+       vp->val.string = NULL;
+       vp->name = NULL;
+       vp->name_length = MAX_NAME_LEN;
+       data = snmp_parse_var_op(data, objid, &vp->name_length, &vp->type, &vp->val_len, &var_val, (int *)&length);
+       if (data == NULL)
+           return -1;
+       op = (oid *)calloc(1, (unsigned)vp->name_length * sizeof(oid));
+       bcopy((char *)objid, (char *)op, vp->name_length * sizeof(oid));
+       vp->name = op;
+
+       len = PACKET_LENGTH;
+       switch((short)vp->type){
+           case ASN_INTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(long));
+               vp->val_len = sizeof(long);
+               asn_parse_int(var_val, &len, &vp->type, (long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER:
+           case GAUGE:
+           case TIMETICKS:
+           case UINTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(unsigned long));
+               vp->val_len = sizeof(unsigned long);
+               asn_parse_unsigned_int(var_val, &len, &vp->type, (unsigned long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER64:
+               vp->val.counter64 = (struct counter64 *)calloc(1,  sizeof(struct counter64) );
+               vp->val_len = sizeof(struct counter64);
+               asn_parse_unsigned_int64(var_val, &len, &vp->type,
+                                        (struct counter64 *)vp->val.counter64,
+                                        sizeof(*vp->val.counter64));
+               break;
+           case ASN_OCTET_STR:
+           case IPADDRESS:
+           case OPAQUE:
+           case NSAP:
+               vp->val.string = (u_char *)calloc(1, (unsigned)vp->val_len);
+               asn_parse_string(var_val, &len, &vp->type, vp->val.string, &vp->val_len);
+               break;
+           case ASN_OBJECT_ID:
+               vp->val_len = MAX_NAME_LEN;
+               asn_parse_objid(var_val, &len, &vp->type, objid, &vp->val_len);
+               vp->val_len *= sizeof(oid);
+               vp->val.objid = (oid *)calloc(1, (unsigned)vp->val_len);
+               bcopy((char *)objid, (char *)vp->val.objid, vp->val_len);
+               break;
+            case SNMP_NOSUCHOBJECT:
+            case SNMP_NOSUCHINSTANCE:
+            case SNMP_ENDOFMIBVIEW:
+           case ASN_NULL:
+               break;
+           default:
+               fprintf(stderr, "bad type returned (%x)\n", vp->type);
+               break;
+       }
+    }
+    return ret;
+}
+
+/*
+ * 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(session, pdu)
+    struct snmp_session *session;
+    struct snmp_pdu    *pdu;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp = NULL;
+    u_char  packet[PACKET_LENGTH];
+    int length = PACKET_LENGTH;
+    struct request_list *rp;
+    struct timeval tv;
+
+    for(slp = Sessions; slp; slp = slp->next){
+       if (slp->session == session){
+           isp = slp->internal;
+           break;
+       }
+    }
+
+    if (! pdu) {
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+
+    if (isp == NULL){
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG
+       || pdu->command == GET_RSP_MSG || pdu->command == SET_REQ_MSG 
+       || pdu->command == GETBULK_REQ_MSG ){
+       if (pdu->reqid == SNMP_DEFAULT_REQID)
+           pdu->reqid = ++Reqid;
+       if (pdu->errstat == SNMP_DEFAULT_ERRSTAT)
+           pdu->errstat = 0;
+       if (pdu->errindex == SNMP_DEFAULT_ERRINDEX)
+           pdu->errindex = 0;
+    } else {
+       /* fill in trap defaults */
+       pdu->reqid = 1; /* give a bogus non-error reqid for traps */
+       if (pdu->enterprise_length == SNMP_DEFAULT_ENTERPRISE_LENGTH){
+           pdu->enterprise = (oid *)calloc(1, sizeof(DEFAULT_ENTERPRISE));
+           bcopy((char *)DEFAULT_ENTERPRISE, (char *)pdu->enterprise, sizeof(DEFAULT_ENTERPRISE));
+           pdu->enterprise_length = sizeof(DEFAULT_ENTERPRISE)/sizeof(oid);
+       }
+       if (pdu->time == SNMP_DEFAULT_TIME)
+           pdu->time = DEFAULT_TIME;
+    }
+    if (pdu->address.sin_addr.s_addr == SNMP_DEFAULT_ADDRESS){
+       if (isp->addr.sin_addr.s_addr != SNMP_DEFAULT_ADDRESS){
+           bcopy((char *)&isp->addr, (char *)&pdu->address, sizeof(pdu->address));
+       } else {
+           fprintf(stderr, "No remote IP address specified\n");
+           snmp_errno = SNMPERR_BAD_ADDRESS;
+           return 0;
+       }
+    }
+       
+
+    if (snmp_build(session, pdu, packet, &length, 0) < 0){
+       fprintf(stderr, "Error building packet\n");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+#if 1 /***/
+    if (snmp_dump_packet){
+      snmp_print_packet(packet, length, pdu->address, 1);
+    }
+#endif /***/
+
+    gettimeofday(&tv, (struct timezone *)0);
+    if (sendto(isp->sd, (char *)packet, length, 0, (struct sockaddr *)&pdu->address, sizeof(pdu->address)) < 0){
+       perror("sendto");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG 
+     || pdu->command == SET_REQ_MSG || pdu->command == GETBULK_REQ_MSG ){
+       /* set up to expect a response */
+       rp = (struct request_list *)calloc(1, sizeof(struct request_list));
+#if 1 /***/
+        if(! rp){
+          fprintf(stderr, "Out of memory!\n");
+          snmp_errno = SNMPERR_GENERR;
+          return 0;
+        }
+#endif /***/
+           rp->next_request = isp->requests;
+       isp->requests = rp;
+       rp->pdu = pdu;
+       rp->request_id = pdu->reqid;
+
+       rp->retries = 1;
+       rp->timeout = session->timeout;
+       rp->time = tv;
+       tv.tv_usec += rp->timeout;
+       tv.tv_sec += tv.tv_usec / 1000000L;
+       tv.tv_usec %= 1000000L;
+       rp->expire = tv;
+#if DEBUG_SNMPTRACE
+       snmp_print_trace(slp, rp, TRACE_SEND);
+#endif
+    }
+    return pdu->reqid;
+}
+
+/*
+ * Frees the pdu and any malloc'd data associated with it.
+ */
+void
+snmp_free_pdu(struct snmp_pdu *pdu)
+{
+    struct variable_list *vp, *ovp;
+
+    if (!pdu)
+       return;
+
+    vp = pdu->variables;
+    while (vp) {
+       if (vp->name) {
+           free((char *) vp->name);
+       }
+       if (vp->val.string) {
+           free((char *) vp->val.string);
+       }
+       ovp = vp;
+       vp = vp->next_variable;
+       free((char *) ovp);
+    }
+    if (pdu->enterprise) {
+       free((char *) pdu->enterprise);
+    }
+    free((char *) pdu);
+}
+
+
+/*
+ * 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(fdset)
+     fd_set *fdset;
+{
+    struct session_list *slp;
+    struct snmp_session *sp;
+    struct snmp_internal_session *isp;
+    u_char packet[PACKET_LENGTH];
+    struct sockaddr_in from;
+    ssize_t length, fromlength;
+    struct snmp_pdu *pdu;
+    struct request_list *rp /**, *orp **/ ;
+
+    for (slp = Sessions; slp; slp = slp->next) {
+       if (FD_ISSET(slp->internal->sd, fdset)) {
+           sp = slp->session;
+           isp = slp->internal;
+           fromlength = sizeof(from);
+           length = recvfrom(isp->sd, (char *) packet, PACKET_LENGTH, 0, (struct sockaddr *) &from, &fromlength);
+           if (length == -1) {
+               perror("recvfrom");
+               return;
+           }
+#if 1/***/ if we found entry that points here */
+ oslp e key!  replace...
+     */
+ * \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 1\ 1\0\0\0\0\0\0\0\19\7fÿ¯ùsnmplib/snmp_api.c\0c\0\0.h\0\0\0\18\7fÿ°\85\10\0<Ðlib/snmp_api.c~\0~\0\0ñ\0\0\0\18\7fÿ±\1e\10\0\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\0\0\0\18\7fÿ±«\10\0=\10\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\0\0\0\18\7fÿ²\1d\10\0=0\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\0\0\0\18\7fÿ²\8a\10\0=P\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\0\0\0\18\7fÿ³
+\10\0=p\7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\0\0\0\18\7fÿ³\82\0\0\0\ 1\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\0\0\0Á\7fÿ³ù\0\0\0\10\7fÿ´\10\10\0\0%\0\19\0\15\0\0\10\0D(\0\0\0\10\7fÿ´_\10\0\0\0\ 2\\0\0\0\0\10\0\0\0\0\10\7fÿ´©\10\0=\98\0\0\ 24\0\0\0\0\10\0\0\0\0\10\7fÿ´ø\10\0\0\0\ 2H\0\0\0\0\10\0\0\0\0\10\7fÿµB\10\0>\10\7fÿµ]\7fÿµm\7fÿµz\0\0\0\10\7fÿµ \10\0>(\7fÿµ·\7fÿµÉ\7fÿµÖ\0\0\0\10\7fÿµï\10\0>@\7fÿ¶\12\7fÿ¶ \7fÿ¶4\0\0\0\10\7fÿ¶P\0\0\0\ 1\7fÿ¶r\7fÿ¶~\7fÿ¶\88\0\0\00\7fÿ¶\9f\0\0\0\0\7fÿ¶·\0\0\0\0\7fÿ¶Ù\10\0\7fÿ·\ 1\0\0\0\0\7fÿ·#\7fÿ·/\7fÿ·>\10\0>X\7fÿ·V\0\0\03\0\0\0\0/usr/people/wessels/.indent.pro\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\ 1\0\0\0\0\7fÿ¯è\7fÿ¯ù\7fÿ°\f\7fÿ°\e\7fÿ°.\7fÿ°?\7fÿ°M\7fÿ°[\7fÿ°p\7fÿ°\85\7fÿ°\95\7fÿ°£\7fÿ°²\7fÿ°Å\7fÿ°Û\7fÿ°ñ\7fÿ±
+\7fÿ±\1e\7fÿ±2\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\7fÿ±\99\7fÿ±«\7fÿ±º\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\7fÿ²\ f\7fÿ²\1d\7fÿ²2\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\7fÿ²\7f\7fÿ²\8a\7fÿ²\99\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\7fÿ²ö\7fÿ³
+\7fÿ³ \7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\7fÿ³s\7fÿ³\82\7fÿ³\91\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\7fÿ³ç\7fÿ³ù\7fÿ´\ 4\7fÿ´\10\7fÿ´\1e\7fÿ´)\7fÿ´3\7fÿ´C\7fÿ´O\7fÿ´_\7fÿ´k\7fÿ´t\7fÿ´\81\7fÿ´\8f\7fÿ´\9f\7fÿ´©\7fÿ´·\7fÿ´Å\7fÿ´Ò\7fÿ´Ý\7fÿ´í\7fÿ´ø\7fÿµ\ 3\7fÿµ\10\7fÿµ\1d\7fÿµ)\7fÿµ7\7fÿµB\7fÿµM\7fÿµ]\7fÿµm\7fÿµz\7fÿµ\89\7fÿµ \7fÿµ«\7fÿµ·\7fÿµÉ\7fÿµÖ\7fÿµâ\7fÿµï\7fÿ¶\ 3\7fÿ¶\12\7fÿ¶ \7fÿ¶4\7fÿ¶?\7fÿ¶P\7fÿ¶b\7fÿ¶r\7fÿ¶~\7fÿ¶\88\7fÿ¶\94\7fÿ¶\9f\7fÿ¶«\7fÿ¶·\7fÿ¶É\7fÿ¶Ù\7fÿ¶í\7fÿ·\ 1\7fÿ·\15\7fÿ·#\7fÿ·/\7fÿ·>\7fÿ·L\7fÿ·V\7fÿ·f\7fÿ·q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0@    \0\0\0\0
+       }
+       if (pdu->time == SNMP_DEFAULT_TIME)
+           pdu->time = DEFAULT_TIME;
+    }
+    if (pdu->address.sin_addr.s_addr == SNMP_DEFAULT_ADDRESS){
+       if (isp->addr.sin_addr.s_addr != SNMP_DEFAULT_ADDRESS){
+           bcopy((char *)&isp->addr, (char *)&pdu->address, sizeof(pdu->address));
+       } else {
+           fprintf(stderr, "No remote IP address specified\n");
+           snmp_errno = SNMPERR_BAD_ADDRESS;
+           return 0;
+       }
+    }
+       
+
+    if (snmp_build(session, pdu, packet, &length, 0) < 0){
+       fprintf(stderr, "Error building packet\n");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+#if 1 /***/
+    if (snmp_dump_packet){
+      snmp_print_packet(packet, length, pdu->address, 1);
+    }
+#endif /***/
+
+    gettimeofday(&tv, (struct timezone *)0);
+    if (sendto(isp->sd, (char *)packet, length, 0, (struct sockaddr *)&pdu->address, sizeof(pdu->address)) < 0){
+       perror("sendto");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG 
+     || pdu->command == SET_REQ_MSG || pdu->command == GETBULK_REQ_MSG ){
+       /* set up to expect a response */
+       rp = (struct request_list *)calloc(1, sizeof(struct request_list));
+#if 1 /***/
+        if(! rp){
+          fprintf(stderr, "Out of memory!\n");
+          snmp_errno = SNMPERR_GENERR;
+          return 0;
+        }
+#endif /***/
+           rp->next_request = isp->requests;
+       isp->requests = rp;
+       rp->pdu = pdu;
+       rp->request_id = pdu->reqid;
+
+       rp->retries = 1;
+       rp->timeout = session->timeout;
+       rp->time = tv;
+       tv.tv_usec += rp->timeout;
+       tv.tv_sec += tv.tv_usec / 1000000L;
+       tv.tv_usec %= 1000000L;
+       rp->expire = tv;
+#if DEBUG_SNMPTRACE
+       snmp_print_trace(slp, rp, TRACE_SEND);
+#endif
+    }
+    return pdu->reqid;
+}
+
+/*
+ * Frees the pdu and any malloc'd data associated with it.
+ */
+void
+snmp_free_pdu(struct snmp_pdu *pdu)
+{
+    struct variable_list *vp, *ovp;
+
+    if (!pdu)
+       return;
+
+    vp = pdu->variables;
+    while (vp) {
+       if (vp->name) {
+           free((char *) vp->name);
+       }
+       if (vp->val.string) {
+           free((char *) vp->val.string);
+       }
+       ovp = vp;
+       vp = vp->next_variable;
+       free((char *) ovp);
+    }
+    if (pdu->enterprise) {
+       free((char *) pdu->enterprise);
+    }
+    free((char *) pdu);
+}
+
+
+/*
+ * 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(fdset)
+     fd_set *fdset;
+{
+    struct session_list *slp;
+    struct snmp_session *sp;
+    struct snmp_internal_session *isp;
+    u_char packet[PACKET_LENGTH];
+    struct sockaddr_in from;
+    ssize_t length, fromlength;
+    struct snmp_pdu *pdu;
+    struct request_list *rp /**, *orp **/ ;
+
+    for (slp = Sessions; slp; slp = slp->next) {
+       if (FD_ISSET(slp->internal->sd, fdset)) {
+           sp = slp->session;
+           isp = slp->internal;
+           fromlength = sizeof(from);
+           length = recvfrom(isp->sd, (char *) packet, PACKET_LENGTH, 0, (struct sockaddr *) &from, &fromlength);
+           if (length == -1) {
+               perror("recvfrom");
+               return;
+           }
+ponse->params.agentID, 12 );
+
+       /* save the clocks -- even though they are not authentic */
+       session->agentBoots = response->params.agentBoots;
+       session->agentTime = response->params.agentTime;
+       session->agentClock = response->params.agentTime - time(NULL);
+
+    } else {
+           if (status == STAT_TIMEOUT){
+               printf("No Response from %s\n", session->peername);
+           } else {    /* status == STAT_ERROR */
+               printf("An error occurred, Quitting\n");
+           }
+           exit( -1 );
+    }
+
+    /** freed to early: 
+      snmp_free_pdu(pdu);
+      if (response) snmp_free_pdu(response);
+     **/
+}
+#if 1 /***/
+/*
+ * Unlink one element from input request list,
+ * then free it and it's pdu.
+ */
+static void
+free_one_request(isp, orp)
+    struct snmp_internal_session *isp;
+    struct request_list *orp;
+{
+    struct request_list *rp;
+    if(! orp) return;
+    if(isp->requests == orp){ 
+      isp->requests = orp->next_request; /* unlink head */
+    }
+    else{
+      for(rp = isp->requests; rp; rp = rp->next_request){
+        if(rp->next_request == orp){ 
+         rp->next_request = orp->next_request; /* unlink element */
+         break;
+        }
+      }
+    }
+    if (orp->pdu != NULL){
+      snmp_free_pdu(orp->pdu);
+    }
+    free((char *)orp);
+}
+#endif /***/
+/*
+ * Free each element in the input request list.
+ */
+static void
+free_request_list(rp)
+    struct request_list *rp;
+{
+    struct request_list *orp;
+
+    while(rp){
+       orp = rp;
+       rp = rp->next_request;
+       if (orp->pdu != NULL)
+           snmp_free_pdu(orp->pdu);
+       free((char *)orp);
+    }
+}
+
+/*
+ * 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.
+ */
+int 
+snmp_close(session)
+    struct snmp_session *session;
+{
+    struct session_list *slp = NULL, *oslp = NULL;
+
+    if (Sessions->session == session){ /* If first entry */
+       slp = Sessions;
+       Sessions = slp->next;
+    } else {
+       for(slp = Sessions; slp; slp = slp->next){
+           if (slp->session == session){
+               if (oslp)   /* if we found entry that points here */
+                   oslp->next = slp->next;     /* link around this entry */
+               break;
+           }
+           oslp = slp;
+       }
+    }
+    /* If we found the session, free all data associated with it */
+    if (slp){
+       if (slp->session->community != NULL)
+           free((char *)slp->session->community);
+       if(slp->session->peername != NULL)
+           free((char *)slp->session->peername);
+       free((char *)slp->session);
+       if (slp->internal->sd != -1)
+           close(slp->internal->sd);
+       free_request_list(slp->internal->requests);
+       free((char *)slp->internal);
+       free((char *)slp);
+    } else {
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    return 1;
+}
+
+/*
+ * Takes a session and a pdu and serializes the ASN PDU into the area
+ * pointed to by packet.  out_length is the size of the data area available.
+ * Returns the length of the completed packet in out_length.  If any errors
+ * occur, -1 is returned.  If all goes well, 0 is returned.
+ */
+int
+snmp_build(session, pdu, packet, out_length, is_agent)
+    struct snmp_session        *session;
+    struct snmp_pdu    *pdu;
+    u_char     *packet;
+    int                        *out_length;
+    int                         is_agent;
+{
+    u_char  buf[PACKET_LENGTH];
+    u_char  *cp;
+    struct variable_list *vp;
+    int            length;
+    int            totallength;
+
+    length = *out_length;
+    cp = packet;
+    for(vp = pdu->variables; vp; vp = vp->next_variable){
+       cp = snmp_build_var_op(cp, vp->name, &vp->name_length, vp->type, vp->val_len, (u_char *)vp->val.string, &length);
+       if (cp == NULL)
+           return -1;
+    }
+    totallength = cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR), totallength);
+    if (cp == NULL)
+       return -1;
+    bcopy((char *)packet, (char *)cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+    if (pdu->command != TRP_REQ_MSG){
+       /* request id */
+       cp = asn_build_int(packet, &length,
+           (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+           (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (cp == NULL)
+           return -1;
+       /* error status */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (cp == NULL)
+           return -1;
+       /* error index */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (cp == NULL)
+           return -1;
+    } else {   /* this is a trap message */
+       /* enterprise */
+       cp = asn_build_objid(packet, &length,
+           (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID),
+           (oid *)pdu->enterprise, pdu->enterprise_length);
+       if (cp == NULL)
+           return -1;
+       /* agent-addr */
+       cp = asn_build_string(cp, &length, (u_char)IPADDRESS,
+               (u_char *)&pdu->agent_addr.sin_addr.s_addr, sizeof(pdu->agent_addr.sin_addr.s_addr));
+       if (cp == NULL)
+           return -1;
+       /* generic trap */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (cp == NULL)
+           return -1;
+       /* specific trap */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (cp == NULL)
+           return -1;
+       /* timestamp  */
+       cp = asn_build_int(cp, &length, (u_char)TIMETICKS,
+               (long *)&pdu->time, sizeof(pdu->time));
+       if (cp == NULL)
+           return -1;
+    }
+    if (length < totallength)
+       return -1;
+    bcopy((char *)buf, (char *)cp, totallength);
+    totallength += cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char)pdu->command, totallength);
+    if (cp == NULL)
+       return -1;
+    if (length < totallength)
+       return -1;
+    bcopy((char *)packet, (char *)cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+
+    cp = snmp_auth_build( packet, &length, session, is_agent, totallength );
+    if (cp == NULL)
+       return -1;
+    if ((*out_length - (cp - packet)) < totallength)
+       return -1;
+    bcopy((char *)buf, (char *)cp, totallength);
+    totallength += cp - packet;
+    *out_length = totallength;
+
+    if( session->qoS & USEC_QOS_AUTH )
+           md5Digest( packet, totallength, cp - (session->contextLen + 16),
+               cp - (session->contextLen + 16) );
+
+    return 0;
+}
+
+/*
+ * Parses the packet received on the input session, and places the data into
+ * the input pdu.  length is the length of the input packet.  If any errors
+ * are encountered, -1 is returned.  Otherwise, a 0 is returned.
+ */
+static int
+snmp_parse(session, pdu, data, length)
+    struct snmp_session *session;
+    struct snmp_pdu *pdu;
+    u_char  *data;
+    int            length;
+{
+    u_char  msg_type;
+    u_char  type;
+    u_char  *var_val;
+    long    version;
+    int            len, four;
+    u_char community[256];
+    int community_length = 256;
+    struct variable_list *vp = 0;
+    oid            objid[MAX_NAME_LEN], *op;
+    u_char  *origdata = data;
+    int      origlength = length;
+    int      ret = 0;
+    u_char  *save_data;
+
+    /* authenticates message and returns length if valid */
+    data = snmp_auth_parse(data, &length, community, &community_length, &version);
+    if (data == NULL)
+       return -1;
+
+   if( version != SNMP_VERSION_1 && version != SNMP_VERSION_2C && version != SNMP_VERSION_2 ) {
+           fprintf(stderr, "Wrong version: %ld\n", version);
+           return -1;
+    }
+
+    save_data = data;
+
+    data = asn_parse_header(data, &length, &msg_type);
+    if (data == NULL)
+       return -1;
+    pdu->command = msg_type;
+
+    if( session->authenticator ) {
+       ret = session->authenticator( origdata, origlength, save_data - community_length, 
+               community_length, session, pdu );
+       if( ret < 0 ) return ret;
+    }
+
+    if (pdu->command != TRP_REQ_MSG){
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (data == NULL)
+           return -1;
+    } else {
+       pdu->enterprise_length = MAX_NAME_LEN;
+       data = asn_parse_objid(data, &length, &type, objid, &pdu->enterprise_length);
+       if (data == NULL)
+           return -1;
+       pdu->enterprise = (oid *)calloc(1, pdu->enterprise_length * sizeof(oid));
+       bcopy((char *)objid, (char *)pdu->enterprise, pdu->enterprise_length * sizeof(oid));
+
+       four = 4;
+       data = asn_parse_string(data, &length, &type, (u_char *)&pdu->agent_addr.sin_addr.s_addr, &four);
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->time, sizeof(pdu->time));
+       if (data == NULL)
+           return -1;
+    }
+    data = asn_parse_header(data, &length, &type);
+    if (data == NULL)
+       return -1;
+    if (type != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR))
+       return -1;
+    while((int)length > 0){
+       if (pdu->variables == NULL){
+           pdu->variables = vp = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+       } else {
+           vp->next_variable = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+           vp = vp->next_variable;
+       }
+       vp->next_variable = NULL;
+       vp->val.string = NULL;
+       vp->name = NULL;
+       vp->name_length = MAX_NAME_LEN;
+       data = snmp_parse_var_op(data, objid, &vp->name_length, &vp->type, &vp->val_len, &var_val, (int *)&length);
+       if (data == NULL)
+           return -1;
+       op = (oid *)calloc(1, (unsigned)vp->name_length * sizeof(oid));
+       bcopy((char *)objid, (char *)op, vp->name_length * sizeof(oid));
+       vp->name = op;
+
+       len = PACKET_LENGTH;
+       switch((short)vp->type){
+           case ASN_INTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(long));
+               vp->val_len = sizeof(long);
+               asn_parse_int(var_val, &len, &vp->type, (long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER:
+           case GAUGE:
+           case TIMETICKS:
+           case UINTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(unsigned long));
+               vp->val_len = sizeof(unsigned long);
+               asn_parse_unsigned_int(var_val, &len, &vp->type, (unsigned long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER64:
+               vp->val.counter64 = (struct counter64 *)calloc(1,  sizeof(struct counter64) );
+               vp->val_len = sizeof(struct counter64);
+               asn_parse_unsigned_int64(var_val, &len, &vp->type,
+                                        (struct counter64 *)vp->val.counter64,
+                                        sizeof(*vp->val.counter64));
+               break;
+           case ASN_OCTET_STR:
+           case IPADDRESS:
+           case OPAQUE:
+           case NSAP:
+               vp->val.string = (u_char *)calloc(1, (unsigned)vp->val_len);
+               asn_parse_string(var_val, &len, &vp->type, vp->val.string, &vp->val_len);
+               break;
+           case ASN_OBJECT_ID:
+               vp->val_len = MAX_NAME_LEN;
+               asn_parse_objid(var_val, &len, &vp->type, objid, &vp->val_len);
+               vp->val_len *= sizeof(oid);
+               vp->val.objid = (oid *)calloc(1, (unsigned)vp->val_len);
+               bcopy((char *)objid, (char *)vp->val.objid, vp->val_len);
+               break;
+            case SNMP_NOSUCHOBJECT:
+            case SNMP_NOSUCHINSTANCE:
+            case SNMP_ENDOFMIBVIEW:
+           case ASN_NULL:
+               break;
+           default:
+               fprintf(stderr, "bad type returned (%x)\n", vp->type);
+               break;
+       }
+    }
+    return ret;
+}
+
+/*
+ * 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(session, pdu)
+    struct snmp_session *session;
+    struct snmp_pdu    *pdu;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp = NULL;
+    u_char  packet[PACKET_LENGTH];
+    int length = PACKET_LENGTH;
+    struct request_list *rp;
+    struct timeval tv;
+
+    for(slp = Sessions; slp; slp = slp->next){
+       if (slp->session == session){
+           isp = slp->internal;
+           break;
+       }
+    }
+
+    if (! pdu) {
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+
+    if (isp == NULL){
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG
+       || pdu->command == GET_RSP_MSG || pdu->command == SET_REQ_MSG 
+       || pdu->command == GETBULK_REQ_MSG ){
+       if (pdu->reqid == SNMP_DEFAULT_REQID)
+           pdu->reqid = ++Reqid;
+       if (pdu->errstat == SNMP_DEFAULT_ERRSTAT)
+           pdu->errstat = 0;
+       if (pdu->errindex == SNMP_DEFAULT_ERRINDEX)
+           pdu->errindex = 0;
+    } else {
+       /* fill in trap defaults */
+       pdu->reqid = 1; /* give a bogus non-error reqid for traps */
+       if (pdu->enterprise_length == SNMP_DEFAULT_ENTERPRISE_LENGTH){
+           pdu->enterprise = (oid *)calloc(1, sizeof(DEFAULT_ENTERPRISE));
+           bcopy((char *)DEFAULT_ENTERPRISE, (char *)pdu->enterprise, sizeof(DEFAULT_ENTERPRISE));
+           pdu->enterprise_length = sizeof(DEFAULT_ENTERPRISE)/sizeof(oid);\10\0BÐ+= m\0\0
+È      /* \10\04¨*/ B\0\0\0\0NMPT\10\ 1Í8 */c\0\0\0\0for testing purposes */e key!  replace...
+     */
+ * \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 1\ 1\0\0\0\0\0\0\0\19\7fÿ¯ùsnmplib/snmp_api.c\0c\0\0.h\0\0\0\18\7fÿ°\85\10\0<Ðlib/snmp_api.c~\0~\0\0ñ\0\0\0\18\7fÿ±\1e\10\0\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\0\0\0\18\7fÿ±«\10\0=\10\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\0\0\0\18\7fÿ²\1d\10\0=0\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\0\0\0\18\7fÿ²\8a\10\0=P\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\0\0\0\18\7fÿ³
+\10\0=p\7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\0\0\0\18\7fÿ³\82\0\0\0\ 1\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\0\0\0Á\7fÿ³ù\0\0\0\10\7fÿ´\10\10\0\0%\0\19\0\15\0\0\10\0D(\0\0\0\10\7fÿ´_\10\0\0\0\ 2\\0\0\0\0\10\0\0\0\0\10\7fÿ´©\10\0=\98\0\0\ 24\0\0\0\0\10\0\0\0\0\10\7fÿ´ø\10\0\0\0\ 2H\0\0\0\0\10\0\0\0\0\10\7fÿµB\10\0>\10\7fÿµ]\7fÿµm\7fÿµz\0\0\0\10\7fÿµ \10\0>(\7fÿµ·\7fÿµÉ\7fÿµÖ\0\0\0\10\7fÿµï\10\0>@\7fÿ¶\12\7fÿ¶ \7fÿ¶4\0\0\0\10\7fÿ¶P\0\0\0\ 1\7fÿ¶r\7fÿ¶~\7fÿ¶\88\0\0\00\7fÿ¶\9f\10\0\7fÿ¶·\0\0\0\0\7fÿ¶Ù\10\0\89è\7fÿ·\ 1\0\0\0\0\7fÿ·#\7fÿ·/\7fÿ·>\10\0>X\7fÿ·V\0\0\03\0\0\0\0/usr/people/wessels/.indent.pro\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\ 1\0\0\0\0\7fÿ¯è\7fÿ¯ù\7fÿ°\f\7fÿ°\e\7fÿ°.\7fÿ°?\7fÿ°M\7fÿ°[\7fÿ°p\7fÿ°\85\7fÿ°\95\7fÿ°£\7fÿ°²\7fÿ°Å\7fÿ°Û\7fÿ°ñ\7fÿ±
+\7fÿ±\1e\7fÿ±2\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\7fÿ±\99\7fÿ±«\7fÿ±º\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\7fÿ²\ f\7fÿ²\1d\7fÿ²2\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\7fÿ²\7f\7fÿ²\8a\7fÿ²\99\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\7fÿ²ö\7fÿ³
+\7fÿ³ \7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\7fÿ³s\7fÿ³\82\7fÿ³\91\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\7fÿ³ç\7fÿ³ù\7fÿ´\ 4\7fÿ´\10\7fÿ´\1e\7fÿ´)\7fÿ´3\7fÿ´C\7fÿ´O\7fÿ´_\7fÿ´k\7fÿ´t\7fÿ´\81\7fÿ´\8f\7fÿ´\9f\7fÿ´©\7fÿ´·\7fÿ´Å\7fÿ´Ò\7fÿ´Ý\7fÿ´í\7fÿ´ø\7fÿµ\ 3\7fÿµ\10\7fÿµ\1d\7fÿµ)\7fÿµ7\7fÿµB\7fÿµM\7fÿµ]\7fÿµm\7fÿµz\7fÿµ\89\7fÿµ \7fÿµ«\7fÿµ·\7fÿµÉ\7fÿµÖ\7fÿµâ\7fÿµï\7fÿ¶\ 3\7fÿ¶\12\7fÿ¶ \7fÿ¶4\7fÿ¶?\7fÿ¶P\7fÿ¶b\7fÿ¶r\7fÿ¶~\7fÿ¶\88\7fÿ¶\94\7fÿ¶\9f\7fÿ¶«\7fÿ¶·\7fÿ¶É\7fÿ¶Ù\7fÿ¶í\7fÿ·\ 1\7fÿ·\15\7fÿ·#\7fÿ·/\7fÿ·>\7fÿ·L\7fÿ·V\7fÿ·f\7fÿ·q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\0\0\0°\0\0\0\ 4\0\0\0\0\0\0\0\b\10\0>X\0\0\0\f\10\0\0\0\0\10\0\0\0\0\0\0\0\14\0\0\0\14\0\0\0\14\0\0\0\18\0\0\0\18\0\0\0\18\0\0\0\1c\0\0\0\1c\0\0\0\1c\0\0\0\1c\0\0\0 \0\0\0 \0\0\0 \0\0\0$\0\0\0\v\0\0\0\e\0\0\0\19\0\0\0\v\0\0\0\e\0\0\0@\0\0\0\0\0\0\0\0\0\0\0\0\10\0,\b\0\0\0\1a\10\02\88\0\0\0\1a\0\0\0\0\0\0\0\1a\10\0\85\b\0\0\0\0\10\0>X\0\0\0\0\0\0\0\0\0\0\0\0\10\0\82à\0\0\0\0\0\0\ 1C\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e0\0\0\0\v\0\0\0\e\0\0\0\18\0\0\0\v\0\0\0\1a\0\0\0\17\0\0\0\v\0\0\0 \0\0\0\0\10\0\8d¸ude/snmp_groupvars.h~\0\0\b\0\0\0\b\0\0\0 \0\0\0\0\10\0\8dàude/snmp_groupvars.h\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8eX\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e\80\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e¨\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8eÐ\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\0\0\0\ 1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\84©\0\0\0\0/***********************************************************
+       Copyright 1989 by Carnegie Mellon University
+
+                      All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the name of CMU not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+******************************************************************/
+/*
+ * snmp_api.c - API for access to snmp.
+ */
+#define DEBUG_SNMPTRACE                0 /* set to 1 to print all SNMP actions */
+#define DEBUG_SNMPFULLDUMP     0 /* set to 1 to dump all SNMP packets */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#ifdef linux
+#include <arpa/inet.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#endif
+
+
+#include "asn1.h"
+#include "snmp.h"
+#include "snmp_impl.h"
+#include "snmp_api.h"
+#include "snmp_client.h"
+
+#define PACKET_LENGTH  4500
+
+#ifndef BSD4_3
+#define BSD4_2
+#endif
+
+#if !defined(BSD4_3) && !defined(linux) && !defined(sun)
+
+typedef long   fd_mask;
+#define NFDBITS        (sizeof(fd_mask) * NBBY)        /* bits per mask */
+
+#define        FD_SET(n, p)    ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+#define        FD_CLR(n, p)    ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+#define        FD_ISSET(n, p)  ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+#define FD_ZERO(p)     bzero((char *)(p), sizeof(*(p)))
+#endif
+
+oid default_enterprise[] = {1, 3, 6, 1, 4, 1, 3, 1, 1}; /* enterprises.cmu.systems.cmuSNMP */
+
+#define DEFAULT_COMMUNITY   "public"
+#define DEFAULT_REMPORT            SNMP_PORT
+#define DEFAULT_ENTERPRISE  default_enterprise
+#define DEFAULT_TIME       0
+#define DEFAULT_MMS        1389 /* large, randomly picked for testing purposes */
+
+/*
+ * Internal information about the state of the snmp session.
+ */
+struct snmp_internal_session {
+    int            sd;         /* socket descriptor for this connection */
+    ipaddr  addr;      /* address of connected peer */
+    struct request_list *requests;/* Info about outstanding requests */
+};
+
+/*
+ * A list of all the outstanding requests for a particular session.
+ */
+struct request_list {
+    struct request_list *next_request;
+    u_long  request_id;        /* request id */
+    int            retries;    /* Number of retries */
+    u_long timeout;    /* length to wait for timeout */
+    struct timeval time; /* Time this request was made */
+    struct timeval expire;  /* time this request is due to expire */
+    struct snmp_pdu *pdu;   /* The pdu for this request (saved so it can be retransmitted */
+};
+
+/*
+ * The list of active/open sessions.
+ */
+struct session_list {
+    struct session_list *next;
+    struct snmp_session *session;
+    struct snmp_internal_session *internal;
+};
+
+struct session_list *Sessions = NULL;
+
+u_long Reqid = 0;
+int snmp_errno = 0;
+
+char *api_errors[4] = {
+    "Unknown session",
+    "Unknown host",
+    "Invalid local port",
+    "Unknown Error"
+};
+
+
+void sync_with_agent();
+int parse_app_community_string();
+void snmp_synch_setup();
+int snmp_synch_response();
+void md5Digest();
+
+
+static char *
+api_errstring(snmp_errnumber)
+    int        snmp_errnumber;
+{
+    if (snmp_errnumber <= SNMPERR_BAD_SESSION && snmp_errnumber >= SNMPERR_GENERR){
+       return api_errors[snmp_errnumber + 4];
+    } else {
+       return "Unknown Error";
+    }
+}
+
+#if 0
+/*
+ * Gets initial request ID for all transactions.
+ */
+static void
+init_snmp(){
+    struct timeval tv;
+
+    gettimeofday(&tv, (struct timezone *)0);
+    srandom(tv.tv_sec ^ tv.tv_usec);
+    Reqid = random();
+}
+#endif
+
+
+/*
+ * Dump snmp packet to stdout:
+ */
+static void
+snmp_print_packet(packet, length, addr, code)
+  char *packet; 
+  int length; 
+  ipaddr addr; 
+  int code;
+{
+  if(length < 0) {
+    return;
+  }
+  if (code <= 0) { /* received */
+    printf("\nReceived %4d bytes from ", length);
+  }
+  else { /* sending */
+    printf("\nSending  %4d bytes to   ", length);
+  }
+  printf("%s:", inet_ntoa(addr.sin_addr));
+#if DEBUG_SNMPFULLDUMP
+  for (count = 0; count < length; count++) {
+    if ((count & 15) == 0) {
+      printf("\n  ");
+    }
+    printf("%02X ", (int)(packet[count]&255));
+  }
+#endif
+  fflush(stdout);
+}
+
+#if DEBUG_SNMPTRACE
+/*
+ * Print request
+ */
+#define TRACE_SEND   (0)
+#define TRACE_RECV   (1)
+#define TRACE_TIMEOUT (2)
+static void
+snmp_print_trace(slp, rp, code)
+  struct session_list *slp;
+  struct request_list *rp;
+  int code;
+{
+  int reqid=0, retries=1;
+  if( rp ){
+    reqid = rp->request_id;
+    retries = rp->retries;
+  }  
+  printf("\n Session %2d  ReqId %4d  ", slp->internal->sd, reqid);
+  switch(code)
+    { 
+    case TRACE_SEND:    printf("send pdu (%d)", retries);break; 
+    case TRACE_RECV:    printf("recv pdu");break; 
+    case TRACE_TIMEOUT: printf("time out");break; 
+    }
+  fflush(stdout);
+}
+#endif /* DEBUG_SNMPTRACE */
+
+
+
+
+/*
+ * 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.
+ */
+struct snmp_session *
+snmp_open(session)
+    struct snmp_session *session;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp;
+    u_char *cp;
+    int sd;
+    u_long addr;
+    struct sockaddr_in me;
+    struct hostent *hp;
+    struct servent *servp;
+    extern int check_received_pkt();
+
+    /* Copy session structure and link into list */
+    slp = (struct session_list *)calloc(1, sizeof(struct session_list));
+    slp->internal = isp = (struct snmp_internal_session *)calloc(1, sizeof(struct snmp_internal_session));
+    bzero((char *)isp, sizeof(struct snmp_internal_session));
+    slp->internal->sd = -1; /* mark it not set */
+    slp->session = (struct snmp_session *)calloc(1, sizeof(struct snmp_session));
+    bcopy((char *)session, (char *)slp->session, sizeof(struct snmp_session));
+    session = slp->session;
+    /* now link it in. */
+    slp->next = Sessions;
+    Sessions = slp;
+
+    /*
+     * session now points to the new structure that still contains pointers to
+     * data allocated elsewhere.  Some of this data is copied to space malloc'd
+     * here, and the pointer replaced with the new one.
+     */
+
+    if (session->peername != NULL){
+       cp = (u_char *)calloc(1, (unsigned)strlen(session->peername) + 1);
+       strcpy((char *)cp, session->peername);
+       session->peername = (char *)cp;
+    }
+
+    if (session->retries == SNMP_DEFAULT_RETRIES)
+       session->retries = SNMP_API_DEFAULT_RETRIES;
+    if (session->timeout == SNMP_DEFAULT_TIMEOUT)
+       session->timeout = SNMP_API_DEFAULT_TIMEOUT;
+    if (session->MMS == 0 )
+       session->MMS = DEFAULT_MMS;
+    isp->requests = NULL;
+
+
+    /* Fill in defaults if necessary */
+    if (session->community_len != SNMP_DEFAULT_COMMUNITY_LEN){
+       if( *session->community == '+' ) {
+               session->community_len--;
+               cp = (u_char *) calloc(1, (unsigned) session->community_len);
+               bcopy((char *) session->community+1, (char *)cp,
+                     session->community_len);
+               session->version = SNMP_VERSION_2C;
+       } else {
+               cp = (u_char *) calloc(1, (unsigned) session->community_len);
+               bcopy((char *) session->community, (char *) cp, 
+                     session->community_len);
+       }
+
+    } else {
+       session->community_len = strlen(DEFAULT_COMMUNITY);
+       cp = (u_char *)calloc(1, (unsigned)session->community_len);
+       bcopy((char *)DEFAULT_COMMUNITY, (char *)cp, session->community_len);
+    }
+
+    /* Set up connections */
+    sd = socket(AF_INET, SOCK_DGRAM, 0);
+    if (sd < 0){
+       perror("socket");
+       snmp_errno = SNMPERR_GENERR;
+       if (!snmp_close(session)){
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+           exit(1);
+       }
+       return 0;
+    }
+    isp->sd = sd;
+
+    if (session->peername != SNMP_DEFAULT_PEERNAME){
+       if ((addr = inet_addr(session->peername)) != -1){
+           bcopy((char *)&addr, (char *)&isp->addr.sin_addr, sizeof(isp->addr.sin_addr));
+       } else {
+           hp = gethostbyname(session->peername);
+           if (hp == NULL){
+               fprintf(stderr, "unknown host: %s\n", session->peername);
+               snmp_errno = SNMPERR_BAD_ADDRESS;
+               if (!snmp_close(session)){
+                   fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+                   exit(2);
+               }
+               return 0;
+           } else {
+               bcopy((char *)hp->h_addr, (char *)&isp->addr.sin_addr, hp->h_length);
+           }
+       }
+       isp->addr.sin_family = AF_INET;
+       if (session->remote_port == SNMP_DEFAULT_REMPORT){
+           /*servp = getservbyname("snmp", "udp");*/
+           servp=NULL;
+           if (servp != NULL){
+               isp->addr.sin_port = servp->s_port;
+           } else {
+               isp->addr.sin_port = htons(SNMP_PORT);
+           }
+       } else {
+           isp->addr.sin_port = htons(session->remote_port);
+       }
+    } else {
+       isp->addr.sin_addr.s_addr = SNMP_DEFAULT_ADDRESS;
+    }
+
+    me.sin_family = AF_INET;
+    me.sin_addr.s_addr = INADDR_ANY;
+    me.sin_port = htons(session->local_port);
+    if (bind(sd, (struct sockaddr *)&me, sizeof(me)) != 0){
+       perror("bind");
+       snmp_errno = SNMPERR_BAD_LOCPORT;
+       if (! snmp_close(session)){
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n", 
+                   api_errstring(snmp_errno));
+           exit(3);
+       }
+       return 0;
+    }
+
+    if( *cp == '/' ) {
+       session->authenticator = check_received_pkt;
+       sync_with_agent(session);
+       parse_app_community_string( session );
+       session->qoS |= USEC_QOS_GENREPORT;
+    }
+
+    /* replace comm pointer with pointer to new data: */
+    session->community = cp;   
+
+    return session;
+}
+
+void
+sync_with_agent( session )
+struct snmp_session *session;
+{
+    struct snmp_pdu *pdu, *response = 0;
+    int status;
+
+    session->qoS = USEC_QOS_GENREPORT;
+    session->userLen = 6;
+    session->version = SNMP_VERSION_2;
+    strcpy( session->userName, "public" );
+
+    snmp_synch_setup(session);
+    pdu = snmp_pdu_create(GET_REQ_MSG);
+    status = snmp_synch_response(session, pdu, &response);
+
+    if (status == STAT_SUCCESS){
+       memcpy( session->agentID, response->params.agentID, 12 );
+
+       /* save the clocks -- even though they are not authentic */
+       session->agentBoots = response->params.agentBoots;
+       session->agentTime = response->params.agentTime;
+       session->agentClock = response->params.agentTime - time(NULL);
+
+    } else {
+           if (status == STAT_TIMEOUT){
+               printf("No Response from %s\n", session->peername);
+           } else {    /* status == STAT_ERROR */
+               printf("An error occurred, Quitting\n");
+           }
+           exit( -1 );
+    }
+
+    /** freed to early: 
+      snmp_free_pdu(pdu);
+      if (response) snmp_free_pdu(response);
+     **/
+}
+#if 1 /***/
+/*
+ * Unlink one element from input request list,
+ * then free it and it's pdu.
+ */
+static void
+free_one_request(isp, orp)
+    struct snmp_internal_session *isp;
+    struct request_list *orp;
+{
+    struct request_list *rp;
+    if(! orp) return;
+    if(isp->requests == orp){ 
+      isp->requests = orp->next_request; /* unlink head */
+    }
+    else{
+      for(rp = isp->requests; rp; rp = rp->next_request){
+        if(rp->next_request == orp){ 
+         rp->next_request = orp->next_request; /* unlink element */
+         break;
+        }
+      }
+    }
+    if (orp->pdu != NULL){
+      snmp_free_pdu(orp->pdu);
+    }
+    free((char *)orp);
+}
+#endif /***/
+/*
+ * Free each element in the input request list.
+ */
+static void
+free_request_list(rp)
+    struct request_list *rp;
+{
+    struct request_list *orp;
+
+    while(rp){
+       orp = rp;
+       rp = rp->next_request;
+       if (orp->pdu != NULL)
+           snmp_free_pdu(orp->pdu);
+       free((char *)orp);
+    }
+}
+
+/*
+ * 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.
+ */
+int 
+snmp_close(session)
+    struct snmp_session *session;
+{
+    struct session_list *slp = NULL, *oslp = NULL;
+
+    if (Sessions->session == session){ /* If first entry */
+       slp = Sessions;
+       Sessions = slp->next;
+    } else {
+       for(slp = Sessions; slp; slp = slp->next){
+           if (slp->session == session){
+               if (oslp)   /* if we found entry that points here */
+                   oslp->next = slp->next;     /* link around this entry */
+               break;
+           }
+           oslp = slp;
+       }
+    }
+    /* If we found the session, free all data associated with it */
+    if (slp){
+       if (slp->session->community != NULL)
+           free((char *)slp->session->community);
+       if(slp->session->peername != NULL)
+           free((char *)slp->session->peername);
+       free((char *)slp->session);
+       if (slp->internal->sd != -1)
+           close(slp->internal->sd);
+       free_request_list(slp->internal->requests);
+       free((char *)slp->internal);
+       free((char *)slp);
+    } else {
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    return 1;
+}
+
+/*
+ * Takes a session and a pdu and serializes the ASN PDU into the area
+ * pointed to by packet.  out_length is the size of the data area available.
+ * Returns the length of the completed packet in out_length.  If any errors
+ * occur, -1 is returned.  If all goes well, 0 is returned.
+ */
+int
+snmp_build(session, pdu, packet, out_length, is_agent)
+    struct snmp_session        *session;
+    struct snmp_pdu    *pdu;
+    u_char     *packet;
+    int                        *out_length;
+    int                         is_agent;
+{
+    u_char  buf[PACKET_LENGTH];
+    u_char  *cp;
+    struct variable_list *vp;
+    int            length;
+    int            totallength;
+
+    length = *out_length;
+    cp = packet;
+    for(vp = pdu->variables; vp; vp = vp->next_variable){
+       cp = snmp_build_var_op(cp, vp->name, &vp->name_length, vp->type, vp->val_len, (u_char *)vp->val.string, &length);
+       if (cp == NULL)
+           return -1;
+    }
+    totallength = cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR), totallength);
+    if (cp == NULL)
+       return -1;
+    bcopy((char *)packet, (char *)cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+    if (pdu->command != TRP_REQ_MSG){
+       /* request id */
+       cp = asn_build_int(packet, &length,
+           (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+           (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (cp == NULL)
+           return -1;
+       /* error status */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (cp == NULL)
+           return -1;
+       /* error index */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (cp == NULL)
+           return -1;
+    } else {   /* this is a trap message */
+       /* enterprise */
+       cp = asn_build_objid(packet, &length,
+           (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID),
+           (oid *)pdu->enterprise, pdu->enterprise_length);
+       if (cp == NULL)
+           return -1;
+       /* agent-addr */
+       cp = asn_build_string(cp, &length, (u_char)IPADDRESS,
+               (u_char *)&pdu->agent_addr.sin_addr.s_addr, sizeof(pdu->agent_addr.sin_addr.s_addr));
+       if (cp == NULL)
+           return -1;
+       /* generic trap */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (cp == NULL)
+           return -1;
+       /* specific trap */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (cp == NULL)
+           return -1;
+       /* timestamp  */
+       cp = asn_build_int(cp, &length, (u_char)TIMETICKS,
+               (long *)&pdu->time, sizeof(pdu->time));
+       if (cp == NULL)
+           return -1;
+    }
+    if (length < totallength)
+       return -1;
+    bcopy((char *)buf, (char *)cp, totallength);
+    totallength += cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char)pdu->command, totallength);
+    if (cp == NULL)
+       return -1;
+    if (length < totallength)
+       return -1;
+    bcopy((char *)packet, (char *)cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+
+    cp = snmp_auth_build( packet, &length, session, is_agent, totallength );
+    if (cp == NULL)
+       return -1;
+    if ((*out_length - (cp - packet)) < totallength)
+       return -1;
+    bcopy((char *)buf, (char *)cp, totallength);
+    totallength += cp - packet;
+    *out_length = totallength;
+
+    if( session->qoS & USEC_QOS_AUTH )
+           md5Digest( packet, totallength, cp - (session->contextLen + 16),
+               cp - (session->contextLen + 16) );
+
+    return 0;
+}
+
+/*
+ * Parses the packet received on the input session, and places the data into
+ * the input pdu.  length is the length of the input packet.  If any errors
+ * are encountered, -1 is returned.  Otherwise, a 0 is returned.
+ */
+static int
+snmp_parse(session, pdu, data, length)
+    struct snmp_session *session;
+    struct snmp_pdu *pdu;
+    u_char  *data;
+    int            length;
+{
+    u_char  msg_type;
+    u_char  type;
+    u_char  *var_val;
+    long    version;
+    int            len, four;
+    u_char community[256];
+    int community_length = 256;
+    struct variable_list *vp = 0;
+    oid            objid[MAX_NAME_LEN], *op;
+    u_char  *origdata = data;
+    int      origlength = length;
+    int      ret = 0;
+    u_char  *save_data;
+
+    /* authenticates message and returns length if valid */
+    data = snmp_auth_parse(data, &length, community, &community_length, &version);
+    if (data == NULL)
+       return -1;
+
+   if( version != SNMP_VERSION_1 && version != SNMP_VERSION_2C && version != SNMP_VERSION_2 ) {
+           fprintf(stderr, "Wrong version: %ld\n", version);
+           return -1;
+    }
+
+    save_data = data;
+
+    data = asn_parse_header(data, &length, &msg_type);
+    if (data == NULL)
+       return -1;
+    pdu->command = msg_type;
+
+    if( session->authenticator ) {
+       ret = session->authenticator( origdata, origlength, save_data - community_length, 
+               community_length, session, pdu );
+       if( ret < 0 ) return ret;
+    }
+
+    if (pdu->command != TRP_REQ_MSG){
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (data == NULL)
+           return -1;
+    } else {
+       pdu->enterprise_length = MAX_NAME_LEN;
+       data = asn_parse_objid(data, &length, &type, objid, &pdu->enterprise_length);
+       if (data == NULL)
+           return -1;
+       pdu->enterprise = (oid *)calloc(1, pdu->enterprise_length * sizeof(oid));
+       bcopy((char *)objid, (char *)pdu->enterprise, pdu->enterprise_length * sizeof(oid));
+
+       four = 4;
+       data = asn_parse_string(data, &length, &type, (u_char *)&pdu->agent_addr.sin_addr.s_addr, &four);
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->time, sizeof(pdu->time));
+       if (data == NULL)
+           return -1;
+    }
+    data = asn_parse_header(data, &length, &type);
+    if (data == NULL)
+       return -1;
+    if (type != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR))
+       return -1;
+    while((int)length > 0){
+       if (pdu->variables == NULL){
+           pdu->variables = vp = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+       } else {
+           vp->next_variable = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+           vp = vp->next_variable;
+       }
+       vp->next_variable = NULL;
+       vp->val.string = NULL;
+       vp->name = NULL;
+       vp->name_length = MAX_NAME_LEN;
+       data = snmp_parse_var_op(data, objid, &vp->name_length, &vp->type, &vp->val_len, &var_val, (int *)&length);
+       if (data == NULL)
+           return -1;
+       op = (oid *)calloc(1, (unsigned)vp->name_length * sizeof(oid));
+       bcopy((char *)objid, (char *)op, vp->name_length * sizeof(oid));
+       vp->name = op;
+
+       len = PACKET_LENGTH;
+       switch((short)vp->type){
+           case ASN_INTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(long));
+               vp->val_len = sizeof(long);
+               asn_parse_int(var_val, &len, &vp->type, (long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER:
+           case GAUGE:
+           case TIMETICKS:
+           case UINTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(unsigned long));
+               vp->val_len = sizeof(unsigned long);
+               asn_parse_unsigned_int(var_val, &len, &vp->type, (unsigned long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER64:
+               vp->val.counter64 = (struct counter64 *)calloc(1,  sizeof(struct counter64) );
+               vp->val_len = sizeof(struct counter64);
+               asn_parse_unsigned_int64(var_val, &len, &vp->type,
+                                        (struct counter64 *)vp->val.counter64,
+                                        sizeof(*vp->val.counter64));
+               break;
+           case ASN_OCTET_STR:
+           case IPADDRESS:
+           case OPAQUE:
+           case NSAP:
+               vp->val.string = (u_char *)calloc(1, (unsigned)vp->val_len);
+               asn_parse_string(var_val, &len, &vp->type, vp->val.string, &vp->val_len);
+               break;
+           case ASN_OBJECT_ID:
+               vp->val_len = MAX_NAME_LEN;
+               asn_parse_objid(var_val, &len, &vp->type, objid, &vp->val_len);
+               vp->val_len *= sizeof(oid);
+               vp->val.objid = (oid *)calloc(1, (unsigned)vp->val_len);
+               bcopy((char *)objid, (char *)vp->val.objid, vp->val_len);
+               break;
+            case SNMP_NOSUCHOBJECT:
+            case SNMP_NOSUCHINSTANCE:
+            case SNMP_ENDOFMIBVIEW:
+           case ASN_NULL:
+               break;
+           default:
+               fprintf(stderr, "bad type returned (%x)\n", vp->type);
+               break;
+       }
+    }
+    return ret;
+}
+
+/*
+ * 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(session, pdu)
+    struct snmp_session *session;
+    struct snmp_pdu    *pdu;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp = NULL;
+    u_char  packet[PACKET_LENGTH];
+    int length = PACKET_LENGTH;
+    struct request_list *rp;
+    struct timeval tv;
+
+    for(slp = Sessions; slp; slp = slp->next){
+       if (slp->session == session){
+           isp = slp->internal;
+           break;
+       }
+    }
+
+    if (! pdu) {
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+
+    if (isp == NULL){
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG
+       || pdu->command == GET_RSP_MSG || pdu->command == SET_REQ_MSG 
+       || pdu->command == GETBULK_REQ_MSG ){
+       if (pdu->reqid == SNMP_DEFAULT_REQID)
+           pdu->reqid = ++Reqid;
+       if (pdu->errstat == SNMP_DEFAULT_ERRSTAT)
+           pdu->errstat = 0;
+       if (pdu->errindex == SNMP_DEFAULT_ERRINDEX)
+           pdu->errindex = 0;
+    } else {
+       /* fill in trap defaults */
+       pdu->reqid = 1; /* give a bogus non-error reqid for traps */
+       if (pdu->enterprise_length == SNMP_DEFAULT_ENTERPRISE_LENGTH){
+           pdu->enterprise = (oid *)calloc(1, sizeof(DEFAULT_ENTERPRISE));
+           bcopy((char *)DEFAULT_ENTERPRISE, (char *)pdu->enterprise, sizeof(DEFAULT_ENTERPRISE));
+           pdu->enterprise_length = sizeof(DEFAULT_ENTERPRISE)/sizeof(oid);
+       }
+       if (pdu->time == SNMP_DEFAULT_TIME)
+           pdu->time = DEFAULT_TIME;
+    }
+    if (pdu->address.sin_addr.s_addr == SNMP_DEFAULT_ADDRESS){
+       if (isp->addr.sin_addr.s_addr != SNMP_DEFAULT_ADDRESS){
+           bcopy((char *)&isp->addr, (char *)&pdu->address, sizeof(pdu->address));
+       } else {
+           fprintf(stderr, "No remote IP address specified\n");
+           snmp_errno = SNMPERR_BAD_ADDRESS;
+           return 0;
+       }
+    }
+       
+
+    if (snmp_build(session, pdu, packet, &length, 0) < 0){
+       fprintf(stderr, "Error building packet\n");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+#if 1 /***/
+    if (snmp_dump_packet){
+      snmp_print_packet(packet, length, pdu->address, 1);
+    }
+#endif /***/
+
+    gettimeofday(&tv, (struct timezone *)0);
+    if (sendto(isp->sd, (char *)packet, length, 0, (struct sockaddr *)&pdu->address, sizeof(pdu->address)) < 0){
+       perror("sendto");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG 
+     || pdu->command == SET_REQ_MSG || pdu->command == GETBULK_REQ_MSG ){
+       /* set up to expect a response */
+       rp = (struct request_list *)calloc(1, sizeof(struct request_list));
+#if 1 /***/
+        if(! rp){
+          fprintf(stderr, "Out of memory!\n");
+          snmp_errno = SNMPERR_GENERR;
+          return 0;
+        }
+#endif /***/
+       rp->next_request = isp->requests;
+       isp->requests = rp;
+       rp->pdu = pdu;
+       rp->request_id = pdu->reqid;
+
+       rp->retries = 1;
+       rp->timeout = session->timeout;
+       rp->time = tv;
+       tv.tv_usec += rp->timeout;
+       tv.tv_sec += tv.tv_usec / 1000000L;
+       tv.tv_usec %= 1000000L;
+       rp->expire = tv;
+#if DEBUG_SNMPTRACE
+       snmp_print_trace(slp, rp, TRACE_SEND);
+#endif
+    }
+    return pdu->reqid;
+}
+
+/*
+ * Frees the pdu and any malloc'd data associated with it.
+ */
+void
+snmp_free_pdu(struct snmp_pdu * pdu)
+{
+    struct variable_list *vp, *ovp;
+
+    if (! pdu)
+      return;
+
+    vp = pdu->variables;
+    while(vp){
+      if (vp->name) {
+       free((char *)vp->name);
+      }
+      if (vp->val.string) {
+       free((char *)vp->val.string);
+      }
+      ovp = vp;
+      vp = vp->next_variable;
+      free((char *)ovp);
+    }
+    if (pdu->enterprise) {
+      free((char *)pdu->enterprise);
+    }
+    free((char *)pdu);
+}
+
+
+/*
+ * 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(fdset)
+    fd_set  *fdset;
+{
+    struct session_list *slp;
+    struct snmp_session *sp;
+    struct snmp_internal_session *isp;
+    u_char packet[PACKET_LENGTH];
+    struct sockaddr_in from;
+    ssize_t length, fromlength;
+    struct snmp_pdu *pdu;
+    struct request_list *rp /**, *orp **/ ;
+
+    for(slp = Sessions; slp; slp = slp->next){
+       if (FD_ISSET(slp->internal->sd, fdset)){
+           sp = slp->session;
+           isp = slp->internal;
+           fromlength = sizeof(from);
+           length = recvfrom(isp->sd, (char *)packet, PACKET_LENGTH, 0, (struct sockaddr *)&from, &fromlength);
+           if (length == -1) {
+               perror("recvfrom");
+               return;
+           }
+#if 1 /***/
+               if (snmp_dump_packet) {
+               snmp_print_packet(packet, length, from, 0);
+           }
+           pdu = (struct snmp_pdu *) calloc(1, sizeof(struct snmp_pdu));
+
+           if (!pdu) {
+               fprintf(stderr, "Out of memory!\n");
+               snmp_errno = SNMPERR_GENERR;
+               return;
+           }
+#endif/***/ if we found entry that points here */
+ oslp e key!  replace...
+     */
+ * \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 1\ 1\0\0\0\0\0\0\0\19\7fÿ¯ùsnmplib/snmp_api.c\0c\0\0.h\0\0\0\18\7fÿ°\85\10\0<Ðlib/snmp_api.c~\0~\0\0ñ\0\0\0\18\7fÿ±\1e\10\0\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\0\0\0\18\7fÿ±«\10\0=\10\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\0\0\0\18\7fÿ²\1d\10\0=0\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\0\0\0\18\7fÿ²\8a\10\0=P\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\0\0\0\18\7fÿ³
+\10\0=p\7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\0\0\0\18\7fÿ³\82\0\0\0\ 1\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\0\0\0Á\7fÿ³ù\0\0\0\10\7fÿ´\10\10\0\0%\0\19\0\15\0\0\10\0D(\0\0\0\10\7fÿ´_\10\0\0\0\ 2\\0\0\0\0\10\0\0\0\0\10\7fÿ´©\10\0=\98\0\0\ 24\0\0\0\0\10\0\0\0\0\10\7fÿ´ø\10\0\0\0\ 2H\0\0\0\0\10\0\0\0\0\10\7fÿµB\10\0>\10\7fÿµ]\7fÿµm\7fÿµz\0\0\0\10\7fÿµ \10\0>(\7fÿµ·\7fÿµÉ\7fÿµÖ\0\0\0\10\7fÿµï\10\0>@\7fÿ¶\12\7fÿ¶ \7fÿ¶4\0\0\0\10\7fÿ¶P\0\0\0\ 1\7fÿ¶r\7fÿ¶~\7fÿ¶\88\0\0\00\7fÿ¶\9f\10\0\82à\7fÿ¶·\0\0\0\0\7fÿ¶Ù\10\0\7fÿ·\ 1\0\0\0\0\7fÿ·#\7fÿ·/\7fÿ·>\10\0>X\7fÿ·V\0\0\03\0\0\0\0/usr/people/wessels/.indent.pro\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\ 1\0\0\0\0\7fÿ¯è\7fÿ¯ù\7fÿ°\f\7fÿ°\e\7fÿ°.\7fÿ°?\7fÿ°M\7fÿ°[\7fÿ°p\7fÿ°\85\7fÿ°\95\7fÿ°£\7fÿ°²\7fÿ°Å\7fÿ°Û\7fÿ°ñ\7fÿ±
+\7fÿ±\1e\7fÿ±2\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\7fÿ±\99\7fÿ±«\7fÿ±º\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\7fÿ²\ f\7fÿ²\1d\7fÿ²2\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\7fÿ²\7f\7fÿ²\8a\7fÿ²\99\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\7fÿ²ö\7fÿ³
+\7fÿ³ \7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\7fÿ³s\7fÿ³\82\7fÿ³\91\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\7fÿ³ç\7fÿ³ù\7fÿ´\ 4\7fÿ´\10\7fÿ´\1e\7fÿ´)\7fÿ´3\7fÿ´C\7fÿ´O\7fÿ´_\7fÿ´k\7fÿ´t\7fÿ´\81\7fÿ´\8f\7fÿ´\9f\7fÿ´©\7fÿ´·\7fÿ´Å\7fÿ´Ò\7fÿ´Ý\7fÿ´í\7fÿ´ø\7fÿµ\ 3\7fÿµ\10\7fÿµ\1d\7fÿµ)\7fÿµ7\7fÿµB\7fÿµM\7fÿµ]\7fÿµm\7fÿµz\7fÿµ\89\7fÿµ \7fÿµ«\7fÿµ·\7fÿµÉ\7fÿµÖ\7fÿµâ\7fÿµï\7fÿ¶\ 3\7fÿ¶\12\7fÿ¶ \7fÿ¶4\7fÿ¶?\7fÿ¶P\7fÿ¶b\7fÿ¶r\7fÿ¶~\7fÿ¶\88\7fÿ¶\94\7fÿ¶\9f\7fÿ¶«\7fÿ¶·\7fÿ¶É\7fÿ¶Ù\7fÿ¶í\7fÿ·\ 1\7fÿ·\15\7fÿ·#\7fÿ·/\7fÿ·>\7fÿ·L\7fÿ·V\7fÿ·f\7fÿ·q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0@    \0\0\0\0   pdu->time = DEFAULT_TIME;
+    }
+    if (pdu->address.sin_addr.s_addr == SNMP_DEFAULT_ADDRESS){
+       if (isp->addr.sin_addr.s_addr != SNMP_DEFAULT_ADDRESS){
+           bcopy((char *)&isp->addr, (char *)&pdu->address, sizeof(pdu->address));
+       } else {
+           fprintf(stderr, "No remote IP address specified\n");
+           snmp_errno = SNMPERR_BAD_ADDRESS;
+           return 0;
+       }
+    }
+       
+
+    if (snmp_build(session, pdu, packet, &length, 0) < 0){
+       fprintf(stderr, "Error building packet\n");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+#if 1 /***/
+    if (snmp_dump_packet){
+      snmp_print_packet(packet, length, pdu->address, 1);
+    }
+#endif /***/
+
+    gettimeofday(&tv, (struct timezone *)0);
+    if (sendto(isp->sd, (char *)packet, length, 0, (struct sockaddr *)&pdu->address, sizeof(pdu->address)) < 0){
+       perror("sendto");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG 
+     || pdu->command == SET_REQ_MSG || pdu->command == GETBULK_REQ_MSG ){
+       /* set up to expect a response */
+       rp = (struct request_list *)calloc(1, sizeof(struct request_list));
+#if 1 /***/
+        if(! rp){
+          fprintf(stderr, "Out of memory!\n");
+          snmp_errno = SNMPERR_GENERR;
+          return 0;
+        }
+#endif /***/
+       rp->next_request = isp->requests;
+       isp->requests = rp;
+       rp->pdu = pdu;
+       rp->request_id = pdu->reqid;
+
+       rp->retries = 1;
+       rp->timeout = session->timeout;
+       rp->time = tv;
+       tv.tv_usec += rp->timeout;
+       tv.tv_sec += tv.tv_usec / 1000000L;
+       tv.tv_usec %= 1000000L;
+       rp->expire = tv;
+#if DEBUG_SNMPTRACE
+       snmp_print_trace(slp, rp, TRACE_SEND);
+#endif
+    }
+    return pdu->reqid;
+}
+
+/*
+ * Frees the pdu and any malloc'd data associated with it.
+ */
+void
+snmp_free_pdu(struct snmp_pdu * pdu)
+{
+    struct variable_list *vp, *ovp;
+
+    if (! pdu)
+      return;
+
+    vp = pdu->variables;
+    while(vp){
+      if (vp->name) {
+       free((char *)vp->name);
+      }
+      if (vp->val.string) {
+       free((char *)vp->val.string);
+      }
+      ovp = vp;
+      vp = vp->next_variable;
+      free((char *)ovp);
+    }
+    if (pdu->enterprise) {
+      free((char *)pdu->enterprise);
+    }
+    free((char *)pdu);
+}
+
+
+/*
+ * 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(fdset)
+    fd_set  *fdset;
+{
+    struct session_list *slp;
+    struct snmp_session *sp;
+    struct snmp_internal_session *isp;
+    u_char packet[PACKET_LENGTH];
+    struct sockaddr_in from;
+    ssize_t length, fromlength;
+    struct snmp_pdu *pdu;
+    struct request_list *rp /**, *orp **/ ;
+
+    for(slp = Sessions; slp; slp = slp->next){
+       if (FD_ISSET(slp->internal->sd, fdset)){
+           sp = slp->session;
+           isp = slp->internal;
+           fromlength = sizeof(from);
+           length = recvfrom(isp->sd, (char *)packet, PACKET_LENGTH, 0, (struct sockaddr *)&from, &fromlength);
+           if (length == -1) {
+               perror("recvfrom");
+               return;
+           }
+#if 1 /***/
+               if (snmp_dump_packet) {
+               snmp_print_packet(packet, length, from, 0);
+           }
+           pdu = (struct snmp_pdu *) calloc(1, sizeof(struct snmp_pdu));
+
+           if (!pdu) {
+               fprintf(stderr, "Out of memory!\n");
+               snmp_errno = SNMPERR_GENERR;
+               return;
+           }
+ == STAT_TIMEOUT){
+               printf("No Response from %s\n", session->peername);
+           } else {    /* status == STAT_ERROR */
+               printf("An error occurred, Quitting\n");
+           }
+           exit( -1 );
+    }
+
+    /** freed to early: 
+      snmp_free_pdu(pdu);
+      if (response) snmp_free_pdu(response);
+     **/
+}
+#if 1 /***/
+/*
+ * Unlink one element from input request list,
+ * then free it and it's pdu.
+ */
+static void
+free_one_request(isp, orp)
+    struct snmp_internal_session *isp;
+    struct request_list *orp;
+{
+    struct request_list *rp;
+    if(! orp) return;
+    if(isp->requests == orp){ 
+      isp->requests = orp->next_request; /* unlink head */
+    }
+    else{
+      for(rp = isp->requests; rp; rp = rp->next_request){
+        if(rp->next_request == orp){ 
+         rp->next_request = orp->next_request; /* unlink element */
+         break;
+        }
+      }
+    }
+    if (orp->pdu != NULL){
+      snmp_free_pdu(orp->pdu);
+    }
+    free((char *)orp);
+}
+#endif /***/
+/*
+ * Free each element in the input request list.
+ */
+static void
+free_request_list(rp)
+    struct request_list *rp;
+{
+    struct request_list *orp;
+
+    while(rp){
+       orp = rp;
+       rp = rp->next_request;
+       if (orp->pdu != NULL)
+           snmp_free_pdu(orp->pdu);
+       free((char *)orp);
+    }
+}
+
+/*
+ * 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.
+ */
+int 
+snmp_close(session)
+    struct snmp_session *session;
+{
+    struct session_list *slp = NULL, *oslp = NULL;
+
+    if (Sessions->session == session){ /* If first entry */
+       slp = Sessions;
+       Sessions = slp->next;
+    } else {
+       for(slp = Sessions; slp; slp = slp->next){
+           if (slp->session == session){
+               if (oslp)   /* if we found entry that points here */
+                   oslp->next = slp->next;     /* link around this entry */
+               break;
+           }
+           oslp = slp;
+       }
+    }
+    /* If we found the session, free all data associated with it */
+    if (slp){
+       if (slp->session->community != NULL)
+           free((char *)slp->session->community);
+       if(slp->session->peername != NULL)
+           free((char *)slp->session->peername);
+       free((char *)slp->session);
+       if (slp->internal->sd != -1)
+           close(slp->internal->sd);
+       free_request_list(slp->internal->requests);
+       free((char *)slp->internal);
+       free((char *)slp);
+    } else {
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    return 1;
+}
+
+/*
+ * Takes a session and a pdu and serializes the ASN PDU into the area
+ * pointed to by packet.  out_length is the size of the data area available.
+ * Returns the length of the completed packet in out_length.  If any errors
+ * occur, -1 is returned.  If all goes well, 0 is returned.
+ */
+int
+snmp_build(session, pdu, packet, out_length, is_agent)
+    struct snmp_session        *session;
+    struct snmp_pdu    *pdu;
+    u_char     *packet;
+    int                        *out_length;
+    int                         is_agent;
+{
+    u_char  buf[PACKET_LENGTH];
+    u_char  *cp;
+    struct variable_list *vp;
+    int            length;
+    int            totallength;
+
+    length = *out_length;
+    cp = packet;
+    for(vp = pdu->variables; vp; vp = vp->next_variable){
+       cp = snmp_build_var_op(cp, vp->name, &vp->name_length, vp->type, vp->val_len, (u_char *)vp->val.string, &length);
+       if (cp == NULL)
+           return -1;
+    }
+    totallength = cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR), totallength);
+    if (cp == NULL)
+       return -1;
+    bcopy((char *)packet, (char *)cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+    if (pdu->command != TRP_REQ_MSG){
+       /* request id */
+       cp = asn_build_int(packet, &length,
+           (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+           (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (cp == NULL)
+           return -1;
+       /* error status */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (cp == NULL)
+           return -1;
+       /* error index */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (cp == NULL)
+           return -1;
+    } else {   /* this is a trap message */
+       /* enterprise */
+       cp = asn_build_objid(packet, &length,
+           (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID),
+           (oid *)pdu->enterprise, pdu->enterprise_length);
+       if (cp == NULL)
+           return -1;
+       /* agent-addr */
+       cp = asn_build_string(cp, &length, (u_char)IPADDRESS,
+               (u_char *)&pdu->agent_addr.sin_addr.s_addr, sizeof(pdu->agent_addr.sin_addr.s_addr));
+       if (cp == NULL)
+           return -1;
+       /* generic trap */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (cp == NULL)
+           return -1;
+       /* specific trap */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (cp == NULL)
+           return -1;
+       /* timestamp  */
+       cp = asn_build_int(cp, &length, (u_char)TIMETICKS,
+               (long *)&pdu->time, sizeof(pdu->time));
+       if (cp == NULL)
+           return -1;
+    }
+    if (length < totallength)
+       return -1;
+    bcopy((char *)buf, (char *)cp, totallength);
+    totallength += cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char)pdu->command, totallength);
+    if (cp == NULL)
+       return -1;
+    if (length < totallength)
+       return -1;
+    bcopy((char *)packet, (char *)cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+
+    cp = snmp_auth_build( packet, &length, session, is_agent, totallength );
+    if (cp == NULL)
+       return -1;
+    if ((*out_length - (cp - packet)) < totallength)
+       return -1;
+    bcopy((char *)buf, (char *)cp, totallength);
+    totallength += cp - packet;
+    *out_length = totallength;
+
+    if( session->qoS & USEC_QOS_AUTH )
+           md5Digest( packet, totallength, cp - (session->contextLen + 16),
+               cp - (session->contextLen + 16) );
+
+    return 0;
+}
+
+/*
+ * Parses the packet received on the input session, and places the data into
+ * the input pdu.  length is the length of the input packet.  If any errors
+ * are encountered, -1 is returned.  Otherwise, a 0 is returned.
+ */
+static int
+snmp_parse(session, pdu, data, length)
+    struct snmp_session *session;
+    struct snmp_pdu *pdu;
+    u_char  *data;
+    int            length;
+{
+    u_char  msg_type;
+    u_char  type;
+    u_char  *var_val;
+    long    version;
+    int            len, four;
+    u_char community[256];
+    int community_length = 256;
+    struct variable_list *vp = 0;
+    oid            objid[MAX_NAME_LEN], *op;
+    u_char  *origdata = data;
+    int      origlength = length;
+    int      ret = 0;
+    u_char  *save_data;
+
+    /* authenticates message and returns length if valid */
+    data = snmp_auth_parse(data, &length, community, &community_length, &version);
+    if (data == NULL)
+       return -1;
+
+   if( version != SNMP_VERSION_1 && version != SNMP_VERSION_2C && version != SNMP_VERSION_2 ) {
+           fprintf(stderr, "Wrong version: %ld\n", version);
+           return -1;
+    }
+
+    save_data = data;
+
+    data = asn_parse_header(data, &length, &msg_type);
+    if (data == NULL)
+       return -1;
+    pdu->command = msg_type;
+
+    if( session->authenticator ) {
+       ret = session->authenticator( origdata, origlength, save_data - community_length, 
+               community_length, session, pdu );
+       if( ret < 0 ) return ret;
+    }
+
+    if (pdu->command != TRP_REQ_MSG){
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (data == NULL)
+           return -1;
+    } else {
+       pdu->enterprise_length = MAX_NAME_LEN;
+       data = asn_parse_objid(data, &length, &type, objid, &pdu->enterprise_length);
+       if (data == NULL)
+           return -1;
+       pdu->enterprise = (oid *)calloc(1, pdu->enterprise_length * sizeof(oid));
+       bcopy((char *)objid, (char *)pdu->enterprise, pdu->enterprise_length * sizeof(oid));
+
+       four = 4;
+       data = asn_parse_string(data, &length, &type, (u_char *)&pdu->agent_addr.sin_addr.s_addr, &four);
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->time, sizeof(pdu->time));
+       if (data == NULL)
+           return -1;
+    }
+    data = asn_parse_header(data, &length, &type);
+    if (data == NULL)
+       return -1;
+    if (type != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR))
+       return -1;
+    while((int)length > 0){
+       if (pdu->variables == NULL){
+           pdu->variables = vp = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+       } else {
+           vp->next_variable = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+           vp = vp->next_variable;
+       }
+       vp->next_variable = NULL;
+       vp->val.string = NULL;
+       vp->name = NULL;
+       vp->name_length = MAX_NAME_LEN;
+       data = snmp_parse_var_op(data, objid, &vp->name_length, &vp->type, &vp->val_len, &var_val, (int *)&length);
+       if (data == NULL)
+           return -1;
+       op = (oid *)calloc(1, (unsigned)vp->name_length * sizeof(oid));
+       bcopy((char *)objid, (char *)op, vp->name_length * sizeof(oid));
+       vp->name = op;
+
+       len = PACKET_LENGTH;
+       switch((short)vp->type){
+           case ASN_INTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(long));
+               vp->val_len = sizeof(long);
+               asn_parse_int(var_val, &len, &vp->type, (long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER:
+           case GAUGE:
+           case TIMETICKS:
+           case UINTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(unsigned long));
+               vp->val_len = sizeof(unsigned long);
+               asn_parse_unsigned_int(var_val, &len, &vp->type, (unsigned long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER64:
+               vp->val.counter64 = (struct counter64 *)calloc(1,  sizeof(struct counter64) );
+               vp->val_len = sizeof(struct counter64);
+               asn_parse_unsigned_int64(var_val, &len, &vp->type,
+                                        (struct counter64 *)vp->val.counter64,
+                                        sizeof(*vp->val.counter64));
+               break;
+           case ASN_OCTET_STR:
+           case IPADDRESS:
+           case OPAQUE:
+           case NSAP:
+               vp->val.string = (u_char *)calloc(1, (unsigned)vp->val_len);
+               asn_parse_string(var_val, &len, &vp->type, vp->val.string, &vp->val_len);
+               break;
+           case ASN_OBJECT_ID:
+               vp->val_len = MAX_NAME_LEN;
+               asn_parse_objid(var_val, &len, &vp->type, objid, &vp->val_len);
+               vp->val_len *= sizeof(oid);
+               vp->val.objid = (oid *)calloc(1, (unsigned)vp->val_len);
+               bcopy((char *)objid, (char *)vp->val.objid, vp->val_len);
+               break;
+            case SNMP_NOSUCHOBJECT:
+            case SNMP_NOSUCHINSTANCE:
+            case SNMP_ENDOFMIBVIEW:
+           case ASN_NULL:
+               break;
+           default:
+               fprintf(stderr, "bad type returned (%x)\n", vp->type);
+               break;
+       }
+    }
+    return ret;
+}
+
+/*
+ * 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(session, pdu)
+    struct snmp_session *session;
+    struct snmp_pdu    *pdu;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp = NULL;
+    u_char  packet[PACKET_LENGTH];
+    int length = PACKET_LENGTH;
+    struct request_list *rp;
+    struct timeval tv;
+
+    for(slp = Sessions; slp; slp = slp->next){
+       if (slp->session == session){
+           isp = slp->internal;
+           break;
+       }
+    }
+
+    if (! pdu) {
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+
+    if (isp == NULL){
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG
+       || pdu->command == GET_RSP_MSG || pdu->command == SET_REQ_MSG 
+       || pdu->command == GETBULK_REQ_MSG ){
+       if (pdu->reqid == SNMP_DEFAULT_REQID)
+           pdu->reqid = ++Reqid;
+       if (pdu->errstat == SNMP_DEFAULT_ERRSTAT)
+           pdu->errstat = 0;
+       if (pdu->errindex == SNMP_DEFAULT_ERRINDEX)
+           pdu->errindex = 0;
+    } else {
+       /* fill in trap defaults */
+       pdu->reqid = 1; /* give a bogus non-error reqid for traps */
+       if (pdu->enterprise_length == SNMP_DEFAULT_ENTERPRISE_LENGTH){
+           pdu->enterprise = (oid *)calloc(1, sizeof(DEFAULT_ENTERPRISE));
+           bcopy((char *)DEFAULT_ENTERPRISE, (char *)pdu->enterprise, sizeof(DEFAULT_ENTERPRISE));
+           pdu->enterprise_length = sizeof(DEFAULT_ENTERPRISE)/sizeof(oid);
+       }
+       if (pdu->time == SNMP_DEFAULT_TIME)
+        \10\0BÐ+= m\0\0
+È      /* \0\0\0\0*/ B\10\0>XNMPT\10\ 1Ôè */c\0\0\0\0for testing purposes */e key!  replace...
+     */
+ * \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 1\ 1\0\0\0\0\0\0\0\19\7fÿ¯ùsnmplib/snmp_api.c\0c\0\0.h\0\0\0\18\7fÿ°\85\10\0<Ðlib/snmp_api.c~\0~\0\0ñ\0\0\0\18\7fÿ±\1e\10\0\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\0\0\0\18\7fÿ±«\10\0=\10\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\0\0\0\18\7fÿ²\1d\10\0=0\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\0\0\0\18\7fÿ²\8a\10\0=P\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\0\0\0\18\7fÿ³
+\10\0=p\7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\0\0\0\18\7fÿ³\82\0\0\0\ 1\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\0\0\0Á\7fÿ³ù\0\0\0\10\7fÿ´\10\10\0\0%\0\19\0\15\0\0\10\0D(\0\0\0\10\7fÿ´_\10\0\0\0\ 2\\0\0\0\0\10\0\0\0\0\10\7fÿ´©\10\0=\98\0\0\ 24\0\0\0\0\10\0\0\0\0\10\7fÿ´ø\10\0\0\0\ 2H\0\0\0\0\10\0\0\0\0\10\7fÿµB\10\0>\10\7fÿµ]\7fÿµm\7fÿµz\0\0\0\10\7fÿµ \10\0>(\7fÿµ·\7fÿµÉ\7fÿµÖ\0\0\0\10\7fÿµï\10\0>@\7fÿ¶\12\7fÿ¶ \7fÿ¶4\0\0\0\10\7fÿ¶P\0\0\0\ 1\7fÿ¶r\7fÿ¶~\7fÿ¶\88\0\0\00\7fÿ¶\9f\10\0\7fÿ¶·\0\0\0\0\7fÿ¶Ù\10\0\89è\7fÿ·\ 1\0\0\0\0\7fÿ·#\7fÿ·/\7fÿ·>\10\0>X\7fÿ·V\0\0\03\0\0\0\0/usr/people/wessels/.indent.pro\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\ 1\0\0\0\0\7fÿ¯è\7fÿ¯ù\7fÿ°\f\7fÿ°\e\7fÿ°.\7fÿ°?\7fÿ°M\7fÿ°[\7fÿ°p\7fÿ°\85\7fÿ°\95\7fÿ°£\7fÿ°²\7fÿ°Å\7fÿ°Û\7fÿ°ñ\7fÿ±
+\7fÿ±\1e\7fÿ±2\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\7fÿ±\99\7fÿ±«\7fÿ±º\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\7fÿ²\ f\7fÿ²\1d\7fÿ²2\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\7fÿ²\7f\7fÿ²\8a\7fÿ²\99\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\7fÿ²ö\7fÿ³
+\7fÿ³ \7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\7fÿ³s\7fÿ³\82\7fÿ³\91\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\7fÿ³ç\7fÿ³ù\7fÿ´\ 4\7fÿ´\10\7fÿ´\1e\7fÿ´)\7fÿ´3\7fÿ´C\7fÿ´O\7fÿ´_\7fÿ´k\7fÿ´t\7fÿ´\81\7fÿ´\8f\7fÿ´\9f\7fÿ´©\7fÿ´·\7fÿ´Å\7fÿ´Ò\7fÿ´Ý\7fÿ´í\7fÿ´ø\7fÿµ\ 3\7fÿµ\10\7fÿµ\1d\7fÿµ)\7fÿµ7\7fÿµB\7fÿµM\7fÿµ]\7fÿµm\7fÿµz\7fÿµ\89\7fÿµ \7fÿµ«\7fÿµ·\7fÿµÉ\7fÿµÖ\7fÿµâ\7fÿµï\7fÿ¶\ 3\7fÿ¶\12\7fÿ¶ \7fÿ¶4\7fÿ¶?\7fÿ¶P\7fÿ¶b\7fÿ¶r\7fÿ¶~\7fÿ¶\88\7fÿ¶\94\7fÿ¶\9f\7fÿ¶«\7fÿ¶·\7fÿ¶É\7fÿ¶Ù\7fÿ¶í\7fÿ·\ 1\7fÿ·\15\7fÿ·#\7fÿ·/\7fÿ·>\7fÿ·L\7fÿ·V\7fÿ·f\7fÿ·q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\0\0\0°\0\0\0\ 4\0\0\0\0\0\0\0\b\10\0>X\0\0\0\f\10\0\0\0\0\10\0\0\0\0\0\0\0\14\0\0\0\14\0\0\0\14\0\0\0\18\0\0\0\18\0\0\0\18\0\0\0\1c\0\0\0\1c\0\0\0\1c\0\0\0\1c\0\0\0 \0\0\0 \0\0\0 \0\0\0$\0\0\0\v\0\0\0\e\0\0\0\19\0\0\0\v\0\0\0\e\0\0\0@\0\0\0\0\0\0\0\0\0\0\0\0\10\0,\b\0\0\0\1a\10\02\88\0\0\0\1a\0\0\0\0\0\0\0\1a\10\0\85\b\0\0\0\0\10\0>X\0\0\0\0\0\0\0\0\0\0\0\0\10\0\82à\0\0\0\0\0\0\ 1C\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e0\0\0\0\v\0\0\0\e\0\0\0\18\0\0\0\v\0\0\0\1a\0\0\0\17\0\0\0\v\0\0\0 \0\0\0\0\10\0\8d¸ude/snmp_groupvars.h~\0\0\b\0\0\0\b\0\0\0 \0\0\0\0\10\0\8dàude/snmp_groupvars.h\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8eX\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e\80\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e¨\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8eÐ\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\0\0\0\ 1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\84©\0\0\0\0/***********************************************************
+       Copyright 1989 by Carnegie Mellon University
+
+                      All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the name of CMU not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+******************************************************************/
+/*
+ * snmp_api.c - API for access to snmp.
+ */
+#define DEBUG_SNMPTRACE                0 /* set to 1 to print all SNMP actions */
+#define DEBUG_SNMPFULLDUMP     0 /* set to 1 to dump all SNMP packets */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#ifdef linux
+#include <arpa/inet.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#endif
+
+
+#include "asn1.h"
+#include "snmp.h"
+#include "snmp_impl.h"
+#include "snmp_api.h"
+#include "snmp_client.h"
+
+#define PACKET_LENGTH  4500
+
+#ifndef BSD4_3
+#define BSD4_2
+#endif
+
+#if !defined(BSD4_3) && !defined(linux) && !defined(sun)
+
+typedef long   fd_mask;
+#define NFDBITS        (sizeof(fd_mask) * NBBY)        /* bits per mask */
+
+#define        FD_SET(n, p)    ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+#define        FD_CLR(n, p)    ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+#define        FD_ISSET(n, p)  ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+#define FD_ZERO(p)     bzero((char *)(p), sizeof(*(p)))
+#endif
+
+oid default_enterprise[] = {1, 3, 6, 1, 4, 1, 3, 1, 1}; /* enterprises.cmu.systems.cmuSNMP */
+
+#define DEFAULT_COMMUNITY   "public"
+#define DEFAULT_REMPORT            SNMP_PORT
+#define DEFAULT_ENTERPRISE  default_enterprise
+#define DEFAULT_TIME       0
+#define DEFAULT_MMS        1389 /* large, randomly picked for testing purposes */
+
+/*
+ * Internal information about the state of the snmp session.
+ */
+struct snmp_internal_session {
+    int            sd;         /* socket descriptor for this connection */
+    ipaddr  addr;      /* address of connected peer */
+    struct request_list *requests;/* Info about outstanding requests */
+};
+
+/*
+ * A list of all the outstanding requests for a particular session.
+ */
+struct request_list {
+    struct request_list *next_request;
+    u_long  request_id;        /* request id */
+    int            retries;    /* Number of retries */
+    u_long timeout;    /* length to wait for timeout */
+    struct timeval time; /* Time this request was made */
+    struct timeval expire;  /* time this request is due to expire */
+    struct snmp_pdu *pdu;   /* The pdu for this request (saved so it can be retransmitted */
+};
+
+/*
+ * The list of active/open sessions.
+ */
+struct session_list {
+    struct session_list *next;
+    struct snmp_session *session;
+    struct snmp_internal_session *internal;
+};
+
+struct session_list *Sessions = NULL;
+
+u_long Reqid = 0;
+int snmp_errno = 0;
+
+char *api_errors[4] = {
+    "Unknown session",
+    "Unknown host",
+    "Invalid local port",
+    "Unknown Error"
+};
+
+
+void sync_with_agent();
+int parse_app_community_string();
+void snmp_synch_setup();
+int snmp_synch_response();
+void md5Digest();
+
+
+static char *
+api_errstring(snmp_errnumber)
+    int        snmp_errnumber;
+{
+    if (snmp_errnumber <= SNMPERR_BAD_SESSION && snmp_errnumber >= SNMPERR_GENERR){
+       return api_errors[snmp_errnumber + 4];
+    } else {
+       return "Unknown Error";
+    }
+}
+
+#if 0
+/*
+ * Gets initial request ID for all transactions.
+ */
+static void
+init_snmp(){
+    struct timeval tv;
+
+    gettimeofday(&tv, (struct timezone *)0);
+    srandom(tv.tv_sec ^ tv.tv_usec);
+    Reqid = random();
+}
+#endif
+
+
+/*
+ * Dump snmp packet to stdout:
+ */
+static void
+snmp_print_packet(packet, length, addr, code)
+  char *packet; 
+  int length; 
+  ipaddr addr; 
+  int code;
+{
+  if(length < 0) {
+    return;
+  }
+  if (code <= 0) { /* received */
+    printf("\nReceived %4d bytes from ", length);
+  }
+  else { /* sending */
+    printf("\nSending  %4d bytes to   ", length);
+  }
+  printf("%s:", inet_ntoa(addr.sin_addr));
+#if DEBUG_SNMPFULLDUMP
+  for (count = 0; count < length; count++) {
+    if ((count & 15) == 0) {
+      printf("\n  ");
+    }
+    printf("%02X ", (int)(packet[count]&255));
+  }
+#endif
+  fflush(stdout);
+}
+
+#if DEBUG_SNMPTRACE
+/*
+ * Print request
+ */
+#define TRACE_SEND   (0)
+#define TRACE_RECV   (1)
+#define TRACE_TIMEOUT (2)
+static void
+snmp_print_trace(slp, rp, code)
+  struct session_list *slp;
+  struct request_list *rp;
+  int code;
+{
+  int reqid=0, retries=1;
+  if( rp ){
+    reqid = rp->request_id;
+    retries = rp->retries;
+  }  
+  printf("\n Session %2d  ReqId %4d  ", slp->internal->sd, reqid);
+  switch(code)
+    { 
+    case TRACE_SEND:    printf("send pdu (%d)", retries);break; 
+    case TRACE_RECV:    printf("recv pdu");break; 
+    case TRACE_TIMEOUT: printf("time out");break; 
+    }
+  fflush(stdout);
+}
+#endif /* DEBUG_SNMPTRACE */
+
+
+
+
+/*
+ * 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.
+ */
+struct snmp_session *
+snmp_open(session)
+    struct snmp_session *session;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp;
+    u_char *cp;
+    int sd;
+    u_long addr;
+    struct sockaddr_in me;
+    struct hostent *hp;
+    struct servent *servp;
+    extern int check_received_pkt();
+
+    /* Copy session structure and link into list */
+    slp = (struct session_list *)calloc(1, sizeof(struct session_list));
+    slp->internal = isp = (struct snmp_internal_session *)calloc(1, sizeof(struct snmp_internal_session));
+    bzero((char *)isp, sizeof(struct snmp_internal_session));
+    slp->internal->sd = -1; /* mark it not set */
+    slp->session = (struct snmp_session *)calloc(1, sizeof(struct snmp_session));
+    bcopy((char *)session, (char *)slp->session, sizeof(struct snmp_session));
+    session = slp->session;
+    /* now link it in. */
+    slp->next = Sessions;
+    Sessions = slp;
+
+    /*
+     * session now points to the new structure that still contains pointers to
+     * data allocated elsewhere.  Some of this data is copied to space malloc'd
+     * here, and the pointer replaced with the new one.
+     */
+
+    if (session->peername != NULL){
+       cp = (u_char *)calloc(1, (unsigned)strlen(session->peername) + 1);
+       strcpy((char *)cp, session->peername);
+       session->peername = (char *)cp;
+    }
+
+    if (session->retries == SNMP_DEFAULT_RETRIES)
+       session->retries = SNMP_API_DEFAULT_RETRIES;
+    if (session->timeout == SNMP_DEFAULT_TIMEOUT)
+       session->timeout = SNMP_API_DEFAULT_TIMEOUT;
+    if (session->MMS == 0 )
+       session->MMS = DEFAULT_MMS;
+    isp->requests = NULL;
+
+
+    /* Fill in defaults if necessary */
+    if (session->community_len != SNMP_DEFAULT_COMMUNITY_LEN){
+       if( *session->community == '+' ) {
+               session->community_len--;
+               cp = (u_char *) calloc(1, (unsigned) session->community_len);
+               bcopy((char *) session->community+1, (char *)cp,
+                     session->community_len);
+               session->version = SNMP_VERSION_2C;
+       } else {
+               cp = (u_char *) calloc(1, (unsigned) session->community_len);
+               bcopy((char *) session->community, (char *) cp, 
+                     session->community_len);
+       }
+
+    } else {
+       session->community_len = strlen(DEFAULT_COMMUNITY);
+       cp = (u_char *)calloc(1, (unsigned)session->community_len);
+       bcopy((char *)DEFAULT_COMMUNITY, (char *)cp, session->community_len);
+    }
+
+    /* Set up connections */
+    sd = socket(AF_INET, SOCK_DGRAM, 0);
+    if (sd < 0){
+       perror("socket");
+       snmp_errno = SNMPERR_GENERR;
+       if (!snmp_close(session)){
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+           exit(1);
+       }
+       return 0;
+    }
+    isp->sd = sd;
+
+    if (session->peername != SNMP_DEFAULT_PEERNAME){
+       if ((addr = inet_addr(session->peername)) != -1){
+           bcopy((char *)&addr, (char *)&isp->addr.sin_addr, sizeof(isp->addr.sin_addr));
+       } else {
+           hp = gethostbyname(session->peername);
+           if (hp == NULL){
+               fprintf(stderr, "unknown host: %s\n", session->peername);
+               snmp_errno = SNMPERR_BAD_ADDRESS;
+               if (!snmp_close(session)){
+                   fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+                   exit(2);
+               }
+               return 0;
+           } else {
+               bcopy((char *)hp->h_addr, (char *)&isp->addr.sin_addr, hp->h_length);
+           }
+       }
+       isp->addr.sin_family = AF_INET;
+       if (session->remote_port == SNMP_DEFAULT_REMPORT){
+           /*servp = getservbyname("snmp", "udp");*/
+           servp=NULL;
+           if (servp != NULL){
+               isp->addr.sin_port = servp->s_port;
+           } else {
+               isp->addr.sin_port = htons(SNMP_PORT);
+           }
+       } else {
+           isp->addr.sin_port = htons(session->remote_port);
+       }
+    } else {
+       isp->addr.sin_addr.s_addr = SNMP_DEFAULT_ADDRESS;
+    }
+
+    me.sin_family = AF_INET;
+    me.sin_addr.s_addr = INADDR_ANY;
+    me.sin_port = htons(session->local_port);
+    if (bind(sd, (struct sockaddr *)&me, sizeof(me)) != 0){
+       perror("bind");
+       snmp_errno = SNMPERR_BAD_LOCPORT;
+       if (! snmp_close(session)){
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n", 
+                   api_errstring(snmp_errno));
+           exit(3);
+       }
+       return 0;
+    }
+
+    if( *cp == '/' ) {
+       session->authenticator = check_received_pkt;
+       sync_with_agent(session);
+       parse_app_community_string( session );
+       session->qoS |= USEC_QOS_GENREPORT;
+    }
+
+    /* replace comm pointer with pointer to new data: */
+    session->community = cp;   
+
+    return session;
+}
+
+void
+sync_with_agent( session )
+struct snmp_session *session;
+{
+    struct snmp_pdu *pdu, *response = 0;
+    int status;
+
+    session->qoS = USEC_QOS_GENREPORT;
+    session->userLen = 6;
+    session->version = SNMP_VERSION_2;
+    strcpy( session->userName, "public" );
+
+    snmp_synch_setup(session);
+    pdu = snmp_pdu_create(GET_REQ_MSG);
+    status = snmp_synch_response(session, pdu, &response);
+
+    if (status == STAT_SUCCESS){
+       memcpy( session->agentID, response->params.agentID, 12 );
+
+       /* save the clocks -- even though they are not authentic */
+       session->agentBoots = response->params.agentBoots;
+       session->agentTime = response->params.agentTime;
+       session->agentClock = response->params.agentTime - time(NULL);
+
+    } else {
+           if (status == STAT_TIMEOUT){
+               printf("No Response from %s\n", session->peername);
+           } else {    /* status == STAT_ERROR */
+               printf("An error occurred, Quitting\n");
+           }
+           exit( -1 );
+    }
+
+    /** freed to early: 
+      snmp_free_pdu(pdu);
+      if (response) snmp_free_pdu(response);
+     **/
+}
+#if 1 /***/
+/*
+ * Unlink one element from input request list,
+ * then free it and it's pdu.
+ */
+static void
+free_one_request(isp, orp)
+    struct snmp_internal_session *isp;
+    struct request_list *orp;
+{
+    struct request_list *rp;
+    if(! orp) return;
+    if(isp->requests == orp){ 
+      isp->requests = orp->next_request; /* unlink head */
+    }
+    else{
+      for(rp = isp->requests; rp; rp = rp->next_request){
+        if(rp->next_request == orp){ 
+         rp->next_request = orp->next_request; /* unlink element */
+         break;
+        }
+      }
+    }
+    if (orp->pdu != NULL){
+      snmp_free_pdu(orp->pdu);
+    }
+    free((char *)orp);
+}
+#endif /***/
+/*
+ * Free each element in the input request list.
+ */
+static void
+free_request_list(rp)
+    struct request_list *rp;
+{
+    struct request_list *orp;
+
+    while(rp){
+       orp = rp;
+       rp = rp->next_request;
+       if (orp->pdu != NULL)
+           snmp_free_pdu(orp->pdu);
+       free((char *)orp);
+    }
+}
+
+/*
+ * 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.
+ */
+int 
+snmp_close(session)
+    struct snmp_session *session;
+{
+    struct session_list *slp = NULL, *oslp = NULL;
+
+    if (Sessions->session == session){ /* If first entry */
+       slp = Sessions;
+       Sessions = slp->next;
+    } else {
+       for(slp = Sessions; slp; slp = slp->next){
+           if (slp->session == session){
+               if (oslp)   /* if we found entry that points here */
+                   oslp->next = slp->next;     /* link around this entry */
+               break;
+           }
+           oslp = slp;
+       }
+    }
+    /* If we found the session, free all data associated with it */
+    if (slp){
+       if (slp->session->community != NULL)
+           free((char *)slp->session->community);
+       if(slp->session->peername != NULL)
+           free((char *)slp->session->peername);
+       free((char *)slp->session);
+       if (slp->internal->sd != -1)
+           close(slp->internal->sd);
+       free_request_list(slp->internal->requests);
+       free((char *)slp->internal);
+       free((char *)slp);
+    } else {
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    return 1;
+}
+
+/*
+ * Takes a session and a pdu and serializes the ASN PDU into the area
+ * pointed to by packet.  out_length is the size of the data area available.
+ * Returns the length of the completed packet in out_length.  If any errors
+ * occur, -1 is returned.  If all goes well, 0 is returned.
+ */
+int
+snmp_build(session, pdu, packet, out_length, is_agent)
+    struct snmp_session        *session;
+    struct snmp_pdu    *pdu;
+    u_char     *packet;
+    int                        *out_length;
+    int                         is_agent;
+{
+    u_char  buf[PACKET_LENGTH];
+    u_char  *cp;
+    struct variable_list *vp;
+    int            length;
+    int            totallength;
+
+    length = *out_length;
+    cp = packet;
+    for(vp = pdu->variables; vp; vp = vp->next_variable){
+       cp = snmp_build_var_op(cp, vp->name, &vp->name_length, vp->type, vp->val_len, (u_char *)vp->val.string, &length);
+       if (cp == NULL)
+           return -1;
+    }
+    totallength = cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR), totallength);
+    if (cp == NULL)
+       return -1;
+    bcopy((char *)packet, (char *)cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+    if (pdu->command != TRP_REQ_MSG){
+       /* request id */
+       cp = asn_build_int(packet, &length,
+           (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+           (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (cp == NULL)
+           return -1;
+       /* error status */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (cp == NULL)
+           return -1;
+       /* error index */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (cp == NULL)
+           return -1;
+    } else {   /* this is a trap message */
+       /* enterprise */
+       cp = asn_build_objid(packet, &length,
+           (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID),
+           (oid *)pdu->enterprise, pdu->enterprise_length);
+       if (cp == NULL)
+           return -1;
+       /* agent-addr */
+       cp = asn_build_string(cp, &length, (u_char)IPADDRESS,
+               (u_char *)&pdu->agent_addr.sin_addr.s_addr, sizeof(pdu->agent_addr.sin_addr.s_addr));
+       if (cp == NULL)
+           return -1;
+       /* generic trap */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (cp == NULL)
+           return -1;
+       /* specific trap */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (cp == NULL)
+           return -1;
+       /* timestamp  */
+       cp = asn_build_int(cp, &length, (u_char)TIMETICKS,
+               (long *)&pdu->time, sizeof(pdu->time));
+       if (cp == NULL)
+           return -1;
+    }
+    if (length < totallength)
+       return -1;
+    bcopy((char *)buf, (char *)cp, totallength);
+    totallength += cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char)pdu->command, totallength);
+    if (cp == NULL)
+       return -1;
+    if (length < totallength)
+       return -1;
+    bcopy((char *)packet, (char *)cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+
+    cp = snmp_auth_build( packet, &length, session, is_agent, totallength );
+    if (cp == NULL)
+       return -1;
+    if ((*out_length - (cp - packet)) < totallength)
+       return -1;
+    bcopy((char *)buf, (char *)cp, totallength);
+    totallength += cp - packet;
+    *out_length = totallength;
+
+    if( session->qoS & USEC_QOS_AUTH )
+           md5Digest( packet, totallength, cp - (session->contextLen + 16),
+               cp - (session->contextLen + 16) );
+
+    return 0;
+}
+
+/*
+ * Parses the packet received on the input session, and places the data into
+ * the input pdu.  length is the length of the input packet.  If any errors
+ * are encountered, -1 is returned.  Otherwise, a 0 is returned.
+ */
+static int
+snmp_parse(session, pdu, data, length)
+    struct snmp_session *session;
+    struct snmp_pdu *pdu;
+    u_char  *data;
+    int            length;
+{
+    u_char  msg_type;
+    u_char  type;
+    u_char  *var_val;
+    long    version;
+    int            len, four;
+    u_char community[256];
+    int community_length = 256;
+    struct variable_list *vp = 0;
+    oid            objid[MAX_NAME_LEN], *op;
+    u_char  *origdata = data;
+    int      origlength = length;
+    int      ret = 0;
+    u_char  *save_data;
+
+    /* authenticates message and returns length if valid */
+    data = snmp_auth_parse(data, &length, community, &community_length, &version);
+    if (data == NULL)
+       return -1;
+
+   if( version != SNMP_VERSION_1 && version != SNMP_VERSION_2C && version != SNMP_VERSION_2 ) {
+           fprintf(stderr, "Wrong version: %ld\n", version);
+           return -1;
+    }
+
+    save_data = data;
+
+    data = asn_parse_header(data, &length, &msg_type);
+    if (data == NULL)
+       return -1;
+    pdu->command = msg_type;
+
+    if( session->authenticator ) {
+       ret = session->authenticator( origdata, origlength, save_data - community_length, 
+               community_length, session, pdu );
+       if( ret < 0 ) return ret;
+    }
+
+    if (pdu->command != TRP_REQ_MSG){
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (data == NULL)
+           return -1;
+    } else {
+       pdu->enterprise_length = MAX_NAME_LEN;
+       data = asn_parse_objid(data, &length, &type, objid, &pdu->enterprise_length);
+       if (data == NULL)
+           return -1;
+       pdu->enterprise = (oid *)calloc(1, pdu->enterprise_length * sizeof(oid));
+       bcopy((char *)objid, (char *)pdu->enterprise, pdu->enterprise_length * sizeof(oid));
+
+       four = 4;
+       data = asn_parse_string(data, &length, &type, (u_char *)&pdu->agent_addr.sin_addr.s_addr, &four);
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->time, sizeof(pdu->time));
+       if (data == NULL)
+           return -1;
+    }
+    data = asn_parse_header(data, &length, &type);
+    if (data == NULL)
+       return -1;
+    if (type != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR))
+       return -1;
+    while((int)length > 0){
+       if (pdu->variables == NULL){
+           pdu->variables = vp = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+       } else {
+           vp->next_variable = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+           vp = vp->next_variable;
+       }
+       vp->next_variable = NULL;
+       vp->val.string = NULL;
+       vp->name = NULL;
+       vp->name_length = MAX_NAME_LEN;
+       data = snmp_parse_var_op(data, objid, &vp->name_length, &vp->type, &vp->val_len, &var_val, (int *)&length);
+       if (data == NULL)
+           return -1;
+       op = (oid *)calloc(1, (unsigned)vp->name_length * sizeof(oid));
+       bcopy((char *)objid, (char *)op, vp->name_length * sizeof(oid));
+       vp->name = op;
+
+       len = PACKET_LENGTH;
+       switch((short)vp->type){
+           case ASN_INTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(long));
+               vp->val_len = sizeof(long);
+               asn_parse_int(var_val, &len, &vp->type, (long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER:
+           case GAUGE:
+           case TIMETICKS:
+           case UINTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(unsigned long));
+               vp->val_len = sizeof(unsigned long);
+               asn_parse_unsigned_int(var_val, &len, &vp->type, (unsigned long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER64:
+               vp->val.counter64 = (struct counter64 *)calloc(1,  sizeof(struct counter64) );
+               vp->val_len = sizeof(struct counter64);
+               asn_parse_unsigned_int64(var_val, &len, &vp->type,
+                                        (struct counter64 *)vp->val.counter64,
+                                        sizeof(*vp->val.counter64));
+               break;
+           case ASN_OCTET_STR:
+           case IPADDRESS:
+           case OPAQUE:
+           case NSAP:
+               vp->val.string = (u_char *)calloc(1, (unsigned)vp->val_len);
+               asn_parse_string(var_val, &len, &vp->type, vp->val.string, &vp->val_len);
+               break;
+           case ASN_OBJECT_ID:
+               vp->val_len = MAX_NAME_LEN;
+               asn_parse_objid(var_val, &len, &vp->type, objid, &vp->val_len);
+               vp->val_len *= sizeof(oid);
+               vp->val.objid = (oid *)calloc(1, (unsigned)vp->val_len);
+               bcopy((char *)objid, (char *)vp->val.objid, vp->val_len);
+               break;
+            case SNMP_NOSUCHOBJECT:
+            case SNMP_NOSUCHINSTANCE:
+            case SNMP_ENDOFMIBVIEW:
+           case ASN_NULL:
+               break;
+           default:
+               fprintf(stderr, "bad type returned (%x)\n", vp->type);
+               break;
+       }
+    }
+    return ret;
+}
+
+/*
+ * 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(session, pdu)
+    struct snmp_session *session;
+    struct snmp_pdu    *pdu;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp = NULL;
+    u_char  packet[PACKET_LENGTH];
+    int length = PACKET_LENGTH;
+    struct request_list *rp;
+    struct timeval tv;
+
+    for(slp = Sessions; slp; slp = slp->next){
+       if (slp->session == session){
+           isp = slp->internal;
+           break;
+       }
+    }
+
+    if (! pdu) {
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+
+    if (isp == NULL){
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG
+       || pdu->command == GET_RSP_MSG || pdu->command == SET_REQ_MSG 
+       || pdu->command == GETBULK_REQ_MSG ){
+       if (pdu->reqid == SNMP_DEFAULT_REQID)
+           pdu->reqid = ++Reqid;
+       if (pdu->errstat == SNMP_DEFAULT_ERRSTAT)
+           pdu->errstat = 0;
+       if (pdu->errindex == SNMP_DEFAULT_ERRINDEX)
+           pdu->errindex = 0;
+    } else {
+       /* fill in trap defaults */
+       pdu->reqid = 1; /* give a bogus non-error reqid for traps */
+       if (pdu->enterprise_length == SNMP_DEFAULT_ENTERPRISE_LENGTH){
+           pdu->enterprise = (oid *)calloc(1, sizeof(DEFAULT_ENTERPRISE));
+           bcopy((char *)DEFAULT_ENTERPRISE, (char *)pdu->enterprise, sizeof(DEFAULT_ENTERPRISE));
+           pdu->enterprise_length = sizeof(DEFAULT_ENTERPRISE)/sizeof(oid);
+       }
+       if (pdu->time == SNMP_DEFAULT_TIME)
+           pdu->time = DEFAULT_TIME;
+    }
+    if (pdu->address.sin_addr.s_addr == SNMP_DEFAULT_ADDRESS){
+       if (isp->addr.sin_addr.s_addr != SNMP_DEFAULT_ADDRESS){
+           bcopy((char *)&isp->addr, (char *)&pdu->address, sizeof(pdu->address));
+       } else {
+           fprintf(stderr, "No remote IP address specified\n");
+           snmp_errno = SNMPERR_BAD_ADDRESS;
+           return 0;
+       }
+    }
+       
+
+    if (snmp_build(session, pdu, packet, &length, 0) < 0){
+       fprintf(stderr, "Error building packet\n");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+#if 1 /***/
+    if (snmp_dump_packet){
+      snmp_print_packet(packet, length, pdu->address, 1);
+    }
+#endif /***/
+
+    gettimeofday(&tv, (struct timezone *)0);
+    if (sendto(isp->sd, (char *)packet, length, 0, (struct sockaddr *)&pdu->address, sizeof(pdu->address)) < 0){
+       perror("sendto");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG 
+     || pdu->command == SET_REQ_MSG || pdu->command == GETBULK_REQ_MSG ){
+       /* set up to expect a response */
+       rp = (struct request_list *)calloc(1, sizeof(struct request_list));
+#if 1 /***/
+        if(! rp){
+          fprintf(stderr, "Out of memory!\n");
+          snmp_errno = SNMPERR_GENERR;
+          return 0;
+        }
+#endif /***/
+       rp->next_request = isp->requests;
+       isp->requests = rp;
+       rp->pdu = pdu;
+       rp->request_id = pdu->reqid;
+
+       rp->retries = 1;
+       rp->timeout = session->timeout;
+       rp->time = tv;
+       tv.tv_usec += rp->timeout;
+       tv.tv_sec += tv.tv_usec / 1000000L;
+       tv.tv_usec %= 1000000L;
+       rp->expire = tv;
+#if DEBUG_SNMPTRACE
+       snmp_print_trace(slp, rp, TRACE_SEND);
+#endif
+    }
+    return pdu->reqid;
+}
+
+/*
+ * Frees the pdu and any malloc'd data associated with it.
+ */
+void
+snmp_free_pdu(struct snmp_pdu * pdu)
+{
+    struct variable_list *vp, *ovp;
+
+    if (! pdu)
+      return;
+
+    vp = pdu->variables;
+    while(vp){
+      if (vp->name) {
+       free((char *)vp->name);
+      }
+      if (vp->val.string) {
+       free((char *)vp->val.string);
+      }
+      ovp = vp;
+      vp = vp->next_variable;
+      free((char *)ovp);
+    }
+    if (pdu->enterprise) {
+      free((char *)pdu->enterprise);
+    }
+    free((char *)pdu);
+}
+
+
+/*
+ * 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(fdset)
+    fd_set  *fdset;
+{
+    struct session_list *slp;
+    struct snmp_session *sp;
+    struct snmp_internal_session *isp;
+    u_char packet[PACKET_LENGTH];
+    struct sockaddr_in from;
+    ssize_t length, fromlength;
+    struct snmp_pdu *pdu;
+    struct request_list *rp /**, *orp **/ ;
+
+    for(slp = Sessions; slp; slp = slp->next){
+       if (FD_ISSET(slp->internal->sd, fdset)){
+           sp = slp->session;
+           isp = slp->internal;
+           fromlength = sizeof(from);
+           length = recvfrom(isp->sd, (char *)packet, PACKET_LENGTH, 0, (struct sockaddr *)&from, &fromlength);
+           if (length == -1) {
+               perror("recvfrom");
+               return;
+           }
+#if 1 /***/
+           if (snmp_dump_packet){
+             snmp_print_packet(packet, length, from, 0);
+           }
+           pdu = (struct snmp_pdu *)calloc(1, sizeof(struct snmp_pdu));
+
+           if(! pdu){
+             fprintf(stderr, "Out of memory!\n");
+             snmp_errno = SNMPERR_GENERR;
+             return;
+           }
+#endif /***/
+
+               pdu->address = from;
+           pdu->reqid = 0;
+           pdu->variables = NULL;
+           pdu->enterprise = NULL;
+           pdu->enterprise_length = 0;
+           if (snmp_parse(sp, pdu, packet, length) < 0) {
+               fprintf(stderr, "Mangled packet\n");
+               snmp_free_pdu(pdu);
+               return;
+           }
+           if (pdu->command == GET_RSP_MSG || pdu->command == REPORT_MSG) {
+#if 1 /***/                    /* bug fix: illegal re-use of rp killed some requests */
+               struct request_list *rp_next = 0;
+               for (rp = isp->requests; rp; rp = rp_next) {
+                   rp_next = rp->next_request;
+                   if (rp->request_id == pdu->reqid) {
+#if DEBUG_SNMPTRACE
+                       snmp_print_trace(slp, rp, TRACE_RECV);
+#endif
+                       if (sp->callback(RECEIVED_MESSAGE, sp, pdu->reqid, pdu, sp->callback_magic) == 1) {
+                           /* successful, so delete request */
+                           free_one_request(isp, rp);
+                           break;      /* no more request with the same reqid */
+                       }
+                   }
+               }
+#endif/***/ g fix: illegal re-use of rp killed some requests */ replace...
+     */
+ * \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 1\ 1\0\0\0\0\0\0\0\19\7fÿ¯ùsnmplib/snmp_api.c\0c\0\0.h\0\0\0\18\7fÿ°\85\10\0<Ðlib/snmp_api.c~\0~\0\0ñ\0\0\0\18\7fÿ±\1e\10\0\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\0\0\0\18\7fÿ±«\10\0=\10\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\0\0\0\18\7fÿ²\1d\10\0=0\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\0\0\0\18\7fÿ²\8a\10\0=P\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\0\0\0\18\7fÿ³
+\10\0=p\7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\0\0\0\18\7fÿ³\82\0\0\0\ 1\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\0\0\0Á\7fÿ³ù\0\0\0\10\7fÿ´\10\10\0\0%\0\19\0\15\0\0\10\0D(\0\0\0\10\7fÿ´_\10\0\0\0\ 2\\0\0\0\0\10\0\0\0\0\10\7fÿ´©\10\0=\98\0\0\ 24\0\0\0\0\10\0\0\0\0\10\7fÿ´ø\10\0\0\0\ 2H\0\0\0\0\10\0\0\0\0\10\7fÿµB\10\0>\10\7fÿµ]\7fÿµm\7fÿµz\0\0\0\10\7fÿµ \10\0>(\7fÿµ·\7fÿµÉ\7fÿµÖ\0\0\0\10\7fÿµï\10\0>@\7fÿ¶\12\7fÿ¶ \7fÿ¶4\0\0\0\10\7fÿ¶P\0\0\0\ 1\7fÿ¶r\7fÿ¶~\7fÿ¶\88\0\0\00\7fÿ¶\9f\0\0\0\0\7fÿ¶·\0\0\0\0\7fÿ¶Ù\10\0\82à\7fÿ·\ 1\0\0\0\0\7fÿ·#\7fÿ·/\7fÿ·>\10\0>X\7fÿ·V\0\0\03\0\0\0\0/usr/people/wessels/.indent.pro\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\ 1\0\0\0\0\7fÿ¯è\7fÿ¯ù\7fÿ°\f\7fÿ°\e\7fÿ°.\7fÿ°?\7fÿ°M\7fÿ°[\7fÿ°p\7fÿ°\85\7fÿ°\95\7fÿ°£\7fÿ°²\7fÿ°Å\7fÿ°Û\7fÿ°ñ\7fÿ±
+\7fÿ±\1e\7fÿ±2\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\7fÿ±\99\7fÿ±«\7fÿ±º\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\7fÿ²\ f\7fÿ²\1d\7fÿ²2\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\7fÿ²\7f\7fÿ²\8a\7fÿ²\99\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\7fÿ²ö\7fÿ³
+\7fÿ³ \7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\7fÿ³s\7fÿ³\82\7fÿ³\91\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\7fÿ³ç\7fÿ³ù\7fÿ´\ 4\7fÿ´\10\7fÿ´\1e\7fÿ´)\7fÿ´3\7fÿ´C\7fÿ´O\7fÿ´_\7fÿ´k\7fÿ´t\7fÿ´\81\7fÿ´\8f\7fÿ´\9f\7fÿ´©\7fÿ´·\7fÿ´Å\7fÿ´Ò\7fÿ´Ý\7fÿ´í\7fÿ´ø\7fÿµ\ 3\7fÿµ\10\7fÿµ\1d\7fÿµ)\7fÿµ7\7fÿµB\7fÿµM\7fÿµ]\7fÿµm\7fÿµz\7fÿµ\89\7fÿµ \7fÿµ«\7fÿµ·\7fÿµÉ\7fÿµÖ\7fÿµâ\7fÿµï\7fÿ¶\ 3\7fÿ¶\12\7fÿ¶ \7fÿ¶4\7fÿ¶?\7fÿ¶P\7fÿ¶b\7fÿ¶r\7fÿ¶~\7fÿ¶\88\7fÿ¶\94\7fÿ¶\9f\7fÿ¶«\7fÿ¶·\7fÿ¶É\7fÿ¶Ù\7fÿ¶í\7fÿ·\ 1\7fÿ·\15\7fÿ·#\7fÿ·/\7fÿ·>\7fÿ·L\7fÿ·V\7fÿ·f\7fÿ·q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0@    \0\0\0\0calloc(1, sizeof(DEFAULT_ENTERPRISE));
+           bcopy((char *)DEFAULT_ENTERPRISE, (char *)pdu->enterprise, sizeof(DEFAULT_ENTERPRISE));
+           pdu->enterprise_length = sizeof(DEFAULT_ENTERPRISE)/sizeof(oid);
+       }
+       if (pdu->time == SNMP_DEFAULT_TIME)
+           pdu->time = DEFAULT_TIME;
+    }
+    if (pdu->address.sin_addr.s_addr == SNMP_DEFAULT_ADDRESS){
+       if (isp->addr.sin_addr.s_addr != SNMP_DEFAULT_ADDRESS){
+           bcopy((char *)&isp->addr, (char *)&pdu->address, sizeof(pdu->address));
+       } else {
+           fprintf(stderr, "No remote IP address specified\n");
+           snmp_errno = SNMPERR_BAD_ADDRESS;
+           return 0;
+       }
+    }
+       
+
+    if (snmp_build(session, pdu, packet, &length, 0) < 0){
+       fprintf(stderr, "Error building packet\n");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+#if 1 /***/
+    if (snmp_dump_packet){
+      snmp_print_packet(packet, length, pdu->address, 1);
+    }
+#endif /***/
+
+    gettimeofday(&tv, (struct timezone *)0);
+    if (sendto(isp->sd, (char *)packet, length, 0, (struct sockaddr *)&pdu->address, sizeof(pdu->address)) < 0){
+       perror("sendto");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG 
+     || pdu->command == SET_REQ_MSG || pdu->command == GETBULK_REQ_MSG ){
+       /* set up to expect a response */
+       rp = (struct request_list *)calloc(1, sizeof(struct request_list));
+#if 1 /***/
+        if(! rp){
+          fprintf(stderr, "Out of memory!\n");
+          snmp_errno = SNMPERR_GENERR;
+          return 0;
+        }
+#endif /***/
+       rp->next_request = isp->requests;
+       isp->requests = rp;
+       rp->pdu = pdu;
+       rp->request_id = pdu->reqid;
+
+       rp->retries = 1;
+       rp->timeout = session->timeout;
+       rp->time = tv;
+       tv.tv_usec += rp->timeout;
+       tv.tv_sec += tv.tv_usec / 1000000L;
+       tv.tv_usec %= 1000000L;
+       rp->expire = tv;
+#if DEBUG_SNMPTRACE
+       snmp_print_trace(slp, rp, TRACE_SEND);
+#endif
+    }
+    return pdu->reqid;
+}
+
+/*
+ * Frees the pdu and any malloc'd data associated with it.
+ */
+void
+snmp_free_pdu(struct snmp_pdu * pdu)
+{
+    struct variable_list *vp, *ovp;
+
+    if (! pdu)
+      return;
+
+    vp = pdu->variables;
+    while(vp){
+      if (vp->name) {
+       free((char *)vp->name);
+      }
+      if (vp->val.string) {
+       free((char *)vp->val.string);
+      }
+      ovp = vp;
+      vp = vp->next_variable;
+      free((char *)ovp);
+    }
+    if (pdu->enterprise) {
+      free((char *)pdu->enterprise);
+    }
+    free((char *)pdu);
+}
+
+
+/*
+ * 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(fdset)
+    fd_set  *fdset;
+{
+    struct session_list *slp;
+    struct snmp_session *sp;
+    struct snmp_internal_session *isp;
+    u_char packet[PACKET_LENGTH];
+    struct sockaddr_in from;
+    ssize_t length, fromlength;
+    struct snmp_pdu *pdu;
+    struct request_list *rp /**, *orp **/ ;
+
+    for(slp = Sessions; slp; slp = slp->next){
+       if (FD_ISSET(slp->internal->sd, fdset)){
+           sp = slp->session;
+           isp = slp->internal;
+           fromlength = sizeof(from);
+           length = recvfrom(isp->sd, (char *)packet, PACKET_LENGTH, 0, (struct sockaddr *)&from, &fromlength);
+           if (length == -1) {
+               perror("recvfrom");
+               return;
+           }
+#if 1 /***/
+           if (snmp_dump_packet){
+             snmp_print_packet(packet, length, from, 0);
+           }
+           pdu = (struct snmp_pdu *)calloc(1, sizeof(struct snmp_pdu));
+
+           if(! pdu){
+             fprintf(stderr, "Out of memory!\n");
+             snmp_errno = SNMPERR_GENERR;
+             return;
+           }
+#endif /***/
+
+               pdu->address = from;
+           pdu->reqid = 0;
+           pdu->variables = NULL;
+           pdu->enterprise = NULL;
+           pdu->enterprise_length = 0;
+           if (snmp_parse(sp, pdu, packet, length) < 0) {
+               fprintf(stderr, "Mangled packet\n");
+               snmp_free_pdu(pdu);
+               return;
+           }
+           if (pdu->command == GET_RSP_MSG || pdu->command == REPORT_MSG) {
+#if 1 /***/                    /* bug fix: illegal re-use of rp killed some requests */
+               struct request_list *rp_next = 0;
+               for (rp = isp->requests; rp; rp = rp_next) {
+                   rp_next = rp->next_request;
+                   if (rp->request_id == pdu->reqid) {
+#if DEBUG_SNMPTRACE
+                       snmp_print_trace(slp, rp, TRACE_RECV);
+#endif
+                       if (sp->callback(RECEIVED_MESSAGE, sp, pdu->reqid, pdu, sp->callback_magic) == 1) {
+                           /* successful, so delete request */
+                           free_one_request(isp, rp);
+                           break;      /* no more request with the same reqid */
+                       }
+                   }
+               }
+>pdu);
+    }
+    free((char *)orp);
+}
+#endif /***/
+/*
+ * Free each element in the input request list.
+ */
+static void
+free_request_list(rp)
+    struct request_list *rp;
+{
+    struct request_list *orp;
+
+    while(rp){
+       orp = rp;
+       rp = rp->next_request;
+       if (orp->pdu != NULL)
+           snmp_free_pdu(orp->pdu);
+       free((char *)orp);
+    }
+}
+
+/*
+ * 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.
+ */
+int 
+snmp_close(session)
+    struct snmp_session *session;
+{
+    struct session_list *slp = NULL, *oslp = NULL;
+
+    if (Sessions->session == session){ /* If first entry */
+       slp = Sessions;
+       Sessions = slp->next;
+    } else {
+       for(slp = Sessions; slp; slp = slp->next){
+           if (slp->session == session){
+               if (oslp)   /* if we found entry that points here */
+                   oslp->next = slp->next;     /* link around this entry */
+               break;
+           }
+           oslp = slp;
+       }
+    }
+    /* If we found the session, free all data associated with it */
+    if (slp){
+       if (slp->session->community != NULL)
+           free((char *)slp->session->community);
+       if(slp->session->peername != NULL)
+           free((char *)slp->session->peername);
+       free((char *)slp->session);
+       if (slp->internal->sd != -1)
+           close(slp->internal->sd);
+       free_request_list(slp->internal->requests);
+       free((char *)slp->internal);
+       free((char *)slp);
+    } else {
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    return 1;
+}
+
+/*
+ * Takes a session and a pdu and serializes the ASN PDU into the area
+ * pointed to by packet.  out_length is the size of the data area available.
+ * Returns the length of the completed packet in out_length.  If any errors
+ * occur, -1 is returned.  If all goes well, 0 is returned.
+ */
+int
+snmp_build(session, pdu, packet, out_length, is_agent)
+    struct snmp_session        *session;
+    struct snmp_pdu    *pdu;
+    u_char     *packet;
+    int                        *out_length;
+    int                         is_agent;
+{
+    u_char  buf[PACKET_LENGTH];
+    u_char  *cp;
+    struct variable_list *vp;
+    int            length;
+    int            totallength;
+
+    length = *out_length;
+    cp = packet;
+    for(vp = pdu->variables; vp; vp = vp->next_variable){
+       cp = snmp_build_var_op(cp, vp->name, &vp->name_length, vp->type, vp->val_len, (u_char *)vp->val.string, &length);
+       if (cp == NULL)
+           return -1;
+    }
+    totallength = cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR), totallength);
+    if (cp == NULL)
+       return -1;
+    bcopy((char *)packet, (char *)cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+    if (pdu->command != TRP_REQ_MSG){
+       /* request id */
+       cp = asn_build_int(packet, &length,
+           (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+           (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (cp == NULL)
+           return -1;
+       /* error status */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (cp == NULL)
+           return -1;
+       /* error index */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (cp == NULL)
+           return -1;
+    } else {   /* this is a trap message */
+       /* enterprise */
+       cp = asn_build_objid(packet, &length,
+           (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID),
+           (oid *)pdu->enterprise, pdu->enterprise_length);
+       if (cp == NULL)
+           return -1;
+       /* agent-addr */
+       cp = asn_build_string(cp, &length, (u_char)IPADDRESS,
+               (u_char *)&pdu->agent_addr.sin_addr.s_addr, sizeof(pdu->agent_addr.sin_addr.s_addr));
+       if (cp == NULL)
+           return -1;
+       /* generic trap */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (cp == NULL)
+           return -1;
+       /* specific trap */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (cp == NULL)
+           return -1;
+       /* timestamp  */
+       cp = asn_build_int(cp, &length, (u_char)TIMETICKS,
+               (long *)&pdu->time, sizeof(pdu->time));
+       if (cp == NULL)
+           return -1;
+    }
+    if (length < totallength)
+       return -1;
+    bcopy((char *)buf, (char *)cp, totallength);
+    totallength += cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char)pdu->command, totallength);
+    if (cp == NULL)
+       return -1;
+    if (length < totallength)
+       return -1;
+    bcopy((char *)packet, (char *)cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+
+    cp = snmp_auth_build( packet, &length, session, is_agent, totallength );
+    if (cp == NULL)
+       return -1;
+    if ((*out_length - (cp - packet)) < totallength)
+       return -1;
+    bcopy((char *)buf, (char *)cp, totallength);
+    totallength += cp - packet;
+    *out_length = totallength;
+
+    if( session->qoS & USEC_QOS_AUTH )
+           md5Digest( packet, totallength, cp - (session->contextLen + 16),
+               cp - (session->contextLen + 16) );
+
+    return 0;
+}
+
+/*
+ * Parses the packet received on the input session, and places the data into
+ * the input pdu.  length is the length of the input packet.  If any errors
+ * are encountered, -1 is returned.  Otherwise, a 0 is returned.
+ */
+static int
+snmp_parse(session, pdu, data, length)
+    struct snmp_session *session;
+    struct snmp_pdu *pdu;
+    u_char  *data;
+    int            length;
+{
+    u_char  msg_type;
+    u_char  type;
+    u_char  *var_val;
+    long    version;
+    int            len, four;
+    u_char community[256];
+    int community_length = 256;
+    struct variable_list *vp = 0;
+    oid            objid[MAX_NAME_LEN], *op;
+    u_char  *origdata = data;
+    int      origlength = length;
+    int      ret = 0;
+    u_char  *save_data;
+
+    /* authenticates message and returns length if valid */
+    data = snmp_auth_parse(data, &length, community, &community_length, &version);
+    if (data == NULL)
+       return -1;
+
+   if( version != SNMP_VERSION_1 && version != SNMP_VERSION_2C && version != SNMP_VERSION_2 ) {
+           fprintf(stderr, "Wrong version: %ld\n", version);
+           return -1;
+    }
+
+    save_data = data;
+
+    data = asn_parse_header(data, &length, &msg_type);
+    if (data == NULL)
+       return -1;
+    pdu->command = msg_type;
+
+    if( session->authenticator ) {
+       ret = session->authenticator( origdata, origlength, save_data - community_length, 
+               community_length, session, pdu );
+       if( ret < 0 ) return ret;
+    }
+
+    if (pdu->command != TRP_REQ_MSG){
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (data == NULL)
+           return -1;
+    } else {
+       pdu->enterprise_length = MAX_NAME_LEN;
+       data = asn_parse_objid(data, &length, &type, objid, &pdu->enterprise_length);
+       if (data == NULL)
+           return -1;
+       pdu->enterprise = (oid *)calloc(1, pdu->enterprise_length * sizeof(oid));
+       bcopy((char *)objid, (char *)pdu->enterprise, pdu->enterprise_length * sizeof(oid));
+
+       four = 4;
+       data = asn_parse_string(data, &length, &type, (u_char *)&pdu->agent_addr.sin_addr.s_addr, &four);
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->time, sizeof(pdu->time));
+       if (data == NULL)
+           return -1;
+    }
+    data = asn_parse_header(data, &length, &type);
+    if (data == NULL)
+       return -1;
+    if (type != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR))
+       return -1;
+    while((int)length > 0){
+       if (pdu->variables == NULL){
+           pdu->variables = vp = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+       } else {
+           vp->next_variable = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+           vp = vp->next_variable;
+       }
+       vp->next_variable = NULL;
+       vp->val.string = NULL;
+       vp->name = NULL;
+       vp->name_length = MAX_NAME_LEN;
+       data = snmp_parse_var_op(data, objid, &vp->name_length, &vp->type, &vp->val_len, &var_val, (int *)&length);
+       if (data == NULL)
+           return -1;
+       op = (oid *)calloc(1, (unsigned)vp->name_length * sizeof(oid));
+       bcopy((char *)objid, (char *)op, vp->name_length * sizeof(oid));
+       vp->name = op;
+
+       len = PACKET_LENGTH;
+       switch((short)vp->type){
+           case ASN_INTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(long));
+               vp->val_len = sizeof(long);
+               asn_parse_int(var_val, &len, &vp->type, (long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER:
+           case GAUGE:
+           case TIMETICKS:
+           case UINTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(unsigned long));
+               vp->val_len = sizeof(unsigned long);
+               asn_parse_unsigned_int(var_val, &len, &vp->type, (unsigned long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER64:
+               vp->val.counter64 = (struct counter64 *)calloc(1,  sizeof(struct counter64) );
+               vp->val_len = sizeof(struct counter64);
+               asn_parse_unsigned_int64(var_val, &len, &vp->type,
+                                        (struct counter64 *)vp->val.counter64,
+                                        sizeof(*vp->val.counter64));
+               break;
+           case ASN_OCTET_STR:
+           case IPADDRESS:
+           case OPAQUE:
+           case NSAP:
+               vp->val.string = (u_char *)calloc(1, (unsigned)vp->val_len);
+               asn_parse_string(var_val, &len, &vp->type, vp->val.string, &vp->val_len);
+               break;
+           case ASN_OBJECT_ID:
+               vp->val_len = MAX_NAME_LEN;
+               asn_parse_objid(var_val, &len, &vp->type, objid, &vp->val_len);
+               vp->val_len *= sizeof(oid);
+               vp->val.objid = (oid *)calloc(1, (unsigned)vp->val_len);
+               bcopy((char *)objid, (char *)vp->val.objid, vp->val_len);
+               break;
+            case SNMP_NOSUCHOBJECT:
+            case SNMP_NOSUCHINSTANCE:
+            case SNMP_ENDOFMIBVIEW:
+           case ASN_NULL:
+               break;
+           default:
+               fprintf(stderr, "bad type returned (%x)\n", vp->type);
+               break;
+       }
+    }
+    return ret;
+}
+
+/*
+ * 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(session, pdu)
+    struct snmp_session *session;
+    struct snmp_pdu    *pdu;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp = NULL;
+    u_char  packet[PACKET_LENGTH];
+    int length = PACKET_LENGTH;
+    struct request_list *rp;
+    struct timeval tv;
+
+    for(slp = Sessions; slp; slp = slp->next){
+       if (slp->session == session){
+           isp = slp->internal;
+           break;
+       }
+    }
+
+    if (! pdu) {
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+
+    if (isp == NULL){
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG
+       || pdu->command == GET_RSP_MSG || pdu->command == SET_REQ_MSG 
+       || pdu->command == GETBULK_REQ_MSG ){
+       if (pdu->reqid == SNMP_DEFAULT_REQID)
+           pdu->reqid = ++Reqid;
+       if (pdu->errstat == SNMP_DEFAULT_ERRSTAT)
+           pdu->errstat = 0;
+       if (pdu->errindex == SNMP_DEFAULT_ERRINDEX)
+           pdu->errindex = 0;
+    } else {
+       /* fill in trap defaults */
+       pdu->reqid = 1; /* give a bogus non-error reqid for traps */
+       if (pdu->enterprise_length == SNMP_DEFAULT_ENTERPRISE_LENGTH){
+           pdu->enterprise = (oid *)\10\0BÐ+= m\0\0
+È      /* \10\0>X*/ B\10\07\0NMPT\10\ 1Ôè */c\0\0\0\0for testing purposes */e key!  replace...
+     */
+ * \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 1\ 1\0\0\0\0\0\0\0\19\7fÿ¯ùsnmplib/snmp_api.c\0c\0\0.h\0\0\0\18\7fÿ°\85\10\0<Ðlib/snmp_api.c~\0~\0\0ñ\0\0\0\18\7fÿ±\1e\10\0\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\0\0\0\18\7fÿ±«\10\0=\10\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\0\0\0\18\7fÿ²\1d\10\0=0\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\0\0\0\18\7fÿ²\8a\10\0=P\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\0\0\0\18\7fÿ³
+\10\0=p\7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\0\0\0\18\7fÿ³\82\0\0\0\ 1\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\0\0\0Á\7fÿ³ù\0\0\0\10\7fÿ´\10\10\0\0%\0\19\0\15\0\0\10\0D(\0\0\0\10\7fÿ´_\10\0\0\0\ 2\\0\0\0\0\10\0\0\0\0\10\7fÿ´©\10\0=\98\0\0\ 24\0\0\0\0\10\0\0\0\0\10\7fÿ´ø\10\0\0\0\ 2H\0\0\0\0\10\0\0\0\0\10\7fÿµB\10\0>\10\7fÿµ]\7fÿµm\7fÿµz\0\0\0\10\7fÿµ \10\0>(\7fÿµ·\7fÿµÉ\7fÿµÖ\0\0\0\10\7fÿµï\10\0>@\7fÿ¶\12\7fÿ¶ \7fÿ¶4\0\0\0\10\7fÿ¶P\0\0\0\ 1\7fÿ¶r\7fÿ¶~\7fÿ¶\88\0\0\00\7fÿ¶\9f\10\0\7fÿ¶·\0\0\0\0\7fÿ¶Ù\10\0\89è\7fÿ·\ 1\0\0\0\0\7fÿ·#\7fÿ·/\7fÿ·>\10\0>X\7fÿ·V\0\0\03\0\0\0\0/usr/people/wessels/.indent.pro\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\ 1\0\0\0\0\7fÿ¯è\7fÿ¯ù\7fÿ°\f\7fÿ°\e\7fÿ°.\7fÿ°?\7fÿ°M\7fÿ°[\7fÿ°p\7fÿ°\85\7fÿ°\95\7fÿ°£\7fÿ°²\7fÿ°Å\7fÿ°Û\7fÿ°ñ\7fÿ±
+\7fÿ±\1e\7fÿ±2\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\7fÿ±\99\7fÿ±«\7fÿ±º\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\7fÿ²\ f\7fÿ²\1d\7fÿ²2\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\7fÿ²\7f\7fÿ²\8a\7fÿ²\99\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\7fÿ²ö\7fÿ³
+\7fÿ³ \7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\7fÿ³s\7fÿ³\82\7fÿ³\91\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\7fÿ³ç\7fÿ³ù\7fÿ´\ 4\7fÿ´\10\7fÿ´\1e\7fÿ´)\7fÿ´3\7fÿ´C\7fÿ´O\7fÿ´_\7fÿ´k\7fÿ´t\7fÿ´\81\7fÿ´\8f\7fÿ´\9f\7fÿ´©\7fÿ´·\7fÿ´Å\7fÿ´Ò\7fÿ´Ý\7fÿ´í\7fÿ´ø\7fÿµ\ 3\7fÿµ\10\7fÿµ\1d\7fÿµ)\7fÿµ7\7fÿµB\7fÿµM\7fÿµ]\7fÿµm\7fÿµz\7fÿµ\89\7fÿµ \7fÿµ«\7fÿµ·\7fÿµÉ\7fÿµÖ\7fÿµâ\7fÿµï\7fÿ¶\ 3\7fÿ¶\12\7fÿ¶ \7fÿ¶4\7fÿ¶?\7fÿ¶P\7fÿ¶b\7fÿ¶r\7fÿ¶~\7fÿ¶\88\7fÿ¶\94\7fÿ¶\9f\7fÿ¶«\7fÿ¶·\7fÿ¶É\7fÿ¶Ù\7fÿ¶í\7fÿ·\ 1\7fÿ·\15\7fÿ·#\7fÿ·/\7fÿ·>\7fÿ·L\7fÿ·V\7fÿ·f\7fÿ·q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\0\0\0°\0\0\0\ 4\0\0\0\0\0\0\0\b\10\0>X\0\0\0\f\10\0\0\0\0\10\0\0\0\0\0\0\0\14\0\0\0\14\0\0\0\14\0\0\0\18\0\0\0\18\0\0\0\18\0\0\0\1c\0\0\0\1c\0\0\0\1c\0\0\0\1c\0\0\0 \0\0\0 \0\0\0 \0\0\0$\0\0\0\v\0\0\0\e\0\0\0\19\0\0\0\v\0\0\0\e\0\0\0@\0\0\0\0\0\0\0\0\0\0\0\0\10\0,\b\0\0\0\1a\10\02\88\0\0\0\1a\0\0\0\0\0\0\0\1a\10\0\85\b\0\0\0\0\10\0>X\0\0\0\0\0\0\0\0\0\0\0\0\10\0\82à\0\0\0\0\0\0\ 1C\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e0\0\0\0\v\0\0\0\e\0\0\0\18\0\0\0\v\0\0\0\1a\0\0\0\17\0\0\0\v\0\0\0 \0\0\0\0\10\0\8d¸ude/snmp_groupvars.h~\0\0\b\0\0\0\b\0\0\0 \0\0\0\0\10\0\8dàude/snmp_groupvars.h\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8eX\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e\80\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e¨\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8eÐ\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\0\0\0\ 1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\84©\0\0\0\0/***********************************************************
+       Copyright 1989 by Carnegie Mellon University
+
+                      All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the name of CMU not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+******************************************************************/
+/*
+ * snmp_api.c - API for access to snmp.
+ */
+#define DEBUG_SNMPTRACE                0 /* set to 1 to print all SNMP actions */
+#define DEBUG_SNMPFULLDUMP     0 /* set to 1 to dump all SNMP packets */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#ifdef linux
+#include <arpa/inet.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#endif
+
+
+#include "asn1.h"
+#include "snmp.h"
+#include "snmp_impl.h"
+#include "snmp_api.h"
+#include "snmp_client.h"
+
+#define PACKET_LENGTH  4500
+
+#ifndef BSD4_3
+#define BSD4_2
+#endif
+
+#if !defined(BSD4_3) && !defined(linux) && !defined(sun)
+
+typedef long   fd_mask;
+#define NFDBITS        (sizeof(fd_mask) * NBBY)        /* bits per mask */
+
+#define        FD_SET(n, p)    ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+#define        FD_CLR(n, p)    ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+#define        FD_ISSET(n, p)  ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+#define FD_ZERO(p)     bzero((char *)(p), sizeof(*(p)))
+#endif
+
+oid default_enterprise[] = {1, 3, 6, 1, 4, 1, 3, 1, 1}; /* enterprises.cmu.systems.cmuSNMP */
+
+#define DEFAULT_COMMUNITY   "public"
+#define DEFAULT_REMPORT            SNMP_PORT
+#define DEFAULT_ENTERPRISE  default_enterprise
+#define DEFAULT_TIME       0
+#define DEFAULT_MMS        1389 /* large, randomly picked for testing purposes */
+
+/*
+ * Internal information about the state of the snmp session.
+ */
+struct snmp_internal_session {
+    int            sd;         /* socket descriptor for this connection */
+    ipaddr  addr;      /* address of connected peer */
+    struct request_list *requests;/* Info about outstanding requests */
+};
+
+/*
+ * A list of all the outstanding requests for a particular session.
+ */
+struct request_list {
+    struct request_list *next_request;
+    u_long  request_id;        /* request id */
+    int            retries;    /* Number of retries */
+    u_long timeout;    /* length to wait for timeout */
+    struct timeval time; /* Time this request was made */
+    struct timeval expire;  /* time this request is due to expire */
+    struct snmp_pdu *pdu;   /* The pdu for this request (saved so it can be retransmitted */
+};
+
+/*
+ * The list of active/open sessions.
+ */
+struct session_list {
+    struct session_list *next;
+    struct snmp_session *session;
+    struct snmp_internal_session *internal;
+};
+
+struct session_list *Sessions = NULL;
+
+u_long Reqid = 0;
+int snmp_errno = 0;
+
+char *api_errors[4] = {
+    "Unknown session",
+    "Unknown host",
+    "Invalid local port",
+    "Unknown Error"
+};
+
+
+void sync_with_agent();
+int parse_app_community_string();
+void snmp_synch_setup();
+int snmp_synch_response();
+void md5Digest();
+
+
+static char *
+api_errstring(snmp_errnumber)
+    int        snmp_errnumber;
+{
+    if (snmp_errnumber <= SNMPERR_BAD_SESSION && snmp_errnumber >= SNMPERR_GENERR){
+       return api_errors[snmp_errnumber + 4];
+    } else {
+       return "Unknown Error";
+    }
+}
+
+#if 0
+/*
+ * Gets initial request ID for all transactions.
+ */
+static void
+init_snmp(){
+    struct timeval tv;
+
+    gettimeofday(&tv, (struct timezone *)0);
+    srandom(tv.tv_sec ^ tv.tv_usec);
+    Reqid = random();
+}
+#endif
+
+
+/*
+ * Dump snmp packet to stdout:
+ */
+static void
+snmp_print_packet(packet, length, addr, code)
+  char *packet; 
+  int length; 
+  ipaddr addr; 
+  int code;
+{
+  if(length < 0) {
+    return;
+  }
+  if (code <= 0) { /* received */
+    printf("\nReceived %4d bytes from ", length);
+  }
+  else { /* sending */
+    printf("\nSending  %4d bytes to   ", length);
+  }
+  printf("%s:", inet_ntoa(addr.sin_addr));
+#if DEBUG_SNMPFULLDUMP
+  for (count = 0; count < length; count++) {
+    if ((count & 15) == 0) {
+      printf("\n  ");
+    }
+    printf("%02X ", (int)(packet[count]&255));
+  }
+#endif
+  fflush(stdout);
+}
+
+#if DEBUG_SNMPTRACE
+/*
+ * Print request
+ */
+#define TRACE_SEND   (0)
+#define TRACE_RECV   (1)
+#define TRACE_TIMEOUT (2)
+static void
+snmp_print_trace(slp, rp, code)
+  struct session_list *slp;
+  struct request_list *rp;
+  int code;
+{
+  int reqid=0, retries=1;
+  if( rp ){
+    reqid = rp->request_id;
+    retries = rp->retries;
+  }  
+  printf("\n Session %2d  ReqId %4d  ", slp->internal->sd, reqid);
+  switch(code)
+    { 
+    case TRACE_SEND:    printf("send pdu (%d)", retries);break; 
+    case TRACE_RECV:    printf("recv pdu");break; 
+    case TRACE_TIMEOUT: printf("time out");break; 
+    }
+  fflush(stdout);
+}
+#endif /* DEBUG_SNMPTRACE */
+
+
+
+
+/*
+ * 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.
+ */
+struct snmp_session *
+snmp_open(session)
+    struct snmp_session *session;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp;
+    u_char *cp;
+    int sd;
+    u_long addr;
+    struct sockaddr_in me;
+    struct hostent *hp;
+    struct servent *servp;
+    extern int check_received_pkt();
+
+    /* Copy session structure and link into list */
+    slp = (struct session_list *)calloc(1, sizeof(struct session_list));
+    slp->internal = isp = (struct snmp_internal_session *)calloc(1, sizeof(struct snmp_internal_session));
+    bzero((char *)isp, sizeof(struct snmp_internal_session));
+    slp->internal->sd = -1; /* mark it not set */
+    slp->session = (struct snmp_session *)calloc(1, sizeof(struct snmp_session));
+    bcopy((char *)session, (char *)slp->session, sizeof(struct snmp_session));
+    session = slp->session;
+    /* now link it in. */
+    slp->next = Sessions;
+    Sessions = slp;
+
+    /*
+     * session now points to the new structure that still contains pointers to
+     * data allocated elsewhere.  Some of this data is copied to space malloc'd
+     * here, and the pointer replaced with the new one.
+     */
+
+    if (session->peername != NULL){
+       cp = (u_char *)calloc(1, (unsigned)strlen(session->peername) + 1);
+       strcpy((char *)cp, session->peername);
+       session->peername = (char *)cp;
+    }
+
+    if (session->retries == SNMP_DEFAULT_RETRIES)
+       session->retries = SNMP_API_DEFAULT_RETRIES;
+    if (session->timeout == SNMP_DEFAULT_TIMEOUT)
+       session->timeout = SNMP_API_DEFAULT_TIMEOUT;
+    if (session->MMS == 0 )
+       session->MMS = DEFAULT_MMS;
+    isp->requests = NULL;
+
+
+    /* Fill in defaults if necessary */
+    if (session->community_len != SNMP_DEFAULT_COMMUNITY_LEN){
+       if( *session->community == '+' ) {
+               session->community_len--;
+               cp = (u_char *) calloc(1, (unsigned) session->community_len);
+               bcopy((char *) session->community+1, (char *)cp,
+                     session->community_len);
+               session->version = SNMP_VERSION_2C;
+       } else {
+               cp = (u_char *) calloc(1, (unsigned) session->community_len);
+               bcopy((char *) session->community, (char *) cp, 
+                     session->community_len);
+       }
+
+    } else {
+       session->community_len = strlen(DEFAULT_COMMUNITY);
+       cp = (u_char *)calloc(1, (unsigned)session->community_len);
+       bcopy((char *)DEFAULT_COMMUNITY, (char *)cp, session->community_len);
+    }
+
+    /* Set up connections */
+    sd = socket(AF_INET, SOCK_DGRAM, 0);
+    if (sd < 0){
+       perror("socket");
+       snmp_errno = SNMPERR_GENERR;
+       if (!snmp_close(session)){
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+           exit(1);
+       }
+       return 0;
+    }
+    isp->sd = sd;
+
+    if (session->peername != SNMP_DEFAULT_PEERNAME){
+       if ((addr = inet_addr(session->peername)) != -1){
+           bcopy((char *)&addr, (char *)&isp->addr.sin_addr, sizeof(isp->addr.sin_addr));
+       } else {
+           hp = gethostbyname(session->peername);
+           if (hp == NULL){
+               fprintf(stderr, "unknown host: %s\n", session->peername);
+               snmp_errno = SNMPERR_BAD_ADDRESS;
+               if (!snmp_close(session)){
+                   fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+                   exit(2);
+               }
+               return 0;
+           } else {
+               bcopy((char *)hp->h_addr, (char *)&isp->addr.sin_addr, hp->h_length);
+           }
+       }
+       isp->addr.sin_family = AF_INET;
+       if (session->remote_port == SNMP_DEFAULT_REMPORT){
+           /*servp = getservbyname("snmp", "udp");*/
+           servp=NULL;
+           if (servp != NULL){
+               isp->addr.sin_port = servp->s_port;
+           } else {
+               isp->addr.sin_port = htons(SNMP_PORT);
+           }
+       } else {
+           isp->addr.sin_port = htons(session->remote_port);
+       }
+    } else {
+       isp->addr.sin_addr.s_addr = SNMP_DEFAULT_ADDRESS;
+    }
+
+    me.sin_family = AF_INET;
+    me.sin_addr.s_addr = INADDR_ANY;
+    me.sin_port = htons(session->local_port);
+    if (bind(sd, (struct sockaddr *)&me, sizeof(me)) != 0){
+       perror("bind");
+       snmp_errno = SNMPERR_BAD_LOCPORT;
+       if (! snmp_close(session)){
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n", 
+                   api_errstring(snmp_errno));
+           exit(3);
+       }
+       return 0;
+    }
+
+    if( *cp == '/' ) {
+       session->authenticator = check_received_pkt;
+       sync_with_agent(session);
+       parse_app_community_string( session );
+       session->qoS |= USEC_QOS_GENREPORT;
+    }
+
+    /* replace comm pointer with pointer to new data: */
+    session->community = cp;   
+
+    return session;
+}
+
+void
+sync_with_agent( session )
+struct snmp_session *session;
+{
+    struct snmp_pdu *pdu, *response = 0;
+    int status;
+
+    session->qoS = USEC_QOS_GENREPORT;
+    session->userLen = 6;
+    session->version = SNMP_VERSION_2;
+    strcpy( session->userName, "public" );
+
+    snmp_synch_setup(session);
+    pdu = snmp_pdu_create(GET_REQ_MSG);
+    status = snmp_synch_response(session, pdu, &response);
+
+    if (status == STAT_SUCCESS){
+       memcpy( session->agentID, response->params.agentID, 12 );
+
+       /* save the clocks -- even though they are not authentic */
+       session->agentBoots = response->params.agentBoots;
+       session->agentTime = response->params.agentTime;
+       session->agentClock = response->params.agentTime - time(NULL);
+
+    } else {
+           if (status == STAT_TIMEOUT){
+               printf("No Response from %s\n", session->peername);
+           } else {    /* status == STAT_ERROR */
+               printf("An error occurred, Quitting\n");
+           }
+           exit( -1 );
+    }
+
+    /** freed to early: 
+      snmp_free_pdu(pdu);
+      if (response) snmp_free_pdu(response);
+     **/
+}
+#if 1 /***/
+/*
+ * Unlink one element from input request list,
+ * then free it and it's pdu.
+ */
+static void
+free_one_request(isp, orp)
+    struct snmp_internal_session *isp;
+    struct request_list *orp;
+{
+    struct request_list *rp;
+    if(! orp) return;
+    if(isp->requests == orp){ 
+      isp->requests = orp->next_request; /* unlink head */
+    }
+    else{
+      for(rp = isp->requests; rp; rp = rp->next_request){
+        if(rp->next_request == orp){ 
+         rp->next_request = orp->next_request; /* unlink element */
+         break;
+        }
+      }
+    }
+    if (orp->pdu != NULL){
+      snmp_free_pdu(orp->pdu);
+    }
+    free((char *)orp);
+}
+#endif /***/
+/*
+ * Free each element in the input request list.
+ */
+static void
+free_request_list(rp)
+    struct request_list *rp;
+{
+    struct request_list *orp;
+
+    while(rp){
+       orp = rp;
+       rp = rp->next_request;
+       if (orp->pdu != NULL)
+           snmp_free_pdu(orp->pdu);
+       free((char *)orp);
+    }
+}
+
+/*
+ * 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.
+ */
+int 
+snmp_close(session)
+    struct snmp_session *session;
+{
+    struct session_list *slp = NULL, *oslp = NULL;
+
+    if (Sessions->session == session){ /* If first entry */
+       slp = Sessions;
+       Sessions = slp->next;
+    } else {
+       for(slp = Sessions; slp; slp = slp->next){
+           if (slp->session == session){
+               if (oslp)   /* if we found entry that points here */
+                   oslp->next = slp->next;     /* link around this entry */
+               break;
+           }
+           oslp = slp;
+       }
+    }
+    /* If we found the session, free all data associated with it */
+    if (slp){
+       if (slp->session->community != NULL)
+           free((char *)slp->session->community);
+       if(slp->session->peername != NULL)
+           free((char *)slp->session->peername);
+       free((char *)slp->session);
+       if (slp->internal->sd != -1)
+           close(slp->internal->sd);
+       free_request_list(slp->internal->requests);
+       free((char *)slp->internal);
+       free((char *)slp);
+    } else {
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    return 1;
+}
+
+/*
+ * Takes a session and a pdu and serializes the ASN PDU into the area
+ * pointed to by packet.  out_length is the size of the data area available.
+ * Returns the length of the completed packet in out_length.  If any errors
+ * occur, -1 is returned.  If all goes well, 0 is returned.
+ */
+int
+snmp_build(session, pdu, packet, out_length, is_agent)
+    struct snmp_session        *session;
+    struct snmp_pdu    *pdu;
+    u_char     *packet;
+    int                        *out_length;
+    int                         is_agent;
+{
+    u_char  buf[PACKET_LENGTH];
+    u_char  *cp;
+    struct variable_list *vp;
+    int            length;
+    int            totallength;
+
+    length = *out_length;
+    cp = packet;
+    for(vp = pdu->variables; vp; vp = vp->next_variable){
+       cp = snmp_build_var_op(cp, vp->name, &vp->name_length, vp->type, vp->val_len, (u_char *)vp->val.string, &length);
+       if (cp == NULL)
+           return -1;
+    }
+    totallength = cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR), totallength);
+    if (cp == NULL)
+       return -1;
+    bcopy((char *)packet, (char *)cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+    if (pdu->command != TRP_REQ_MSG){
+       /* request id */
+       cp = asn_build_int(packet, &length,
+           (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+           (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (cp == NULL)
+           return -1;
+       /* error status */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (cp == NULL)
+           return -1;
+       /* error index */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (cp == NULL)
+           return -1;
+    } else {   /* this is a trap message */
+       /* enterprise */
+       cp = asn_build_objid(packet, &length,
+           (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID),
+           (oid *)pdu->enterprise, pdu->enterprise_length);
+       if (cp == NULL)
+           return -1;
+       /* agent-addr */
+       cp = asn_build_string(cp, &length, (u_char)IPADDRESS,
+               (u_char *)&pdu->agent_addr.sin_addr.s_addr, sizeof(pdu->agent_addr.sin_addr.s_addr));
+       if (cp == NULL)
+           return -1;
+       /* generic trap */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (cp == NULL)
+           return -1;
+       /* specific trap */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (cp == NULL)
+           return -1;
+       /* timestamp  */
+       cp = asn_build_int(cp, &length, (u_char)TIMETICKS,
+               (long *)&pdu->time, sizeof(pdu->time));
+       if (cp == NULL)
+           return -1;
+    }
+    if (length < totallength)
+       return -1;
+    bcopy((char *)buf, (char *)cp, totallength);
+    totallength += cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char)pdu->command, totallength);
+    if (cp == NULL)
+       return -1;
+    if (length < totallength)
+       return -1;
+    bcopy((char *)packet, (char *)cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+
+    cp = snmp_auth_build( packet, &length, session, is_agent, totallength );
+    if (cp == NULL)
+       return -1;
+    if ((*out_length - (cp - packet)) < totallength)
+       return -1;
+    bcopy((char *)buf, (char *)cp, totallength);
+    totallength += cp - packet;
+    *out_length = totallength;
+
+    if( session->qoS & USEC_QOS_AUTH )
+           md5Digest( packet, totallength, cp - (session->contextLen + 16),
+               cp - (session->contextLen + 16) );
+
+    return 0;
+}
+
+/*
+ * Parses the packet received on the input session, and places the data into
+ * the input pdu.  length is the length of the input packet.  If any errors
+ * are encountered, -1 is returned.  Otherwise, a 0 is returned.
+ */
+static int
+snmp_parse(session, pdu, data, length)
+    struct snmp_session *session;
+    struct snmp_pdu *pdu;
+    u_char  *data;
+    int            length;
+{
+    u_char  msg_type;
+    u_char  type;
+    u_char  *var_val;
+    long    version;
+    int            len, four;
+    u_char community[256];
+    int community_length = 256;
+    struct variable_list *vp = 0;
+    oid            objid[MAX_NAME_LEN], *op;
+    u_char  *origdata = data;
+    int      origlength = length;
+    int      ret = 0;
+    u_char  *save_data;
+
+    /* authenticates message and returns length if valid */
+    data = snmp_auth_parse(data, &length, community, &community_length, &version);
+    if (data == NULL)
+       return -1;
+
+   if( version != SNMP_VERSION_1 && version != SNMP_VERSION_2C && version != SNMP_VERSION_2 ) {
+           fprintf(stderr, "Wrong version: %ld\n", version);
+           return -1;
+    }
+
+    save_data = data;
+
+    data = asn_parse_header(data, &length, &msg_type);
+    if (data == NULL)
+       return -1;
+    pdu->command = msg_type;
+
+    if( session->authenticator ) {
+       ret = session->authenticator( origdata, origlength, save_data - community_length, 
+               community_length, session, pdu );
+       if( ret < 0 ) return ret;
+    }
+
+    if (pdu->command != TRP_REQ_MSG){
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (data == NULL)
+           return -1;
+    } else {
+       pdu->enterprise_length = MAX_NAME_LEN;
+       data = asn_parse_objid(data, &length, &type, objid, &pdu->enterprise_length);
+       if (data == NULL)
+           return -1;
+       pdu->enterprise = (oid *)calloc(1, pdu->enterprise_length * sizeof(oid));
+       bcopy((char *)objid, (char *)pdu->enterprise, pdu->enterprise_length * sizeof(oid));
+
+       four = 4;
+       data = asn_parse_string(data, &length, &type, (u_char *)&pdu->agent_addr.sin_addr.s_addr, &four);
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->time, sizeof(pdu->time));
+       if (data == NULL)
+           return -1;
+    }
+    data = asn_parse_header(data, &length, &type);
+    if (data == NULL)
+       return -1;
+    if (type != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR))
+       return -1;
+    while((int)length > 0){
+       if (pdu->variables == NULL){
+           pdu->variables = vp = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+       } else {
+           vp->next_variable = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+           vp = vp->next_variable;
+       }
+       vp->next_variable = NULL;
+       vp->val.string = NULL;
+       vp->name = NULL;
+       vp->name_length = MAX_NAME_LEN;
+       data = snmp_parse_var_op(data, objid, &vp->name_length, &vp->type, &vp->val_len, &var_val, (int *)&length);
+       if (data == NULL)
+           return -1;
+       op = (oid *)calloc(1, (unsigned)vp->name_length * sizeof(oid));
+       bcopy((char *)objid, (char *)op, vp->name_length * sizeof(oid));
+       vp->name = op;
+
+       len = PACKET_LENGTH;
+       switch((short)vp->type){
+           case ASN_INTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(long));
+               vp->val_len = sizeof(long);
+               asn_parse_int(var_val, &len, &vp->type, (long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER:
+           case GAUGE:
+           case TIMETICKS:
+           case UINTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(unsigned long));
+               vp->val_len = sizeof(unsigned long);
+               asn_parse_unsigned_int(var_val, &len, &vp->type, (unsigned long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER64:
+               vp->val.counter64 = (struct counter64 *)calloc(1,  sizeof(struct counter64) );
+               vp->val_len = sizeof(struct counter64);
+               asn_parse_unsigned_int64(var_val, &len, &vp->type,
+                                        (struct counter64 *)vp->val.counter64,
+                                        sizeof(*vp->val.counter64));
+               break;
+           case ASN_OCTET_STR:
+           case IPADDRESS:
+           case OPAQUE:
+           case NSAP:
+               vp->val.string = (u_char *)calloc(1, (unsigned)vp->val_len);
+               asn_parse_string(var_val, &len, &vp->type, vp->val.string, &vp->val_len);
+               break;
+           case ASN_OBJECT_ID:
+               vp->val_len = MAX_NAME_LEN;
+               asn_parse_objid(var_val, &len, &vp->type, objid, &vp->val_len);
+               vp->val_len *= sizeof(oid);
+               vp->val.objid = (oid *)calloc(1, (unsigned)vp->val_len);
+               bcopy((char *)objid, (char *)vp->val.objid, vp->val_len);
+               break;
+            case SNMP_NOSUCHOBJECT:
+            case SNMP_NOSUCHINSTANCE:
+            case SNMP_ENDOFMIBVIEW:
+           case ASN_NULL:
+               break;
+           default:
+               fprintf(stderr, "bad type returned (%x)\n", vp->type);
+               break;
+       }
+    }
+    return ret;
+}
+
+/*
+ * 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(session, pdu)
+    struct snmp_session *session;
+    struct snmp_pdu    *pdu;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp = NULL;
+    u_char  packet[PACKET_LENGTH];
+    int length = PACKET_LENGTH;
+    struct request_list *rp;
+    struct timeval tv;
+
+    for(slp = Sessions; slp; slp = slp->next){
+       if (slp->session == session){
+           isp = slp->internal;
+           break;
+       }
+    }
+
+    if (! pdu) {
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+
+    if (isp == NULL){
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG
+       || pdu->command == GET_RSP_MSG || pdu->command == SET_REQ_MSG 
+       || pdu->command == GETBULK_REQ_MSG ){
+       if (pdu->reqid == SNMP_DEFAULT_REQID)
+           pdu->reqid = ++Reqid;
+       if (pdu->errstat == SNMP_DEFAULT_ERRSTAT)
+           pdu->errstat = 0;
+       if (pdu->errindex == SNMP_DEFAULT_ERRINDEX)
+           pdu->errindex = 0;
+    } else {
+       /* fill in trap defaults */
+       pdu->reqid = 1; /* give a bogus non-error reqid for traps */
+       if (pdu->enterprise_length == SNMP_DEFAULT_ENTERPRISE_LENGTH){
+           pdu->enterprise = (oid *)calloc(1, sizeof(DEFAULT_ENTERPRISE));
+           bcopy((char *)DEFAULT_ENTERPRISE, (char *)pdu->enterprise, sizeof(DEFAULT_ENTERPRISE));
+           pdu->enterprise_length = sizeof(DEFAULT_ENTERPRISE)/sizeof(oid);
+       }
+       if (pdu->time == SNMP_DEFAULT_TIME)
+           pdu->time = DEFAULT_TIME;
+    }
+    if (pdu->address.sin_addr.s_addr == SNMP_DEFAULT_ADDRESS){
+       if (isp->addr.sin_addr.s_addr != SNMP_DEFAULT_ADDRESS){
+           bcopy((char *)&isp->addr, (char *)&pdu->address, sizeof(pdu->address));
+       } else {
+           fprintf(stderr, "No remote IP address specified\n");
+           snmp_errno = SNMPERR_BAD_ADDRESS;
+           return 0;
+       }
+    }
+       
+
+    if (snmp_build(session, pdu, packet, &length, 0) < 0){
+       fprintf(stderr, "Error building packet\n");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+#if 1 /***/
+    if (snmp_dump_packet){
+      snmp_print_packet(packet, length, pdu->address, 1);
+    }
+#endif /***/
+
+    gettimeofday(&tv, (struct timezone *)0);
+    if (sendto(isp->sd, (char *)packet, length, 0, (struct sockaddr *)&pdu->address, sizeof(pdu->address)) < 0){
+       perror("sendto");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG 
+     || pdu->command == SET_REQ_MSG || pdu->command == GETBULK_REQ_MSG ){
+       /* set up to expect a response */
+       rp = (struct request_list *)calloc(1, sizeof(struct request_list));
+#if 1 /***/
+        if(! rp){
+          fprintf(stderr, "Out of memory!\n");
+          snmp_errno = SNMPERR_GENERR;
+          return 0;
+        }
+#endif /***/
+       rp->next_request = isp->requests;
+       isp->requests = rp;
+       rp->pdu = pdu;
+       rp->request_id = pdu->reqid;
+
+       rp->retries = 1;
+       rp->timeout = session->timeout;
+       rp->time = tv;
+       tv.tv_usec += rp->timeout;
+       tv.tv_sec += tv.tv_usec / 1000000L;
+       tv.tv_usec %= 1000000L;
+       rp->expire = tv;
+#if DEBUG_SNMPTRACE
+       snmp_print_trace(slp, rp, TRACE_SEND);
+#endif
+    }
+    return pdu->reqid;
+}
+
+/*
+ * Frees the pdu and any malloc'd data associated with it.
+ */
+void
+snmp_free_pdu(struct snmp_pdu * pdu)
+{
+    struct variable_list *vp, *ovp;
+
+    if (! pdu)
+      return;
+
+    vp = pdu->variables;
+    while(vp){
+      if (vp->name) {
+       free((char *)vp->name);
+      }
+      if (vp->val.string) {
+       free((char *)vp->val.string);
+      }
+      ovp = vp;
+      vp = vp->next_variable;
+      free((char *)ovp);
+    }
+    if (pdu->enterprise) {
+      free((char *)pdu->enterprise);
+    }
+    free((char *)pdu);
+}
+
+
+/*
+ * 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(fdset)
+    fd_set  *fdset;
+{
+    struct session_list *slp;
+    struct snmp_session *sp;
+    struct snmp_internal_session *isp;
+    u_char packet[PACKET_LENGTH];
+    struct sockaddr_in from;
+    ssize_t length, fromlength;
+    struct snmp_pdu *pdu;
+    struct request_list *rp /**, *orp **/ ;
+
+    for(slp = Sessions; slp; slp = slp->next){
+       if (FD_ISSET(slp->internal->sd, fdset)){
+           sp = slp->session;
+           isp = slp->internal;
+           fromlength = sizeof(from);
+           length = recvfrom(isp->sd, (char *)packet, PACKET_LENGTH, 0, (struct sockaddr *)&from, &fromlength);
+           if (length == -1) {
+               perror("recvfrom");
+               return;
+           }
+#if 1 /***/
+           if (snmp_dump_packet){
+             snmp_print_packet(packet, length, from, 0);
+           }
+           pdu = (struct snmp_pdu *)calloc(1, sizeof(struct snmp_pdu));
+
+           if(! pdu){
+             fprintf(stderr, "Out of memory!\n");
+             snmp_errno = SNMPERR_GENERR;
+             return;
+           }
+#endif /***/
+
+           pdu->address = from;
+           pdu->reqid = 0;
+           pdu->variables = NULL;
+           pdu->enterprise = NULL;
+           pdu->enterprise_length = 0;
+           if (snmp_parse(sp, pdu, packet, length) < 0){
+               fprintf(stderr, "Mangled packet\n");
+               snmp_free_pdu(pdu);
+               return;
+           }
+
+           if (pdu->command == GET_RSP_MSG || pdu->command == REPORT_MSG){
+#if 1 /***/ /* bug fix: illegal re-use of rp killed some requests */
+             struct request_list *rp_next= 0;
+             for(rp = isp->requests; rp; rp = rp_next){
+               rp_next = rp->next_request;
+               if (rp->request_id == pdu->reqid){
+#if DEBUG_SNMPTRACE
+                 snmp_print_trace(slp, rp, TRACE_RECV);
+#endif
+                 if (sp->callback(RECEIVED_MESSAGE, sp, pdu->reqid, pdu, sp->callback_magic) == 1){
+                   /* successful, so delete request */
+                   free_one_request(isp, rp);
+                   break;  /* no more request with the same reqid */
+                 }
+               }
+             }
+#endif /***/
+           } else if (pdu->command == GET_REQ_MSG
+                   || pdu->command == GETNEXT_REQ_MSG
+                   || pdu->command == GETBULK_REQ_MSG
+               || pdu->command == TRP_REQ_MSG || pdu->command == SET_REQ_MSG) {
+#if DEBUG_SNMPTRACE
+               snmp_print_trace(slp, NULL, TRACE_RECV);
+#endif
+               sp->callback(RECEIVED_MESSAGE, sp, pdu->reqid, pdu, sp->callback_magic);
+           }
+           snmp_free_pdu(pdu);
+       }
+    }
+}
+
+/*
+ * 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(numfds, fdset, timeout, block)
+     int *numfds;
+     fd_set *fdset;
+     struct timeval *timeout;
+     int *block;               /* should the select block until input arrives (i.e. no input) */
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp;
+    struct request_list *rp;
+    struct timeval now, earliest;
+    int active = 0, requests = 0;
+
+    timerclear(&earliest);
+    /*
+     * For each request outstanding, add it's socket to the fdset,
+     * and if it is the earliest timeout to expire, mark it as lowest.
+     */
+    for (slp = Sessions; slp; slp = slp->next) {
+       active++;
+       isp = slp->internal;
+       if ((isp->sd + 1) > *numfds)
+           *numfds = (isp->sd + 1);
+       FD_SET(isp->sd, fdset);
+       if (isp->requests) {
+           /* found another session with outstanding requests */
+           requests++;
+           for (rp = isp->requests; rp; rp = rp->next_request) {
+               if (!timerisset(&earliest) || timercmp(&rp->expire, &earliest, <))
+                   earliest = rp->expire;
+           }
+       }
+    }
+    if (requests == 0)         /* if none are active, skip arithmetic */
+       return active;
+
+    /*
+     * Now find out how much time until the earliest timeout.  This
+     * transforms earliest from an absolute time into a delta time, the
+     * time left until the select should timeout.
+     */
+    gettimeofday(&now, (struct timezone *) 0);
+    earliest.tv_sec--;         /* adjust time to make arithmetic easier */
+    earliest.tv_usec += 1000000L;
+    earliest.tv_sec -= now.tv_sec;
+    earliest.tv_usec -= now.tv_usec;
+    while (earliest.tv_usec >= 1000000L) {
+       earliest.tv_usec -= 1000000L;
+       earliest.tv_sec += 1;
+    }
+    if (earliest.tv_sec < 0) {
+       earliest.tv_sec = 0;
+       earliest.tv_usec = 0;
+    }
+    /* if it was blocking before or our delta time is less, reset timeout */
+    if (*block == 1 || timercmp(&earliest, timeout, <)) {
+       *timeout = earliest;
+       *block = 0;
+    }
+    return active;
+}
+
+/* 
+ * 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()
+{
+    struct session_list *slp;
+    struct snmp_session *sp;
+    struct snmp_internal_session *isp;
+#if 1 /***/                    /* replacing freeme by simpler and safer rp_next */
+    struct request_list *rp, *rp_next = 0;
+#endif/***/ placing freeme by simpler and safer rp_next*/n s */ replace...
+     */
+ * \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 1\ 1\0\0\0\0\0\0\0\19\7fÿ¯ùsnmplib/snmp_api.c\0c\0\0.h\0\0\0\18\7fÿ°\85\10\0<Ðlib/snmp_api.c~\0~\0\0ñ\0\0\0\18\7fÿ±\1e\10\0\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\0\0\0\18\7fÿ±«\10\0=\10\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\0\0\0\18\7fÿ²\1d\10\0=0\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\0\0\0\18\7fÿ²\8a\10\0=P\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\0\0\0\18\7fÿ³
+\10\0=p\7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\0\0\0\18\7fÿ³\82\0\0\0\ 1\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\0\0\0Á\7fÿ³ù\0\0\0\10\7fÿ´\10\10\0\0%\0\19\0\15\0\0\10\0D(\0\0\0\10\7fÿ´_\10\0\0\0\ 2\\0\0\0\0\10\0\0\0\0\10\7fÿ´©\10\0=\98\0\0\ 24\0\0\0\0\10\0\0\0\0\10\7fÿ´ø\10\0\0\0\ 2H\0\0\0\0\10\0\0\0\0\10\7fÿµB\10\0>\10\7fÿµ]\7fÿµm\7fÿµz\0\0\0\10\7fÿµ \10\0>(\7fÿµ·\7fÿµÉ\7fÿµÖ\0\0\0\10\7fÿµï\10\0>@\7fÿ¶\12\7fÿ¶ \7fÿ¶4\0\0\0\10\7fÿ¶P\0\0\0\ 1\7fÿ¶r\7fÿ¶~\7fÿ¶\88\0\0\00\7fÿ¶\9f\0\0\0\0\7fÿ¶·\0\0\0\0\7fÿ¶Ù\10\0\7fÿ·\ 1\0\0\0\0\7fÿ·#\7fÿ·/\7fÿ·>\10\0>X\7fÿ·V\0\0\03\0\0\0\0/usr/people/wessels/.indent.pro\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\ 1\0\0\0\0\7fÿ¯è\7fÿ¯ù\7fÿ°\f\7fÿ°\e\7fÿ°.\7fÿ°?\7fÿ°M\7fÿ°[\7fÿ°p\7fÿ°\85\7fÿ°\95\7fÿ°£\7fÿ°²\7fÿ°Å\7fÿ°Û\7fÿ°ñ\7fÿ±
+\7fÿ±\1e\7fÿ±2\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\7fÿ±\99\7fÿ±«\7fÿ±º\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\7fÿ²\ f\7fÿ²\1d\7fÿ²2\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\7fÿ²\7f\7fÿ²\8a\7fÿ²\99\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\7fÿ²ö\7fÿ³
+\7fÿ³ \7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\7fÿ³s\7fÿ³\82\7fÿ³\91\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\7fÿ³ç\7fÿ³ù\7fÿ´\ 4\7fÿ´\10\7fÿ´\1e\7fÿ´)\7fÿ´3\7fÿ´C\7fÿ´O\7fÿ´_\7fÿ´k\7fÿ´t\7fÿ´\81\7fÿ´\8f\7fÿ´\9f\7fÿ´©\7fÿ´·\7fÿ´Å\7fÿ´Ò\7fÿ´Ý\7fÿ´í\7fÿ´ø\7fÿµ\ 3\7fÿµ\10\7fÿµ\1d\7fÿµ)\7fÿµ7\7fÿµB\7fÿµM\7fÿµ]\7fÿµm\7fÿµz\7fÿµ\89\7fÿµ \7fÿµ«\7fÿµ·\7fÿµÉ\7fÿµÖ\7fÿµâ\7fÿµï\7fÿ¶\ 3\7fÿ¶\12\7fÿ¶ \7fÿ¶4\7fÿ¶?\7fÿ¶P\7fÿ¶b\7fÿ¶r\7fÿ¶~\7fÿ¶\88\7fÿ¶\94\7fÿ¶\9f\7fÿ¶«\7fÿ¶·\7fÿ¶É\7fÿ¶Ù\7fÿ¶í\7fÿ·\ 1\7fÿ·\15\7fÿ·#\7fÿ·/\7fÿ·>\7fÿ·L\7fÿ·V\7fÿ·f\7fÿ·q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0@    \0\0\0\0 a failure occured.
+ */
+int
+snmp_send(session, pdu)
+    struct snmp_session *session;
+    struct snmp_pdu    *pdu;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp = NULL;
+    u_char  packet[PACKET_LENGTH];
+    int length = PACKET_LENGTH;
+    struct request_list *rp;
+    struct timeval tv;
+
+    for(slp = Sessions; slp; slp = slp->next){
+       if (slp->session == session){
+           isp = slp->internal;
+           break;
+       }
+    }
+
+    if (! pdu) {
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+
+    if (isp == NULL){
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG
+       || pdu->command == GET_RSP_MSG || pdu->command == SET_REQ_MSG 
+       || pdu->command == GETBULK_REQ_MSG ){
+       if (pdu->reqid == SNMP_DEFAULT_REQID)
+           pdu->reqid = ++Reqid;
+       if (pdu->errstat == SNMP_DEFAULT_ERRSTAT)
+           pdu->errstat = 0;
+       if (pdu->errindex == SNMP_DEFAULT_ERRINDEX)
+           pdu->errindex = 0;
+    } else {
+       /* fill in trap defaults */
+       pdu->reqid = 1; /* give a bogus non-error reqid for traps */
+       if (pdu->enterprise_length == SNMP_DEFAULT_ENTERPRISE_LENGTH){
+           pdu->enterprise = (oid *)calloc(1, sizeof(DEFAULT_ENTERPRISE));
+           bcopy((char *)DEFAULT_ENTERPRISE, (char *)pdu->enterprise, sizeof(DEFAULT_ENTERPRISE));
+           pdu->enterprise_length = sizeof(DEFAULT_ENTERPRISE)/sizeof(oid);
+       }
+       if (pdu->time == SNMP_DEFAULT_TIME)
+           pdu->time = DEFAULT_TIME;
+    }
+    if (pdu->address.sin_addr.s_addr == SNMP_DEFAULT_ADDRESS){
+       if (isp->addr.sin_addr.s_addr != SNMP_DEFAULT_ADDRESS){
+           bcopy((char *)&isp->addr, (char *)&pdu->address, sizeof(pdu->address));
+       } else {
+           fprintf(stderr, "No remote IP address specified\n");
+           snmp_errno = SNMPERR_BAD_ADDRESS;
+           return 0;
+       }
+    }
+       
+
+    if (snmp_build(session, pdu, packet, &length, 0) < 0){
+       fprintf(stderr, "Error building packet\n");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+#if 1 /***/
+    if (snmp_dump_packet){
+      snmp_print_packet(packet, length, pdu->address, 1);
+    }
+#endif /***/
+
+    gettimeofday(&tv, (struct timezone *)0);
+    if (sendto(isp->sd, (char *)packet, length, 0, (struct sockaddr *)&pdu->address, sizeof(pdu->address)) < 0){
+       perror("sendto");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG 
+     || pdu->command == SET_REQ_MSG || pdu->command == GETBULK_REQ_MSG ){
+       /* set up to expect a response */
+       rp = (struct request_list *)calloc(1, sizeof(struct request_list));
+#if 1 /***/
+        if(! rp){
+          fprintf(stderr, "Out of memory!\n");
+          snmp_errno = SNMPERR_GENERR;
+          return 0;
+        }
+#endif /***/
+       rp->next_request = isp->requests;
+       isp->requests = rp;
+       rp->pdu = pdu;
+       rp->request_id = pdu->reqid;
+
+       rp->retries = 1;
+       rp->timeout = session->timeout;
+       rp->time = tv;
+       tv.tv_usec += rp->timeout;
+       tv.tv_sec += tv.tv_usec / 1000000L;
+       tv.tv_usec %= 1000000L;
+       rp->expire = tv;
+#if DEBUG_SNMPTRACE
+       snmp_print_trace(slp, rp, TRACE_SEND);
+#endif
+    }
+    return pdu->reqid;
+}
+
+/*
+ * Frees the pdu and any malloc'd data associated with it.
+ */
+void
+snmp_free_pdu(struct snmp_pdu * pdu)
+{
+    struct variable_list *vp, *ovp;
+
+    if (! pdu)
+      return;
+
+    vp = pdu->variables;
+    while(vp){
+      if (vp->name) {
+       free((char *)vp->name);
+      }
+      if (vp->val.string) {
+       free((char *)vp->val.string);
+      }
+      ovp = vp;
+      vp = vp->next_variable;
+      free((char *)ovp);
+    }
+    if (pdu->enterprise) {
+      free((char *)pdu->enterprise);
+    }
+    free((char *)pdu);
+}
+
+
+/*
+ * 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(fdset)
+    fd_set  *fdset;
+{
+    struct session_list *slp;
+    struct snmp_session *sp;
+    struct snmp_internal_session *isp;
+    u_char packet[PACKET_LENGTH];
+    struct sockaddr_in from;
+    ssize_t length, fromlength;
+    struct snmp_pdu *pdu;
+    struct request_list *rp /**, *orp **/ ;
+
+    for(slp = Sessions; slp; slp = slp->next){
+       if (FD_ISSET(slp->internal->sd, fdset)){
+           sp = slp->session;
+           isp = slp->internal;
+           fromlength = sizeof(from);
+           length = recvfrom(isp->sd, (char *)packet, PACKET_LENGTH, 0, (struct sockaddr *)&from, &fromlength);
+           if (length == -1) {
+               perror("recvfrom");
+               return;
+           }
+#if 1 /***/
+           if (snmp_dump_packet){
+             snmp_print_packet(packet, length, from, 0);
+           }
+           pdu = (struct snmp_pdu *)calloc(1, sizeof(struct snmp_pdu));
+
+           if(! pdu){
+             fprintf(stderr, "Out of memory!\n");
+             snmp_errno = SNMPERR_GENERR;
+             return;
+           }
+#endif /***/
+
+           pdu->address = from;
+           pdu->reqid = 0;
+           pdu->variables = NULL;
+           pdu->enterprise = NULL;
+           pdu->enterprise_length = 0;
+           if (snmp_parse(sp, pdu, packet, length) < 0){
+               fprintf(stderr, "Mangled packet\n");
+               snmp_free_pdu(pdu);
+               return;
+           }
+
+           if (pdu->command == GET_RSP_MSG || pdu->command == REPORT_MSG){
+#if 1 /***/ /* bug fix: illegal re-use of rp killed some requests */
+             struct request_list *rp_next= 0;
+             for(rp = isp->requests; rp; rp = rp_next){
+               rp_next = rp->next_request;
+               if (rp->request_id == pdu->reqid){
+#if DEBUG_SNMPTRACE
+                 snmp_print_trace(slp, rp, TRACE_RECV);
+#endif
+                 if (sp->callback(RECEIVED_MESSAGE, sp, pdu->reqid, pdu, sp->callback_magic) == 1){
+                   /* successful, so delete request */
+                   free_one_request(isp, rp);
+                   break;  /* no more request with the same reqid */
+                 }
+               }
+             }
+#endif /***/
+           } else if (pdu->command == GET_REQ_MSG
+                   || pdu->command == GETNEXT_REQ_MSG
+                   || pdu->command == GETBULK_REQ_MSG
+               || pdu->command == TRP_REQ_MSG || pdu->command == SET_REQ_MSG) {
+#if DEBUG_SNMPTRACE
+               snmp_print_trace(slp, NULL, TRACE_RECV);
+#endif
+               sp->callback(RECEIVED_MESSAGE, sp, pdu->reqid, pdu, sp->callback_magic);
+           }
+           snmp_free_pdu(pdu);
+       }
+    }
+}
+
+/*
+ * 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(numfds, fdset, timeout, block)
+     int *numfds;
+     fd_set *fdset;
+     struct timeval *timeout;
+     int *block;               /* should the select block until input arrives (i.e. no input) */
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp;
+    struct request_list *rp;
+    struct timeval now, earliest;
+    int active = 0, requests = 0;
+
+    timerclear(&earliest);
+    /*
+     * For each request outstanding, add it's socket to the fdset,
+     * and if it is the earliest timeout to expire, mark it as lowest.
+     */
+    for (slp = Sessions; slp; slp = slp->next) {
+       active++;
+       isp = slp->internal;
+       if ((isp->sd + 1) > *numfds)
+           *numfds = (isp->sd + 1);
+       FD_SET(isp->sd, fdset);
+       if (isp->requests) {
+           /* found another session with outstanding requests */
+           requests++;
+           for (rp = isp->requests; rp; rp = rp->next_request) {
+               if (!timerisset(&earliest) || timercmp(&rp->expire, &earliest, <))
+                   earliest = rp->expire;
+           }
+       }
+    }
+    if (requests == 0)         /* if none are active, skip arithmetic */
+       return active;
+
+    /*
+     * Now find out how much time until the earliest timeout.  This
+     * transforms earliest from an absolute time into a delta time, the
+     * time left until the select should timeout.
+     */
+    gettimeofday(&now, (struct timezone *) 0);
+    earliest.tv_sec--;         /* adjust time to make arithmetic easier */
+    earliest.tv_usec += 1000000L;
+    earliest.tv_sec -= now.tv_sec;
+    earliest.tv_usec -= now.tv_usec;
+    while (earliest.tv_usec >= 1000000L) {
+       earliest.tv_usec -= 1000000L;
+       earliest.tv_sec += 1;
+    }
+    if (earliest.tv_sec < 0) {
+       earliest.tv_sec = 0;
+       earliest.tv_usec = 0;
+    }
+    /* if it was blocking before or our delta time is less, reset timeout */
+    if (*block == 1 || timercmp(&earliest, timeout, <)) {
+       *timeout = earliest;
+       *block = 0;
+    }
+    return active;
+}
+
+/* 
+ * 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()
+{
+    struct session_list *slp;
+    struct snmp_session *sp;
+    struct snmp_internal_session *isp;
+#if 1 /***/                    /* replacing freeme by simpler and safer rp_next */
+    struct request_list *rp, *rp_next = 0;
+  */
+       cp = asn_build_int(cp, &length, (u_char)TIMETICKS,
+               (long *)&pdu->time, sizeof(pdu->time));
+       if (cp == NULL)
+           return -1;
+    }
+    if (length < totallength)
+       return -1;
+    bcopy((char *)buf, (char *)cp, totallength);
+    totallength += cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char)pdu->command, totallength);
+    if (cp == NULL)
+       return -1;
+    if (length < totallength)
+       return -1;
+    bcopy((char *)packet, (char *)cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+
+    cp = snmp_auth_build( packet, &length, session, is_agent, totallength );
+    if (cp == NULL)
+       return -1;
+    if ((*out_length - (cp - packet)) < totallength)
+       return -1;
+    bcopy((char *)buf, (char *)cp, totallength);
+    totallength += cp - packet;
+    *out_length = totallength;
+
+    if( session->qoS & USEC_QOS_AUTH )
+           md5Digest( packet, totallength, cp - (session->contextLen + 16),
+               cp - (session->contextLen + 16) );
+
+    return 0;
+}
+
+/*
+ * Parses the packet received on the input session, and places the data into
+ * the input pdu.  length is the length of the input packet.  If any errors
+ * are encountered, -1 is returned.  Otherwise, a 0 is returned.
+ */
+static int
+snmp_parse(session, pdu, data, length)
+    struct snmp_session *session;
+    struct snmp_pdu *pdu;
+    u_char  *data;
+    int            length;
+{
+    u_char  msg_type;
+    u_char  type;
+    u_char  *var_val;
+    long    version;
+    int            len, four;
+    u_char community[256];
+    int community_length = 256;
+    struct variable_list *vp = 0;
+    oid            objid[MAX_NAME_LEN], *op;
+    u_char  *origdata = data;
+    int      origlength = length;
+    int      ret = 0;
+    u_char  *save_data;
+
+    /* authenticates message and returns length if valid */
+    data = snmp_auth_parse(data, &length, community, &community_length, &version);
+    if (data == NULL)
+       return -1;
+
+   if( version != SNMP_VERSION_1 && version != SNMP_VERSION_2C && version != SNMP_VERSION_2 ) {
+           fprintf(stderr, "Wrong version: %ld\n", version);
+           return -1;
+    }
+
+    save_data = data;
+
+    data = asn_parse_header(data, &length, &msg_type);
+    if (data == NULL)
+       return -1;
+    pdu->command = msg_type;
+
+    if( session->authenticator ) {
+       ret = session->authenticator( origdata, origlength, save_data - community_length, 
+               community_length, session, pdu );
+       if( ret < 0 ) return ret;
+    }
+
+    if (pdu->command != TRP_REQ_MSG){
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (data == NULL)
+           return -1;
+    } else {
+       pdu->enterprise_length = MAX_NAME_LEN;
+       data = asn_parse_objid(data, &length, &type, objid, &pdu->enterprise_length);
+       if (data == NULL)
+           return -1;
+       pdu->enterprise = (oid *)calloc(1, pdu->enterprise_length * sizeof(oid));
+       bcopy((char *)objid, (char *)pdu->enterprise, pdu->enterprise_length * sizeof(oid));
+
+       four = 4;
+       data = asn_parse_string(data, &length, &type, (u_char *)&pdu->agent_addr.sin_addr.s_addr, &four);
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->time, sizeof(pdu->time));
+       if (data == NULL)
+           return -1;
+    }
+    data = asn_parse_header(data, &length, &type);
+    if (data == NULL)
+       return -1;
+    if (type != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR))
+       return -1;
+    while((int)length > 0){
+       if (pdu->variables == NULL){
+           pdu->variables = vp = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+       } else {
+           vp->next_variable = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+           vp = vp->next_variable;
+       }
+       vp->next_variable = NULL;
+       vp->val.string = NULL;
+       vp->name = NULL;
+       vp->name_length = MAX_NAME_LEN;
+       data = snmp_parse_var_op(data, objid, &vp->name_length, &vp->type, &vp->val_len, &var_val, (int *)&length);
+       if (data == NULL)
+           return -1;
+       op = (oid *)calloc(1, (unsigned)vp->name_length * sizeof(oid));
+       bcopy((char *)objid, (char *)op, vp->name_length * sizeof(oid));
+       vp->name = op;
+
+       len = PACKET_LENGTH;
+       switch((short)vp->type){
+           case ASN_INTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(long));
+               vp->val_len = sizeof(long);
+               asn_parse_int(var_val, &len, &vp->type, (long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER:
+           case GAUGE:
+           case TIMETICKS:
+           case UINTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(unsigned long));
+               vp->val_len = sizeof(unsigned long);
+               asn_parse_unsigned_int(var_val, &len, &vp->type, (unsigned long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER64:
+               vp->val.counter64 = (struct counter64 *)calloc(1,  sizeof(struct counter64) );
+               vp->val_len = sizeof(struct counter64);
+               asn_parse_unsigned_int64(var_val, &len, &vp->type,
+                                        (struct counter64 *)vp->val.counter64,
+                                        sizeof(*vp->val.counter64));
+               break;
+           case ASN_OCTET_STR:
+           case IPADDRESS:
+           case OPAQUE:
+           case NSAP:
+               vp->val.string = (u_char *)calloc(1, (unsigned)vp->val_len);
+               asn_parse_string(var_val, &len, &vp->type, vp->val.string, &vp->val_len);
+               break;
+           case ASN_OBJECT_ID:
+               vp->val_len = MAX_NAME_LEN;
+               asn_parse_objid(var_val, &len, &vp->type, objid, &vp->val_len);
+               vp->val_len *= sizeof(oid);
+               vp->val.objid = (oid *)calloc(1, (unsigned)vp->val_len);
+               bcopy((char *)objid, (char *)vp->val.objid, vp->val_len);
+               break;
+            case SNMP_NOSUCHOBJECT:
+            case SNMP_NOSUCHINSTANCE:
+            case SNMP_ENDOFMIBVIEW:
+           case ASN_NULL:
+               break;
+           default:
+               fprintf(stderr, "bad type returned (%x)\n", vp->type);
+               break;
+       }
+    }
+    return ret;
+}
+
+/*
+ * 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\10\0BÐ+= m\0\0
+È      /* \10\00¸*/ B\0\0\0\0NMPT\10\ 1Ù\88 */c\0\0\0\0for testing purposes */e key!  replace...
+     */
+ * \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 1\ 1\0\0\0\0\0\0\0\19\7fÿ¯ùsnmplib/snmp_api.c\0c\0\0.h\0\0\0\18\7fÿ°\85\10\0<Ðlib/snmp_api.c~\0~\0\0ñ\0\0\0\18\7fÿ±\1e\10\0\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\0\0\0\18\7fÿ±«\10\0=\10\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\0\0\0\18\7fÿ²\1d\10\0=0\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\0\0\0\18\7fÿ²\8a\10\0=P\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\0\0\0\18\7fÿ³
+\10\0=p\7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\0\0\0\18\7fÿ³\82\0\0\0\ 1\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\0\0\0Á\7fÿ³ù\0\0\0\10\7fÿ´\10\10\0\0%\0\19\0\15\0\0\10\0D(\0\0\0\10\7fÿ´_\10\0\0\0\ 2\\0\0\0\0\10\0\0\0\0\10\7fÿ´©\10\0=\98\0\0\ 24\0\0\0\0\10\0\0\0\0\10\7fÿ´ø\10\0\0\0\ 2H\0\0\0\0\10\0\0\0\0\10\7fÿµB\10\0>\10\7fÿµ]\7fÿµm\7fÿµz\0\0\0\10\7fÿµ \10\0>(\7fÿµ·\7fÿµÉ\7fÿµÖ\0\0\0\10\7fÿµï\10\0>@\7fÿ¶\12\7fÿ¶ \7fÿ¶4\0\0\0\10\7fÿ¶P\0\0\0\ 1\7fÿ¶r\7fÿ¶~\7fÿ¶\88\0\0\00\7fÿ¶\9f\10\0\7fÿ¶·\0\0\0\0\7fÿ¶Ù\10\0\89è\7fÿ·\ 1\0\0\0\0\7fÿ·#\7fÿ·/\7fÿ·>\10\0>X\7fÿ·V\0\0\03\0\0\0\0/usr/people/wessels/.indent.pro\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\ 1\0\0\0\0\7fÿ¯è\7fÿ¯ù\7fÿ°\f\7fÿ°\e\7fÿ°.\7fÿ°?\7fÿ°M\7fÿ°[\7fÿ°p\7fÿ°\85\7fÿ°\95\7fÿ°£\7fÿ°²\7fÿ°Å\7fÿ°Û\7fÿ°ñ\7fÿ±
+\7fÿ±\1e\7fÿ±2\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\7fÿ±\99\7fÿ±«\7fÿ±º\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\7fÿ²\ f\7fÿ²\1d\7fÿ²2\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\7fÿ²\7f\7fÿ²\8a\7fÿ²\99\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\7fÿ²ö\7fÿ³
+\7fÿ³ \7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\7fÿ³s\7fÿ³\82\7fÿ³\91\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\7fÿ³ç\7fÿ³ù\7fÿ´\ 4\7fÿ´\10\7fÿ´\1e\7fÿ´)\7fÿ´3\7fÿ´C\7fÿ´O\7fÿ´_\7fÿ´k\7fÿ´t\7fÿ´\81\7fÿ´\8f\7fÿ´\9f\7fÿ´©\7fÿ´·\7fÿ´Å\7fÿ´Ò\7fÿ´Ý\7fÿ´í\7fÿ´ø\7fÿµ\ 3\7fÿµ\10\7fÿµ\1d\7fÿµ)\7fÿµ7\7fÿµB\7fÿµM\7fÿµ]\7fÿµm\7fÿµz\7fÿµ\89\7fÿµ \7fÿµ«\7fÿµ·\7fÿµÉ\7fÿµÖ\7fÿµâ\7fÿµï\7fÿ¶\ 3\7fÿ¶\12\7fÿ¶ \7fÿ¶4\7fÿ¶?\7fÿ¶P\7fÿ¶b\7fÿ¶r\7fÿ¶~\7fÿ¶\88\7fÿ¶\94\7fÿ¶\9f\7fÿ¶«\7fÿ¶·\7fÿ¶É\7fÿ¶Ù\7fÿ¶í\7fÿ·\ 1\7fÿ·\15\7fÿ·#\7fÿ·/\7fÿ·>\7fÿ·L\7fÿ·V\7fÿ·f\7fÿ·q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\0\0\0°\0\0\0\ 4\0\0\0\0\0\0\0\b\10\0>X\0\0\0\f\10\0\0\0\0\10\0\0\0\0\0\0\0\14\0\0\0\14\0\0\0\14\0\0\0\18\0\0\0\18\0\0\0\18\0\0\0\1c\0\0\0\1c\0\0\0\1c\0\0\0\1c\0\0\0 \0\0\0 \0\0\0 \0\0\0$\0\0\0\v\0\0\0\e\0\0\0\19\0\0\0\v\0\0\0\e\0\0\0@\0\0\0\0\0\0\0\0\0\0\0\0\10\0,\b\0\0\0\1a\10\02\88\0\0\0\1a\0\0\0\0\0\0\0\1a\10\0\85\b\0\0\0\0\10\0>X\0\0\0\0\0\0\0\0\0\0\0\0\10\0\82à\0\0\0\0\0\0\ 1C\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e0\0\0\0\v\0\0\0\e\0\0\0\18\0\0\0\v\0\0\0\1a\0\0\0\17\0\0\0\v\0\0\0 \0\0\0\0\10\0\8d¸ude/snmp_groupvars.h~\0\0\b\0\0\0\b\0\0\0 \0\0\0\0\10\0\8dàude/snmp_groupvars.h\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8eX\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e\80\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e¨\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8eÐ\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\0\0\0\ 1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\84©\0\0\0\0/***********************************************************
+       Copyright 1989 by Carnegie Mellon University
+
+                      All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the name of CMU not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+******************************************************************/
+/*
+ * snmp_api.c - API for access to snmp.
+ */
+#define DEBUG_SNMPTRACE                0 /* set to 1 to print all SNMP actions */
+#define DEBUG_SNMPFULLDUMP     0 /* set to 1 to dump all SNMP packets */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#ifdef linux
+#include <arpa/inet.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#endif
+
+
+#include "asn1.h"
+#include "snmp.h"
+#include "snmp_impl.h"
+#include "snmp_api.h"
+#include "snmp_client.h"
+
+#define PACKET_LENGTH  4500
+
+#ifndef BSD4_3
+#define BSD4_2
+#endif
+
+#if !defined(BSD4_3) && !defined(linux) && !defined(sun)
+
+typedef long   fd_mask;
+#define NFDBITS        (sizeof(fd_mask) * NBBY)        /* bits per mask */
+
+#define        FD_SET(n, p)    ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+#define        FD_CLR(n, p)    ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+#define        FD_ISSET(n, p)  ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+#define FD_ZERO(p)     bzero((char *)(p), sizeof(*(p)))
+#endif
+
+oid default_enterprise[] = {1, 3, 6, 1, 4, 1, 3, 1, 1}; /* enterprises.cmu.systems.cmuSNMP */
+
+#define DEFAULT_COMMUNITY   "public"
+#define DEFAULT_REMPORT            SNMP_PORT
+#define DEFAULT_ENTERPRISE  default_enterprise
+#define DEFAULT_TIME       0
+#define DEFAULT_MMS        1389 /* large, randomly picked for testing purposes */
+
+/*
+ * Internal information about the state of the snmp session.
+ */
+struct snmp_internal_session {
+    int            sd;         /* socket descriptor for this connection */
+    ipaddr  addr;      /* address of connected peer */
+    struct request_list *requests;/* Info about outstanding requests */
+};
+
+/*
+ * A list of all the outstanding requests for a particular session.
+ */
+struct request_list {
+    struct request_list *next_request;
+    u_long  request_id;        /* request id */
+    int            retries;    /* Number of retries */
+    u_long timeout;    /* length to wait for timeout */
+    struct timeval time; /* Time this request was made */
+    struct timeval expire;  /* time this request is due to expire */
+    struct snmp_pdu *pdu;   /* The pdu for this request (saved so it can be retransmitted */
+};
+
+/*
+ * The list of active/open sessions.
+ */
+struct session_list {
+    struct session_list *next;
+    struct snmp_session *session;
+    struct snmp_internal_session *internal;
+};
+
+struct session_list *Sessions = NULL;
+
+u_long Reqid = 0;
+int snmp_errno = 0;
+
+char *api_errors[4] = {
+    "Unknown session",
+    "Unknown host",
+    "Invalid local port",
+    "Unknown Error"
+};
+
+
+void sync_with_agent();
+int parse_app_community_string();
+void snmp_synch_setup();
+int snmp_synch_response();
+void md5Digest();
+
+
+static char *
+api_errstring(snmp_errnumber)
+    int        snmp_errnumber;
+{
+    if (snmp_errnumber <= SNMPERR_BAD_SESSION && snmp_errnumber >= SNMPERR_GENERR){
+       return api_errors[snmp_errnumber + 4];
+    } else {
+       return "Unknown Error";
+    }
+}
+
+#if 0
+/*
+ * Gets initial request ID for all transactions.
+ */
+static void
+init_snmp(){
+    struct timeval tv;
+
+    gettimeofday(&tv, (struct timezone *)0);
+    srandom(tv.tv_sec ^ tv.tv_usec);
+    Reqid = random();
+}
+#endif
+
+
+/*
+ * Dump snmp packet to stdout:
+ */
+static void
+snmp_print_packet(packet, length, addr, code)
+  char *packet; 
+  int length; 
+  ipaddr addr; 
+  int code;
+{
+  if(length < 0) {
+    return;
+  }
+  if (code <= 0) { /* received */
+    printf("\nReceived %4d bytes from ", length);
+  }
+  else { /* sending */
+    printf("\nSending  %4d bytes to   ", length);
+  }
+  printf("%s:", inet_ntoa(addr.sin_addr));
+#if DEBUG_SNMPFULLDUMP
+  for (count = 0; count < length; count++) {
+    if ((count & 15) == 0) {
+      printf("\n  ");
+    }
+    printf("%02X ", (int)(packet[count]&255));
+  }
+#endif
+  fflush(stdout);
+}
+
+#if DEBUG_SNMPTRACE
+/*
+ * Print request
+ */
+#define TRACE_SEND   (0)
+#define TRACE_RECV   (1)
+#define TRACE_TIMEOUT (2)
+static void
+snmp_print_trace(slp, rp, code)
+  struct session_list *slp;
+  struct request_list *rp;
+  int code;
+{
+  int reqid=0, retries=1;
+  if( rp ){
+    reqid = rp->request_id;
+    retries = rp->retries;
+  }  
+  printf("\n Session %2d  ReqId %4d  ", slp->internal->sd, reqid);
+  switch(code)
+    { 
+    case TRACE_SEND:    printf("send pdu (%d)", retries);break; 
+    case TRACE_RECV:    printf("recv pdu");break; 
+    case TRACE_TIMEOUT: printf("time out");break; 
+    }
+  fflush(stdout);
+}
+#endif /* DEBUG_SNMPTRACE */
+
+
+
+
+/*
+ * 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.
+ */
+struct snmp_session *
+snmp_open(session)
+    struct snmp_session *session;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp;
+    u_char *cp;
+    int sd;
+    u_long addr;
+    struct sockaddr_in me;
+    struct hostent *hp;
+    struct servent *servp;
+    extern int check_received_pkt();
+
+    /* Copy session structure and link into list */
+    slp = (struct session_list *)calloc(1, sizeof(struct session_list));
+    slp->internal = isp = (struct snmp_internal_session *)calloc(1, sizeof(struct snmp_internal_session));
+    bzero((char *)isp, sizeof(struct snmp_internal_session));
+    slp->internal->sd = -1; /* mark it not set */
+    slp->session = (struct snmp_session *)calloc(1, sizeof(struct snmp_session));
+    bcopy((char *)session, (char *)slp->session, sizeof(struct snmp_session));
+    session = slp->session;
+    /* now link it in. */
+    slp->next = Sessions;
+    Sessions = slp;
+
+    /*
+     * session now points to the new structure that still contains pointers to
+     * data allocated elsewhere.  Some of this data is copied to space malloc'd
+     * here, and the pointer replaced with the new one.
+     */
+
+    if (session->peername != NULL){
+       cp = (u_char *)calloc(1, (unsigned)strlen(session->peername) + 1);
+       strcpy((char *)cp, session->peername);
+       session->peername = (char *)cp;
+    }
+
+    if (session->retries == SNMP_DEFAULT_RETRIES)
+       session->retries = SNMP_API_DEFAULT_RETRIES;
+    if (session->timeout == SNMP_DEFAULT_TIMEOUT)
+       session->timeout = SNMP_API_DEFAULT_TIMEOUT;
+    if (session->MMS == 0 )
+       session->MMS = DEFAULT_MMS;
+    isp->requests = NULL;
+
+
+    /* Fill in defaults if necessary */
+    if (session->community_len != SNMP_DEFAULT_COMMUNITY_LEN){
+       if( *session->community == '+' ) {
+               session->community_len--;
+               cp = (u_char *) calloc(1, (unsigned) session->community_len);
+               bcopy((char *) session->community+1, (char *)cp,
+                     session->community_len);
+               session->version = SNMP_VERSION_2C;
+       } else {
+               cp = (u_char *) calloc(1, (unsigned) session->community_len);
+               bcopy((char *) session->community, (char *) cp, 
+                     session->community_len);
+       }
+
+    } else {
+       session->community_len = strlen(DEFAULT_COMMUNITY);
+       cp = (u_char *)calloc(1, (unsigned)session->community_len);
+       bcopy((char *)DEFAULT_COMMUNITY, (char *)cp, session->community_len);
+    }
+
+    /* Set up connections */
+    sd = socket(AF_INET, SOCK_DGRAM, 0);
+    if (sd < 0){
+       perror("socket");
+       snmp_errno = SNMPERR_GENERR;
+       if (!snmp_close(session)){
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+           exit(1);
+       }
+       return 0;
+    }
+    isp->sd = sd;
+
+    if (session->peername != SNMP_DEFAULT_PEERNAME){
+       if ((addr = inet_addr(session->peername)) != -1){
+           bcopy((char *)&addr, (char *)&isp->addr.sin_addr, sizeof(isp->addr.sin_addr));
+       } else {
+           hp = gethostbyname(session->peername);
+           if (hp == NULL){
+               fprintf(stderr, "unknown host: %s\n", session->peername);
+               snmp_errno = SNMPERR_BAD_ADDRESS;
+               if (!snmp_close(session)){
+                   fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+                   exit(2);
+               }
+               return 0;
+           } else {
+               bcopy((char *)hp->h_addr, (char *)&isp->addr.sin_addr, hp->h_length);
+           }
+       }
+       isp->addr.sin_family = AF_INET;
+       if (session->remote_port == SNMP_DEFAULT_REMPORT){
+           /*servp = getservbyname("snmp", "udp");*/
+           servp=NULL;
+           if (servp != NULL){
+               isp->addr.sin_port = servp->s_port;
+           } else {
+               isp->addr.sin_port = htons(SNMP_PORT);
+           }
+       } else {
+           isp->addr.sin_port = htons(session->remote_port);
+       }
+    } else {
+       isp->addr.sin_addr.s_addr = SNMP_DEFAULT_ADDRESS;
+    }
+
+    me.sin_family = AF_INET;
+    me.sin_addr.s_addr = INADDR_ANY;
+    me.sin_port = htons(session->local_port);
+    if (bind(sd, (struct sockaddr *)&me, sizeof(me)) != 0){
+       perror("bind");
+       snmp_errno = SNMPERR_BAD_LOCPORT;
+       if (! snmp_close(session)){
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n", 
+                   api_errstring(snmp_errno));
+           exit(3);
+       }
+       return 0;
+    }
+
+    if( *cp == '/' ) {
+       session->authenticator = check_received_pkt;
+       sync_with_agent(session);
+       parse_app_community_string( session );
+       session->qoS |= USEC_QOS_GENREPORT;
+    }
+
+    /* replace comm pointer with pointer to new data: */
+    session->community = cp;   
+
+    return session;
+}
+
+void
+sync_with_agent( session )
+struct snmp_session *session;
+{
+    struct snmp_pdu *pdu, *response = 0;
+    int status;
+
+    session->qoS = USEC_QOS_GENREPORT;
+    session->userLen = 6;
+    session->version = SNMP_VERSION_2;
+    strcpy( session->userName, "public" );
+
+    snmp_synch_setup(session);
+    pdu = snmp_pdu_create(GET_REQ_MSG);
+    status = snmp_synch_response(session, pdu, &response);
+
+    if (status == STAT_SUCCESS){
+       memcpy( session->agentID, response->params.agentID, 12 );
+
+       /* save the clocks -- even though they are not authentic */
+       session->agentBoots = response->params.agentBoots;
+       session->agentTime = response->params.agentTime;
+       session->agentClock = response->params.agentTime - time(NULL);
+
+    } else {
+           if (status == STAT_TIMEOUT){
+               printf("No Response from %s\n", session->peername);
+           } else {    /* status == STAT_ERROR */
+               printf("An error occurred, Quitting\n");
+           }
+           exit( -1 );
+    }
+
+    /** freed to early: 
+      snmp_free_pdu(pdu);
+      if (response) snmp_free_pdu(response);
+     **/
+}
+#if 1 /***/
+/*
+ * Unlink one element from input request list,
+ * then free it and it's pdu.
+ */
+static void
+free_one_request(isp, orp)
+    struct snmp_internal_session *isp;
+    struct request_list *orp;
+{
+    struct request_list *rp;
+    if(! orp) return;
+    if(isp->requests == orp){ 
+      isp->requests = orp->next_request; /* unlink head */
+    }
+    else{
+      for(rp = isp->requests; rp; rp = rp->next_request){
+        if(rp->next_request == orp){ 
+         rp->next_request = orp->next_request; /* unlink element */
+         break;
+        }
+      }
+    }
+    if (orp->pdu != NULL){
+      snmp_free_pdu(orp->pdu);
+    }
+    free((char *)orp);
+}
+#endif /***/
+/*
+ * Free each element in the input request list.
+ */
+static void
+free_request_list(rp)
+    struct request_list *rp;
+{
+    struct request_list *orp;
+
+    while(rp){
+       orp = rp;
+       rp = rp->next_request;
+       if (orp->pdu != NULL)
+           snmp_free_pdu(orp->pdu);
+       free((char *)orp);
+    }
+}
+
+/*
+ * 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.
+ */
+int 
+snmp_close(session)
+    struct snmp_session *session;
+{
+    struct session_list *slp = NULL, *oslp = NULL;
+
+    if (Sessions->session == session){ /* If first entry */
+       slp = Sessions;
+       Sessions = slp->next;
+    } else {
+       for(slp = Sessions; slp; slp = slp->next){
+           if (slp->session == session){
+               if (oslp)   /* if we found entry that points here */
+                   oslp->next = slp->next;     /* link around this entry */
+               break;
+           }
+           oslp = slp;
+       }
+    }
+    /* If we found the session, free all data associated with it */
+    if (slp){
+       if (slp->session->community != NULL)
+           free((char *)slp->session->community);
+       if(slp->session->peername != NULL)
+           free((char *)slp->session->peername);
+       free((char *)slp->session);
+       if (slp->internal->sd != -1)
+           close(slp->internal->sd);
+       free_request_list(slp->internal->requests);
+       free((char *)slp->internal);
+       free((char *)slp);
+    } else {
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    return 1;
+}
+
+/*
+ * Takes a session and a pdu and serializes the ASN PDU into the area
+ * pointed to by packet.  out_length is the size of the data area available.
+ * Returns the length of the completed packet in out_length.  If any errors
+ * occur, -1 is returned.  If all goes well, 0 is returned.
+ */
+int
+snmp_build(session, pdu, packet, out_length, is_agent)
+    struct snmp_session        *session;
+    struct snmp_pdu    *pdu;
+    u_char     *packet;
+    int                        *out_length;
+    int                         is_agent;
+{
+    u_char  buf[PACKET_LENGTH];
+    u_char  *cp;
+    struct variable_list *vp;
+    int            length;
+    int            totallength;
+
+    length = *out_length;
+    cp = packet;
+    for(vp = pdu->variables; vp; vp = vp->next_variable){
+       cp = snmp_build_var_op(cp, vp->name, &vp->name_length, vp->type, vp->val_len, (u_char *)vp->val.string, &length);
+       if (cp == NULL)
+           return -1;
+    }
+    totallength = cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR), totallength);
+    if (cp == NULL)
+       return -1;
+    bcopy((char *)packet, (char *)cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+    if (pdu->command != TRP_REQ_MSG){
+       /* request id */
+       cp = asn_build_int(packet, &length,
+           (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+           (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (cp == NULL)
+           return -1;
+       /* error status */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (cp == NULL)
+           return -1;
+       /* error index */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (cp == NULL)
+           return -1;
+    } else {   /* this is a trap message */
+       /* enterprise */
+       cp = asn_build_objid(packet, &length,
+           (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID),
+           (oid *)pdu->enterprise, pdu->enterprise_length);
+       if (cp == NULL)
+           return -1;
+       /* agent-addr */
+       cp = asn_build_string(cp, &length, (u_char)IPADDRESS,
+               (u_char *)&pdu->agent_addr.sin_addr.s_addr, sizeof(pdu->agent_addr.sin_addr.s_addr));
+       if (cp == NULL)
+           return -1;
+       /* generic trap */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (cp == NULL)
+           return -1;
+       /* specific trap */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (cp == NULL)
+           return -1;
+       /* timestamp  */
+       cp = asn_build_int(cp, &length, (u_char)TIMETICKS,
+               (long *)&pdu->time, sizeof(pdu->time));
+       if (cp == NULL)
+           return -1;
+    }
+    if (length < totallength)
+       return -1;
+    bcopy((char *)buf, (char *)cp, totallength);
+    totallength += cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char)pdu->command, totallength);
+    if (cp == NULL)
+       return -1;
+    if (length < totallength)
+       return -1;
+    bcopy((char *)packet, (char *)cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+
+    cp = snmp_auth_build( packet, &length, session, is_agent, totallength );
+    if (cp == NULL)
+       return -1;
+    if ((*out_length - (cp - packet)) < totallength)
+       return -1;
+    bcopy((char *)buf, (char *)cp, totallength);
+    totallength += cp - packet;
+    *out_length = totallength;
+
+    if( session->qoS & USEC_QOS_AUTH )
+           md5Digest( packet, totallength, cp - (session->contextLen + 16),
+               cp - (session->contextLen + 16) );
+
+    return 0;
+}
+
+/*
+ * Parses the packet received on the input session, and places the data into
+ * the input pdu.  length is the length of the input packet.  If any errors
+ * are encountered, -1 is returned.  Otherwise, a 0 is returned.
+ */
+static int
+snmp_parse(session, pdu, data, length)
+    struct snmp_session *session;
+    struct snmp_pdu *pdu;
+    u_char  *data;
+    int            length;
+{
+    u_char  msg_type;
+    u_char  type;
+    u_char  *var_val;
+    long    version;
+    int            len, four;
+    u_char community[256];
+    int community_length = 256;
+    struct variable_list *vp = 0;
+    oid            objid[MAX_NAME_LEN], *op;
+    u_char  *origdata = data;
+    int      origlength = length;
+    int      ret = 0;
+    u_char  *save_data;
+
+    /* authenticates message and returns length if valid */
+    data = snmp_auth_parse(data, &length, community, &community_length, &version);
+    if (data == NULL)
+       return -1;
+
+   if( version != SNMP_VERSION_1 && version != SNMP_VERSION_2C && version != SNMP_VERSION_2 ) {
+           fprintf(stderr, "Wrong version: %ld\n", version);
+           return -1;
+    }
+
+    save_data = data;
+
+    data = asn_parse_header(data, &length, &msg_type);
+    if (data == NULL)
+       return -1;
+    pdu->command = msg_type;
+
+    if( session->authenticator ) {
+       ret = session->authenticator( origdata, origlength, save_data - community_length, 
+               community_length, session, pdu );
+       if( ret < 0 ) return ret;
+    }
+
+    if (pdu->command != TRP_REQ_MSG){
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (data == NULL)
+           return -1;
+    } else {
+       pdu->enterprise_length = MAX_NAME_LEN;
+       data = asn_parse_objid(data, &length, &type, objid, &pdu->enterprise_length);
+       if (data == NULL)
+           return -1;
+       pdu->enterprise = (oid *)calloc(1, pdu->enterprise_length * sizeof(oid));
+       bcopy((char *)objid, (char *)pdu->enterprise, pdu->enterprise_length * sizeof(oid));
+
+       four = 4;
+       data = asn_parse_string(data, &length, &type, (u_char *)&pdu->agent_addr.sin_addr.s_addr, &four);
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->time, sizeof(pdu->time));
+       if (data == NULL)
+           return -1;
+    }
+    data = asn_parse_header(data, &length, &type);
+    if (data == NULL)
+       return -1;
+    if (type != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR))
+       return -1;
+    while((int)length > 0){
+       if (pdu->variables == NULL){
+           pdu->variables = vp = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+       } else {
+           vp->next_variable = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+           vp = vp->next_variable;
+       }
+       vp->next_variable = NULL;
+       vp->val.string = NULL;
+       vp->name = NULL;
+       vp->name_length = MAX_NAME_LEN;
+       data = snmp_parse_var_op(data, objid, &vp->name_length, &vp->type, &vp->val_len, &var_val, (int *)&length);
+       if (data == NULL)
+           return -1;
+       op = (oid *)calloc(1, (unsigned)vp->name_length * sizeof(oid));
+       bcopy((char *)objid, (char *)op, vp->name_length * sizeof(oid));
+       vp->name = op;
+
+       len = PACKET_LENGTH;
+       switch((short)vp->type){
+           case ASN_INTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(long));
+               vp->val_len = sizeof(long);
+               asn_parse_int(var_val, &len, &vp->type, (long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER:
+           case GAUGE:
+           case TIMETICKS:
+           case UINTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(unsigned long));
+               vp->val_len = sizeof(unsigned long);
+               asn_parse_unsigned_int(var_val, &len, &vp->type, (unsigned long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER64:
+               vp->val.counter64 = (struct counter64 *)calloc(1,  sizeof(struct counter64) );
+               vp->val_len = sizeof(struct counter64);
+               asn_parse_unsigned_int64(var_val, &len, &vp->type,
+                                        (struct counter64 *)vp->val.counter64,
+                                        sizeof(*vp->val.counter64));
+               break;
+           case ASN_OCTET_STR:
+           case IPADDRESS:
+           case OPAQUE:
+           case NSAP:
+               vp->val.string = (u_char *)calloc(1, (unsigned)vp->val_len);
+               asn_parse_string(var_val, &len, &vp->type, vp->val.string, &vp->val_len);
+               break;
+           case ASN_OBJECT_ID:
+               vp->val_len = MAX_NAME_LEN;
+               asn_parse_objid(var_val, &len, &vp->type, objid, &vp->val_len);
+               vp->val_len *= sizeof(oid);
+               vp->val.objid = (oid *)calloc(1, (unsigned)vp->val_len);
+               bcopy((char *)objid, (char *)vp->val.objid, vp->val_len);
+               break;
+            case SNMP_NOSUCHOBJECT:
+            case SNMP_NOSUCHINSTANCE:
+            case SNMP_ENDOFMIBVIEW:
+           case ASN_NULL:
+               break;
+           default:
+               fprintf(stderr, "bad type returned (%x)\n", vp->type);
+               break;
+       }
+    }
+    return ret;
+}
+
+/*
+ * 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(session, pdu)
+    struct snmp_session *session;
+    struct snmp_pdu    *pdu;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp = NULL;
+    u_char  packet[PACKET_LENGTH];
+    int length = PACKET_LENGTH;
+    struct request_list *rp;
+    struct timeval tv;
+
+    for(slp = Sessions; slp; slp = slp->next){
+       if (slp->session == session){
+           isp = slp->internal;
+           break;
+       }
+    }
+
+    if (! pdu) {
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+
+    if (isp == NULL){
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG
+       || pdu->command == GET_RSP_MSG || pdu->command == SET_REQ_MSG 
+       || pdu->command == GETBULK_REQ_MSG ){
+       if (pdu->reqid == SNMP_DEFAULT_REQID)
+           pdu->reqid = ++Reqid;
+       if (pdu->errstat == SNMP_DEFAULT_ERRSTAT)
+           pdu->errstat = 0;
+       if (pdu->errindex == SNMP_DEFAULT_ERRINDEX)
+           pdu->errindex = 0;
+    } else {
+       /* fill in trap defaults */
+       pdu->reqid = 1; /* give a bogus non-error reqid for traps */
+       if (pdu->enterprise_length == SNMP_DEFAULT_ENTERPRISE_LENGTH){
+           pdu->enterprise = (oid *)calloc(1, sizeof(DEFAULT_ENTERPRISE));
+           bcopy((char *)DEFAULT_ENTERPRISE, (char *)pdu->enterprise, sizeof(DEFAULT_ENTERPRISE));
+           pdu->enterprise_length = sizeof(DEFAULT_ENTERPRISE)/sizeof(oid);
+       }
+       if (pdu->time == SNMP_DEFAULT_TIME)
+           pdu->time = DEFAULT_TIME;
+    }
+    if (pdu->address.sin_addr.s_addr == SNMP_DEFAULT_ADDRESS){
+       if (isp->addr.sin_addr.s_addr != SNMP_DEFAULT_ADDRESS){
+           bcopy((char *)&isp->addr, (char *)&pdu->address, sizeof(pdu->address));
+       } else {
+           fprintf(stderr, "No remote IP address specified\n");
+           snmp_errno = SNMPERR_BAD_ADDRESS;
+           return 0;
+       }
+    }
+       
+
+    if (snmp_build(session, pdu, packet, &length, 0) < 0){
+       fprintf(stderr, "Error building packet\n");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+#if 1 /***/
+    if (snmp_dump_packet){
+      snmp_print_packet(packet, length, pdu->address, 1);
+    }
+#endif /***/
+
+    gettimeofday(&tv, (struct timezone *)0);
+    if (sendto(isp->sd, (char *)packet, length, 0, (struct sockaddr *)&pdu->address, sizeof(pdu->address)) < 0){
+       perror("sendto");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG 
+     || pdu->command == SET_REQ_MSG || pdu->command == GETBULK_REQ_MSG ){
+       /* set up to expect a response */
+       rp = (struct request_list *)calloc(1, sizeof(struct request_list));
+#if 1 /***/
+        if(! rp){
+          fprintf(stderr, "Out of memory!\n");
+          snmp_errno = SNMPERR_GENERR;
+          return 0;
+        }
+#endif /***/
+       rp->next_request = isp->requests;
+       isp->requests = rp;
+       rp->pdu = pdu;
+       rp->request_id = pdu->reqid;
+
+       rp->retries = 1;
+       rp->timeout = session->timeout;
+       rp->time = tv;
+       tv.tv_usec += rp->timeout;
+       tv.tv_sec += tv.tv_usec / 1000000L;
+       tv.tv_usec %= 1000000L;
+       rp->expire = tv;
+#if DEBUG_SNMPTRACE
+       snmp_print_trace(slp, rp, TRACE_SEND);
+#endif
+    }
+    return pdu->reqid;
+}
+
+/*
+ * Frees the pdu and any malloc'd data associated with it.
+ */
+void
+snmp_free_pdu(struct snmp_pdu * pdu)
+{
+    struct variable_list *vp, *ovp;
+
+    if (! pdu)
+      return;
+
+    vp = pdu->variables;
+    while(vp){
+      if (vp->name) {
+       free((char *)vp->name);
+      }
+      if (vp->val.string) {
+       free((char *)vp->val.string);
+      }
+      ovp = vp;
+      vp = vp->next_variable;
+      free((char *)ovp);
+    }
+    if (pdu->enterprise) {
+      free((char *)pdu->enterprise);
+    }
+    free((char *)pdu);
+}
+
+
+/*
+ * 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(fdset)
+    fd_set  *fdset;
+{
+    struct session_list *slp;
+    struct snmp_session *sp;
+    struct snmp_internal_session *isp;
+    u_char packet[PACKET_LENGTH];
+    struct sockaddr_in from;
+    ssize_t length, fromlength;
+    struct snmp_pdu *pdu;
+    struct request_list *rp /**, *orp **/ ;
+
+    for(slp = Sessions; slp; slp = slp->next){
+       if (FD_ISSET(slp->internal->sd, fdset)){
+           sp = slp->session;
+           isp = slp->internal;
+           fromlength = sizeof(from);
+           length = recvfrom(isp->sd, (char *)packet, PACKET_LENGTH, 0, (struct sockaddr *)&from, &fromlength);
+           if (length == -1) {
+               perror("recvfrom");
+               return;
+           }
+#if 1 /***/
+           if (snmp_dump_packet){
+             snmp_print_packet(packet, length, from, 0);
+           }
+           pdu = (struct snmp_pdu *)calloc(1, sizeof(struct snmp_pdu));
+
+           if(! pdu){
+             fprintf(stderr, "Out of memory!\n");
+             snmp_errno = SNMPERR_GENERR;
+             return;
+           }
+#endif /***/
+
+           pdu->address = from;
+           pdu->reqid = 0;
+           pdu->variables = NULL;
+           pdu->enterprise = NULL;
+           pdu->enterprise_length = 0;
+           if (snmp_parse(sp, pdu, packet, length) < 0){
+               fprintf(stderr, "Mangled packet\n");
+               snmp_free_pdu(pdu);
+               return;
+           }
+
+           if (pdu->command == GET_RSP_MSG || pdu->command == REPORT_MSG){
+#if 1 /***/ /* bug fix: illegal re-use of rp killed some requests */
+             struct request_list *rp_next= 0;
+             for(rp = isp->requests; rp; rp = rp_next){
+               rp_next = rp->next_request;
+               if (rp->request_id == pdu->reqid){
+#if DEBUG_SNMPTRACE
+                 snmp_print_trace(slp, rp, TRACE_RECV);
+#endif
+                 if (sp->callback(RECEIVED_MESSAGE, sp, pdu->reqid, pdu, sp->callback_magic) == 1){
+                   /* successful, so delete request */
+                   free_one_request(isp, rp);
+                   break;  /* no more request with the same reqid */
+                 }
+               }
+             }
+#endif /***/
+           } else if (pdu->command == GET_REQ_MSG 
+                   || pdu->command == GETNEXT_REQ_MSG
+                   || pdu->command == GETBULK_REQ_MSG
+                   || pdu->command == TRP_REQ_MSG || pdu->command == SET_REQ_MSG){
+#if DEBUG_SNMPTRACE
+             snmp_print_trace(slp, NULL, TRACE_RECV);
+#endif
+             sp->callback(RECEIVED_MESSAGE, sp, pdu->reqid, pdu, sp->callback_magic);
+           }
+           snmp_free_pdu(pdu);
+       }
+    }
+}
+
+/*
+ * 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(numfds, fdset, timeout, block)
+    int            *numfds;
+    fd_set  *fdset;
+    struct timeval *timeout;
+    int            *block; /* should the select block until input arrives (i.e. no input) */
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp;
+    struct request_list *rp;
+    struct timeval now, earliest;
+    int active = 0, requests = 0;
+
+    timerclear(&earliest);
+    /*
+     * For each request outstanding, add it's socket to the fdset,
+     * and if it is the earliest timeout to expire, mark it as lowest.
+     */
+    for(slp = Sessions; slp; slp = slp->next){
+       active++;
+       isp = slp->internal;
+       if ((isp->sd + 1) > *numfds)
+           *numfds = (isp->sd + 1);
+       FD_SET(isp->sd, fdset);
+       if (isp->requests){
+           /* found another session with outstanding requests */
+           requests++;
+           for(rp = isp->requests; rp; rp = rp->next_request){
+               if (!timerisset(&earliest) || timercmp(&rp->expire, &earliest, <))
+                   earliest = rp->expire;
+           }
+       }
+    }
+    if (requests == 0) /* if none are active, skip arithmetic */
+       return active;
+
+    /*
+     * Now find out how much time until the earliest timeout.  This
+     * transforms earliest from an absolute time into a delta time, the
+     * time left until the select should timeout.
+     */
+    gettimeofday(&now, (struct timezone *)0);
+    earliest.tv_sec--; /* adjust time to make arithmetic easier */
+    earliest.tv_usec += 1000000L;
+    earliest.tv_sec -= now.tv_sec;
+    earliest.tv_usec -= now.tv_usec;
+    while (earliest.tv_usec >= 1000000L){
+       earliest.tv_usec -= 1000000L;
+       earliest.tv_sec += 1;
+    }
+    if (earliest.tv_sec < 0){
+       earliest.tv_sec = 0;
+       earliest.tv_usec = 0;
+    }
+
+    /* if it was blocking before or our delta time is less, reset timeout */
+    if (*block == 1 || timercmp(&earliest, timeout, <)){
+       *timeout = earliest;
+       *block = 0;
+    }
+    return active;
+}
+
+/* 
+ * 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()
+{
+    struct session_list *slp;
+    struct snmp_session *sp;
+    struct snmp_internal_session *isp;
+#if 1 /***/ /* replacing freeme by simpler and safer rp_next*/
+    struct request_list *rp, *rp_next = 0;
+#endif /***/
+       struct timeval now;
+
+    gettimeofday(&now, (struct timezone *) 0);
+    /*
+     * For each request outstanding, check to see if it has expired.
+     */
+    for (slp = Sessions; slp; slp = slp->next) {
+       sp = slp->session;
+       isp = slp->internal;
+#if 1 /***/                    /* simplification */
+       for (rp = isp->requests; rp; rp = rp_next) {
+           rp_next = rp->next_request;
+           if (timercmp(&rp->expire, &now, <)) {
+               /* this timer has expired */
+               if (rp->retries >= sp->retries) {
+#if DEBUG_SNMPTRACE
+                   snmp_print_trace(slp, rp, TRACE_TIMEOUT);
+#endif
+                   /* No more chances, delete this entry */
+                   sp->callback(TIMED_OUT, sp, rp->pdu->reqid, rp->pdu, sp->callback_magic);
+                   free_one_request(isp, rp);
+                   continue;
+#endif/***/ mplification */by simpler and safer rp_next*/n s */ replace...
+     */
+ * \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 1\ 1\0\0\0\0\0\0\0\19\7fÿ¯ùsnmplib/snmp_api.c\0c\0\0.h\0\0\0\18\7fÿ°\85\10\0<Ðlib/snmp_api.c~\0~\0\0ñ\0\0\0\18\7fÿ±\1e\10\0\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\0\0\0\18\7fÿ±«\10\0=\10\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\0\0\0\18\7fÿ²\1d\10\0=0\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\0\0\0\18\7fÿ²\8a\10\0=P\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\0\0\0\18\7fÿ³
+\10\0=p\7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\0\0\0\18\7fÿ³\82\0\0\0\ 1\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\0\0\0Á\7fÿ³ù\0\0\0\10\7fÿ´\10\10\0\0%\0\19\0\15\0\0\10\0D(\0\0\0\10\7fÿ´_\10\0\0\0\ 2\\0\0\0\0\10\0\0\0\0\10\7fÿ´©\10\0=\98\0\0\ 24\0\0\0\0\10\0\0\0\0\10\7fÿ´ø\10\0\0\0\ 2H\0\0\0\0\10\0\0\0\0\10\7fÿµB\10\0>\10\7fÿµ]\7fÿµm\7fÿµz\0\0\0\10\7fÿµ \10\0>(\7fÿµ·\7fÿµÉ\7fÿµÖ\0\0\0\10\7fÿµï\10\0>@\7fÿ¶\12\7fÿ¶ \7fÿ¶4\0\0\0\10\7fÿ¶P\0\0\0\ 1\7fÿ¶r\7fÿ¶~\7fÿ¶\88\0\0\00\7fÿ¶\9f\0\0\0\0\7fÿ¶·\0\0\0\0\7fÿ¶Ù\10\0\82à\7fÿ·\ 1\0\0\0\0\7fÿ·#\7fÿ·/\7fÿ·>\10\0>X\7fÿ·V\0\0\03\0\0\0\0/usr/people/wessels/.indent.pro\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\ 1\0\0\0\0\7fÿ¯è\7fÿ¯ù\7fÿ°\f\7fÿ°\e\7fÿ°.\7fÿ°?\7fÿ°M\7fÿ°[\7fÿ°p\7fÿ°\85\7fÿ°\95\7fÿ°£\7fÿ°²\7fÿ°Å\7fÿ°Û\7fÿ°ñ\7fÿ±
+\7fÿ±\1e\7fÿ±2\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\7fÿ±\99\7fÿ±«\7fÿ±º\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\7fÿ²\ f\7fÿ²\1d\7fÿ²2\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\7fÿ²\7f\7fÿ²\8a\7fÿ²\99\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\7fÿ²ö\7fÿ³
+\7fÿ³ \7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\7fÿ³s\7fÿ³\82\7fÿ³\91\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\7fÿ³ç\7fÿ³ù\7fÿ´\ 4\7fÿ´\10\7fÿ´\1e\7fÿ´)\7fÿ´3\7fÿ´C\7fÿ´O\7fÿ´_\7fÿ´k\7fÿ´t\7fÿ´\81\7fÿ´\8f\7fÿ´\9f\7fÿ´©\7fÿ´·\7fÿ´Å\7fÿ´Ò\7fÿ´Ý\7fÿ´í\7fÿ´ø\7fÿµ\ 3\7fÿµ\10\7fÿµ\1d\7fÿµ)\7fÿµ7\7fÿµB\7fÿµM\7fÿµ]\7fÿµm\7fÿµz\7fÿµ\89\7fÿµ \7fÿµ«\7fÿµ·\7fÿµÉ\7fÿµÖ\7fÿµâ\7fÿµï\7fÿ¶\ 3\7fÿ¶\12\7fÿ¶ \7fÿ¶4\7fÿ¶?\7fÿ¶P\7fÿ¶b\7fÿ¶r\7fÿ¶~\7fÿ¶\88\7fÿ¶\94\7fÿ¶\9f\7fÿ¶«\7fÿ¶·\7fÿ¶É\7fÿ¶Ù\7fÿ¶í\7fÿ·\ 1\7fÿ·\15\7fÿ·#\7fÿ·/\7fÿ·>\7fÿ·L\7fÿ·V\7fÿ·f\7fÿ·q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0@    \0\0\0\0h)
+    struct snmp_session *session;
+    struct snmp_pdu *pdu;
+    u_char  *data;
+    int            length;
+{
+    u_char  msg_type;
+    u_char  type;
+    u_char  *var_val;
+    long    version;
+    int            len, four;
+    u_char community[256];
+    int community_length = 256;
+    struct variable_list *vp = 0;
+    oid            objid[MAX_NAME_LEN], *op;
+    u_char  *origdata = data;
+    int      origlength = length;
+    int      ret = 0;
+    u_char  *save_data;
+
+    /* authenticates message and returns length if valid */
+    data = snmp_auth_parse(data, &length, community, &community_length, &version);
+    if (data == NULL)
+       return -1;
+
+   if( version != SNMP_VERSION_1 && version != SNMP_VERSION_2C && version != SNMP_VERSION_2 ) {
+           fprintf(stderr, "Wrong version: %ld\n", version);
+           return -1;
+    }
+
+    save_data = data;
+
+    data = asn_parse_header(data, &length, &msg_type);
+    if (data == NULL)
+       return -1;
+    pdu->command = msg_type;
+
+    if( session->authenticator ) {
+       ret = session->authenticator( origdata, origlength, save_data - community_length, 
+               community_length, session, pdu );
+       if( ret < 0 ) return ret;
+    }
+
+    if (pdu->command != TRP_REQ_MSG){
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (data == NULL)
+           return -1;
+    } else {
+       pdu->enterprise_length = MAX_NAME_LEN;
+       data = asn_parse_objid(data, &length, &type, objid, &pdu->enterprise_length);
+       if (data == NULL)
+           return -1;
+       pdu->enterprise = (oid *)calloc(1, pdu->enterprise_length * sizeof(oid));
+       bcopy((char *)objid, (char *)pdu->enterprise, pdu->enterprise_length * sizeof(oid));
+
+       four = 4;
+       data = asn_parse_string(data, &length, &type, (u_char *)&pdu->agent_addr.sin_addr.s_addr, &four);
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->time, sizeof(pdu->time));
+       if (data == NULL)
+           return -1;
+    }
+    data = asn_parse_header(data, &length, &type);
+    if (data == NULL)
+       return -1;
+    if (type != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR))
+       return -1;
+    while((int)length > 0){
+       if (pdu->variables == NULL){
+           pdu->variables = vp = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+       } else {
+           vp->next_variable = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+           vp = vp->next_variable;
+       }
+       vp->next_variable = NULL;
+       vp->val.string = NULL;
+       vp->name = NULL;
+       vp->name_length = MAX_NAME_LEN;
+       data = snmp_parse_var_op(data, objid, &vp->name_length, &vp->type, &vp->val_len, &var_val, (int *)&length);
+       if (data == NULL)
+           return -1;
+       op = (oid *)calloc(1, (unsigned)vp->name_length * sizeof(oid));
+       bcopy((char *)objid, (char *)op, vp->name_length * sizeof(oid));
+       vp->name = op;
+
+       len = PACKET_LENGTH;
+       switch((short)vp->type){
+           case ASN_INTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(long));
+               vp->val_len = sizeof(long);
+               asn_parse_int(var_val, &len, &vp->type, (long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER:
+           case GAUGE:
+           case TIMETICKS:
+           case UINTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(unsigned long));
+               vp->val_len = sizeof(unsigned long);
+               asn_parse_unsigned_int(var_val, &len, &vp->type, (unsigned long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER64:
+               vp->val.counter64 = (struct counter64 *)calloc(1,  sizeof(struct counter64) );
+               vp->val_len = sizeof(struct counter64);
+               asn_parse_unsigned_int64(var_val, &len, &vp->type,
+                                        (struct counter64 *)vp->val.counter64,
+                                        sizeof(*vp->val.counter64));
+               break;
+           case ASN_OCTET_STR:
+           case IPADDRESS:
+           case OPAQUE:
+           case NSAP:
+               vp->val.string = (u_char *)calloc(1, (unsigned)vp->val_len);
+               asn_parse_string(var_val, &len, &vp->type, vp->val.string, &vp->val_len);
+               break;
+           case ASN_OBJECT_ID:
+               vp->val_len = MAX_NAME_LEN;
+               asn_parse_objid(var_val, &len, &vp->type, objid, &vp->val_len);
+               vp->val_len *= sizeof(oid);
+               vp->val.objid = (oid *)calloc(1, (unsigned)vp->val_len);
+               bcopy((char *)objid, (char *)vp->val.objid, vp->val_len);
+               break;
+            case SNMP_NOSUCHOBJECT:
+            case SNMP_NOSUCHINSTANCE:
+            case SNMP_ENDOFMIBVIEW:
+           case ASN_NULL:
+               break;
+           default:
+               fprintf(stderr, "bad type returned (%x)\n", vp->type);
+               break;
+       }
+    }
+    return ret;
+}
+
+/*
+ * 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(session, pdu)
+    struct snmp_session *session;
+    struct snmp_pdu    *pdu;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp = NULL;
+    u_char  packet[PACKET_LENGTH];
+    int length = PACKET_LENGTH;
+    struct request_list *rp;
+    struct timeval tv;
+
+    for(slp = Sessions; slp; slp = slp->next){
+       if (slp->session == session){
+           isp = slp->internal;
+           break;
+       }
+    }
+
+    if (! pdu) {
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+
+    if (isp == NULL){
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG
+       || pdu->command == GET_RSP_MSG || pdu->command == SET_REQ_MSG 
+       || pdu->command == GETBULK_REQ_MSG ){
+       if (pdu->reqid == SNMP_DEFAULT_REQID)
+           pdu->reqid = ++Reqid;
+       if (pdu->errstat == SNMP_DEFAULT_ERRSTAT)
+           pdu->errstat = 0;
+       if (pdu->errindex == SNMP_DEFAULT_ERRINDEX)
+           pdu->errindex = 0;
+    } else {
+       /* fill in trap defaults */
+       pdu->reqid = 1; /* give a bogus non-error reqid for traps */
+       if (pdu->enterprise_length == SNMP_DEFAULT_ENTERPRISE_LENGTH){
+           pdu->enterprise = (oid *)calloc(1, sizeof(DEFAULT_ENTERPRISE));
+           bcopy((char *)DEFAULT_ENTERPRISE, (char *)pdu->enterprise, sizeof(DEFAULT_ENTERPRISE));
+           pdu->enterprise_length = sizeof(DEFAULT_ENTERPRISE)/sizeof(oid);
+       }
+       if (pdu->time == SNMP_DEFAULT_TIME)
+           pdu->time = DEFAULT_TIME;
+    }
+    if (pdu->address.sin_addr.s_addr == SNMP_DEFAULT_ADDRESS){
+       if (isp->addr.sin_addr.s_addr != SNMP_DEFAULT_ADDRESS){
+           bcopy((char *)&isp->addr, (char *)&pdu->address, sizeof(pdu->address));
+       } else {
+           fprintf(stderr, "No remote IP address specified\n");
+           snmp_errno = SNMPERR_BAD_ADDRESS;
+           return 0;
+       }
+    }
+       
+
+    if (snmp_build(session, pdu, packet, &length, 0) < 0){
+       fprintf(stderr, "Error building packet\n");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+#if 1 /***/
+    if (snmp_dump_packet){
+      snmp_print_packet(packet, length, pdu->address, 1);
+    }
+#endif /***/
+
+    gettimeofday(&tv, (struct timezone *)0);
+    if (sendto(isp->sd, (char *)packet, length, 0, (struct sockaddr *)&pdu->address, sizeof(pdu->address)) < 0){
+       perror("sendto");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG 
+     || pdu->command == SET_REQ_MSG || pdu->command == GETBULK_REQ_MSG ){
+       /* set up to expect a response */
+       rp = (struct request_list *)calloc(1, sizeof(struct request_list));
+#if 1 /***/
+        if(! rp){
+          fprintf(stderr, "Out of memory!\n");
+          snmp_errno = SNMPERR_GENERR;
+          return 0;
+        }
+#endif /***/
+       rp->next_request = isp->requests;
+       isp->requests = rp;
+       rp->pdu = pdu;
+       rp->request_id = pdu->reqid;
+
+       rp->retries = 1;
+       rp->timeout = session->timeout;
+       rp->time = tv;
+       tv.tv_usec += rp->timeout;
+       tv.tv_sec += tv.tv_usec / 1000000L;
+       tv.tv_usec %= 1000000L;
+       rp->expire = tv;
+#if DEBUG_SNMPTRACE
+       snmp_print_trace(slp, rp, TRACE_SEND);
+#endif
+    }
+    return pdu->reqid;
+}
+
+/*
+ * Frees the pdu and any malloc'd data associated with it.
+ */
+void
+snmp_free_pdu(struct snmp_pdu * pdu)
+{
+    struct variable_list *vp, *ovp;
+
+    if (! pdu)
+      return;
+
+    vp = pdu->variables;
+    while(vp){
+      if (vp->name) {
+       free((char *)vp->name);
+      }
+      if (vp->val.string) {
+       free((char *)vp->val.string);
+      }
+      ovp = vp;
+      vp = vp->next_variable;
+      free((char *)ovp);
+    }
+    if (pdu->enterprise) {
+      free((char *)pdu->enterprise);
+    }
+    free((char *)pdu);
+}
+
+
+/*
+ * 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(fdset)
+    fd_set  *fdset;
+{
+    struct session_list *slp;
+    struct snmp_session *sp;
+    struct snmp_internal_session *isp;
+    u_char packet[PACKET_LENGTH];
+    struct sockaddr_in from;
+    ssize_t length, fromlength;
+    struct snmp_pdu *pdu;
+    struct request_list *rp /**, *orp **/ ;
+
+    for(slp = Sessions; slp; slp = slp->next){
+       if (FD_ISSET(slp->internal->sd, fdset)){
+           sp = slp->session;
+           isp = slp->internal;
+           fromlength = sizeof(from);
+           length = recvfrom(isp->sd, (char *)packet, PACKET_LENGTH, 0, (struct sockaddr *)&from, &fromlength);
+           if (length == -1) {
+               perror("recvfrom");
+               return;
+           }
+#if 1 /***/
+           if (snmp_dump_packet){
+             snmp_print_packet(packet, length, from, 0);
+           }
+           pdu = (struct snmp_pdu *)calloc(1, sizeof(struct snmp_pdu));
+
+           if(! pdu){
+             fprintf(stderr, "Out of memory!\n");
+             snmp_errno = SNMPERR_GENERR;
+             return;
+           }
+#endif /***/
+
+           pdu->address = from;
+           pdu->reqid = 0;
+           pdu->variables = NULL;
+           pdu->enterprise = NULL;
+           pdu->enterprise_length = 0;
+           if (snmp_parse(sp, pdu, packet, length) < 0){
+               fprintf(stderr, "Mangled packet\n");
+               snmp_free_pdu(pdu);
+               return;
+           }
+
+           if (pdu->command == GET_RSP_MSG || pdu->command == REPORT_MSG){
+#if 1 /***/ /* bug fix: illegal re-use of rp killed some requests */
+             struct request_list *rp_next= 0;
+             for(rp = isp->requests; rp; rp = rp_next){
+               rp_next = rp->next_request;
+               if (rp->request_id == pdu->reqid){
+#if DEBUG_SNMPTRACE
+                 snmp_print_trace(slp, rp, TRACE_RECV);
+#endif
+                 if (sp->callback(RECEIVED_MESSAGE, sp, pdu->reqid, pdu, sp->callback_magic) == 1){
+                   /* successful, so delete request */
+                   free_one_request(isp, rp);
+                   break;  /* no more request with the same reqid */
+                 }
+               }
+             }
+#endif /***/
+           } else if (pdu->command == GET_REQ_MSG 
+                   || pdu->command == GETNEXT_REQ_MSG
+                   || pdu->command == GETBULK_REQ_MSG
+                   || pdu->command == TRP_REQ_MSG || pdu->command == SET_REQ_MSG){
+#if DEBUG_SNMPTRACE
+             snmp_print_trace(slp, NULL, TRACE_RECV);
+#endif
+             sp->callback(RECEIVED_MESSAGE, sp, pdu->reqid, pdu, sp->callback_magic);
+           }
+           snmp_free_pdu(pdu);
+       }
+    }
+}
+
+/*
+ * 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(numfds, fdset, timeout, block)
+    int            *numfds;
+    fd_set  *fdset;
+    struct timeval *timeout;
+    int            *block; /* should the select block until input arrives (i.e. no input) */
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp;
+    struct request_list *rp;
+    struct timeval now, earliest;
+    int active = 0, requests = 0;
+
+    timerclear(&earliest);
+    /*
+     * For each request outstanding, add it's socket to the fdset,
+     * and if it is the earliest timeout to expire, mark it as lowest.
+     */
+    for(slp = Sessions; slp; slp = slp->next){
+       active++;
+       isp = slp->internal;
+       if ((isp->sd + 1) > *numfds)
+           *numfds = (isp->sd + 1);
+       FD_SET(isp->sd, fdset);
+       if (isp->requests){
+           /* found another session with outstanding requests */
+           requests++;
+           for(rp = isp->requests; rp; rp = rp->next_request){
+               if (!timerisset(&earliest) || timercmp(&rp->expire, &earliest, <))
+                   earliest = rp->expire;
+           }
+       }
+    }
+    if (requests == 0) /* if none are active, skip arithmetic */
+       return active;
+
+    /*
+     * Now find out how much time until the earliest timeout.  This
+     * transforms earliest from an absolute time into a delta time, the
+     * time left until the select should timeout.
+     */
+    gettimeofday(&now, (struct timezone *)0);
+    earliest.tv_sec--; /* adjust time to make arithmetic easier */
+    earliest.tv_usec += 1000000L;
+    earliest.tv_sec -= now.tv_sec;
+    earliest.tv_usec -= now.tv_usec;
+    while (earliest.tv_usec >= 1000000L){
+       earliest.tv_usec -= 1000000L;
+       earliest.tv_sec += 1;
+    }
+    if (earliest.tv_sec < 0){
+       earliest.tv_sec = 0;
+       earliest.tv_usec = 0;
+    }
+
+    /* if it was blocking before or our delta time is less, reset timeout */
+    if (*block == 1 || timercmp(&earliest, timeout, <)){
+       *timeout = earliest;
+       *block = 0;
+    }
+    return active;
+}
+
+/* 
+ * 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()
+{
+    struct session_list *slp;
+    struct snmp_session *sp;
+    struct snmp_internal_session *isp;
+#if 1 /***/ /* replacing freeme by simpler and safer rp_next*/
+    struct request_list *rp, *rp_next = 0;
+#endif /***/
+       struct timeval now;
+
+    gettimeofday(&now, (struct timezone *) 0);
+    /*
+     * For each request outstanding, check to see if it has expired.
+     */
+    for (slp = Sessions; slp; slp = slp->next) {
+       sp = slp->session;
+       isp = slp->internal;
+#if 1 /***/                    /* simplification */
+       for (rp = isp->requests; rp; rp = rp_next) {
+           rp_next = rp->next_request;
+           if (timercmp(&rp->expire, &now, <)) {
+               /* this timer has expired */
+               if (rp->retries >= sp->retries) {
+#if DEBUG_SNMPTRACE
+                   snmp_print_trace(slp, rp, TRACE_TIMEOUT);
+#endif
+                   /* No more chances, delete this entry */
+                   sp->callback(TIMED_OUT, sp, rp->pdu->reqid, rp->pdu, sp->callback_magic);
+                   free_one_request(isp, rp);
+                   continue;
+r *)buf, (char *)cp, totallength);
+    totallength += cp - packet;
+    *out_length = totallength;
+
+    if( session->qoS & USEC_QOS_AUTH )
+           md5Digest( packet, totallength, cp - (session->contextLen + 16),
+               cp - (session->contextLen + 16) );
+
+    return 0;
+}
+
+/*
+ * Parses the packet received on the input session, and places the data into
+ * the input pdu.  length is the length of the input packet.  If any errors
+ * are encountered, -1 is returned.  Otherwise, a 0 is returned.
+ */
+static int
+snmp_parse(session, pdu, data, lengt\10\0BÐ+= m\0\0
+È      /* \10\0>X*/ B\10\03\10NMPT\10\ 1èè */c\0\0\0\0for testing purposes */e key!  replace...
+     */
+ * \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 1\ 1\0\0\0\0\0\0\0\19\7fÿ¯ùsnmplib/snmp_api.c\0c\0\0.h\0\0\0\18\7fÿ°\85\10\0<Ðlib/snmp_api.c~\0~\0\0ñ\0\0\0\18\7fÿ±\1e\10\0\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\0\0\0\18\7fÿ±«\10\0=\10\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\0\0\0\18\7fÿ²\1d\10\0=0\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\0\0\0\18\7fÿ²\8a\10\0=P\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\0\0\0\18\7fÿ³
+\10\0=p\7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\0\0\0\18\7fÿ³\82\0\0\0\ 1\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\0\0\0Á\7fÿ³ù\0\0\0\10\7fÿ´\10\10\0\0%\0\19\0\15\0\0\10\0D(\0\0\0\10\7fÿ´_\10\0\0\0\ 2\\0\0\0\0\10\0\0\0\0\10\7fÿ´©\10\0=\98\0\0\ 24\0\0\0\0\10\0\0\0\0\10\7fÿ´ø\10\0\0\0\ 2H\0\0\0\0\10\0\0\0\0\10\7fÿµB\10\0>\10\7fÿµ]\7fÿµm\7fÿµz\0\0\0\10\7fÿµ \10\0>(\7fÿµ·\7fÿµÉ\7fÿµÖ\0\0\0\10\7fÿµï\10\0>@\7fÿ¶\12\7fÿ¶ \7fÿ¶4\0\0\0\10\7fÿ¶P\0\0\0\ 1\7fÿ¶r\7fÿ¶~\7fÿ¶\88\0\0\00\7fÿ¶\9f\10\0\7fÿ¶·\0\0\0\0\7fÿ¶Ù\10\0\89è\7fÿ·\ 1\0\0\0\0\7fÿ·#\7fÿ·/\7fÿ·>\10\0>X\7fÿ·V\0\0\03\0\0\0\0/usr/people/wessels/.indent.pro\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\ 1\0\0\0\0\7fÿ¯è\7fÿ¯ù\7fÿ°\f\7fÿ°\e\7fÿ°.\7fÿ°?\7fÿ°M\7fÿ°[\7fÿ°p\7fÿ°\85\7fÿ°\95\7fÿ°£\7fÿ°²\7fÿ°Å\7fÿ°Û\7fÿ°ñ\7fÿ±
+\7fÿ±\1e\7fÿ±2\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\7fÿ±\99\7fÿ±«\7fÿ±º\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\7fÿ²\ f\7fÿ²\1d\7fÿ²2\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\7fÿ²\7f\7fÿ²\8a\7fÿ²\99\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\7fÿ²ö\7fÿ³
+\7fÿ³ \7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\7fÿ³s\7fÿ³\82\7fÿ³\91\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\7fÿ³ç\7fÿ³ù\7fÿ´\ 4\7fÿ´\10\7fÿ´\1e\7fÿ´)\7fÿ´3\7fÿ´C\7fÿ´O\7fÿ´_\7fÿ´k\7fÿ´t\7fÿ´\81\7fÿ´\8f\7fÿ´\9f\7fÿ´©\7fÿ´·\7fÿ´Å\7fÿ´Ò\7fÿ´Ý\7fÿ´í\7fÿ´ø\7fÿµ\ 3\7fÿµ\10\7fÿµ\1d\7fÿµ)\7fÿµ7\7fÿµB\7fÿµM\7fÿµ]\7fÿµm\7fÿµz\7fÿµ\89\7fÿµ \7fÿµ«\7fÿµ·\7fÿµÉ\7fÿµÖ\7fÿµâ\7fÿµï\7fÿ¶\ 3\7fÿ¶\12\7fÿ¶ \7fÿ¶4\7fÿ¶?\7fÿ¶P\7fÿ¶b\7fÿ¶r\7fÿ¶~\7fÿ¶\88\7fÿ¶\94\7fÿ¶\9f\7fÿ¶«\7fÿ¶·\7fÿ¶É\7fÿ¶Ù\7fÿ¶í\7fÿ·\ 1\7fÿ·\15\7fÿ·#\7fÿ·/\7fÿ·>\7fÿ·L\7fÿ·V\7fÿ·f\7fÿ·q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\0\0\0°\0\0\0\ 4\0\0\0\0\0\0\0\b\10\0>X\0\0\0\f\10\0\0\0\0\10\0\0\0\0\0\0\0\14\0\0\0\14\0\0\0\14\0\0\0\18\0\0\0\18\0\0\0\18\0\0\0\1c\0\0\0\1c\0\0\0\1c\0\0\0\1c\0\0\0 \0\0\0 \0\0\0 \0\0\0$\0\0\0\v\0\0\0\e\0\0\0\19\0\0\0\v\0\0\0\e\0\0\0@\0\0\0\0\0\0\0\0\0\0\0\0\10\0,\b\0\0\0\1a\10\02\88\0\0\0\1a\0\0\0\0\0\0\0\1a\10\0\85\b\0\0\0\0\10\0>X\0\0\0\0\0\0\0\0\0\0\0\0\10\0\82à\0\0\0\0\0\0\ 1C\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e0\0\0\0\v\0\0\0\e\0\0\0\18\0\0\0\v\0\0\0\1a\0\0\0\17\0\0\0\v\0\0\0 \0\0\0\0\10\0\8d¸ude/snmp_groupvars.h~\0\0\b\0\0\0\b\0\0\0 \0\0\0\0\10\0\8dàude/snmp_groupvars.h\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8eX\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e\80\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e¨\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8eÐ\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\0\0\0\ 1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\84©\0\0\0\0/***********************************************************
+       Copyright 1989 by Carnegie Mellon University
+
+                      All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the name of CMU not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+******************************************************************/
+/*
+ * snmp_api.c - API for access to snmp.
+ */
+#define DEBUG_SNMPTRACE                0 /* set to 1 to print all SNMP actions */
+#define DEBUG_SNMPFULLDUMP     0 /* set to 1 to dump all SNMP packets */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#ifdef linux
+#include <arpa/inet.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#endif
+
+
+#include "asn1.h"
+#include "snmp.h"
+#include "snmp_impl.h"
+#include "snmp_api.h"
+#include "snmp_client.h"
+
+#define PACKET_LENGTH  4500
+
+#ifndef BSD4_3
+#define BSD4_2
+#endif
+
+#if !defined(BSD4_3) && !defined(linux) && !defined(sun)
+
+typedef long   fd_mask;
+#define NFDBITS        (sizeof(fd_mask) * NBBY)        /* bits per mask */
+
+#define        FD_SET(n, p)    ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+#define        FD_CLR(n, p)    ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+#define        FD_ISSET(n, p)  ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+#define FD_ZERO(p)     bzero((char *)(p), sizeof(*(p)))
+#endif
+
+oid default_enterprise[] = {1, 3, 6, 1, 4, 1, 3, 1, 1}; /* enterprises.cmu.systems.cmuSNMP */
+
+#define DEFAULT_COMMUNITY   "public"
+#define DEFAULT_REMPORT            SNMP_PORT
+#define DEFAULT_ENTERPRISE  default_enterprise
+#define DEFAULT_TIME       0
+#define DEFAULT_MMS        1389 /* large, randomly picked for testing purposes */
+
+/*
+ * Internal information about the state of the snmp session.
+ */
+struct snmp_internal_session {
+    int            sd;         /* socket descriptor for this connection */
+    ipaddr  addr;      /* address of connected peer */
+    struct request_list *requests;/* Info about outstanding requests */
+};
+
+/*
+ * A list of all the outstanding requests for a particular session.
+ */
+struct request_list {
+    struct request_list *next_request;
+    u_long  request_id;        /* request id */
+    int            retries;    /* Number of retries */
+    u_long timeout;    /* length to wait for timeout */
+    struct timeval time; /* Time this request was made */
+    struct timeval expire;  /* time this request is due to expire */
+    struct snmp_pdu *pdu;   /* The pdu for this request (saved so it can be retransmitted */
+};
+
+/*
+ * The list of active/open sessions.
+ */
+struct session_list {
+    struct session_list *next;
+    struct snmp_session *session;
+    struct snmp_internal_session *internal;
+};
+
+struct session_list *Sessions = NULL;
+
+u_long Reqid = 0;
+int snmp_errno = 0;
+
+char *api_errors[4] = {
+    "Unknown session",
+    "Unknown host",
+    "Invalid local port",
+    "Unknown Error"
+};
+
+
+void sync_with_agent();
+int parse_app_community_string();
+void snmp_synch_setup();
+int snmp_synch_response();
+void md5Digest();
+
+
+static char *
+api_errstring(snmp_errnumber)
+    int        snmp_errnumber;
+{
+    if (snmp_errnumber <= SNMPERR_BAD_SESSION && snmp_errnumber >= SNMPERR_GENERR){
+       return api_errors[snmp_errnumber + 4];
+    } else {
+       return "Unknown Error";
+    }
+}
+
+#if 0
+/*
+ * Gets initial request ID for all transactions.
+ */
+static void
+init_snmp(){
+    struct timeval tv;
+
+    gettimeofday(&tv, (struct timezone *)0);
+    srandom(tv.tv_sec ^ tv.tv_usec);
+    Reqid = random();
+}
+#endif
+
+
+/*
+ * Dump snmp packet to stdout:
+ */
+static void
+snmp_print_packet(packet, length, addr, code)
+  char *packet; 
+  int length; 
+  ipaddr addr; 
+  int code;
+{
+  if(length < 0) {
+    return;
+  }
+  if (code <= 0) { /* received */
+    printf("\nReceived %4d bytes from ", length);
+  }
+  else { /* sending */
+    printf("\nSending  %4d bytes to   ", length);
+  }
+  printf("%s:", inet_ntoa(addr.sin_addr));
+#if DEBUG_SNMPFULLDUMP
+  for (count = 0; count < length; count++) {
+    if ((count & 15) == 0) {
+      printf("\n  ");
+    }
+    printf("%02X ", (int)(packet[count]&255));
+  }
+#endif
+  fflush(stdout);
+}
+
+#if DEBUG_SNMPTRACE
+/*
+ * Print request
+ */
+#define TRACE_SEND   (0)
+#define TRACE_RECV   (1)
+#define TRACE_TIMEOUT (2)
+static void
+snmp_print_trace(slp, rp, code)
+  struct session_list *slp;
+  struct request_list *rp;
+  int code;
+{
+  int reqid=0, retries=1;
+  if( rp ){
+    reqid = rp->request_id;
+    retries = rp->retries;
+  }  
+  printf("\n Session %2d  ReqId %4d  ", slp->internal->sd, reqid);
+  switch(code)
+    { 
+    case TRACE_SEND:    printf("send pdu (%d)", retries);break; 
+    case TRACE_RECV:    printf("recv pdu");break; 
+    case TRACE_TIMEOUT: printf("time out");break; 
+    }
+  fflush(stdout);
+}
+#endif /* DEBUG_SNMPTRACE */
+
+
+
+
+/*
+ * 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.
+ */
+struct snmp_session *
+snmp_open(session)
+    struct snmp_session *session;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp;
+    u_char *cp;
+    int sd;
+    u_long addr;
+    struct sockaddr_in me;
+    struct hostent *hp;
+    struct servent *servp;
+    extern int check_received_pkt();
+
+    /* Copy session structure and link into list */
+    slp = (struct session_list *)calloc(1, sizeof(struct session_list));
+    slp->internal = isp = (struct snmp_internal_session *)calloc(1, sizeof(struct snmp_internal_session));
+    bzero((char *)isp, sizeof(struct snmp_internal_session));
+    slp->internal->sd = -1; /* mark it not set */
+    slp->session = (struct snmp_session *)calloc(1, sizeof(struct snmp_session));
+    bcopy((char *)session, (char *)slp->session, sizeof(struct snmp_session));
+    session = slp->session;
+    /* now link it in. */
+    slp->next = Sessions;
+    Sessions = slp;
+
+    /*
+     * session now points to the new structure that still contains pointers to
+     * data allocated elsewhere.  Some of this data is copied to space malloc'd
+     * here, and the pointer replaced with the new one.
+     */
+
+    if (session->peername != NULL){
+       cp = (u_char *)calloc(1, (unsigned)strlen(session->peername) + 1);
+       strcpy((char *)cp, session->peername);
+       session->peername = (char *)cp;
+    }
+
+    if (session->retries == SNMP_DEFAULT_RETRIES)
+       session->retries = SNMP_API_DEFAULT_RETRIES;
+    if (session->timeout == SNMP_DEFAULT_TIMEOUT)
+       session->timeout = SNMP_API_DEFAULT_TIMEOUT;
+    if (session->MMS == 0 )
+       session->MMS = DEFAULT_MMS;
+    isp->requests = NULL;
+
+
+    /* Fill in defaults if necessary */
+    if (session->community_len != SNMP_DEFAULT_COMMUNITY_LEN){
+       if( *session->community == '+' ) {
+               session->community_len--;
+               cp = (u_char *) calloc(1, (unsigned) session->community_len);
+               bcopy((char *) session->community+1, (char *)cp,
+                     session->community_len);
+               session->version = SNMP_VERSION_2C;
+       } else {
+               cp = (u_char *) calloc(1, (unsigned) session->community_len);
+               bcopy((char *) session->community, (char *) cp, 
+                     session->community_len);
+       }
+
+    } else {
+       session->community_len = strlen(DEFAULT_COMMUNITY);
+       cp = (u_char *)calloc(1, (unsigned)session->community_len);
+       bcopy((char *)DEFAULT_COMMUNITY, (char *)cp, session->community_len);
+    }
+
+    /* Set up connections */
+    sd = socket(AF_INET, SOCK_DGRAM, 0);
+    if (sd < 0){
+       perror("socket");
+       snmp_errno = SNMPERR_GENERR;
+       if (!snmp_close(session)){
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+           exit(1);
+       }
+       return 0;
+    }
+    isp->sd = sd;
+
+    if (session->peername != SNMP_DEFAULT_PEERNAME){
+       if ((addr = inet_addr(session->peername)) != -1){
+           bcopy((char *)&addr, (char *)&isp->addr.sin_addr, sizeof(isp->addr.sin_addr));
+       } else {
+           hp = gethostbyname(session->peername);
+           if (hp == NULL){
+               fprintf(stderr, "unknown host: %s\n", session->peername);
+               snmp_errno = SNMPERR_BAD_ADDRESS;
+               if (!snmp_close(session)){
+                   fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+                   exit(2);
+               }
+               return 0;
+           } else {
+               bcopy((char *)hp->h_addr, (char *)&isp->addr.sin_addr, hp->h_length);
+           }
+       }
+       isp->addr.sin_family = AF_INET;
+       if (session->remote_port == SNMP_DEFAULT_REMPORT){
+           /*servp = getservbyname("snmp", "udp");*/
+           servp=NULL;
+           if (servp != NULL){
+               isp->addr.sin_port = servp->s_port;
+           } else {
+               isp->addr.sin_port = htons(SNMP_PORT);
+           }
+       } else {
+           isp->addr.sin_port = htons(session->remote_port);
+       }
+    } else {
+       isp->addr.sin_addr.s_addr = SNMP_DEFAULT_ADDRESS;
+    }
+
+    me.sin_family = AF_INET;
+    me.sin_addr.s_addr = INADDR_ANY;
+    me.sin_port = htons(session->local_port);
+    if (bind(sd, (struct sockaddr *)&me, sizeof(me)) != 0){
+       perror("bind");
+       snmp_errno = SNMPERR_BAD_LOCPORT;
+       if (! snmp_close(session)){
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n", 
+                   api_errstring(snmp_errno));
+           exit(3);
+       }
+       return 0;
+    }
+
+    if( *cp == '/' ) {
+       session->authenticator = check_received_pkt;
+       sync_with_agent(session);
+       parse_app_community_string( session );
+       session->qoS |= USEC_QOS_GENREPORT;
+    }
+
+    /* replace comm pointer with pointer to new data: */
+    session->community = cp;   
+
+    return session;
+}
+
+void
+sync_with_agent( session )
+struct snmp_session *session;
+{
+    struct snmp_pdu *pdu, *response = 0;
+    int status;
+
+    session->qoS = USEC_QOS_GENREPORT;
+    session->userLen = 6;
+    session->version = SNMP_VERSION_2;
+    strcpy( session->userName, "public" );
+
+    snmp_synch_setup(session);
+    pdu = snmp_pdu_create(GET_REQ_MSG);
+    status = snmp_synch_response(session, pdu, &response);
+
+    if (status == STAT_SUCCESS){
+       memcpy( session->agentID, response->params.agentID, 12 );
+
+       /* save the clocks -- even though they are not authentic */
+       session->agentBoots = response->params.agentBoots;
+       session->agentTime = response->params.agentTime;
+       session->agentClock = response->params.agentTime - time(NULL);
+
+    } else {
+           if (status == STAT_TIMEOUT){
+               printf("No Response from %s\n", session->peername);
+           } else {    /* status == STAT_ERROR */
+               printf("An error occurred, Quitting\n");
+           }
+           exit( -1 );
+    }
+
+    /** freed to early: 
+      snmp_free_pdu(pdu);
+      if (response) snmp_free_pdu(response);
+     **/
+}
+#if 1 /***/
+/*
+ * Unlink one element from input request list,
+ * then free it and it's pdu.
+ */
+static void
+free_one_request(isp, orp)
+    struct snmp_internal_session *isp;
+    struct request_list *orp;
+{
+    struct request_list *rp;
+    if(! orp) return;
+    if(isp->requests == orp){ 
+      isp->requests = orp->next_request; /* unlink head */
+    }
+    else{
+      for(rp = isp->requests; rp; rp = rp->next_request){
+        if(rp->next_request == orp){ 
+         rp->next_request = orp->next_request; /* unlink element */
+         break;
+        }
+      }
+    }
+    if (orp->pdu != NULL){
+      snmp_free_pdu(orp->pdu);
+    }
+    free((char *)orp);
+}
+#endif /***/
+/*
+ * Free each element in the input request list.
+ */
+static void
+free_request_list(rp)
+    struct request_list *rp;
+{
+    struct request_list *orp;
+
+    while(rp){
+       orp = rp;
+       rp = rp->next_request;
+       if (orp->pdu != NULL)
+           snmp_free_pdu(orp->pdu);
+       free((char *)orp);
+    }
+}
+
+/*
+ * 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.
+ */
+int 
+snmp_close(session)
+    struct snmp_session *session;
+{
+    struct session_list *slp = NULL, *oslp = NULL;
+
+    if (Sessions->session == session){ /* If first entry */
+       slp = Sessions;
+       Sessions = slp->next;
+    } else {
+       for(slp = Sessions; slp; slp = slp->next){
+           if (slp->session == session){
+               if (oslp)   /* if we found entry that points here */
+                   oslp->next = slp->next;     /* link around this entry */
+               break;
+           }
+           oslp = slp;
+       }
+    }
+    /* If we found the session, free all data associated with it */
+    if (slp){
+       if (slp->session->community != NULL)
+           free((char *)slp->session->community);
+       if(slp->session->peername != NULL)
+           free((char *)slp->session->peername);
+       free((char *)slp->session);
+       if (slp->internal->sd != -1)
+           close(slp->internal->sd);
+       free_request_list(slp->internal->requests);
+       free((char *)slp->internal);
+       free((char *)slp);
+    } else {
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    return 1;
+}
+
+/*
+ * Takes a session and a pdu and serializes the ASN PDU into the area
+ * pointed to by packet.  out_length is the size of the data area available.
+ * Returns the length of the completed packet in out_length.  If any errors
+ * occur, -1 is returned.  If all goes well, 0 is returned.
+ */
+int
+snmp_build(session, pdu, packet, out_length, is_agent)
+    struct snmp_session        *session;
+    struct snmp_pdu    *pdu;
+    u_char     *packet;
+    int                        *out_length;
+    int                         is_agent;
+{
+    u_char  buf[PACKET_LENGTH];
+    u_char  *cp;
+    struct variable_list *vp;
+    int            length;
+    int            totallength;
+
+    length = *out_length;
+    cp = packet;
+    for(vp = pdu->variables; vp; vp = vp->next_variable){
+       cp = snmp_build_var_op(cp, vp->name, &vp->name_length, vp->type, vp->val_len, (u_char *)vp->val.string, &length);
+       if (cp == NULL)
+           return -1;
+    }
+    totallength = cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR), totallength);
+    if (cp == NULL)
+       return -1;
+    bcopy((char *)packet, (char *)cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+    if (pdu->command != TRP_REQ_MSG){
+       /* request id */
+       cp = asn_build_int(packet, &length,
+           (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+           (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (cp == NULL)
+           return -1;
+       /* error status */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (cp == NULL)
+           return -1;
+       /* error index */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (cp == NULL)
+           return -1;
+    } else {   /* this is a trap message */
+       /* enterprise */
+       cp = asn_build_objid(packet, &length,
+           (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID),
+           (oid *)pdu->enterprise, pdu->enterprise_length);
+       if (cp == NULL)
+           return -1;
+       /* agent-addr */
+       cp = asn_build_string(cp, &length, (u_char)IPADDRESS,
+               (u_char *)&pdu->agent_addr.sin_addr.s_addr, sizeof(pdu->agent_addr.sin_addr.s_addr));
+       if (cp == NULL)
+           return -1;
+       /* generic trap */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (cp == NULL)
+           return -1;
+       /* specific trap */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (cp == NULL)
+           return -1;
+       /* timestamp  */
+       cp = asn_build_int(cp, &length, (u_char)TIMETICKS,
+               (long *)&pdu->time, sizeof(pdu->time));
+       if (cp == NULL)
+           return -1;
+    }
+    if (length < totallength)
+       return -1;
+    bcopy((char *)buf, (char *)cp, totallength);
+    totallength += cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char)pdu->command, totallength);
+    if (cp == NULL)
+       return -1;
+    if (length < totallength)
+       return -1;
+    bcopy((char *)packet, (char *)cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+
+    cp = snmp_auth_build( packet, &length, session, is_agent, totallength );
+    if (cp == NULL)
+       return -1;
+    if ((*out_length - (cp - packet)) < totallength)
+       return -1;
+    bcopy((char *)buf, (char *)cp, totallength);
+    totallength += cp - packet;
+    *out_length = totallength;
+
+    if( session->qoS & USEC_QOS_AUTH )
+           md5Digest( packet, totallength, cp - (session->contextLen + 16),
+               cp - (session->contextLen + 16) );
+
+    return 0;
+}
+
+/*
+ * Parses the packet received on the input session, and places the data into
+ * the input pdu.  length is the length of the input packet.  If any errors
+ * are encountered, -1 is returned.  Otherwise, a 0 is returned.
+ */
+static int
+snmp_parse(session, pdu, data, length)
+    struct snmp_session *session;
+    struct snmp_pdu *pdu;
+    u_char  *data;
+    int            length;
+{
+    u_char  msg_type;
+    u_char  type;
+    u_char  *var_val;
+    long    version;
+    int            len, four;
+    u_char community[256];
+    int community_length = 256;
+    struct variable_list *vp = 0;
+    oid            objid[MAX_NAME_LEN], *op;
+    u_char  *origdata = data;
+    int      origlength = length;
+    int      ret = 0;
+    u_char  *save_data;
+
+    /* authenticates message and returns length if valid */
+    data = snmp_auth_parse(data, &length, community, &community_length, &version);
+    if (data == NULL)
+       return -1;
+
+   if( version != SNMP_VERSION_1 && version != SNMP_VERSION_2C && version != SNMP_VERSION_2 ) {
+           fprintf(stderr, "Wrong version: %ld\n", version);
+           return -1;
+    }
+
+    save_data = data;
+
+    data = asn_parse_header(data, &length, &msg_type);
+    if (data == NULL)
+       return -1;
+    pdu->command = msg_type;
+
+    if( session->authenticator ) {
+       ret = session->authenticator( origdata, origlength, save_data - community_length, 
+               community_length, session, pdu );
+       if( ret < 0 ) return ret;
+    }
+
+    if (pdu->command != TRP_REQ_MSG){
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (data == NULL)
+           return -1;
+    } else {
+       pdu->enterprise_length = MAX_NAME_LEN;
+       data = asn_parse_objid(data, &length, &type, objid, &pdu->enterprise_length);
+       if (data == NULL)
+           return -1;
+       pdu->enterprise = (oid *)calloc(1, pdu->enterprise_length * sizeof(oid));
+       bcopy((char *)objid, (char *)pdu->enterprise, pdu->enterprise_length * sizeof(oid));
+
+       four = 4;
+       data = asn_parse_string(data, &length, &type, (u_char *)&pdu->agent_addr.sin_addr.s_addr, &four);
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->time, sizeof(pdu->time));
+       if (data == NULL)
+           return -1;
+    }
+    data = asn_parse_header(data, &length, &type);
+    if (data == NULL)
+       return -1;
+    if (type != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR))
+       return -1;
+    while((int)length > 0){
+       if (pdu->variables == NULL){
+           pdu->variables = vp = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+       } else {
+           vp->next_variable = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+           vp = vp->next_variable;
+       }
+       vp->next_variable = NULL;
+       vp->val.string = NULL;
+       vp->name = NULL;
+       vp->name_length = MAX_NAME_LEN;
+       data = snmp_parse_var_op(data, objid, &vp->name_length, &vp->type, &vp->val_len, &var_val, (int *)&length);
+       if (data == NULL)
+           return -1;
+       op = (oid *)calloc(1, (unsigned)vp->name_length * sizeof(oid));
+       bcopy((char *)objid, (char *)op, vp->name_length * sizeof(oid));
+       vp->name = op;
+
+       len = PACKET_LENGTH;
+       switch((short)vp->type){
+           case ASN_INTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(long));
+               vp->val_len = sizeof(long);
+               asn_parse_int(var_val, &len, &vp->type, (long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER:
+           case GAUGE:
+           case TIMETICKS:
+           case UINTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(unsigned long));
+               vp->val_len = sizeof(unsigned long);
+               asn_parse_unsigned_int(var_val, &len, &vp->type, (unsigned long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER64:
+               vp->val.counter64 = (struct counter64 *)calloc(1,  sizeof(struct counter64) );
+               vp->val_len = sizeof(struct counter64);
+               asn_parse_unsigned_int64(var_val, &len, &vp->type,
+                                        (struct counter64 *)vp->val.counter64,
+                                        sizeof(*vp->val.counter64));
+               break;
+           case ASN_OCTET_STR:
+           case IPADDRESS:
+           case OPAQUE:
+           case NSAP:
+               vp->val.string = (u_char *)calloc(1, (unsigned)vp->val_len);
+               asn_parse_string(var_val, &len, &vp->type, vp->val.string, &vp->val_len);
+               break;
+           case ASN_OBJECT_ID:
+               vp->val_len = MAX_NAME_LEN;
+               asn_parse_objid(var_val, &len, &vp->type, objid, &vp->val_len);
+               vp->val_len *= sizeof(oid);
+               vp->val.objid = (oid *)calloc(1, (unsigned)vp->val_len);
+               bcopy((char *)objid, (char *)vp->val.objid, vp->val_len);
+               break;
+            case SNMP_NOSUCHOBJECT:
+            case SNMP_NOSUCHINSTANCE:
+            case SNMP_ENDOFMIBVIEW:
+           case ASN_NULL:
+               break;
+           default:
+               fprintf(stderr, "bad type returned (%x)\n", vp->type);
+               break;
+       }
+    }
+    return ret;
+}
+
+/*
+ * 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(session, pdu)
+    struct snmp_session *session;
+    struct snmp_pdu    *pdu;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp = NULL;
+    u_char  packet[PACKET_LENGTH];
+    int length = PACKET_LENGTH;
+    struct request_list *rp;
+    struct timeval tv;
+
+    for(slp = Sessions; slp; slp = slp->next){
+       if (slp->session == session){
+           isp = slp->internal;
+           break;
+       }
+    }
+
+    if (! pdu) {
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+
+    if (isp == NULL){
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG
+       || pdu->command == GET_RSP_MSG || pdu->command == SET_REQ_MSG 
+       || pdu->command == GETBULK_REQ_MSG ){
+       if (pdu->reqid == SNMP_DEFAULT_REQID)
+           pdu->reqid = ++Reqid;
+       if (pdu->errstat == SNMP_DEFAULT_ERRSTAT)
+           pdu->errstat = 0;
+       if (pdu->errindex == SNMP_DEFAULT_ERRINDEX)
+           pdu->errindex = 0;
+    } else {
+       /* fill in trap defaults */
+       pdu->reqid = 1; /* give a bogus non-error reqid for traps */
+       if (pdu->enterprise_length == SNMP_DEFAULT_ENTERPRISE_LENGTH){
+           pdu->enterprise = (oid *)calloc(1, sizeof(DEFAULT_ENTERPRISE));
+           bcopy((char *)DEFAULT_ENTERPRISE, (char *)pdu->enterprise, sizeof(DEFAULT_ENTERPRISE));
+           pdu->enterprise_length = sizeof(DEFAULT_ENTERPRISE)/sizeof(oid);
+       }
+       if (pdu->time == SNMP_DEFAULT_TIME)
+           pdu->time = DEFAULT_TIME;
+    }
+    if (pdu->address.sin_addr.s_addr == SNMP_DEFAULT_ADDRESS){
+       if (isp->addr.sin_addr.s_addr != SNMP_DEFAULT_ADDRESS){
+           bcopy((char *)&isp->addr, (char *)&pdu->address, sizeof(pdu->address));
+       } else {
+           fprintf(stderr, "No remote IP address specified\n");
+           snmp_errno = SNMPERR_BAD_ADDRESS;
+           return 0;
+       }
+    }
+       
+
+    if (snmp_build(session, pdu, packet, &length, 0) < 0){
+       fprintf(stderr, "Error building packet\n");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+#if 1 /***/
+    if (snmp_dump_packet){
+      snmp_print_packet(packet, length, pdu->address, 1);
+    }
+#endif /***/
+
+    gettimeofday(&tv, (struct timezone *)0);
+    if (sendto(isp->sd, (char *)packet, length, 0, (struct sockaddr *)&pdu->address, sizeof(pdu->address)) < 0){
+       perror("sendto");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG 
+     || pdu->command == SET_REQ_MSG || pdu->command == GETBULK_REQ_MSG ){
+       /* set up to expect a response */
+       rp = (struct request_list *)calloc(1, sizeof(struct request_list));
+#if 1 /***/
+        if(! rp){
+          fprintf(stderr, "Out of memory!\n");
+          snmp_errno = SNMPERR_GENERR;
+          return 0;
+        }
+#endif /***/
+       rp->next_request = isp->requests;
+       isp->requests = rp;
+       rp->pdu = pdu;
+       rp->request_id = pdu->reqid;
+
+       rp->retries = 1;
+       rp->timeout = session->timeout;
+       rp->time = tv;
+       tv.tv_usec += rp->timeout;
+       tv.tv_sec += tv.tv_usec / 1000000L;
+       tv.tv_usec %= 1000000L;
+       rp->expire = tv;
+#if DEBUG_SNMPTRACE
+       snmp_print_trace(slp, rp, TRACE_SEND);
+#endif
+    }
+    return pdu->reqid;
+}
+
+/*
+ * Frees the pdu and any malloc'd data associated with it.
+ */
+void
+snmp_free_pdu(struct snmp_pdu * pdu)
+{
+    struct variable_list *vp, *ovp;
+
+    if (! pdu)
+      return;
+
+    vp = pdu->variables;
+    while(vp){
+      if (vp->name) {
+       free((char *)vp->name);
+      }
+      if (vp->val.string) {
+       free((char *)vp->val.string);
+      }
+      ovp = vp;
+      vp = vp->next_variable;
+      free((char *)ovp);
+    }
+    if (pdu->enterprise) {
+      free((char *)pdu->enterprise);
+    }
+    free((char *)pdu);
+}
+
+
+/*
+ * 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(fdset)
+    fd_set  *fdset;
+{
+    struct session_list *slp;
+    struct snmp_session *sp;
+    struct snmp_internal_session *isp;
+    u_char packet[PACKET_LENGTH];
+    struct sockaddr_in from;
+    ssize_t length, fromlength;
+    struct snmp_pdu *pdu;
+    struct request_list *rp /**, *orp **/ ;
+
+    for(slp = Sessions; slp; slp = slp->next){
+       if (FD_ISSET(slp->internal->sd, fdset)){
+           sp = slp->session;
+           isp = slp->internal;
+           fromlength = sizeof(from);
+           length = recvfrom(isp->sd, (char *)packet, PACKET_LENGTH, 0, (struct sockaddr *)&from, &fromlength);
+           if (length == -1) {
+               perror("recvfrom");
+               return;
+           }
+#if 1 /***/
+           if (snmp_dump_packet){
+             snmp_print_packet(packet, length, from, 0);
+           }
+           pdu = (struct snmp_pdu *)calloc(1, sizeof(struct snmp_pdu));
+
+           if(! pdu){
+             fprintf(stderr, "Out of memory!\n");
+             snmp_errno = SNMPERR_GENERR;
+             return;
+           }
+#endif /***/
+
+           pdu->address = from;
+           pdu->reqid = 0;
+           pdu->variables = NULL;
+           pdu->enterprise = NULL;
+           pdu->enterprise_length = 0;
+           if (snmp_parse(sp, pdu, packet, length) < 0){
+               fprintf(stderr, "Mangled packet\n");
+               snmp_free_pdu(pdu);
+               return;
+           }
+
+           if (pdu->command == GET_RSP_MSG || pdu->command == REPORT_MSG){
+#if 1 /***/ /* bug fix: illegal re-use of rp killed some requests */
+             struct request_list *rp_next= 0;
+             for(rp = isp->requests; rp; rp = rp_next){
+               rp_next = rp->next_request;
+               if (rp->request_id == pdu->reqid){
+#if DEBUG_SNMPTRACE
+                 snmp_print_trace(slp, rp, TRACE_RECV);
+#endif
+                 if (sp->callback(RECEIVED_MESSAGE, sp, pdu->reqid, pdu, sp->callback_magic) == 1){
+                   /* successful, so delete request */
+                   free_one_request(isp, rp);
+                   break;  /* no more request with the same reqid */
+                 }
+               }
+             }
+#endif /***/
+           } else if (pdu->command == GET_REQ_MSG 
+                   || pdu->command == GETNEXT_REQ_MSG
+                   || pdu->command == GETBULK_REQ_MSG
+                   || pdu->command == TRP_REQ_MSG || pdu->command == SET_REQ_MSG){
+#if DEBUG_SNMPTRACE
+             snmp_print_trace(slp, NULL, TRACE_RECV);
+#endif
+             sp->callback(RECEIVED_MESSAGE, sp, pdu->reqid, pdu, sp->callback_magic);
+           }
+           snmp_free_pdu(pdu);
+       }
+    }
+}
+
+/*
+ * 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(numfds, fdset, timeout, block)
+    int            *numfds;
+    fd_set  *fdset;
+    struct timeval *timeout;
+    int            *block; /* should the select block until input arrives (i.e. no input) */
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp;
+    struct request_list *rp;
+    struct timeval now, earliest;
+    int active = 0, requests = 0;
+
+    timerclear(&earliest);
+    /*
+     * For each request outstanding, add it's socket to the fdset,
+     * and if it is the earliest timeout to expire, mark it as lowest.
+     */
+    for(slp = Sessions; slp; slp = slp->next){
+       active++;
+       isp = slp->internal;
+       if ((isp->sd + 1) > *numfds)
+           *numfds = (isp->sd + 1);
+       FD_SET(isp->sd, fdset);
+       if (isp->requests){
+           /* found another session with outstanding requests */
+           requests++;
+           for(rp = isp->requests; rp; rp = rp->next_request){
+               if (!timerisset(&earliest) || timercmp(&rp->expire, &earliest, <))
+                   earliest = rp->expire;
+           }
+       }
+    }
+    if (requests == 0) /* if none are active, skip arithmetic */
+       return active;
+
+    /*
+     * Now find out how much time until the earliest timeout.  This
+     * transforms earliest from an absolute time into a delta time, the
+     * time left until the select should timeout.
+     */
+    gettimeofday(&now, (struct timezone *)0);
+    earliest.tv_sec--; /* adjust time to make arithmetic easier */
+    earliest.tv_usec += 1000000L;
+    earliest.tv_sec -= now.tv_sec;
+    earliest.tv_usec -= now.tv_usec;
+    while (earliest.tv_usec >= 1000000L){
+       earliest.tv_usec -= 1000000L;
+       earliest.tv_sec += 1;
+    }
+    if (earliest.tv_sec < 0){
+       earliest.tv_sec = 0;
+       earliest.tv_usec = 0;
+    }
+
+    /* if it was blocking before or our delta time is less, reset timeout */
+    if (*block == 1 || timercmp(&earliest, timeout, <)){
+       *timeout = earliest;
+       *block = 0;
+    }
+    return active;
+}
+
+/* 
+ * 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()
+{
+    struct session_list *slp;
+    struct snmp_session *sp;
+    struct snmp_internal_session *isp;
+#if 1 /***/ /* replacing freeme by simpler and safer rp_next*/
+    struct request_list *rp, *rp_next = 0;
+#endif /***/
+    struct timeval now;
+
+    gettimeofday(&now, (struct timezone *)0);
+    /*
+     * For each request outstanding, check to see if it has expired.
+     */
+    for(slp = Sessions; slp; slp = slp->next){
+       sp = slp->session;
+       isp = slp->internal;
+#if 1 /***/ /* simplification */
+       for(rp = isp->requests; rp; rp = rp_next){
+           rp_next = rp->next_request;
+           if (timercmp(&rp->expire, &now, <)){
+               /* this timer has expired */
+               if (rp->retries >= sp->retries){
+#if DEBUG_SNMPTRACE
+                 snmp_print_trace(slp, rp, TRACE_TIMEOUT);
+#endif
+                 /* No more chances, delete this entry */
+                 sp->callback(TIMED_OUT, sp, rp->pdu->reqid, rp->pdu, sp->callback_magic);
+                 free_one_request(isp, rp);
+                 continue;
+#endif /***/
+               } else {
+                   u_char packet[PACKET_LENGTH];
+                   int length = PACKET_LENGTH;
+                   struct timeval tv;
+
+                   /* retransmit this pdu */
+                   rp->retries++;
+                   rp->timeout <<= 1;
+                   if (snmp_build(sp, rp->pdu, packet, &length, 0) < 0) {
+                       fprintf(stderr, "Error building packet\n");
+                   }
+#if 1/***/ mplification */by simpler and safer rp_next*/n s */ replace...
+     */
+ * \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 1\ 1\0\0\0\0\0\0\0\19\7fÿ¯ùsnmplib/snmp_api.c\0c\0\0.h\0\0\0\18\7fÿ°\85\10\0<Ðlib/snmp_api.c~\0~\0\0ñ\0\0\0\18\7fÿ±\1e\10\0\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\0\0\0\18\7fÿ±«\10\0=\10\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\0\0\0\18\7fÿ²\1d\10\0=0\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\0\0\0\18\7fÿ²\8a\10\0=P\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\0\0\0\18\7fÿ³
+\10\0=p\7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\0\0\0\18\7fÿ³\82\0\0\0\ 1\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\0\0\0Á\7fÿ³ù\0\0\0\10\7fÿ´\10\10\0\0%\0\19\0\15\0\0\10\0D(\0\0\0\10\7fÿ´_\10\0\0\0\ 2\\0\0\0\0\10\0\0\0\0\10\7fÿ´©\10\0=\98\0\0\ 24\0\0\0\0\10\0\0\0\0\10\7fÿ´ø\10\0\0\0\ 2H\0\0\0\0\10\0\0\0\0\10\7fÿµB\10\0>\10\7fÿµ]\7fÿµm\7fÿµz\0\0\0\10\7fÿµ \10\0>(\7fÿµ·\7fÿµÉ\7fÿµÖ\0\0\0\10\7fÿµï\10\0>@\7fÿ¶\12\7fÿ¶ \7fÿ¶4\0\0\0\10\7fÿ¶P\0\0\0\ 1\7fÿ¶r\7fÿ¶~\7fÿ¶\88\0\0\00\7fÿ¶\9f\0\0\0\0\7fÿ¶·\0\0\0\0\7fÿ¶Ù\10\0\82à\7fÿ·\ 1\0\0\0\0\7fÿ·#\7fÿ·/\7fÿ·>\10\0>X\7fÿ·V\0\0\03\0\0\0\0/usr/people/wessels/.indent.pro\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\ 1\0\0\0\0\7fÿ¯è\7fÿ¯ù\7fÿ°\f\7fÿ°\e\7fÿ°.\7fÿ°?\7fÿ°M\7fÿ°[\7fÿ°p\7fÿ°\85\7fÿ°\95\7fÿ°£\7fÿ°²\7fÿ°Å\7fÿ°Û\7fÿ°ñ\7fÿ±
+\7fÿ±\1e\7fÿ±2\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\7fÿ±\99\7fÿ±«\7fÿ±º\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\7fÿ²\ f\7fÿ²\1d\7fÿ²2\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\7fÿ²\7f\7fÿ²\8a\7fÿ²\99\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\7fÿ²ö\7fÿ³
+\7fÿ³ \7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\7fÿ³s\7fÿ³\82\7fÿ³\91\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\7fÿ³ç\7fÿ³ù\7fÿ´\ 4\7fÿ´\10\7fÿ´\1e\7fÿ´)\7fÿ´3\7fÿ´C\7fÿ´O\7fÿ´_\7fÿ´k\7fÿ´t\7fÿ´\81\7fÿ´\8f\7fÿ´\9f\7fÿ´©\7fÿ´·\7fÿ´Å\7fÿ´Ò\7fÿ´Ý\7fÿ´í\7fÿ´ø\7fÿµ\ 3\7fÿµ\10\7fÿµ\1d\7fÿµ)\7fÿµ7\7fÿµB\7fÿµM\7fÿµ]\7fÿµm\7fÿµz\7fÿµ\89\7fÿµ \7fÿµ«\7fÿµ·\7fÿµÉ\7fÿµÖ\7fÿµâ\7fÿµï\7fÿ¶\ 3\7fÿ¶\12\7fÿ¶ \7fÿ¶4\7fÿ¶?\7fÿ¶P\7fÿ¶b\7fÿ¶r\7fÿ¶~\7fÿ¶\88\7fÿ¶\94\7fÿ¶\9f\7fÿ¶«\7fÿ¶·\7fÿ¶É\7fÿ¶Ù\7fÿ¶í\7fÿ·\ 1\7fÿ·\15\7fÿ·#\7fÿ·/\7fÿ·>\7fÿ·L\7fÿ·V\7fÿ·f\7fÿ·q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0@    \0\0\0\0;
+           }
+
+           if (pdu->command == GET_RSP_MSG || pdu->command == REPORT_MSG){
+#if 1 /***/ /* bug fix: illegal re-use of rp killed some requests */
+             struct request_list *rp_next= 0;
+             for(rp = isp->requests; rp; rp = rp_next){
+               rp_next = rp->next_request;
+               if (rp->request_id == pdu->reqid){
+#if DEBUG_SNMPTRACE
+                 snmp_print_trace(slp, rp, TRACE_RECV);
+#endif
+                 if (sp->callback(RECEIVED_MESSAGE, sp, pdu->reqid, pdu, sp->callback_magic) == 1){
+                   /* successful, so delete request */
+                   free_one_request(isp, rp);
+                   break;  /* no more request with the same reqid */
+                 }
+               }
+             }
+#endif /***/
+           } else if (pdu->command == GET_REQ_MSG 
+                   || pdu->command == GETNEXT_REQ_MSG
+                   || pdu->command == GETBULK_REQ_MSG
+                   || pdu->command == TRP_REQ_MSG || pdu->command == SET_REQ_MSG){
+#if DEBUG_SNMPTRACE
+             snmp_print_trace(slp, NULL, TRACE_RECV);
+#endif
+             sp->callback(RECEIVED_MESSAGE, sp, pdu->reqid, pdu, sp->callback_magic);
+           }
+           snmp_free_pdu(pdu);
+       }
+    }
+}
+
+/*
+ * 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(numfds, fdset, timeout, block)
+    int            *numfds;
+    fd_set  *fdset;
+    struct timeval *timeout;
+    int            *block; /* should the select block until input arrives (i.e. no input) */
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp;
+    struct request_list *rp;
+    struct timeval now, earliest;
+    int active = 0, requests = 0;
+
+    timerclear(&earliest);
+    /*
+     * For each request outstanding, add it's socket to the fdset,
+     * and if it is the earliest timeout to expire, mark it as lowest.
+     */
+    for(slp = Sessions; slp; slp = slp->next){
+       active++;
+       isp = slp->internal;
+       if ((isp->sd + 1) > *numfds)
+           *numfds = (isp->sd + 1);
+       FD_SET(isp->sd, fdset);
+       if (isp->requests){
+           /* found another session with outstanding requests */
+           requests++;
+           for(rp = isp->requests; rp; rp = rp->next_request){
+               if (!timerisset(&earliest) || timercmp(&rp->expire, &earliest, <))
+                   earliest = rp->expire;
+           }
+       }
+    }
+    if (requests == 0) /* if none are active, skip arithmetic */
+       return active;
+
+    /*
+     * Now find out how much time until the earliest timeout.  This
+     * transforms earliest from an absolute time into a delta time, the
+     * time left until the select should timeout.
+     */
+    gettimeofday(&now, (struct timezone *)0);
+    earliest.tv_sec--; /* adjust time to make arithmetic easier */
+    earliest.tv_usec += 1000000L;
+    earliest.tv_sec -= now.tv_sec;
+    earliest.tv_usec -= now.tv_usec;
+    while (earliest.tv_usec >= 1000000L){
+       earliest.tv_usec -= 1000000L;
+       earliest.tv_sec += 1;
+    }
+    if (earliest.tv_sec < 0){
+       earliest.tv_sec = 0;
+       earliest.tv_usec = 0;
+    }
+
+    /* if it was blocking before or our delta time is less, reset timeout */
+    if (*block == 1 || timercmp(&earliest, timeout, <)){
+       *timeout = earliest;
+       *block = 0;
+    }
+    return active;
+}
+
+/* 
+ * 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()
+{
+    struct session_list *slp;
+    struct snmp_session *sp;
+    struct snmp_internal_session *isp;
+#if 1 /***/ /* replacing freeme by simpler and safer rp_next*/
+    struct request_list *rp, *rp_next = 0;
+#endif /***/
+    struct timeval now;
+
+    gettimeofday(&now, (struct timezone *)0);
+    /*
+     * For each request outstanding, check to see if it has expired.
+     */
+    for(slp = Sessions; slp; slp = slp->next){
+       sp = slp->session;
+       isp = slp->internal;
+#if 1 /***/ /* simplification */
+       for(rp = isp->requests; rp; rp = rp_next){
+           rp_next = rp->next_request;
+           if (timercmp(&rp->expire, &now, <)){
+               /* this timer has expired */
+               if (rp->retries >= sp->retries){
+#if DEBUG_SNMPTRACE
+                 snmp_print_trace(slp, rp, TRACE_TIMEOUT);
+#endif
+                 /* No more chances, delete this entry */
+                 sp->callback(TIMED_OUT, sp, rp->pdu->reqid, rp->pdu, sp->callback_magic);
+                 free_one_request(isp, rp);
+                 continue;
+#endif /***/
+               } else {
+                   u_char packet[PACKET_LENGTH];
+                   int length = PACKET_LENGTH;
+                   struct timeval tv;
+
+                   /* retransmit this pdu */
+                   rp->retries++;
+                   rp->timeout <<= 1;
+                   if (snmp_build(sp, rp->pdu, packet, &length, 0) < 0) {
+                       fprintf(stderr, "Error building packet\n");
+                   }
+ the input session, and places the data into
+ * the input pdu.  length is the length of the input packet.  If any errors
+ * are encountered, -1 is returned.  Otherwise, a 0 is returned.
+ */
+static int
+snmp_parse(session, pdu, data, length)
+    struct snmp_session *session;
+    struct snmp_pdu *pdu;
+    u_char  *data;
+    int            length;
+{
+    u_char  msg_type;
+    u_char  type;
+    u_char  *var_val;
+    long    version;
+    int            len, four;
+    u_char community[256];
+    int community_length = 256;
+    struct variable_list *vp = 0;
+    oid            objid[MAX_NAME_LEN], *op;
+    u_char  *origdata = data;
+    int      origlength = length;
+    int      ret = 0;
+    u_char  *save_data;
+
+    /* authenticates message and returns length if valid */
+    data = snmp_auth_parse(data, &length, community, &community_length, &version);
+    if (data == NULL)
+       return -1;
+
+   if( version != SNMP_VERSION_1 && version != SNMP_VERSION_2C && version != SNMP_VERSION_2 ) {
+           fprintf(stderr, "Wrong version: %ld\n", version);
+           return -1;
+    }
+
+    save_data = data;
+
+    data = asn_parse_header(data, &length, &msg_type);
+    if (data == NULL)
+       return -1;
+    pdu->command = msg_type;
+
+    if( session->authenticator ) {
+       ret = session->authenticator( origdata, origlength, save_data - community_length, 
+               community_length, session, pdu );
+       if( ret < 0 ) return ret;
+    }
+
+    if (pdu->command != TRP_REQ_MSG){
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (data == NULL)
+           return -1;
+    } else {
+       pdu->enterprise_length = MAX_NAME_LEN;
+       data = asn_parse_objid(data, &length, &type, objid, &pdu->enterprise_length);
+       if (data == NULL)
+           return -1;
+       pdu->enterprise = (oid *)calloc(1, pdu->enterprise_length * sizeof(oid));
+       bcopy((char *)objid, (char *)pdu->enterprise, pdu->enterprise_length * sizeof(oid));
+
+       four = 4;
+       data = asn_parse_string(data, &length, &type, (u_char *)&pdu->agent_addr.sin_addr.s_addr, &four);
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->time, sizeof(pdu->time));
+       if (data == NULL)
+           return -1;
+    }
+    data = asn_parse_header(data, &length, &type);
+    if (data == NULL)
+       return -1;
+    if (type != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR))
+       return -1;
+    while((int)length > 0){
+       if (pdu->variables == NULL){
+           pdu->variables = vp = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+       } else {
+           vp->next_variable = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+           vp = vp->next_variable;
+       }
+       vp->next_variable = NULL;
+       vp->val.string = NULL;
+       vp->name = NULL;
+       vp->name_length = MAX_NAME_LEN;
+       data = snmp_parse_var_op(data, objid, &vp->name_length, &vp->type, &vp->val_len, &var_val, (int *)&length);
+       if (data == NULL)
+           return -1;
+       op = (oid *)calloc(1, (unsigned)vp->name_length * sizeof(oid));
+       bcopy((char *)objid, (char *)op, vp->name_length * sizeof(oid));
+       vp->name = op;
+
+       len = PACKET_LENGTH;
+       switch((short)vp->type){
+           case ASN_INTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(long));
+               vp->val_len = sizeof(long);
+               asn_parse_int(var_val, &len, &vp->type, (long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER:
+           case GAUGE:
+           case TIMETICKS:
+           case UINTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(unsigned long));
+               vp->val_len = sizeof(unsigned long);
+               asn_parse_unsigned_int(var_val, &len, &vp->type, (unsigned long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER64:
+               vp->val.counter64 = (struct counter64 *)calloc(1,  sizeof(struct counter64) );
+               vp->val_len = sizeof(struct counter64);
+               asn_parse_unsigned_int64(var_val, &len, &vp->type,
+                                        (struct counter64 *)vp->val.counter64,
+                                        sizeof(*vp->val.counter64));
+               break;
+           case ASN_OCTET_STR:
+           case IPADDRESS:
+           case OPAQUE:
+           case NSAP:
+               vp->val.string = (u_char *)calloc(1, (unsigned)vp->val_len);
+               asn_parse_string(var_val, &len, &vp->type, vp->val.string, &vp->val_len);
+               break;
+           case ASN_OBJECT_ID:
+               vp->val_len = MAX_NAME_LEN;
+               asn_parse_objid(var_val, &len, &vp->type, objid, &vp->val_len);
+               vp->val_len *= sizeof(oid);
+               vp->val.objid = (oid *)calloc(1, (unsigned)vp->val_len);
+               bcopy((char *)objid, (char *)vp->val.objid, vp->val_len);
+               break;
+            case SNMP_NOSUCHOBJECT:
+            case SNMP_NOSUCHINSTANCE:
+            case SNMP_ENDOFMIBVIEW:
+           case ASN_NULL:
+               break;
+           default:
+               fprintf(stderr, "bad type returned (%x)\n", vp->type);
+               break;
+       }
+    }
+    return ret;
+}
+
+/*
+ * 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(session, pdu)
+    struct snmp_session *session;
+    struct snmp_pdu    *pdu;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp = NULL;
+    u_char  packet[PACKET_LENGTH];
+    int length = PACKET_LENGTH;
+    struct request_list *rp;
+    struct timeval tv;
+
+    for(slp = Sessions; slp; slp = slp->next){
+       if (slp->session == session){
+           isp = slp->internal;
+           break;
+       }
+    }
+
+    if (! pdu) {
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+
+    if (isp == NULL){
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG
+       || pdu->command == GET_RSP_MSG || pdu->command == SET_REQ_MSG 
+       || pdu->command == GETBULK_REQ_MSG ){
+       if (pdu->reqid == SNMP_DEFAULT_REQID)
+           pdu->reqid = ++Reqid;
+       if (pdu->errstat == SNMP_DEFAULT_ERRSTAT)
+           pdu->errstat = 0;
+       if (pdu->errindex == SNMP_DEFAULT_ERRINDEX)
+           pdu->errindex = 0;
+    } else {
+       /* fill in trap defaults */
+       pdu->reqid = 1; /* give a bogus non-error reqid for traps */
+       if (pdu->enterprise_length == SNMP_DEFAULT_ENTERPRISE_LENGTH){
+           pdu->enterprise = (oid *)calloc(1, sizeof(DEFAULT_ENTERPRISE));
+           bcopy((char *)DEFAULT_ENTERPRISE, (char *)pdu->enterprise, sizeof(DEFAULT_ENTERPRISE));
+           pdu->enterprise_length = sizeof(DEFAULT_ENTERPRISE)/sizeof(oid);
+       }
+       if (pdu->time == SNMP_DEFAULT_TIME)
+           pdu->time = DEFAULT_TIME;
+    }
+    if (pdu->address.sin_addr.s_addr == SNMP_DEFAULT_ADDRESS){
+       if (isp->addr.sin_addr.s_addr != SNMP_DEFAULT_ADDRESS){
+           bcopy((char *)&isp->addr, (char *)&pdu->address, sizeof(pdu->address));
+       } else {
+           fprintf(stderr, "No remote IP address specified\n");
+           snmp_errno = SNMPERR_BAD_ADDRESS;
+           return 0;
+       }
+    }
+       
+
+    if (snmp_build(session, pdu, packet, &length, 0) < 0){
+       fprintf(stderr, "Error building packet\n");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+#if 1 /***/
+    if (snmp_dump_packet){
+      snmp_print_packet(packet, length, pdu->address, 1);
+    }
+#endif /***/
+
+    gettimeofday(&tv, (struct timezone *)0);
+    if (sendto(isp->sd, (char *)packet, length, 0, (struct sockaddr *)&pdu->address, sizeof(pdu->address)) < 0){
+       perror("sendto");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG 
+     || pdu->command == SET_REQ_MSG || pdu->command == GETBULK_REQ_MSG ){
+       /* set up to expect a response */
+       rp = (struct request_list *)calloc(1, sizeof(struct request_list));
+#if 1 /***/
+        if(! rp){
+          fprintf(stderr, "Out of memory!\n");
+          snmp_errno = SNMPERR_GENERR;
+          return 0;
+        }
+#endif /***/
+       rp->next_request = isp->requests;
+       isp->requests = rp;
+       rp->pdu = pdu;
+       rp->request_id = pdu->reqid;
+
+       rp->retries = 1;
+       rp->timeout = session->timeout;
+       rp->time = tv;
+       tv.tv_usec += rp->timeout;
+       tv.tv_sec += tv.tv_usec / 1000000L;
+       tv.tv_usec %= 1000000L;
+       rp->expire = tv;
+#if DEBUG_SNMPTRACE
+       snmp_print_trace(slp, rp, TRACE_SEND);
+#endif
+    }
+    return pdu->reqid;
+}
+
+/*
+ * Frees the pdu and any malloc'd data associated with it.
+ */
+void
+snmp_free_pdu(struct snmp_pdu * pdu)
+{
+    struct variable_list *vp, *ovp;
+
+    if (! pdu)
+      return;
+
+    vp = pdu->variables;
+    while(vp){
+      if (vp->name) {
+       free((char *)vp->name);
+      }
+      if (vp->val.string) {
+       free((char *)vp->val.string);
+      }
+      ovp = vp;
+      vp = vp->next_variable;
+      free((char *)ovp);
+    }
+    if (pdu->enterprise) {
+      free((char *)pdu->enterprise);
+    }
+    free((char *)pdu);
+}
+
+
+/*
+ * 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(fdset)
+    fd_set  *fdset;
+{
+    struct session_list *slp;
+    struct snmp_session *sp;
+    struct snmp_internal_session *isp;
+    u_char packet[PACKET_LENGTH];
+    struct sockaddr_in from;
+    ssize_t length, fromlength;
+    struct snmp_pdu *pdu;
+    struct request_list *rp /**, *orp **/ ;
+
+    for(slp = Sessions; slp; slp = slp->next){
+       if (FD_ISSET(slp->internal->sd, fdset)){
+           sp = slp->session;
+           isp = slp->internal;
+           fromlength = sizeof(from);
+           length = recvfrom(isp->sd, (char *)packet, PACKET_LENGTH, 0, (struct sockaddr *)&from, &fromlength);
+           if (length == -1) {
+               perror("recvfrom");
+               return;
+           }
+#if 1 /***/
+           if (snmp_dump_packet){
+             snmp_print_packet(packet, length, from, 0);
+           }
+           pdu = (struct snmp_pdu *)calloc(1, sizeof(struct snmp_pdu));
+
+           if(! pdu){
+             fprintf(stderr, "Out of memory!\n");
+             snmp_errno = SNMPERR_GENERR;
+             return;
+           }
+#endif /***/
+
+           pdu->address = from;
+           pdu->reqid = 0;
+           pdu->variables = NULL;
+           pdu->enterprise = NULL;
+           pdu->enterprise_length = 0;
+           if (snmp_parse(sp, pdu, packet, length) < 0){
+               fprintf(stderr, "Mangled packet\n");
+               snmp_free_pdu(pdu);
+               return\10\0BÐ+= m\0\0
+È      /* \10\0>X*/ B\10\04¨NMPT\10\ 1ì\0 */c\0\0\0\0for testing purposes */e key!  replace...
+     */
+ * \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 1\ 1\0\0\0\0\0\0\0\19\7fÿ¯ùsnmplib/snmp_api.c\0c\0\0.h\0\0\0\18\7fÿ°\85\10\0<Ðlib/snmp_api.c~\0~\0\0ñ\0\0\0\18\7fÿ±\1e\10\0\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\0\0\0\18\7fÿ±«\10\0=\10\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\0\0\0\18\7fÿ²\1d\10\0=0\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\0\0\0\18\7fÿ²\8a\10\0=P\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\0\0\0\18\7fÿ³
+\10\0=p\7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\0\0\0\18\7fÿ³\82\0\0\0\ 1\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\0\0\0Á\7fÿ³ù\0\0\0\10\7fÿ´\10\10\0\0%\0\19\0\15\0\0\10\0D(\0\0\0\10\7fÿ´_\10\0\0\0\ 2\\0\0\0\0\10\0\0\0\0\10\7fÿ´©\10\0=\98\0\0\ 24\0\0\0\0\10\0\0\0\0\10\7fÿ´ø\10\0\0\0\ 2H\0\0\0\0\10\0\0\0\0\10\7fÿµB\10\0>\10\7fÿµ]\7fÿµm\7fÿµz\0\0\0\10\7fÿµ \10\0>(\7fÿµ·\7fÿµÉ\7fÿµÖ\0\0\0\10\7fÿµï\10\0>@\7fÿ¶\12\7fÿ¶ \7fÿ¶4\0\0\0\10\7fÿ¶P\0\0\0\ 1\7fÿ¶r\7fÿ¶~\7fÿ¶\88\0\0\00\7fÿ¶\9f\10\0\7fÿ¶·\0\0\0\0\7fÿ¶Ù\10\0\89è\7fÿ·\ 1\0\0\0\0\7fÿ·#\7fÿ·/\7fÿ·>\10\0>X\7fÿ·V\0\0\03\0\0\0\0/usr/people/wessels/.indent.pro\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\ 1\0\0\0\0\7fÿ¯è\7fÿ¯ù\7fÿ°\f\7fÿ°\e\7fÿ°.\7fÿ°?\7fÿ°M\7fÿ°[\7fÿ°p\7fÿ°\85\7fÿ°\95\7fÿ°£\7fÿ°²\7fÿ°Å\7fÿ°Û\7fÿ°ñ\7fÿ±
+\7fÿ±\1e\7fÿ±2\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\7fÿ±\99\7fÿ±«\7fÿ±º\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\7fÿ²\ f\7fÿ²\1d\7fÿ²2\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\7fÿ²\7f\7fÿ²\8a\7fÿ²\99\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\7fÿ²ö\7fÿ³
+\7fÿ³ \7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\7fÿ³s\7fÿ³\82\7fÿ³\91\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\7fÿ³ç\7fÿ³ù\7fÿ´\ 4\7fÿ´\10\7fÿ´\1e\7fÿ´)\7fÿ´3\7fÿ´C\7fÿ´O\7fÿ´_\7fÿ´k\7fÿ´t\7fÿ´\81\7fÿ´\8f\7fÿ´\9f\7fÿ´©\7fÿ´·\7fÿ´Å\7fÿ´Ò\7fÿ´Ý\7fÿ´í\7fÿ´ø\7fÿµ\ 3\7fÿµ\10\7fÿµ\1d\7fÿµ)\7fÿµ7\7fÿµB\7fÿµM\7fÿµ]\7fÿµm\7fÿµz\7fÿµ\89\7fÿµ \7fÿµ«\7fÿµ·\7fÿµÉ\7fÿµÖ\7fÿµâ\7fÿµï\7fÿ¶\ 3\7fÿ¶\12\7fÿ¶ \7fÿ¶4\7fÿ¶?\7fÿ¶P\7fÿ¶b\7fÿ¶r\7fÿ¶~\7fÿ¶\88\7fÿ¶\94\7fÿ¶\9f\7fÿ¶«\7fÿ¶·\7fÿ¶É\7fÿ¶Ù\7fÿ¶í\7fÿ·\ 1\7fÿ·\15\7fÿ·#\7fÿ·/\7fÿ·>\7fÿ·L\7fÿ·V\7fÿ·f\7fÿ·q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\0\0\0°\0\0\0\ 4\0\0\0\0\0\0\0\b\10\0>X\0\0\0\f\10\0\0\0\0\10\0\0\0\0\0\0\0\14\0\0\0\14\0\0\0\14\0\0\0\18\0\0\0\18\0\0\0\18\0\0\0\1c\0\0\0\1c\0\0\0\1c\0\0\0\1c\0\0\0 \0\0\0 \0\0\0 \0\0\0$\0\0\0\v\0\0\0\e\0\0\0\19\0\0\0\v\0\0\0\e\0\0\0@\0\0\0\0\0\0\0\0\0\0\0\0\10\0,\b\0\0\0\1a\10\02\88\0\0\0\1a\0\0\0\0\0\0\0\1a\10\0\85\b\0\0\0\0\10\0>X\0\0\0\0\0\0\0\0\0\0\0\0\10\0\82à\0\0\0\0\0\0\ 1C\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e0\0\0\0\v\0\0\0\e\0\0\0\18\0\0\0\v\0\0\0\1a\0\0\0\17\0\0\0\v\0\0\0 \0\0\0\0\10\0\8d¸ude/snmp_groupvars.h~\0\0\b\0\0\0\b\0\0\0 \0\0\0\0\10\0\8dàude/snmp_groupvars.h\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8eX\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e\80\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e¨\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8eÐ\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\0\0\0\ 1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\84©\0\0\0\0/***********************************************************
+       Copyright 1989 by Carnegie Mellon University
+
+                      All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the name of CMU not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+******************************************************************/
+/*
+ * snmp_api.c - API for access to snmp.
+ */
+#define DEBUG_SNMPTRACE                0 /* set to 1 to print all SNMP actions */
+#define DEBUG_SNMPFULLDUMP     0 /* set to 1 to dump all SNMP packets */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#ifdef linux
+#include <arpa/inet.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#endif
+
+
+#include "asn1.h"
+#include "snmp.h"
+#include "snmp_impl.h"
+#include "snmp_api.h"
+#include "snmp_client.h"
+
+#define PACKET_LENGTH  4500
+
+#ifndef BSD4_3
+#define BSD4_2
+#endif
+
+#if !defined(BSD4_3) && !defined(linux) && !defined(sun)
+
+typedef long   fd_mask;
+#define NFDBITS        (sizeof(fd_mask) * NBBY)        /* bits per mask */
+
+#define        FD_SET(n, p)    ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+#define        FD_CLR(n, p)    ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+#define        FD_ISSET(n, p)  ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+#define FD_ZERO(p)     bzero((char *)(p), sizeof(*(p)))
+#endif
+
+oid default_enterprise[] = {1, 3, 6, 1, 4, 1, 3, 1, 1}; /* enterprises.cmu.systems.cmuSNMP */
+
+#define DEFAULT_COMMUNITY   "public"
+#define DEFAULT_REMPORT            SNMP_PORT
+#define DEFAULT_ENTERPRISE  default_enterprise
+#define DEFAULT_TIME       0
+#define DEFAULT_MMS        1389 /* large, randomly picked for testing purposes */
+
+/*
+ * Internal information about the state of the snmp session.
+ */
+struct snmp_internal_session {
+    int            sd;         /* socket descriptor for this connection */
+    ipaddr  addr;      /* address of connected peer */
+    struct request_list *requests;/* Info about outstanding requests */
+};
+
+/*
+ * A list of all the outstanding requests for a particular session.
+ */
+struct request_list {
+    struct request_list *next_request;
+    u_long  request_id;        /* request id */
+    int            retries;    /* Number of retries */
+    u_long timeout;    /* length to wait for timeout */
+    struct timeval time; /* Time this request was made */
+    struct timeval expire;  /* time this request is due to expire */
+    struct snmp_pdu *pdu;   /* The pdu for this request (saved so it can be retransmitted */
+};
+
+/*
+ * The list of active/open sessions.
+ */
+struct session_list {
+    struct session_list *next;
+    struct snmp_session *session;
+    struct snmp_internal_session *internal;
+};
+
+struct session_list *Sessions = NULL;
+
+u_long Reqid = 0;
+int snmp_errno = 0;
+
+char *api_errors[4] = {
+    "Unknown session",
+    "Unknown host",
+    "Invalid local port",
+    "Unknown Error"
+};
+
+
+void sync_with_agent();
+int parse_app_community_string();
+void snmp_synch_setup();
+int snmp_synch_response();
+void md5Digest();
+
+
+static char *
+api_errstring(snmp_errnumber)
+    int        snmp_errnumber;
+{
+    if (snmp_errnumber <= SNMPERR_BAD_SESSION && snmp_errnumber >= SNMPERR_GENERR){
+       return api_errors[snmp_errnumber + 4];
+    } else {
+       return "Unknown Error";
+    }
+}
+
+#if 0
+/*
+ * Gets initial request ID for all transactions.
+ */
+static void
+init_snmp(){
+    struct timeval tv;
+
+    gettimeofday(&tv, (struct timezone *)0);
+    srandom(tv.tv_sec ^ tv.tv_usec);
+    Reqid = random();
+}
+#endif
+
+
+/*
+ * Dump snmp packet to stdout:
+ */
+static void
+snmp_print_packet(packet, length, addr, code)
+  char *packet; 
+  int length; 
+  ipaddr addr; 
+  int code;
+{
+  if(length < 0) {
+    return;
+  }
+  if (code <= 0) { /* received */
+    printf("\nReceived %4d bytes from ", length);
+  }
+  else { /* sending */
+    printf("\nSending  %4d bytes to   ", length);
+  }
+  printf("%s:", inet_ntoa(addr.sin_addr));
+#if DEBUG_SNMPFULLDUMP
+  for (count = 0; count < length; count++) {
+    if ((count & 15) == 0) {
+      printf("\n  ");
+    }
+    printf("%02X ", (int)(packet[count]&255));
+  }
+#endif
+  fflush(stdout);
+}
+
+#if DEBUG_SNMPTRACE
+/*
+ * Print request
+ */
+#define TRACE_SEND   (0)
+#define TRACE_RECV   (1)
+#define TRACE_TIMEOUT (2)
+static void
+snmp_print_trace(slp, rp, code)
+  struct session_list *slp;
+  struct request_list *rp;
+  int code;
+{
+  int reqid=0, retries=1;
+  if( rp ){
+    reqid = rp->request_id;
+    retries = rp->retries;
+  }  
+  printf("\n Session %2d  ReqId %4d  ", slp->internal->sd, reqid);
+  switch(code)
+    { 
+    case TRACE_SEND:    printf("send pdu (%d)", retries);break; 
+    case TRACE_RECV:    printf("recv pdu");break; 
+    case TRACE_TIMEOUT: printf("time out");break; 
+    }
+  fflush(stdout);
+}
+#endif /* DEBUG_SNMPTRACE */
+
+
+
+
+/*
+ * 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.
+ */
+struct snmp_session *
+snmp_open(session)
+    struct snmp_session *session;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp;
+    u_char *cp;
+    int sd;
+    u_long addr;
+    struct sockaddr_in me;
+    struct hostent *hp;
+    struct servent *servp;
+    extern int check_received_pkt();
+
+    /* Copy session structure and link into list */
+    slp = (struct session_list *)calloc(1, sizeof(struct session_list));
+    slp->internal = isp = (struct snmp_internal_session *)calloc(1, sizeof(struct snmp_internal_session));
+    bzero((char *)isp, sizeof(struct snmp_internal_session));
+    slp->internal->sd = -1; /* mark it not set */
+    slp->session = (struct snmp_session *)calloc(1, sizeof(struct snmp_session));
+    bcopy((char *)session, (char *)slp->session, sizeof(struct snmp_session));
+    session = slp->session;
+    /* now link it in. */
+    slp->next = Sessions;
+    Sessions = slp;
+
+    /*
+     * session now points to the new structure that still contains pointers to
+     * data allocated elsewhere.  Some of this data is copied to space malloc'd
+     * here, and the pointer replaced with the new one.
+     */
+
+    if (session->peername != NULL){
+       cp = (u_char *)calloc(1, (unsigned)strlen(session->peername) + 1);
+       strcpy((char *)cp, session->peername);
+       session->peername = (char *)cp;
+    }
+
+    if (session->retries == SNMP_DEFAULT_RETRIES)
+       session->retries = SNMP_API_DEFAULT_RETRIES;
+    if (session->timeout == SNMP_DEFAULT_TIMEOUT)
+       session->timeout = SNMP_API_DEFAULT_TIMEOUT;
+    if (session->MMS == 0 )
+       session->MMS = DEFAULT_MMS;
+    isp->requests = NULL;
+
+
+    /* Fill in defaults if necessary */
+    if (session->community_len != SNMP_DEFAULT_COMMUNITY_LEN){
+       if( *session->community == '+' ) {
+               session->community_len--;
+               cp = (u_char *) calloc(1, (unsigned) session->community_len);
+               bcopy((char *) session->community+1, (char *)cp,
+                     session->community_len);
+               session->version = SNMP_VERSION_2C;
+       } else {
+               cp = (u_char *) calloc(1, (unsigned) session->community_len);
+               bcopy((char *) session->community, (char *) cp, 
+                     session->community_len);
+       }
+
+    } else {
+       session->community_len = strlen(DEFAULT_COMMUNITY);
+       cp = (u_char *)calloc(1, (unsigned)session->community_len);
+       bcopy((char *)DEFAULT_COMMUNITY, (char *)cp, session->community_len);
+    }
+
+    /* Set up connections */
+    sd = socket(AF_INET, SOCK_DGRAM, 0);
+    if (sd < 0){
+       perror("socket");
+       snmp_errno = SNMPERR_GENERR;
+       if (!snmp_close(session)){
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+           exit(1);
+       }
+       return 0;
+    }
+    isp->sd = sd;
+
+    if (session->peername != SNMP_DEFAULT_PEERNAME){
+       if ((addr = inet_addr(session->peername)) != -1){
+           bcopy((char *)&addr, (char *)&isp->addr.sin_addr, sizeof(isp->addr.sin_addr));
+       } else {
+           hp = gethostbyname(session->peername);
+           if (hp == NULL){
+               fprintf(stderr, "unknown host: %s\n", session->peername);
+               snmp_errno = SNMPERR_BAD_ADDRESS;
+               if (!snmp_close(session)){
+                   fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+                   exit(2);
+               }
+               return 0;
+           } else {
+               bcopy((char *)hp->h_addr, (char *)&isp->addr.sin_addr, hp->h_length);
+           }
+       }
+       isp->addr.sin_family = AF_INET;
+       if (session->remote_port == SNMP_DEFAULT_REMPORT){
+           /*servp = getservbyname("snmp", "udp");*/
+           servp=NULL;
+           if (servp != NULL){
+               isp->addr.sin_port = servp->s_port;
+           } else {
+               isp->addr.sin_port = htons(SNMP_PORT);
+           }
+       } else {
+           isp->addr.sin_port = htons(session->remote_port);
+       }
+    } else {
+       isp->addr.sin_addr.s_addr = SNMP_DEFAULT_ADDRESS;
+    }
+
+    me.sin_family = AF_INET;
+    me.sin_addr.s_addr = INADDR_ANY;
+    me.sin_port = htons(session->local_port);
+    if (bind(sd, (struct sockaddr *)&me, sizeof(me)) != 0){
+       perror("bind");
+       snmp_errno = SNMPERR_BAD_LOCPORT;
+       if (! snmp_close(session)){
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n", 
+                   api_errstring(snmp_errno));
+           exit(3);
+       }
+       return 0;
+    }
+
+    if( *cp == '/' ) {
+       session->authenticator = check_received_pkt;
+       sync_with_agent(session);
+       parse_app_community_string( session );
+       session->qoS |= USEC_QOS_GENREPORT;
+    }
+
+    /* replace comm pointer with pointer to new data: */
+    session->community = cp;   
+
+    return session;
+}
+
+void
+sync_with_agent( session )
+struct snmp_session *session;
+{
+    struct snmp_pdu *pdu, *response = 0;
+    int status;
+
+    session->qoS = USEC_QOS_GENREPORT;
+    session->userLen = 6;
+    session->version = SNMP_VERSION_2;
+    strcpy( session->userName, "public" );
+
+    snmp_synch_setup(session);
+    pdu = snmp_pdu_create(GET_REQ_MSG);
+    status = snmp_synch_response(session, pdu, &response);
+
+    if (status == STAT_SUCCESS){
+       memcpy( session->agentID, response->params.agentID, 12 );
+
+       /* save the clocks -- even though they are not authentic */
+       session->agentBoots = response->params.agentBoots;
+       session->agentTime = response->params.agentTime;
+       session->agentClock = response->params.agentTime - time(NULL);
+
+    } else {
+           if (status == STAT_TIMEOUT){
+               printf("No Response from %s\n", session->peername);
+           } else {    /* status == STAT_ERROR */
+               printf("An error occurred, Quitting\n");
+           }
+           exit( -1 );
+    }
+
+    /** freed to early: 
+      snmp_free_pdu(pdu);
+      if (response) snmp_free_pdu(response);
+     **/
+}
+#if 1 /***/
+/*
+ * Unlink one element from input request list,
+ * then free it and it's pdu.
+ */
+static void
+free_one_request(isp, orp)
+    struct snmp_internal_session *isp;
+    struct request_list *orp;
+{
+    struct request_list *rp;
+    if(! orp) return;
+    if(isp->requests == orp){ 
+      isp->requests = orp->next_request; /* unlink head */
+    }
+    else{
+      for(rp = isp->requests; rp; rp = rp->next_request){
+        if(rp->next_request == orp){ 
+         rp->next_request = orp->next_request; /* unlink element */
+         break;
+        }
+      }
+    }
+    if (orp->pdu != NULL){
+      snmp_free_pdu(orp->pdu);
+    }
+    free((char *)orp);
+}
+#endif /***/
+/*
+ * Free each element in the input request list.
+ */
+static void
+free_request_list(rp)
+    struct request_list *rp;
+{
+    struct request_list *orp;
+
+    while(rp){
+       orp = rp;
+       rp = rp->next_request;
+       if (orp->pdu != NULL)
+           snmp_free_pdu(orp->pdu);
+       free((char *)orp);
+    }
+}
+
+/*
+ * 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.
+ */
+int 
+snmp_close(session)
+    struct snmp_session *session;
+{
+    struct session_list *slp = NULL, *oslp = NULL;
+
+    if (Sessions->session == session){ /* If first entry */
+       slp = Sessions;
+       Sessions = slp->next;
+    } else {
+       for(slp = Sessions; slp; slp = slp->next){
+           if (slp->session == session){
+               if (oslp)   /* if we found entry that points here */
+                   oslp->next = slp->next;     /* link around this entry */
+               break;
+           }
+           oslp = slp;
+       }
+    }
+    /* If we found the session, free all data associated with it */
+    if (slp){
+       if (slp->session->community != NULL)
+           free((char *)slp->session->community);
+       if(slp->session->peername != NULL)
+           free((char *)slp->session->peername);
+       free((char *)slp->session);
+       if (slp->internal->sd != -1)
+           close(slp->internal->sd);
+       free_request_list(slp->internal->requests);
+       free((char *)slp->internal);
+       free((char *)slp);
+    } else {
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    return 1;
+}
+
+/*
+ * Takes a session and a pdu and serializes the ASN PDU into the area
+ * pointed to by packet.  out_length is the size of the data area available.
+ * Returns the length of the completed packet in out_length.  If any errors
+ * occur, -1 is returned.  If all goes well, 0 is returned.
+ */
+int
+snmp_build(session, pdu, packet, out_length, is_agent)
+    struct snmp_session        *session;
+    struct snmp_pdu    *pdu;
+    u_char     *packet;
+    int                        *out_length;
+    int                         is_agent;
+{
+    u_char  buf[PACKET_LENGTH];
+    u_char  *cp;
+    struct variable_list *vp;
+    int            length;
+    int            totallength;
+
+    length = *out_length;
+    cp = packet;
+    for(vp = pdu->variables; vp; vp = vp->next_variable){
+       cp = snmp_build_var_op(cp, vp->name, &vp->name_length, vp->type, vp->val_len, (u_char *)vp->val.string, &length);
+       if (cp == NULL)
+           return -1;
+    }
+    totallength = cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR), totallength);
+    if (cp == NULL)
+       return -1;
+    bcopy((char *)packet, (char *)cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+    if (pdu->command != TRP_REQ_MSG){
+       /* request id */
+       cp = asn_build_int(packet, &length,
+           (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+           (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (cp == NULL)
+           return -1;
+       /* error status */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (cp == NULL)
+           return -1;
+       /* error index */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (cp == NULL)
+           return -1;
+    } else {   /* this is a trap message */
+       /* enterprise */
+       cp = asn_build_objid(packet, &length,
+           (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID),
+           (oid *)pdu->enterprise, pdu->enterprise_length);
+       if (cp == NULL)
+           return -1;
+       /* agent-addr */
+       cp = asn_build_string(cp, &length, (u_char)IPADDRESS,
+               (u_char *)&pdu->agent_addr.sin_addr.s_addr, sizeof(pdu->agent_addr.sin_addr.s_addr));
+       if (cp == NULL)
+           return -1;
+       /* generic trap */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (cp == NULL)
+           return -1;
+       /* specific trap */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (cp == NULL)
+           return -1;
+       /* timestamp  */
+       cp = asn_build_int(cp, &length, (u_char)TIMETICKS,
+               (long *)&pdu->time, sizeof(pdu->time));
+       if (cp == NULL)
+           return -1;
+    }
+    if (length < totallength)
+       return -1;
+    bcopy((char *)buf, (char *)cp, totallength);
+    totallength += cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char)pdu->command, totallength);
+    if (cp == NULL)
+       return -1;
+    if (length < totallength)
+       return -1;
+    bcopy((char *)packet, (char *)cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+
+    cp = snmp_auth_build( packet, &length, session, is_agent, totallength );
+    if (cp == NULL)
+       return -1;
+    if ((*out_length - (cp - packet)) < totallength)
+       return -1;
+    bcopy((char *)buf, (char *)cp, totallength);
+    totallength += cp - packet;
+    *out_length = totallength;
+
+    if( session->qoS & USEC_QOS_AUTH )
+           md5Digest( packet, totallength, cp - (session->contextLen + 16),
+               cp - (session->contextLen + 16) );
+
+    return 0;
+}
+
+/*
+ * Parses the packet received on the input session, and places the data into
+ * the input pdu.  length is the length of the input packet.  If any errors
+ * are encountered, -1 is returned.  Otherwise, a 0 is returned.
+ */
+static int
+snmp_parse(session, pdu, data, length)
+    struct snmp_session *session;
+    struct snmp_pdu *pdu;
+    u_char  *data;
+    int            length;
+{
+    u_char  msg_type;
+    u_char  type;
+    u_char  *var_val;
+    long    version;
+    int            len, four;
+    u_char community[256];
+    int community_length = 256;
+    struct variable_list *vp = 0;
+    oid            objid[MAX_NAME_LEN], *op;
+    u_char  *origdata = data;
+    int      origlength = length;
+    int      ret = 0;
+    u_char  *save_data;
+
+    /* authenticates message and returns length if valid */
+    data = snmp_auth_parse(data, &length, community, &community_length, &version);
+    if (data == NULL)
+       return -1;
+
+   if( version != SNMP_VERSION_1 && version != SNMP_VERSION_2C && version != SNMP_VERSION_2 ) {
+           fprintf(stderr, "Wrong version: %ld\n", version);
+           return -1;
+    }
+
+    save_data = data;
+
+    data = asn_parse_header(data, &length, &msg_type);
+    if (data == NULL)
+       return -1;
+    pdu->command = msg_type;
+
+    if( session->authenticator ) {
+       ret = session->authenticator( origdata, origlength, save_data - community_length, 
+               community_length, session, pdu );
+       if( ret < 0 ) return ret;
+    }
+
+    if (pdu->command != TRP_REQ_MSG){
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (data == NULL)
+           return -1;
+    } else {
+       pdu->enterprise_length = MAX_NAME_LEN;
+       data = asn_parse_objid(data, &length, &type, objid, &pdu->enterprise_length);
+       if (data == NULL)
+           return -1;
+       pdu->enterprise = (oid *)calloc(1, pdu->enterprise_length * sizeof(oid));
+       bcopy((char *)objid, (char *)pdu->enterprise, pdu->enterprise_length * sizeof(oid));
+
+       four = 4;
+       data = asn_parse_string(data, &length, &type, (u_char *)&pdu->agent_addr.sin_addr.s_addr, &four);
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->time, sizeof(pdu->time));
+       if (data == NULL)
+           return -1;
+    }
+    data = asn_parse_header(data, &length, &type);
+    if (data == NULL)
+       return -1;
+    if (type != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR))
+       return -1;
+    while((int)length > 0){
+       if (pdu->variables == NULL){
+           pdu->variables = vp = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+       } else {
+           vp->next_variable = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+           vp = vp->next_variable;
+       }
+       vp->next_variable = NULL;
+       vp->val.string = NULL;
+       vp->name = NULL;
+       vp->name_length = MAX_NAME_LEN;
+       data = snmp_parse_var_op(data, objid, &vp->name_length, &vp->type, &vp->val_len, &var_val, (int *)&length);
+       if (data == NULL)
+           return -1;
+       op = (oid *)calloc(1, (unsigned)vp->name_length * sizeof(oid));
+       bcopy((char *)objid, (char *)op, vp->name_length * sizeof(oid));
+       vp->name = op;
+
+       len = PACKET_LENGTH;
+       switch((short)vp->type){
+           case ASN_INTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(long));
+               vp->val_len = sizeof(long);
+               asn_parse_int(var_val, &len, &vp->type, (long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER:
+           case GAUGE:
+           case TIMETICKS:
+           case UINTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(unsigned long));
+               vp->val_len = sizeof(unsigned long);
+               asn_parse_unsigned_int(var_val, &len, &vp->type, (unsigned long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER64:
+               vp->val.counter64 = (struct counter64 *)calloc(1,  sizeof(struct counter64) );
+               vp->val_len = sizeof(struct counter64);
+               asn_parse_unsigned_int64(var_val, &len, &vp->type,
+                                        (struct counter64 *)vp->val.counter64,
+                                        sizeof(*vp->val.counter64));
+               break;
+           case ASN_OCTET_STR:
+           case IPADDRESS:
+           case OPAQUE:
+           case NSAP:
+               vp->val.string = (u_char *)calloc(1, (unsigned)vp->val_len);
+               asn_parse_string(var_val, &len, &vp->type, vp->val.string, &vp->val_len);
+               break;
+           case ASN_OBJECT_ID:
+               vp->val_len = MAX_NAME_LEN;
+               asn_parse_objid(var_val, &len, &vp->type, objid, &vp->val_len);
+               vp->val_len *= sizeof(oid);
+               vp->val.objid = (oid *)calloc(1, (unsigned)vp->val_len);
+               bcopy((char *)objid, (char *)vp->val.objid, vp->val_len);
+               break;
+            case SNMP_NOSUCHOBJECT:
+            case SNMP_NOSUCHINSTANCE:
+            case SNMP_ENDOFMIBVIEW:
+           case ASN_NULL:
+               break;
+           default:
+               fprintf(stderr, "bad type returned (%x)\n", vp->type);
+               break;
+       }
+    }
+    return ret;
+}
+
+/*
+ * 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(session, pdu)
+    struct snmp_session *session;
+    struct snmp_pdu    *pdu;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp = NULL;
+    u_char  packet[PACKET_LENGTH];
+    int length = PACKET_LENGTH;
+    struct request_list *rp;
+    struct timeval tv;
+
+    for(slp = Sessions; slp; slp = slp->next){
+       if (slp->session == session){
+           isp = slp->internal;
+           break;
+       }
+    }
+
+    if (! pdu) {
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+
+    if (isp == NULL){
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG
+       || pdu->command == GET_RSP_MSG || pdu->command == SET_REQ_MSG 
+       || pdu->command == GETBULK_REQ_MSG ){
+       if (pdu->reqid == SNMP_DEFAULT_REQID)
+           pdu->reqid = ++Reqid;
+       if (pdu->errstat == SNMP_DEFAULT_ERRSTAT)
+           pdu->errstat = 0;
+       if (pdu->errindex == SNMP_DEFAULT_ERRINDEX)
+           pdu->errindex = 0;
+    } else {
+       /* fill in trap defaults */
+       pdu->reqid = 1; /* give a bogus non-error reqid for traps */
+       if (pdu->enterprise_length == SNMP_DEFAULT_ENTERPRISE_LENGTH){
+           pdu->enterprise = (oid *)calloc(1, sizeof(DEFAULT_ENTERPRISE));
+           bcopy((char *)DEFAULT_ENTERPRISE, (char *)pdu->enterprise, sizeof(DEFAULT_ENTERPRISE));
+           pdu->enterprise_length = sizeof(DEFAULT_ENTERPRISE)/sizeof(oid);
+       }
+       if (pdu->time == SNMP_DEFAULT_TIME)
+           pdu->time = DEFAULT_TIME;
+    }
+    if (pdu->address.sin_addr.s_addr == SNMP_DEFAULT_ADDRESS){
+       if (isp->addr.sin_addr.s_addr != SNMP_DEFAULT_ADDRESS){
+           bcopy((char *)&isp->addr, (char *)&pdu->address, sizeof(pdu->address));
+       } else {
+           fprintf(stderr, "No remote IP address specified\n");
+           snmp_errno = SNMPERR_BAD_ADDRESS;
+           return 0;
+       }
+    }
+       
+
+    if (snmp_build(session, pdu, packet, &length, 0) < 0){
+       fprintf(stderr, "Error building packet\n");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+#if 1 /***/
+    if (snmp_dump_packet){
+      snmp_print_packet(packet, length, pdu->address, 1);
+    }
+#endif /***/
+
+    gettimeofday(&tv, (struct timezone *)0);
+    if (sendto(isp->sd, (char *)packet, length, 0, (struct sockaddr *)&pdu->address, sizeof(pdu->address)) < 0){
+       perror("sendto");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG 
+     || pdu->command == SET_REQ_MSG || pdu->command == GETBULK_REQ_MSG ){
+       /* set up to expect a response */
+       rp = (struct request_list *)calloc(1, sizeof(struct request_list));
+#if 1 /***/
+        if(! rp){
+          fprintf(stderr, "Out of memory!\n");
+          snmp_errno = SNMPERR_GENERR;
+          return 0;
+        }
+#endif /***/
+       rp->next_request = isp->requests;
+       isp->requests = rp;
+       rp->pdu = pdu;
+       rp->request_id = pdu->reqid;
+
+       rp->retries = 1;
+       rp->timeout = session->timeout;
+       rp->time = tv;
+       tv.tv_usec += rp->timeout;
+       tv.tv_sec += tv.tv_usec / 1000000L;
+       tv.tv_usec %= 1000000L;
+       rp->expire = tv;
+#if DEBUG_SNMPTRACE
+       snmp_print_trace(slp, rp, TRACE_SEND);
+#endif
+    }
+    return pdu->reqid;
+}
+
+/*
+ * Frees the pdu and any malloc'd data associated with it.
+ */
+void
+snmp_free_pdu(struct snmp_pdu * pdu)
+{
+    struct variable_list *vp, *ovp;
+
+    if (! pdu)
+      return;
+
+    vp = pdu->variables;
+    while(vp){
+      if (vp->name) {
+       free((char *)vp->name);
+      }
+      if (vp->val.string) {
+       free((char *)vp->val.string);
+      }
+      ovp = vp;
+      vp = vp->next_variable;
+      free((char *)ovp);
+    }
+    if (pdu->enterprise) {
+      free((char *)pdu->enterprise);
+    }
+    free((char *)pdu);
+}
+
+
+/*
+ * 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(fdset)
+    fd_set  *fdset;
+{
+    struct session_list *slp;
+    struct snmp_session *sp;
+    struct snmp_internal_session *isp;
+    u_char packet[PACKET_LENGTH];
+    struct sockaddr_in from;
+    ssize_t length, fromlength;
+    struct snmp_pdu *pdu;
+    struct request_list *rp /**, *orp **/ ;
+
+    for(slp = Sessions; slp; slp = slp->next){
+       if (FD_ISSET(slp->internal->sd, fdset)){
+           sp = slp->session;
+           isp = slp->internal;
+           fromlength = sizeof(from);
+           length = recvfrom(isp->sd, (char *)packet, PACKET_LENGTH, 0, (struct sockaddr *)&from, &fromlength);
+           if (length == -1) {
+               perror("recvfrom");
+               return;
+           }
+#if 1 /***/
+           if (snmp_dump_packet){
+             snmp_print_packet(packet, length, from, 0);
+           }
+           pdu = (struct snmp_pdu *)calloc(1, sizeof(struct snmp_pdu));
+
+           if(! pdu){
+             fprintf(stderr, "Out of memory!\n");
+             snmp_errno = SNMPERR_GENERR;
+             return;
+           }
+#endif /***/
+
+           pdu->address = from;
+           pdu->reqid = 0;
+           pdu->variables = NULL;
+           pdu->enterprise = NULL;
+           pdu->enterprise_length = 0;
+           if (snmp_parse(sp, pdu, packet, length) < 0){
+               fprintf(stderr, "Mangled packet\n");
+               snmp_free_pdu(pdu);
+               return;
+           }
+
+           if (pdu->command == GET_RSP_MSG || pdu->command == REPORT_MSG){
+#if 1 /***/ /* bug fix: illegal re-use of rp killed some requests */
+             struct request_list *rp_next= 0;
+             for(rp = isp->requests; rp; rp = rp_next){
+               rp_next = rp->next_request;
+               if (rp->request_id == pdu->reqid){
+#if DEBUG_SNMPTRACE
+                 snmp_print_trace(slp, rp, TRACE_RECV);
+#endif
+                 if (sp->callback(RECEIVED_MESSAGE, sp, pdu->reqid, pdu, sp->callback_magic) == 1){
+                   /* successful, so delete request */
+                   free_one_request(isp, rp);
+                   break;  /* no more request with the same reqid */
+                 }
+               }
+             }
+#endif /***/
+           } else if (pdu->command == GET_REQ_MSG 
+                   || pdu->command == GETNEXT_REQ_MSG
+                   || pdu->command == GETBULK_REQ_MSG
+                   || pdu->command == TRP_REQ_MSG || pdu->command == SET_REQ_MSG){
+#if DEBUG_SNMPTRACE
+             snmp_print_trace(slp, NULL, TRACE_RECV);
+#endif
+             sp->callback(RECEIVED_MESSAGE, sp, pdu->reqid, pdu, sp->callback_magic);
+           }
+           snmp_free_pdu(pdu);
+       }
+    }
+}
+
+/*
+ * 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(numfds, fdset, timeout, block)
+    int            *numfds;
+    fd_set  *fdset;
+    struct timeval *timeout;
+    int            *block; /* should the select block until input arrives (i.e. no input) */
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp;
+    struct request_list *rp;
+    struct timeval now, earliest;
+    int active = 0, requests = 0;
+
+    timerclear(&earliest);
+    /*
+     * For each request outstanding, add it's socket to the fdset,
+     * and if it is the earliest timeout to expire, mark it as lowest.
+     */
+    for(slp = Sessions; slp; slp = slp->next){
+       active++;
+       isp = slp->internal;
+       if ((isp->sd + 1) > *numfds)
+           *numfds = (isp->sd + 1);
+       FD_SET(isp->sd, fdset);
+       if (isp->requests){
+           /* found another session with outstanding requests */
+           requests++;
+           for(rp = isp->requests; rp; rp = rp->next_request){
+               if (!timerisset(&earliest) || timercmp(&rp->expire, &earliest, <))
+                   earliest = rp->expire;
+           }
+       }
+    }
+    if (requests == 0) /* if none are active, skip arithmetic */
+       return active;
+
+    /*
+     * Now find out how much time until the earliest timeout.  This
+     * transforms earliest from an absolute time into a delta time, the
+     * time left until the select should timeout.
+     */
+    gettimeofday(&now, (struct timezone *)0);
+    earliest.tv_sec--; /* adjust time to make arithmetic easier */
+    earliest.tv_usec += 1000000L;
+    earliest.tv_sec -= now.tv_sec;
+    earliest.tv_usec -= now.tv_usec;
+    while (earliest.tv_usec >= 1000000L){
+       earliest.tv_usec -= 1000000L;
+       earliest.tv_sec += 1;
+    }
+    if (earliest.tv_sec < 0){
+       earliest.tv_sec = 0;
+       earliest.tv_usec = 0;
+    }
+
+    /* if it was blocking before or our delta time is less, reset timeout */
+    if (*block == 1 || timercmp(&earliest, timeout, <)){
+       *timeout = earliest;
+       *block = 0;
+    }
+    return active;
+}
+
+/* 
+ * 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()
+{
+    struct session_list *slp;
+    struct snmp_session *sp;
+    struct snmp_internal_session *isp;
+#if 1 /***/ /* replacing freeme by simpler and safer rp_next*/
+    struct request_list *rp, *rp_next = 0;
+#endif /***/
+    struct timeval now;
+
+    gettimeofday(&now, (struct timezone *)0);
+    /*
+     * For each request outstanding, check to see if it has expired.
+     */
+    for(slp = Sessions; slp; slp = slp->next){
+       sp = slp->session;
+       isp = slp->internal;
+#if 1 /***/ /* simplification */
+       for(rp = isp->requests; rp; rp = rp_next){
+           rp_next = rp->next_request;
+           if (timercmp(&rp->expire, &now, <)){
+               /* this timer has expired */
+               if (rp->retries >= sp->retries){
+#if DEBUG_SNMPTRACE
+                 snmp_print_trace(slp, rp, TRACE_TIMEOUT);
+#endif
+                 /* No more chances, delete this entry */
+                 sp->callback(TIMED_OUT, sp, rp->pdu->reqid, rp->pdu, sp->callback_magic);
+                 free_one_request(isp, rp);
+                 continue;
+#endif /***/
+               } else {
+                   u_char  packet[PACKET_LENGTH];
+                   int length = PACKET_LENGTH;
+                   struct timeval tv;
+
+                   /* retransmit this pdu */
+                   rp->retries++;
+                   rp->timeout <<= 1;
+                   if (snmp_build(sp, rp->pdu, packet, &length, 0) < 0){
+                       fprintf(stderr, "Error building packet\n");
+                   }
+#if 1 /***/
+                       if (snmp_dump_packet) {
+                       snmp_print_packet(packet, length, rp->pdu->address, 1);
+                   }
+#endif/***/ mplification */by simpler and safer rp_next*/n s */ replace...
+     */
+ * \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 1\ 1\0\0\0\0\0\0\0\19\7fÿ¯ùsnmplib/snmp_api.c\0c\0\0.h\0\0\0\18\7fÿ°\85\10\0<Ðlib/snmp_api.c~\0~\0\0ñ\0\0\0\18\7fÿ±\1e\10\0\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\0\0\0\18\7fÿ±«\10\0=\10\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\0\0\0\18\7fÿ²\1d\10\0=0\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\0\0\0\18\7fÿ²\8a\10\0=P\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\0\0\0\18\7fÿ³
+\10\0=p\7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\0\0\0\18\7fÿ³\82\0\0\0\ 1\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\0\0\0Á\7fÿ³ù\0\0\0\10\7fÿ´\10\10\0\0%\0\19\0\15\0\0\10\0D(\0\0\0\10\7fÿ´_\10\0\0\0\ 2\\0\0\0\0\10\0\0\0\0\10\7fÿ´©\10\0=\98\0\0\ 24\0\0\0\0\10\0\0\0\0\10\7fÿ´ø\10\0\0\0\ 2H\0\0\0\0\10\0\0\0\0\10\7fÿµB\10\0>\10\7fÿµ]\7fÿµm\7fÿµz\0\0\0\10\7fÿµ \10\0>(\7fÿµ·\7fÿµÉ\7fÿµÖ\0\0\0\10\7fÿµï\10\0>@\7fÿ¶\12\7fÿ¶ \7fÿ¶4\0\0\0\10\7fÿ¶P\0\0\0\ 1\7fÿ¶r\7fÿ¶~\7fÿ¶\88\0\0\00\7fÿ¶\9f\10\0\82à\7fÿ¶·\0\0\0\0\7fÿ¶Ù\10\0\7fÿ·\ 1\0\0\0\0\7fÿ·#\7fÿ·/\7fÿ·>\10\0>X\7fÿ·V\0\0\03\0\0\0\0/usr/people/wessels/.indent.pro\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\ 1\0\0\0\0\7fÿ¯è\7fÿ¯ù\7fÿ°\f\7fÿ°\e\7fÿ°.\7fÿ°?\7fÿ°M\7fÿ°[\7fÿ°p\7fÿ°\85\7fÿ°\95\7fÿ°£\7fÿ°²\7fÿ°Å\7fÿ°Û\7fÿ°ñ\7fÿ±
+\7fÿ±\1e\7fÿ±2\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\7fÿ±\99\7fÿ±«\7fÿ±º\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\7fÿ²\ f\7fÿ²\1d\7fÿ²2\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\7fÿ²\7f\7fÿ²\8a\7fÿ²\99\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\7fÿ²ö\7fÿ³
+\7fÿ³ \7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\7fÿ³s\7fÿ³\82\7fÿ³\91\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\7fÿ³ç\7fÿ³ù\7fÿ´\ 4\7fÿ´\10\7fÿ´\1e\7fÿ´)\7fÿ´3\7fÿ´C\7fÿ´O\7fÿ´_\7fÿ´k\7fÿ´t\7fÿ´\81\7fÿ´\8f\7fÿ´\9f\7fÿ´©\7fÿ´·\7fÿ´Å\7fÿ´Ò\7fÿ´Ý\7fÿ´í\7fÿ´ø\7fÿµ\ 3\7fÿµ\10\7fÿµ\1d\7fÿµ)\7fÿµ7\7fÿµB\7fÿµM\7fÿµ]\7fÿµm\7fÿµz\7fÿµ\89\7fÿµ \7fÿµ«\7fÿµ·\7fÿµÉ\7fÿµÖ\7fÿµâ\7fÿµï\7fÿ¶\ 3\7fÿ¶\12\7fÿ¶ \7fÿ¶4\7fÿ¶?\7fÿ¶P\7fÿ¶b\7fÿ¶r\7fÿ¶~\7fÿ¶\88\7fÿ¶\94\7fÿ¶\9f\7fÿ¶«\7fÿ¶·\7fÿ¶É\7fÿ¶Ù\7fÿ¶í\7fÿ·\ 1\7fÿ·\15\7fÿ·#\7fÿ·/\7fÿ·>\7fÿ·L\7fÿ·V\7fÿ·f\7fÿ·q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0@    \0\0\0\064));
+               break;
+           case ASN_OCTET_STR:
+           case IPADDRESS:
+           case OPAQUE:
+           case NSAP:
+               vp->val.string = (u_char *)calloc(1, (unsigned)vp->val_len);
+               asn_parse_string(var_val, &len, &vp->type, vp->val.string, &vp->val_len);
+               break;
+           case ASN_OBJECT_ID:
+               vp->val_len = MAX_NAME_LEN;
+               asn_parse_objid(var_val, &len, &vp->type, objid, &vp->val_len);
+               vp->val_len *= sizeof(oid);
+               vp->val.objid = (oid *)calloc(1, (unsigned)vp->val_len);
+               bcopy((char *)objid, (char *)vp->val.objid, vp->val_len);
+               break;
+            case SNMP_NOSUCHOBJECT:
+            case SNMP_NOSUCHINSTANCE:
+            case SNMP_ENDOFMIBVIEW:
+           case ASN_NULL:
+               break;
+           default:
+               fprintf(stderr, "bad type returned (%x)\n", vp->type);
+               break;
+       }
+    }
+    return ret;
+}
+
+/*
+ * 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(session, pdu)
+    struct snmp_session *session;
+    struct snmp_pdu    *pdu;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp = NULL;
+    u_char  packet[PACKET_LENGTH];
+    int length = PACKET_LENGTH;
+    struct request_list *rp;
+    struct timeval tv;
+
+    for(slp = Sessions; slp; slp = slp->next){
+       if (slp->session == session){
+           isp = slp->internal;
+           break;
+       }
+    }
+
+    if (! pdu) {
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+
+    if (isp == NULL){
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG
+       || pdu->command == GET_RSP_MSG || pdu->command == SET_REQ_MSG 
+       || pdu->command == GETBULK_REQ_MSG ){
+       if (pdu->reqid == SNMP_DEFAULT_REQID)
+           pdu->reqid = ++Reqid;
+       if (pdu->errstat == SNMP_DEFAULT_ERRSTAT)
+           pdu->errstat = 0;
+       if (pdu->errindex == SNMP_DEFAULT_ERRINDEX)
+           pdu->errindex = 0;
+    } else {
+       /* fill in trap defaults */
+       pdu->reqid = 1; /* give a bogus non-error reqid for traps */
+       if (pdu->enterprise_length == SNMP_DEFAULT_ENTERPRISE_LENGTH){
+           pdu->enterprise = (oid *)calloc(1, sizeof(DEFAULT_ENTERPRISE));
+           bcopy((char *)DEFAULT_ENTERPRISE, (char *)pdu->enterprise, sizeof(DEFAULT_ENTERPRISE));
+           pdu->enterprise_length = sizeof(DEFAULT_ENTERPRISE)/sizeof(oid);
+       }
+       if (pdu->time == SNMP_DEFAULT_TIME)
+           pdu->time = DEFAULT_TIME;
+    }
+    if (pdu->address.sin_addr.s_addr == SNMP_DEFAULT_ADDRESS){
+       if (isp->addr.sin_addr.s_addr != SNMP_DEFAULT_ADDRESS){
+           bcopy((char *)&isp->addr, (char *)&pdu->address, sizeof(pdu->address));
+       } else {
+           fprintf(stderr, "No remote IP address specified\n");
+           snmp_errno = SNMPERR_BAD_ADDRESS;
+           return 0;
+       }
+    }
+       
+
+    if (snmp_build(session, pdu, packet, &length, 0) < 0){
+       fprintf(stderr, "Error building packet\n");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+#if 1 /***/
+    if (snmp_dump_packet){
+      snmp_print_packet(packet, length, pdu->address, 1);
+    }
+#endif /***/
+
+    gettimeofday(&tv, (struct timezone *)0);
+    if (sendto(isp->sd, (char *)packet, length, 0, (struct sockaddr *)&pdu->address, sizeof(pdu->address)) < 0){
+       perror("sendto");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG 
+     || pdu->command == SET_REQ_MSG || pdu->command == GETBULK_REQ_MSG ){
+       /* set up to expect a response */
+       rp = (struct request_list *)calloc(1, sizeof(struct request_list));
+#if 1 /***/
+        if(! rp){
+          fprintf(stderr, "Out of memory!\n");
+          snmp_errno = SNMPERR_GENERR;
+          return 0;
+        }
+#endif /***/
+       rp->next_request = isp->requests;
+       isp->requests = rp;
+       rp->pdu = pdu;
+       rp->request_id = pdu->reqid;
+
+       rp->retries = 1;
+       rp->timeout = session->timeout;
+       rp->time = tv;
+       tv.tv_usec += rp->timeout;
+       tv.tv_sec += tv.tv_usec / 1000000L;
+       tv.tv_usec %= 1000000L;
+       rp->expire = tv;
+#if DEBUG_SNMPTRACE
+       snmp_print_trace(slp, rp, TRACE_SEND);
+#endif
+    }
+    return pdu->reqid;
+}
+
+/*
+ * Frees the pdu and any malloc'd data associated with it.
+ */
+void
+snmp_free_pdu(struct snmp_pdu * pdu)
+{
+    struct variable_list *vp, *ovp;
+
+    if (! pdu)
+      return;
+
+    vp = pdu->variables;
+    while(vp){
+      if (vp->name) {
+       free((char *)vp->name);
+      }
+      if (vp->val.string) {
+       free((char *)vp->val.string);
+      }
+      ovp = vp;
+      vp = vp->next_variable;
+      free((char *)ovp);
+    }
+    if (pdu->enterprise) {
+      free((char *)pdu->enterprise);
+    }
+    free((char *)pdu);
+}
+
+
+/*
+ * 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(fdset)
+    fd_set  *fdset;
+{
+    struct session_list *slp;
+    struct snmp_session *sp;
+    struct snmp_internal_session *isp;
+    u_char packet[PACKET_LENGTH];
+    struct sockaddr_in from;
+    ssize_t length, fromlength;
+    struct snmp_pdu *pdu;
+    struct request_list *rp /**, *orp **/ ;
+
+    for(slp = Sessions; slp; slp = slp->next){
+       if (FD_ISSET(slp->internal->sd, fdset)){
+           sp = slp->session;
+           isp = slp->internal;
+           fromlength = sizeof(from);
+           length = recvfrom(isp->sd, (char *)packet, PACKET_LENGTH, 0, (struct sockaddr *)&from, &fromlength);
+           if (length == -1) {
+               perror("recvfrom");
+               return;
+           }
+#if 1 /***/
+           if (snmp_dump_packet){
+             snmp_print_packet(packet, length, from, 0);
+           }
+           pdu = (struct snmp_pdu *)calloc(1, sizeof(struct snmp_pdu));
+
+           if(! pdu){
+             fprintf(stderr, "Out of memory!\n");
+             snmp_errno = SNMPERR_GENERR;
+             return;
+           }
+#endif /***/
+
+           pdu->address = from;
+           pdu->reqid = 0;
+           pdu->variables = NULL;
+           pdu->enterprise = NULL;
+           pdu->enterprise_length = 0;
+           if (snmp_parse(sp, pdu, packet, length) < 0){
+               fprintf(stderr, "Mangled packet\n");
+               snmp_free_pdu(pdu);
+               return;
+           }
+
+           if (pdu->command == GET_RSP_MSG || pdu->command == REPORT_MSG){
+#if 1 /***/ /* bug fix: illegal re-use of rp killed some requests */
+             struct request_list *rp_next= 0;
+             for(rp = isp->requests; rp; rp = rp_next){
+               rp_next = rp->next_request;
+               if (rp->request_id == pdu->reqid){
+#if DEBUG_SNMPTRACE
+                 snmp_print_trace(slp, rp, TRACE_RECV);
+#endif
+                 if (sp->callback(RECEIVED_MESSAGE, sp, pdu->reqid, pdu, sp->callback_magic) == 1){
+                   /* successful, so delete request */
+                   free_one_request(isp, rp);
+                   break;  /* no more request with the same reqid */
+                 }
+               }
+             }
+#endif /***/
+           } else if (pdu->command == GET_REQ_MSG 
+                   || pdu->command == GETNEXT_REQ_MSG
+                   || pdu->command == GETBULK_REQ_MSG
+                   || pdu->command == TRP_REQ_MSG || pdu->command == SET_REQ_MSG){
+#if DEBUG_SNMPTRACE
+             snmp_print_trace(slp, NULL, TRACE_RECV);
+#endif
+             sp->callback(RECEIVED_MESSAGE, sp, pdu->reqid, pdu, sp->callback_magic);
+           }
+           snmp_free_pdu(pdu);
+       }
+    }
+}
+
+/*
+ * 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(numfds, fdset, timeout, block)
+    int            *numfds;
+    fd_set  *fdset;
+    struct timeval *timeout;
+    int            *block; /* should the select block until input arrives (i.e. no input) */
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp;
+    struct request_list *rp;
+    struct timeval now, earliest;
+    int active = 0, requests = 0;
+
+    timerclear(&earliest);
+    /*
+     * For each request outstanding, add it's socket to the fdset,
+     * and if it is the earliest timeout to expire, mark it as lowest.
+     */
+    for(slp = Sessions; slp; slp = slp->next){
+       active++;
+       isp = slp->internal;
+       if ((isp->sd + 1) > *numfds)
+           *numfds = (isp->sd + 1);
+       FD_SET(isp->sd, fdset);
+       if (isp->requests){
+           /* found another session with outstanding requests */
+           requests++;
+           for(rp = isp->requests; rp; rp = rp->next_request){
+               if (!timerisset(&earliest) || timercmp(&rp->expire, &earliest, <))
+                   earliest = rp->expire;
+           }
+       }
+    }
+    if (requests == 0) /* if none are active, skip arithmetic */
+       return active;
+
+    /*
+     * Now find out how much time until the earliest timeout.  This
+     * transforms earliest from an absolute time into a delta time, the
+     * time left until the select should timeout.
+     */
+    gettimeofday(&now, (struct timezone *)0);
+    earliest.tv_sec--; /* adjust time to make arithmetic easier */
+    earliest.tv_usec += 1000000L;
+    earliest.tv_sec -= now.tv_sec;
+    earliest.tv_usec -= now.tv_usec;
+    while (earliest.tv_usec >= 1000000L){
+       earliest.tv_usec -= 1000000L;
+       earliest.tv_sec += 1;
+    }
+    if (earliest.tv_sec < 0){
+       earliest.tv_sec = 0;
+       earliest.tv_usec = 0;
+    }
+
+    /* if it was blocking before or our delta time is less, reset timeout */
+    if (*block == 1 || timercmp(&earliest, timeout, <)){
+       *timeout = earliest;
+       *block = 0;
+    }
+    return active;
+}
+
+/* 
+ * 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()
+{
+    struct session_list *slp;
+    struct snmp_session *sp;
+    struct snmp_internal_session *isp;
+#if 1 /***/ /* replacing freeme by simpler and safer rp_next*/
+    struct request_list *rp, *rp_next = 0;
+#endif /***/
+    struct timeval now;
+
+    gettimeofday(&now, (struct timezone *)0);
+    /*
+     * For each request outstanding, check to see if it has expired.
+     */
+    for(slp = Sessions; slp; slp = slp->next){
+       sp = slp->session;
+       isp = slp->internal;
+#if 1 /***/ /* simplification */
+       for(rp = isp->requests; rp; rp = rp_next){
+           rp_next = rp->next_request;
+           if (timercmp(&rp->expire, &now, <)){
+               /* this timer has expired */
+               if (rp->retries >= sp->retries){
+#if DEBUG_SNMPTRACE
+                 snmp_print_trace(slp, rp, TRACE_TIMEOUT);
+#endif
+                 /* No more chances, delete this entry */
+                 sp->callback(TIMED_OUT, sp, rp->pdu->reqid, rp->pdu, sp->callback_magic);
+                 free_one_request(isp, rp);
+                 continue;
+#endif /***/
+               } else {
+                   u_char  packet[PACKET_LENGTH];
+                   int length = PACKET_LENGTH;
+                   struct timeval tv;
+
+                   /* retransmit this pdu */
+                   rp->retries++;
+                   rp->timeout <<= 1;
+                   if (snmp_build(sp, rp->pdu, packet, &length, 0) < 0){
+                       fprintf(stderr, "Error building packet\n");
+                   }
+#if 1 /***/
+                       if (snmp_dump_packet) {
+                       snmp_print_packet(packet, length, rp->pdu->address, 1);
+                   }
+ If any errors
+ * are encountered, -1 is returned.  Otherwise, a 0 is returned.
+ */
+static int
+snmp_parse(session, pdu, data, length)
+    struct snmp_session *session;
+    struct snmp_pdu *pdu;
+    u_char  *data;
+    int            length;
+{
+    u_char  msg_type;
+    u_char  type;
+    u_char  *var_val;
+    long    version;
+    int            len, four;
+    u_char community[256];
+    int community_length = 256;
+    struct variable_list *vp = 0;
+    oid            objid[MAX_NAME_LEN], *op;
+    u_char  *origdata = data;
+    int      origlength = length;
+    int      ret = 0;
+    u_char  *save_data;
+
+    /* authenticates message and returns length if valid */
+    data = snmp_auth_parse(data, &length, community, &community_length, &version);
+    if (data == NULL)
+       return -1;
+
+   if( version != SNMP_VERSION_1 && version != SNMP_VERSION_2C && version != SNMP_VERSION_2 ) {
+           fprintf(stderr, "Wrong version: %ld\n", version);
+           return -1;
+    }
+
+    save_data = data;
+
+    data = asn_parse_header(data, &length, &msg_type);
+    if (data == NULL)
+       return -1;
+    pdu->command = msg_type;
+
+    if( session->authenticator ) {
+       ret = session->authenticator( origdata, origlength, save_data - community_length, 
+               community_length, session, pdu );
+       if( ret < 0 ) return ret;
+    }
+
+    if (pdu->command != TRP_REQ_MSG){
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (data == NULL)
+           return -1;
+    } else {
+       pdu->enterprise_length = MAX_NAME_LEN;
+       data = asn_parse_objid(data, &length, &type, objid, &pdu->enterprise_length);
+       if (data == NULL)
+           return -1;
+       pdu->enterprise = (oid *)calloc(1, pdu->enterprise_length * sizeof(oid));
+       bcopy((char *)objid, (char *)pdu->enterprise, pdu->enterprise_length * sizeof(oid));
+
+       four = 4;
+       data = asn_parse_string(data, &length, &type, (u_char *)&pdu->agent_addr.sin_addr.s_addr, &four);
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->time, sizeof(pdu->time));
+       if (data == NULL)
+           return -1;
+    }
+    data = asn_parse_header(data, &length, &type);
+    if (data == NULL)
+       return -1;
+    if (type != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR))
+       return -1;
+    while((int)length > 0){
+       if (pdu->variables == NULL){
+           pdu->variables = vp = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+       } else {
+           vp->next_variable = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+           vp = vp->next_variable;
+       }
+       vp->next_variable = NULL;
+       vp->val.string = NULL;
+       vp->name = NULL;
+       vp->name_length = MAX_NAME_LEN;
+       data = snmp_parse_var_op(data, objid, &vp->name_length, &vp->type, &vp->val_len, &var_val, (int *)&length);
+       if (data == NULL)
+           return -1;
+       op = (oid *)calloc(1, (unsigned)vp->name_length * sizeof(oid));
+       bcopy((char *)objid, (char *)op, vp->name_length * sizeof(oid));
+       vp->name = op;
+
+       len = PACKET_LENGTH;
+       switch((short)vp->type){
+           case ASN_INTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(long));
+               vp->val_len = sizeof(long);
+               asn_parse_int(var_val, &len, &vp->type, (long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER:
+           case GAUGE:
+           case TIMETICKS:
+           case UINTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(unsigned long));
+               vp->val_len = sizeof(unsigned long);
+               asn_parse_unsigned_int(var_val, &len, &vp->type, (unsigned long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER64:
+               vp->val.counter64 = (struct counter64 *)calloc(1,  sizeof(struct counter64) );
+               vp->val_len = sizeof(struct counter64);
+               asn_parse_unsigned_int64(var_val, &len, &vp->type,
+                                        (struct counter64 *)vp->val.counter64,
+                                        sizeof(*vp->val.counter\10\0BÐ+= m\0\0
+È      /* \0\0\0\0*/ B\10\0>XNMPT\10\ 1í\88 */c\0\0\0\0for testing purposes */e key!  replace...
+     */
+ * \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 1\ 1\0\0\0\0\0\0\0\19\7fÿ¯ùsnmplib/snmp_api.c\0c\0\0.h\0\0\0\18\7fÿ°\85\10\0<Ðlib/snmp_api.c~\0~\0\0ñ\0\0\0\18\7fÿ±\1e\10\0\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\0\0\0\18\7fÿ±«\10\0=\10\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\0\0\0\18\7fÿ²\1d\10\0=0\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\0\0\0\18\7fÿ²\8a\10\0=P\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\0\0\0\18\7fÿ³
+\10\0=p\7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\0\0\0\18\7fÿ³\82\0\0\0\ 1\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\0\0\0Á\7fÿ³ù\0\0\0\10\7fÿ´\10\10\0\0%\0\19\0\15\0\0\10\0D(\0\0\0\10\7fÿ´_\10\0\0\0\ 2\\0\0\0\0\10\0\0\0\0\10\7fÿ´©\10\0=\98\0\0\ 24\0\0\0\0\10\0\0\0\0\10\7fÿ´ø\10\0\0\0\ 2H\0\0\0\0\10\0\0\0\0\10\7fÿµB\10\0>\10\7fÿµ]\7fÿµm\7fÿµz\0\0\0\10\7fÿµ \10\0>(\7fÿµ·\7fÿµÉ\7fÿµÖ\0\0\0\10\7fÿµï\10\0>@\7fÿ¶\12\7fÿ¶ \7fÿ¶4\0\0\0\10\7fÿ¶P\0\0\0\ 1\7fÿ¶r\7fÿ¶~\7fÿ¶\88\0\0\00\7fÿ¶\9f\10\0\7fÿ¶·\0\0\0\0\7fÿ¶Ù\10\0\89è\7fÿ·\ 1\0\0\0\0\7fÿ·#\7fÿ·/\7fÿ·>\10\0>X\7fÿ·V\0\0\03\0\0\0\0/usr/people/wessels/.indent.pro\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\ 1\0\0\0\0\7fÿ¯è\7fÿ¯ù\7fÿ°\f\7fÿ°\e\7fÿ°.\7fÿ°?\7fÿ°M\7fÿ°[\7fÿ°p\7fÿ°\85\7fÿ°\95\7fÿ°£\7fÿ°²\7fÿ°Å\7fÿ°Û\7fÿ°ñ\7fÿ±
+\7fÿ±\1e\7fÿ±2\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\7fÿ±\99\7fÿ±«\7fÿ±º\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\7fÿ²\ f\7fÿ²\1d\7fÿ²2\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\7fÿ²\7f\7fÿ²\8a\7fÿ²\99\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\7fÿ²ö\7fÿ³
+\7fÿ³ \7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\7fÿ³s\7fÿ³\82\7fÿ³\91\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\7fÿ³ç\7fÿ³ù\7fÿ´\ 4\7fÿ´\10\7fÿ´\1e\7fÿ´)\7fÿ´3\7fÿ´C\7fÿ´O\7fÿ´_\7fÿ´k\7fÿ´t\7fÿ´\81\7fÿ´\8f\7fÿ´\9f\7fÿ´©\7fÿ´·\7fÿ´Å\7fÿ´Ò\7fÿ´Ý\7fÿ´í\7fÿ´ø\7fÿµ\ 3\7fÿµ\10\7fÿµ\1d\7fÿµ)\7fÿµ7\7fÿµB\7fÿµM\7fÿµ]\7fÿµm\7fÿµz\7fÿµ\89\7fÿµ \7fÿµ«\7fÿµ·\7fÿµÉ\7fÿµÖ\7fÿµâ\7fÿµï\7fÿ¶\ 3\7fÿ¶\12\7fÿ¶ \7fÿ¶4\7fÿ¶?\7fÿ¶P\7fÿ¶b\7fÿ¶r\7fÿ¶~\7fÿ¶\88\7fÿ¶\94\7fÿ¶\9f\7fÿ¶«\7fÿ¶·\7fÿ¶É\7fÿ¶Ù\7fÿ¶í\7fÿ·\ 1\7fÿ·\15\7fÿ·#\7fÿ·/\7fÿ·>\7fÿ·L\7fÿ·V\7fÿ·f\7fÿ·q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\0\0\0°\0\0\0\ 4\0\0\0\0\0\0\0\b\10\0>X\0\0\0\f\10\0\0\0\0\10\0\0\0\0\0\0\0\14\0\0\0\14\0\0\0\14\0\0\0\18\0\0\0\18\0\0\0\18\0\0\0\1c\0\0\0\1c\0\0\0\1c\0\0\0\1c\0\0\0 \0\0\0 \0\0\0 \0\0\0$\0\0\0\v\0\0\0\e\0\0\0\19\0\0\0\v\0\0\0\e\0\0\0@\0\0\0\0\0\0\0\0\0\0\0\0\10\0,\b\0\0\0\1a\10\02\88\0\0\0\1a\0\0\0\0\0\0\0\1a\10\0\85\b\0\0\0\0\10\0>X\0\0\0\0\0\0\0\0\0\0\0\0\10\0\82à\0\0\0\0\0\0\ 1C\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e0\0\0\0\v\0\0\0\e\0\0\0\18\0\0\0\v\0\0\0\1a\0\0\0\17\0\0\0\v\0\0\0 \0\0\0\0\10\0\8d¸ude/snmp_groupvars.h~\0\0\b\0\0\0\b\0\0\0 \0\0\0\0\10\0\8dàude/snmp_groupvars.h\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8eX\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e\80\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e¨\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8eÐ\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\0\0\0\ 1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\84©\0\0\0\0/***********************************************************
+       Copyright 1989 by Carnegie Mellon University
+
+                      All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the name of CMU not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+******************************************************************/
+/*
+ * snmp_api.c - API for access to snmp.
+ */
+#define DEBUG_SNMPTRACE                0 /* set to 1 to print all SNMP actions */
+#define DEBUG_SNMPFULLDUMP     0 /* set to 1 to dump all SNMP packets */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#ifdef linux
+#include <arpa/inet.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#endif
+
+
+#include "asn1.h"
+#include "snmp.h"
+#include "snmp_impl.h"
+#include "snmp_api.h"
+#include "snmp_client.h"
+
+#define PACKET_LENGTH  4500
+
+#ifndef BSD4_3
+#define BSD4_2
+#endif
+
+#if !defined(BSD4_3) && !defined(linux) && !defined(sun)
+
+typedef long   fd_mask;
+#define NFDBITS        (sizeof(fd_mask) * NBBY)        /* bits per mask */
+
+#define        FD_SET(n, p)    ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+#define        FD_CLR(n, p)    ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+#define        FD_ISSET(n, p)  ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+#define FD_ZERO(p)     bzero((char *)(p), sizeof(*(p)))
+#endif
+
+oid default_enterprise[] = {1, 3, 6, 1, 4, 1, 3, 1, 1}; /* enterprises.cmu.systems.cmuSNMP */
+
+#define DEFAULT_COMMUNITY   "public"
+#define DEFAULT_REMPORT            SNMP_PORT
+#define DEFAULT_ENTERPRISE  default_enterprise
+#define DEFAULT_TIME       0
+#define DEFAULT_MMS        1389 /* large, randomly picked for testing purposes */
+
+/*
+ * Internal information about the state of the snmp session.
+ */
+struct snmp_internal_session {
+    int            sd;         /* socket descriptor for this connection */
+    ipaddr  addr;      /* address of connected peer */
+    struct request_list *requests;/* Info about outstanding requests */
+};
+
+/*
+ * A list of all the outstanding requests for a particular session.
+ */
+struct request_list {
+    struct request_list *next_request;
+    u_long  request_id;        /* request id */
+    int            retries;    /* Number of retries */
+    u_long timeout;    /* length to wait for timeout */
+    struct timeval time; /* Time this request was made */
+    struct timeval expire;  /* time this request is due to expire */
+    struct snmp_pdu *pdu;   /* The pdu for this request (saved so it can be retransmitted */
+};
+
+/*
+ * The list of active/open sessions.
+ */
+struct session_list {
+    struct session_list *next;
+    struct snmp_session *session;
+    struct snmp_internal_session *internal;
+};
+
+struct session_list *Sessions = NULL;
+
+u_long Reqid = 0;
+int snmp_errno = 0;
+
+char *api_errors[4] = {
+    "Unknown session",
+    "Unknown host",
+    "Invalid local port",
+    "Unknown Error"
+};
+
+
+void sync_with_agent();
+int parse_app_community_string();
+void snmp_synch_setup();
+int snmp_synch_response();
+void md5Digest();
+
+
+static char *
+api_errstring(snmp_errnumber)
+    int        snmp_errnumber;
+{
+    if (snmp_errnumber <= SNMPERR_BAD_SESSION && snmp_errnumber >= SNMPERR_GENERR){
+       return api_errors[snmp_errnumber + 4];
+    } else {
+       return "Unknown Error";
+    }
+}
+
+#if 0
+/*
+ * Gets initial request ID for all transactions.
+ */
+static void
+init_snmp(){
+    struct timeval tv;
+
+    gettimeofday(&tv, (struct timezone *)0);
+    srandom(tv.tv_sec ^ tv.tv_usec);
+    Reqid = random();
+}
+#endif
+
+
+/*
+ * Dump snmp packet to stdout:
+ */
+static void
+snmp_print_packet(packet, length, addr, code)
+  char *packet; 
+  int length; 
+  ipaddr addr; 
+  int code;
+{
+  if(length < 0) {
+    return;
+  }
+  if (code <= 0) { /* received */
+    printf("\nReceived %4d bytes from ", length);
+  }
+  else { /* sending */
+    printf("\nSending  %4d bytes to   ", length);
+  }
+  printf("%s:", inet_ntoa(addr.sin_addr));
+#if DEBUG_SNMPFULLDUMP
+  for (count = 0; count < length; count++) {
+    if ((count & 15) == 0) {
+      printf("\n  ");
+    }
+    printf("%02X ", (int)(packet[count]&255));
+  }
+#endif
+  fflush(stdout);
+}
+
+#if DEBUG_SNMPTRACE
+/*
+ * Print request
+ */
+#define TRACE_SEND   (0)
+#define TRACE_RECV   (1)
+#define TRACE_TIMEOUT (2)
+static void
+snmp_print_trace(slp, rp, code)
+  struct session_list *slp;
+  struct request_list *rp;
+  int code;
+{
+  int reqid=0, retries=1;
+  if( rp ){
+    reqid = rp->request_id;
+    retries = rp->retries;
+  }  
+  printf("\n Session %2d  ReqId %4d  ", slp->internal->sd, reqid);
+  switch(code)
+    { 
+    case TRACE_SEND:    printf("send pdu (%d)", retries);break; 
+    case TRACE_RECV:    printf("recv pdu");break; 
+    case TRACE_TIMEOUT: printf("time out");break; 
+    }
+  fflush(stdout);
+}
+#endif /* DEBUG_SNMPTRACE */
+
+
+
+
+/*
+ * 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.
+ */
+struct snmp_session *
+snmp_open(session)
+    struct snmp_session *session;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp;
+    u_char *cp;
+    int sd;
+    u_long addr;
+    struct sockaddr_in me;
+    struct hostent *hp;
+    struct servent *servp;
+    extern int check_received_pkt();
+
+    /* Copy session structure and link into list */
+    slp = (struct session_list *)calloc(1, sizeof(struct session_list));
+    slp->internal = isp = (struct snmp_internal_session *)calloc(1, sizeof(struct snmp_internal_session));
+    bzero((char *)isp, sizeof(struct snmp_internal_session));
+    slp->internal->sd = -1; /* mark it not set */
+    slp->session = (struct snmp_session *)calloc(1, sizeof(struct snmp_session));
+    bcopy((char *)session, (char *)slp->session, sizeof(struct snmp_session));
+    session = slp->session;
+    /* now link it in. */
+    slp->next = Sessions;
+    Sessions = slp;
+
+    /*
+     * session now points to the new structure that still contains pointers to
+     * data allocated elsewhere.  Some of this data is copied to space malloc'd
+     * here, and the pointer replaced with the new one.
+     */
+
+    if (session->peername != NULL){
+       cp = (u_char *)calloc(1, (unsigned)strlen(session->peername) + 1);
+       strcpy((char *)cp, session->peername);
+       session->peername = (char *)cp;
+    }
+
+    if (session->retries == SNMP_DEFAULT_RETRIES)
+       session->retries = SNMP_API_DEFAULT_RETRIES;
+    if (session->timeout == SNMP_DEFAULT_TIMEOUT)
+       session->timeout = SNMP_API_DEFAULT_TIMEOUT;
+    if (session->MMS == 0 )
+       session->MMS = DEFAULT_MMS;
+    isp->requests = NULL;
+
+
+    /* Fill in defaults if necessary */
+    if (session->community_len != SNMP_DEFAULT_COMMUNITY_LEN){
+       if( *session->community == '+' ) {
+               session->community_len--;
+               cp = (u_char *) calloc(1, (unsigned) session->community_len);
+               bcopy((char *) session->community+1, (char *)cp,
+                     session->community_len);
+               session->version = SNMP_VERSION_2C;
+       } else {
+               cp = (u_char *) calloc(1, (unsigned) session->community_len);
+               bcopy((char *) session->community, (char *) cp, 
+                     session->community_len);
+       }
+
+    } else {
+       session->community_len = strlen(DEFAULT_COMMUNITY);
+       cp = (u_char *)calloc(1, (unsigned)session->community_len);
+       bcopy((char *)DEFAULT_COMMUNITY, (char *)cp, session->community_len);
+    }
+
+    /* Set up connections */
+    sd = socket(AF_INET, SOCK_DGRAM, 0);
+    if (sd < 0){
+       perror("socket");
+       snmp_errno = SNMPERR_GENERR;
+       if (!snmp_close(session)){
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+           exit(1);
+       }
+       return 0;
+    }
+    isp->sd = sd;
+
+    if (session->peername != SNMP_DEFAULT_PEERNAME){
+       if ((addr = inet_addr(session->peername)) != -1){
+           bcopy((char *)&addr, (char *)&isp->addr.sin_addr, sizeof(isp->addr.sin_addr));
+       } else {
+           hp = gethostbyname(session->peername);
+           if (hp == NULL){
+               fprintf(stderr, "unknown host: %s\n", session->peername);
+               snmp_errno = SNMPERR_BAD_ADDRESS;
+               if (!snmp_close(session)){
+                   fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
+                   exit(2);
+               }
+               return 0;
+           } else {
+               bcopy((char *)hp->h_addr, (char *)&isp->addr.sin_addr, hp->h_length);
+           }
+       }
+       isp->addr.sin_family = AF_INET;
+       if (session->remote_port == SNMP_DEFAULT_REMPORT){
+           /*servp = getservbyname("snmp", "udp");*/
+           servp=NULL;
+           if (servp != NULL){
+               isp->addr.sin_port = servp->s_port;
+           } else {
+               isp->addr.sin_port = htons(SNMP_PORT);
+           }
+       } else {
+           isp->addr.sin_port = htons(session->remote_port);
+       }
+    } else {
+       isp->addr.sin_addr.s_addr = SNMP_DEFAULT_ADDRESS;
+    }
+
+    me.sin_family = AF_INET;
+    me.sin_addr.s_addr = INADDR_ANY;
+    me.sin_port = htons(session->local_port);
+    if (bind(sd, (struct sockaddr *)&me, sizeof(me)) != 0){
+       perror("bind");
+       snmp_errno = SNMPERR_BAD_LOCPORT;
+       if (! snmp_close(session)){
+           fprintf(stderr, "Couldn't abort session: %s. Exiting\n", 
+                   api_errstring(snmp_errno));
+           exit(3);
+       }
+       return 0;
+    }
+
+    if( *cp == '/' ) {
+       session->authenticator = check_received_pkt;
+       sync_with_agent(session);
+       parse_app_community_string( session );
+       session->qoS |= USEC_QOS_GENREPORT;
+    }
+
+    /* replace comm pointer with pointer to new data: */
+    session->community = cp;   
+
+    return session;
+}
+
+void
+sync_with_agent( session )
+struct snmp_session *session;
+{
+    struct snmp_pdu *pdu, *response = 0;
+    int status;
+
+    session->qoS = USEC_QOS_GENREPORT;
+    session->userLen = 6;
+    session->version = SNMP_VERSION_2;
+    strcpy( session->userName, "public" );
+
+    snmp_synch_setup(session);
+    pdu = snmp_pdu_create(GET_REQ_MSG);
+    status = snmp_synch_response(session, pdu, &response);
+
+    if (status == STAT_SUCCESS){
+       memcpy( session->agentID, response->params.agentID, 12 );
+
+       /* save the clocks -- even though they are not authentic */
+       session->agentBoots = response->params.agentBoots;
+       session->agentTime = response->params.agentTime;
+       session->agentClock = response->params.agentTime - time(NULL);
+
+    } else {
+           if (status == STAT_TIMEOUT){
+               printf("No Response from %s\n", session->peername);
+           } else {    /* status == STAT_ERROR */
+               printf("An error occurred, Quitting\n");
+           }
+           exit( -1 );
+    }
+
+    /** freed to early: 
+      snmp_free_pdu(pdu);
+      if (response) snmp_free_pdu(response);
+     **/
+}
+#if 1 /***/
+/*
+ * Unlink one element from input request list,
+ * then free it and it's pdu.
+ */
+static void
+free_one_request(isp, orp)
+    struct snmp_internal_session *isp;
+    struct request_list *orp;
+{
+    struct request_list *rp;
+    if(! orp) return;
+    if(isp->requests == orp){ 
+      isp->requests = orp->next_request; /* unlink head */
+    }
+    else{
+      for(rp = isp->requests; rp; rp = rp->next_request){
+        if(rp->next_request == orp){ 
+         rp->next_request = orp->next_request; /* unlink element */
+         break;
+        }
+      }
+    }
+    if (orp->pdu != NULL){
+      snmp_free_pdu(orp->pdu);
+    }
+    free((char *)orp);
+}
+#endif /***/
+/*
+ * Free each element in the input request list.
+ */
+static void
+free_request_list(rp)
+    struct request_list *rp;
+{
+    struct request_list *orp;
+
+    while(rp){
+       orp = rp;
+       rp = rp->next_request;
+       if (orp->pdu != NULL)
+           snmp_free_pdu(orp->pdu);
+       free((char *)orp);
+    }
+}
+
+/*
+ * 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.
+ */
+int 
+snmp_close(session)
+    struct snmp_session *session;
+{
+    struct session_list *slp = NULL, *oslp = NULL;
+
+    if (Sessions->session == session){ /* If first entry */
+       slp = Sessions;
+       Sessions = slp->next;
+    } else {
+       for(slp = Sessions; slp; slp = slp->next){
+           if (slp->session == session){
+               if (oslp)   /* if we found entry that points here */
+                   oslp->next = slp->next;     /* link around this entry */
+               break;
+           }
+           oslp = slp;
+       }
+    }
+    /* If we found the session, free all data associated with it */
+    if (slp){
+       if (slp->session->community != NULL)
+           free((char *)slp->session->community);
+       if(slp->session->peername != NULL)
+           free((char *)slp->session->peername);
+       free((char *)slp->session);
+       if (slp->internal->sd != -1)
+           close(slp->internal->sd);
+       free_request_list(slp->internal->requests);
+       free((char *)slp->internal);
+       free((char *)slp);
+    } else {
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    return 1;
+}
+
+/*
+ * Takes a session and a pdu and serializes the ASN PDU into the area
+ * pointed to by packet.  out_length is the size of the data area available.
+ * Returns the length of the completed packet in out_length.  If any errors
+ * occur, -1 is returned.  If all goes well, 0 is returned.
+ */
+int
+snmp_build(session, pdu, packet, out_length, is_agent)
+    struct snmp_session        *session;
+    struct snmp_pdu    *pdu;
+    u_char     *packet;
+    int                        *out_length;
+    int                         is_agent;
+{
+    u_char  buf[PACKET_LENGTH];
+    u_char  *cp;
+    struct variable_list *vp;
+    int            length;
+    int            totallength;
+
+    length = *out_length;
+    cp = packet;
+    for(vp = pdu->variables; vp; vp = vp->next_variable){
+       cp = snmp_build_var_op(cp, vp->name, &vp->name_length, vp->type, vp->val_len, (u_char *)vp->val.string, &length);
+       if (cp == NULL)
+           return -1;
+    }
+    totallength = cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR), totallength);
+    if (cp == NULL)
+       return -1;
+    bcopy((char *)packet, (char *)cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+    if (pdu->command != TRP_REQ_MSG){
+       /* request id */
+       cp = asn_build_int(packet, &length,
+           (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+           (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (cp == NULL)
+           return -1;
+       /* error status */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (cp == NULL)
+           return -1;
+       /* error index */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (cp == NULL)
+           return -1;
+    } else {   /* this is a trap message */
+       /* enterprise */
+       cp = asn_build_objid(packet, &length,
+           (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID),
+           (oid *)pdu->enterprise, pdu->enterprise_length);
+       if (cp == NULL)
+           return -1;
+       /* agent-addr */
+       cp = asn_build_string(cp, &length, (u_char)IPADDRESS,
+               (u_char *)&pdu->agent_addr.sin_addr.s_addr, sizeof(pdu->agent_addr.sin_addr.s_addr));
+       if (cp == NULL)
+           return -1;
+       /* generic trap */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (cp == NULL)
+           return -1;
+       /* specific trap */
+       cp = asn_build_int(cp, &length,
+               (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+               (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (cp == NULL)
+           return -1;
+       /* timestamp  */
+       cp = asn_build_int(cp, &length, (u_char)TIMETICKS,
+               (long *)&pdu->time, sizeof(pdu->time));
+       if (cp == NULL)
+           return -1;
+    }
+    if (length < totallength)
+       return -1;
+    bcopy((char *)buf, (char *)cp, totallength);
+    totallength += cp - packet;
+
+    length = PACKET_LENGTH;
+    cp = asn_build_header(buf, &length, (u_char)pdu->command, totallength);
+    if (cp == NULL)
+       return -1;
+    if (length < totallength)
+       return -1;
+    bcopy((char *)packet, (char *)cp, totallength);
+    totallength += cp - buf;
+
+    length = *out_length;
+
+    cp = snmp_auth_build( packet, &length, session, is_agent, totallength );
+    if (cp == NULL)
+       return -1;
+    if ((*out_length - (cp - packet)) < totallength)
+       return -1;
+    bcopy((char *)buf, (char *)cp, totallength);
+    totallength += cp - packet;
+    *out_length = totallength;
+
+    if( session->qoS & USEC_QOS_AUTH )
+           md5Digest( packet, totallength, cp - (session->contextLen + 16),
+               cp - (session->contextLen + 16) );
+
+    return 0;
+}
+
+/*
+ * Parses the packet received on the input session, and places the data into
+ * the input pdu.  length is the length of the input packet.  If any errors
+ * are encountered, -1 is returned.  Otherwise, a 0 is returned.
+ */
+static int
+snmp_parse(session, pdu, data, length)
+    struct snmp_session *session;
+    struct snmp_pdu *pdu;
+    u_char  *data;
+    int            length;
+{
+    u_char  msg_type;
+    u_char  type;
+    u_char  *var_val;
+    long    version;
+    int            len, four;
+    u_char community[256];
+    int community_length = 256;
+    struct variable_list *vp = 0;
+    oid            objid[MAX_NAME_LEN], *op;
+    u_char  *origdata = data;
+    int      origlength = length;
+    int      ret = 0;
+    u_char  *save_data;
+
+    /* authenticates message and returns length if valid */
+    data = snmp_auth_parse(data, &length, community, &community_length, &version);
+    if (data == NULL)
+       return -1;
+
+   if( version != SNMP_VERSION_1 && version != SNMP_VERSION_2C && version != SNMP_VERSION_2 ) {
+           fprintf(stderr, "Wrong version: %ld\n", version);
+           return -1;
+    }
+
+    save_data = data;
+
+    data = asn_parse_header(data, &length, &msg_type);
+    if (data == NULL)
+       return -1;
+    pdu->command = msg_type;
+
+    if( session->authenticator ) {
+       ret = session->authenticator( origdata, origlength, save_data - community_length, 
+               community_length, session, pdu );
+       if( ret < 0 ) return ret;
+    }
+
+    if (pdu->command != TRP_REQ_MSG){
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (data == NULL)
+           return -1;
+    } else {
+       pdu->enterprise_length = MAX_NAME_LEN;
+       data = asn_parse_objid(data, &length, &type, objid, &pdu->enterprise_length);
+       if (data == NULL)
+           return -1;
+       pdu->enterprise = (oid *)calloc(1, pdu->enterprise_length * sizeof(oid));
+       bcopy((char *)objid, (char *)pdu->enterprise, pdu->enterprise_length * sizeof(oid));
+
+       four = 4;
+       data = asn_parse_string(data, &length, &type, (u_char *)&pdu->agent_addr.sin_addr.s_addr, &four);
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->time, sizeof(pdu->time));
+       if (data == NULL)
+           return -1;
+    }
+    data = asn_parse_header(data, &length, &type);
+    if (data == NULL)
+       return -1;
+    if (type != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR))
+       return -1;
+    while((int)length > 0){
+       if (pdu->variables == NULL){
+           pdu->variables = vp = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+       } else {
+           vp->next_variable = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+           vp = vp->next_variable;
+       }
+       vp->next_variable = NULL;
+       vp->val.string = NULL;
+       vp->name = NULL;
+       vp->name_length = MAX_NAME_LEN;
+       data = snmp_parse_var_op(data, objid, &vp->name_length, &vp->type, &vp->val_len, &var_val, (int *)&length);
+       if (data == NULL)
+           return -1;
+       op = (oid *)calloc(1, (unsigned)vp->name_length * sizeof(oid));
+       bcopy((char *)objid, (char *)op, vp->name_length * sizeof(oid));
+       vp->name = op;
+
+       len = PACKET_LENGTH;
+       switch((short)vp->type){
+           case ASN_INTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(long));
+               vp->val_len = sizeof(long);
+               asn_parse_int(var_val, &len, &vp->type, (long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER:
+           case GAUGE:
+           case TIMETICKS:
+           case UINTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(unsigned long));
+               vp->val_len = sizeof(unsigned long);
+               asn_parse_unsigned_int(var_val, &len, &vp->type, (unsigned long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER64:
+               vp->val.counter64 = (struct counter64 *)calloc(1,  sizeof(struct counter64) );
+               vp->val_len = sizeof(struct counter64);
+               asn_parse_unsigned_int64(var_val, &len, &vp->type,
+                                        (struct counter64 *)vp->val.counter64,
+                                        sizeof(*vp->val.counter64));
+               break;
+           case ASN_OCTET_STR:
+           case IPADDRESS:
+           case OPAQUE:
+           case NSAP:
+               vp->val.string = (u_char *)calloc(1, (unsigned)vp->val_len);
+               asn_parse_string(var_val, &len, &vp->type, vp->val.string, &vp->val_len);
+               break;
+           case ASN_OBJECT_ID:
+               vp->val_len = MAX_NAME_LEN;
+               asn_parse_objid(var_val, &len, &vp->type, objid, &vp->val_len);
+               vp->val_len *= sizeof(oid);
+               vp->val.objid = (oid *)calloc(1, (unsigned)vp->val_len);
+               bcopy((char *)objid, (char *)vp->val.objid, vp->val_len);
+               break;
+            case SNMP_NOSUCHOBJECT:
+            case SNMP_NOSUCHINSTANCE:
+            case SNMP_ENDOFMIBVIEW:
+           case ASN_NULL:
+               break;
+           default:
+               fprintf(stderr, "bad type returned (%x)\n", vp->type);
+               break;
+       }
+    }
+    return ret;
+}
+
+/*
+ * 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(session, pdu)
+    struct snmp_session *session;
+    struct snmp_pdu    *pdu;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp = NULL;
+    u_char  packet[PACKET_LENGTH];
+    int length = PACKET_LENGTH;
+    struct request_list *rp;
+    struct timeval tv;
+
+    for(slp = Sessions; slp; slp = slp->next){
+       if (slp->session == session){
+           isp = slp->internal;
+           break;
+       }
+    }
+
+    if (! pdu) {
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+
+    if (isp == NULL){
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG
+       || pdu->command == GET_RSP_MSG || pdu->command == SET_REQ_MSG 
+       || pdu->command == GETBULK_REQ_MSG ){
+       if (pdu->reqid == SNMP_DEFAULT_REQID)
+           pdu->reqid = ++Reqid;
+       if (pdu->errstat == SNMP_DEFAULT_ERRSTAT)
+           pdu->errstat = 0;
+       if (pdu->errindex == SNMP_DEFAULT_ERRINDEX)
+           pdu->errindex = 0;
+    } else {
+       /* fill in trap defaults */
+       pdu->reqid = 1; /* give a bogus non-error reqid for traps */
+       if (pdu->enterprise_length == SNMP_DEFAULT_ENTERPRISE_LENGTH){
+           pdu->enterprise = (oid *)calloc(1, sizeof(DEFAULT_ENTERPRISE));
+           bcopy((char *)DEFAULT_ENTERPRISE, (char *)pdu->enterprise, sizeof(DEFAULT_ENTERPRISE));
+           pdu->enterprise_length = sizeof(DEFAULT_ENTERPRISE)/sizeof(oid);
+       }
+       if (pdu->time == SNMP_DEFAULT_TIME)
+           pdu->time = DEFAULT_TIME;
+    }
+    if (pdu->address.sin_addr.s_addr == SNMP_DEFAULT_ADDRESS){
+       if (isp->addr.sin_addr.s_addr != SNMP_DEFAULT_ADDRESS){
+           bcopy((char *)&isp->addr, (char *)&pdu->address, sizeof(pdu->address));
+       } else {
+           fprintf(stderr, "No remote IP address specified\n");
+           snmp_errno = SNMPERR_BAD_ADDRESS;
+           return 0;
+       }
+    }
+       
+
+    if (snmp_build(session, pdu, packet, &length, 0) < 0){
+       fprintf(stderr, "Error building packet\n");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+#if 1 /***/
+    if (snmp_dump_packet){
+      snmp_print_packet(packet, length, pdu->address, 1);
+    }
+#endif /***/
+
+    gettimeofday(&tv, (struct timezone *)0);
+    if (sendto(isp->sd, (char *)packet, length, 0, (struct sockaddr *)&pdu->address, sizeof(pdu->address)) < 0){
+       perror("sendto");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG 
+     || pdu->command == SET_REQ_MSG || pdu->command == GETBULK_REQ_MSG ){
+       /* set up to expect a response */
+       rp = (struct request_list *)calloc(1, sizeof(struct request_list));
+#if 1 /***/
+        if(! rp){
+          fprintf(stderr, "Out of memory!\n");
+          snmp_errno = SNMPERR_GENERR;
+          return 0;
+        }
+#endif /***/
+       rp->next_request = isp->requests;
+       isp->requests = rp;
+       rp->pdu = pdu;
+       rp->request_id = pdu->reqid;
+
+       rp->retries = 1;
+       rp->timeout = session->timeout;
+       rp->time = tv;
+       tv.tv_usec += rp->timeout;
+       tv.tv_sec += tv.tv_usec / 1000000L;
+       tv.tv_usec %= 1000000L;
+       rp->expire = tv;
+#if DEBUG_SNMPTRACE
+       snmp_print_trace(slp, rp, TRACE_SEND);
+#endif
+    }
+    return pdu->reqid;
+}
+
+/*
+ * Frees the pdu and any malloc'd data associated with it.
+ */
+void
+snmp_free_pdu(struct snmp_pdu * pdu)
+{
+    struct variable_list *vp, *ovp;
+
+    if (! pdu)
+      return;
+
+    vp = pdu->variables;
+    while(vp){
+      if (vp->name) {
+       free((char *)vp->name);
+      }
+      if (vp->val.string) {
+       free((char *)vp->val.string);
+      }
+      ovp = vp;
+      vp = vp->next_variable;
+      free((char *)ovp);
+    }
+    if (pdu->enterprise) {
+      free((char *)pdu->enterprise);
+    }
+    free((char *)pdu);
+}
+
+
+/*
+ * 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(fdset)
+    fd_set  *fdset;
+{
+    struct session_list *slp;
+    struct snmp_session *sp;
+    struct snmp_internal_session *isp;
+    u_char packet[PACKET_LENGTH];
+    struct sockaddr_in from;
+    ssize_t length, fromlength;
+    struct snmp_pdu *pdu;
+    struct request_list *rp /**, *orp **/ ;
+
+    for(slp = Sessions; slp; slp = slp->next){
+       if (FD_ISSET(slp->internal->sd, fdset)){
+           sp = slp->session;
+           isp = slp->internal;
+           fromlength = sizeof(from);
+           length = recvfrom(isp->sd, (char *)packet, PACKET_LENGTH, 0, (struct sockaddr *)&from, &fromlength);
+           if (length == -1) {
+               perror("recvfrom");
+               return;
+           }
+#if 1 /***/
+           if (snmp_dump_packet){
+             snmp_print_packet(packet, length, from, 0);
+           }
+           pdu = (struct snmp_pdu *)calloc(1, sizeof(struct snmp_pdu));
+
+           if(! pdu){
+             fprintf(stderr, "Out of memory!\n");
+             snmp_errno = SNMPERR_GENERR;
+             return;
+           }
+#endif /***/
+
+           pdu->address = from;
+           pdu->reqid = 0;
+           pdu->variables = NULL;
+           pdu->enterprise = NULL;
+           pdu->enterprise_length = 0;
+           if (snmp_parse(sp, pdu, packet, length) < 0){
+               fprintf(stderr, "Mangled packet\n");
+               snmp_free_pdu(pdu);
+               return;
+           }
+
+           if (pdu->command == GET_RSP_MSG || pdu->command == REPORT_MSG){
+#if 1 /***/ /* bug fix: illegal re-use of rp killed some requests */
+             struct request_list *rp_next= 0;
+             for(rp = isp->requests; rp; rp = rp_next){
+               rp_next = rp->next_request;
+               if (rp->request_id == pdu->reqid){
+#if DEBUG_SNMPTRACE
+                 snmp_print_trace(slp, rp, TRACE_RECV);
+#endif
+                 if (sp->callback(RECEIVED_MESSAGE, sp, pdu->reqid, pdu, sp->callback_magic) == 1){
+                   /* successful, so delete request */
+                   free_one_request(isp, rp);
+                   break;  /* no more request with the same reqid */
+                 }
+               }
+             }
+#endif /***/
+           } else if (pdu->command == GET_REQ_MSG 
+                   || pdu->command == GETNEXT_REQ_MSG
+                   || pdu->command == GETBULK_REQ_MSG
+                   || pdu->command == TRP_REQ_MSG || pdu->command == SET_REQ_MSG){
+#if DEBUG_SNMPTRACE
+             snmp_print_trace(slp, NULL, TRACE_RECV);
+#endif
+             sp->callback(RECEIVED_MESSAGE, sp, pdu->reqid, pdu, sp->callback_magic);
+           }
+           snmp_free_pdu(pdu);
+       }
+    }
+}
+
+/*
+ * 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(numfds, fdset, timeout, block)
+    int            *numfds;
+    fd_set  *fdset;
+    struct timeval *timeout;
+    int            *block; /* should the select block until input arrives (i.e. no input) */
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp;
+    struct request_list *rp;
+    struct timeval now, earliest;
+    int active = 0, requests = 0;
+
+    timerclear(&earliest);
+    /*
+     * For each request outstanding, add it's socket to the fdset,
+     * and if it is the earliest timeout to expire, mark it as lowest.
+     */
+    for(slp = Sessions; slp; slp = slp->next){
+       active++;
+       isp = slp->internal;
+       if ((isp->sd + 1) > *numfds)
+           *numfds = (isp->sd + 1);
+       FD_SET(isp->sd, fdset);
+       if (isp->requests){
+           /* found another session with outstanding requests */
+           requests++;
+           for(rp = isp->requests; rp; rp = rp->next_request){
+               if (!timerisset(&earliest) || timercmp(&rp->expire, &earliest, <))
+                   earliest = rp->expire;
+           }
+       }
+    }
+    if (requests == 0) /* if none are active, skip arithmetic */
+       return active;
+
+    /*
+     * Now find out how much time until the earliest timeout.  This
+     * transforms earliest from an absolute time into a delta time, the
+     * time left until the select should timeout.
+     */
+    gettimeofday(&now, (struct timezone *)0);
+    earliest.tv_sec--; /* adjust time to make arithmetic easier */
+    earliest.tv_usec += 1000000L;
+    earliest.tv_sec -= now.tv_sec;
+    earliest.tv_usec -= now.tv_usec;
+    while (earliest.tv_usec >= 1000000L){
+       earliest.tv_usec -= 1000000L;
+       earliest.tv_sec += 1;
+    }
+    if (earliest.tv_sec < 0){
+       earliest.tv_sec = 0;
+       earliest.tv_usec = 0;
+    }
+
+    /* if it was blocking before or our delta time is less, reset timeout */
+    if (*block == 1 || timercmp(&earliest, timeout, <)){
+       *timeout = earliest;
+       *block = 0;
+    }
+    return active;
+}
+
+/* 
+ * 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()
+{
+    struct session_list *slp;
+    struct snmp_session *sp;
+    struct snmp_internal_session *isp;
+#if 1 /***/ /* replacing freeme by simpler and safer rp_next*/
+    struct request_list *rp, *rp_next = 0;
+#endif /***/
+    struct timeval now;
+
+    gettimeofday(&now, (struct timezone *)0);
+    /*
+     * For each request outstanding, check to see if it has expired.
+     */
+    for(slp = Sessions; slp; slp = slp->next){
+       sp = slp->session;
+       isp = slp->internal;
+#if 1 /***/ /* simplification */
+       for(rp = isp->requests; rp; rp = rp_next){
+           rp_next = rp->next_request;
+           if (timercmp(&rp->expire, &now, <)){
+               /* this timer has expired */
+               if (rp->retries >= sp->retries){
+#if DEBUG_SNMPTRACE
+                 snmp_print_trace(slp, rp, TRACE_TIMEOUT);
+#endif
+                 /* No more chances, delete this entry */
+                 sp->callback(TIMED_OUT, sp, rp->pdu->reqid, rp->pdu, sp->callback_magic);
+                 free_one_request(isp, rp);
+                 continue;
+#endif /***/
+               } else {
+                   u_char  packet[PACKET_LENGTH];
+                   int length = PACKET_LENGTH;
+                   struct timeval tv;
+
+                   /* retransmit this pdu */
+                   rp->retries++;
+                   rp->timeout <<= 1;
+                   if (snmp_build(sp, rp->pdu, packet, &length, 0) < 0){
+                       fprintf(stderr, "Error building packet\n");
+                   }
+#if 1 /***/
+                   if (snmp_dump_packet){
+                     snmp_print_packet(packet, length, rp->pdu->address, 1);
+                   }
+#endif /***/
+                       gettimeofday(&tv, (struct timezone *) 0);
+                   if (sendto(isp->sd, (char *) packet, length, 0, (struct sockaddr *) &rp->pdu->address, sizeof(rp->pdu->address)) < 0) {
+                       perror("sendto");
+                   }
+                   rp->time = tv;
+                   tv.tv_usec += rp->timeout;
+                   tv.tv_sec += tv.tv_usec / 1000000L;
+                   tv.tv_usec %= 1000000L;
+                   rp->expire = tv;
+#if DEBUG_SNMPTRACE
+                   snmp_print_trace(slp, rp, TRACE_SEND);
+#endif
+               }
+           }
+#if 1 /***/                    /* simplification */
+       }
+#endif/***/ mplification */by simpler and safer rp_next*/n s */ replace...
+     */
+ * \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 1\ 1\0\0\0\0\0\0\0\19\7fÿ¯ùsnmplib/snmp_api.c\0c\0\0.h\0\0\0\18\7fÿ°\85\10\0<Ðlib/snmp_api.c~\0~\0\0ñ\0\0\0\18\7fÿ±\1e\10\0\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\0\0\0\18\7fÿ±«\10\0=\10\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\0\0\0\18\7fÿ²\1d\10\0=0\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\0\0\0\18\7fÿ²\8a\10\0=P\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\0\0\0\18\7fÿ³
+\10\0=p\7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\0\0\0\18\7fÿ³\82\0\0\0\ 1\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\0\0\0Á\7fÿ³ù\0\0\0\10\7fÿ´\10\10\0\0%\0\19\0\15\0\0\10\0D(\0\0\0\10\7fÿ´_\10\0\0\0\ 2\\0\0\0\0\10\0\0\0\0\10\7fÿ´©\10\0=\98\0\0\ 24\0\0\0\0\10\0\0\0\0\10\7fÿ´ø\10\0\0\0\ 2H\0\0\0\0\10\0\0\0\0\10\7fÿµB\10\0>\10\7fÿµ]\7fÿµm\7fÿµz\0\0\0\10\7fÿµ \10\0>(\7fÿµ·\7fÿµÉ\7fÿµÖ\0\0\0\10\7fÿµï\10\0>@\7fÿ¶\12\7fÿ¶ \7fÿ¶4\0\0\0\10\7fÿ¶P\0\0\0\ 1\7fÿ¶r\7fÿ¶~\7fÿ¶\88\0\0\00\7fÿ¶\9f\0\0\0\0\7fÿ¶·\0\0\0\0\7fÿ¶Ù\10\0\82à\7fÿ·\ 1\0\0\0\0\7fÿ·#\7fÿ·/\7fÿ·>\10\0>X\7fÿ·V\0\0\03\0\0\0\0/usr/people/wessels/.indent.pro\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\ 1\0\0\0\0\7fÿ¯è\7fÿ¯ù\7fÿ°\f\7fÿ°\e\7fÿ°.\7fÿ°?\7fÿ°M\7fÿ°[\7fÿ°p\7fÿ°\85\7fÿ°\95\7fÿ°£\7fÿ°²\7fÿ°Å\7fÿ°Û\7fÿ°ñ\7fÿ±
+\7fÿ±\1e\7fÿ±2\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\7fÿ±\99\7fÿ±«\7fÿ±º\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\7fÿ²\ f\7fÿ²\1d\7fÿ²2\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\7fÿ²\7f\7fÿ²\8a\7fÿ²\99\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\7fÿ²ö\7fÿ³
+\7fÿ³ \7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\7fÿ³s\7fÿ³\82\7fÿ³\91\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\7fÿ³ç\7fÿ³ù\7fÿ´\ 4\7fÿ´\10\7fÿ´\1e\7fÿ´)\7fÿ´3\7fÿ´C\7fÿ´O\7fÿ´_\7fÿ´k\7fÿ´t\7fÿ´\81\7fÿ´\8f\7fÿ´\9f\7fÿ´©\7fÿ´·\7fÿ´Å\7fÿ´Ò\7fÿ´Ý\7fÿ´í\7fÿ´ø\7fÿµ\ 3\7fÿµ\10\7fÿµ\1d\7fÿµ)\7fÿµ7\7fÿµB\7fÿµM\7fÿµ]\7fÿµm\7fÿµz\7fÿµ\89\7fÿµ \7fÿµ«\7fÿµ·\7fÿµÉ\7fÿµÖ\7fÿµâ\7fÿµï\7fÿ¶\ 3\7fÿ¶\12\7fÿ¶ \7fÿ¶4\7fÿ¶?\7fÿ¶P\7fÿ¶b\7fÿ¶r\7fÿ¶~\7fÿ¶\88\7fÿ¶\94\7fÿ¶\9f\7fÿ¶«\7fÿ¶·\7fÿ¶É\7fÿ¶Ù\7fÿ¶í\7fÿ·\ 1\7fÿ·\15\7fÿ·#\7fÿ·/\7fÿ·>\7fÿ·L\7fÿ·V\7fÿ·f\7fÿ·q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0@    \0\0\0\0000000L;
+       earliest.tv_sec += 1;
+    }
+    if (earliest.tv_sec < 0){
+       earliest.tv_sec = 0;
+       earliest.tv_usec = 0;
+    }
+
+    /* if it was blocking before or our delta time is less, reset timeout */
+    if (*block == 1 || timercmp(&earliest, timeout, <)){
+       *timeout = earliest;
+       *block = 0;
+    }
+    return active;
+}
+
+/* 
+ * 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()
+{
+    struct session_list *slp;
+    struct snmp_session *sp;
+    struct snmp_internal_session *isp;
+#if 1 /***/ /* replacing freeme by simpler and safer rp_next*/
+    struct request_list *rp, *rp_next = 0;
+#endif /***/
+    struct timeval now;
+
+    gettimeofday(&now, (struct timezone *)0);
+    /*
+     * For each request outstanding, check to see if it has expired.
+     */
+    for(slp = Sessions; slp; slp = slp->next){
+       sp = slp->session;
+       isp = slp->internal;
+#if 1 /***/ /* simplification */
+       for(rp = isp->requests; rp; rp = rp_next){
+           rp_next = rp->next_request;
+           if (timercmp(&rp->expire, &now, <)){
+               /* this timer has expired */
+               if (rp->retries >= sp->retries){
+#if DEBUG_SNMPTRACE
+                 snmp_print_trace(slp, rp, TRACE_TIMEOUT);
+#endif
+                 /* No more chances, delete this entry */
+                 sp->callback(TIMED_OUT, sp, rp->pdu->reqid, rp->pdu, sp->callback_magic);
+                 free_one_request(isp, rp);
+                 continue;
+#endif /***/
+               } else {
+                   u_char  packet[PACKET_LENGTH];
+                   int length = PACKET_LENGTH;
+                   struct timeval tv;
+
+                   /* retransmit this pdu */
+                   rp->retries++;
+                   rp->timeout <<= 1;
+                   if (snmp_build(sp, rp->pdu, packet, &length, 0) < 0){
+                       fprintf(stderr, "Error building packet\n");
+                   }
+#if 1 /***/
+                   if (snmp_dump_packet){
+                     snmp_print_packet(packet, length, rp->pdu->address, 1);
+                   }
+#endif /***/
+                       gettimeofday(&tv, (struct timezone *) 0);
+                   if (sendto(isp->sd, (char *) packet, length, 0, (struct sockaddr *) &rp->pdu->address, sizeof(rp->pdu->address)) < 0) {
+                       perror("sendto");
+                   }
+                   rp->time = tv;
+                   tv.tv_usec += rp->timeout;
+                   tv.tv_sec += tv.tv_usec / 1000000L;
+                   tv.tv_usec %= 1000000L;
+                   rp->expire = tv;
+#if DEBUG_SNMPTRACE
+                   snmp_print_trace(slp, rp, TRACE_SEND);
+#endif
+               }
+           }
+#if 1 /***/                    /* simplification */
+       }
+ata = data;
+    int      origlength = length;
+    int      ret = 0;
+    u_char  *save_data;
+
+    /* authenticates message and returns length if valid */
+    data = snmp_auth_parse(data, &length, community, &community_length, &version);
+    if (data == NULL)
+       return -1;
+
+   if( version != SNMP_VERSION_1 && version != SNMP_VERSION_2C && version != SNMP_VERSION_2 ) {
+           fprintf(stderr, "Wrong version: %ld\n", version);
+           return -1;
+    }
+
+    save_data = data;
+
+    data = asn_parse_header(data, &length, &msg_type);
+    if (data == NULL)
+       return -1;
+    pdu->command = msg_type;
+
+    if( session->authenticator ) {
+       ret = session->authenticator( origdata, origlength, save_data - community_length, 
+               community_length, session, pdu );
+       if( ret < 0 ) return ret;
+    }
+
+    if (pdu->command != TRP_REQ_MSG){
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->reqid, sizeof(pdu->reqid));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errstat, sizeof(pdu->errstat));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->errindex, sizeof(pdu->errindex));
+       if (data == NULL)
+           return -1;
+    } else {
+       pdu->enterprise_length = MAX_NAME_LEN;
+       data = asn_parse_objid(data, &length, &type, objid, &pdu->enterprise_length);
+       if (data == NULL)
+           return -1;
+       pdu->enterprise = (oid *)calloc(1, pdu->enterprise_length * sizeof(oid));
+       bcopy((char *)objid, (char *)pdu->enterprise, pdu->enterprise_length * sizeof(oid));
+
+       four = 4;
+       data = asn_parse_string(data, &length, &type, (u_char *)&pdu->agent_addr.sin_addr.s_addr, &four);
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->trap_type, sizeof(pdu->trap_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->specific_type, sizeof(pdu->specific_type));
+       if (data == NULL)
+           return -1;
+       data = asn_parse_int(data, &length, &type, (long *)&pdu->time, sizeof(pdu->time));
+       if (data == NULL)
+           return -1;
+    }
+    data = asn_parse_header(data, &length, &type);
+    if (data == NULL)
+       return -1;
+    if (type != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR))
+       return -1;
+    while((int)length > 0){
+       if (pdu->variables == NULL){
+           pdu->variables = vp = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+       } else {
+           vp->next_variable = (struct variable_list *)calloc(1, sizeof(struct variable_list));
+           vp = vp->next_variable;
+       }
+       vp->next_variable = NULL;
+       vp->val.string = NULL;
+       vp->name = NULL;
+       vp->name_length = MAX_NAME_LEN;
+       data = snmp_parse_var_op(data, objid, &vp->name_length, &vp->type, &vp->val_len, &var_val, (int *)&length);
+       if (data == NULL)
+           return -1;
+       op = (oid *)calloc(1, (unsigned)vp->name_length * sizeof(oid));
+       bcopy((char *)objid, (char *)op, vp->name_length * sizeof(oid));
+       vp->name = op;
+
+       len = PACKET_LENGTH;
+       switch((short)vp->type){
+           case ASN_INTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(long));
+               vp->val_len = sizeof(long);
+               asn_parse_int(var_val, &len, &vp->type, (long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER:
+           case GAUGE:
+           case TIMETICKS:
+           case UINTEGER:
+               vp->val.integer = (long *)calloc(1, sizeof(unsigned long));
+               vp->val_len = sizeof(unsigned long);
+               asn_parse_unsigned_int(var_val, &len, &vp->type, (unsigned long *)vp->val.integer, sizeof(vp->val.integer));
+               break;
+           case COUNTER64:
+               vp->val.counter64 = (struct counter64 *)calloc(1,  sizeof(struct counter64) );
+               vp->val_len = sizeof(struct counter64);
+               asn_parse_unsigned_int64(var_val, &len, &vp->type,
+                                        (struct counter64 *)vp->val.counter64,
+                                        sizeof(*vp->val.counter64));
+               break;
+           case ASN_OCTET_STR:
+           case IPADDRESS:
+           case OPAQUE:
+           case NSAP:
+               vp->val.string = (u_char *)calloc(1, (unsigned)vp->val_len);
+               asn_parse_string(var_val, &len, &vp->type, vp->val.string, &vp->val_len);
+               break;
+           case ASN_OBJECT_ID:
+               vp->val_len = MAX_NAME_LEN;
+               asn_parse_objid(var_val, &len, &vp->type, objid, &vp->val_len);
+               vp->val_len *= sizeof(oid);
+               vp->val.objid = (oid *)calloc(1, (unsigned)vp->val_len);
+               bcopy((char *)objid, (char *)vp->val.objid, vp->val_len);
+               break;
+            case SNMP_NOSUCHOBJECT:
+            case SNMP_NOSUCHINSTANCE:
+            case SNMP_ENDOFMIBVIEW:
+           case ASN_NULL:
+               break;
+           default:
+               fprintf(stderr, "bad type returned (%x)\n", vp->type);
+               break;
+       }
+    }
+    return ret;
+}
+
+/*
+ * 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(session, pdu)
+    struct snmp_session *session;
+    struct snmp_pdu    *pdu;
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp = NULL;
+    u_char  packet[PACKET_LENGTH];
+    int length = PACKET_LENGTH;
+    struct request_list *rp;
+    struct timeval tv;
+
+    for(slp = Sessions; slp; slp = slp->next){
+       if (slp->session == session){
+           isp = slp->internal;
+           break;
+       }
+    }
+
+    if (! pdu) {
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+
+    if (isp == NULL){
+       snmp_errno = SNMPERR_BAD_SESSION;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG
+       || pdu->command == GET_RSP_MSG || pdu->command == SET_REQ_MSG 
+       || pdu->command == GETBULK_REQ_MSG ){
+       if (pdu->reqid == SNMP_DEFAULT_REQID)
+           pdu->reqid = ++Reqid;
+       if (pdu->errstat == SNMP_DEFAULT_ERRSTAT)
+           pdu->errstat = 0;
+       if (pdu->errindex == SNMP_DEFAULT_ERRINDEX)
+           pdu->errindex = 0;
+    } else {
+       /* fill in trap defaults */
+       pdu->reqid = 1; /* give a bogus non-error reqid for traps */
+       if (pdu->enterprise_length == SNMP_DEFAULT_ENTERPRISE_LENGTH){
+           pdu->enterprise = (oid *)calloc(1, sizeof(DEFAULT_ENTERPRISE));
+           bcopy((char *)DEFAULT_ENTERPRISE, (char *)pdu->enterprise, sizeof(DEFAULT_ENTERPRISE));
+           pdu->enterprise_length = sizeof(DEFAULT_ENTERPRISE)/sizeof(oid);
+       }
+       if (pdu->time == SNMP_DEFAULT_TIME)
+           pdu->time = DEFAULT_TIME;
+    }
+    if (pdu->address.sin_addr.s_addr == SNMP_DEFAULT_ADDRESS){
+       if (isp->addr.sin_addr.s_addr != SNMP_DEFAULT_ADDRESS){
+           bcopy((char *)&isp->addr, (char *)&pdu->address, sizeof(pdu->address));
+       } else {
+           fprintf(stderr, "No remote IP address specified\n");
+           snmp_errno = SNMPERR_BAD_ADDRESS;
+           return 0;
+       }
+    }
+       
+
+    if (snmp_build(session, pdu, packet, &length, 0) < 0){
+       fprintf(stderr, "Error building packet\n");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+#if 1 /***/
+    if (snmp_dump_packet){
+      snmp_print_packet(packet, length, pdu->address, 1);
+    }
+#endif /***/
+
+    gettimeofday(&tv, (struct timezone *)0);
+    if (sendto(isp->sd, (char *)packet, length, 0, (struct sockaddr *)&pdu->address, sizeof(pdu->address)) < 0){
+       perror("sendto");
+       snmp_errno = SNMPERR_GENERR;
+       return 0;
+    }
+    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG 
+     || pdu->command == SET_REQ_MSG || pdu->command == GETBULK_REQ_MSG ){
+       /* set up to expect a response */
+       rp = (struct request_list *)calloc(1, sizeof(struct request_list));
+#if 1 /***/
+        if(! rp){
+          fprintf(stderr, "Out of memory!\n");
+          snmp_errno = SNMPERR_GENERR;
+          return 0;
+        }
+#endif /***/
+       rp->next_request = isp->requests;
+       isp->requests = rp;
+       rp->pdu = pdu;
+       rp->request_id = pdu->reqid;
+
+       rp->retries = 1;
+       rp->timeout = session->timeout;
+       rp->time = tv;
+       tv.tv_usec += rp->timeout;
+       tv.tv_sec += tv.tv_usec / 1000000L;
+       tv.tv_usec %= 1000000L;
+       rp->expire = tv;
+#if DEBUG_SNMPTRACE
+       snmp_print_trace(slp, rp, TRACE_SEND);
+#endif
+    }
+    return pdu->reqid;
+}
+
+/*
+ * Frees the pdu and any malloc'd data associated with it.
+ */
+void
+snmp_free_pdu(struct snmp_pdu * pdu)
+{
+    struct variable_list *vp, *ovp;
+
+    if (! pdu)
+      return;
+
+    vp = pdu->variables;
+    while(vp){
+      if (vp->name) {
+       free((char *)vp->name);
+      }
+      if (vp->val.string) {
+       free((char *)vp->val.string);
+      }
+      ovp = vp;
+      vp = vp->next_variable;
+      free((char *)ovp);
+    }
+    if (pdu->enterprise) {
+      free((char *)pdu->enterprise);
+    }
+    free((char *)pdu);
+}
+
+
+/*
+ * 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(fdset)
+    fd_set  *fdset;
+{
+    struct session_list *slp;
+    struct snmp_session *sp;
+    struct snmp_internal_session *isp;
+    u_char packet[PACKET_LENGTH];
+    struct sockaddr_in from;
+    ssize_t length, fromlength;
+    struct snmp_pdu *pdu;
+    struct request_list *rp /**, *orp **/ ;
+
+    for(slp = Sessions; slp; slp = slp->next){
+       if (FD_ISSET(slp->internal->sd, fdset)){
+           sp = slp->session;
+           isp = slp->internal;
+           fromlength = sizeof(from);
+           length = recvfrom(isp->sd, (char *)packet, PACKET_LENGTH, 0, (struct sockaddr *)&from, &fromlength);
+           if (length == -1) {
+               perror("recvfrom");
+               return;
+           }
+#if 1 /***/
+           if (snmp_dump_packet){
+             snmp_print_packet(packet, length, from, 0);
+           }
+           pdu = (struct snmp_pdu *)calloc(1, sizeof(struct snmp_pdu));
+
+           if(! pdu){
+             fprintf(stderr, "Out of memory!\n");
+             snmp_errno = SNMPERR_GENERR;
+             return;
+           }
+#endif /***/
+
+           pdu->address = from;
+           pdu->reqid = 0;
+           pdu->variables = NULL;
+           pdu->enterprise = NULL;
+           pdu->enterprise_length = 0;
+           if (snmp_parse(sp, pdu, packet, length) < 0){
+               fprintf(stderr, "Mangled packet\n");
+               snmp_free_pdu(pdu);
+               return;
+           }
+
+           if (pdu->command == GET_RSP_MSG || pdu->command == REPORT_MSG){
+#if 1 /***/ /* bug fix: illegal re-use of rp killed some requests */
+             struct request_list *rp_next= 0;
+             for(rp = isp->requests; rp; rp = rp_next){
+               rp_next = rp->next_request;
+               if (rp->request_id == pdu->reqid){
+#if DEBUG_SNMPTRACE
+                 snmp_print_trace(slp, rp, TRACE_RECV);
+#endif
+                 if (sp->callback(RECEIVED_MESSAGE, sp, pdu->reqid, pdu, sp->callback_magic) == 1){
+                   /* successful, so delete request */
+                   free_one_request(isp, rp);
+                   break;  /* no more request with the same reqid */
+                 }
+               }
+             }
+#endif /***/
+           } else if (pdu->command == GET_REQ_MSG 
+                   || pdu->command == GETNEXT_REQ_MSG
+                   || pdu->command == GETBULK_REQ_MSG
+                   || pdu->command == TRP_REQ_MSG || pdu->command == SET_REQ_MSG){
+#if DEBUG_SNMPTRACE
+             snmp_print_trace(slp, NULL, TRACE_RECV);
+#endif
+             sp->callback(RECEIVED_MESSAGE, sp, pdu->reqid, pdu, sp->callback_magic);
+           }
+           snmp_free_pdu(pdu);
+       }
+    }
+}
+
+/*
+ * 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(numfds, fdset, timeout, block)
+    int            *numfds;
+    fd_set  *fdset;
+    struct timeval *timeout;
+    int            *block; /* should the select block until input arrives (i.e. no input) */
+{
+    struct session_list *slp;
+    struct snmp_internal_session *isp;
+    struct request_list *rp;
+    struct timeval now, earliest;
+    int active = 0, requests = 0;
+
+    timerclear(&earliest);
+    /*
+     * For each request outstanding, add it's socket to the fdset,
+     * and if it is the earliest timeout to expire, mark it as lowest.
+     */
+    for(slp = Sessions; slp; slp = slp->next){
+       active++;
+       isp = slp->internal;
+       if ((isp->sd + 1) > *numfds)
+           *numfds = (isp->sd + 1);
+       FD_SET(isp->sd, fdset);
+       if (isp->requests){
+           /* found another session with outstanding requests */
+           requests++;
+           for(rp = isp->requests; rp; rp = rp->next_request){
+               if (!timerisset(&earliest) || timercmp(&rp->expire, &earliest, <))
+                   earliest = rp->expire;
+           }
+       }
+    }
+    if (requests == 0) /* if none are active, skip arithmetic */
+       return active;
+
+    /*
+     * Now find out how much time until the earliest timeout.  This
+     * transforms earliest from an absolute time into a delta time, the
+     * time left until the select should timeout.
+     */
+    gettimeofday(&now, (struct timezone *)0);
+    earliest.tv_sec--; /* adjust time to make arithmetic easier */
+    earliest.tv_usec += 1000000L;
+    earliest.tv_sec -= now.tv_sec;
+    earliest.tv_usec -= now.tv_usec;
+    while (earliest.tv_usec >= 1000000L){
+       earliest.tv_usec -= 1\10\0BÐ+= m\0\0
+È      /* \10\0>X*/ B\10\04¨NMPT\10\ 1í\88 */c\0\0\0\0for testing purposes */e key!  replace...
+     */
+ * \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 1\ 1\0\0\0\0\0\0\0\19\7fÿ¯ùsnmplib/snmp_api.c\0c\0\0.h\0\0\0\18\7fÿ°\85\10\0<Ðlib/snmp_api.c~\0~\0\0ñ\0\0\0\18\7fÿ±\1e\10\0\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\0\0\0\18\7fÿ±«\10\0=\10\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\0\0\0\18\7fÿ²\1d\10\0=0\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\0\0\0\18\7fÿ²\8a\10\0=P\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\0\0\0\18\7fÿ³
+\10\0=p\7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\0\0\0\18\7fÿ³\82\0\0\0\ 1\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\0\0\0Á\7fÿ³ù\0\0\0\10\7fÿ´\10\10\0\0%\0\19\0\15\0\0\10\0D(\0\0\0\10\7fÿ´_\10\0\0\0\ 2\\0\0\0\0\10\0\0\0\0\10\7fÿ´©\10\0=\98\0\0\ 24\0\0\0\0\10\0\0\0\0\10\7fÿ´ø\10\0\0\0\ 2H\0\0\0\0\10\0\0\0\0\10\7fÿµB\10\0>\10\7fÿµ]\7fÿµm\7fÿµz\0\0\0\10\7fÿµ \10\0>(\7fÿµ·\7fÿµÉ\7fÿµÖ\0\0\0\10\7fÿµï\10\0>@\7fÿ¶\12\7fÿ¶ \7fÿ¶4\0\0\0\10\7fÿ¶P\0\0\0\ 1\7fÿ¶r\7fÿ¶~\7fÿ¶\88\0\0\00\7fÿ¶\9f\10\0\7fÿ¶·\0\0\0\0\7fÿ¶Ù\10\0\89è\7fÿ·\ 1\0\0\0\0\7fÿ·#\7fÿ·/\7fÿ·>\10\0>X\7fÿ·V\0\0\03\0\0\0\0/usr/people/wessels/.indent.pro\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\ 1\0\0\0\0\7fÿ¯è\7fÿ¯ù\7fÿ°\f\7fÿ°\e\7fÿ°.\7fÿ°?\7fÿ°M\7fÿ°[\7fÿ°p\7fÿ°\85\7fÿ°\95\7fÿ°£\7fÿ°²\7fÿ°Å\7fÿ°Û\7fÿ°ñ\7fÿ±
+\7fÿ±\1e\7fÿ±2\7fÿ±F\7fÿ±Y\7fÿ±i\7fÿ±{\7fÿ±\8a\7fÿ±\99\7fÿ±«\7fÿ±º\7fÿ±Ç\7fÿ±Ó\7fÿ±é\7fÿ±÷\7fÿ²\ 1\7fÿ²\ f\7fÿ²\1d\7fÿ²2\7fÿ²<\7fÿ²K\7fÿ²W\7fÿ²f\7fÿ²t\7fÿ²\7f\7fÿ²\8a\7fÿ²\99\7fÿ²¨\7fÿ²¶\7fÿ²Ä\7fÿ²Ô\7fÿ²ã\7fÿ²ö\7fÿ³
+\7fÿ³ \7fÿ³3\7fÿ³B\7fÿ³S\7fÿ³]\7fÿ³i\7fÿ³s\7fÿ³\82\7fÿ³\91\7fÿ³ \7fÿ³­\7fÿ³º\7fÿ³Ê\7fÿ³×\7fÿ³ç\7fÿ³ù\7fÿ´\ 4\7fÿ´\10\7fÿ´\1e\7fÿ´)\7fÿ´3\7fÿ´C\7fÿ´O\7fÿ´_\7fÿ´k\7fÿ´t\7fÿ´\81\7fÿ´\8f\7fÿ´\9f\7fÿ´©\7fÿ´·\7fÿ´Å\7fÿ´Ò\7fÿ´Ý\7fÿ´í\7fÿ´ø\7fÿµ\ 3\7fÿµ\10\7fÿµ\1d\7fÿµ)\7fÿµ7\7fÿµB\7fÿµM\7fÿµ]\7fÿµm\7fÿµz\7fÿµ\89\7fÿµ \7fÿµ«\7fÿµ·\7fÿµÉ\7fÿµÖ\7fÿµâ\7fÿµï\7fÿ¶\ 3\7fÿ¶\12\7fÿ¶ \7fÿ¶4\7fÿ¶?\7fÿ¶P\7fÿ¶b\7fÿ¶r\7fÿ¶~\7fÿ¶\88\7fÿ¶\94\7fÿ¶\9f\7fÿ¶«\7fÿ¶·\7fÿ¶É\7fÿ¶Ù\7fÿ¶í\7fÿ·\ 1\7fÿ·\15\7fÿ·#\7fÿ·/\7fÿ·>\7fÿ·L\7fÿ·V\7fÿ·f\7fÿ·q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\0\0\0°\0\0\0\ 4\0\0\0\0\0\0\0\b\10\0>X\0\0\0\f\10\0\0\0\0\10\0\0\0\0\0\0\0\14\0\0\0\14\0\0\0\14\0\0\0\18\0\0\0\18\0\0\0\18\0\0\0\1c\0\0\0\1c\0\0\0\1c\0\0\0\1c\0\0\0 \0\0\0 \0\0\0 \0\0\0$\0\0\0\v\0\0\0\e\0\0\0\19\0\0\0\v\0\0\0\e\0\0\0@\0\0\0\0\0\0\0\0\0\0\0\0\10\0,\b\0\0\0\1a\10\02\88\0\0\0\1a\0\0\0\0\0\0\0\1a\10\0\85\b\0\0\0\0\10\0>X\0\0\0\0\0\0\0\0\0\0\0\0\10\0\82à\0\0\0\0\0\0\ 1C\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e0\0\0\0\v\0\0\0\e\0\0\0\18\0\0\0\v\0\0\0\1a\0\0\0\17\0\0\0\v\0\0\0 \0\0\0\0\10\0\8d¸ude/snmp_groupvars.h~\0\0\b\0\0\0\b\0\0\0 \0\0\0\0\10\0\8dàude/snmp_groupvars.h\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8eX\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e\80\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8e¨\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\10\0\8eÐ\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\0\0\0\ 1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\84©\0\0\0\0/***********************************************************
+       Copyright 1989 by Carnegie Mellon University
+
+                      All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the name of CMU not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
 CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
 CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
@@ -1149,5 +21573,3 @@ snmp_timeout()
 #endif /***/
     }
 }
-
-
index dbd6d43e77f1842b1b81bb01188934e564c39d56..73566b0dfba75b075751a89e92582c0e6a82c35e 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: acl.cc,v 1.119 1997/11/17 22:11:24 wessels Exp $
+ * $Id: acl.cc,v 1.120 1997/11/21 01:59:14 wessels Exp $
  *
  * DEBUG: section 28    Access Control
  * AUTHOR: Duane Wessels
@@ -1073,7 +1073,7 @@ aclMatchProxyAuth(struct _acl_proxy_auth *p, aclCheck_t * checklist)
     if ((passwd = strchr(sent_user, ':')) != NULL)
        *passwd++ = '\0';
     if (passwd == NULL) {
-        debug(28, 3) ("aclMatchProxyAuth: No passwd in auth blob\n");
+       debug(28, 3) ("aclMatchProxyAuth: No passwd in auth blob\n");
        return 0;
     }
     debug(28, 5) ("aclMatchProxyAuth: checking user %s\n", sent_user);
index 7272bd5ed91c761fedcaae3f8c2259d08dafa3c9..abc4b88f8e5d62d0fd86f7da7fd4191baf12bbae 100644 (file)
@@ -1,6 +1,7 @@
 
+
 /*
- * $Id: client.cc,v 1.41 1997/11/21 00:29:34 wessels Exp $
+ * $Id: client.cc,v 1.42 1997/11/21 01:59:15 wessels Exp $
  *
  * DEBUG: section 0     WWW Client
  * AUTHOR: Harvest Derived
index 4b53f3d3beca5651fe82e8d7eb2c63bc1523a371..38b6da419e66b7b1177934b9568d6c4ab54ab915 100644 (file)
@@ -195,7 +195,7 @@ typedef enum {
     ICP_UNUSED19,
     ICP_UNUSED20,
     ICP_MISS_NOFETCH,
-    ICP_DENIED,        
+    ICP_DENIED,
     ICP_HIT_OBJ,
     ICP_END
 } icp_opcode;
index 8f535a33a7f59e5225059b97db4b34b41ef4505e..d7ffd815a29e7b295366b7b4eb44fd54c04f6942 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: main.cc,v 1.193 1997/11/21 00:29:36 wessels Exp $
+ * $Id: main.cc,v 1.194 1997/11/21 01:59:16 wessels Exp $
  *
  * DEBUG: section 1     Startup and Main Loop
  * AUTHOR: Harvest Derived
@@ -404,7 +404,7 @@ serverConnectionsOpen(void)
        }
     }
 #ifdef SQUID_SNMP
-        initSquidSnmp();
+    initSquidSnmp();
 #endif
 
     clientdbInit();
@@ -572,7 +572,7 @@ mainInitialize(void)
     configured_once = 1;
 
 #ifdef SQUID_SNMP
-       init_snmp();
+    init_snmp();
 #endif
 }
 
index 88f65e12f2e4220d426434abc56e49920357261c..3ee2d679c7595f56175bd00de2585ce4ee4fb0ba 100644 (file)
@@ -239,8 +239,8 @@ extern PF icpHandleUdp;
 extern PF httpAccept;
 extern DEFER httpAcceptDefer;
 #ifdef SQUID_SNMP
-/*extern PF snmpHandleUdp;*/
-/*extern void initSquidSnmp();*/
+/*extern PF snmpHandleUdp; */
+/*extern void initSquidSnmp(); */
 #endif /* SQUID_SNMP */
 
 extern void icpSendERROR(int fd,