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

📄 var_route.c

📁 Snmp(简单网管协议)软件包。
💻 C
📖 第 1 页 / 共 4 页
字号:
        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 + -