⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 var_route.c

📁 非常不错的网管开发包
💻 C
📖 第 1 页 / 共 3 页
字号:
		     */		    memcpy( (char *)rthead[rtsize],(char *)rt, sizeof(RTENTRY));		    rtsize++;		}	    }            free(routehash);	}	/*	 *  Sort it!	 */	qsort((char *)rthead,rtsize,sizeof(rthead[0]),#ifdef __STDC__              (int (*)(const void *, const void *)) qsort_compare#else              qsort_compare#endif          );}#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]),#ifdef __STDC__              (int (*)(const void *, const void *)) qsort_compare#else              qsort_compare#endif          );}#endif#endif#endif#ifndef solaris2/* *	Create a host table */static int qsort_compare(RTENTRY **r1, 			 RTENTRY **r2){#if NEED_KLGETSA	register u_long dst1 = ntohl(klgetsa((struct sockaddr_in *)(*r1)->rt_dst)->sin_addr.s_addr);	register u_long dst2 = ntohl(klgetsa((struct sockaddr_in *)(*r2)->rt_dst)->sin_addr.s_addr);#else	register u_long dst1 = ntohl(((struct sockaddr_in *) &((*r1)->rt_dst))->sin_addr.s_addr);	register u_long dst2 = ntohl(((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 /* 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 "asn1.h"#include "snmp_api.h"#include "snmp_impl.h"#include "mib.h"#include "snmp.h"#include "../snmp_vars.h"#include "ip.h"#include "../kernel.h"#include "interfaces.h"#include "struct.h"#include "util_funcs.h"#include "snmp_logging.h"#include "snmp_debug.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 + -