📄 at.c
字号:
/* * Template MIB group implementation - at.c * */#include <config.h>#if HAVE_STRING_H#include <string.h>#else#include <strings.h>#endif#if HAVE_STDLIB_H#include <stdlib.h>#endif#if defined(IFNET_NEEDS_KERNEL) && !defined(_KERNEL)#define _KERNEL 1#define _I_DEFINED_KERNEL#endif#include <sys/types.h>#if TIME_WITH_SYS_TIME# ifdef WIN32# include <sys/timeb.h># else# include <sys/time.h># endif# include <time.h>#else# if HAVE_SYS_TIME_H# include <sys/time.h># else# include <time.h># endif#endif#if HAVE_SYS_SOCKET_H#include <sys/socket.h>#endif#if HAVE_NETINET_IN_H#include <netinet/in.h>#endif#if HAVE_NET_IF_H#include <net/if.h>#endif#if HAVE_NET_IF_VAR_H#include <net/if_var.h>#endif#ifdef _I_DEFINED_KERNEL#undef _KERNEL#endif#if HAVE_NETINET_IF_ETHER_H#include <netinet/if_ether.h>#endif#if HAVE_INET_MIB2_H#include <inet/mib2.h>#endif#if HAVE_SYS_PARAM_H#include <sys/param.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_SYS_STREAM_H#include <sys/stream.h>#endif#if HAVE_NET_ROUTE_H#include <net/route.h>#endif#ifdef solaris2#include "kernel_sunos5.h"#endif#if HAVE_WINSOCK_H#include <winsock.h>#endif#if HAVE_DMALLOC_H#include <dmalloc.h>#endif#include "mibincl.h"#include "at.h"#include "interfaces.h"#include "auto_nlist.h"#include "system.h"#if defined(HAVE_SYS_SYSCTL_H) && !defined(CAN_USE_SYSCTL)# if defined(RTF_LLINFO) && !defined(irix6)# define CAN_USE_SYSCTL 1# endif#endif#ifdef cygwin#define WIN32#include <windows.h>#endif /********************* * * Kernel & interface information, * and internal forward declarations * *********************/#ifndef WIN32#ifndef solaris2static void ARP_Scan_Init (void);#ifdef ARP_SCAN_FOUR_ARGUMENTSstatic int ARP_Scan_Next (u_long *, char *, u_long *, u_short *);#elsestatic int ARP_Scan_Next (u_long *, char *, u_long *);#endif#endif#endif /********************* * * Public interface functions * *********************//* define the structure we're going to ask the agent to register our information at */struct variable4 at_variables[] = { {ATIFINDEX, ASN_INTEGER, RONLY, var_atEntry, 1, {1}}, {ATPHYSADDRESS, ASN_OCTET_STR, RONLY, var_atEntry, 1, {2}}, {ATNETADDRESS, ASN_IPADDRESS, RONLY, var_atEntry, 1, {3}}};/* Define the OID pointer to the top of the mib tree that we're registering underneath */oid at_variables_oid[] = { SNMP_OID_MIB2,3,1,1 };void init_at(void){ /* register ourselves with the agent to handle our mib tree */ REGISTER_MIB("mibII/at", at_variables, variable4, at_variables_oid);}#ifndef WIN32#ifndef solaris2/* var_atEntry(... 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 */u_char *var_atEntry(struct variable *vp, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method){ /* * Address Translation table object identifier is of form: * 1.3.6.1.2.1.3.1.1.1.interface.1.A.B.C.D, where A.B.C.D is IP address. * Interface is at offset 10, * IPADDR starts at offset 12. * * IP Net to Media table object identifier is of form: * 1.3.6.1.2.1.4.22.1.1.1.interface.A.B.C.D, where A.B.C.D is IP address. * Interface is at offset 10, * IPADDR starts at offset 11. */ u_char *cp; oid *op; oid lowest[16]; oid current[16]; static char PhysAddr[6], LowPhysAddr[6]; u_long Addr, LowAddr, foundone;#ifdef ARP_SCAN_FOUR_ARGUMENTS u_short ifIndex, lowIfIndex = 0;#endif/* ARP_SCAN_FOUR_ARGUMENTS */ u_long ifType, lowIfType = 0; int oid_length; /* fill in object part of name for current (less sizeof instance part) */ memcpy((char *)current, (char *)vp->name, (int)vp->namelen * sizeof(oid)); if (current[6] == 3 ) { /* AT group oid */ oid_length = 16; } else { /* IP NetToMedia group oid */ oid_length = 15; } LowAddr = 0; /* Don't have one yet */ foundone = 0; ARP_Scan_Init(); for (;;) {#ifdef ARP_SCAN_FOUR_ARGUMENTS if (ARP_Scan_Next(&Addr, PhysAddr, &ifType, &ifIndex) == 0) break; current[10] = ifIndex; if (current[6] == 3 ) { /* AT group oid */ current[11] = 1; op = current + 12; } else { /* IP NetToMedia group oid */ op = current + 11; }#else /* ARP_SCAN_FOUR_ARGUMENTS */ if (ARP_Scan_Next(&Addr, PhysAddr, &ifType) == 0) break; current[10] = 1; if (current[6] == 3 ) { /* AT group oid */ current[11] = 1; op = current + 12; } else { /* IP NetToMedia group oid */ op = current + 11; }#endif /* ARP_SCAN_FOUR_ARGUMENTS */ cp = (u_char *)&Addr; *op++ = *cp++; *op++ = *cp++; *op++ = *cp++; *op++ = *cp++; if (exact){ if (snmp_oid_compare(current, oid_length, name, *length) == 0){ memcpy( (char *)lowest,(char *)current, oid_length * sizeof(oid)); LowAddr = Addr; foundone = 1;#ifdef ARP_SCAN_FOUR_ARGUMENTS lowIfIndex = ifIndex;#endif /* ARP_SCAN_FOUR_ARGUMENTS */ memcpy( LowPhysAddr,PhysAddr, sizeof(PhysAddr)); lowIfType = ifType; break; /* no need to search further */ } } else { if ((snmp_oid_compare(current, oid_length, name, *length) > 0) && ((foundone == 0) || (snmp_oid_compare(current, oid_length, lowest, oid_length) < 0))){ /* * if new one is greater than input and closer to input than * previous lowest, save this one as the "next" one. */ memcpy( (char *)lowest,(char *)current, oid_length * sizeof(oid)); LowAddr = Addr; foundone = 1;#ifdef ARP_SCAN_FOUR_ARGUMENTS lowIfIndex = ifIndex;#endif /* ARP_SCAN_FOUR_ARGUMENTS */ memcpy( LowPhysAddr,PhysAddr, sizeof(PhysAddr)); lowIfType = ifType; } } } if (foundone == 0) return(NULL); memcpy( (char *)name,(char *)lowest, oid_length * sizeof(oid)); *length = oid_length; *write_method = 0; switch(vp->magic){ case IPMEDIAIFINDEX: /* also ATIFINDEX */ *var_len = sizeof long_return;#ifdef ARP_SCAN_FOUR_ARGUMENTS long_return = lowIfIndex;#else /* ARP_SCAN_FOUR_ARGUMENTS */#if NO_DUMMY_VALUES return NULL;#endif long_return = 1; /* XXX */#endif /* ARP_SCAN_FOUR_ARGUMENTS */ return (u_char *)&long_return; case IPMEDIAPHYSADDRESS: /* also ATPHYSADDRESS */ *var_len = sizeof(LowPhysAddr); return (u_char *)LowPhysAddr; case IPMEDIANETADDRESS: /* also ATNETADDRESS */ *var_len = sizeof long_return; long_return = LowAddr; return (u_char *)&long_return; case IPMEDIATYPE: *var_len = sizeof long_return; long_return = lowIfType; return (u_char *)&long_return; default: DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_atEntry\n", vp->magic)); } return NULL;}#else /* solaris2 */typedef struct if_ip { int ifIdx; IpAddress ipAddr;} if_ip_t;static intAT_Cmp(void *addr, void *ep){ mib2_ipNetToMediaEntry_t *mp = (mib2_ipNetToMediaEntry_t *) ep; int ret = -1; DEBUGMSGTL(("mibII/at", "......... AT_Cmp %lx<>%lx %d<>%d (%.5s)\n", mp->ipNetToMediaNetAddress, ((if_ip_t *)addr)->ipAddr, ((if_ip_t*)addr)->ifIdx,Interface_Index_By_Name (mp->ipNetToMediaIfIndex.o_bytes, mp->ipNetToMediaIfIndex.o_length), mp->ipNetToMediaIfIndex.o_bytes)); if (mp->ipNetToMediaNetAddress != ((if_ip_t *)addr)->ipAddr) ret = 1; else if (((if_ip_t*)addr)->ifIdx != Interface_Index_By_Name (mp->ipNetToMediaIfIndex.o_bytes, mp->ipNetToMediaIfIndex.o_length)) ret = 1; else ret = 0; DEBUGMSGTL(("mibII/at", "......... AT_Cmp returns %d\n", ret)); return ret;}u_char *var_atEntry(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.3.1.1.1.interface.1.A.B.C.D, where A.B.C.D is IP address. * Interface is at offset 10, * IPADDR starts at offset 12. */#define AT_MAX_NAME_LENGTH 16#define AT_IFINDEX_OFF 10 u_char *cp; oid *op; oid lowest[AT_MAX_NAME_LENGTH]; oid current[AT_MAX_NAME_LENGTH]; if_ip_t NextAddr; mib2_ipNetToMediaEntry_t entry, Lowentry; int Found = 0; req_e req_type; int offset, olength; /* fill in object part of name for current (less sizeof instance part) */ DEBUGMSGTL(("mibII/at", "var_atEntry: ")); DEBUGMSGOID(("mibII/at", vp->name, vp->namelen)); DEBUGMSG(("mibII/at"," %d\n", exact)); memset (&Lowentry, 0, sizeof (Lowentry)); memcpy( (char *)current,(char *)vp->name, vp->namelen * sizeof(oid)); lowest[0] = 1024; for (NextAddr.ipAddr = (u_long)-1, NextAddr.ifIdx = 255, req_type = GET_FIRST; ; NextAddr.ipAddr = entry.ipNetToMediaNetAddress, NextAddr.ifIdx = current [AT_IFINDEX_OFF], req_type = GET_NEXT) { if (getMibstat(MIB_IP_NET, &entry, sizeof(mib2_ipNetToMediaEntry_t), req_type, &AT_Cmp, &NextAddr) != 0) break; current[AT_IFINDEX_OFF] = Interface_Index_By_Name (entry.ipNetToMediaIfIndex.o_bytes, entry.ipNetToMediaIfIndex.o_length); if (current[6] == 3 ) { /* AT group oid */ current[AT_IFINDEX_OFF+1] = 1; offset = AT_IFINDEX_OFF+2; olength = AT_IFINDEX_OFF+6; } else { offset = AT_IFINDEX_OFF+1; olength = AT_IFINDEX_OFF+5; } COPY_IPADDR(cp,(u_char *)&entry.ipNetToMediaNetAddress, op, current+offset); if (exact){ if (snmp_oid_compare(current, olength, name, *length) == 0){ memcpy( (char *)lowest,(char *)current, olength * sizeof(oid)); Lowentry = entry; Found++; break; /* no need to search further */ } } else { if (snmp_oid_compare(current, olength, name, *length) > 0 && snmp_oid_compare(current, olength, lowest, *length) < 0) { /* * if new one is greater than input and closer to input than * previous lowest, and is not equal to it, save this one as the "next" one. */ memcpy( (char *)lowest,(char *)current, olength * sizeof(oid)); Lowentry = entry; Found++; } } } DEBUGMSGTL(("mibII/at", "... Found = %d\n", Found)); if (Found == 0) return(NULL); memcpy( (char *)name,(char *)lowest, olength * sizeof(oid)); *length = olength; *write_method = 0; switch(vp->magic){ case IPMEDIAIFINDEX: *var_len = sizeof long_return; long_return = Interface_Index_By_Name(Lowentry.ipNetToMediaIfIndex.o_bytes, Lowentry.ipNetToMediaIfIndex.o_length); return (u_char *)&long_return; case IPMEDIAPHYSADDRESS: *var_len = Lowentry.ipNetToMediaPhysAddress.o_length; (void)memcpy(return_buf, Lowentry.ipNetToMediaPhysAddress.o_bytes, *var_len); return (u_char *)return_buf; case IPMEDIANETADDRESS: *var_len = sizeof long_return; long_return = Lowentry.ipNetToMediaNetAddress; return (u_char *)&long_return; case IPMEDIATYPE: *var_len = sizeof long_return; long_return = Lowentry.ipNetToMediaType; return (u_char *)&long_return; default: DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_atEntry\n", vp->magic)); } return NULL;}#endif /* solaris2 */ /********************* * * Internal implementation functions * *********************/#ifndef solaris2static int arptab_size, arptab_current;#if CAN_USE_SYSCTLstatic char *lim, *rtnext;static char *at = 0;#else#ifdef STRUCT_ARPHD_HAS_AT_NEXTstatic struct arphd *at=0;static struct arptab *at_ptr, at_entry;static struct arpcom at_com;#elsestatic struct arptab *at=0;#endif#endif /* CAN_USE_SYSCTL */static void ARP_Scan_Init (void){#ifndef CAN_USE_SYSCTL#ifndef linux if (!at) { auto_nlist(ARPTAB_SIZE_SYMBOL, (char *)&arptab_size, sizeof arptab_size);#ifdef STRUCT_ARPHD_HAS_AT_NEXT at = (struct arphd *) malloc(arptab_size * sizeof(struct arphd));#else at = (struct arptab *) malloc(arptab_size * sizeof(struct arptab));#endif }#ifdef STRUCT_ARPHD_HAS_AT_NEXT auto_nlist(ARPTAB_SYMBOL, (char *)at, arptab_size * sizeof(struct arphd)); at_ptr = at[0].at_next;#else auto_nlist(ARPTAB_SYMBOL, (char *)at, arptab_size * sizeof(struct arptab));#endif arptab_current = 0;#else /* linux */ FILE *in = fopen ("/proc/net/arp", "r"); int i, n = 0; char line [128]; int za, zb, zc, zd, ze, zf, zg, zh, zi, zj; char ifname[20]; if (!in) { snmp_log(LOG_ERR, "snmpd: Cannot open /proc/net/arp\n"); arptab_current = 0; return; } for (n = -1; fgets (line, sizeof(line), in); n++) ; fclose (in); in = fopen ("/proc/net/arp", "r"); fgets(line, sizeof(line), in); /* skip header */ if (at) free (at); arptab_current = 0; /* it was missing, bug??? */ arptab_size = n; if (arptab_size > 0) at = (struct arptab *) malloc (arptab_size * sizeof (struct arptab)); else at = NULL; for (i = 0; i < arptab_size; i++) { u_long tmp_a; while (line == fgets (line, sizeof(line), in) && 12 != sscanf (line, "%d.%d.%d.%d 0x%*x 0x%x %x:%x:%x:%x:%x:%x %*[^ ] %20s\n", &za, &zb, &zc, &zd, &at[i].at_flags, &ze, &zf, &zg, &zh, &zi, &zj, ifname)) { snmp_log(LOG_ERR, "Bad line in /proc/net/arp: %s", line); continue; } at [i].at_enaddr[0] = ze; at [i].at_enaddr[1] = zf;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -