📄 var_route.c
字号:
RTENTRY **routehash, mb; register RTENTRY *m; RTENTRY *rt; struct ifnet ifnet; int i, table; register char *cp; char name[16], temp[16]; int hashsize;#endif static int Time_Of_Last_Reload=0; struct timeval now; gettimeofday(&now, (struct timezone *)0); if (Time_Of_Last_Reload+CACHE_TIME > now.tv_sec) return; Time_Of_Last_Reload = now.tv_sec; /* * Makes sure we have SOME space allocated for new routing entries */ if (!rthead) { rthead = (RTENTRY **) malloc(100 * sizeof(RTENTRY *)); if (!rthead) { snmp_log(LOG_ERR,"route table malloc fail\n"); return; } memset((char *)rthead,(0), 100 * sizeof(RTENTRY *)); rtallocate = 100; } /* reset the routing table size to zero -- was a CMU memory leak */ rtsize = 0;#ifdef RTENTRY_4_4 /* rtentry is a BSD 4.4 compat */#if !defined(AF_UNSPEC)#define AF_UNSPEC AF_INET #endif auto_nlist(RTTABLES_SYMBOL, (char *) rt_table, sizeof(rt_table)); for(i=0; i <= AF_MAX; i++) { if(rt_table[i] == 0) continue; if (klookup((unsigned long)rt_table[i], (char *) &head, sizeof(head))) { load_rtentries(head.rnh_treetop); } } #else /* rtentry is a BSD 4.3 compat */ for (table=0; table<NUM_ROUTE_SYMBOLS; table++) { auto_nlist(RTHASHSIZE_SYMBOL, (char *)&hashsize, sizeof(hashsize)); routehash = (RTENTRY **)malloc(hashsize * sizeof(struct mbuf *)); auto_nlist(route_symbols[table], (char *)routehash, hashsize * sizeof(struct mbuf *)); for (i = 0; i < hashsize; i++) { if (routehash[i] == 0) continue; m = routehash[i]; while (m) { /* * Dig the route out of the kernel... */ klookup(m , (char *)&mb, sizeof (mb)); m = mb.rt_next; rt = &mb; if (rt->rt_ifp != 0) { klookup( rt->rt_ifp, (char *)&ifnet, sizeof (ifnet)); klookup( ifnet.if_name, name, 16); name[15] = '\0'; cp = (char *) strchr(name, '\0'); string_append_int (cp, ifnet.if_unit); Interface_Scan_Init(); while (Interface_Scan_Next((short *)&rt->rt_unit, temp, NULL, NULL) != 0) { if (strcmp(name, temp) == 0) break; } } /* * Allocate a block to hold it and add it to the database */ if (rtsize >= rtallocate) { rthead = (RTENTRY **) realloc((char *)rthead, 2 * rtallocate * sizeof(RTENTRY *)); memset((char *) &rthead[rtallocate],(0), rtallocate * sizeof(RTENTRY *)); rtallocate *= 2; } if (!rthead[rtsize]) rthead[rtsize] = (RTENTRY *) malloc(sizeof(RTENTRY)); /* * Add this to the database */ memcpy( (char *)rthead[rtsize],(char *)rt, sizeof(RTENTRY)); rtsize++; } } free(routehash); }#endif /* * Sort it! */ qsort((char *) rthead, rtsize, sizeof(rthead[0]), qsort_compare);}#else#if HAVE_SYS_MBUF_Hstatic void Route_Scan_Reload (void){ struct mbuf **routehash, mb; register struct mbuf *m; struct ifnet ifnet; RTENTRY *rt; int i, table; register char *cp; char name[16], temp[16]; static int Time_Of_Last_Reload=0; struct timeval now; int hashsize; gettimeofday(&now, (struct timezone *)0); if (Time_Of_Last_Reload+CACHE_TIME > now.tv_sec) return; Time_Of_Last_Reload = now.tv_sec; /* * Makes sure we have SOME space allocated for new routing entries */ if (!rthead) { rthead = (RTENTRY **) malloc(100 * sizeof(RTENTRY *)); if (!rthead) { snmp_log(LOG_ERR,"route table malloc fail\n"); return; } memset((char *)rthead,(0), 100 * sizeof(RTENTRY *)); rtallocate = 100; } /* reset the routing table size to zero -- was a CMU memory leak */ rtsize = 0; for (table=0; table<NUM_ROUTE_SYMBOLS; table++) {#ifdef sunV3 hashsize = RTHASHSIZ;#else auto_nlist(RTHASHSIZE_SYMBOL, (char *)&hashsize, sizeof(hashsize));#endif routehash = (struct mbuf **)malloc(hashsize * sizeof(struct mbuf *)); auto_nlist(route_symbols[table], (char *)routehash, hashsize * sizeof(struct mbuf *)); for (i = 0; i < hashsize; i++) { if (routehash[i] == 0) continue; m = routehash[i]; while (m) { /* * Dig the route out of the kernel... */ klookup((unsigned long) m , (char *)&mb, sizeof (mb)); m = mb.m_next; rt = mtod(&mb, RTENTRY *); if (rt->rt_ifp != 0) { klookup((unsigned long) rt->rt_ifp, (char *)&ifnet, sizeof (ifnet)); klookup((unsigned long) ifnet.if_name, name, 16); name[15] = '\0'; cp = (char *) strchr(name, '\0'); string_append_int (cp, ifnet.if_unit); if (strcmp(name,"lo0") == 0) continue; Interface_Scan_Init(); while (Interface_Scan_Next((short *)&rt->rt_unit, temp, NULL, NULL) != 0) { if (strcmp(name, temp) == 0) break; } } /* * Allocate a block to hold it and add it to the database */ if (rtsize >= rtallocate) { rthead = (RTENTRY **) realloc((char *)rthead, 2 * rtallocate * sizeof(RTENTRY *)); memset((char *) &rthead[rtallocate],(0), rtallocate * sizeof(RTENTRY *)); rtallocate *= 2; } if (!rthead[rtsize]) rthead[rtsize] = (RTENTRY *) malloc(sizeof(RTENTRY)); /* * Add this to the database */ memcpy( (char *)rthead[rtsize],(char *)rt, sizeof(RTENTRY)); rtsize++; } } free(routehash); } /* * Sort it! */ qsort((char *)rthead,rtsize,sizeof(rthead[0]), qsort_compare);}#else#ifdef linuxstatic void Route_Scan_Reload (void){ FILE *in; char line [256]; struct rtentry *rt; char name[16], temp[16]; static int Time_Of_Last_Reload=0; struct timeval now; /* allow 20 seconds in cache: */ gettimeofday(&now, (struct timezone *)0); if (Time_Of_Last_Reload + 20 > now.tv_sec) return; Time_Of_Last_Reload = now.tv_sec; /* * Makes sure we have SOME space allocated for new routing entries */ if (! rthead) { rthead = (struct rtentry **) calloc(100, sizeof(struct rtentry *)); if (! rthead) { snmp_log(LOG_ERR,"route table malloc fail\n"); return; } rtallocate = 100; } /* * fetch routes from the proc file-system: */ rtsize = 0; if (! (in = fopen ("/proc/net/route", "r"))) { snmp_log(LOG_ERR, "cannot open /proc/net/route - burps\n"); return; } while (fgets (line, sizeof(line), in)) { struct rtentry rtent; char rtent_name [32]; int refcnt, flags, metric; unsigned use; rt = &rtent; memset ((char *) rt,(0), sizeof(*rt)); rt->rt_dev = rtent_name; /* * as with 1.99.14: * Iface Dest GW Flags RefCnt Use Metric Mask MTU Win IRTT * eth0 0A0A0A0A 00000000 05 0 0 0 FFFFFFFF 1500 0 0 */ if (8 != sscanf (line, "%s %x %x %x %u %d %d %x %*d %*d %*d\n", rt->rt_dev, &(((struct sockaddr_in *) &(rtent.rt_dst))->sin_addr.s_addr), &(((struct sockaddr_in *) &(rtent.rt_gateway))->sin_addr.s_addr),/* XXX: fix type of the args */ &flags, &refcnt, &use, &metric, &(((struct sockaddr_in *) &(rtent.rt_genmask))->sin_addr.s_addr))) continue; strcpy (name, rt->rt_dev); /* linux says ``lo'', but the interface is stored as ``lo0'': */ if (! strcmp (name, "lo")) strcat (name, "0"); name[15] = '\0'; rt->rt_flags = flags, rt->rt_refcnt = refcnt; rt->rt_use = use, rt->rt_metric = metric; Interface_Scan_Init(); while (Interface_Scan_Next((short *)&rt->rt_unit, temp, NULL, NULL) != 0) if (strcmp(name, temp) == 0) break; /* * Allocate a block to hold it and add it to the database */ if (rtsize >= rtallocate) { rthead = (struct rtentry **) realloc((char *)rthead, 2 * rtallocate * sizeof(struct rtentry *)); memset(&rthead[rtallocate], 0, rtallocate * sizeof(struct rtentry *)); rtallocate *= 2; } if (! rthead[rtsize]) rthead[rtsize] = (struct rtentry *) malloc(sizeof(struct rtentry)); /* * Add this to the database */ memcpy( (char *)rthead[rtsize],(char *)rt, sizeof(struct rtentry)); rtsize++; } fclose (in); /* * Sort it! */ qsort((char *)rthead,rtsize,sizeof(rthead[0]), qsort_compare);}#endif#endif#endif#ifndef solaris2/* * Create a host table */static int qsort_compare(const void *v1, const void *v2){ const RTENTRY **r1 = (const RTENTRY **) v1; const RTENTRY **r2 = (const RTENTRY **) v2;#if NEED_KLGETSA register u_long dst1 = ntohl(klgetsa((const struct sockaddr_in *)(*r1)->rt_dst)->sin_addr.s_addr); register u_long dst2 = ntohl(klgetsa((const struct sockaddr_in *)(*r2)->rt_dst)->sin_addr.s_addr);#else register u_long dst1 = ntohl(((const struct sockaddr_in *) &((*r1)->rt_dst))->sin_addr.s_addr); register u_long dst2 = ntohl(((const struct sockaddr_in *) &((*r2)->rt_dst))->sin_addr.s_addr);#endif /* NEED_KLGETSA */ /* * Do the comparison */ if (dst1 == dst2) return(0); if (dst1 > dst2) return(1); return(-1);}#endif /* not USE_SYSCTL_ROUTE_DUMP */#endif /* solaris2 */#else /* WIN32 */#include <iphlpapi.h>#ifndef MIB_IPPROTO_NETMGMT#define MIB_IPPROTO_NETMGMT 3#endifPMIB_IPFORWARDROW route_row;int create_flag;void init_var_route(void){}u_char *var_ipRouteEntry(struct variable *vp, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method){ /* * object identifier is of form: * 1.3.6.1.2.1.4.21.1.?.A.B.C.D, where A.B.C.D is IP address. * IPADDR starts at offset 10. */ register int Save_Valid, result, RtIndex; static int saveNameLen=0, saveExact=0, saveRtIndex=0, rtsize = 0; static oid saveName[MAX_OID_LEN], Current[MAX_OID_LEN]; u_char *cp; oid *op; DWORD status = NO_ERROR; DWORD dwActualSize = 0; static PMIB_IPFORWARDTABLE pIpRtrTable = NULL; struct timeval now; static long Time_Of_Last_Reload = 0; u_char dest_addr[4]; MIB_IPFORWARDROW temp_row; /** ** this optimisation fails, if there is only a single route avail. ** it is a very special case, but better leave it out ... **/#if NO_DUMMY_VALUES saveNameLen = 0;#endif if(route_row == NULL){ /* Free allocated memory in case of SET request's FREE phase */ route_row = (PMIB_IPFORWARDROW)malloc(sizeof(MIB_IPFORWARDROW)); } gettimeofday (&now, (struct timezone *) 0); if ((rtsize <= 1) || (Time_Of_Last_Reload + 5 <= now.tv_sec)) Save_Valid = 0; else /* * OPTIMIZATION: * * If the name was the same as the last name, with the possible * exception of the [9]th token, then don't read the routing table * */ if ((saveNameLen == (int)*length) && (saveExact == exact)) { register int temp=name[9]; name[9] = 0; Save_Valid = (snmp_oid_compare(name, *length, saveName, saveNameLen) == 0); name[9] = temp; } else Save_Valid = 0; if (Save_Valid) { register int temp=name[9]; /* Fix up 'lowest' found entry */ memcpy( (char *) name,(char *) Current, 14 * sizeof(oid)); name[9] = temp; *length = 14; RtIndex = saveRtIndex; } else { /* fill in object part of name for current(less sizeof instance part) */ memcpy( (char *)Current,(char *)vp->name, (int)(vp->namelen) * sizeof(oid)); if ((Time_Of_Last_Reload + 5 <= now.tv_sec) || (pIpRtrTable == NULL) ) { if(pIpRtrTable != NULL) free(pIpRtrTable); Time_Of_Last_Reload = now.tv_sec; /* query for buffer size needed */ status = GetIpForwardTable(pIpRtrTable, &dwActualSize, TRUE); if (status == ERROR_INSUFFICIENT_BUFFER) { pIpRtrTable = (PMIB_IPFORWARDTABLE) malloc(dwActualSize); if(pIpRtrTable != NULL){ /* Get the sorted IP Route Table */ status = GetIpForwardTable(pIpRtrTable, &dwActualSize, TRUE); } } } if(status == NO_ERROR) { rtsize = pIpRtrTable->dwNumEntries; for(RtIndex=0; RtIndex < rtsize; RtIndex++) { cp = (u_char *)&pIpRtrTable->table[RtIndex].dwForwardDest; op = Current + 10; *op++ = *cp++; *op++ = *cp++; *op++ = *cp++; *op++ = *cp++; result = snmp_oid_compare(name, *length, Current, 14); if ((exact && (result == 0)) || (!exact && (result < 0))) break; } } if (RtIndex >= rtsize){ /* for creation of new row, only ipNetToMediaTable case is considered */ if(*length == 14){ create_flag = 1; *write_method = write_rte; dest_addr[0] = (u_char)name[10]; dest_addr[1] = (u_char)name[11]; dest_addr[2] = (u_char)name[12]; dest_addr[3] = (u_char) name[13]; temp_row.dwForwardDest = *((DWORD *)dest_addr); temp_row.dwForwardPolicy = 0; temp_row.dwForwardProto = MIB_IPPROTO_NETMGMT; *route_row = temp_row; } free(pIpRtrTable); pIpRtrTable = NULL; rtsize = 0; return(NULL); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -