📄 iproute.c
字号:
/********************* * * System-independent implementation functions * *********************/ /* * Search the list of route entries and return * the appropriate one for this query */ROUTE_TYPE* search_route(oid* idx, int idx_len, int exact){ static ROUTE_TYPE entry; char *cp; oid *op; if ( exact && idx_len != 4 ) return NULL; if ( idx_len < 4 ) { /* XXX - not correct */ satosin(entry.RT_ADDRESS_FIELD)->sin_port = 0; SOCKADDR(entry.RT_ADDRESS_FIELD) = 0; } else { cp = (char *)&(SOCKADDR(entry.RT_ADDRESS_FIELD)); op = idx; *cp++ = *op++; *cp++ = *op++; *cp++ = *op++; *cp++ = *op++; } if ( Search_Table( route_table, (void*)&entry, exact ) == 0 ) return &entry; else return NULL;} /* * Compare two route entries */intIP_Cmp_Route(const void* first, const void* second){ const ROUTE_TYPE *rt1 = (const ROUTE_TYPE *) first; const ROUTE_TYPE *rt2 = (const ROUTE_TYPE *) second; int res; res = (SOCKADDR(rt1->RT_ADDRESS_FIELD) - SOCKADDR(rt2->RT_ADDRESS_FIELD)); if ( res == 0 && SOCKADDR(rt1->RT_ADDRESS_FIELD) == 0 ) res = ( satosin(rt1->RT_ADDRESS_FIELD)->sin_port - satosin(rt2->RT_ADDRESS_FIELD)->sin_port); return res;} /********************* * * System-specific functions to read * in the list of routing entries * *********************/#ifdef solaris2#define ROUTE_SCAN_RELOADint Route_Scan_Reload( mib_table_t t ){ /* Do something clever with 'getMibstat' */}#endif#ifdef hpux#define ROUTE_SCAN_RELOADint Route_Scan_Reload( mib_table_t t ){ int numEntries, size, i; mib_ipRouteEnt *entries; if (hpux_read_stat((char *)&numEntries, sizeof(int), ID_ipRouteNumEnt) == -1) return -1; size = numEntries*sizeof(mib_ipRouteEnt); if ( (entries=(mib_ipRouteEnt *)malloc ( size )) == NULL ) return -1; if (hpux_read_stat((char *)entries, size, ID_ipRouteTable) == -1) { free( entries ); return -1; } /* XXX - Need to check (& correct?) ifIndex values */ /* Or add all in one go ? */ for ( i = 0 ; i<numEntries ; i++ ) if ( Add_Entry( t, (void*)&(entries[i])) < 0 ) break; free( entries ); return 0;}#endif#ifdef linux#define ROUTE_SCAN_RELOADint Route_Scan_Reload( mib_table_t t ){ FILE *in; char line [256], name[32]; struct rtentry rtent; int refcnt, flags, metric; unsigned use; if (! (in = fopen ("/proc/net/route", "r"))) { snmp_log(LOG_ERR, "snmpd: cannot open /proc/net/route ...\n"); return -1; } while (fgets (line, sizeof(line), in)) { /* * 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", name, &(((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; satosin(rtent.rt_dst)->sin_port = 1; /* Hack! */ rtent.rt_flags = flags;#ifdef NOT_USED rtent.rt_refcnt = refcnt; /* Not used */ rtent.rt_use = use; /* Not used */ rtent.rt_metric = metric; /* Not used */#endif rtent.rt_window = Interface_Index_By_Name( name ); if (Add_Entry( t, (void *)&rtent) < 0 ) break; } fclose (in); return 0;}#endif /* linux */#ifdef CAN_USE_SYSCTL#define ROUTE_SCAN_RELOADint Route_Scan_Reload( mib_table_t t ){ size_t size = 0; int name[] = { CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_DUMP, 0 }; char *all_routes, *cp; struct snmprt entry; struct rt_msghdr *rtp; struct sockaddr *sa; int bit; if (sysctl (name, sizeof (name) / sizeof (int), 0, &size, 0, 0) == -1) { snmp_log(LOG_ERR,"sysctl size fail\n"); return -1; } if ((all_routes = malloc (size)) == NULL) { snmp_log(LOG_ERR,"out of memory allocating route table\n"); return -1; } if (sysctl (name, sizeof (name) / sizeof (int), all_routes, &size, 0, 0) == -1) { snmp_log(LOG_ERR,"sysctl get fail\n"); return -1; } for ( cp = all_routes; cp < all_routes+size; cp += rtp->rtm_msglen) { rtp = (struct rt_msghdr *) cp; /* * Check for a valid route entry */ if (rtp->rtm_type == 0) break; if (rtp->rtm_version != RTM_VERSION) { snmp_log(LOG_ERR, "routing socket message version mismatch (%d instead of %d)\n", rtp->rtm_version, RTM_VERSION); break; } if (rtp->rtm_type != RTM_GET) { snmp_log(LOG_ERR, "routing socket returned message other than GET (%d)\n", rtp->rtm_type); continue; } if (!(rtp->rtm_addrs & RTA_DST)) /* Need a destination address! */ continue; /* * Set up the entry and add it to the list */ memcpy( &entry.hdr, rtp, sizeof( struct rt_msghdr )); entry.index = rtp->rtm_index; entry.rt_dst.s_addr = 0; entry.rt_gateway.s_addr = 0; entry.rt_genmask.s_addr = 0; entry.ifa.s_addr = 0; sa = (struct sockaddr *)(rtp + 1); for ( bit = 1; bit && ((char *)sa < (char *)rtp + rtp->rtm_msglen); bit <<= 1) { if (( rtp->rtm_addrs & bit ) == 0 ) continue; switch ( bit ) { case RTA_DST: entry.rt_dst = satosin(*sa)->sin_addr; break; case RTA_GATEWAY: if ( sa->sa_family == AF_INET ) entry.rt_gateway = satosin(*sa)->sin_addr; break; case RTA_NETMASK: entry.rt_genmask = satosin(*sa)->sin_addr; break; case RTA_IFA: if ( sa->sa_family == AF_INET ) entry.ifa = satosin(*sa)->sin_addr; break; }/* from 'rtsock.c' */#define ROUNDUP(a) \ ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) sa = (struct sockaddr *)((char *)sa + ROUNDUP(sa->sa_len)); } if (Add_Entry( t, (void *)&entry) < 0 ) break; } free( all_routes ); return 0;}#endif#ifdef ROUTE_SCAN_RELOAD#undef RTENTRY_4_4 /* already been handled */#endif#ifdef RTENTRY_4_4#define ROUTE_SCAN_RELOADvoid load_rtentries(struct radix_node *pt, mib_table_t t); /* see below */int Route_Scan_Reload( mib_table_t t ){ struct radix_node_head head, *rt_table[AF_MAX+1]; int i; 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))) continue; load_rtentries(head.rnh_treetop, t ); } return 0;}#endif#ifndef ROUTE_SCAN_RELOAD#define NUM_ROUTE_SYMBOLS 2char* route_symbols[] = { RTHOST_SYMBOL, RTNET_SYMBOL};int Route_Scan_Reload( mib_table_t t ){ RTENTRY **routehash, *m, rt; struct ifnet ifnet; int i, table, hashsize; char name[16], *cp; auto_nlist(RTHASHSIZE_SYMBOL, (char *)&hashsize, sizeof(hashsize)); routehash = (RTENTRY **)malloc(hashsize * sizeof(struct mbuf *)); for (table=0; table<NUM_ROUTE_SYMBOLS; table++) { auto_nlist(route_symbols[table], (char *)routehash, hashsize * sizeof(struct mbuf *)); /* Walk through the hash table of routes */ 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 *)&rt, sizeof (rt)); m = rt.rt_next; if (rt.rt_ifp != 0) { /* Find the I/F name, and hence the index */ 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); rt.RT_INDEX_FIELD = Interface_Index_By_Name( name ); } (void)Add_Entry( t, (void *)&rt); } } } free( routehash ); return 0;}#endif /***************** * * Additional routines * *****************/#ifdef RTENTRY_4_4voidload_rtentries(struct radix_node *pt, mib_table_t t){ struct radix_node node; RTENTRY rt; struct ifnet ifnet; char name[16], temp[16];#if !STRUCT_IFNET_HAS_IF_XNAME register char *cp;#endif if (!klookup((unsigned long)pt , (char *) &node , sizeof (struct radix_node))) { DEBUGMSGTL(("mibII/var_route", "Fail\n")); return; } if (node.rn_b >= 0) { load_rtentries(node.rn_r, t); load_rtentries(node.rn_l, t); return; } if (node.rn_flags & RNF_ROOT) { /* root node */ if (node.rn_dupedkey) load_rtentries(node.rn_dupedkey, t); return; } /* get the route */ klookup((unsigned long)pt, (char *) &rt, sizeof (RTENTRY)); if (rt.rt_ifp != 0) { /* * Find the I/F name, and hence the index */ klookup((unsigned long)rt.rt_ifp, (char *)&ifnet, sizeof (ifnet));#if STRUCT_IFNET_HAS_IF_XNAME#if defined(netbsd1) || defined(openbsd2) strncpy(name, ifnet.if_xname, sizeof name);#else klookup((unsigned long)ifnet.if_xname, name, sizeof name);#endif name[sizeof (name)-1] = '\0';#else klookup((unsigned long)ifnet.if_name, name, sizeof name); name[sizeof (name) - 1] = '\0'; cp = (char *) strchr(name, '\0'); string_append_int (cp, ifnet.if_unit);#endif rt.RT_INDEX_FIELD = Interface_Index_By_Name( name ); /* Add this entry to our table */#if CHECK_RT_FLAGS if (((rt.rt_flags & RTF_CLONING) != RTF_CLONING) && ((rt.rt_flags & RTF_LLINFO) != RTF_LLINFO)) {#endif (void)Add_Entry( t, (void *)&rt);#if CHECK_RT_FLAGS }#endif if (node.rn_dupedkey) load_rtentries(node.rn_dupedkey, t); }}#endif /* RTENTRY_4_4 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -