📄 proxyarplib.c
字号:
/* proxyArpLib.c - proxy Address Resolution Protocol (ARP) server library *//* Copyright 1984 - 2002 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01p,07may02,kbw man page edits01o,26mar02,vvv fixed proxy broadcast storm (SPR #74518)01n,07dec01,vvv fixed proxy broadcast forwarding enabled by proxyPortFwdOn (SPR #71656)01m,05nov01,vvv fixed transfer of broadcasts across networks (SPR #70768)01l,15oct01,rae merge from truestack ver 01p, base o1h (cleanup)01k,26feb01,spm fixed transfer of broadcasts across networks (SPR #31718)0ij,07feb01,spm added merge record for 30jan01 update from version 01i of tor2_0_x branch (base 01h) and fixed modification history; removed excess code from merge01i,30jan01,ijm merged SPR# 28602 fixes (proxy ARP services are obsolete); added permanent flag to proxy ARP entries and fixed handling of ARP requests for local addresses01h,09feb99,fle doc: put the library description chart inside .CS / .CE markups + and removed dash line to stay in the INTERNAL field01g,14dec97,jdi doc: cleanup.01f,25oct97,kbw fixed man page problems found in beta review01e,15apr97,kbw fixed minor format problems in man page01d,29jan97,vin replaced routeCmd with proxyRouteCmd which adds an explicit network mask of 0xffffffff. Always added the route before adding the arp entry.01c,22nov96,vin added cluster support replaced m_gethdr(..) with mHdrClGet(..).01h,11aug93,jmm Changed ioctl.h and socket.h to sys/ioctl.h and sys/socket.h01g,13nov92,dnw added include of semLibP.h01f,21sep92,jdi Documentation cleanup.01e,16aug92,elh documentation changes.01d,15jun92,elh changed parameters, general cleanup. 01c,04jun92,ajm quieted ansi warnings on netTypeAdd parameters01b,26may92,rrr the tree shuffle -changed includes to have absolute path from h/01a,20sep91,elh written.*//*DESCRIPTIONThis library implements a proxy ARP server that uses the Address ResolutionProtocol (ARP) to make physically distinct networks appear as one logicalnetwork (that is, the networks share the same address space). The serverforwards ARP messages between the separate networks so that hosts on themain network can access hosts on the proxy network without altering theirrouting tables.The proxyArpLibInit() initializes the server and adds this library to theVxWorks image. This happens automatically if INCLUDE_PROXY_SERVER isdefined at the time the image is built. The proxyNetCreate() andproxyNetDelete() routines will enable and disable the forwarding of ARPmessages between networks. The proxyNetShow() routine displays the currentset of proxy networks and the main network and known clients for each.By default, this server automatically adds a client when it first detectsan ARP message from that host. A VxWorks target can also register asa client with the proxyReg() routine and remove that registration withthe proxyUnreg() routine. See the proxyLib manual pages for details.To minimize traffic on the main network, the proxy server will only forwardbroadcast packets to the specified destination ports visible with theproxyPortShow() routine. The proxyPortFwdOn() and proxyPortFwdOff() routineswill alter the current settings. Initially, broadcast forwarding is notactive for any ports.INCLUDE FILES: proxyArpLib.hSEE ALSO: proxyLib, RFC 925, RFC 1027, RFC 826INTERNALProxy Server StructuresThe proxy server must hold information about each of the proxy networks.A proxy network is defined by a proxy network structure (PROXY_NET) whichcontains the local interface addresses for each network and a list of thecurrent proxy clients. The proxyNetList variable stores all of the proxynetwork information.Proxy ClientsA proxy client corresponds to a host on a proxy network. The proxy serverstores information about each proxy client in the PROXY_CLNT structure.By default, the server adds a client when it detects the initial ARP messagefrom the host. Clients may also be added and deleted explicitly withproxyLib routines.The proxy client information is available as both a hash table and a linkedlist. The hash table (called clientTbl) provides fast lookup using theclient IP address as the key. Each proxy network structure provides athird method for accessing a particular proxy client on that network throughthe clientList element of the structure.The combined collection of proxy ARP structures (i.e the proxyNetList, andthe clientTbl) are protected by a single mutual exclusion semaphore.Registering and Unregistering Proxy ClientsA vxWorks target can explicitly register and unregister itself as a proxy client by generating and sending messages of an unused Ethernettype to the server. These messages use the format given by the PROXY_MSGstructure and have either operation type PROXY_REG or PROXY_UNREG. Ifthe proxy server receives one of these messages it performs the appropriateaction by either adding or deleting the node as a proxy client. The servernotifies the client on completion by sending back an ACK message. By default, the proxy server registers a client when it detects the initialARP message from a host and never removes that registration. As a result,the proxy client component is normally not required. The explicit registrationwhich that library allows is only necessary for protocols such as BOOTPthat may require proxy ARP services before configuring an interface withan IP address (which sends a gratuitous ARP message).There are two main hooks into this library from the network modules. Thein_arpinput() routine in if_ether.c uses the first hook to handle specialARP processing. When the server is active, that routine processes all validARP messages as follows: if (proxyArpHook == NULL || (* proxyArpHook) ( (struct arpcom *)m->m_pkthdr.rcvif, m) == FALSE) in_arpinput(m);The proxyArpHook function pointer uses the proxyArpInput() routine to forwardany ARP requests or replies as appropriate. That routine typically returnsFALSE since the standard ARP processing handles most cases correctly.The ipintr() routine in ip_input.c uses a similar function pointer(proxyBroadcastHook) so that the proxy ARP server may forward selectedbroadcast packets to and from the main network with the proxyBroadcastInputroutine.VXWORKS AE PROTECTION DOMAINSUnder VxWorks AE, the functions you assign for either 'proxyArpHook' or 'proxyBroadcastHook' must be valid within the kernel protection domain. This restriction does not apply under non-AE versions of VxWorks. Structure Chart:.CS v v proxyArpLibInit proxyNetShow (in_arpinput) v ----------------proxyArpInput------------------------------------------/ / | \ \ \ \ v | | | | || proxyArpReplyFwd------|---------------|--|---------------------|-------->| | v | | | |v | proxyArpRequestFwd---- -|--|---------------------|-------->proxyArpReply | / | | | | | | | | | | | v v v | | | | proxyArpSend | | | | | | | | | | | | (ipintr) | | | | v | | | | --proxyBroadcastInput-----------------|--> | | / | \ | | | | v ------ <-----------/ | (do_protocol) | |proxyBroadcast | | | v | | | | | proxyMsgInput-----> | |----/ | | | | | | | | | | | | | v | | | | | | proxyIsAMainNet | | | | | v | | /---/ | | |proxyNetCreate| | | | | | v | | | v | |proxyNetDelete| ----------------------|-proxyClientAdd| | v v / | v v | | proxyNetFind<-/ |proxyClientDelete| | v v | \ proxyClientFind<-/ ------------\ v | v vproxyPortFwdOn | proxyPortFwdOff proxyPortShow | | | | | \------------------>|<-------/<--------------------/ v v proxyPortPrint proxyPortTblFind.CE*//* includes */#include "vxWorks.h"#include "netinet/if_ether.h"#include "proxyArpLib.h"#include "sys/socket.h"#include "net/if_arp.h"#include "net/route.h"#include "net/if.h"#include "net/mbuf.h"#include "netinet/in_systm.h"#include "netinet/ip.h"#include "sys/ioctl.h"#include "netinet/in.h"#include "errno.h"#include "hashLib.h"#include "netinet/ip_var.h"#include "netinet/udp.h"#include "netinet/udp_var.h"#include "inetLib.h"#include "string.h"#include "stdlib.h"#include "logLib.h"#include "arpLib.h"#include "routeLib.h"#include "stdio.h"#include "net/unixLib.h"#include "net/if_subr.h"#include "private/semLibP.h"#include "memPartLib.h"#ifdef VIRTUAL_STACK#include "netinet/vsLib.h"#include "netinet/vsProxyArp.h"#endif/* defines */#define CLNT_TBL_SZ 8 /* default client table sz 2^8 */#define PORT_TBL_SZ 8 /* default port table sz 2^8 *//* useful macros */#define proxyIsAproxyNet(pAddr) ((proxyNetFind (pAddr) == NULL) ? \ (FALSE) : (TRUE))#define proxyIsAClient(pAddr) ((proxyClientFind ((pAddr)) == NULL) ? \ (FALSE) : (TRUE))#define NODE_TO_CLIENT(pNode) (PROXY_CLNT *) \ ((u_long)(pNode + 1) - sizeof (PROXY_CLNT)) /* fill in sockaddr_in structure */#define SIN_FILL(pSin, family, addr, port) \ { \ bzero ((caddr_t) (pSin), sizeof (struct sockaddr_in)); \ (pSin)->sin_len = sizeof(struct sockaddr_in); \ (pSin)->sin_family = (family); \ (pSin)->sin_addr.s_addr = (addr); \ (pSin)->sin_port = (port); \ }/* globals */#ifndef VIRTUAL_STACK/* debug variables */BOOL arpDebug = FALSE; /* ARP debug messages */BOOL proxyArpVerbose = FALSE; /* proxy ARP messages */BOOL proxyBroadcastVerbose = FALSE; /* broadcast messages *//* enabling variables */BOOL proxyBroadcastFwd = TRUE; /* forward broadcasts */BOOL arpRegister = TRUE; /* use ARP message to */ /* register clients */int clientTblSizeDefault = CLNT_TBL_SZ; /* default size */int portTblSizeDefault = PORT_TBL_SZ; /* default size *//* locals *//* * proxy semahore & semid and options and structures * protected by proxySem (clientTbl, proxyNetList) */LOCAL SEMAPHORE proxySem; /* proxy ARP semphore */LOCAL SEM_ID proxySemId = &proxySem;int proxySemOptions = (SEM_Q_FIFO | SEM_DELETE_SAFE );LOCAL HASH_ID clientTbl = NULL; /* hashed clients */LOCAL LIST proxyNetList; /* proxy network list *//* port table sem semid and options, and port table*/LOCAL SEMAPHORE portTblSem;LOCAL SEM_ID portTblSemId = &portTblSem;int portTblSemOptions = (SEM_Q_FIFO | SEM_DELETE_SAFE );LOCAL HASH_ID portTbl = NULL; /* hashed ports */LOCAL BOOL proxyLibInitialized = FALSE; /* server initialized */LOCAL int hashKeyArg = 425871; /* hash key */#endif /* VIRTUAL_STACK *//* forward declarations */IMPORT FUNCPTR proxyArpHook;IMPORT FUNCPTR proxyBroadcastHook;IMPORT int in_cksum ();IMPORT int in_broadcast ();/* locals */ /* hook routines */LOCAL void proxyBroadcastInput (struct mbuf *pMbuf, struct ifnet * pIf);LOCAL BOOL proxyArpInput (struct arpcom * pArpcom, struct mbuf * pMbuf);LOCAL void proxyMsgInput (struct arpcom * pArpcom, struct mbuf * pMbuf, int len);LOCAL void proxyArpReply (struct arpcom * pArpcom, struct mbuf * pMbuf, int proto);LOCAL void proxyArpRequestFwd (struct in_addr * pClientAddr, struct mbuf * pMbuf);LOCAL void proxyArpReplyFwd (PROXY_CLNT * pClient, struct mbuf * pMbuf);LOCAL void proxyArpSend (struct ifnet * pIf, int op, int proto, u_char * srcProtoAddr, u_char * dstHwAddr, u_char * dstProtoAddr);LOCAL void proxyBroadcast (struct ifnet * pIf, struct mbuf * pMbuf, int ttl);LOCAL PROXY_NET * proxyNetFind (struct in_addr * pProxyAddr);LOCAL PROXY_CLNT * proxyClientFind (struct in_addr * clientAddr);LOCAL BOOL proxyIsAMainNet (struct in_addr * pMainAddr);LOCAL PORT_NODE * portTblFind (int port);LOCAL BOOL proxyPortPrint (PORT_NODE * pPort);LOCAL STATUS proxyRouteCmd (int destInetAddr, int gateInetAddr, int ioctlCmd); LOCAL STATUS proxyClientAdd (struct arpcom * pArpcom, struct in_addr * pClientAddr, u_char * pClientHwAddr);LOCAL STATUS proxyClientDelete (struct in_addr * pClientAddr);LOCAL void proxyClientRemove (PROXY_CLNT * pClient);LOCAL M_BLK_ID proxyPacketDup (M_BLK_ID pMblk);/********************************************************************************* proxyArpLibInit - initialize proxy ARP** This routine starts the proxy ARP server by initializing the required data* structures and installing the necessary input hooks. It should be called* only once; subsequent calls have no effect. The <clientSizeLog2> and* <portSizeLog2> parameters specify the internal hash table sizes. Each* must be equal to a power of two, or zero to use a default size value.** RETURNS: OK, or ERROR if unsuccessful.*/STATUS proxyArpLibInit ( int clientSizeLog2, /* client table size as power of two */ int portSizeLog2 /* port table size as power of two */ ) { if (proxyLibInitialized) /* already initialized */ return (OK);#ifdef VIRTUAL_STACK/* need to initialize vars */arpDebug = FALSE; /* ARP debug messages */proxyArpVerbose = FALSE; /* proxy ARP messages */proxyBroadcastVerbose = FALSE; /* broadcast messages *//* enabling variables */proxyBroadcastFwd = TRUE; /* forward broadcasts */arpRegister = TRUE; /* use ARP message to */ /* to register clients */clientTblSizeDefault = CLNT_TBL_SZ; /* default size */portTblSizeDefault = PORT_TBL_SZ; /* default size */proxySemId = &proxySem;proxySemOptions = (SEM_Q_FIFO | SEM_DELETE_SAFE );clientTbl = NULL; /* hashed clients *//* port table sem semid and options, and port table*/portTblSemId = &portTblSem;portTblSemOptions = (SEM_Q_FIFO | SEM_DELETE_SAFE );portTbl = NULL; /* hashed ports */proxyLibInitialized = FALSE; /* server initialized */hashKeyArg = 425871; /* hash key */#endif /* VIRTUAL_STACK */ /* use default values if zero passed */ clientSizeLog2 = (clientSizeLog2 == 0) ? clientTblSizeDefault : clientSizeLog2; portSizeLog2 = (portSizeLog2 == 0) ? portTblSizeDefault : portSizeLog2; lstInit (&proxyNetList); if ((proxySemId = semMCreate (proxySemOptions)) == NULL) return (ERROR); if ((portTblSemId = semMCreate (portTblSemOptions)) == NULL) { semDelete (proxySemId); return (ERROR); } if ((clientTbl = hashTblCreate (clientSizeLog2, hashKeyCmp, hashFuncModulo, hashKeyArg)) == NULL) { semDelete (proxySemId); semDelete (portTblSemId); return (ERROR); } if ((portTbl = hashTblCreate (portSizeLog2, hashKeyCmp, hashFuncModulo, hashKeyArg)) == NULL) { semDelete (proxySemId); semDelete (portTblSemId); hashTblDelete (clientTbl); return (ERROR); } proxyBroadcastHook = (FUNCPTR) proxyBroadcastInput; netTypeAdd (PROXY_TYPE, (FUNCPTR) proxyMsgInput); proxyArpHook = (FUNCPTR) proxyArpInput; proxyLibInitialized = TRUE; return (OK); }/********************************************************************************* proxyArpInput - proxy ARP input hook** The proxyArpInput routine completes the gateway transparency between a* proxy network and the main network, allowing the physically distinct* hosts to share the same logical subnet. The standard ARP processing is* able to manage all ARP messages except requests from a proxy client for* a host on the main network. The arpintr routine in the if_ether.c module* calls this routine to relay those requests to the destination network and* return the replies. The routine returns TRUE for those messages to prevent* redundant (and usually incorrect) processing by the in_arpinput routine.** The <pArpcom> parameter identifies the interface which received the* ARP message contained in the <pMbuf> mbuf chain.** RETURNS: TRUE if message handled, or FALSE otherwise.** NOMANUAL*/LOCAL BOOL proxyArpInput ( struct arpcom * pArpcom, /* arpcom structure */ struct mbuf * pMbuf /* mbuf chain */ ) { struct ether_arp * pArp; /* ARP message */ struct in_addr srcAddr; /* source address */ struct in_addr dstAddr; /* destination address */ u_short arpOp; /* ARP operation */ PROXY_CLNT * pClient; /* registration of proxy client */ PROXY_NET * pNet; /* proxy network */ /* * Extract information from the ARP message which the arpintr() * routine has validated.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -