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

📄 proxyarplib.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 4 页
字号:
    }/********************************************************************************* 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);    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.*/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 enabled ports** This routine displays the ports currently enabled.** 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** This routine prints the list of enabled ports.** RETURNS: TRUE (always)*/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).** Datagrams forwarded onto a proxy network are given a TTL of 1.  This is so* they never actually leave the proxy network.  This is a precaution to prevent* broadcast storms and network meltdown.  Datagrams forwarded on the ethernet* have their original ttl - 1.** 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*/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 */    /*     * If ttl goes to zero don't forward the datagram.     * Also only forward UDP packets with the ports enabled.     */    if ((pIP->ip_ttl <= IPTTLDEC) || (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 (pUDP->uh_dport) && !portTblFind ((u_short) 0))	return;    semTake (proxySemId, WAIT_FOREVER);    inputAddr.s_addr  =  ((struct arpcom *) pIf)->ac_ipaddr.s_addr;    if ((pNet = proxyNetFind (&inputAddr)) != NULL)	{	/*	 * 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);	}    else	{	/* interface not a proxy network, make sure it's a main network */	if (!proxyIsAMainNet (&inputAddr))	    {    	    semGive (proxySemId);	    return;	    }    	mainAddr.s_addr = inputAddr.s_addr;	}    for (pNet = (PROXY_NET *) lstFirst (&proxyNetList); (pNet != NULL);	 pNet = (PROXY_NET *) lstNext (&pNet->netNode))	{    	/*	 * Forward datagram to all proxy networks that have the main network     	 * as their main network (with ttl as 1).  Don't forward to	 * originating network, however.     	 */	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> out on  on* interface <pIf> with a new time-to-live value of <ttl>.  It changes the* fields back into network byte order, and re checksums the header.** RETURNS: N/A*/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	    */    if ((pMbufCopy = (struct mbuf *) m_copy (pMbuf, 0, M_COPYALL)) == NULL)	return;    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);    pIP->ip_len += pIP->ip_hl << 2;    pIP->ip_id  = htons ((u_short) pIP->ip_id);	/* convert to network format */    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); /* checksum	*/    (*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*/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 (                (proxyClientAdd (pArpcom, &pMsg->clientAddr) == OK) &&		(arpCmd (SIOCSARP, &pMsg->clientAddr, pMsg->clientHwAddr,			 (int *) NULL) == 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));     }

⌨️ 快捷键说明

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