📄 arp.c
字号:
/* $Header: /usr/cvsroot/target/src/wrn/wm/demo/unxagent/sun/arp.c,v 1.2 2001/11/09 21:49:00 josh Exp $ *//* * Copyright (C) 1999-2005 Wind River Systems, Inc. * All rights reserved. Provided under license only. * Distribution or other use of this software is only * permitted pursuant to the terms of a license agreement * from Wind River Systems (and is otherwise prohibited). * Refer to that license agreement for terms of use. *//**************************************************************************** * Copyright 1988-1997 Epilogue Technology Corporation. * Copyright 1998 Integrated Systems, Inc. * All rights reserved. ****************************************************************************//* * $Log: arp.c,v $ * Revision 1.2 2001/11/09 21:49:00 josh * unxagent demo path adjustment, first pass * * Revision 1.1.1.1 2001/11/05 17:49:16 tneale * Tornado shuffle * * Revision 7.7 2001/01/19 22:25:00 paul * Update copyright. * * Revision 7.6 2000/03/17 00:15:13 meister * Update copyright message * * Revision 7.5 1998/02/25 04:58:16 sra * Update copyrights. * * Revision 7.4 1997/03/20 06:54:04 sra * DFARS-safe copyright text. Zap! * * Revision 7.3 1997/02/25 10:58:16 sra * Update copyright notice, dust under the bed. * * Revision 7.2 1997/01/15 22:35:30 sar * tweak the copy of the ether address from the system into our * structures to try and make it compile on more systems. * * Revision 7.1 1997/01/08 23:01:49 sar * Updated copyright and modified include files to use envoy/h as * appropriate * * Revision 7.0 1996/03/15 22:07:57 sar * Updated revision to 7.0 and copyright to 96 * * Revision 6.1 1995/11/01 01:03:00 sar * removed casts of 0 and no_pp stuff * * Revision 6.0 1995/05/31 21:49:40 sra * Release 6.0. * * Revision 5.4 1995/05/09 17:47:51 sar * Modified the next routine to use OIDC_T's internally and to get rid of * the use of -1 as a tag value allowing us to use the entire 4g range. * * Revision 5.3 1995/05/02 23:25:51 sar * Minor cleanup to make compilers happier. * * Revision 5.2 1995/04/28 22:24:48 sar * Dropped the static/dymanic flag from the nextproc_no_instance call * * Revision 5.1 1995/03/21 19:36:16 sar * Updated method routines to use new api & scheme * * Revision 5.0 1994/05/16 16:20:43 sar * Updated revision to 5.0 and copyright to include 1994 * * Revision 4.0 1993/06/24 17:34:02 sar * Updated rev to 4.0 copyright to 93 * * Revision 3.3 1993/06/13 02:53:35 sar * Removed sysent.h and libc.h and moved them into envoy.h * for mach386. * * Revision 3.2 1993/05/13 22:20:00 sar * Added defines, includes (<sysent.h>, <errno.h>, <libc.h>) and casts * (struct sockaddr *) as well as changed memfoo to MEMFOO and objidcmp * to llist_cmp to get rid of warnings. * * Revision 3.1 1992/09/01 11:34:29 dab * Fixed up for Mach386 * * Revision 3.0 92/04/03 19:53:44 dab * Release 3.0 * * Revision 2.101 92/02/04 10:46:38 dab * Updated for release 3.0 of SNMP. * * Revision 2.100 92/02/03 16:46:02 dab * Generic unix SNMP agent. * * * Rev 2.0 31 Mar 1990 15:34:18 * Initial revision. * *//* [clearcase]modification history-------------------01a,19apr05,job update copyright notices*/#include <stdio.h>#include <string.h>#include <wrn/wm/snmp/engine/asn1.h>#include <wrn/wm/snmp/engine/snmp.h>#include <wrn/wm/snmp/engine/auxfuncs.h>#include <sys/param.h>#include <sys/types.h>#include <sys/protosw.h>#include <sys/socket.h>#include <net/route.h>#include <netinet/in.h>#include <netinet/in_systm.h>#include <netinet/ip.h>#include <netinet/in_pcb.h>#include <sys/ioctl.h>#include <net/if.h>#include <netinet/if_ether.h>#include "snmpvars.h"#include "general.h"#define CACHE_LIFETIME 4/* ARP table last match values */#define atIfIndex 1#define atPhysAddress 2#define atNetAddress 3#define AT_INSTANCE_LEN 6#define AT_INTERFACE 0#define AT_PROT 1#define AT_ADDR 2/* N2M table last match values */#define n2mIfIndex 1#define n2mPhysAddress 2#define n2mNetAddress 3#define n2mType 4#define N2M_INSTANCE_LEN 5#define N2M_INTERFACE 0#define N2M_ADDR 1static struct kernel_symbol arptab = { "_arptab", 0, 0 };static struct kernel_symbol arptab_size = { "_arptab_size", 0, 0 };/* the "digested" arp table is held as follows: */typedef struct atab_s { struct in_addr a_iaddr; /* internet address */ struct ether_addr a_enaddr; /* ethernet address */ u_char a_flags; /* flags */ int a_ifnum; /* interface number */ } atab_t;static atab_t *atabp = 0;static atab_cnt = 0; /* Number of useful entries referenced by atabp *//* For a_flags above: */#define ATA_HAS_MBUF 0x01static struct arptab *krnl_atab = 0;static krnl_atab_cnt = 0; /* # of items the kernel maintains */static krnl_atab_bytes; /* # bytes referenced by krnl_atab */#define ARP_FORCE 1#define invalidate_arptab() arp_cache_time = 0static time_t arp_cache_time = 0;#ifdef DEBUGstatic void pr_arptab(){atab_t * tab;int i;printf("Arp table has %d entries:\n", atab_cnt);if (atab_cnt != 0) { for (tab = atabp, i = 0; i < atab_cnt; tab++, i++) { printf("%3d %15s %02X:%02X:%02X:%02X:%02X:%02X %2.2X %3d\n", i, inet_ntoa(tab->a_iaddr), tab->a_enaddr.ether_addr_octet[0], tab->a_enaddr.ether_addr_octet[1], tab->a_enaddr.ether_addr_octet[2], tab->a_enaddr.ether_addr_octet[3], tab->a_enaddr.ether_addr_octet[4], tab->a_enaddr.ether_addr_octet[5], tab->a_flags, tab->a_ifnum); } }}#endifstatic int read_arptab(int force){ atab_t *atp; struct arptab *kp; time_t now; /* Check whether we actually need to read the cache */ (void) time(&now); if (!force && ((now - arp_cache_time) <= CACHE_LIFETIME)) return 0; arp_cache_time = now; if (find_loc(&arptab) == 0) return -1; (void) read_bytes((off_t)arptab.offset, (char *)krnl_atab, krnl_atab_bytes); /* Now squeeze out the useless entries */ for (atp = atabp, atab_cnt = 0, kp = krnl_atab; kp != &krnl_atab[krnl_atab_cnt]; kp++) { if (!(kp->at_flags & ATF_COM)) continue; atp->a_iaddr = kp->at_iaddr; /* use the & for kp instead of ether_addr_octet as not all systems uses ether_addr_octet (mach386 for example) */ MEMCPY(atp->a_enaddr.ether_addr_octet, &kp->at_enaddr, 6); /* Make note whether an MBUF is attached */ atp->a_flags = kp->at_hold != 0 ? ATA_HAS_MBUF : 0; atp->a_ifnum = 1; /* No interface # given in kernel */ atp++; atab_cnt++; }#ifdef DEBUG pr_arptab();#endif return 0;}void get_arpinfo(OIDC_T last_match, SNMP_PKT_T *pktp, VB_T *vbp, atab_t *tab){switch(last_match) { case atIfIndex: getproc_got_int32(pktp, vbp, tab->a_ifnum); break; case atPhysAddress: getproc_got_string(pktp, vbp, 6, tab->a_enaddr.ether_addr_octet, 0, VT_STRING); break; case atNetAddress: getproc_got_ip_address(pktp, vbp, tab->a_iaddr.s_addr); break; }}/****************************************************************************NAME: arptable_getPURPOSE: Find the appropriate entry in the arp table and attach information from it to the vbp using the getproc_got_* functions. If we can't find an entry indicate that by calling getproc_nosuchins.PARAMETERS: OIDC_T Last component of the object id leading to the leaf node in the MIB. This is usually the identifier for the particular attribute in the table. int Number of components in the unused part of the object identifier OIDC_T * Unused part of the object identifier SNMP_PKT_T * SNMP packet currently being processed. VB_T * Variable being processed.RETURNS: void****************************************************************************//*ARGSUSED*/void arptable_get(OIDC_T last_match, int tcount, OIDC_T *tlist, SNMP_PKT_T *pktp, VB_T *vbp){struct in_addr ipaddr;atab_t *tab;int i;OIDC_T iface;/* Check that the oid is well formed, it must have 6 unused components, be a request for the IP protocol, the ip address must be realistic, and we need to be able to read the arp table */if ((tcount != AT_INSTANCE_LEN) || (*(tlist+AT_PROT) != 1) || (oid_to_ip(4, tlist + AT_ADDR, &ipaddr.s_addr) != 0) || (read_arptab(0) == -1)) { getproc_nosuchins(pktp, vbp); return; }/* Look up entry and call get_arpinfo to fill in the vbp */iface = tlist[AT_INTERFACE];for (tab = atabp, i = 0; i < atab_cnt; i++, tab++) { if ((ipaddr.s_addr == tab->a_iaddr.s_addr) && (iface == tab->a_ifnum)) { get_arpinfo(last_match, pktp, vbp, tab); return; } }/* We fall through to here if there are no entries that match the request */getproc_nosuchins(pktp, vbp);return;}static void zap_arp(struct in_addr ipaddr, int ifnum, char *cp, int length){atab_t *tab;int i;if (read_arptab(ARP_FORCE) == -1) return; /* Look up entry */ for (tab = atabp, i = 0; i < atab_cnt; i++, tab++) { if ((ipaddr.s_addr == tab->a_iaddr.s_addr) && (ifnum == tab->a_ifnum)) { struct arpreq areq; /* Don't mess with anything that has a transmission pending */ if (tab->a_flags & ATA_HAS_MBUF) return; (void)memset((char *)&areq, 0, sizeof(areq)); ((struct sockaddr_in *)&areq.arp_pa)->sin_family = AF_INET; ((struct sockaddr_in *)&areq.arp_pa)->sin_addr.s_addr = tab->a_iaddr.s_addr; areq.arp_ha.sa_family = AF_UNSPEC; if (length == 0) { /* Blow the entry away here */ (void)MEMCPY((char *)areq.arp_ha.sa_data, (char *)(tab->a_enaddr.ether_addr_octet), 6); (void)ioctl(snmp_socket, SIOCDARP, &areq); } else { (void)MEMCPY((char *)areq.arp_ha.sa_data, cp, min(length, 6)); (void)ioctl(snmp_socket, SIOCSARP, &areq); } invalidate_arptab(); return; } }}/****************************************************************************NAME: set_atPhysAddressPURPOSE: Perform the set of the arp addressPARAMETERS: OIDC_T Last component of the object id leading to the leaf node in the MIB. This is usually the identifier for the particular attribute in the table. int Number of components in the unused part of the object identifier OIDC_T * Unused part of the object identifier SNMP_PKT_T * SNMP packet currently being processed. VB_T * Variable being processed.RETURNS: void****************************************************************************//*ARGSUSED*/void set_atPhysAddress(OIDC_T last_match, int tcount, OIDC_T *tlist, SNMP_PKT_T *pktp, VB_T *vbp){struct in_addr ipaddr;if (oid_to_ip(4, tlist + AT_ADDR, &ipaddr.s_addr) == 0) zap_arp(ipaddr, (int)(tlist[AT_INTERFACE]), (char *)EBufferStart(&vbp->value_u.v_string), EBufferUsed(&vbp->value_u.v_string));setproc_good(pktp, vbp);return;}/****************************************************************************NAME: arptable_testPURPOSE: Test whether a given object exists in the ARP tablePARAMETERS: OIDC_T Last component of the object id leading to the leaf node in the MIB. This is usually the identifier for the particular attribute in the table. int Number of components in the unused part of the object identifier OIDC_T * Unused part of the object identifier
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -