?? proxyarplib.c
字號:
semGive (proxySemId); return (OK); }/********************************************************************************* proxyNetDelete - delete a proxy network** This routine deletes the proxy network specified by <proxyAddr>. It also* removes all the proxy clients that exist on that network.** RETURNS: OK, or ERROR if unsuccessful.**/STATUS proxyNetDelete ( char * proxyAddr /* proxy net address */ ) { PROXY_NET * pNet; /* proxy network */ NODE * pNode; /* client node */ PROXY_CLNT * pClient; /* proxy client */ STATUS status = ERROR; /* return value */ struct in_addr proxyAddrIn; semTake (proxySemId, WAIT_FOREVER); proxyAddrIn.s_addr = inet_addr (proxyAddr); if ((pNet = proxyNetFind (&proxyAddrIn)) != NULL) { /* clear out the clients */ for (pNode = lstFirst (&pNet->clientList); pNode != NULL;) { pClient = NODE_TO_CLIENT (pNode); proxyClientRemove (pClient); pNode = lstNext (pNode); KHEAP_FREE((caddr_t)pClient); } lstDelete (&proxyNetList, &pNet->netNode); KHEAP_FREE((caddr_t)pNet); status = OK; } semGive (proxySemId); return (status); }/********************************************************************************* proxyNetFind - find a proxy network structure** This routine finds the proxy network structure associated * with <proxyAddr>. The `proxySemId' semaphore must already * be taken before calling this routine.** RETURNS: A PROXY_NET pointer if found, otherwise NULL.** ERRNO: * S_proxyArpLib_INVALID_NET** NOMANUAL*/LOCAL PROXY_NET * proxyNetFind ( struct in_addr * pProxyAddr /* proxy address */ ) { PROXY_NET * pNet; /* proxy network */ for (pNet = (PROXY_NET *) lstFirst (&proxyNetList); (pNet != NULL); pNet = (PROXY_NET *) lstNext (&pNet->netNode)) if (pNet->proxyAddr.s_addr == pProxyAddr->s_addr) return (pNet); errno = S_proxyArpLib_INVALID_PROXY_NET; return (NULL); }/********************************************************************************* proxyIsAMainNet - is the interface a main network ?** This routine determines if <mainAddr> is a main network. * `proxySemId' must already be taken before this routine is called.** RETURNS: TRUE if a main network, FALSE otherwise.** NOMANUAL*/LOCAL BOOL proxyIsAMainNet ( struct in_addr * pMainAddr /* main address */ ) { PROXY_NET * pNet; /* proxy network */ for (pNet = (PROXY_NET *) lstFirst (&proxyNetList); (pNet != NULL); pNet = (PROXY_NET *) lstNext (&pNet->netNode)) if (pNet->mainAddr.s_addr == pMainAddr->s_addr) return (TRUE); return (FALSE); }/********************************************************************************* proxyNetShow - show proxy ARP networks** This routine displays the proxy networks and their associated clients.** EXAMPLE* .CS* -> proxyNetShow* main interface 147.11.1.182 proxy interface 147.11.1.183* client 147.11.1.184* .CE** RETURNS: N/A** INTERNAL* calls printf while semaphore taken.*/void proxyNetShow (void) { PROXY_NET * pNet; /* proxy net */ PROXY_CLNT * pClient; /* proxy client */ NODE * pNode; /* pointer to node */ /* address in ascii */ char asciiAddr [ INET_ADDR_LEN ]; semTake (proxySemId, WAIT_FOREVER); for (pNet = (PROXY_NET *) lstFirst (&proxyNetList); pNet != NULL; pNet = (PROXY_NET *) lstNext (&pNet->netNode)) { inet_ntoa_b (pNet->mainAddr, asciiAddr); printf ("main interface %s ", asciiAddr); inet_ntoa_b (pNet->proxyAddr, asciiAddr); printf ("proxy interface %s\n", asciiAddr); for (pNode = lstFirst (&pNet->clientList); pNode != NULL; pNode = lstNext (pNode)) { pClient = NODE_TO_CLIENT (pNode); inet_ntoa_b (pClient->ipaddr, asciiAddr); printf (" client:%s\n", asciiAddr); } } semGive (proxySemId); }/********************************************************************************* proxyClientAdd - add a proxy client** This routine adds the client, whose ip address is <pArpcom>.ac_ipaddr, onto * the proxy network identified by <pProxyNetAddr>.** RETURNS: OK, or ERROR if unsuccessful.** ERRNO:* S_proxyArpLib_INVALID_ADDRESS** NOMANUAL*/LOCAL STATUS proxyClientAdd ( struct arpcom * pArpcom, /* interface on proxy network */ struct in_addr * pClientAddr, /* client internet address */ u_char * pClientHwAddr /* client hardware address */ ) { PROXY_NET * pNet; /* proxy net */ PROXY_CLNT * pClient; /* proxy client */ struct sockaddr_in sin; /* sin structure */ struct ifaddr * pIfa; /* interface address */ struct in_addr * pProxyNetAddr; /* proxy net address */ int flags; /* ARP flags */ /* validate addresses */ pProxyNetAddr = &pArpcom->ac_ipaddr; if ((in_netof (*pProxyNetAddr) != in_netof (*pClientAddr)) || in_broadcast (*pClientAddr, (struct ifnet *)pArpcom)) { errno = S_proxyArpLib_INVALID_ADDRESS; return (ERROR); } if ((pClient = (PROXY_CLNT *) KHEAP_ALLOC(sizeof(PROXY_CLNT))) == NULL) return (ERROR); bzero ((char *)pClient, sizeof(PROXY_CLNT)); semTake (proxySemId, WAIT_FOREVER); if (!proxyIsAproxyNet (pClientAddr) && ((pNet = (PROXY_NET *) proxyNetFind (pProxyNetAddr)) != NULL)) { /* find main interface */ SIN_FILL (&sin, AF_INET, pNet->mainAddr.s_addr, 0); if ((pIfa = ifa_ifwithaddr ((struct sockaddr *) &sin)) != NULL) { (void) proxyClientDelete (pClientAddr); /* * Create a cloneable route (which will ultimately produce a * standard ARP entry for the client) and add the client to * the active list. */ if (proxyRouteCmd (pClientAddr->s_addr, pProxyNetAddr->s_addr, SIOCADDRT) == OK) { pClient->pNet = pNet; pClient->ipaddr = *pClientAddr; bcopy (pClientHwAddr, pClient->hwaddr, sizeof (struct ether_addr)); hashTblPut (clientTbl, &pClient->hashNode); lstAdd (&pNet->clientList, &pClient->clientNode); /* * Send a gratuitous ARP request to update any entries * on the main network. */ proxyArpSend (pIfa->ifa_ifp, ARPOP_REQUEST, ETHERTYPE_IP, (u_char *) pClientAddr, (u_char *) NULL, (u_char *) pClientAddr); /* * Add a proxy ARP entry allowing the standard ARP processing * to reply to requests for this client from hosts on other * networks. Ignore failures caused if an entry already exists. */ flags = ATF_PUBL | ATF_PROXY | ATF_PERM; arpCmd (SIOCSARP, pClientAddr, pClientHwAddr, &flags); if (proxyArpVerbose) logMsg ("added client 0x%x proxyNet 0x%x\n", ntohl (pClientAddr->s_addr), ntohl (pProxyNetAddr->s_addr), 0, 0, 0, 0); semGive (proxySemId); return (OK); } } else { if (proxyArpVerbose) logMsg ("proxyClientAdd: no main if 0x%x\n", ntohl (pNet->mainAddr.s_addr), 0, 0, 0, 0, 0); } } semGive (proxySemId); KHEAP_FREE((caddr_t)pClient); return (ERROR); }/********************************************************************************* proxyClientDelete - delete a proxy client** This routines deletes the proxy client specified by <pClientAddr>.** RETURNS: OK, or ERROR if unsuccessful.** NOMANUAL*/LOCAL STATUS proxyClientDelete ( struct in_addr * pClientAddr /* client address */ ) { PROXY_CLNT * pClient; /* proxy client */ STATUS status = ERROR; /* return status */ semTake (proxySemId, WAIT_FOREVER); if ((pClient = proxyClientFind (pClientAddr)) != NULL) { proxyClientRemove (pClient); lstDelete (&pClient->pNet->clientList, &pClient->clientNode); if (proxyArpVerbose) logMsg ("deleted client 0x%x\n", ntohl (pClientAddr->s_addr), 0, 0, 0, 0, 0); status = OK; } semGive (proxySemId); if (pClient != NULL) KHEAP_FREE((caddr_t)pClient); return (status); }/********************************************************************************* proxyClientFind - find a proxy client** This routine finds the proxy client structure associated with <pClientAddr>.* Caller must have taken `proxySemId' before this routine is called.** RETURNS: Pointer to PROXY_CLNT if found, NULL otherwise.** ERRNO:* S_proxyArpLib_INVALID_CLIENT** NOMANUAL*/LOCAL PROXY_CLNT * proxyClientFind ( struct in_addr * pClientAddr /* client address */ ) { PROXY_CLNT client; /* client to find */ PROXY_CLNT * pClient; /* pointer to client */ client.ipaddr.s_addr = pClientAddr->s_addr; if ((pClient = (PROXY_CLNT *) hashTblFind (clientTbl, &client.hashNode, 0)) == NULL) errno = S_proxyArpLib_INVALID_CLIENT; return (pClient); }/********************************************************************************* proxyPortFwdOn - enable broadcast forwarding for a particular port** This routine enables broadcasts destined for the port, <port>, to be * forwarded to and from the proxy network. To enable all ports, specify * zero for <port>.** RETURNS: OK, or ERROR if unsuccessful.*/STATUS proxyPortFwdOn ( int port /* port number */ ) { PORT_NODE * pPort; /* port node */ if ((pPort = (PORT_NODE *) KHEAP_ALLOC(sizeof(PORT_NODE))) == NULL) return (ERROR); bzero ((char *)pPort, sizeof(PORT_NODE)); semTake (portTblSemId, WAIT_FOREVER); if (portTblFind (port) != NULL) /* already enabled so ok */ { semGive (portTblSemId); KHEAP_FREE((caddr_t)pPort); return (OK); } pPort->port = (int) port; (void) hashTblPut (portTbl, &pPort->hashNode); semGive (portTblSemId); return (OK); }/********************************************************************************* proxyPortFwdOff - disable broadcast forwarding for a particular port** This routine disables broadcast forwarding on port number <port>. To* disable the (previously enabled) forwarding of all ports via* proxyPortFwdOn(), specify zero for <port>.** RETURNS: OK, or ERROR if unsuccessful.*/STATUS proxyPortFwdOff ( int port /* port number */ ) { PORT_NODE * pPort; /* port node */ semTake (portTblSemId, WAIT_FOREVER); if ((pPort = portTblFind (port)) == NULL) { /* not in port table so ok */ semGive (portTblSemId); return (OK); } (void) hashTblRemove (portTbl, &pPort->hashNode); semGive (portTblSemId); KHEAP_FREE((caddr_t)pPort); return (OK); }/********************************************************************************* portTblFind - find the port node** This routine finds the port node associated with port number <port>.** RETURNS: A pointer to the port node, or NULL if not found.** NOMANUAL*/LOCAL PORT_NODE * portTblFind ( int port /* port number */ ) { PORT_NODE portNode; /* port node */ portNode.port = (int) port; return ((PORT_NODE *) hashTblFind (portTbl, &portNode.hashNode, 0)); }/********************************************************************************* proxyPortShow - show ports enabled for broadcast forwarding** This routine displays the destination ports for which the proxy ARP server* will forward broadcast messages between the physically separate networks.** EXAMPLE* .CS* -> proxyPortShow* enabled ports:* port 67* .CE** RETURNS: N/A** INTERNAL* calls printf() while semaphore taken.*/void proxyPortShow (void) { semTake (portTblSemId, WAIT_FOREVER); printf ("enabled ports:\n"); if (portTblFind (0) != NULL) printf (" all ports enabled\n"); else hashTblEach (portTbl, proxyPortPrint, 0); semGive (portTblSemId); }/********************************************************************************* proxyPortPrint - print ports enabled*
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -