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

📄 ip_input.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	}	NTOHS(ip->ip_id);	NTOHS(ip->ip_off);	/*	 * Check that the amount of data in the buffers	 * is as at least much as the IP header would have us expect.	 * Trim mbufs if longer than we expect.	 * Drop packet if shorter than we expect.	 */	if (m->m_pkthdr.len < ip->ip_len) {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_CRITICAL event */        WV_NET_ADDRIN_EVENT_2 (NET_CORE_EVENT, WV_NET_CRITICAL, 17, 8,                               ip->ip_src.s_addr, ip->ip_dst.s_addr,                               WV_NETEVENT_IPIN_BADMBLK, WV_NET_RECV,                               m->m_pkthdr.len, ip->ip_len)#endif  /* INCLUDE_WVNET */#endif#ifdef VIRTUAL_STACK		_ipstat.ips_tooshort++;#else		ipstat.ips_tooshort++;#endif /* VIRTUAL_STACK */		goto bad;	}	if (m->m_pkthdr.len > ip->ip_len) {		if (m->m_len == m->m_pkthdr.len) {			m->m_len = ip->ip_len;			m->m_pkthdr.len = ip->ip_len;		} else			m_adj(m, ip->ip_len - m->m_pkthdr.len);	}   /* IPsec filter Hook */   if (_func_ipsecFilterHook != NULL)      {      if (_func_ipsecFilterHook (&m, &ip, hlen) == ERROR)         {         goto done; /* IPsec filter hook has already freed the mbuf */         }      }		/* ipFilterHook example fireWall Hook processing */   if (_ipFilterHook != NULL)     {	    /* process the packet if the hook returns other than TRUE */     if ((*_ipFilterHook) (m->m_pkthdr.rcvif, &m, &ip, hlen) == TRUE)        goto done;	/* the hook should free the mbuf */     }	/*	 * Process options and, if not destined for us,	 * ship it on.  ip_dooptions returns 1 when an	 * error was detected (causing an icmp message	 * to be sent and the original packet to be freed).	 */	ip_nhops = 0;		/* for source routed packets */	if (hlen > sizeof (struct ip) && ip_dooptions(m))		goto done;	/*	 * Check our list of addresses, to see if the packet is for us.	 */#ifdef VIRTUAL_STACK	for (ia = _in_ifaddr; ia; ia = ia->ia_next) {#else	for (ia = in_ifaddr; ia; ia = ia->ia_next) {#endif /* VIRTUAL_STACK */#define	satosin(sa)	((struct sockaddr_in *)(sa))		/* if ip is strong ended we will accept packets on  an interface		 * only if destination in ip hdr matches ip  address on the		 * receiving interface and not just any interface. 		 */                if ((ipStrongEnded == TRUE) && 		    (ia->ia_ifp != m->m_pkthdr.rcvif))		    continue;		if (IA_SIN(ia)->sin_addr.s_addr == ip->ip_dst.s_addr)			goto ours;		if (#ifdef	DIRECTED_BROADCAST		    ia->ia_ifp == m->m_pkthdr.rcvif &&#endif		    (ia->ia_ifp->if_flags & IFF_BROADCAST)) {			u_long t;			if (satosin(&ia->ia_broadaddr)->sin_addr.s_addr ==			    ip->ip_dst.s_addr)				goto ours;			if (ip->ip_dst.s_addr == ia->ia_netbroadcast.s_addr)				goto ours;			/*			 * Look for all-0's host part (old broadcast addr),			 * either for subnet or net.			 */			t = ntohl(ip->ip_dst.s_addr);			if (t == ia->ia_subnet)				goto ours;			if (t == ia->ia_net)				goto ours;		}	}	if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) {		struct in_multi *inm;		if (_mCastRouteFwdHook != NULL) {			/*			 * If we are acting as a multicast router, all			 * incoming multicast packets are passed to the			 * kernel-level multicast forwarding function.			 * The packet is returned (relatively) intact; if			 * ip_mforward() returns a non-zero value, the packet			 * must be discarded, else it may be accepted below.			 *			 * (The IP ident field is put in the same byte order			 * as expected when ip_mforward() is called from			 * ip_output().)			 */			ip->ip_id = htons(ip->ip_id);                        if ((*_mCastRouteFwdHook)(m, m->m_pkthdr.rcvif, ip, NULL) != 0) {#ifdef VIRTUAL_STACK				_ipstat.ips_cantforward++;#else				ipstat.ips_cantforward++;#endif /* VIRTUAL_STACK */				m_freem(m);				goto done;			}			ip->ip_id = ntohs(ip->ip_id);			/*			 * The process-level routing demon needs to receive			 * all multicast IGMP packets, whether or not this			 * host belongs to their destination groups.			 */			if (ip->ip_p == IPPROTO_IGMP)				goto ours;#ifdef VIRTUAL_STACK			_ipstat.ips_forward++;#else			ipstat.ips_forward++;#endif /* VIRTUAL_STACK */		}		/*		 * See if we belong to the destination multicast group on the		 * arrival interface.		 */		IN_LOOKUP_MULTI(ip->ip_dst, m->m_pkthdr.rcvif, inm);		if (inm == NULL) {#ifdef VIRTUAL_STACK			_ipstat.ips_cantforward++;#else			ipstat.ips_cantforward++;#endif /* VIRTUAL_STACK */			m_freem(m);			goto done;		}		goto ours;	}	if (ip->ip_dst.s_addr == (u_long)INADDR_BROADCAST)		goto ours;	if (ip->ip_dst.s_addr == INADDR_ANY)		goto ours;	/*	 * Not for us; forward if possible and desirable.	 */	if ((_ipCfgFlags & IP_DO_FORWARDING) == 0) {#ifdef VIRTUAL_STACK		_ipstat.ips_cantforward++;#else		ipstat.ips_cantforward++;#endif /* VIRTUAL_STACK */		m_freem(m);	} else		ip_forward(m, 0);	goto done;ours:#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_INFO event */    WV_NET_ADDRIN_EVENT_2 (NET_CORE_EVENT, WV_NET_INFO, 6, 16,                           ip->ip_src.s_addr, ip->ip_dst.s_addr,                           WV_NETEVENT_IPIN_GOODMBLK, WV_NET_RECV,                           ip->ip_src.s_addr, ip->ip_dst.s_addr)#endif  /* INCLUDE_WVNET */#endif	/*	 * If offset or IP_MF are set, must reassemble.	 * Otherwise, nothing need be done.	 * (We could look in the reassembly queue to see	 * if the packet was previously fragmented,	 * but it's not worth the time; just let them time out.)	 */	if (ip->ip_off &~ IP_DF) {		/*		 * Look for queue of fragments		 * of this datagram.		 */#ifdef VIRTUAL_STACK		for (fp = _ipq.next; fp != &_ipq; fp = fp->next)#else		for (fp = ipq.next; fp != &ipq; fp = fp->next)#endif			if (ip->ip_id == fp->ipq_id &&			    ip->ip_src.s_addr == fp->ipq_src.s_addr &&			    ip->ip_dst.s_addr == fp->ipq_dst.s_addr &&			    ip->ip_p == fp->ipq_p)				goto found;		fp = 0;found:		/*		 * Adjust ip_len to not reflect header,		 * set ip_mff if more fragments are expected,		 * convert offset of this to bytes.		 */		ip->ip_len -= hlen;		((struct ipasfrag *)ip)->ipf_mff &= ~1;		if (ip->ip_off & IP_MF)			((struct ipasfrag *)ip)->ipf_mff |= 1;		ip->ip_off <<= 3;		/*		 * If datagram marked as having more fragments		 * or if this is not the first fragment,		 * attempt reassembly; if it succeeds, proceed.		 */		if (((struct ipasfrag *)ip)->ipf_mff & 1 || ip->ip_off) {#ifdef VIRTUAL_STACK			_ipstat.ips_fragments++;#else			ipstat.ips_fragments++;#endif /* VIRTUAL_STACK */			if ((m = ipReAssemble (m, fp)) == NULL)				goto done;                        ip = mtod (m, struct ip *);			hlen = ip->ip_hl << 2;#ifdef VIRTUAL_STACK			_ipstat.ips_reassembled++;#else			ipstat.ips_reassembled++;#endif /* VIRTUAL_STACK */		} else			if (fp)				ip_freef(fp);	} else		ip->ip_len -= hlen;#ifdef  FORWARD_BROADCASTS        if ((m->m_flags & M_BCAST) && (proxyBroadcastHook != NULL))            (* proxyBroadcastHook) (m, m->m_pkthdr.rcvif);#endif        if (_func_ipsecInput != NULL)            {            /* Deliver the packet to ipsec for further processing/filtering. */            if (_func_ipsecInput (&m, hlen, &ip) == ERROR)                {                goto done;                }            }	/*	 * Switch out to protocol's input routine.	 */#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_NOTICE event */    WV_NET_ADDRIN_EVENT_2 (NET_CORE_EVENT, WV_NET_NOTICE, 10, 14,                           ip->ip_src.s_addr, ip->ip_dst.s_addr,                           WV_NETEVENT_IPIN_FINISH, WV_NET_RECV,                           ip->ip_src.s_addr, ip->ip_dst.s_addr)#endif  /* INCLUDE_WVNET */#endif#ifdef VIRTUAL_STACK	_ipstat.ips_delivered++;#else	ipstat.ips_delivered++;#endif /* VIRTUAL_STACK */	(*inetsw[ip_protox[ip->ip_p]].pr_input) (m, hlen);        splx (s);        return;bad:	m_freem(m);done:                splx (s);        return;        }/********************************************************************************* ipReAssemble - reassemble ip fragments** This function reassembles the ip fragments and returns the pointer to the* mbuf chain if reassembly is complete orelse returns null.** RETURNS: pMbuf/NULL** SEE ALSO: ,** NOMANUAL*/LOCAL struct mbuf * ipReAssemble    (    FAST struct mbuf *	pMbuf,		/* pointer to mbuf chain fragment */    FAST struct ipq *	pIpFragQueue	/* pointer to ip fragment queue */    )    {    FAST struct mbuf ** 	pPtrMbuf; 	   /* pointer to ptr to mbuf */    FAST struct mbuf * 		pMbPktFrag = NULL; /* pointer to the packet */    FAST struct ip * 		pIpHdr;   	   /* pointer to ip header */    FAST struct ipasfrag *	pIpHdrFrag = NULL; /* ipfragment header */    FAST int		        len;     FAST struct mbuf *		pMbufTmp;	   /* pointer to mbuf */        pIpHdr = mtod (pMbuf, struct ip *);     pMbuf->m_nextpkt = NULL;     /*     * If first fragment to arrive, create a reassembly queue.     */    if (pIpFragQueue == 0)	{	if ((pMbufTmp = mBufClGet (M_DONTWAIT, MT_FTABLE, sizeof(struct ipq),				   TRUE)) == NULL)	    goto dropFrag;	pIpFragQueue = mtod(pMbufTmp, struct ipq *);#ifdef VIRTUAL_STACK	insque(pIpFragQueue, &_ipq);#else	insque(pIpFragQueue, &ipq);#endif	pIpFragQueue->ipq_ttl = ipfragttl;	/* configuration parameter */	pIpFragQueue->ipq_p = pIpHdr->ip_p;	pIpFragQueue->ipq_id = pIpHdr->ip_id;	pIpFragQueue->ipq_src = ((struct ip *)pIpHdr)->ip_src;	pIpFragQueue->ipq_dst = ((struct ip *)pIpHdr)->ip_dst;	pIpFragQueue->pMbufHdr   = pMbufTmp; 	/* back pointer to mbuf */	pIpFragQueue->pMbufPkt = pMbuf; 	/* first fragment received */	goto ipChkReAssembly; 	}    for (pPtrMbuf = &(pIpFragQueue->pMbufPkt); *pPtrMbuf != NULL;	 pPtrMbuf = &(*pPtrMbuf)->m_nextpkt)	{	pMbPktFrag = *pPtrMbuf; 	pIpHdrFrag = mtod(pMbPktFrag, struct ipasfrag *); 	if ((USHORT)pIpHdr->ip_off > (USHORT)pIpHdrFrag->ip_off)	    {	    if ((len = (signed int)((USHORT)pIpHdrFrag->ip_off +				    pIpHdrFrag->ip_len -				    (USHORT)pIpHdr->ip_off)) > 0)		{		if (len >= pIpHdr->ip_len)		    goto dropFrag;		/* drop the fragment */		pIpHdrFrag->ip_len -= len; 		m_adj(pMbPktFrag, -len); 	/* trim from the tail */		}	    if (pMbPktFrag->m_nextpkt == NULL)		{ 	/* this is the likely case most of the time */		pMbPktFrag->m_nextpkt = pMbuf; 	/* insert the fragment */		pMbuf->m_nextpkt = NULL;		break;		}	    }	else 		/* if pIpHdr->ip_off <= pIpHdrFrag->ip_off */	    {            /* if complete overlap */            while (((USHORT)pIpHdr->ip_off + pIpHdr->ip_len) >=                   ((USHORT)pIpHdrFrag->ip_off + pIpHdrFrag->ip_len))                {                *pPtrMbuf = (*pPtrMbuf)->m_nextpkt;                pMbPktFrag->m_nextpkt = NULL;                m_freem (pMbPktFrag);           /* drop the fragment */                pMbPktFrag = *pPtrMbuf;                if (pMbPktFrag == NULL)                    break;                pIpHdrFrag = mtod(pMbPktFrag, struct ipasfrag *);                }            /* if partial overlap trim my data at the end*/            if ((pMbPktFrag != NULL) &&                ((len = (((USHORT) pIpHdr->ip_off + pIpHdr->ip_len) -                         (USHORT) pIpHdrFrag->ip_off)) > 0))                {                pIpHdr->ip_len -= len;                m_adj (pMbuf, -len);        	/* trim from the tail */                }	    pMbuf->m_nextpkt = pMbPktFrag; 	    *pPtrMbuf = pMbuf; 	/* insert the current fragment */	    	    break; 	    }	}    ipChkReAssembly:    len = 0;     for (pMbPktFrag = pIpFragQueue->pMbufPkt; pMbPktFrag != NULL;	 pMbPktFrag = pMbPktFrag->m_nextpkt)	{	pIpHdrFrag = mtod(pMbPktFrag, struct ipasfrag *); 	if ((USHORT)pIpHdrFrag->ip_off != len)	    return (NULL); 	len += pIpHdrFrag->ip_len; 	}        if (pIpHdrFrag->ipf_mff & 1)	/* last fragment's mff bit still set */	return (NULL);     /* reassemble and concatenate all fragments */    pMbuf = pIpFragQueue->pMbufPkt;     pMbufTmp = pMbuf->m_nextpkt;     pMbuf->m_nextpkt = NULL;     while (pMbufTmp != NULL)	{	pMbPktFrag = pMbufTmp; 	pIpHdrFrag = mtod(pMbPktFrag, struct ipasfrag *); 	pMbPktFrag->m_data += pIpHdrFrag->ip_hl << 2;	/* remove the header */	pMbPktFrag->m_len  -= pIpHdrFrag->ip_hl << 2;

⌨️ 快捷键说明

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