📄 arplib.c
字号:
/* arpLib.c - Address Resolution Protocol (ARP) table manipulation library *//* Copyright 1984-1992 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------02k,05feb99,dgp document errno values02j,16apr97,vin changed SOCK_DGRAM to SOCK_RAW as udp can be scaled out.02i,11aug93,jmm Changed ioctl.h and socket.h to sys/ioctl.h and sys/socket.h02h,21sep92,jdi documentation cleanup. 02g,14aug92,elh documentation changes. 02f,11jun92,elh changed parameter to arpCmd. Moved arpShow to netShow.02e,26may92,rrr the tree shuffle -changed includes to have absolute path from h/02d,19apr92,elh added spl pair around arpFlush.02c,04apr92,elh added arpFlush.02b,03jan92,elh ansi-fied.02a,18nov91,elh major overhaul. Rewrote to comply with WRS standards and coding conventions, added error handling and documentation.01a,06jun91,jrb written.*//*DESCRIPTIONThis library provides functionality for manipulating the system AddressResolution Protocol (ARP) table (cache). ARP is used by the networkingmodules to map dynamically between Internet Protocol (IP) addresses andphysical hardware (Ethernet) addresses. Once these addresses get resolved,they are stored in the system ARP table.Two routines allow the caller to modify this ARP table manually: arpAdd()and arpDelete(). Use arpAdd() to add new or modify existing entries inthe ARP table. Use arpDelete() to delete entries from the ARP table. UsearpShow() to show current entries in the ARP table.INTERNALThe structure chart for this module looks like: arpAdd arpDelete | \ / | v v | arpCmd vetherAsciiToEnetINCLUDE FILES: arpLib.hSEE ALSO: inetLib, routeLib, etherLib, netShow,.pG "Network"*//* includes */#include "vxWorks.h"#include "sys/types.h"#include "sys/socket.h"#include "sys/ioctl.h"#include "net/if.h"#include "netinet/if_ether.h"#include "net/if_arp.h"#include "net/unixLib.h"#include "errno.h"#include "arpLib.h"#include "inetLib.h"#include "stdio.h"#include "string.h"#include "sockLib.h"#include "ioLib.h"#include "unistd.h"#include "hostLib.h"#include "netShow.h"/* defines */#define ENET_SIZE 6 /* Ethernet address size *//* forward static functions */LOCAL STATUS etherAsciiToEnet (char * asciiAddr, u_char * retEnet);IMPORT arptfree ();IMPORT struct llinfo_arp llinfo_arp;/********************************************************************************* arpAdd - add an entry to the system ARP table** This routine adds a specified entry to the ARP table. <host> is a valid* host name or Internet address. <eaddr> is the Ethernet address of the* host and has the form "x:x:x:x:x:x" where x is a hexadecimal number* between 0 and ff.** The <flags> parameter specifies the ARP flags for the entry;* the following bits are settable:* .iP "ATF_PERM (0x04)"* The ATF_PERM bit makes the ARP entry permanent. A permanent ARP* entry does not time out as do normal ARP entries. * .iP "ATF_PUBL (0x08)"* The ATF_PUBL bit causes the entry to be published (i.e., this system * responds to ARP requests for this entry, even though it is not the host). * .iP "ATF_USETRAILERS (0x10)"* The ATF_USETRAILERS bit indicates that trailer encapsulations can be sent * to this host.** EXAMPLE* The following call creates a permanent ARP table entry for the host with* IP address 90.0.0.3 and Ethernet address 0:80:f9:1:2:3:* .CS* arpAdd ("90.0.0.3", "0:80:f9:1:2:3", 0x4)* .CE** The following call adds an entry to the ARP table for host "myHost", with* an Ethernet address of 0:80:f9:1:2:4; no flags are set for this entry:* .CS* arpAdd ("myHost", "0:80:f9:1:2:4", 0)* .CE** RETURNS: OK, or ERROR if unsuccessful.** ERRNO: S_arpLib_INVALID_ARGUMENT, S_arpLib_INVALID_FLAG**/STATUS arpAdd ( char * host, /* host name or IP address */ char * eaddr, /* Ethernet address */ int flags /* ARP flags */ ) { struct in_addr hostAddr; /* host address */ u_char ea [ENET_SIZE]; /* Ethernet address */ if ((host == NULL) || (eaddr == NULL)) /* validate parameters */ { errno = S_arpLib_INVALID_ARGUMENT; return (ERROR); } /* convert address from ascii */ if (((hostAddr.s_addr = inet_addr (host)) == ERROR) && ((hostAddr.s_addr = hostGetByName (host)) == ERROR)) { printf ("%s:unknown host\n", host); return (ERROR); } /* convert enet from ascii */ if (etherAsciiToEnet (eaddr, ea) != OK) return (ERROR); /* validate flags */ if (flags & ~(ATF_PERM | ATF_PUBL | ATF_USETRAILERS)) { printf("invalid ARP flag\n"); errno = S_arpLib_INVALID_FLAG; return (ERROR); } if (arpCmd (SIOCSARP, &hostAddr, ea, &flags) == ERROR) return (ERROR); return (OK); }/********************************************************************************* arpDelete - delete an entry from the system ARP table** This routine deletes an ARP table entry. <host> specifies the entry to* delete and is a valid host name or Internet address.** EXAMPLE* .CS* arpDelete ("91.0.0.3")* arpDelete ("myHost")* .CE** RETURNS: OK, or ERROR if unsuccessful.** ERRNO: S_arpLib_INVALID_ARGUMENT*/STATUS arpDelete ( char * host /* host name or IP address */ ) { struct in_addr hostAddr; /* host address */ char addrInAscii [ INET_ADDR_LEN ]; /* IP in ascii */ if (host == NULL) /* validate argument */ { errno = S_arpLib_INVALID_ARGUMENT; return (ERROR); } /* convert addr from ascii */ if (((hostAddr.s_addr = inet_addr (host)) == ERROR) && ((hostAddr.s_addr = hostGetByName (host)) == ERROR)) { printf ("%s:unknown host\n", host); return (ERROR); } inet_ntoa_b (hostAddr, addrInAscii); /* convert to printable fmt */ if (arpCmd (SIOCDARP, &hostAddr, (u_char *) NULL, (int *) NULL) == ERROR) { if (errno == ENXIO) printf ("%s (%s) -- no entry\n", host, addrInAscii); return (ERROR); } else printf ("%s (%s) deleted\n", host, addrInAscii); return (OK); }/********************************************************************************* arpCmd - issues an ARP command** This routine issues an ARP command. <cmd> specifies the command and can be* either SIOCSARP, SIOCGARP, or SIOCDARP. <pIpAddr> is the IP address of* the host. <pHwAddr> is an optional pointer to the hardware address.* <pFlags> is an optional pointer to the flags.** RETURNS: OK, or ERROR if unsuccessful.** NOMANUAL** INTERNAL* This is global but no manual so other modules can access it without using* the higher level ascii interface(s).*/STATUS arpCmd ( int cmd, /* arp command */ struct in_addr * pIpAddr, /* ip address */ u_char * pHwAddr, /* hardware address */ int * pFlags /* arp flags */ ) { struct arpreq arpRequest; /* arp request struct */ STATUS status = ERROR; /* return status */ int sock; /* socket */ /* fill in arp request structure */ bzero ((caddr_t) &arpRequest, sizeof (struct arpreq)); arpRequest.arp_pa.sa_family = AF_INET; ((struct sockaddr_in *) &(arpRequest.arp_pa))->sin_addr.s_addr = pIpAddr->s_addr; arpRequest.arp_ha.sa_family = AF_UNSPEC; if (pHwAddr != NULL) bcopy ((caddr_t) pHwAddr ,(caddr_t) arpRequest.arp_ha.sa_data, ENET_SIZE); if (pFlags != NULL) arpRequest.arp_flags = *pFlags; if ((sock = socket (AF_INET, SOCK_RAW, 0)) != ERROR) { if ((status = ioctl (sock, cmd, (int) &arpRequest)) == OK) { if (pHwAddr != NULL) bcopy ((caddr_t) arpRequest.arp_ha.sa_data, (caddr_t) pHwAddr, ENET_SIZE); if (pFlags != NULL) *pFlags = arpRequest.arp_flags; } close (sock); } return (status); }/********************************************************************************* arpFlush - flush all entries in the system ARP table** This routine flushes all non-permanent entries in the ARP cache.** RETURNS: N/A*/void arpFlush (void) { register struct llinfo_arp *la = llinfo_arp.la_next; FAST struct rtentry * pRoute; int s; s = splnet (); while (la != &llinfo_arp) { pRoute = la->la_rt; la = la->la_next; /* if entry permanent */ if ((pRoute->rt_rmx.rmx_expire == 0) || (pRoute->rt_flags == 0)) continue; arptfree(la->la_prev); /* timer has expired; clear */ } splx (s); }/********************************************************************************* etherAsciiToEnet - convert Ethernet address** This routine converts an Ethernet address in ascii format to its normal* 48 bit format. <asciiAddr> is the string Ethernet address which has the form* "x:x:x:x:x:x" where x is a hexadecimal number between 0 and ff. <retEnet> is* where the Ethernet address gets returned. This routine is similar to the* UNIX call ether_aton.** RETURNS: OK, or ERROR if unsuccessful.** ERRNO: S_arpLib_INVALID_ENET_ADDRESS*/LOCAL STATUS etherAsciiToEnet ( char * asciiAddr, /* enet addr in ascii */ u_char * retEnet /* return enet addr */ ) { int enet [ENET_SIZE]; /* Ethernet address */ int ix; /* index variable */ if (sscanf (asciiAddr, "%x:%x:%x:%x:%x:%x", &enet [0], &enet [1], &enet [2], &enet [3], &enet [4], &enet [5]) != ENET_SIZE) { printf ("arp: invalid Ethernet address %s\n", asciiAddr); errno = S_arpLib_INVALID_ENET_ADDRESS; return (ERROR); } for (ix = 0; ix < ENET_SIZE; ix++) retEnet [ix] = (u_char) enet [ix]; return (OK); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -