📄 var_route.c
字号:
create_flag = 0; /* * Save in the 'cache' */ memcpy( (char *) saveName,(char *) name, SNMP_MIN(*length,MAX_OID_LEN) * sizeof(oid)); saveName[9] = 0; saveNameLen = *length; saveExact = exact; saveRtIndex = RtIndex; /* * Return the name */ memcpy( (char *) name,(char *) Current, 14 * sizeof(oid)); *length = 14; } *var_len = sizeof(long_return); *route_row = pIpRtrTable->table[RtIndex]; switch(vp->magic){ case IPROUTEDEST: *write_method = write_rte; long_return = pIpRtrTable->table[RtIndex].dwForwardDest; return (u_char *)&long_return; case IPROUTEIFINDEX: *write_method = write_rte; long_return = pIpRtrTable->table[RtIndex].dwForwardIfIndex; return (u_char *)&long_return; case IPROUTEMETRIC1: *write_method = write_rte; long_return = pIpRtrTable->table[RtIndex].dwForwardMetric1; return (u_char *)&long_return; case IPROUTEMETRIC2: *write_method = write_rte; long_return = pIpRtrTable->table[RtIndex].dwForwardMetric2; return (u_char *)&long_return; case IPROUTEMETRIC3: *write_method = write_rte; long_return = pIpRtrTable->table[RtIndex].dwForwardMetric3; return (u_char *)&long_return; case IPROUTEMETRIC4: *write_method = write_rte; long_return = pIpRtrTable->table[RtIndex].dwForwardMetric4; return (u_char *)&long_return; case IPROUTEMETRIC5: *write_method = write_rte; long_return = pIpRtrTable->table[RtIndex].dwForwardMetric5; return (u_char *)&long_return; case IPROUTENEXTHOP: *write_method = write_rte; long_return = pIpRtrTable->table[RtIndex].dwForwardNextHop; return (u_char *)&long_return; case IPROUTETYPE: *write_method = write_rte; long_return = pIpRtrTable->table[RtIndex].dwForwardType; return (u_char *)&long_return; case IPROUTEPROTO: long_return = pIpRtrTable->table[RtIndex].dwForwardProto; return (u_char *)&long_return; case IPROUTEAGE: *write_method = write_rte; long_return = pIpRtrTable->table[RtIndex].dwForwardAge; return (u_char *)&long_return; case IPROUTEMASK: *write_method = write_rte; long_return = pIpRtrTable->table[RtIndex].dwForwardMask; return (u_char *)&long_return; case IPROUTEINFO: *var_len = nullOidLen; return (u_char *)nullOid; default: DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_ipRouteEntry\n", vp->magic)); } return NULL;}#endif /* WIN32 */ #else /* CAN_USE_SYSCTL */#include <stddef.h>#include <stdlib.h>#include <syslog.h>#include <time.h>#include <sys/types.h>#include <sys/param.h>#include <sys/queue.h>#include <sys/socket.h>#include <sys/sysctl.h>#if HAVE_SYS_TIME_H#include <sys/time.h>#endif#include <net/if_dl.h>#if HAVE_SYS_STREAM_H#include <sys/stream.h>#endif#include <net/route.h>#include <netinet/in.h>#define CACHE_TIME (120) /* Seconds */#include "mibincl.h"#include "ip.h"#include "../kernel.h"#include "interfaces.h"#include "struct.h"#include "util_funcs.h"static TAILQ_HEAD(, snmprt) rthead;static char *rtbuf;static size_t rtbuflen;static time_t lasttime;struct snmprt { TAILQ_ENTRY(snmprt) link; struct rt_msghdr *hdr; struct in_addr dest; struct in_addr gateway; struct in_addr netmask; int index; struct in_addr ifa;};static voidrtmsg(struct rt_msghdr *rtm){ struct snmprt *rt; struct sockaddr *sa; int bit, gotdest, gotmask; rt = malloc(sizeof *rt); if (rt == 0) return; rt->hdr = rtm; rt->ifa.s_addr = 0; rt->dest = rt->gateway = rt->netmask = rt->ifa; rt->index = rtm->rtm_index; gotdest = gotmask = 0; sa = (struct sockaddr *)(rtm + 1); for (bit = 1; ((char *)sa < (char *)rtm + rtm->rtm_msglen) && bit; bit <<= 1) { if ((rtm->rtm_addrs & bit) == 0) continue; switch (bit) { case RTA_DST:#define satosin(sa) ((struct sockaddr_in *)(sa)) rt->dest = satosin(sa)->sin_addr; gotdest = 1; break; case RTA_GATEWAY: if (sa->sa_family == AF_INET) rt->gateway = satosin(sa)->sin_addr; break; case RTA_NETMASK: if (sa->sa_len >= offsetof(struct sockaddr_in, sin_addr)) rt->netmask = satosin(sa)->sin_addr; gotmask = 1; break; case RTA_IFA: if (sa->sa_family == AF_INET) rt->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 (!gotdest) { /* XXX can't happen if code above is correct */ snmp_log(LOG_ERR, "route no dest?\n"); free(rt); } else { /* If no mask provided, it was a host route. */ if (!gotmask) rt->netmask.s_addr = ~0; TAILQ_INSERT_TAIL(&rthead, rt, link); }}static intsuck_krt(int force){ time_t now; struct snmprt *rt, *next; size_t len; static int name[6] = { CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_DUMP, 0 }; char *cp; struct rt_msghdr *rtm; time(&now); if (now < (lasttime + CACHE_TIME) && !force) return 0; lasttime = now; for (rt = rthead.tqh_first; rt; rt = next) { next = rt->link.tqe_next; free(rt); } TAILQ_INIT(&rthead); if (sysctl(name, 6, 0, &len, 0, 0) < 0) { syslog(LOG_WARNING, "sysctl net-route-dump: %m"); return -1; } if (len > rtbuflen) { char *newbuf; newbuf = realloc(rtbuf, len); if (newbuf == 0) return -1; rtbuf = newbuf; rtbuflen = len; } if (sysctl(name, 6, rtbuf, &len, 0, 0) < 0) { syslog(LOG_WARNING, "sysctl net-route-dump: %m"); return -1; } cp = rtbuf; while (cp < rtbuf + len) { rtm = (struct rt_msghdr *)cp; /* * NB: * You might want to exclude routes with RTF_WASCLONED * set. This keeps the cloned host routes (and thus also * ARP entries) out of the routing table. Thus, it also * presents management stations with an incomplete view. * I believe that it should be possible for a management * station to examine (and perhaps delete) such routes. */ if (rtm->rtm_version == RTM_VERSION && rtm->rtm_type == RTM_GET) rtmsg(rtm); cp += rtm->rtm_msglen; } return 0;}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.1.A.B.C.D, where A.B.C.D is IP address. * IPADDR starts at offset 10. */ int Save_Valid, result; u_char *cp; oid *op; struct snmprt *rt; static struct snmprt *savert; static int saveNameLen, saveExact; static oid saveName[14], Current[14];#if 0 /* * 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 == *length) && (saveExact == exact)) { int temp = name[9]; name[9] = 0; Save_Valid = !snmp_oid_compare(name, *length, saveName, saveNameLen); name[9] = temp; } else { Save_Valid = 0; }#else Save_Valid = 0;#endif if (Save_Valid) { int temp = name[9]; memcpy(name, Current, 14 * sizeof(oid)); name[9] = temp; *length = 14; rt = savert; } else { /* fill in object part of name for current (less sizeof instance part) */ memcpy(Current, vp->name, (int)(vp->namelen) * sizeof(oid)); suck_krt(0); for (rt = rthead.tqh_first; rt; rt = rt->link.tqe_next) { op = Current + 10; cp = (u_char *)&rt->dest; *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 (rt == NULL) return NULL; /* * Save in the 'cache' */ memcpy(saveName, name, *length * sizeof(oid)); saveName[9] = 0; saveNameLen = *length; saveExact = exact; savert = rt; /* * Return the name */ memcpy(name, Current, 14 * sizeof(oid)); *length = 14; } *write_method = write_rte; *var_len = sizeof long_return; switch (vp->magic) { case IPROUTEDEST: long_return = rt->dest.s_addr; return (u_char *)&long_return; case IPROUTEIFINDEX: long_return = rt->index; return (u_char *)&long_return; case IPROUTEMETRIC1: long_return = (rt->hdr->rtm_flags & RTF_GATEWAY) ? 1 : 0; return (u_char *)&long_return; case IPROUTEMETRIC2: long_return = rt->hdr->rtm_rmx.rmx_rtt; return (u_char *)&long_return; case IPROUTEMETRIC3: long_return = rt->hdr->rtm_rmx.rmx_rttvar; return (u_char *)&long_return; case IPROUTEMETRIC4: long_return = rt->hdr->rtm_rmx.rmx_ssthresh; return (u_char *)&long_return; case IPROUTEMETRIC5: long_return = rt->hdr->rtm_rmx.rmx_mtu; return (u_char *)&long_return; case IPROUTENEXTHOP: if (rt->gateway.s_addr == 0 && rt->ifa.s_addr == 0) long_return = 0; else if (rt->gateway.s_addr == 0) long_return = rt->ifa.s_addr; else long_return = rt->gateway.s_addr; return (u_char *)&long_return; case IPROUTETYPE: long_return = (rt->hdr->rtm_flags & RTF_GATEWAY) ? 4 : 3; return (u_char *)&long_return; case IPROUTEPROTO: long_return = (rt->hdr->rtm_flags & RTF_DYNAMIC) ? 4 : 2; return (u_char *)&long_return; case IPROUTEAGE:#if NO_DUMMY_VALUES return NULL;#endif long_return = 0; return (u_char *)&long_return; case IPROUTEMASK: long_return = rt->netmask.s_addr; return (u_char *)&long_return; case IPROUTEINFO: *var_len = nullOidLen; return (u_char *)nullOid; default: DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_ipRouteEntry\n", vp->magic)); } return NULL;}voidinit_var_route(void){ ;}#endif /* CAN_USE_SYSCTL */#if defined(HAVE_SYS_SYSCTL_H) && !defined(linux)/* get_address() Traverse the address structures after a routing socket message and extract a specific one. Some of this is peculiar to IRIX 6.2, which doesn't have sa_len in the sockaddr structure yet. With sa_len, skipping an address entry would be much easier. */#include <sys/un.h>const struct sockaddr *get_address (const void * _ap, int addresses, int wanted){ const struct sockaddr *ap = (const struct sockaddr *) _ap; int iindex; int bitmask; for (iindex = 0, bitmask = 1; iindex < RTAX_MAX; ++iindex, bitmask <<= 1) { if (bitmask == wanted) { if (bitmask & addresses) { return ap; } else { return 0; } } else if (bitmask & addresses) { unsigned length = (unsigned)snmp_socket_length(ap->sa_family); while (length % sizeof (long) != 0) ++length; ap = (const struct sockaddr *) ((const char *) ap + length); } } return 0;}/* get_in_address() Convenience function for the special case of get_address where an AF_INET address is desired, and we're only interested in the in_addr part. */const struct in_addr *get_in_address (const void * ap, int addresses, int wanted){ const struct sockaddr_in * a; a = (const struct sockaddr_in *)get_address (ap, addresses, wanted); if (a == NULL) return NULL; if (a->sin_family != AF_INET) { DEBUGMSGTL(("snmpd", "unknown socket family %d [AF_INET expected] in var_ipRouteEntry.\n", a->sin_family)); } return &a->sin_addr;}#endif /* HAVE_SYS_SYSCTL_H */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -