/* * Add a null variable with the requested name to the end of the list of * variables for this pdu. */ void snmp_add_null_var(struct snmp_pdu *pdu, oid *name, int name_length) { struct variable_list *vars; struct variable_list *ptr; vars = snmp_var_new(name, name_length); if (vars == NULL) { #ifdef STDERR_OUTPUT perror("snmp_add_null_var:malloc"); #endif return; } if (pdu->variables == NULL) { pdu->variables = vars; } else { /* Insert at the end */ for (ptr = pdu->variables; ptr->next_variable; ptr = ptr->next_variable) /*EXIT*/; ptr->next_variable = vars; } return; }
struct variable_list * snmp_var_new_integer(oid * Name, int Len, int ival, unsigned char type) { variable_list *v = snmp_var_new(Name, Len); v->val_len = sizeof(int); v->val.integer = xmalloc(sizeof(int)); v->type = type; *(v->val.integer) = ival; return v; }
variable_list * snmp_confFn(variable_list * Var, snint * ErrP) { variable_list *Answer = NULL; const char *cp = NULL; debug(49, 5) ("snmp_confFn: Processing request with magic %d!\n", Var->name[8]); *ErrP = SNMP_ERR_NOERROR; switch (Var->name[LEN_SQ_CONF]) { case CONF_ADMIN: Answer = snmp_var_new(Var->name, Var->name_length); Answer->type = ASN_OCTET_STR; Answer->val_len = strlen(Config.adminEmail); Answer->val.string = (u_char *) xstrdup(Config.adminEmail); break; case CONF_VERSION: Answer = snmp_var_new(Var->name, Var->name_length); Answer->type = ASN_OCTET_STR; Answer->val_len = strlen(appname); Answer->val.string = (u_char *) xstrdup(appname); break; case CONF_VERSION_ID: Answer = snmp_var_new(Var->name, Var->name_length); Answer->type = ASN_OCTET_STR; Answer->val_len = strlen(VERSION); Answer->val.string = (u_char *) xstrdup(VERSION); break; case CONF_STORAGE: switch (Var->name[LEN_SQ_CONF + 1]) { case CONF_ST_MMAXSZ: Answer = snmp_var_new_integer(Var->name, Var->name_length, (snint) Config.memMaxSize >> 20, ASN_INTEGER); break; case CONF_ST_SWMAXSZ: Answer = snmp_var_new_integer(Var->name, Var->name_length, (snint) Config.Swap.maxSize >> 10, ASN_INTEGER); break; case CONF_ST_SWHIWM: Answer = snmp_var_new_integer(Var->name, Var->name_length, (snint) Config.Swap.highWaterMark, ASN_INTEGER); break; case CONF_ST_SWLOWM: Answer = snmp_var_new_integer(Var->name, Var->name_length, (snint) Config.Swap.lowWaterMark, ASN_INTEGER); break; default: *ErrP = SNMP_ERR_NOSUCHNAME; break; } break; case CONF_LOG_FAC: Answer = snmp_var_new(Var->name, Var->name_length); if (!(cp = Config.debugOptions)) cp = "None"; Answer->type = ASN_OCTET_STR; Answer->val_len = strlen(cp); Answer->val.string = (u_char *) xstrdup(cp); break; default: *ErrP = SNMP_ERR_NOSUCHNAME; break; } return Answer; }
variable_list * snmp_meshPtblFn(variable_list * Var, snint * ErrP) { variable_list *Answer = NULL; struct in_addr *laddr; char *cp = NULL; peer *p = NULL; int cnt = 0; debug(49, 5) ("snmp_meshPtblFn: peer %d requested!\n", Var->name[LEN_SQ_MESH + 3]); *ErrP = SNMP_ERR_NOERROR; laddr = oid2addr(&Var->name[LEN_SQ_MESH + 3]); for (p = Config.peers; p != NULL; p = p->next, cnt++) if (p->in_addr.sin_addr.s_addr == laddr->s_addr) break; if (p == NULL) { *ErrP = SNMP_ERR_NOSUCHNAME; return NULL; } switch (Var->name[LEN_SQ_MESH + 2]) { case MESH_PTBL_NAME: cp = p->host; Answer = snmp_var_new(Var->name, Var->name_length); Answer->type = ASN_OCTET_STR; Answer->val_len = strlen(cp); Answer->val.string = (u_char *) xstrdup(cp); break; case MESH_PTBL_IP: Answer = snmp_var_new_integer(Var->name, Var->name_length, (snint) p->in_addr.sin_addr.s_addr, SMI_IPADDRESS); break; case MESH_PTBL_HTTP: Answer = snmp_var_new_integer(Var->name, Var->name_length, (snint) p->http_port, ASN_INTEGER); break; case MESH_PTBL_ICP: Answer = snmp_var_new_integer(Var->name, Var->name_length, (snint) p->icp.port, ASN_INTEGER); break; case MESH_PTBL_TYPE: Answer = snmp_var_new_integer(Var->name, Var->name_length, (snint) p->type, ASN_INTEGER); break; case MESH_PTBL_STATE: Answer = snmp_var_new_integer(Var->name, Var->name_length, (snint) neighborUp(p), ASN_INTEGER); break; case MESH_PTBL_SENT: Answer = snmp_var_new_integer(Var->name, Var->name_length, p->stats.pings_sent, SMI_COUNTER32); break; case MESH_PTBL_PACKED: Answer = snmp_var_new_integer(Var->name, Var->name_length, p->stats.pings_acked, SMI_COUNTER32); break; case MESH_PTBL_FETCHES: Answer = snmp_var_new_integer(Var->name, Var->name_length, p->stats.fetches, SMI_COUNTER32); break; case MESH_PTBL_RTT: Answer = snmp_var_new_integer(Var->name, Var->name_length, p->stats.rtt, ASN_INTEGER); break; case MESH_PTBL_IGN: Answer = snmp_var_new_integer(Var->name, Var->name_length, p->stats.ignored_replies, SMI_COUNTER32); break; case MESH_PTBL_KEEPAL_S: Answer = snmp_var_new_integer(Var->name, Var->name_length, p->stats.n_keepalives_sent, SMI_COUNTER32); break; case MESH_PTBL_KEEPAL_R: Answer = snmp_var_new_integer(Var->name, Var->name_length, p->stats.n_keepalives_recv, SMI_COUNTER32); break; default: *ErrP = SNMP_ERR_NOSUCHNAME; break; } return Answer; }
/* 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); }