📄 var_route.c
字号:
/* * snmp_var_route.c - return a pointer to the named variable. * * *//*********************************************************** Copyright 1988, 1989 by Carnegie Mellon University Copyright 1989 TGV, Incorporated All Rights ReservedPermission to use, copy, modify, and distribute this software and itsdocumentation for any purpose and without fee is hereby granted,provided that the above copyright notice appear in all copies and thatboth that copyright notice and this permission notice appear insupporting documentation, and that the name of CMU and TGV not be usedin advertising or publicity pertaining to distribution of the softwarewithout specific, written prior permission.CMU AND TGV DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NOEVENT SHALL CMU OR TGV BE LIABLE FOR ANY SPECIAL, INDIRECT ORCONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OFUSE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OROTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE ORPERFORMANCE OF THIS SOFTWARE.******************************************************************//* * additions, fixes and enhancements for Linux by Erik Schoenfelder * (schoenfr@ibr.cs.tu-bs.de) 1994/1995. * Linux additions taken from CMU to UCD stack by Jennifer Bray of Origin * (jbray@origin-at.co.uk) 1997 * Support for system({CTL_NET,PF_ROUTE,...) by Simon Leinen * (simon@switch.ch) 1997 */#include <config.h>#if !defined(CAN_USE_SYSCTL)#define GATEWAY /* MultiNet is always configured this way! */#include <stdio.h>#include <sys/types.h>#if HAVE_SYS_PARAM_H#include <sys/param.h>#endif#if HAVE_SYS_SOCKET_H#include <sys/socket.h>#endif#if TIME_WITH_SYS_TIME# include <sys/time.h># include <time.h>#else# if HAVE_SYS_TIME_H# include <sys/time.h># else# include <time.h># endif#endif#if HAVE_SYS_SELECT_H#include <sys/select.h>#endif#if HAVE_NETINET_IN_H#include <netinet/in.h>#endif#if HAVE_ARPA_INET_H#include <arpa/inet.h>#endif#if HAVE_SYSLOG_H#include <syslog.h>#endif#if HAVE_MACHINE_PARAM_H#include <machine/param.h>#endif#if HAVE_SYS_MBUF_H#include <sys/mbuf.h>#endif#if HAVE_NET_IF_H#include <net/if.h>#endif#ifdef HAVE_NET_IF_VAR_H#include <net/if_var.h>#endif#if HAVE_SYS_HASHING_H#include <sys/hashing.h>#endif#if HAVE_NETINET_IN_VAR_H#include <netinet/in_var.h>#endif#define KERNEL /* to get routehash and RTHASHSIZ */#if HAVE_SYS_STREAM_H#include <sys/stream.h>#endif#if HAVE_NET_ROUTE_H#include <net/route.h>#endif#undef KERNEL#ifdef RTENTRY_4_4#ifndef STRUCT_RTENTRY_HAS_RT_UNIT#define rt_unit rt_refcnt /* Reuse this field for device # */#endif#ifndef STRUCT_RTENTRY_HAS_RT_DST#define rt_dst rt_nodes->rn_key#endif#else /* RTENTRY_4_3 */#ifndef STRUCT_RTENTRY_HAS_RT_DST#define rt_dst rt_nodes->rn_key#endif#ifndef STRUCT_RTENTRY_HAS_RT_HASH#define rt_hash rt_pad1#endif#ifndef STRUCT_RTENTRY_HAS_RT_REFCNT#ifndef hpux10#define rt_refcnt rt_pad2#endif#endif#ifndef STRUCT_RTENTRY_HAS_RT_USE#define rt_use rt_pad3#endif#ifndef STRUCT_RTENTRY_HAS_RT_UNIT#define rt_unit rt_refcnt /* Reuse this field for device # */#endif#endif#ifndef NULL#define NULL 0#endif#if HAVE_KVM_OPENFILES#include <fcntl.h>#endif#if HAVE_KVM_H#include <kvm.h>#endif#if HAVE_STRING_H#include <string.h>#else#include <strings.h>#endif#if HAVE_STDLIB_H#include <stdlib.h>#endif#if HAVE_INET_MIB2_H#include <inet/mib2.h>#endif#if HAVE_SYS_SYSCTL_H#include <sys/sysctl.h>#endif#if HAVE_NET_IF_DL_H#include <net/if_dl.h>#endif#if HAVE_WINSOCK_H#include <winsock.h>#endif#if HAVE_NLIST_H#include <nlist.h>#endif#include "auto_nlist.h"#if solaris2#include "kernel_sunos5.h"#endif #ifdef HAVE_SYS_SYSCTL_H# ifdef CTL_NET# ifdef PF_ROUTE# ifdef NET_RT_DUMP# define USE_SYSCTL_ROUTE_DUMP# endif# endif# endif#endif#if HAVE_DMALLOC_H#include <dmalloc.h>#endif#define CACHE_TIME (120) /* Seconds */#include "mibincl.h"#include "ip.h"#include "../kernel.h"#include "interfaces.h"#include "struct.h"#include "util_funcs.h"#ifndef MIN#define MIN(a,b) (((a) < (b)) ? (a) : (b))#endifextern WriteMethod write_rte;#ifndef WIN32#ifdef USE_SYSCTL_ROUTE_DUMPstatic void Route_Scan_Reload (void);static unsigned char *all_routes = 0;static unsigned char *all_routes_end;static size_t all_routes_size;extern const struct sockaddr * get_address (const void *, int, int);extern const struct in_addr * get_in_address (const void *, int, int);/* var_ipRouteEntry(... Arguments: vp IN - pointer to variable entry that points here name IN/OUT - IN/name requested, OUT/name found length IN/OUT - length of IN/OUT oid's exact IN - TRUE if an exact match was requested var_len OUT - length of variable or 0 if function returned write_method out - pointer to function to set variable, otherwise 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. */ struct rt_msghdr *rtp, *saveRtp=0; register int Save_Valid, result; static int saveNameLen=0, saveExact=0; static oid saveName[MAX_OID_LEN], Current[MAX_OID_LEN]; u_char *cp; u_char *ap; oid *op;#if 0 /** ** this optimisation fails, if there is only a single route avail. ** it is a very special case, but better leave it out ... **/#if 0 if (rtsize <= 1) Save_Valid = 0; else#endif /* 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)) { 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 && saveRtp) { register int temp=name[9]; /* Fix up 'lowest' found entry */ memcpy( (char *) name,(char *) Current, 14 * sizeof(oid)); name[9] = temp; *length = 14; rtp = saveRtp; } else {#endif /* 0 */ /* fill in object part of name for current (less sizeof instance part) */ memcpy( (char *)Current,(char *)vp->name, (int)(vp->namelen) * sizeof(oid));#if 0 /* * Only reload if this is the start of a wildcard */ if (*length < 14) { Route_Scan_Reload(); }#else Route_Scan_Reload();#endif for(ap = all_routes; ap < all_routes_end; ap += rtp->rtm_msglen) { rtp = (struct rt_msghdr *) ap; 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)) continue; cp = (u_char *) get_in_address ((struct sockaddr *) (rtp + 1), rtp->rtm_addrs, RTA_DST); if (cp == NULL) return NULL; 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 (ap >= all_routes_end || rtp->rtm_type == 0) return 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; saveRtp = rtp; /* * Return the name */ memcpy( (char *) name,(char *) Current, 14 * sizeof(oid)); *length = 14;#if 0 }#endif /* 0 */ *write_method = write_rte; *var_len = sizeof(long_return); switch(vp->magic){ case IPROUTEDEST: return (u_char *)get_in_address ((struct sockaddr *) (rtp + 1), rtp->rtm_addrs, RTA_DST); case IPROUTEIFINDEX: long_return = (u_long)rtp->rtm_index; return (u_char *)&long_return; case IPROUTEMETRIC1: long_return = (rtp->rtm_flags & RTF_UP) ? 1 : 0; return (u_char *)&long_return; case IPROUTEMETRIC2:#if NO_DUMMY_VALUES return NULL;#endif long_return = -1; return (u_char *)&long_return; case IPROUTEMETRIC3:#if NO_DUMMY_VALUES return NULL;#endif long_return = -1; return (u_char *)&long_return; case IPROUTEMETRIC4:#if NO_DUMMY_VALUES return NULL;#endif long_return = -1; return (u_char *)&long_return; case IPROUTEMETRIC5:#if NO_DUMMY_VALUES return NULL;#endif long_return = -1; return (u_char *)&long_return; case IPROUTENEXTHOP: return (u_char *)get_in_address ((struct sockaddr *) (rtp + 1), rtp->rtm_addrs, RTA_GATEWAY); case IPROUTETYPE: long_return = (rtp->rtm_flags & RTF_UP) ? (rtp->rtm_flags & RTF_UP) ? 4 : 3 : 2; return (u_char *)&long_return; case IPROUTEPROTO: long_return = (rtp->rtm_flags & RTF_DYNAMIC) ? 10 : (rtp->rtm_flags & RTF_STATIC) ? 2 : (rtp->rtm_flags & RTF_DYNAMIC) ? 4 : 1; return (u_char *)&long_return; case IPROUTEAGE:#if NO_DUMMY_VALUES return NULL;#endif long_return = 0; return (u_char *)&long_return; case IPROUTEMASK: if (rtp->rtm_flags & RTF_HOST) { long_return = 0x00000001; return (u_char *)&long_return; } else { return (u_char *)get_in_address ((struct sockaddr *) (rtp + 1), rtp->rtm_addrs, RTA_NETMASK); } case IPROUTEINFO: *var_len = nullOidLen; return (u_char *) nullOid; default: DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_ipRouteEntry\n", vp->magic)); } return NULL;}#else /* not USE_SYSCTL_ROUTE_DUMP */static void Route_Scan_Reload (void);static RTENTRY **rthead=0;static int rtsize=0, rtallocate=0;#if !(defined(linux) || defined(solaris2))#define NUM_ROUTE_SYMBOLS 2static char* route_symbols[] = { RTHOST_SYMBOL, RTNET_SYMBOL};#endif#endif#ifdef USE_SYSCTL_ROUTE_DUMPvoidinit_var_route (void){}static void Route_Scan_Reload (void){ size_t size = 0; int name[] = { CTL_NET, PF_ROUTE, 0, 0, NET_RT_DUMP, 0 }; if (sysctl (name, sizeof (name) / sizeof (int), 0, &size, 0, 0) == -1) { snmp_log(LOG_ERR, "sysctl(CTL_NET,PF_ROUTE,0,0,NET_RT_DUMP,0)\n"); } else { if (all_routes == 0 || all_routes_size < size) { if (all_routes != 0) { free (all_routes); all_routes = 0; } if ((all_routes = malloc (size)) == 0) { snmp_log(LOG_ERR, "out of memory allocating route table\n"); } all_routes_size = size; } else { size = all_routes_size;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -