netsnmp_pdu* convert_v1pdu_to_v2( netsnmp_pdu* template_v1pdu ) { netsnmp_pdu *template_v2pdu; netsnmp_variable_list *first_vb; netsnmp_variable_list *var; oid enterprise[MAX_OID_LEN]; size_t enterprise_len; /* * Make a copy of the v1 Trap PDU * before starting to convert this * into a v2 Trap PDU. */ template_v2pdu = snmp_clone_pdu( template_v1pdu); if (!template_v2pdu) { snmp_log(LOG_WARNING, "send_trap: failed to copy v2 template PDU\n"); return NULL; } template_v2pdu->command = SNMP_MSG_TRAP2; first_vb = template_v2pdu->variables; /* * Insert an snmpTrapOID varbind before the original v1 varbind list * either using one of the standard defined trap OIDs, * or constructing this from the PDU enterprise & specific trap fields */ if (template_v1pdu->trap_type == SNMP_TRAP_ENTERPRISESPECIFIC) { memcpy(enterprise, template_v1pdu->enterprise, template_v1pdu->enterprise_length*sizeof(oid)); enterprise_len = template_v1pdu->enterprise_length; enterprise[enterprise_len++] = 0; enterprise[enterprise_len++] = template_v1pdu->specific_type; } else { memcpy(enterprise, cold_start_oid, sizeof(cold_start_oid)); enterprise[9] = template_v1pdu->trap_type+1; enterprise_len = sizeof(cold_start_oid)/sizeof(oid); } var = NULL; if (!snmp_varlist_add_variable( &var, snmptrap_oid, snmptrap_oid_len, ASN_OBJECT_ID, (u_char*)enterprise, enterprise_len*sizeof(oid))) { snmp_log(LOG_WARNING, "send_trap: failed to insert copied snmpTrapOID varbind\n"); snmp_free_pdu(template_v2pdu); return NULL; } var->next_variable = template_v2pdu->variables; template_v2pdu->variables = var; /* * Insert a sysUptime varbind at the head of the v2 varbind list */ var = NULL; if (!snmp_varlist_add_variable( &var, sysuptime_oid, sysuptime_oid_len, ASN_TIMETICKS, (u_char*)&(template_v1pdu->time), sizeof(template_v1pdu->time))) { snmp_log(LOG_WARNING, "send_trap: failed to insert copied sysUptime varbind\n"); snmp_free_pdu(template_v2pdu); return NULL; } var->next_variable = template_v2pdu->variables; template_v2pdu->variables = var; /* * Append the other three conversion varbinds, * (snmpTrapAgentAddr, snmpTrapCommunity & snmpTrapEnterprise) * if they're not already present. * But don't bomb out completely if there are problems. */ var = find_varbind_in_list( template_v2pdu->variables, agentaddr_oid, agentaddr_oid_len); if (!var && (template_v1pdu->agent_addr[0] || template_v1pdu->agent_addr[1] || template_v1pdu->agent_addr[2] || template_v1pdu->agent_addr[3])) { if (!snmp_varlist_add_variable( &(template_v2pdu->variables), agentaddr_oid, agentaddr_oid_len, ASN_IPADDRESS, (u_char*)&(template_v1pdu->agent_addr), sizeof(template_v1pdu->agent_addr))) snmp_log(LOG_WARNING, "send_trap: failed to append snmpTrapAddr varbind\n"); } var = find_varbind_in_list( template_v2pdu->variables, community_oid, community_oid_len); if (!var && template_v1pdu->community) { if (!snmp_varlist_add_variable( &(template_v2pdu->variables), community_oid, community_oid_len, ASN_OCTET_STR, template_v1pdu->community, template_v1pdu->community_len)) snmp_log(LOG_WARNING, "send_trap: failed to append snmpTrapCommunity varbind\n"); } var = find_varbind_in_list( template_v2pdu->variables, snmptrapenterprise_oid, snmptrapenterprise_oid_len); if (!var && template_v1pdu->trap_type != SNMP_TRAP_ENTERPRISESPECIFIC) { if (!snmp_varlist_add_variable( &(template_v2pdu->variables), snmptrapenterprise_oid, snmptrapenterprise_oid_len, ASN_OBJECT_ID, (u_char*)template_v1pdu->enterprise, template_v1pdu->enterprise_length*sizeof(oid))) snmp_log(LOG_WARNING, "send_trap: failed to append snmpEnterprise varbind\n"); } return template_v2pdu; }
main() { oid oidsave[MAX_OID_LEN]; int len = MAX_OID_LEN, len2; netsnmp_variable_list *vars; long ltmp = 4242, ltmp2 = 88, ltmp3 = 1, ltmp4 = 4200; oid ourprefix[] = { 1, 2, 3, 4 }; oid testparse[] = { 4, 116, 101, 115, 116, 4200 }; int ret; char *string = "wes", *string2 = "dawn", *string3 = "test"; struct header_complex_index *thestorage = NULL; debug_register_tokens("header_complex"); snmp_set_do_debugging(1); vars = NULL; len2 = sizeof(ltmp); snmp_varlist_add_variable(&vars, NULL, 0, ASN_INTEGER, (char *) <mp, len2); header_complex_add_data(&thestorage, vars, ourprefix); vars = NULL; len2 = strlen(string); snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, string, len2); header_complex_add_data(&thestorage, vars, ourprefix); vars = NULL; len2 = sizeof(ltmp2); snmp_varlist_add_variable(&vars, NULL, 0, ASN_INTEGER, (char *) <mp2, len2); header_complex_add_data(&thestorage, vars, ourprefix); vars = NULL; len2 = strlen(string2); snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, string2, len2); header_complex_add_data(&thestorage, vars, ourprefix); vars = NULL; len2 = sizeof(ltmp3); snmp_varlist_add_variable(&vars, NULL, 0, ASN_INTEGER, (char *) <mp3, len2); header_complex_add_data(&thestorage, vars, ourprefix); vars = NULL; len2 = strlen(string3); snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, string3, len2); len2 = sizeof(ltmp4); snmp_varlist_add_variable(&vars, NULL, 0, ASN_INTEGER, (char *) <mp4, len2); header_complex_add_data(&thestorage, vars, ourprefix); header_complex_dump(thestorage); vars = NULL; snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, NULL, 0); snmp_varlist_add_variable(&vars, NULL, 0, ASN_INTEGER, NULL, 0); ret = header_complex_parse_oid(testparse, sizeof(testparse) / sizeof(oid), vars); DEBUGMSGTL(("header_complex_test", "parse returned %d...\n", ret)); }
/* * mteTriggerTable_add(): adds a structure node to our data set */ int expValueTable_add(struct expExpressionTable_data *expression_data, char *owner, size_t owner_len, char *name, size_t name_len, oid * index, size_t index_len) { netsnmp_variable_list *vars = NULL; struct expValueTable_data *thedata, *StorageTmp; struct header_complex_index *hcindex; int founded = 0; thedata = create_expValueTable_data(); thedata->expValueCounter32Val = 0; thedata->expExpressionOwner = owner; thedata->expExpressionOwnerLen = owner_len; thedata->expExpressionName = name; thedata->expExpressionNameLen = name_len; thedata->expValueInstance = index; thedata->expValueInstanceLen = index_len; thedata->expression_data = expression_data; DEBUGMSGTL(("expValueTable", "adding data... ")); /* * add the index variables to the varbind list, which is * used by header_complex to index the data */ snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->expExpressionOwner, thedata->expExpressionOwnerLen); /* expExpressionOwner */ snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->expExpressionName, thedata->expExpressionNameLen); /* expExpressionName */ snmp_varlist_add_variable(&vars, NULL, 0, ASN_PRIV_IMPLIED_OBJECT_ID, (u_char *) thedata->expValueInstance, thedata->expValueInstanceLen * sizeof(oid)); for (hcindex = expValueTableStorage; hcindex != NULL; hcindex = hcindex->next) { StorageTmp = (struct expValueTable_data *) hcindex->data; if (!strcmp (StorageTmp->expExpressionOwner, thedata->expExpressionOwner) && (StorageTmp->expExpressionOwnerLen == thedata->expExpressionOwnerLen) && !strcmp(StorageTmp->expExpressionName, thedata->expExpressionName) && (StorageTmp->expExpressionNameLen == thedata->expExpressionNameLen) && !snmp_oid_compare(StorageTmp->expValueInstance, StorageTmp->expValueInstanceLen, thedata->expValueInstance, thedata->expValueInstanceLen)) { founded = 1; break; } } if (!founded) { header_complex_add_data(&expValueTableStorage, vars, thedata); DEBUGMSGTL(("expValueTable", "registered an entry\n")); } else { SNMP_FREE(thedata); DEBUGMSGTL(("expValueTable", "already have an entry, dont registe\n")); } DEBUGMSGTL(("expValueTable", "done.\n")); return SNMPERR_SUCCESS; }
/* only accepts read-only data */ int sipContactTable_replaceRow( struct sip_snmp_obj *idx, struct sip_snmp_obj *data) { netsnmp_table_row *row; netsnmp_variable_list *idxs=NULL; struct sip_snmp_obj *o; int col; static int applIndex = -1; const char *func = "snmp_mod"; if(applIndex == -1) { applIndex = ser_getApplIndex(); if(applIndex == -1 ) { LOG(L_ERR, "%s: Error while looking for previous row\n", func); return -1; } } /* create index list */ if(snmp_varlist_add_variable(&idxs, NULL, 0, ASN_INTEGER, (u_char*)&applIndex, sizeof(applIndex)) == NULL) { LOG(L_ERR, "%s: Error while looking for previous row\n", func); return -1; } o = idx; while(o) { if(snmp_varlist_add_variable(&idxs, NULL, 0, ser_types[o->type], o->value.voidp, o->val_len) == NULL) { LOG(L_ERR, "%s: Error while looking for row to replace\n", func); snmp_free_var(idxs); return -1; } o = o->next; } /* find row */ row = netsnmp_table_data_get(sipContactTable->table, idxs); if(!row) { LOG(L_ERR, "%s: Couldn't find row to replace\n", func); snmp_free_var(idxs); return -1; } snmp_free_var(idxs); /* add the data */ o = data; col = 2; while(o) { if(col > SIPCONTACTTABLE_COLUMNS) { LOG(L_ERR, "%s: Too many columns to add\n", func); return -1; } if(!o->value.voidp) { LOG(L_ERR, "%s: Invalid object to add\n", func); return -1; } o->col = col; /* all previous objects are left in the row */ if(netsnmp_set_row_column(row, col, ser_types[o->type], o->value.voidp, o->val_len) != SNMPERR_SUCCESS) { LOG(L_ERR, "%s: Error adding object to row\n", func); return -1; } o=o->next; col++; } return 0; }
/* * Retrieve the interface addressing information * XXX - This could also be extended to handle non-IP interfaces */ void _set_address( struct _if_info *cur_if ) { oid ipaddr_oid[] = { 1,3,6,1,2,1,4,20,1,0 }; size_t ipaddr_len = OID_LENGTH( ipaddr_oid ); static netsnmp_variable_list *addr_if_var =NULL; static netsnmp_variable_list *addr_mask_var=NULL; netsnmp_variable_list *vp, *vp2; union { in_addr_t addr; char data[4]; } tmpAddr; char *cp; in_addr_t ifAddr, mask; /* * Note that this information only needs to be retrieved * once, and can be re-used for subsequent calls. */ if ( addr_if_var == NULL ) { ipaddr_oid[ 9 ] = 2; /* ipAdEntIfIndex */ snmp_varlist_add_variable( &addr_if_var, ipaddr_oid, ipaddr_len, ASN_NULL, NULL, 0); netsnmp_query_walk( addr_if_var, ss ); ipaddr_oid[ 9 ] = 3; /* ipAdEntNetMask */ snmp_varlist_add_variable( &addr_mask_var, ipaddr_oid, ipaddr_len, ASN_NULL, NULL, 0); netsnmp_query_walk( addr_mask_var, ss ); } /* * Find the address row relevant to this interface */ for (vp=addr_if_var, vp2=addr_mask_var; vp; vp=vp->next_variable, vp2=vp2->next_variable) { if ( vp->val.integer && *vp->val.integer == cur_if->ifindex ) break; } if (vp2) { /* * Always want a numeric interface IP address */ snprintf( cur_if->ip, 128, "%lu.%lu.%lu.%lu", vp2->name[10], vp2->name[11], vp2->name[12], vp2->name[13]); /* * But re-use the routing table utilities/code for * displaying the local network information */ cp = tmpAddr.data; cp[0] = vp2->name[ 10 ] & 0xff; cp[1] = vp2->name[ 11 ] & 0xff; cp[2] = vp2->name[ 12 ] & 0xff; cp[3] = vp2->name[ 13 ] & 0xff; ifAddr = tmpAddr.addr; cp = tmpAddr.data; cp[0] = vp2->val.string[ 0 ] & 0xff; cp[1] = vp2->val.string[ 1 ] & 0xff; cp[2] = vp2->val.string[ 2 ] & 0xff; cp[3] = vp2->val.string[ 3 ] & 0xff; mask = tmpAddr.addr; snprintf( cur_if->route, 128, "%s", netname(ifAddr, mask)); } }
void SendIdeTrap(int trapID, cpqIdeAtaDiskTable_entry *disk) { static oid sysName[] = { 1, 3, 6, 1, 2, 1, 1, 5, 0 }; static oid cpqHoTrapFlags[] = { 1, 3, 6, 1, 4, 1, 232, 11, 2, 11, 1, 0 }; static oid cpqIdeAtaDiskControllerIndex[] = { 1, 3, 6, 1, 4, 1, 232, 14, 2, 4, 1, 1, 1 }; static oid cpqIdeAtaDiskIndex[] = { 1, 3, 6, 1, 4, 1, 232, 14, 2, 4, 1, 1, 2 }; static oid cpqIdeAtaDiskModel[] = { 1, 3, 6, 1, 4, 1, 232, 14, 2, 4, 1, 1, 3 }; static oid cpqIdeAtaDiskFwRev[] = { 1, 3, 6, 1, 4, 1, 232, 14, 2, 4, 1, 1, 4 }; static oid cpqIdeAtaDiskSerialNumber[] = { 1, 3, 6, 1, 4, 1, 232, 14, 2, 4, 1, 1, 5 }; static oid cpqIdeAtaDiskStatus[] = { 1, 3, 6, 1, 4, 1, 232, 14, 2, 4, 1, 1, 6 }; static oid cpqIdeAtaDiskChannel[] = { 1, 3, 6, 1, 4, 1, 232, 14, 2, 4, 1, 1, 11 }; static oid cpqIdeAtaDiskNumber[] = { 1, 3, 6, 1, 4, 1, 232, 14, 2, 4, 1, 1, 12 }; netsnmp_variable_list *var_list = NULL; snmp_varlist_add_variable(&var_list, sysName, sizeof(sysName) / sizeof(oid), ASN_OCTET_STR, (u_char *) "", 0); snmp_varlist_add_variable(&var_list, cpqHoTrapFlags, sizeof(cpqHoTrapFlags) / sizeof(oid), ASN_INTEGER, 0, sizeof(ASN_INTEGER)); snmp_varlist_add_variable(&var_list, cpqIdeAtaDiskControllerIndex, sizeof(cpqIdeAtaDiskControllerIndex)/sizeof(oid), ASN_INTEGER, (u_char *) &disk->cpqIdeAtaDiskControllerIndex, sizeof(ASN_INTEGER)); snmp_varlist_add_variable(&var_list, cpqIdeAtaDiskIndex, sizeof(cpqIdeAtaDiskIndex) / sizeof(oid), ASN_INTEGER, (u_char *) &disk->cpqIdeAtaDiskIndex, sizeof(ASN_INTEGER)); snmp_varlist_add_variable(&var_list, cpqIdeAtaDiskModel, sizeof(cpqIdeAtaDiskModel) / sizeof(oid), ASN_OCTET_STR, (u_char *) disk->cpqIdeAtaDiskModel, 0); snmp_varlist_add_variable(&var_list, cpqIdeAtaDiskFwRev, sizeof(cpqIdeAtaDiskFwRev) / sizeof(oid), ASN_OCTET_STR, (u_char *) disk->cpqIdeAtaDiskFwRev, 0); snmp_varlist_add_variable(&var_list, cpqIdeAtaDiskSerialNumber, sizeof(cpqIdeAtaDiskSerialNumber) / sizeof(oid), ASN_OCTET_STR, (u_char *) disk->cpqIdeAtaDiskSerialNumber, 0); snmp_varlist_add_variable(&var_list, cpqIdeAtaDiskStatus, sizeof(cpqIdeAtaDiskStatus) / sizeof(oid), ASN_INTEGER, (u_char *) &disk->cpqIdeAtaDiskStatus, sizeof(ASN_INTEGER)); snmp_varlist_add_variable(&var_list, cpqIdeAtaDiskChannel, sizeof(cpqIdeAtaDiskChannel) / sizeof(oid), ASN_INTEGER, (u_char *) &disk->cpqIdeAtaDiskChannel, sizeof(ASN_INTEGER)); snmp_varlist_add_variable(&var_list, cpqIdeAtaDiskNumber, sizeof(cpqIdeAtaDiskNumber) / sizeof(oid), ASN_INTEGER, (u_char *) &disk->cpqIdeAtaDiskNumber, sizeof(ASN_INTEGER)); }
netsnmp_variable_list * build_notification (const netsnmp_index * index, const trap_vars * var, const size_t var_len, const oid * notification_oid, const size_t notification_oid_len, const oid * root_table_oid, const size_t root_table_oid_len, const SaHpiDomainIdT domain_id, const oid * domain_id_oid, const size_t domain_id_oid_len, const SaHpiResourceIdT resource_id, const oid * resource_id_oid, const size_t resource_id_oid_len) { int i, j; netsnmp_variable_list *notification_vars = NULL; oid snmptrap[] = { snmptrap_oid }; oid full_oid[MAX_OID_LEN]; size_t full_oid_len; DEBUGMSGTL ((AGENT, "--- build_notification: Entry.\n")); if ((root_table_oid_len + 2 + index->len) > MAX_OID_LEN) { DEBUGMSGTL ((AGENT, "The length of the OID exceeds MAX_OID_LEN!\n")); return NULL; } // First is the Notification_OID snmp_varlist_add_variable (¬ification_vars, snmptrap, OID_LENGTH (snmptrap), ASN_OBJECT_ID, (const u_char *) (const oid *) notification_oid, notification_oid_len * sizeof (oid)); // Next the DomainID snmp_varlist_add_variable (¬ification_vars, domain_id_oid, domain_id_oid_len, ASN_UNSIGNED, (const u_char *) &domain_id, sizeof (SaHpiDomainIdT)); // The ResourceID snmp_varlist_add_variable (¬ification_vars, resource_id_oid, resource_id_oid_len, ASN_UNSIGNED, (const u_char *) &resource_id, sizeof (SaHpiResourceIdT)); // Attach the rest of information for (i = 0; i < var_len; i++) { // Generate the full OID. memcpy (full_oid, root_table_oid, root_table_oid_len * sizeof (oid)); full_oid_len = root_table_oid_len; // Get the column number. full_oid[full_oid_len++] = 1; full_oid[full_oid_len++] = var[i].column; // Put the index value in for (j = 0; j < index->len; j++) { full_oid[full_oid_len + j] = index->oids[j]; } full_oid_len += index->len; snmp_varlist_add_variable (¬ification_vars, full_oid, full_oid_len, var[i].type, var[i].value, var[i].value_len); } DEBUGMSGTL ((AGENT, "--- build_notification: Exit.\n")); return notification_vars; }
/* * send trap */ void run_mte_events(struct mteTriggerTable_data *item, oid * name_oid, size_t name_oid_len, const char *eventobjowner, const char *eventobjname) { static oid objid_snmptrap[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 }; /* snmpTrapIOD.0 */ netsnmp_variable_list *var_list = NULL; netsnmp_table_row *row, *notif_row; netsnmp_table_data_set_storage *col1, *tc, *no, *noo; for(row = table_set->table->first_row; row; row = row->next) { if (strcmp(row->indexes->val.string, eventobjowner) == 0 && strcmp(row->indexes->next_variable->val.string, eventobjname) == 0) { /* run this event */ col1 = (netsnmp_table_data_set_storage *) row->data; tc = netsnmp_table_data_set_find_column(col1, COLUMN_MTEEVENTACTIONS); if (!tc->data.bitstring[0] & 0x80) { /* not a notification. next! (XXX: do sets) */ continue; } tc = netsnmp_table_data_set_find_column(col1, COLUMN_MTEEVENTENABLED); if (*(tc->data.integer) != 1) { /* not enabled. next! */ continue; } if (!mteEventNotif_table_set) { /* no notification info */ continue; } /* send the notification */ var_list = NULL; /* XXX: get notif information */ for(notif_row = mteEventNotif_table_set->table->first_row; notif_row; notif_row = notif_row->next) { if (strcmp(notif_row->indexes->val.string, eventobjowner) == 0 && strcmp(notif_row->indexes->next_variable->val.string, eventobjname) == 0) { /* run this event */ col1 = (netsnmp_table_data_set_storage *) notif_row->data; tc = netsnmp_table_data_set_find_column(col1, COLUMN_MTEEVENTNOTIFICATION); no = netsnmp_table_data_set_find_column(col1, COLUMN_MTEEVENTNOTIFICATIONOBJECTS); noo = netsnmp_table_data_set_find_column(col1, COLUMN_MTEEVENTNOTIFICATIONOBJECTSOWNER); if (!tc) continue; /* no notification to be had. XXX: return? */ /* * snmpTrap oid */ snmp_varlist_add_variable(&var_list, objid_snmptrap, sizeof(objid_snmptrap) / sizeof(oid), ASN_OBJECT_ID, (u_char *) tc->data.objid, tc->data_len); /* XXX: add objects from the mteObjectsTable */ if (no && no->data.string && noo && noo->data.string && name_oid) { mte_add_objects(var_list, item, noo->data.string, no->data.string, name_oid + item->mteTriggerValueIDLen, name_oid_len - item->mteTriggerValueIDLen); } DEBUGMSGTL(("mteEventTable:send_events", "sending an event ")); DEBUGMSGOID(("mteEventTable:send_events", tc->data.objid, tc->data_len / sizeof(oid))); DEBUGMSG(("mteEventTable:send_events", "\n")); send_v2trap(var_list); snmp_free_varbind(var_list); } } } } }
void tcpprotopr(const char *name) { netsnmp_variable_list *var, *vp; oid tcpConnState_oid[] = { 1,3,6,1,2,1,6,13,1,1 }; size_t tcpConnState_len = OID_LENGTH( tcpConnState_oid ); int state, width; union { struct in_addr addr; char data[4]; } tmpAddr; oid localPort, remotePort; struct in_addr localAddr, remoteAddr; char *cp; int first = 1; /* * Walking the tcpConnState column will provide all * the necessary information. */ var = NULL; snmp_varlist_add_variable( &var, tcpConnState_oid, tcpConnState_len, ASN_NULL, NULL, 0); if (!var) return; if (netsnmp_query_walk( var, ss ) != SNMP_ERR_NOERROR) return; for (vp = var; vp ; vp=vp->next_variable) { state = *vp->val.integer; if (!aflag && state == MIB_TCPCONNSTATE_LISTEN) continue; if (first) { printf("Active Internet (%s) Connections", name); if (aflag) printf(" (including servers)"); putchar('\n'); width = Aflag ? 18 : 22; printf("%-5.5s %*.*s %*.*s %s\n", "Proto", -width, width, "Local Address", -width, width, "Remote Address", "(state)"); first=0; } /* Extract the local/remote information from the index values */ cp = tmpAddr.data; cp[0] = vp->name[ 10 ] & 0xff; cp[1] = vp->name[ 11 ] & 0xff; cp[2] = vp->name[ 12 ] & 0xff; cp[3] = vp->name[ 13 ] & 0xff; localAddr.s_addr = tmpAddr.addr.s_addr; localPort = ntohs((u_short)(vp->name[ 14 ])); cp = tmpAddr.data; cp[0] = vp->name[ 15 ] & 0xff; cp[1] = vp->name[ 16 ] & 0xff; cp[2] = vp->name[ 17 ] & 0xff; cp[3] = vp->name[ 18 ] & 0xff; remoteAddr.s_addr = tmpAddr.addr.s_addr; remotePort = ntohs((u_short)(vp->name[ 19 ])); printf("%-5.5s", name); inetprint(&localAddr, localPort, name, 1); inetprint(&remoteAddr, remotePort, name, 0); if ( state < 1 || state > TCP_NSTATES ) printf("%d\n", state ); else printf("%s\n", tcpstates[ state ]); } snmp_free_varbind( var ); }
/** here we send a SNMP v2 trap (which can be sent through snmpv3 and * snmpv1 as well) and send it out. */ void send_example_notification(unsigned int clientreg, void *clientarg) { /* * define the OID for the notification we're going to send * NET-SNMP-EXAMPLES-MIB::netSnmpExampleNotification */ oid notification_oid[] = { 1, 3, 6, 1, 4, 1, 8072, 2, 3, 1 }; size_t notification_oid_len = OID_LENGTH(notification_oid); /* * In the notification, we have to assign our notification OID to * the snmpTrapOID.0 object. Here is it's definition. */ oid objid_snmptrap[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 }; size_t objid_snmptrap_len = OID_LENGTH(objid_snmptrap); /* * here is where we store the variables to be sent in the trap */ netsnmp_variable_list *notification_vars = NULL; DEBUGMSGTL(("example_notification", "defining the trap\n")); /* * add in the trap definition object */ snmp_varlist_add_variable(¬ification_vars, /* * the snmpTrapOID.0 variable */ objid_snmptrap, objid_snmptrap_len, /* * value type is an OID */ ASN_OBJECT_ID, /* * value contents is our notification OID */ (u_char *) notification_oid, /* * size in bytes = oid length * sizeof(oid) */ notification_oid_len * sizeof(oid)); /* * if we wanted to insert additional objects, we'd do it here */ /* * send the trap out. This will send it to all registered * receivers (see the "SETTING UP TRAP AND/OR INFORM DESTINATIONS" * section of the snmpd.conf manual page. */ DEBUGMSGTL(("example_notification", "sending the trap\n")); send_v2trap(notification_vars); /* * free the created notification variable list */ DEBUGMSGTL(("example_notification", "cleaning up\n")); snmp_free_varbind(notification_vars); }
int write_snmpNotifyFilterProfileRowStatus(int action, u_char * var_val, u_char var_val_type, size_t var_val_len, u_char * statP, oid * name, size_t name_len) { struct snmpNotifyFilterProfileTable_data *StorageTmp = NULL; static struct snmpNotifyFilterProfileTable_data *StorageDel; size_t newlen = name_len - (sizeof(snmpNotifyFilterProfileTable_variables_oid) / sizeof(oid) + 3 - 1); static int old_value; int set_value = *((long *) var_val); netsnmp_variable_list *vars; struct header_complex_index *hciptr; DEBUGMSGTL(("snmpNotifyFilterProfileTable", "write_snmpNotifyFilterProfileRowStatus entering action=%d... \n", action)); StorageTmp = (struct snmpNotifyFilterProfileTable_data *) header_complex((struct header_complex_index *) snmpNotifyFilterProfileTableStorage, NULL, &name[sizeof (snmpNotifyFilterProfileTable_variables_oid) / sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL); switch (action) { case RESERVE1: if (var_val_type != ASN_INTEGER || var_val == NULL) { return SNMP_ERR_WRONGTYPE; } if (var_val_len != sizeof(long)) { return SNMP_ERR_WRONGLENGTH; } if (set_value < 1 || set_value > 6 || set_value == RS_NOTREADY) { return SNMP_ERR_WRONGVALUE; } /* * stage one: test validity */ if (StorageTmp == NULL) { /* * create the row now? */ /* * ditch illegal values now */ if (set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE) { return SNMP_ERR_INCONSISTENTVALUE; } } else { /* * row exists. Check for a valid state change */ if (set_value == RS_CREATEANDGO || set_value == RS_CREATEANDWAIT) { /* * can't create a row that exists */ return SNMP_ERR_INCONSISTENTVALUE; } if ((set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE) && StorageTmp->snmpNotifyFilterProfileNameLen == 0) { /* * can't activate row without a profile name */ return SNMP_ERR_INCONSISTENTVALUE; } /* * XXX: interaction with row storage type needed */ } /* * memory reseveration, final preparation... */ if (StorageTmp == NULL && (set_value == RS_CREATEANDGO || set_value == RS_CREATEANDWAIT)) { /* * creation */ vars = NULL; snmp_varlist_add_variable(&vars, NULL, 0, ASN_PRIV_IMPLIED_OCTET_STR, NULL, 0); if (header_complex_parse_oid (& (name [sizeof(snmpNotifyFilterProfileTable_variables_oid) / sizeof(oid) + 2]), newlen, vars) != SNMPERR_SUCCESS) { snmp_free_var(vars); return SNMP_ERR_INCONSISTENTNAME; } StorageNew = SNMP_MALLOC_STRUCT(snmpNotifyFilterProfileTable_data); if (StorageNew == NULL) return SNMP_ERR_GENERR; memdup((u_char **) & (StorageNew->snmpTargetParamsName), vars->val.string, vars->val_len); StorageNew->snmpTargetParamsNameLen = vars->val_len; StorageNew->snmpNotifyFilterProfileStorType = ST_NONVOLATILE; StorageNew->snmpNotifyFilterProfileRowStatus = RS_NOTREADY; snmp_free_var(vars); } break; case RESERVE2: break; case FREE: /* * XXX: free, zero vars */ /* * Release any resources that have been allocated */ if (StorageNew != NULL) { SNMP_FREE(StorageNew->snmpTargetParamsName); SNMP_FREE(StorageNew->snmpNotifyFilterProfileName); free(StorageNew); StorageNew = NULL; } break; case ACTION: /* * The variable has been stored in set_value for you to * use, and you have just been asked to do something with * it. Note that anything done here must be reversable in * the UNDO case */ if (StorageTmp == NULL && (set_value == RS_CREATEANDGO || set_value == RS_CREATEANDWAIT)) { /* * row creation, so add it */ if (StorageNew != NULL) snmpNotifyFilterProfileTable_add(StorageNew); /* * XXX: ack, and if it is NULL? */ } else if (set_value != RS_DESTROY) { /* * set the flag? */ if (StorageTmp == NULL) return SNMP_ERR_GENERR; /* should never ever get here */ old_value = StorageTmp->snmpNotifyFilterProfileRowStatus; StorageTmp->snmpNotifyFilterProfileRowStatus = *((long *) var_val); } else { /* * destroy... extract it for now */ if (StorageTmp) { hciptr = header_complex_find_entry (snmpNotifyFilterProfileTableStorage, StorageTmp); StorageDel = (struct snmpNotifyFilterProfileTable_data *) header_complex_extract_entry((struct header_complex_index **) &snmpNotifyFilterProfileTableStorage, hciptr); } } break; case UNDO: /* * Back out any changes made in the ACTION case */ if (StorageTmp == NULL && (set_value == RS_CREATEANDGO || set_value == RS_CREATEANDWAIT)) { /* * row creation, so remove it again */ hciptr = header_complex_find_entry (snmpNotifyFilterProfileTableStorage, StorageNew); StorageDel = (struct snmpNotifyFilterProfileTable_data *) header_complex_extract_entry((struct header_complex_index **) &snmpNotifyFilterProfileTableStorage, hciptr); /* * XXX: free it */ } else if (StorageDel != NULL) { /* * row deletion, so add it again */ snmpNotifyFilterProfileTable_add(StorageDel); StorageDel = NULL; } else if (set_value != RS_DESTROY) { if (StorageTmp) StorageTmp->snmpNotifyFilterProfileRowStatus = old_value; } break; case COMMIT: /* * Things are working well, so it's now safe to make the change * permanently. Make sure that anything done here can't fail! */ if (StorageDel != NULL) { SNMP_FREE(StorageDel->snmpTargetParamsName); SNMP_FREE(StorageDel->snmpNotifyFilterProfileName); free(StorageDel); StorageDel = NULL; } if (StorageTmp && set_value == RS_CREATEANDGO) { if (StorageTmp->snmpNotifyFilterProfileNameLen) StorageTmp->snmpNotifyFilterProfileRowStatus = RS_ACTIVE; StorageNew = NULL; } else if (StorageTmp && set_value == RS_CREATEANDWAIT) { if (StorageTmp->snmpNotifyFilterProfileNameLen) StorageTmp->snmpNotifyFilterProfileRowStatus = RS_NOTINSERVICE; StorageNew = NULL; } break; } return SNMP_ERR_NOERROR; }
int write_expExpressionEntryStatus(int action, u_char * var_val, u_char var_val_type, size_t var_val_len, u_char * statP, oid * name, size_t name_len) { struct expExpressionTable_data *StorageTmp = NULL; static struct expExpressionTable_data *StorageNew, *StorageDel; size_t newlen = name_len - (sizeof(expExpressionTable_variables_oid) / sizeof(oid) + 3 - 1); static int old_value; int set_value; static netsnmp_variable_list *vars, *vp; struct header_complex_index *hciptr; StorageTmp = header_complex(expExpressionTableStorage, NULL, &name[sizeof(expExpressionTable_variables_oid) / sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL); if (var_val_type != ASN_INTEGER || var_val == NULL) { snmp_log(LOG_ERR, "write to expExpressionEntryStatus not ASN_INTEGER\n"); return SNMP_ERR_WRONGTYPE; } set_value = *((long *) var_val); /* * check legal range, and notReady is reserved for us, not a user */ if (set_value < 1 || set_value > 6 || set_value == RS_NOTREADY) return SNMP_ERR_INCONSISTENTVALUE; switch (action) { case RESERVE1: /* * stage one: test validity */ if (StorageTmp == NULL) { /* * create the row now? */ /* * ditch illegal values now */ if (set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE) return SNMP_ERR_INCONSISTENTVALUE; /* * destroying a non-existent row is actually legal */ if (set_value == RS_DESTROY) { return SNMP_ERR_NOERROR; } /* * illegal creation values */ if (set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE) { return SNMP_ERR_INCONSISTENTVALUE; } } else { /* * row exists. Check for a valid state change */ if (set_value == RS_CREATEANDGO || set_value == RS_CREATEANDWAIT) { /* * can't create a row that exists */ return SNMP_ERR_INCONSISTENTVALUE; } if (StorageTmp->expExpressionEntryStatus == RS_ACTIVE && set_value != RS_DESTROY) { /* * "Once made active an entry may not be modified except to * delete it." XXX: doesn't this in fact apply to ALL * columns of the table and not just this one? */ return SNMP_ERR_INCONSISTENTVALUE; } if (StorageTmp->storageType != ST_NONVOLATILE) return SNMP_ERR_NOTWRITABLE; } break; case RESERVE2: /* * memory reseveration, final preparation... */ if (StorageTmp == NULL) { /* * creation */ vars = NULL; snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, NULL, 0); /* expExpressionOwner */ snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, NULL, 0); /* expExpressionName */ if (header_complex_parse_oid (& (name [sizeof(expExpressionTable_variables_oid) / sizeof(oid) + 2]), newlen, vars) != SNMPERR_SUCCESS) { /* * XXX: free, zero vars */ return SNMP_ERR_INCONSISTENTNAME; } vp = vars; StorageNew = create_expExpressionTable_data(); StorageNew->expExpressionOwner = malloc(vp->val_len + 1); memcpy(StorageNew->expExpressionOwner, vp->val.string, vp->val_len); StorageNew->expExpressionOwner[vp->val_len] = '\0'; StorageNew->expExpressionOwnerLen = vp->val_len; vp = vp->next_variable; StorageNew->expExpressionName = malloc(vp->val_len + 1); memcpy(StorageNew->expExpressionName, vp->val.string, vp->val_len); StorageNew->expExpressionName[vp->val_len] = '\0'; StorageNew->expExpressionNameLen = vp->val_len; vp = vp->next_variable; StorageNew->expExpressionEntryStatus = set_value; } break; case FREE: /* * XXX: free, zero vars */ /* * Release any resources that have been allocated */ break; case ACTION: /* * The variable has been stored in set_value for you to * use, and you have just been asked to do something with * it. Note that anything done here must be reversable in * the UNDO case */ if (StorageTmp == NULL) { /* * row creation, so add it */ if (StorageNew != NULL) expExpressionTable_add(StorageNew); /* * XXX: ack, and if it is NULL? */ } else if (set_value != RS_DESTROY) { /* * set the flag? */ old_value = StorageTmp->expExpressionEntryStatus; StorageTmp->expExpressionEntryStatus = *((long *) var_val); } else { /* * destroy... extract it for now */ hciptr = header_complex_find_entry(expExpressionTableStorage, StorageTmp); StorageDel = header_complex_extract_entry(&expExpressionTableStorage, hciptr); } break; case UNDO: /* * Back out any changes made in the ACTION case */ if (StorageTmp == NULL) { /* * row creation, so remove it again */ hciptr = header_complex_find_entry(expExpressionTableStorage, StorageTmp); StorageDel = header_complex_extract_entry(&expExpressionTableStorage, hciptr); /* * XXX: free it */ } else if (StorageDel != NULL) { /* * row deletion, so add it again */ expExpressionTable_add(StorageDel); } else { StorageTmp->expExpressionEntryStatus = old_value; } break; case COMMIT: /* * Things are working well, so it's now safe to make the change * permanently. Make sure that anything done here can't fail! */ if (StorageDel != NULL) { StorageDel = 0; /* * XXX: free it, its dead */ } else { if (StorageTmp && StorageTmp->expExpressionEntryStatus == RS_CREATEANDGO) { StorageTmp->expExpressionEntryStatus = RS_ACTIVE; } else if (StorageTmp && StorageTmp->expExpressionEntryStatus == RS_CREATEANDWAIT) { StorageTmp->expExpressionEntryStatus = RS_NOTINSERVICE; } } if (StorageTmp && StorageTmp->expExpressionEntryStatus == RS_ACTIVE && !StorageTmp->have_copied_auth_info) { netsnmp_agent_session *asp = netsnmp_get_current_agent_session(); netsnmp_pdu *pdu = NULL; if (!asp) { snmp_log(LOG_ERR, "snmpTriggerTable: can't get master session for authentication params\n"); } else { pdu = asp->orig_pdu; if (!pdu) { snmp_log(LOG_ERR, "snmpTriggerTable: can't get master pdu for authentication params\n"); } } if (pdu) { DEBUGMSGTL(("expExpressionTest", "copying PDU auth info\n")); StorageTmp->pdu_version = pdu->version; StorageTmp->pdu_securityModel = pdu->securityModel; StorageTmp->pdu_securityLevel = pdu->securityLevel; StorageTmp->pdu_tDomain = pdu->tDomain; StorageTmp->pdu_tDomainLen = pdu->tDomainLen; if (pdu->transport_data != NULL) { StorageTmp->pdu_transport = malloc(pdu->transport_data_length); memcpy(StorageTmp->pdu_transport, pdu->transport_data, pdu->transport_data_length); } StorageTmp->pdu_transportLen = pdu->transport_data_length; if (pdu->community) { StorageTmp->pdu_community = calloc(1, pdu->community_len + 1); memcpy(StorageTmp->pdu_community, pdu->community, pdu->community_len); StorageTmp->pdu_community_len = pdu->community_len; } else { StorageTmp->pdu_community = NULL; StorageTmp->pdu_community_len = 0; } if (pdu->securityName) { StorageTmp->pdu_securityName = calloc(1, pdu->securityNameLen + 1); memcpy(StorageTmp->pdu_securityName, pdu->securityName, pdu->securityNameLen); StorageTmp->pdu_securityNameLen = pdu->securityNameLen; } else { StorageTmp->pdu_securityName = NULL; StorageTmp->pdu_securityNameLen = 0; } StorageTmp->have_copied_auth_info = 1; } } break; } return SNMP_ERR_NOERROR; }
/** * This function allows you to make a distinction between generic * traps from different classes of equipment. For example, you may want * to handle a SNMP_TRAP_LINKDOWN trap for a particular device in a * different manner to a generic system SNMP_TRAP_LINKDOWN trap. * * * @param trap is the generic trap type. The trap types are: * - SNMP_TRAP_COLDSTART: * cold start * - SNMP_TRAP_WARMSTART: * warm start * - SNMP_TRAP_LINKDOWN: * link down * - SNMP_TRAP_LINKUP: * link up * - SNMP_TRAP_AUTHFAIL: * authentication failure * - SNMP_TRAP_EGPNEIGHBORLOSS: * egp neighbor loss * - SNMP_TRAP_ENTERPRISESPECIFIC: * enterprise specific * * @param specific is the specific trap value. * * @param enterprise is an enterprise oid in which you want to send specifc * traps from. * * @param enterprise_length is the length of the enterprise oid, use macro, * OID_LENGTH, to compute length. * * @param vars is used to supply list of variable bindings to form an SNMPv2 * trap. * * @param context currently unused * * @param flags currently unused * * @return void * * @see send_easy_trap * @see send_v2trap */ int netsnmp_send_traps(int trap, int specific, oid * enterprise, int enterprise_length, netsnmp_variable_list * vars, char * context, int flags) { netsnmp_pdu *template_v1pdu; netsnmp_pdu *template_v2pdu; netsnmp_variable_list *vblist = NULL; netsnmp_variable_list *trap_vb; netsnmp_variable_list *var; in_addr_t *pdu_in_addr_t; u_long uptime; struct trap_sink *sink; DEBUGMSGTL(( "trap", "send_trap %d %d ", trap, specific)); DEBUGMSGOID(("trap", enterprise, enterprise_length)); DEBUGMSG(( "trap", "\n")); if (vars) { vblist = snmp_clone_varbind( vars ); if (!vblist) { snmp_log(LOG_WARNING, "send_trap: failed to clone varbind list\n"); return -1; } } if ( trap == -1 ) { /* * Construct the SNMPv2-style notification PDU */ if (!vblist) { snmp_log(LOG_WARNING, "send_trap: called with NULL v2 information\n"); return -1; } template_v2pdu = snmp_pdu_create(SNMP_MSG_TRAP2); if (!template_v2pdu) { snmp_log(LOG_WARNING, "send_trap: failed to construct v2 template PDU\n"); snmp_free_varbind(vblist); return -1; } /* * Check the varbind list we've been given. * If it starts with a 'sysUptime.0' varbind, then use that. * Otherwise, prepend a suitable 'sysUptime.0' varbind. */ if (!snmp_oid_compare( vblist->name, vblist->name_length, sysuptime_oid, sysuptime_oid_len )) { template_v2pdu->variables = vblist; trap_vb = vblist->next_variable; } else { uptime = netsnmp_get_agent_uptime(); var = NULL; snmp_varlist_add_variable( &var, sysuptime_oid, sysuptime_oid_len, ASN_TIMETICKS, (u_char*)&uptime, sizeof(uptime)); if (!var) { snmp_log(LOG_WARNING, "send_trap: failed to insert sysUptime varbind\n"); snmp_free_pdu(template_v2pdu); snmp_free_varbind(vblist); return -1; } template_v2pdu->variables = var; var->next_variable = vblist; trap_vb = vblist; } /* * 'trap_vb' should point to the snmpTrapOID.0 varbind, * identifying the requested trap. If not then bomb out. * If it's a 'standard' trap, then we need to append an * snmpEnterprise varbind (if there isn't already one). */ if (!trap_vb || snmp_oid_compare(trap_vb->name, trap_vb->name_length, snmptrap_oid, snmptrap_oid_len)) { snmp_log(LOG_WARNING, "send_trap: no v2 trapOID varbind provided\n"); snmp_free_pdu(template_v2pdu); return -1; } if (!snmp_oid_compare(vblist->val.objid, OID_LENGTH(trap_prefix), trap_prefix, OID_LENGTH(trap_prefix))) { var = find_varbind_in_list( template_v2pdu->variables, snmptrapenterprise_oid, snmptrapenterprise_oid_len); if (!var && !snmp_varlist_add_variable( &(template_v2pdu->variables), snmptrapenterprise_oid, snmptrapenterprise_oid_len, ASN_OBJECT_ID, (char*)enterprise, enterprise_length*sizeof(oid))) { snmp_log(LOG_WARNING, "send_trap: failed to add snmpEnterprise to v2 trap\n"); snmp_free_pdu(template_v2pdu); return -1; } } /* * If everything's OK, convert the v2 template into an SNMPv1 trap PDU. */ template_v1pdu = convert_v2pdu_to_v1( template_v2pdu ); if (!template_v1pdu) { snmp_log(LOG_WARNING, "send_trap: failed to convert v2->v1 template PDU\n"); snmp_free_pdu(template_v2pdu); return -1; } } else { /* * Construct the SNMPv1 trap PDU.... */ template_v1pdu = snmp_pdu_create(SNMP_MSG_TRAP); if (!template_v1pdu) { snmp_log(LOG_WARNING, "send_trap: failed to construct v1 template PDU\n"); snmp_free_varbind(vblist); return -1; } template_v1pdu->trap_type = trap; template_v1pdu->specific_type = specific; template_v1pdu->time = netsnmp_get_agent_uptime(); if (snmp_clone_mem((void **) &template_v1pdu->enterprise, enterprise, enterprise_length * sizeof(oid))) { snmp_log(LOG_WARNING, "send_trap: failed to set v1 enterprise OID\n"); snmp_free_varbind(vblist); snmp_free_pdu(template_v1pdu); return -1; } template_v1pdu->enterprise_length = enterprise_length; template_v1pdu->flags |= UCD_MSG_FLAG_FORCE_PDU_COPY; template_v1pdu->variables = vblist; /* * ... and convert it into an SNMPv2-style notification PDU. */ template_v2pdu = convert_v1pdu_to_v2( template_v1pdu ); if (!template_v2pdu) { snmp_log(LOG_WARNING, "send_trap: failed to convert v1->v2 template PDU\n"); snmp_free_pdu(template_v1pdu); return -1; } } /* * Check whether we're ignoring authFail traps */ if (template_v1pdu->trap_type == SNMP_TRAP_AUTHFAIL && snmp_enableauthentraps == SNMP_AUTHENTICATED_TRAPS_DISABLED) { snmp_free_pdu(template_v1pdu); snmp_free_pdu(template_v2pdu); return 0; } /* * Ensure that the v1 trap PDU includes the local IP address */ pdu_in_addr_t = (in_addr_t *) template_v1pdu->agent_addr; *pdu_in_addr_t = get_myaddr(); /* * Now loop through the list of trap sinks * and call the trap callback routines, * providing an appropriately formatted PDU in each case */ for (sink = sinks; sink; sink = sink->next) { #ifndef DISABLE_SNMPV1 if (sink->version == SNMP_VERSION_1) { send_trap_to_sess(sink->sesp, template_v1pdu); } else { #endif template_v2pdu->command = sink->pdutype; send_trap_to_sess(sink->sesp, template_v2pdu); #ifndef DISABLE_SNMPV1 } #endif } snmp_call_callbacks(SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_SEND_TRAP1, template_v1pdu); snmp_call_callbacks(SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_SEND_TRAP2, template_v2pdu); snmp_free_pdu(template_v1pdu); snmp_free_pdu(template_v2pdu); return 0; }
netsnmp_variable_list * register_index(netsnmp_variable_list * varbind, int flags, netsnmp_session * ss) { netsnmp_variable_list *rv = NULL; struct snmp_index *new_index, *idxptr, *idxptr2; struct snmp_index *prev_oid_ptr, *prev_idx_ptr; int res, res2, i; DEBUGMSGTL(("register_index", "register ")); DEBUGMSGVAR(("register_index", varbind)); DEBUGMSG(("register_index", "for session %8p\n", ss)); #if defined(USING_AGENTX_SUBAGENT_MODULE) && !defined(TESTING) if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE) == SUB_AGENT) { return (agentx_register_index(ss, varbind, flags)); } #endif /* * Look for the requested OID entry */ prev_oid_ptr = NULL; prev_idx_ptr = NULL; res = 1; res2 = 1; for (idxptr = snmp_index_head; idxptr != NULL; prev_oid_ptr = idxptr, idxptr = idxptr->next_oid) { if ((res = snmp_oid_compare(varbind->name, varbind->name_length, idxptr->varbind->name, idxptr->varbind->name_length)) <= 0) break; } /* * Found the OID - now look at the registered indices */ if (res == 0 && idxptr) { if (varbind->type != idxptr->varbind->type) return NULL; /* wrong type */ /* * If we've been asked for an arbitrary new value, * then find the end of the list. * If we've been asked for any arbitrary value, * then look for an unused entry, and use that. * If there aren't any, continue as for new. * Otherwise, locate the given value in the (sorted) * list of already allocated values */ if (flags & ALLOCATE_ANY_INDEX) { for (idxptr2 = idxptr; idxptr2 != NULL; prev_idx_ptr = idxptr2, idxptr2 = idxptr2->next_idx) { if (flags == ALLOCATE_ANY_INDEX && !(idxptr2->allocated)) { if ((rv = snmp_clone_varbind(idxptr2->varbind)) != NULL) { idxptr2->session = ss; idxptr2->allocated = 1; } return rv; } } } else { for (idxptr2 = idxptr; idxptr2 != NULL; prev_idx_ptr = idxptr2, idxptr2 = idxptr2->next_idx) { switch (varbind->type) { case ASN_INTEGER: res2 = (*varbind->val.integer - *idxptr2->varbind->val.integer); break; case ASN_OCTET_STR: i = SNMP_MIN(varbind->val_len, idxptr2->varbind->val_len); res2 = memcmp(varbind->val.string, idxptr2->varbind->val.string, i); break; case ASN_OBJECT_ID: res2 = snmp_oid_compare(varbind->val.objid, varbind->val_len / sizeof(oid), idxptr2->varbind->val.objid, idxptr2->varbind->val_len / sizeof(oid)); break; default: return NULL; /* wrong type */ } if (res2 <= 0) break; } if (res2 == 0) { if (idxptr2->allocated) { /* * No good: the index is in use. */ return NULL; } else { /* * Okay, it's unallocated, we can just claim ownership * here. */ if ((rv = snmp_clone_varbind(idxptr2->varbind)) != NULL) { idxptr2->session = ss; idxptr2->allocated = 1; } return rv; } } } } /* * OK - we've now located where the new entry needs to * be fitted into the index registry tree * To recap: * 'prev_oid_ptr' points to the head of the OID index * list prior to this one. If this is null, then * it means that this is the first OID in the list. * 'idxptr' points either to the head of this OID list, * or the next OID (if this is a new OID request) * These can be distinguished by the value of 'res'. * * 'prev_idx_ptr' points to the index entry that sorts * immediately prior to the requested value (if any). * If an arbitrary value is required, then this will * point to the last allocated index. * If this pointer is null, then either this is a new * OID request, or the requested value is the first * in the list. * 'idxptr2' points to the next sorted index (if any) * but is not actually needed any more. * * Clear? Good! * I hope you've been paying attention. * There'll be a test later :-) */ /* * We proceed by creating the new entry * (by copying the entry provided) */ new_index = (struct snmp_index *) calloc(1, sizeof(struct snmp_index)); if (new_index == NULL) return NULL; if (NULL == snmp_varlist_add_variable(&new_index->varbind, varbind->name, varbind->name_length, varbind->type, varbind->val.string, varbind->val_len)) { /* * if (snmp_clone_var( varbind, new_index->varbind ) != 0 ) */ free(new_index); return NULL; } new_index->session = ss; new_index->allocated = 1; if (varbind->type == ASN_OCTET_STR && flags == ALLOCATE_THIS_INDEX) new_index->varbind->val.string[new_index->varbind->val_len] = 0; /* * If we've been given a value, then we can use that, but * otherwise, we need to create a new value for this entry. * Note that ANY_INDEX and NEW_INDEX are both covered by this * test (since NEW_INDEX & ANY_INDEX = ANY_INDEX, remember?) */ if (flags & ALLOCATE_ANY_INDEX) { if (prev_idx_ptr) { if (snmp_clone_var(prev_idx_ptr->varbind, new_index->varbind) != 0) { free(new_index); return NULL; } } else new_index->varbind->val.string = new_index->varbind->buf; switch (varbind->type) { case ASN_INTEGER: if (prev_idx_ptr) { (*new_index->varbind->val.integer)++; } else *(new_index->varbind->val.integer) = 1; new_index->varbind->val_len = sizeof(long); break; case ASN_OCTET_STR: if (prev_idx_ptr) { i = new_index->varbind->val_len - 1; while (new_index->varbind->buf[i] == 'z') { new_index->varbind->buf[i] = 'a'; i--; if (i < 0) { i = new_index->varbind->val_len; new_index->varbind->buf[i] = 'a'; new_index->varbind->buf[i + 1] = 0; } } new_index->varbind->buf[i]++; } else strcpy((char *) new_index->varbind->buf, "aaaa"); new_index->varbind->val_len = strlen((char *) new_index->varbind->buf); break; case ASN_OBJECT_ID: if (prev_idx_ptr) { i = prev_idx_ptr->varbind->val_len / sizeof(oid) - 1; while (new_index->varbind->val.objid[i] == 255) { new_index->varbind->val.objid[i] = 1; i--; if (i == 0 && new_index->varbind->val.objid[0] == 2) { new_index->varbind->val.objid[0] = 1; i = new_index->varbind->val_len / sizeof(oid); new_index->varbind->val.objid[i] = 0; new_index->varbind->val_len += sizeof(oid); } } new_index->varbind->val.objid[i]++; } else { /* * If the requested OID name is small enough, * * append another OID (1) and use this as the * * default starting value for new indexes. */ if ((varbind->name_length + 1) * sizeof(oid) <= 40) { for (i = 0; i < (int) varbind->name_length; i++) new_index->varbind->val.objid[i] = varbind->name[i]; new_index->varbind->val.objid[varbind->name_length] = 1; new_index->varbind->val_len = (varbind->name_length + 1) * sizeof(oid); } else { /* * Otherwise use '.1.1.1.1...' */ i = 40 / sizeof(oid); if (i > 4) i = 4; new_index->varbind->val_len = i * (sizeof(oid)); for (i--; i >= 0; i--) new_index->varbind->val.objid[i] = 1; } } break; default: snmp_free_var(new_index->varbind); free(new_index); return NULL; /* Index type not supported */ } } /* * Try to duplicate the new varbind for return. */ if ((rv = snmp_clone_varbind(new_index->varbind)) == NULL) { snmp_free_var(new_index->varbind); free(new_index); return NULL; } /* * Right - we've set up the new entry. * All that remains is to link it into the tree. * There are a number of possible cases here, * so watch carefully. */ if (prev_idx_ptr) { new_index->next_idx = prev_idx_ptr->next_idx; new_index->next_oid = prev_idx_ptr->next_oid; prev_idx_ptr->next_idx = new_index; } else { if (res == 0 && idxptr) { new_index->next_idx = idxptr; new_index->next_oid = idxptr->next_oid; } else { new_index->next_idx = NULL; new_index->next_oid = idxptr; } if (prev_oid_ptr) { while (prev_oid_ptr) { prev_oid_ptr->next_oid = new_index; prev_oid_ptr = prev_oid_ptr->next_idx; } } else snmp_index_head = new_index; } return rv; }
/* * Unlike the equivalent IPv4 statistics display routine, * the IPv6 version must walk the columns of a table * and total the statistics for each column (rather * than simply retrieving individual scalar values) */ void _dump_v6stats( const char *name, oid *oid_buf, size_t buf_len, struct stat_table *stable ) { netsnmp_variable_list *var, *vp; struct stat_table *sp; long *stats; oid stat; unsigned int max_stat = 0; int active = 0; var = NULL; for (sp=stable; sp->entry; sp++) { oid_buf[buf_len-1] = sp->entry; if (sp->entry > max_stat) max_stat = sp->entry; snmp_varlist_add_variable( &var, oid_buf, buf_len, ASN_NULL, NULL, 0); } oid_buf[buf_len-1] = stable[0].entry; stats = (long *)calloc(max_stat+1, sizeof(long)); /* * Walk the specified column(s), and total the individual statistics */ while (1) { if (netsnmp_query_getnext( var, ss ) != SNMP_ERR_NOERROR) break; if ((var->type & 0xF0) == 0x80) /* exception */ break; if ( snmp_oid_compare( oid_buf, buf_len, var->name, buf_len) != 0 ) break; /* End of Table */ for ( vp=var; vp; vp=vp->next_variable ) { stat = vp->name[ buf_len-1 ]; stats[stat] += *vp->val.integer; } active=1; } if (!active) { free( stats ); snmp_free_varbind( var ); return; /* No statistics to display */ } /* * Display the results */ printf("%s:\n", name); for (sp=stable; sp->entry; sp++) { /* * If '-Cs' was specified twice, * then only display non-zero stats. */ if ( stats[sp->entry] > 0 || sflag == 1 ) { printf(sp->description, stats[sp->entry], plural(stats[sp->entry])); putchar('\n'); } } free( stats ); snmp_free_varbind( var ); }
int write_mteObjectsEntryStatus(int action, u_char * var_val, u_char var_val_type, size_t var_val_len, u_char * statP, oid * name, size_t name_len) { struct mteObjectsTable_data *StorageTmp = NULL; static struct mteObjectsTable_data *StorageNew, *StorageDel; size_t newlen = name_len - (sizeof(mteObjectsTable_variables_oid) / sizeof(oid) + 3 - 1); static int old_value; int set_value; static netsnmp_variable_list *vars, *vp; struct header_complex_index *hciptr; StorageTmp = header_complex(mteObjectsTableStorage, NULL, &name[sizeof(mteObjectsTable_variables_oid) / sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL); if (var_val_type != ASN_INTEGER || var_val == NULL) { snmp_log(LOG_ERR, "write to mteObjectsEntryStatus not ASN_INTEGER\n"); return SNMP_ERR_WRONGTYPE; } if (StorageTmp && StorageTmp->storagetype == ST_READONLY) { return SNMP_ERR_NOTWRITABLE; } set_value = *((long *) var_val); /* * check legal range, and notReady is reserved for us, not a user */ if (set_value < 1 || set_value > 6 || set_value == RS_NOTREADY) return SNMP_ERR_INCONSISTENTVALUE; switch (action) { case RESERVE1: /* * stage one: test validity */ if (StorageTmp == NULL) { /* * create the row now? */ /* * ditch illegal values now */ if (set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE) return SNMP_ERR_INCONSISTENTVALUE; /* * destroying a non-existent row is actually legal */ if (set_value == RS_DESTROY) { return SNMP_ERR_NOERROR; } /* * illegal creation values */ if (set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE) { return SNMP_ERR_INCONSISTENTVALUE; } } else { /* * row exists. Check for a valid state change */ if (set_value == RS_CREATEANDGO || set_value == RS_CREATEANDWAIT) { /* * can't create a row that exists */ return SNMP_ERR_INCONSISTENTVALUE; } /* * XXX: interaction with row storage type needed */ } break; case RESERVE2: /* * memory reseveration, final preparation... */ if (StorageTmp == NULL) { /* * creation */ vars = NULL; snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, NULL, 0); /* mteOwner */ snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, NULL, 0); /* mteObjectsName */ snmp_varlist_add_variable(&vars, NULL, 0, ASN_UNSIGNED, NULL, 0); /* mteObjectsIndex */ if (header_complex_parse_oid (& (name [sizeof(mteObjectsTable_variables_oid) / sizeof(oid) + 2]), newlen, vars) != SNMPERR_SUCCESS) { /* * XXX: free, zero vars */ return SNMP_ERR_INCONSISTENTNAME; } vp = vars; StorageNew = SNMP_MALLOC_STRUCT(mteObjectsTable_data); if (StorageNew == NULL) return SNMP_ERR_GENERR; StorageNew->mteOwner = netsnmp_strdup_and_null(vp->val.string, vp->val_len); StorageNew->mteOwnerLen = vp->val_len; vp = vp->next_variable; StorageNew->mteObjectsName = netsnmp_strdup_and_null(vp->val.string, vp->val_len); StorageNew->mteObjectsNameLen = vp->val_len; vp = vp->next_variable; StorageNew->mteObjectsIndex = *(vp->val.integer); /* * XXX: fill in default row values here into StorageNew */ StorageNew->mteObjectsID = calloc(1, sizeof(oid) * sizeof(2)); /* 0.0 */ StorageNew->mteObjectsIDLen = 2; StorageNew->mteObjectsIDWildcard = MTEOBJECTSIDWILDCARD_FALSE; StorageNew->mteObjectsEntryStatus = set_value; /* * XXX: free, zero vars, no longer needed? */ } break; case FREE: /* * XXX: free, zero vars */ /* * Release any resources that have been allocated */ break; case ACTION: /* * The variable has been stored in set_value for you to * use, and you have just been asked to do something with * it. Note that anything done here must be reversable in * the UNDO case */ if (StorageTmp == NULL) { /* * row creation, so add it */ if (StorageNew != NULL) mteObjectsTable_add(StorageNew); /* * XXX: ack, and if it is NULL? */ } else if (set_value != RS_DESTROY) { /* * set the flag? */ old_value = StorageTmp->mteObjectsEntryStatus; StorageTmp->mteObjectsEntryStatus = *((long *) var_val); } else { /* * destroy... extract it for now */ hciptr = header_complex_find_entry(mteObjectsTableStorage, StorageTmp); StorageDel = header_complex_extract_entry(&mteObjectsTableStorage, hciptr); } break; case UNDO: /* * Back out any changes made in the ACTION case */ if (StorageTmp == NULL) { /* * row creation, so remove it again */ hciptr = header_complex_find_entry(mteObjectsTableStorage, StorageTmp); StorageDel = header_complex_extract_entry(&mteObjectsTableStorage, hciptr); /* * XXX: free it */ } else if (StorageDel != NULL) { /* * row deletion, so add it again */ mteObjectsTable_add(StorageDel); } else { StorageTmp->mteObjectsEntryStatus = old_value; } break; case COMMIT: /* * Things are working well, so it's now safe to make the change * permanently. Make sure that anything done here can't fail! */ if (StorageDel != NULL) { StorageDel = 0; /* * XXX: free it, its dead */ } else { if (StorageTmp && StorageTmp->mteObjectsEntryStatus == RS_CREATEANDGO) { StorageTmp->mteObjectsEntryStatus = RS_ACTIVE; } else if (StorageTmp && StorageTmp->mteObjectsEntryStatus == RS_CREATEANDWAIT) { StorageTmp->mteObjectsEntryStatus = RS_NOTINSERVICE; } } break; } return SNMP_ERR_NOERROR; }