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

📄 ip_input.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	pMbufTmp = pMbPktFrag->m_nextpkt; 	pMbPktFrag->m_nextpkt = NULL ; 	m_cat (pMbuf, pMbPktFrag); 	/* concatenate the fragment */	}    pIpHdrFrag = mtod(pMbuf, struct ipasfrag *);     pIpHdrFrag->ip_len = len; 		/* length of the ip packet */    if (len > 0xffff - (pIpHdrFrag->ip_hl << 2))  /* ping of death */        goto dropFrag;                            /* drop entire chain */    pIpHdrFrag->ipf_mff &= ~1;    remque(pIpFragQueue);    (void) m_free (pIpFragQueue->pMbufHdr);     /* some debugging cruft by sklower, below, will go away soon */    if (pMbuf->m_flags & M_PKTHDR)	{ /* XXX this should be done elsewhere */	len = 0; 	for (pMbufTmp = pMbuf; pMbufTmp; pMbufTmp = pMbufTmp->m_next)	    len += pMbufTmp->m_len;	pMbuf->m_pkthdr.len = len;	}    return (pMbuf);			/* return the assembled packet */    dropFrag:#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_WARNING event */    WV_NET_ADDRIN_EVENT_1 (NET_CORE_EVENT, WV_NET_WARNING, 8, 13,                           pIpHdr->ip_src.s_addr, pIpHdr->ip_dst.s_addr,                           WV_NETEVENT_IPIN_FRAGDROP, WV_NET_RECV, pIpHdrFrag)#endif  /* INCLUDE_WVNET */#endif#ifdef VIRTUAL_STACK    _ipstat.ips_fragdropped++;#else    ipstat.ips_fragdropped++;#endif /* VIRTUAL_STACK */    m_freem (pMbuf);			/* free the fragment */    return (NULL);    }/* * Free a fragment reassembly header and all * associated datagrams. */voidip_freef(fp)	struct ipq *fp;{	struct mbuf **  pPtrMbuf; 	struct mbuf *  pMbuf;#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_INFO event */    WV_NET_ADDRIN_MARKER_2 (NET_AUX_EVENT, WV_NET_INFO, 7, 17,                            fp->ipq_src.s_addr, fp->ipq_dst.s_addr,                            WV_NETEVENT_IPFRAGFREE_START,                            fp->ipq_src.s_addr, fp->ipq_dst.s_addr)#endif  /* INCLUDE_WVNET */#endif	/* free all fragments */	pPtrMbuf = &(fp->pMbufPkt); 	while (*pPtrMbuf)	    {	    pMbuf = (*pPtrMbuf)->m_nextpkt; 	    m_freem (*pPtrMbuf); 	    *pPtrMbuf = pMbuf; 	    }	remque(fp);	(void) m_free(fp->pMbufHdr);}n_timeiptime(){	u_long t;	/* t is time in milliseconds (i hope) */	t = ((int) tickGet () * 1000) / sysClkRateGet ();	return (htonl(t));}/* * IP timer processing; * if a timer expires on a reassembly * queue, discard it. */voidip_slowtimo(){	register struct ipq *fp;	int s = splnet();#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_INFO event */    WV_NET_MARKER_0 (NET_AUX_EVENT, WV_NET_INFO, 8, 18,                      WV_NETEVENT_IPTIMER_FRAGFREE)#endif  /* INCLUDE_WVNET */#endif#ifdef VIRTUAL_STACK	fp = _ipq.next;#else	fp = ipq.next;#endif	if (fp == 0) {		splx(s);		return;	}#ifdef VIRTUAL_STACK	while (fp != &_ipq) {#else	while (fp != &ipq) {#endif		--fp->ipq_ttl;		fp = fp->next;		if (fp->prev->ipq_ttl == 0) {#ifdef VIRTUAL_STACK			_ipstat.ips_fragtimeout++;#else			ipstat.ips_fragtimeout++;#endif /* VIRTUAL_STACK */			ip_freef(fp->prev);		}	}	splx(s);	return;}/* * Drain off all datagram fragments and excess (unused) route entries. */voidip_drain(){#ifdef VIRTUAL_STACK	while (_ipq.next != &_ipq) {		_ipstat.ips_fragdropped++;		ip_freef(_ipq.next);	}#else	while (ipq.next != &ipq) {		ipstat.ips_fragdropped++;		ip_freef(ipq.next);	}#endif /* VIRTUAL_STACK */        routeDrain();	return;}/* * Do option processing on a datagram, * possibly discarding it if bad options are encountered, * or forwarding it if source-routed. * Returns 1 if packet has been forwarded/freed, * 0 if the packet should be processed further. */intip_dooptions(m)	struct mbuf *m;{	register struct ip *ip = mtod(m, struct ip *);	register u_char *cp;	register struct ip_timestamp *ipt;	register struct in_ifaddr *ia;	int opt, optlen, cnt, off, code, type = ICMP_PARAMPROB, forward = 0;	struct in_addr *sin, dst;	n_time ntime;	dst = ip->ip_dst;	cp = (u_char *)(ip + 1);	cnt = (ip->ip_hl << 2) - sizeof (struct ip);	for (; cnt > 0; cnt -= optlen, cp += optlen) {		opt = cp[IPOPT_OPTVAL];		if (opt == IPOPT_EOL)			break;		if (opt == IPOPT_NOP)			optlen = 1;		else {			optlen = cp[IPOPT_OLEN];			if (optlen <= 0 || optlen > cnt) {				code = &cp[IPOPT_OLEN] - (u_char *)ip;				goto bad;			}		}		switch (opt) {		default:			break;		/*		 * Source routing with record.		 * Find interface with current destination address.		 * If none on this machine then drop if strictly routed,		 * or do nothing if loosely routed.		 * Record interface address and bring up next address		 * component.  If strictly routed make sure next		 * address is on directly accessible net.		 */		case IPOPT_LSRR:		case IPOPT_SSRR:			if ((off = cp[IPOPT_OFFSET]) < IPOPT_MINOFF) {				code = &cp[IPOPT_OFFSET] - (u_char *)ip;				goto bad;			}			input_ipaddr.sin_addr = ip->ip_dst;			TOS_SET (&input_ipaddr, ip->ip_tos);  /* tos routing */			ia = (struct in_ifaddr *)				ifa_ifwithaddr((struct sockaddr *)&input_ipaddr);			if (ia == 0) {				if (opt == IPOPT_SSRR) {					type = ICMP_UNREACH;					code = ICMP_UNREACH_SRCFAIL;					goto bad;				}				/*				 * Loose routing, and not at next destination				 * yet; nothing to do except forward.				 */				break;			}			off--;			/* 0 origin */			if (off > optlen - sizeof(struct in_addr)) {				/*				 * End of source route.  Should be for us.				 */#ifdef SRCRT				save_rte(cp, ip->ip_src);#endif /* SRCRT */				break;			}			/*			 * locate outgoing interface			 */			bcopy((caddr_t)(cp + off), (caddr_t)&input_ipaddr.sin_addr,			    sizeof(input_ipaddr.sin_addr));			if (opt == IPOPT_SSRR) {#define	INA	struct in_ifaddr *#define	SA	struct sockaddr *			    if ((ia = (INA)ifa_ifwithdstaddr((SA)&input_ipaddr)) == 0)				ia = (INA)ifa_ifwithnet((SA)&input_ipaddr);			} else				ia = ip_rtaddr(input_ipaddr.sin_addr);			if (ia == 0) {				type = ICMP_UNREACH;				code = ICMP_UNREACH_SRCFAIL;				goto bad;			}			ip->ip_dst = input_ipaddr.sin_addr;			bcopy((caddr_t)&(IA_SIN(ia)->sin_addr),			    (caddr_t)(cp + off), sizeof(struct in_addr));			cp[IPOPT_OFFSET] += sizeof(struct in_addr);			/*			 * Let ip_intr's mcast routing check handle mcast pkts			 */			forward = !IN_MULTICAST(ntohl(ip->ip_dst.s_addr));			break;		case IPOPT_RR:			if ((off = cp[IPOPT_OFFSET]) < IPOPT_MINOFF) {				code = &cp[IPOPT_OFFSET] - (u_char *)ip;				goto bad;			}			/*			 * If no space remains, ignore.			 */			off--;			/* 0 origin */			if (off > optlen - sizeof(struct in_addr))				break;			bcopy((caddr_t)(&ip->ip_dst), (caddr_t)&input_ipaddr.sin_addr,			    sizeof(input_ipaddr.sin_addr));			/*			 * locate outgoing interface; if we're the destination,			 * use the incoming interface (should be same).			 */			if ((ia = (INA)ifa_ifwithaddr((SA)&input_ipaddr)) == 0 &&			    (ia = ip_rtaddr(input_ipaddr.sin_addr)) == 0) {				type = ICMP_UNREACH;				code = ICMP_UNREACH_HOST;				goto bad;			}			bcopy((caddr_t)&(IA_SIN(ia)->sin_addr),			    (caddr_t)(cp + off), sizeof(struct in_addr));			cp[IPOPT_OFFSET] += sizeof(struct in_addr);			break;		case IPOPT_TS:			code = cp - (u_char *)ip;			ipt = (struct ip_timestamp *)cp;			if (ipt->ipt_len < 5)				goto bad;			if (ipt->ipt_ptr > ipt->ipt_len - sizeof (long)) {				if (++ipt->ipt_oflw == 0)					goto bad;				break;			}			sin = (struct in_addr *)(cp + ipt->ipt_ptr - 1);			switch (ipt->ipt_flg) {			case IPOPT_TS_TSONLY:				break;			case IPOPT_TS_TSANDADDR:				if (ipt->ipt_ptr + sizeof(n_time) +				    sizeof(struct in_addr) > ipt->ipt_len)					goto bad;				input_ipaddr.sin_addr = dst;				ia = (INA)ifaof_ifpforaddr((SA)&input_ipaddr,							    m->m_pkthdr.rcvif);				if (ia == 0)					continue;				bcopy((caddr_t)&IA_SIN(ia)->sin_addr,				    (caddr_t)sin, sizeof(struct in_addr));				ipt->ipt_ptr += sizeof(struct in_addr);				break;			case IPOPT_TS_PRESPEC:				if (ipt->ipt_ptr + sizeof(n_time) +				    sizeof(struct in_addr) > ipt->ipt_len)					goto bad;				bcopy((caddr_t)sin, (caddr_t)&input_ipaddr.sin_addr,				    sizeof(struct in_addr));				if (ifa_ifwithaddr((SA)&input_ipaddr) == 0)					continue;				ipt->ipt_ptr += sizeof(struct in_addr);				break;			default:				goto bad;			}			ntime = iptime();			bcopy((caddr_t)&ntime, (caddr_t)cp + ipt->ipt_ptr - 1,			    sizeof(n_time));			ipt->ipt_ptr += sizeof(n_time);		}	}	if (forward) {		ip_forward(m, 1);		return (1);	}	return (0);bad:	ip->ip_len -= ip->ip_hl << 2;   /* XXX icmp_error adds in hdr length */	if (_icmpErrorHook != NULL)	    (*_icmpErrorHook) (m, type, code, 0, 0); #ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_CRITICAL event */        WV_NET_EVENT_2 (NET_CORE_EVENT, WV_NET_CRITICAL, 18, 9,                         WV_NETEVENT_IPIN_BADOPT, WV_NET_RECV, type, code)#endif  /* INCLUDE_WVNET */#endif#ifdef VIRTUAL_STACK	_ipstat.ips_badoptions++;#else	ipstat.ips_badoptions++;#endif /* VIRTUAL_STACK */	return (1);}/* * Given address of next destination (final or next hop), * return internet address info of interface to be used to get there. */struct in_ifaddr *ip_rtaddr(dst)	 struct in_addr dst;{	register struct sockaddr_in *sin;	sin = (struct sockaddr_in *) &ipforward_rt.ro_dst;	if (ipforward_rt.ro_rt == 0 ||            (ipforward_rt.ro_rt->rt_flags & RTF_UP) == 0 ||            dst.s_addr != sin->sin_addr.s_addr) {		if (ipforward_rt.ro_rt) {			RTFREE(ipforward_rt.ro_rt);			ipforward_rt.ro_rt = 0;		}		sin->sin_family = AF_INET;		sin->sin_len = sizeof(*sin);		sin->sin_addr = dst;		ipforward_rt.ro_rt = rtalloc2 (&ipforward_rt.ro_dst);	}	if (ipforward_rt.ro_rt == 0)		return ((struct in_ifaddr *)0);	return ((struct in_ifaddr *) ipforward_rt.ro_rt->rt_ifa);}#ifdef SRCRT/* * Save incoming source route for use in replies, * to be picked up later by ip_srcroute if the receiver is interested. */voidsave_rte(option, dst)	u_char *option;	struct in_addr dst;{	unsigned olen;	olen = option[IPOPT_OLEN];#ifdef DIAGNOSTIC	if (ipprintfs)		printf("save_rte: olen %d\n", olen);#endif	if (olen > sizeof(ip_srcrt) - (1 + sizeof(dst)))		return;	bcopy((caddr_t)option, (caddr_t)ip_srcrt.srcopt, olen);	ip_nhops = (olen - IPOPT_OFFSET - 1) / sizeof(struct in_addr);	ip_srcrt.dst = dst;}

⌨️ 快捷键说明

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