📄 at.c
字号:
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;#elif defined(hpux11)static mib_ipNetToMediaEnt *at = (mib_ipNetToMediaEnt *)0;#elsestatic struct arptab *at=0;#endif#endif /* CAN_USE_SYSCTL */static void ARP_Scan_Init (void){#ifndef CAN_USE_SYSCTL#ifndef linux#ifdef hpux11 int fd; struct nmparms p; int val; unsigned int ulen; int ret; if (at) free(at); at = (mib_ipNetToMediaEnt *)0; arptab_size = 0; if ((fd = open_mib("/dev/ip", O_RDONLY, 0, NM_ASYNC_OFF)) >= 0) { p.objid = ID_ipNetToMediaTableNum; p.buffer = (void *)&val; ulen = sizeof(int); p.len = &ulen; if ((ret = get_mib_info(fd, &p)) == 0) arptab_size = val; if (arptab_size > 0) { ulen = (unsigned)arptab_size * sizeof(mib_ipNetToMediaEnt); at = (mib_ipNetToMediaEnt *)malloc(ulen); p.objid = ID_ipNetToMediaTable; p.buffer = (void *)at; p.len = &ulen; if ((ret = get_mib_info(fd, &p)) < 0) arptab_size = 0; } close_mib(fd); } arptab_current = 0;#else /* hpux11 */ 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;#endif /* hpux11 */#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; at [i].at_enaddr[2] = zg; at [i].at_enaddr[3] = zh; at [i].at_enaddr[4] = zi; at [i].at_enaddr[5] = zj; tmp_a = ((u_long)za << 24) | ((u_long)zb << 16) | ((u_long)zc << 8) | ((u_long)zd ) ; at [i].at_iaddr.s_addr = htonl(tmp_a); at [i].if_index = Interface_Index_By_Name(ifname, strlen(ifname)); } fclose (in);#endif /* linux */#else /* CAN_USE_SYSCTL */ int mib[6]; size_t needed; mib[0] = CTL_NET; mib[1] = PF_ROUTE; mib[2] = 0; mib[3] = AF_INET; mib[4] = NET_RT_FLAGS; mib[5] = RTF_LLINFO; if (at) free(at); if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) snmp_log_perror("route-sysctl-estimate"); if ((at = malloc(needed ? needed : 1)) == NULL) snmp_log_perror("malloc"); if (sysctl(mib, 6, at, &needed, NULL, 0) < 0) snmp_log_perror("actual retrieval of routing table"); lim = at + needed; rtnext = at;#endif /* CAN_USE_SYSCTL */}#ifdef ARP_SCAN_FOUR_ARGUMENTSstatic int ARP_Scan_Next(u_long *IPAddr, char *PhysAddr, u_long *ifType, u_short *ifIndex)#elsestatic int ARP_Scan_Next(u_long *IPAddr, char *PhysAddr, u_long *ifType)#endif{#ifndef CAN_USE_SYSCTL#ifdef linux if (arptab_current<arptab_size) { /* copy values */ *IPAddr= at[arptab_current].at_iaddr.s_addr; *ifType= (at[arptab_current].at_flags & ATF_PERM) ? 4/*static*/ : 3/*dynamic*/ ; *ifIndex = at[arptab_current].if_index; memcpy( PhysAddr, &at[arptab_current].at_enaddr, sizeof(at[arptab_current].at_enaddr) ); /* increment to point next entry */ arptab_current++; /* return success */ return( 1 ); }#elif defined(hpux11) if (arptab_current < arptab_size) { /* copy values */ *IPAddr = at[arptab_current].NetAddr; memcpy(PhysAddr, at[arptab_current].PhysAddr.o_bytes, at[arptab_current].PhysAddr.o_length); *ifType = at[arptab_current].Type; *ifIndex = at[arptab_current].IfIndex; /* increment to point next entry */ arptab_current++; /* return success */ return (1); }#elif !defined(ARP_SCAN_FOUR_ARGUMENTS) || defined(hpux) register struct arptab *atab; while (arptab_current < arptab_size) {#ifdef STRUCT_ARPHD_HAS_AT_NEXT /* The arp table is an array of linked lists of arptab entries. Unused slots have pointers back to the array entry itself */ if ( at_ptr == (auto_nlist_value(ARPTAB_SYMBOL) + arptab_current*sizeof(struct arphd))) { /* Usused */ arptab_current++; at_ptr = at[arptab_current].at_next; continue; } klookup( at_ptr, (char *)&at_entry, sizeof(struct arptab)); klookup( at_entry.at_ac, (char *)&at_com, sizeof(struct arpcom)); at_ptr = at_entry.at_next; atab = &at_entry; *ifIndex = at_com.ac_if.if_index; /* not strictly ARPHD */#else /* STRUCT_ARPHD_HAS_AT_NEXT */ atab = &at[arptab_current++];#endif /* STRUCT_ARPHD_HAS_AT_NEXT */ if (!(atab->at_flags & ATF_COM)) continue; *ifType = (atab->at_flags & ATF_PERM) ? 4 : 3 ; *IPAddr = atab->at_iaddr.s_addr;#if defined (sunV3) || defined(sparc) || defined(hpux) memcpy( PhysAddr,(char *) &atab->at_enaddr, sizeof(atab->at_enaddr));#endif#if defined(mips) || defined(ibm032) memcpy( PhysAddr,(char *) atab->at_enaddr, sizeof(atab->at_enaddr));#endif return(1); }#endif /* linux || hpux11 || !ARP_SCAN_FOUR_ARGUMENTS || hpux */ return 0; /* we need someone with an irix box to fix this section */#else /* !CAN_USE_SYSCTL */ struct rt_msghdr *rtm; struct sockaddr_inarp *sin; struct sockaddr_dl *sdl; while (rtnext < lim) { rtm = (struct rt_msghdr *)rtnext; sin = (struct sockaddr_inarp *)(rtm + 1); sdl = (struct sockaddr_dl *)(sin + 1); rtnext += rtm->rtm_msglen; if (sdl->sdl_alen) { *IPAddr = sin->sin_addr.s_addr; memcpy( PhysAddr,(char *) LLADDR(sdl), sdl->sdl_alen); *ifIndex = sdl->sdl_index; *ifType = 1; /* XXX */ return(1); } } return(0); /* "EOF" */#endif /* !CAN_USE_SYSCTL */}#endif /* solaris2 */#else /* WIN32 */#include <iphlpapi.h>extern WriteMethod write_arp;MIB_IPNETROW *arp_row = NULL;int create_flag = 0;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.?.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.?.interface.A.B.C.D, where A.B.C.D is IP address. * Interface is at offset 10, * IPADDR starts at offset 11.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -