[insert project logo here (125x200px max)] Navigator Mailinglists Please report any errors or ommissions you find to our `Help' mailinglist, or post a message in the Forums. Copyright and Licensing Information Snap is (c) Jonathan T. Moore, 1999-2002 and licensed under the GNU General Public License (GPL). All other parts of Splash are (c) Willem de Bruijn, 2002-2003 and licensed under the BSD Open Source License. All sourcecode is made publicly available. Acknowledgement Splash and the Splash website are hosted by SourceForge.net |
Splash - DocumentationSNMP Plus a Lightweight API for SNAP Handlingsnap_svc/snap_svc_snmp.cGo to the documentation of this file.00001 /* snap service library */ 00002 /* (c) Willem de Bruijn, 2002, 2003 */ 00003 /* Licensed under the BSD License */ 00004 /* snap_svc_snmp library sourcefile */ 00005 00006 #include <stdio.h> 00007 #include <string.h> 00008 00009 #include <net-snmp/net-snmp-config.h> 00010 #include <net-snmp/net-snmp-includes.h> 00011 #include <net-snmp/definitions.h> 00012 #include <net-snmp/pdu_api.h> 00013 #include <net-snmp/agent/snmp_agent.h> 00014 00015 #include "snap_svc.h" 00016 #include "snap_svc_snmp.h" 00017 #include "d_printf.h" 00018 00019 /* referenced external variables */ 00020 extern int callback_master_num; /* some variable to reference the master */ 00021 00022 /* global variables*/ 00023 unsigned short svc_snmp_active = 0; 00024 unsigned short svc_snmp_pdu_load = 0; /* how many variables are we referencing? */ 00025 netsnmp_pdu* svc_snmp_pdu = NULL; /* the pdu (really ;-) )*/ 00026 netsnmp_session* svc_snmp_session = NULL; /* the connection */ 00027 int svc_snmp_pdu_waiting = 0; 00028 00029 /* library handling functions */ 00030 void snap_external_svclib_init(){ 00031 if (snap_external_svclib_snmp_init(NULL)) 00032 d_printf(50,"snap_svc_snmp : initialized\n"); 00033 } 00034 00035 void snap_external_svclib_done(){ 00036 00037 /* snmp lib specific */ 00038 if (svc_snmp_pdu){ 00039 snmp_free_pdu(svc_snmp_pdu); 00040 svc_snmp_pdu = NULL; 00041 } 00042 if (svc_snmp_session || svc_snmp_active) 00043 snap_external_svclib_snmp_close(NULL); 00044 00045 svc_snmp_pdu_load = 0; 00046 svc_snmp_session = NULL; 00047 svc_snmp_pdu_waiting = 0; 00048 00049 d_printf(50,"snap_svc_snmp : closed\n"); 00050 } 00051 00052 /* there is where functions inside the library should be listed for registration */ 00053 void snap_external_svclib_getnextfunc(char** snapsvc_name, snapsvc_func_proto* snapsvc_func, int* snapsvc_args, int* snapsvc_rets){ 00054 00055 switch (svc_fun_counter){ 00056 case 0 : (*snapsvc_name) = strdup ("snmp_init"); 00057 (*snapsvc_func) = (snapsvc_func_proto) &snap_external_svclib_snmp_init; 00058 (*snapsvc_args) = 0; 00059 (*snapsvc_rets) = SVC_SNMP_TYPE_NULL; 00060 break; 00061 case 1 : (*snapsvc_name) = strdup ("snmp_init_ip"); 00062 (*snapsvc_func) = (snapsvc_func_proto) &snap_external_svclib_snmp_init_ip; 00063 (*snapsvc_args) = 1; 00064 (*snapsvc_rets) = SVC_SNMP_TYPE_NULL; 00065 break; 00066 case 2 : (*snapsvc_name) = strdup ("snmp_pdu_init"); 00067 (*snapsvc_func) = (snapsvc_func_proto) &snap_external_svclib_snmp_initpdu; 00068 (*snapsvc_args) = 1; 00069 (*snapsvc_rets) = SVC_SNMP_TYPE_NULL; 00070 break; 00071 case 3 : (*snapsvc_name) = strdup ("snmp_pdu_addvar_null"); 00072 (*snapsvc_func) = (snapsvc_func_proto) &snap_external_svclib_snmp_addvar_null; 00073 (*snapsvc_args) = 1; 00074 (*snapsvc_rets) = SVC_SNMP_TYPE_NULL; 00075 break; 00076 case 4 : (*snapsvc_name) = strdup ("snmp_pdu_addvar_withvalue"); 00077 (*snapsvc_func) = (snapsvc_func_proto) &snap_external_svclib_snmp_addvar_withvalue; 00078 (*snapsvc_args) = 4; 00079 (*snapsvc_rets) = SVC_SNMP_TYPE_NULL; 00080 break; 00081 case 5 : (*snapsvc_name) = strdup ("snmp_pdu_send"); 00082 (*snapsvc_func) = (snapsvc_func_proto) &snap_external_svclib_snmp_execpdu; 00083 (*snapsvc_args) = 0; 00084 (*snapsvc_rets) = SVC_SNMP_TYPE_NULL; 00085 break; 00086 case 6 : (*snapsvc_name) = strdup ("snmp_close"); 00087 (*snapsvc_func) = (snapsvc_func_proto) &snap_external_svclib_snmp_close; 00088 (*snapsvc_args) = 0; 00089 (*snapsvc_rets) = SVC_SNMP_TYPE_NULL; 00090 break; 00091 case 7 : (*snapsvc_name) = strdup ("snmp_getsingle"); 00092 (*snapsvc_func) = (snapsvc_func_proto) &snap_external_svclib_snmp_getsingle; 00093 (*snapsvc_args) = 1; 00094 (*snapsvc_rets) = SVC_SNMP_TYPE_NULL; 00095 break; 00096 case 8 : (*snapsvc_name) = strdup ("snmp_setsingle"); 00097 (*snapsvc_func) = (snapsvc_func_proto) &snap_external_svclib_snmp_setsingle; 00098 (*snapsvc_args) = 4; 00099 (*snapsvc_rets) = SVC_SNMP_TYPE_NULL; 00100 break; 00101 case 9 : (*snapsvc_name) = strdup ("snmp_getnexthop"); 00102 (*snapsvc_func) = (snapsvc_func_proto) &snap_external_svclib_snmp_getnexthopfromip; 00103 (*snapsvc_args) = 1; 00104 (*snapsvc_rets) = SVC_SNMP_TYPE_NULL; 00105 break; 00106 case 10 : (*snapsvc_name) = strdup ("snmp_getneighbours"); 00107 (*snapsvc_func) = (snapsvc_func_proto) &snap_external_svclib_snmp_getallotherneighboursfromip; 00108 (*snapsvc_args) = 1; 00109 (*snapsvc_rets) = SVC_SNMP_TYPE_NULL; 00110 break; 00111 /* unknown handler -> return NULL as end-of-list symbol */ 00112 default : (*snapsvc_name) = NULL; 00113 (*snapsvc_func) = NULL; 00114 (*snapsvc_args) = 0; 00115 (*snapsvc_rets) = 0; 00116 } 00117 svc_fun_counter ++; 00118 } 00119 00120 /* snmp callback handler*/ 00121 int snap_external_svclib_snmp_INTERNAL_execpdu_handler(int op, netsnmp_session * session, int reqid, 00122 netsnmp_pdu *pdu, void *useless){ 00123 netsnmp_variable_list* curlist; 00124 int count = 0; 00125 00126 if (op == NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE ){ 00127 00128 /* create a structure to hold the results */ 00129 curlist = pdu->variables; 00130 while (curlist){ 00131 count++; 00132 curlist = curlist->next_variable; 00133 } 00134 snap_external_svclib_free_local_returnstruct(); 00135 svc_return = (struct svc_returnstruct*) calloc (1,sizeof(struct svc_returnstruct)); 00136 svc_return->length = count; 00137 svc_return->list = (struct svc_returnitem*) calloc (count,sizeof(struct svc_returnitem)); 00138 00139 /* write data to SNAP stack */ 00140 curlist = pdu->variables; 00141 count = 0; 00142 while(curlist){ 00143 /* simply walk the available options and select the necessary one */ 00144 /* 00145 NB: net-snmp uses a #ifdef OPAQUE_SPECIAL_TYPES top add the float 00146 and double type. We will adhere to the failsafe case == undefined 00147 */ 00148 00149 /* copy the OID */ 00150 svc_return->list[count].oid_length = curlist->name_length; 00151 svc_return->list[count].oid = calloc (curlist->name_length, sizeof(unsigned long)); 00152 memmove(svc_return->list[count].oid, curlist->name, curlist->name_length * sizeof(unsigned long)); 00153 00154 /* copy the value length */ 00155 svc_return->list[count].length = curlist->val_len; 00156 00157 /* copy the value */ 00158 switch(curlist->type){ 00159 case ASN_BIT_STR : case ASN_OCTET_STR : 00160 svc_return->list[count].type = SVC_SNMP_TYPE_STRING; 00161 svc_return->list[count].data = calloc (curlist->val_len, sizeof(u_char)); 00162 memmove(svc_return->list[count].data,curlist->val.string,curlist->val_len); 00163 break; 00164 case ASN_IPADDRESS : 00165 svc_return->list[count].type = SVC_SNMP_TYPE_ADDR; 00166 svc_return->list[count].data = calloc (curlist->val_len, sizeof(uint32_t)); 00167 memmove(svc_return->list[count].data,curlist->val.integer,sizeof(uint32_t)); 00168 break; 00169 case ASN_BOOLEAN : case ASN_INTEGER : 00170 case ASN_TIMETICKS : 00171 case ASN_COUNTER : case ASN_GAUGE : /* case ASN_UNSIGNED : is the same as ASN_GAUGE */ 00172 svc_return->list[count].type = SVC_SNMP_TYPE_INT; 00173 svc_return->list[count].data = calloc (curlist->val_len, sizeof(int)); 00174 memmove(svc_return->list[count].data,curlist->val.integer,curlist->val_len); 00175 break; 00176 case ASN_OBJECT_ID : 00177 svc_return->list[count].type = SVC_SNMP_TYPE_LONG; 00178 svc_return->list[count].data = calloc (curlist->val_len, sizeof(unsigned long)); 00179 memmove(svc_return->list[count].data,curlist->val.string,curlist->val_len); 00180 break; 00181 case ASN_COUNTER64 : 00182 svc_return->list[count].type = SVC_SNMP_TYPE_LONG; 00183 svc_return->list[count].data = calloc (curlist->val_len, sizeof(unsigned long)); 00184 ((unsigned long*) svc_return->list[count].data)[0] = curlist->val.counter64->high; 00185 ((unsigned long*) svc_return->list[count].data)[1] = curlist->val.counter64->low; 00186 svc_return->list[count].length = 2; /* override general case */ 00187 break; 00188 case ASN_NULL : 00189 svc_return->list[count].type = SVC_SNMP_TYPE_NULL; 00190 svc_return->list[count].data = NULL; 00191 svc_return->list[count].length = 0; 00192 break; 00193 default : 00194 svc_return->list[count].type = SVC_SNMP_TYPE_NULL; 00195 svc_return->list[count].data = NULL; 00196 svc_return->list[count].length = 0; 00197 d_printf(10,"snap_svc_snmp : received value of unknown ASN type [%d], treating it as NULL\n",curlist->type); 00198 } 00199 curlist = curlist->next_variable; 00200 count ++; 00201 00202 } 00203 00204 /* notify our waiting function */ 00205 svc_snmp_pdu_waiting = 0; 00206 return 1; 00207 } 00208 else{ 00209 d_printf(10,"snap_svc_snmp : received error message %d while expecting result\n",op); 00210 if (op == 2){ /* timeout */ 00211 svc_snmp_pdu_waiting = 0; 00212 } 00213 return 0; 00214 } 00215 } 00216 00217 /* ADD SERVICES BELOW */ 00218 /* declarations of snap service handlers */ 00219 00220 00221 int snap_external_svclib_snmp_init(void* useless){ 00222 if (svc_snmp_active) 00223 snap_external_svclib_snmp_close(NULL); 00224 00225 SOCK_STARTUP; 00226 00227 00228 svc_snmp_session = netsnmp_callback_open(callback_master_num, 00229 snap_external_svclib_snmp_INTERNAL_execpdu_handler, 00230 NULL, NULL); 00231 if (svc_snmp_session == NULL) { 00232 d_printf(50,"snap_svc_snmp : error while opening callback transport \n"); 00233 return 1; 00234 } 00235 00236 svc_snmp_active = 1; 00237 return 0; 00238 } 00239 00240 int snap_external_svclib_snmp_init_ip(unsigned int ip){ 00241 if (svc_snmp_active) 00242 snap_external_svclib_snmp_close(NULL); 00243 00244 00245 SOCK_STARTUP; 00246 00247 00248 svc_snmp_session = calloc( sizeof(netsnmp_session), 1); 00249 snmp_sess_init( svc_snmp_session ); /* set up defaults */ 00250 svc_snmp_session->peername = malloc (sizeof(char) * 16); 00251 sprintf(svc_snmp_session->peername,"%u.%u.%u.%u",ip << 24 >> 24, ip << 16 >> 24, ip << 8 >> 24, ip >> 24); 00252 00253 d_printf(110,"snap_svc_snmp_ip : trying ip %s\n",svc_snmp_session->peername); 00254 svc_snmp_session->callback = snap_external_svclib_snmp_INTERNAL_execpdu_handler; 00255 svc_snmp_session->remote_port = 161; 00256 svc_snmp_session->version = SNMP_VERSION_2c; 00257 svc_snmp_session->community = strdup("public"); 00258 svc_snmp_session->community_len = 6; 00259 00260 svc_snmp_session = snmp_open(svc_snmp_session); 00261 if ( svc_snmp_session == NULL) { 00262 d_printf(50,"snap_svc_snmp : error while opening ip transport \n"); 00263 snmp_perror("snap_svc_snmp"); 00264 return 1; 00265 } 00266 00267 svc_snmp_active = 1; 00268 return 0; 00269 } 00270 00271 int snap_external_svclib_snmp_initpdu(unsigned int msg_type){ 00272 /* open a connection if it does not yet exist */ 00273 if (!svc_snmp_session) 00274 snap_external_svclib_snmp_init(NULL); 00275 00276 d_printf(200,"snap_svc_snmp : message type is %u\n",msg_type); 00277 /* remove the current pdu if it exists */ 00278 if (svc_snmp_pdu){ 00279 snmp_free_pdu(svc_snmp_pdu); 00280 svc_snmp_pdu = NULL; 00281 svc_snmp_pdu_load = 0; 00282 } 00283 00284 /* initialize the pdu */ 00285 svc_snmp_pdu = snmp_pdu_create(msg_type); 00286 if (svc_snmp_pdu == NULL){ 00287 d_printf(10,"snap_svc_snmp : error creating a PDU \n"); 00288 return 1; 00289 } 00290 00291 svc_snmp_pdu->version = SNMP_VERSION_2c; /* keep the communication as simple as possible */ 00292 svc_snmp_pdu->securityName = strdup("anonymousSecName001"); 00293 svc_snmp_pdu->securityNameLen = 19; 00294 svc_snmp_pdu->securityModel = SNMP_SEC_MODEL_ANY; 00295 svc_snmp_pdu->errindex = 0; 00296 svc_snmp_pdu->community = strdup("public"); 00297 svc_snmp_pdu->community_len = 6; 00298 svc_snmp_pdu->flags = svc_snmp_pdu->flags | UCD_MSG_FLAG_ALWAYS_IN_VIEW; /* BEWARE: this statement makes the system bypasse the access control code */ 00299 svc_snmp_pdu_load = 0; 00300 00301 return 0; 00302 } 00303 00304 int snap_external_svclib_snmp_addvar_null(char* name){ 00305 oid my_oid[MAX_OID_LEN]; 00306 int my_oid_length = MAX_OID_LEN; 00307 00308 if (!svc_snmp_pdu){ 00309 int msgtype = SNMP_MSG_GET; 00310 snap_external_svclib_snmp_initpdu(msgtype); 00311 } 00312 00313 /* convert the string encoded name to an oid and add the variable */ 00314 d_printf(100,"snap_svc_snmp : finding OID for string %s\n",name); 00315 if (!snmp_parse_oid(name, my_oid,&my_oid_length)){ 00316 d_printf(20,"snap_svc_snmp : unable to create OID from input string, received SNMP error code %d\n",snmp_errno); 00317 return 1; 00318 } 00319 00320 if (snmp_add_null_var(svc_snmp_pdu, my_oid, my_oid_length) == NULL){ 00321 d_printf(20,"snap_svc_snmp : unable to add variable to the PDU, received SNMP error code %d\n",snmp_errno); 00322 return 1; 00323 } 00324 00325 return 0; 00326 } 00327 00328 int snap_external_svclib_snmp_addvar_withvalue(char* name, int type, void* value, int valuelen){ 00329 oid my_oid[MAX_OID_LEN]; 00330 int my_oid_length = MAX_OID_LEN; 00331 00332 if (!svc_snmp_pdu){ 00333 int msgtype = SNMP_MSG_SET; 00334 snap_external_svclib_snmp_initpdu(msgtype); 00335 } 00336 00337 /* convert the string encoded name to an oid and add the variable */ 00338 if (!snmp_parse_oid(name, my_oid,&my_oid_length)){ 00339 d_printf(20,"snap_svc_snmp : unable to create OID from input string, received SNMP error code %d\n",snmp_errno); 00340 return 1; 00341 } 00342 00343 if (snmp_pdu_add_variable(svc_snmp_pdu, my_oid, my_oid_length, type, value, valuelen) == NULL){ 00344 d_printf(20,"snap_svc_snmp : unable to add variable to the PDU\n"); 00345 return 1; 00346 } 00347 00348 return 0; 00349 } 00350 00351 int snap_external_svclib_snmp_execpdu(void* useless){ 00352 00353 /* do some safety checks */ 00354 if (!svc_snmp_pdu){ 00355 d_printf(10, "snap_svc_snmp : no PDU initialized, unable to send it"); 00356 return 1; 00357 } 00358 00359 /* send the PDU */ 00360 d_printf_timed(5,"snap_svc_snmp : sending a request to SNMP ...\n"); 00361 if (! snmp_send(svc_snmp_session, svc_snmp_pdu)){ 00362 d_printf(10,"snap_svc_snmp : unable to send the request to the snmplibrary, received SNMP error code %d\n",snmp_errno); 00363 snmp_perror("snap_svc_snmp"); 00364 snmp_free_pdu(svc_snmp_pdu); 00365 svc_snmp_pdu = NULL; 00366 return 1; 00367 } 00368 00369 /* wait for handler to return */ 00370 svc_snmp_pdu_waiting = 1; 00371 while (svc_snmp_pdu_waiting) { 00372 int fds = 0, block = 1; 00373 fd_set fdset; 00374 struct timeval timeout; 00375 timeout.tv_sec = 3; /* timeout in 3 secs */ 00376 timeout.tv_usec = 0; 00377 00378 d_printf(200,"snap_svc_snmp : ... waiting for a response ...\n"); 00379 FD_ZERO(&fdset); 00380 snmp_select_info(&fds, &fdset, &timeout, &block); 00381 fds = select(fds, &fdset, NULL, NULL, block ? NULL : &timeout); 00382 if (fds) 00383 snmp_read(&fdset); 00384 else 00385 snmp_timeout(); 00386 } 00387 d_printf_timed(5,"snap_svc_snmp : ... finished\n"); 00388 00389 /* 00390 if the request succeeded the pdu will be freed in the snmplib 00391 DO NOT FREE! 00392 */ 00393 svc_snmp_pdu = NULL; 00394 00395 if (svc_snmp_pdu_load != 0) 00396 svc_snmp_pdu_load = 0; 00397 00398 return 0; 00399 } 00400 00401 int snap_external_svclib_snmp_close(void* useless){ 00402 00403 if (svc_snmp_active){ 00404 if (svc_snmp_pdu){ 00405 snmp_free_pdu(svc_snmp_pdu); 00406 svc_snmp_pdu = NULL; 00407 } 00408 00409 if (!svc_snmp_session) 00410 return 0; 00411 00412 /* close the connection */ 00413 if (!snmp_close(svc_snmp_session)) 00414 d_printf(50,"snap_svc_snmp : I was unable to gracefully shut down the snmp connection, destroying... \n"); 00415 svc_snmp_session = NULL; 00416 00417 SOCK_CLEANUP; 00418 00419 svc_snmp_active = 0; 00420 } 00421 00422 return 0; 00423 } 00424 00425 /* declarations of DERIVED snap service handlers */ 00426 00427 /* return a single value */ 00428 int snap_external_svclib_snmp_getsingle(char* name){ 00429 int msgtype = SNMP_MSG_GET; 00430 00431 snap_external_svclib_snmp_initpdu(msgtype); 00432 snap_external_svclib_snmp_addvar_null(name); 00433 snap_external_svclib_snmp_execpdu(NULL); 00434 00435 return 0; 00436 } 00437 00438 /* set a single value */ 00439 int snap_external_svclib_snmp_setsingle(char* name, int type, void* value, int valuelen){ 00440 int msgtype = SNMP_MSG_SET; 00441 00442 snap_external_svclib_snmp_initpdu(msgtype); 00443 snap_external_svclib_snmp_addvar_withvalue(name, type, value, valuelen); 00444 snap_external_svclib_snmp_execpdu(NULL); 00445 00446 return 0; 00447 } 00448 00449 /* 00450 find the incoming interface N from the last hop command IP (the in_IP) 00451 and calculate the next hop using ~ interface (N+1) mod (#ifaces) 00452 00453 */ 00454 00455 int snap_external_svclib_snmp_getiface(unsigned long in_ip){ 00456 char oid[100]; 00457 int iface = -1; 00458 00459 sprintf(oid,"ipAdEntIfIndex.%lu.%lu.%lu.%lu",in_ip << 24 >> 24, in_ip << 16 >> 24, in_ip << 8 >> 24, in_ip >> 24); 00460 d_printf(50,"oid = %s\n",oid); 00461 snap_external_svclib_snmp_getsingle(oid); 00462 00463 if (svc_return->length == 1){ 00464 if (svc_return->list[0].type == SVC_SNMP_TYPE_INT && svc_return->list[0].length == 4) 00465 iface = *((int*) svc_return->list[0].data); 00466 else 00467 d_printf(20,"ERROR >> wrong returntype or incorrect length [%d:%lu]\n",svc_return->list[0].type,svc_return->list[0].length); 00468 } 00469 else 00470 d_printf(20,"ERROR >> retrieving an incorrect number of results [%d]\n",svc_return->length); 00471 00472 d_printf(50,"DEBUG >> iface = %d\n",iface); 00473 return iface; 00474 } 00475 00476 unsigned long snap_external_svclib_snmp_gethop(int iface){ 00477 int loopcount, dotcount; 00478 int msgtype = SNMP_MSG_GETBULK; 00479 char* out_ip = NULL; 00480 char oid[100]; 00481 int ip_temp[4]; 00482 unsigned long ip_address = 0; 00483 00484 snap_external_svclib_snmp_initpdu(msgtype); 00485 svc_snmp_pdu->non_repeaters=0; 00486 svc_snmp_pdu->max_repetitions=10; 00487 snap_external_svclib_snmp_addvar_null("ipRouteIfIndex"); 00488 snap_external_svclib_snmp_execpdu(NULL); 00489 d_printf(50,"DEBUG >> received bulk response with %d variables\n",svc_return->length); 00490 loopcount = 0; 00491 while (loopcount < svc_return->length){ 00492 if (svc_return->list[loopcount].type == SVC_SNMP_TYPE_INT && svc_return->list[loopcount].length == 4){ 00493 if ( *((int*) svc_return->list[loopcount].data) == iface){ /* if we have a hop on the right interface */ 00494 snprint_objid(oid,100,svc_return->list[loopcount].oid,svc_return->list[loopcount].oid_length); 00495 if (!strncmp(oid,"RFC1213-MIB::ipRouteIfIndex",27)){ 00496 /* only keep the last part: the IP address */ 00497 loopcount = strlen(oid) - 1; 00498 dotcount = 0; 00499 while (loopcount && dotcount < 4){ 00500 if (oid[loopcount] == '.'){ 00501 dotcount ++; 00502 ip_address += strtoul(&oid[loopcount],NULL,10) << dotcount * 8; 00503 d_printf(50,"DEBUG >> ip so far = %ld, new = %d\n",ip_address,atoi(&oid[loopcount])); 00504 } 00505 loopcount --; 00506 } 00507 loopcount += 2; /* forget the last dot and the last loopcount-- */ 00508 out_ip = strdup (&oid[loopcount]); 00509 d_printf(50,"DEBUG >> found a correct hop [%s], iface is %d\n",out_ip, iface); 00510 loopcount = svc_return->length + 1; /* exit this while loop */ 00511 } 00512 d_printf(20,"ERROR >> oid : %s, iface = %d\n",oid, iface); 00513 } 00514 } 00515 else 00516 d_printf(20,"ERROR >> wrong returntype or incorrect length [%d:%lu]\n",svc_return->list[loopcount].type,svc_return->list[loopcount].length); 00517 loopcount++; 00518 } 00519 if (loopcount != svc_return->length + 2) 00520 d_printf(10,"ERROR >> unable to find correct hop\n"); 00521 00522 /* convert from char to IP */ 00523 if (out_ip){ 00524 sscanf(out_ip,"%d.%d.%d.%d",&ip_temp[0],&ip_temp[1],&ip_temp[2],&ip_temp[3]); 00525 /*ip_address = ((unsigned long) ip_temp[0] << 24) & ((unsigned long) ip_temp[1] << 16) & ((unsigned long) (ip_temp[2] << 8)) & ((unsigned long) ip_temp[3]); 00526 */ 00527 for (loopcount = 3; loopcount >= 0; loopcount--){ 00528 ip_address = ip_address << 8; 00529 ip_address += ip_temp[loopcount]; 00530 } 00531 00532 d_printf(50,"DEBUG >> ip = %lu.%lu.%lu.%lu (long) == %s (string)\n",ip_address << 24 >> 24, ip_address << 16 >> 24, ip_address << 8 >> 24, ip_address >> 24, out_ip); 00533 free (out_ip); 00534 } 00535 00536 return ip_address; 00537 00538 } 00539 00540 int snap_external_svclib_snmp_getifnumber(void* useless){ 00541 int ifnumber = -1; 00542 00543 snap_external_svclib_snmp_getsingle("ifNumber.0"); 00544 if (svc_return->length == 1){ 00545 if (svc_return->list[0].type == SVC_SNMP_TYPE_INT && svc_return->list[0].length == 4) 00546 ifnumber = *((int*) svc_return->list[0].data); 00547 else 00548 d_printf(20,"ERROR >> wrong returntype or incorrect length [%d:%lu]\n",svc_return->list[0].type,svc_return->list[0].length); 00549 } 00550 else 00551 d_printf(20,"ERROR >> retrieving an incorrect number of results [%d]\n",svc_return->length); 00552 00553 d_printf(50,"DEBUG >> ifNumber.0 = %d\n",ifnumber); 00554 return ifnumber; 00555 } 00556 00557 int snap_external_svclib_snmp_isupiface(int iface){ 00558 char oid[10]; 00559 int status = -1; 00560 00561 sprintf(oid,"ifOperStatus.%d",iface); 00562 snap_external_svclib_snmp_getsingle(oid); 00563 if (svc_return->length == 1){ 00564 if (svc_return->list[0].type == SVC_SNMP_TYPE_INT && svc_return->list[0].length == 4) 00565 status = *((int*) svc_return->list[0].data); 00566 else 00567 d_printf(20,"ERROR >> wrong returntype or incorrect length [%d:%lu]\n",svc_return->list[0].type,svc_return->list[0].length); 00568 } 00569 else 00570 d_printf(20,"ERROR >> retrieving an incorrect number of results [%d]\n",svc_return->length); 00571 00572 00573 d_printf(50,"DEBUG >> iface %d has status %d (1=up, 2=down)\n",iface, status); 00574 return status; 00575 } 00576 00577 int snap_external_svclib_snmp_getnextiface(int old_iface){ 00578 int ifnumber, isup = 0, count=0, iface; 00579 ifnumber = snap_external_svclib_snmp_getifnumber(NULL); 00580 00581 iface = old_iface; 00582 if (iface != -1 && ifnumber != -1){ 00583 do{ 00584 if (iface < ifnumber) 00585 iface ++ ; 00586 else 00587 iface = 2; 00588 isup = snap_external_svclib_snmp_isupiface(iface); 00589 count++; 00590 } while (isup != 1 && count < ifnumber); 00591 } 00592 00593 if (isup != 1) 00594 return -1; 00595 else 00596 return iface; 00597 } 00598 00599 int snap_external_svclib_snmp_getnextifacefromip(unsigned long in_ip){ 00600 int iface; 00601 00602 iface = snap_external_svclib_snmp_getiface(in_ip); 00603 return snap_external_svclib_snmp_getnextiface(iface); 00604 } 00605 00606 unsigned long snap_internal_svclib_snmp_getnexthopfromip(unsigned long in_ip){ 00607 int iface; 00608 unsigned long ip = 0; 00609 00610 iface = snap_external_svclib_snmp_getnextifacefromip(in_ip); 00611 if (iface != -1) 00612 ip = snap_external_svclib_snmp_gethop(iface); 00613 00614 return ip; 00615 } 00616 00617 unsigned long snap_external_svclib_snmp_getnexthopfromip(unsigned long in_ip){ 00618 unsigned long ip = snap_internal_svclib_snmp_getnexthopfromip(in_ip); 00619 00620 snap_external_svclib_free_local_returnstruct(); 00621 svc_return = (struct svc_returnstruct*) calloc (1,sizeof(struct svc_returnstruct)); 00622 svc_return->length = 1; 00623 svc_return->list = (struct svc_returnitem*) calloc (1,sizeof(struct svc_returnitem)); 00624 svc_return->list[0].data = calloc (1, sizeof(unsigned long)); 00625 memmove(svc_return->list[0].data,&ip,sizeof(unsigned long)); 00626 svc_return->list[0].type = SVC_SNMP_TYPE_ADDR; 00627 00628 return ip; 00629 } 00630 00631 int snap_external_svclib_snmp_getallotherneighboursfromip(unsigned long in_ip){ 00632 unsigned long ip = in_ip; 00633 int listcount=0, ifnumber, whilecount=2; 00634 struct svc_returnstruct* svc_temp; 00635 00636 ifnumber = snap_external_svclib_snmp_getifnumber(NULL); 00637 ifnumber--; /* disregard the local interface */ 00638 snap_external_svclib_free_local_returnstruct(); 00639 svc_temp = (struct svc_returnstruct*) calloc (1,sizeof(struct svc_returnstruct)); 00640 svc_temp->length = ifnumber + 1; 00641 svc_temp->list = (struct svc_returnitem*) calloc (ifnumber+1,sizeof(struct svc_returnitem)); 00642 while(whilecount <= ifnumber + 1){ 00643 d_printf(50,"DEBUG >> finding a hop for iface %d\n",whilecount); 00644 if (snap_external_svclib_snmp_isupiface(whilecount) == 1){ 00645 ip = snap_external_svclib_snmp_gethop(whilecount); 00646 svc_temp->list[listcount].data = calloc (1, sizeof(unsigned long)); 00647 memmove(svc_temp->list[listcount].data,&ip,sizeof(unsigned long)); 00648 svc_temp->list[listcount].type = SVC_SNMP_TYPE_ADDR; 00649 listcount++; 00650 d_printf(50,"DEBUG >> visited an iface\n"); 00651 } 00652 else{ 00653 svc_temp->list[listcount].type = SVC_SNMP_TYPE_NULL; 00654 svc_temp->list[listcount].data = NULL; 00655 svc_temp->list[listcount].length = 0; 00656 listcount++; 00657 } 00658 whilecount++; 00659 } 00660 00661 /* the #of new entries */ 00662 svc_temp->list[ifnumber].type = SVC_SNMP_TYPE_INT; 00663 svc_temp->list[ifnumber].data = calloc (1, sizeof(int)); 00664 memmove(svc_temp->list[ifnumber].data,&listcount,sizeof(int)); 00665 snap_external_svclib_free_local_returnstruct(); 00666 svc_return = svc_temp; 00667 /* if (count != ifnumber) 00668 d_printf(50,"WARNING : found %d hops, only going to use %d\n",count,ifnumber); 00669 */ 00670 return listcount; 00671 } |