⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 proxyarplib.c

📁 the vxworks system kernel souce packeg.there may be something you need .
💻 C
📖 第 1 页 / 共 4 页
字号:
* This routine prints the list of enabled ports.** RETURNS: TRUE (always)** NOMANUAL*/LOCAL BOOL proxyPortPrint    (    PORT_NODE *		pPort				/* port node 	*/    )    {    printf ("    port %d\n", pPort->port);    return (TRUE);    }/********************************************************************************* proxyBroadcastInput - hook routine for broadcasts** This routine is the hook routine that forwards a broadcast datagram* <pMbuf> which was received on interface <pIf> to and from proxy interfaces.* As a measure of control, it only forwards broadcasts that are destined for* ports that have been previously enabled (with proxyPortFwdOn()).* proxyBroadcastInput() gets called from routine ipintr(), in file ip_input.c.* It assumes the datagram is whole (i.e., if the datagram was fragmented,* then it was previously reassembled).** If the broadcast datagram came from a main network, then forward the* broadcast to all proxy network's that have the input interface as their* main network.  If the broadcast came from a proxy network, then forward* the broadcast to all other proxy networks that have that proxy network's main* network as their main network (and forward it to the main network as well).** INTERNAL* Would we ever want to forward anything beyond UDP broadcasts (what* about ICMP?)? The old backplane driver makes a local copy of broadcasts* so we'll get an extra copy of broadcast packets if we are using the old* backplane driver.** RETURNS: N/A** NOMANUAL*/LOCAL void proxyBroadcastInput    (    struct mbuf *			pMbuf,		/* mbuf chain	     */    struct ifnet *			pIf		/* interface pointer */    )    {    struct in_addr			inputAddr;	/* input interface   */    PROXY_NET *				pNet;		/* proxy network     */    struct in_addr			mainAddr;	/* main interface    */    struct ifaddr *			pIfa;		/* if address	     */    struct sockaddr_in			sin;		/* sin structure     */    struct ip *				pIP;		/* ip header pointer */    int					hlen;		/* ip header length  */    struct udphdr *			pUDP;		/* udp header 	     */    if (!proxyBroadcastFwd) 			/* broadcasts got turned off */	return;    if (pMbuf->m_len < sizeof (struct ip) &&	(pMbuf = m_pullup(pMbuf, sizeof (struct ip))) == 0)	return;        pIP = mtod (pMbuf, struct ip *);		/* pulled tight in ip_input */    /*     * Only forward UDP broadcast packets.     */    if (pIP->ip_p != IPPROTO_UDP)	return;    hlen = pIP->ip_hl << 2;    /*     * make sure IP header (with options) and UDP header fit into the     * first mbuf.     */    if (pMbuf->m_len < (hlen + sizeof (struct udphdr)))	{        if ((pMbuf = m_pullup (pMbuf, hlen + sizeof (struct udphdr))) == 0)	    return;    	pIP = mtod (pMbuf, struct ip *);	}    pUDP = (struct udphdr *) ((u_char *) pIP + hlen);    if (!portTblFind (ntohs (pUDP->uh_dport)) && !portTblFind ((u_short) 0))	return;    semTake (proxySemId, WAIT_FOREVER);    inputAddr.s_addr  =  ((struct arpcom *) pIf)->ac_ipaddr.s_addr;    /* Validate the interface which received the original broadcast message. */    pNet = proxyNetFind (&inputAddr);    if (pNet == NULL && !proxyIsAMainNet (&inputAddr))        {        /*         * The receiving interface is not part of any proxy network or         * main network. Don't forward the broadcast message.         */        semGive (proxySemId);        return;        }        if (pNet)	{	/*	 * Input interface was a proxy network.  Find main network associated	 * with that proxy network (and the interface to the main network)	 * and forward the datagram onto it.	 */	mainAddr.s_addr = pNet->mainAddr.s_addr;    	SIN_FILL(&sin, AF_INET, pNet->mainAddr.s_addr, 0);    	if ((pIfa = ifa_ifwithaddr ((struct sockaddr *) &sin)) != NULL)	    proxyBroadcast (pIfa->ifa_ifp, pMbuf, pIP->ip_ttl - 1);	}    else	{    	mainAddr.s_addr = inputAddr.s_addr;	}    for (pNet = (PROXY_NET *) lstFirst (&proxyNetList); (pNet != NULL);	 pNet = (PROXY_NET *) lstNext (&pNet->netNode))	{    	/*	 * Forward packet to all appropriate proxy networks. (A copy is not         * sent to any proxy network which contained the original broadcast).     	 */	if ((pNet->mainAddr.s_addr == mainAddr.s_addr)  &&	    (pNet->proxyAddr.s_addr != inputAddr.s_addr))	    {	    /* find proxy interface and ship it off */    	    SIN_FILL(&sin, AF_INET, pNet->proxyAddr.s_addr, 0);    	    if ((pIfa = ifa_ifwithaddr ((struct sockaddr *) &sin)) != NULL)		proxyBroadcast (pIfa->ifa_ifp, pMbuf, 1);	    }	}    semGive (proxySemId);    }/********************************************************************************* proxyBroadcast - send a broadcast** This routine sends a copy of the broadcast message <pMbuf> on the interface* <pIf> so that all (physically separated) hosts on a logical subnet receive* the expected broadcasts.** RETURNS: N/A** NOMANUAL*/LOCAL void proxyBroadcast    (    FAST struct ifnet *		pIf,		/* output interface pointer */    struct mbuf *		pMbuf,  	/* mbuf chain		    */    int                         ttl             /* time to live */    )    {    struct mbuf *		pMbufCopy;	/* mbuf chain (copy)	    */    struct sockaddr_in  	sin;		/* address 		    */    struct ip *			pIP;		/* ip header pointer	    */    /*      * Copy the message to protect forwarded packet from changes made by      * upper layers.     */    if ((pMbufCopy = (struct mbuf *) proxyPacketDup (pMbuf)) == NULL)	return;    pMbufCopy->mBlkHdr.mFlags |= M_PROXY;    pIP = mtod (pMbufCopy, struct ip *);    if (proxyBroadcastVerbose)    	logMsg ("forward broadcast (if:0x%x) src 0x%x [%d] dst 0x%x [%d]\n",	        ((struct arpcom *) pIf)->ac_ipaddr.s_addr,		pIP->ip_src.s_addr, ((struct udpiphdr *) pIP)->ui_sport,		pIP->ip_dst.s_addr, ((struct udpiphdr *) pIP)->ui_dport, 0);    SIN_FILL(&sin, AF_INET, pIP->ip_dst.s_addr, 0);    /* Adjust the IP packet length (modified in receive processing). */    pIP->ip_len +=  pIP->ip_hl << 2;    /* Convert appropriate header fields to network order for transmission. */    pIP->ip_id  = htons ((u_short) pIP->ip_id);	    pIP->ip_len = htons ((u_short) pIP->ip_len);    pIP->ip_off = htons ((u_short) pIP->ip_off);    pIP->ip_ttl = ttl;    pIP->ip_sum = 0;    pIP->ip_sum = in_cksum (pMbufCopy, pIP->ip_hl << 2);     (*pIf->if_output)(pIf, pMbufCopy, (struct sockaddr *) &sin, 		      (struct rtentry *) NULL);    }/********************************************************************************* proxyMsgInput - input routine for proxy messages** This routine is the input hook routine for proxy messages.  It handles* the probe, client register and client unregister messages.  For a probe* message it just sends an ACK.  PROXY_REG and PROXY_UNREG messages cause* the proxy server to add the client (via proxyClientAdd()) and delete the* (via proxyClientDelete()), respectively then reply with an ACK.** <pArpcom> is the arpcom structure for the input interface.  <pMbuf> is the* mbuf chain.  <len> is the length of the message.** RETURNS: N/A** NOMANUAL*/LOCAL void proxyMsgInput    (    FAST struct arpcom *	pArpcom,	/* arpcom structure 	*/    FAST struct mbuf *		pMbuf,         	/* mbuf chain       	*/    int                         len             /* length           	*/    )    {    PROXY_MSG *             	pMsg;		/* proxy message	*/    int				op;		/* operation 		*/    BOOL                        sendACK = FALSE;/* send client ack	*/    if (pMbuf->m_len < sizeof (PROXY_MSG))      /* check message length */        {        m_freem (pMbuf);        return;        }    pMsg = mtod (pMbuf, PROXY_MSG *);    op = ntohl (pMsg->op);    if (proxyArpVerbose)    	logMsg ("(%d) from 0x%x [%s]\n", op, ntohl (pMsg->clientAddr.s_addr),                (int) ether_sprintf (pMsg->clientHwAddr), 0, 0, 0);    if (proxyLibInitialized)        {    	if (op == PROXY_PROBE)       /* probe message        */	    sendACK = TRUE;	        semTake (proxySemId, WAIT_FOREVER);        if (op == PROXY_REG)    /* add client message   */	    {            if (proxyIsAClient (&pMsg->clientAddr))                sendACK = TRUE;    /* Acknowledge duplicate registrations. */	    else if (proxyClientAdd (pArpcom, &pMsg->clientAddr,                pMsg->clientHwAddr) == OK)                sendACK = TRUE;	    }        if (op == PROXY_UNREG) /* delete client message */            {            (void) proxyClientDelete (&pMsg->clientAddr);            sendACK = TRUE;            }        semGive (proxySemId);	if (sendACK)	    {	    struct ether_header *	pEh;    /* ether header         */	    struct sockaddr		sa;     /* sockaddr structure   */	    struct ifnet *		pIf;	/* interface pointer  	*/	    /* fill in proxy message */            pMsg->op = htonl (PROXY_ACK);            pMsg->serverAddr.s_addr = pArpcom->ac_ipaddr.s_addr;            bcopy ((caddr_t) pArpcom->ac_enaddr, (caddr_t) pMsg->serverHwAddr,                   sizeof (pMsg->serverHwAddr));	    if (proxyArpVerbose)                logMsg ("proxy ACK sent to 0x%x\n", 			ntohl (pMsg->clientAddr.s_addr), 0, 0, 0, 0, 0);	    bzero ((caddr_t) &sa, sizeof (sa));	    sa.sa_family = AF_UNSPEC;	    /* fill in ethernet header */	    pEh = (struct ether_header *) sa.sa_data;	    pEh->ether_type = PROXY_TYPE;	    pIf = (struct ifnet *) pArpcom;	    bcopy ((caddr_t) pMsg->clientHwAddr, (caddr_t) pEh->ether_dhost, 	           sizeof (pEh->ether_dhost));	    (*pIf->if_output) (pIf, pMbuf, &sa, (struct rtentry *) NULL);	    return;            }        }    m_freem (pMbuf);    }/********************************************************************************* proxyRouteCmd - add and delete a proxy client routes** This routine adds and deletes routes to the proxy clients with the netmask* of 0xffffffff so that arp route entries to the proxy clients can be cloned* from the route added by this routine.** RETURNS: OK, or ERROR if unsuccessful.** NOMANUAL*/LOCAL STATUS proxyRouteCmd    (    int		destInetAddr,		/* destination adrs */    int		gateInetAddr,		/* gateway adrs */    int		ioctlCmd		/* route command */    )    {    struct sockaddr 	destAddr;    struct sockaddr 	gateWayAddr;    struct sockaddr 	netMask;        bzero((char *)(&destAddr), sizeof(struct sockaddr));    destAddr.sa_family	= AF_INET;    destAddr.sa_len	= sizeof(struct sockaddr_in);	    ((struct sockaddr_in *)&destAddr)->sin_addr.s_addr = (u_long)destInetAddr;    /* zero out sockaddr_in, fill in gateway info */    bzero ((char *)&gateWayAddr, sizeof(struct sockaddr));    gateWayAddr.sa_family	= AF_INET;    gateWayAddr.sa_len	= sizeof(struct sockaddr_in);	    ((struct sockaddr_in *)&gateWayAddr)->sin_addr.s_addr =      (u_long)gateInetAddr;    /* initialize the netmask to 0xffffffff */    netMask.sa_family 	= AF_INET;    netMask.sa_len	= 8;     ((struct sockaddr_in *)&netMask)->sin_addr.s_addr = 0xffffffff;    in_socktrim ((struct sockaddr_in *)&netMask);     return (rtrequest (((ioctlCmd == SIOCADDRT) ? RTM_ADD : RTM_DELETE), 	    &destAddr, &gateWayAddr, &netMask, RTF_CLONING, NULL));     }/********************************************************************************* proxyClientRemove - clear client structures** This routine deletes the client routes from the route table.** NOMANUAL*/LOCAL void proxyClientRemove    (    PROXY_CLNT * pClient    )    {    int flags = ATF_PROXY;    (void) hashTblRemove (clientTbl, &pClient->hashNode);    /* Remove proxy ARP entry explicitly */    (void) arpCmd (SIOCDARP, &pClient->ipaddr, (u_char *)  NULL,                   &flags);    /* Remove regular ARP entry */    (void) arpCmd (SIOCDARP, &pClient->ipaddr, (u_char *)  NULL,				   (int *) NULL);    (void) proxyRouteCmd (pClient->ipaddr.s_addr,                      pClient->pNet->proxyAddr.s_addr, SIOCDELRT);    }/********************************************************************************* proxyPacketDup - copies IP header, dups the rest of the packet** This routine makes a new mbuf chain copying the IP header of the* original packet to a newly allocated cluster and copying by reference* the rest of the packet.  This kind of copying is necessary if the IP* header must be altered to reflect a new TTL when broadcast packets* are forwarded.** RETURNS: An M_BLK_ID for the new mbuf chain if successful, NULL*          otherwise.** NOMANUAL*/LOCAL M_BLK_ID proxyPacketDup    (    M_BLK_ID pMblk      /* pointer to source mBlk */    )    {    M_BLK_ID pNewMblk = NULL;    M_BLK_ID pPktMblk = NULL;    int ipHeaderSize = sizeof (struct ip);    int bytesDuped = 0;    if (pMblk == NULL)        return (NULL);    /* First mbuf must have enough room for link layer header */    if ((pNewMblk = netTupleGet (_pNetDpool, max_linkhdr + ipHeaderSize,				 M_DONTWAIT, MT_DATA, TRUE)) == NULL)	return (NULL);    /* Copy IP header which is in the first mbuf (done by m_pullup) */    pNewMblk->mBlkHdr.mData += max_linkhdr; /* Leave room */    bcopy (pMblk->mBlkHdr.mData, pNewMblk->mBlkHdr.mData, ipHeaderSize);    pNewMblk->mBlkHdr.mLen = ipHeaderSize;    if (pMblk->mBlkHdr.mFlags & M_PKTHDR)        {        /* Copy packet header information */	pNewMblk->mBlkPktHdr = pMblk->mBlkPktHdr;	pNewMblk->mBlkHdr.mFlags = pMblk->mBlkHdr.mFlags;	}    /* Copy by reference the rest of the packet */    bytesDuped = pMblk->mBlkPktHdr.len - ipHeaderSize;    pPktMblk = netMblkChainDup (_pNetDpool, pMblk, ipHeaderSize,				bytesDuped, M_DONTWAIT);    if (pPktMblk == NULL)        {        netMblkClChainFree(pNewMblk);        return (NULL);        }    /* Make chain */    pNewMblk->mBlkPktHdr.len = pMblk->mBlkPktHdr.len;    pNewMblk->mBlkHdr.mNext = pPktMblk;    return (pNewMblk);    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -