struct variable_list * snmp_var_clone(struct variable_list *Src) { struct variable_list *Dest; #ifdef DEBUG_VARS printf("VARS: Cloning.\n"); #endif Dest = (struct variable_list *) xmalloc(sizeof(struct variable_list)); if (Dest == NULL) { snmp_set_api_error(SNMPERR_OS_ERR); return (NULL); } #ifdef DEBUG_VARS printf("VARS: Copying entire variable list. (Size %d)\n", sizeof(struct variable_list)); #endif xmemcpy((char *) Dest, (char *) Src, sizeof(struct variable_list)); if (Src->name != NULL) { Dest->name = (oid *) xmalloc(Src->name_length * sizeof(oid)); if (Dest->name == NULL) { snmp_set_api_error(SNMPERR_OS_ERR); xfree(Dest); return (NULL); } #ifdef DEBUG_VARS printf("VARS: Copying name OID. (Size %d)\n", Src->name_length); #endif xmemcpy((char *) Dest->name, (char *) Src->name, Src->name_length * sizeof(oid)); } /* CISCO Catalyst 2900 returns NULL strings as data of length 0. */ if ((Src->val.string != NULL) && (Src->val_len)) { Dest->val.string = (u_char *) xmalloc(Src->val_len); if (Dest->val.string == NULL) { snmp_set_api_error(SNMPERR_OS_ERR); xfree(Dest->name); xfree(Dest); return (NULL); } #ifdef DEBUG_VARS printf("VARS: Copying value (Size %d)\n", Src->val_len); #endif xmemcpy((char *) Dest->val.string, (char *) Src->val.string, Src->val_len); } #ifdef DEBUG_VARS printf("VARS: Cloned %x.\n", (unsigned int) Dest); #endif #ifdef DEBUG_VARS_MALLOC printf("VARS: Cloned (%x)\n", (unsigned int) Dest); printf("VARS: Name is (%x)\n", (unsigned int) Dest->name); #endif return (Dest); }
/* * RFC 1908: Coexistence between SNMPv1 and SNMPv2 * * These convert: * * V1 PDUs from an ** AGENT ** to V2 PDUs for an ** MANAGER ** * V2 PDUs from an ** MANAGER ** to V1 PDUs for an ** AGENT ** * * We will never convert V1 information from a manager into V2 PDUs. V1 * requests are always honored by V2 agents, and the responses will be * valid V1 responses. (I think. XXXXX) * */ int snmp_coexist_V2toV1(struct snmp_pdu *PDU) { /* Per 3.1.1: */ switch (PDU->command) { case SNMP_PDU_GET: case SNMP_PDU_GETNEXT: #if SNMP_PDU_SET case SNMP_PDU_SET: #endif return (1); break; case SNMP_PDU_GETBULK: PDU->non_repeaters = 0; PDU->max_repetitions = 0; PDU->command = SNMP_PDU_GETNEXT; return (1); break; default: snmplib_debug(2, "Unable to translate PDU %d to SNMPv1!\n", PDU->command); snmp_set_api_error(SNMPERR_PDU_TRANSLATION); return (0); } }
struct variable_list * snmp_var_new(oid * Name, int Len) { struct variable_list *New; #ifdef DEBUG_VARS printf("VARS: Creating.\n"); #endif New = xmalloc(sizeof(*New)); /* XXX xmalloc never returns NULL */ if (New == NULL) { snmp_set_api_error(SNMPERR_OS_ERR); return (NULL); } memset(New, '\0', sizeof(struct variable_list)); /* New->next_variable = NULL; */ New->type = ASN_NULL; New->name_length = Len; if (New->name_length == 0) { New->name = NULL; return (New); } New->name = (oid *) xmalloc(Len * sizeof(oid)); /* XXX xmalloc never returns NULL */ if (New->name == NULL) { xfree(New); snmp_set_api_error(SNMPERR_OS_ERR); return (NULL); } #ifdef DEBUG_VARS printf("VARS: Copying name, size (%d)\n", Len); #endif /* Only copy a name if it was specified. */ if (Name) xmemcpy((char *) New->name, (char *) Name, Len * sizeof(oid)); return (New); }
SNMP_NAMESPACE //static char rcsid[] = //"$Id: snmp_pdu.c,v 1.1.1.1 2001/11/15 01:29:34 panther Exp $"; /* #define DEBUG_PDU 1 */ /* #define DEBUG_PDU_DECODE 1 */ /* #define DEBUG_PDU_ENCODE 1 */ #define ASN_PARSE_ERROR(x) { snmpInASNParseErrs_Add(1); return(x); } /**********************************************************************/ /* Create a PDU. */ struct snmp_pdu *snmp_pdu_create(int command) { struct snmp_pdu *pdu; #ifdef DEBUG_PDU printf("PDU: Creating\n"); #endif pdu = (struct snmp_pdu *)malloc(sizeof(struct snmp_pdu)); if (pdu == NULL) { snmp_set_api_error(SNMPERR_OS_ERR); return(NULL); } memset((char *)pdu, '\0', sizeof(struct snmp_pdu)); pdu->command = command; pdu->errstat = SNMP_ERR_NOERROR; pdu->errindex = 0; /* XXXXX Is this right? */ pdu->address.sin_addr.s_addr = SNMP_DEFAULT_ADDRESS; pdu->enterprise = NULL; pdu->enterprise_length = 0; pdu->variables = NULL; #ifdef DEBUG_PDU printf("PDU: Created %x\n", (unsigned int)pdu); #endif return(pdu); }
/* Clone an existing PDU. */ struct snmp_pdu *snmp_pdu_clone(struct snmp_pdu *Src) { struct snmp_pdu *Dest; #ifdef DEBUG_PDU printf("PDU %x: Cloning\n", (unsigned int)Src); #endif Dest = (struct snmp_pdu *)malloc(sizeof(struct snmp_pdu)); if (Dest == NULL) { snmp_set_api_error(SNMPERR_OS_ERR); return(NULL); } memcpy((char *)Dest, (char *)Src, sizeof(struct snmp_pdu)); #ifdef DEBUG_PDU printf("PDU %x: Created %x\n", (unsigned int)Src, (unsigned int)Dest); #endif return(Dest); }
SNMP_NAMESPACE //static char rcsid[] = //"$Id: snmp_vars.c,v 1.1.1.1 2001/11/15 01:29:34 panther Exp $"; /* #define DEBUG_VARS 1 */ /* #define DEBUG_VARS_MALLOC 1 */ /* #define DEBUG_VARS_DECODE 1 */ /* #define DEBUG_VARS_ENCODE 1 */ #define ASN_PARSE_ERROR(x) { snmpInASNParseErrs_Add(1); return(x); } /* Create a new variable_list structure representing oid Name of length Len. * * Returns NULL upon error. */ struct variable_list *snmp_var_new(oid *Name, int Len) { struct variable_list *New; #ifdef DEBUG_VARS printf("VARS: Creating.\n"); #endif New = (struct variable_list *)malloc(sizeof(struct variable_list)); if (New == NULL) { snmp_set_api_error(SNMPERR_OS_ERR); return(NULL); } memset(New, '\0', sizeof(struct variable_list)); /* New->next_variable = NULL; */ New->type = ASN_NULL; New->name_length = Len; if (New->name_length == 0) { New->name = NULL; return(New); } New->name = (oid *)malloc(Len * sizeof(oid)); if (New->name == NULL) { free(New); snmp_set_api_error(SNMPERR_OS_ERR); return(NULL); } #ifdef DEBUG_VARS printf("VARS: Copying name, size (%d)\n", Len); #endif /* Only copy a name if it was specified. */ if (Name) memcpy((char *)New->name, (char *)Name, Len * sizeof(oid)); /* New->val.string = NULL; */ /* New->val_len = 0; */ #ifdef DEBUG_VARS printf("VARS: Created %x.\n", (unsigned int)New); #endif #ifdef DEBUG_VARS_MALLOC printf("VARS: Created (%x)\n", (unsigned int)New); printf("VARS: Name is (%x)\n", (unsigned int)New->name); #endif return(New); }
/* Parse all Vars from the buffer */ u_char *snmp_var_DecodeVarBind(u_char *Buffer, int *BufLen, struct variable_list **VarP, int Version) { struct variable_list *Var, **VarLastP; u_char *bufp, *tmp; u_char VarBindType; u_char *DataPtr; int DataLen; oid TmpBuf[MAX_NAME_LEN]; int AllVarLen = *BufLen; int ThisVarLen = 0; VarLastP = VarP; #ifdef DEBUG_VARS_DECODE printf("VARS: Decoding buffer of length %d\n", *BufLen); #endif /* Now parse the variables */ bufp = asn_parse_header(Buffer, &AllVarLen, &VarBindType); if (bufp == NULL) ASN_PARSE_ERROR(NULL); if (VarBindType != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR)) { snmp_set_api_error(SNMPERR_PDU_PARSE); ASN_PARSE_ERROR(NULL); } #ifdef DEBUG_VARS_DECODE printf("VARS: All Variable length %d\n", AllVarLen); #endif /* We know how long the variable list is. Parse it. */ while ((int)AllVarLen > 0) { /* Create a new variable */ Var = snmp_var_new(NULL, MAX_NAME_LEN); if (Var == NULL) return(NULL); /* Parse the header to find out the length of this variable. */ ThisVarLen = AllVarLen; tmp = asn_parse_header(bufp, &ThisVarLen, &VarBindType); if (tmp == NULL) ASN_PARSE_ERROR(NULL); /* Now that we know the length , figure out how it relates to * the entire variable list */ AllVarLen = AllVarLen - (ThisVarLen + (tmp - bufp)); bufp = tmp; /* Is it valid? */ if (VarBindType != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR)) { snmp_set_api_error(SNMPERR_PDU_PARSE); ASN_PARSE_ERROR(NULL); } #ifdef DEBUG_VARS_DECODE printf("VARS: Header type 0x%x (%d bytes left)\n", VarBindType, ThisVarLen); #endif /* Parse the OBJID */ bufp = asn_parse_objid(bufp, &ThisVarLen, &VarBindType, Var->name, &(Var->name_length)); if (bufp == NULL) ASN_PARSE_ERROR(NULL); if (VarBindType != (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID)) { snmp_set_api_error(SNMPERR_PDU_PARSE); ASN_PARSE_ERROR(NULL); } #ifdef DEBUG_VARS_DECODE printf("VARS: Decoded OBJID (%d bytes). (%d bytes left)\n", Var->name_length, ThisVarLen); #endif /* Keep a pointer to this object */ DataPtr = bufp; DataLen = ThisVarLen; /* find out type of object */ bufp = asn_parse_header(bufp, &ThisVarLen, &(Var->type)); if (bufp == NULL) ASN_PARSE_ERROR(NULL); ThisVarLen = DataLen; #ifdef DEBUG_VARS_DECODE printf("VARS: Data type %d\n", Var->type); #endif /* Parse the type */ switch((short)Var->type){ case ASN_INTEGER: Var->val.integer = (int *)malloc(sizeof(int)); if (Var->val.integer == NULL) { snmp_set_api_error(SNMPERR_OS_ERR); return(NULL); } Var->val_len = sizeof(int); bufp = asn_parse_int(DataPtr, &ThisVarLen, &Var->type, (int *)Var->val.integer, Var->val_len); #ifdef DEBUG_VARS_DECODE printf("VARS: Decoded integer '%d' (%d bytes left)\n", *(Var->val.integer), ThisVarLen); #endif break; case SMI_COUNTER32: case SMI_GAUGE32: /* case SMI_UNSIGNED32: */ case SMI_TIMETICKS: Var->val.integer = (int *)malloc(sizeof(u_int)); if (Var->val.integer == NULL) { snmp_set_api_error(SNMPERR_OS_ERR); return(NULL); } Var->val_len = sizeof(u_int); bufp = asn_parse_unsigned_int(DataPtr, &ThisVarLen, &Var->type, (u_int *)Var->val.integer, Var->val_len); #ifdef DEBUG_VARS_DECODE printf("VARS: Decoded timeticks '%d' (%d bytes left)\n", *(Var->val.integer), ThisVarLen); #endif break; case ASN_OCTET_STR: case SMI_IPADDRESS: case SMI_OPAQUE: Var->val_len = *&ThisVarLen; /* String is this at most */ Var->val.string = (u_char *)malloc((unsigned)Var->val_len); if (Var->val.string == NULL) { snmp_set_api_error(SNMPERR_OS_ERR); return(NULL); } bufp = asn_parse_string(DataPtr, &ThisVarLen, &Var->type, Var->val.string, &Var->val_len); #ifdef DEBUG_VARS_DECODE printf("VARS: Decoded string '%s' (length %d) (%d bytes left)\n", (Var->val.string), Var->val_len, ThisVarLen); #endif break; case ASN_OBJECT_ID: Var->val_len = MAX_NAME_LEN; bufp = asn_parse_objid(DataPtr, &ThisVarLen, &Var->type, TmpBuf, &Var->val_len); Var->val_len *= sizeof(oid); Var->val.objid = (oid *)malloc((unsigned)Var->val_len); if (Var->val.integer == NULL) { snmp_set_api_error(SNMPERR_OS_ERR); return(NULL); } /* Only copy if we successfully decoded something */ if (bufp) { memcpy((char *)Var->val.objid, (char *)TmpBuf, Var->val_len); } #ifdef DEBUG_VARS_DECODE printf("VARS: Decoded OBJID (length %d) (%d bytes left)\n", Var->val_len, ThisVarLen); #endif break; case ASN_NULL: case SMI_NOSUCHINSTANCE: case SMI_NOSUCHOBJECT: case SMI_ENDOFMIBVIEW: Var->val_len = 0; Var->val.objid = NULL; bufp = asn_parse_null(DataPtr, &ThisVarLen, &Var->type); #ifdef DEBUG_VARS_DECODE printf("VARS: Decoded ASN_NULL (length %d) (%d bytes left)\n", Var->val_len, ThisVarLen); #endif break; case SMI_COUNTER64: #ifdef STDERR_OUTPUT fprintf(stderr, WIDE("Unable to parse type SMI_COUNTER64!\n")); #endif snmp_set_api_error(SNMPERR_UNSUPPORTED_TYPE); return(NULL); break; default: #ifdef STDERR_OUTPUT fprintf(stderr, WIDE("bad type returned (%x)\n"), Var->type); #endif snmp_set_api_error(SNMPERR_PDU_PARSE); return(NULL); break; } /* End of var type switch */ /* Why is this here? XXXXX */ if (bufp == NULL) return(NULL); #ifdef DEBUG_VARS_DECODE printf("VARS: Adding to list of decoded variables. (%d bytes remain.)\n", AllVarLen); #endif /* Add variable to the list */ *VarLastP = Var; VarLastP = &(Var->next_variable); } return(bufp); }
/* Build a variable binding. * * RFC 1905: Protocol Operations for SNMPv2 * * VarBind ::= * SEQUENCE { * name ObjectName * CHOICE { * value ObjectSyntax * unSpecified NULL * noSuchObject[0] NULL * noSuchInstance[1] NULL * endOfMibView[2] NULL * } * } */ u_char *snmp_var_EncodeVarBind(u_char *Buffer, int *BufLenP, struct variable_list *VarList, int Version) { struct variable_list *Vars; u_char *bufp; u_char *HeaderStart; u_char *HeaderEnd; int FakeArg = *BufLenP; #ifdef DEBUG_VARS_ENCODE int StartLen = *BufLenP; int Counter = 1; #endif bufp = Buffer; #ifdef DEBUG_VARS_ENCODE printf("VARS: Encoding Variable list into buffer at 0x%x.\n", Buffer); #endif for (Vars=VarList; Vars; Vars=Vars->next_variable) { #ifdef DEBUG_VARS_ENCODE printf("VARS %d: Encoding Variable 0x%x.\n", Counter, Vars); printf("VARS %d: Starting at 0x%x (%d bytes left)\n", Counter, bufp, *BufLenP); #endif /* Build the header for this variable * * Use Maximum size. */ HeaderStart = bufp; HeaderEnd = asn_build_header(HeaderStart, BufLenP, (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR), FakeArg); if (HeaderEnd == NULL) return(NULL); #ifdef DEBUG_VARS_ENCODE printf("VARS %d: Encoding Object Identifier 0x%x (%d bytes) at 0x%x (%d bytes left)\n", Counter, Vars, Vars->name_length, HeaderEnd, *BufLenP); print_oid(Vars->name, Vars->name_length), #endif /* Now, let's put the Object Identifier into the buffer */ bufp = asn_build_objid(HeaderEnd, BufLenP, (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID), Vars->name, Vars->name_length); if (bufp == NULL) return(NULL); /* Now put the data in */ switch(Vars->type) { case ASN_INTEGER: #ifdef DEBUG_VARS_ENCODE printf("VARS %d: Encoding Integer %d at 0x%x\n", Counter, *(Vars->val.integer), bufp); #endif bufp = asn_build_int(bufp, BufLenP, Vars->type, (int *)Vars->val.integer, Vars->val_len); break; case SMI_COUNTER32: case SMI_GAUGE32: /* case SMI_UNSIGNED32: */ case SMI_TIMETICKS: #ifdef DEBUG_VARS_ENCODE printf("VARS %d: Encoding Timeticks %d at 0x%x\n", Counter, *(Vars->val.integer), bufp); #endif bufp = asn_build_unsigned_int(bufp, BufLenP, Vars->type, (u_int *)Vars->val.integer, Vars->val_len); break; case ASN_OCTET_STR: case SMI_IPADDRESS: case SMI_OPAQUE: #ifdef DEBUG_VARS_ENCODE printf("VARS %d: Encoding String %s (%d bytes) at 0x%x\n", Counter, (Vars->val.string), Vars->val_len, bufp); #endif bufp = asn_build_string(bufp, BufLenP, Vars->type, Vars->val.string, Vars->val_len); break; case ASN_OBJECT_ID: #ifdef DEBUG_VARS_ENCODE printf("VARS %d: Encoding Object Identifier (%d bytes) at 0x%x\n", Counter, Vars->val_len, bufp); #endif bufp = asn_build_objid(bufp, BufLenP, Vars->type, (oid *)Vars->val.objid, Vars->val_len / sizeof(oid)); break; case SMI_NOSUCHINSTANCE: case SMI_NOSUCHOBJECT: case SMI_ENDOFMIBVIEW: #ifdef DEBUG_VARS_ENCODE printf("VARS %d: Encoding NULL at 0x%x\n", Counter, bufp); #endif if (Version == SNMP_VERSION_1) { /* SNMP Version 1 does not support these error codes. */ bufp = asn_build_null(bufp, BufLenP, SMI_NOSUCHOBJECT); } else { bufp = asn_build_exception(bufp, BufLenP, Vars->type); } break; case ASN_NULL: #ifdef DEBUG_VARS_ENCODE printf("VARS %d: Encoding NULL at 0x%x\n", Counter, bufp); #endif bufp = asn_build_null(bufp, BufLenP, Vars->type); break; case SMI_COUNTER64: #ifdef STDERR_OUTPUT fprintf(stderr, WIDE("Unable to encode type SMI_COUNTER64!\n")); #endif /* Fall through */ default: snmp_set_api_error(SNMPERR_UNSUPPORTED_TYPE); return(NULL); } /* ASSERT: bufp should now point to the next valid byte. */ if (bufp == NULL) return(NULL); /* Rebuild the header with the appropriate length */ #ifdef DEBUG_VARS_ENCODE printf("VARS %d: Resetting length to %d at 0x%x (%d bytes left)\n", Counter, (bufp - HeaderEnd), HeaderStart, *BufLenP); #endif HeaderEnd = asn_build_header(HeaderStart, &FakeArg, (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR), (bufp - HeaderEnd)); /* Returns NULL */ if (HeaderEnd == NULL) return(NULL); #ifdef DEBUG_VARS_ENCODE Counter++; #endif } #ifdef DEBUG_VARS_ENCODE printf("VARS: Variable list of %d vars takes up %d bytes.\n", --Counter, StartLen - *BufLenP); #endif /* or the end of the entire thing */ return(bufp); }
/* Build a variable binding. * * RFC 1905: Protocol Operations for SNMPv2 * * VarBind ::= * SEQUENCE { * name ObjectName * CHOICE { * value ObjectSyntax * unSpecified NULL * noSuchObject[0] NULL * noSuchInstance[1] NULL * endOfMibView[2] NULL * } * } */ u_char * snmp_var_EncodeVarBind(u_char * Buffer, int *BufLenP, variable_list * VarList, int Version) { struct variable_list *Vars; u_char *bufp; u_char *HeaderStart; u_char *HeaderEnd; int FakeArg = *BufLenP; bufp = Buffer; for (Vars = VarList; Vars; Vars = Vars->next_variable) { /* Build the header for this variable * * Use Maximum size. */ HeaderStart = bufp; HeaderEnd = asn_build_header(HeaderStart, BufLenP, (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR), FakeArg); if (HeaderEnd == NULL) return (NULL); /* Now, let's put the Object Identifier into the buffer */ bufp = asn_build_objid(HeaderEnd, BufLenP, (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID), Vars->name, Vars->name_length); if (bufp == NULL) return (NULL); /* Now put the data in */ switch (Vars->type) { case ASN_INTEGER: bufp = asn_build_int(bufp, BufLenP, Vars->type, (int *) Vars->val.integer, Vars->val_len); break; case SMI_COUNTER32: case SMI_GAUGE32: /* case SMI_UNSIGNED32: */ case SMI_TIMETICKS: bufp = asn_build_unsigned_int(bufp, BufLenP, Vars->type, (u_int *) Vars->val.integer, Vars->val_len); break; case ASN_OCTET_STR: case SMI_IPADDRESS: case SMI_OPAQUE: bufp = asn_build_string(bufp, BufLenP, Vars->type, Vars->val.string, Vars->val_len); break; case ASN_OBJECT_ID: bufp = asn_build_objid(bufp, BufLenP, Vars->type, (oid *) Vars->val.objid, Vars->val_len / sizeof(oid)); break; case SMI_NOSUCHINSTANCE: case SMI_NOSUCHOBJECT: case SMI_ENDOFMIBVIEW: if (Version == SNMP_VERSION_1) { /* SNMP Version 1 does not support these error codes. */ bufp = asn_build_null(bufp, BufLenP, SMI_NOSUCHOBJECT); } else { bufp = asn_build_exception(bufp, BufLenP, Vars->type); } break; case ASN_NULL: bufp = asn_build_null(bufp, BufLenP, Vars->type); break; case SMI_COUNTER64: snmplib_debug(2, "Unable to encode type SMI_COUNTER64!\n"); /* Fall through */ default: snmp_set_api_error(SNMPERR_UNSUPPORTED_TYPE); return (NULL); } /* ASSERT: bufp should now point to the next valid byte. */ if (bufp == NULL) return (NULL); /* Rebuild the header with the appropriate length */ HeaderEnd = asn_build_header(HeaderStart, &FakeArg, (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR), (bufp - HeaderEnd)); /* Returns NULL */ if (HeaderEnd == NULL) return (NULL); } /* or the end of the entire thing */ return (bufp); }
/* Decodes PDU from Packet into PDU. * * Returns a pointer to the next byte of the packet, which is where the * Variable Bindings start. */ u_char *snmp_pdu_decode(u_char *Packet, /* data */ int *Length, /* &length */ struct snmp_pdu *PDU) /* pdu */ { u_char *bufp; u_char PDUType; int four; u_char ASNType; oid objid[MAX_NAME_LEN]; bufp = asn_parse_header(Packet, Length, &PDUType); if (bufp == NULL) ASN_PARSE_ERROR(NULL); #ifdef DEBUG_PDU_DECODE printf("PDU Type: %d\n", PDUType); #endif PDU->command = PDUType; switch (PDUType) { case TRP_REQ_MSG: /* SNMPv1 Trap Message */ /* enterprise */ PDU->enterprise_length = MAX_NAME_LEN; bufp = asn_parse_objid(bufp, Length, &ASNType, objid, &PDU->enterprise_length); if (bufp == NULL) ASN_PARSE_ERROR(NULL); PDU->enterprise = (oid *)malloc(PDU->enterprise_length * sizeof(oid)); if (PDU->enterprise == NULL) { snmp_set_api_error(SNMPERR_OS_ERR); return(NULL); } memcpy((char *)PDU->enterprise, (char *)objid, PDU->enterprise_length * sizeof(oid)); /* Agent-addr */ four = 4; bufp = asn_parse_string(bufp, Length, &ASNType, (u_char *)&PDU->agent_addr.sin_addr.s_addr, &four); if (bufp == NULL) ASN_PARSE_ERROR(NULL); /* Generic trap */ bufp = asn_parse_int(bufp, Length, &ASNType, (int *)&PDU->trap_type, sizeof(PDU->trap_type)); if (bufp == NULL) ASN_PARSE_ERROR(NULL); /* Specific Trap */ bufp = asn_parse_int(bufp, Length, &ASNType, (int *)&PDU->specific_type, sizeof(PDU->specific_type)); if (bufp == NULL) ASN_PARSE_ERROR(NULL); /* Timestamp */ bufp = asn_parse_unsigned_int(bufp, Length, &ASNType, &PDU->time, sizeof(PDU->time)); if (bufp == NULL) ASN_PARSE_ERROR(NULL); break; /**********************************************************************/ case SNMP_PDU_GETBULK: /* SNMPv2 Bulk Request */ /* request id */ bufp = asn_parse_int(bufp, Length, &ASNType, &PDU->reqid, sizeof(PDU->reqid)); if (bufp == NULL) ASN_PARSE_ERROR(NULL); /* non-repeaters */ bufp = asn_parse_int(bufp, Length, &ASNType, &PDU->non_repeaters, sizeof(PDU->non_repeaters)); if (bufp == NULL) ASN_PARSE_ERROR(NULL); /* max-repetitions */ bufp = asn_parse_int(bufp, Length, &ASNType, &PDU->max_repetitions, sizeof(PDU->max_repetitions)); if (bufp == NULL) ASN_PARSE_ERROR(NULL); break; /**********************************************************************/ default: /* Normal PDU Encoding */ /* request id */ bufp = asn_parse_int(bufp, Length, &ASNType, &PDU->reqid, sizeof(PDU->reqid)); if (bufp == NULL) ASN_PARSE_ERROR(NULL); #ifdef DEBUG_PDU_DECODE printf("PDU Request ID: %d\n", PDU->reqid); #endif /* error status */ bufp = asn_parse_int(bufp, Length, &ASNType, &PDU->errstat, sizeof(PDU->errstat)); if (bufp == NULL) ASN_PARSE_ERROR(NULL); #ifdef DEBUG_PDU_DECODE printf("PDU Error Status: %d\n", PDU->errstat); #endif /* error index */ bufp = asn_parse_int(bufp, Length, &ASNType, &PDU->errindex, sizeof(PDU->errindex)); if (bufp == NULL) ASN_PARSE_ERROR(NULL); #ifdef DEBUG_PDU_DECODE printf("PDU Error Index: %d\n", PDU->errindex); #endif break; } return(bufp); }
struct snmp_pdu *snmp_fix_pdu(struct snmp_pdu *pdu, int command) { struct variable_list *var, *newvar; struct snmp_pdu *newpdu; int index; int copied = 0; #ifdef DEBUG_PDU printf("PDU %x: Fixing. Err index is %d\n", (unsigned int)pdu, (unsigned int)pdu->errindex); #endif if (pdu->command != SNMP_PDU_RESPONSE || pdu->errstat == SNMP_ERR_NOERROR || pdu->errindex <= 0) { snmp_set_api_error(SNMPERR_UNABLE_TO_FIX); return(NULL); } /* clone the pdu */ newpdu = snmp_pdu_clone(pdu); if (newpdu == NULL) return(NULL); newpdu->variables = 0; newpdu->command = command; newpdu->reqid = SNMP_DEFAULT_REQID; newpdu->errstat = SNMP_ERR_NOERROR; newpdu->errindex = 0; /* XXXXX Is this right? */ /* Loop through the variables, removing whatever isn't necessary */ var = pdu->variables; index = 1; /* skip first variable if necessary*/ if (pdu->errindex == index) { var = var->next_variable; index++; } if (var != NULL) { /* VAR is the first uncopied variable */ /* Clone this variable */ newpdu->variables = snmp_var_clone(var); if (newpdu->variables == NULL) { snmp_pdu_free(newpdu); return(NULL); } copied++; newvar = newpdu->variables; /* VAR has been copied to NEWVAR. */ while(var->next_variable) { /* Skip the item that was bad */ if (++index == pdu->errindex) { var = var->next_variable; continue; } /* Copy this var */ newvar->next_variable = snmp_var_clone(var->next_variable); if (newvar->next_variable == NULL) { snmp_pdu_free(newpdu); return(NULL); } /* Move to the next one */ newvar = newvar->next_variable; var = var->next_variable; copied++; } newvar->next_variable = NULL; } /* If we didn't copy anything, free the new pdu. */ if (index < pdu->errindex || copied == 0) { snmp_free_pdu(newpdu); snmp_set_api_error(SNMPERR_UNABLE_TO_FIX); return(NULL); } #ifdef DEBUG_PDU printf("PDU %x: Fixed PDU is %x\n", (unsigned int)pdu, (unsigned int)newpdu); #endif return(newpdu); }