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

📄 ip_icmp.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	icmpsrc.sin_addr = ip->ip_src;	if (ia == (struct in_ifaddr *)0)		ia = (struct in_ifaddr *)ifaof_ifpforaddr(			(struct sockaddr *)&icmpsrc, m->m_pkthdr.rcvif);	/*	 * The following happens if the packet was not addressed to us,	 * and was received on an interface with no IP address.	 */	if (ia == (struct in_ifaddr *)0)#ifdef VIRTUAL_STACK		ia = _in_ifaddr;#else		ia = in_ifaddr;#endif /* VIRTUAL_STACK */	t = IA_SIN(ia)->sin_addr;	ip->ip_src = t;	ip->ip_ttl = ipTimeToLive;	if (optlen > 0) {		register u_char *cp;		int opt, cnt;		u_int len;		/*		 * Retrieve any source routing from the incoming packet;		 * add on any record-route or timestamp options.		 */		cp = (u_char *) (ip + 1);#ifdef SRCRT		if ((opts = ip_srcroute()) == 0 &&		    (opts = mHdrClGet(M_DONTWAIT, MT_HEADER, CL_SIZE_128,				      TRUE))) {			opts->m_len = sizeof(struct in_addr);			mtod(opts, struct in_addr *)->s_addr = 0;		}#endif /* SRCRT */		if (opts) {#ifdef ICMPPRINTFS		    if (icmpprintfs)			    printf("icmp_reflect optlen %d rt %d => ",				optlen, opts->m_len);#endif		    for (cnt = optlen; cnt > 0; cnt -= len, cp += len) {			    opt = cp[IPOPT_OPTVAL];			    if (opt == IPOPT_EOL)				    break;			    if (opt == IPOPT_NOP)				    len = 1;			    else {				    len = cp[IPOPT_OLEN];				    if (len <= 0 || len > cnt)					    break;			    }			    /*			     * Should check for overflow, but it "can't happen"			     */			    if (opt == IPOPT_RR || opt == IPOPT_TS || 				opt == IPOPT_SECURITY) {				    bcopy((caddr_t)cp,					mtod(opts, caddr_t) + opts->m_len, len);				    opts->m_len += len;			    }		    }		    /* Terminate & pad, if necessary */		    if ((cnt = opts->m_len % 4)) {			    for (; cnt < 4; cnt++) {				    *(mtod(opts, caddr_t) + opts->m_len) =					IPOPT_EOL;				    opts->m_len++;			    }		    }#ifdef ICMPPRINTFS		    if (icmpprintfs)			    printf("%d\n", opts->m_len);#endif		}		/*		 * Now strip out original options by copying rest of first		 * mbuf's data back, and adjust the IP length.		 */		ip->ip_len -= optlen;		ip->ip_hl = sizeof(struct ip) >> 2;		m->m_len -= optlen;		if (m->m_flags & M_PKTHDR)			m->m_pkthdr.len -= optlen;		optlen += sizeof(struct ip);		bcopy((caddr_t)ip + optlen, (caddr_t)(ip + 1),			 (unsigned)(m->m_len - sizeof(struct ip)));	}	m->m_flags &= ~(M_BCAST|M_MCAST);	icmp_send(m, opts);done:	if (opts)		(void)m_free(opts);}/* * Send an icmp packet back to the ip level, * after supplying a checksum. */static voidicmp_send(m, opts)	register struct mbuf *m;	struct mbuf *opts;{	register struct ip *ip = mtod(m, struct ip *);	register int hlen;	register struct icmp *icp;#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_NOTICE event */    WV_NET_ADDROUT_EVENT_2 (NET_CORE_EVENT, WV_NET_NOTICE, 9, 10,                             ip->ip_src.s_addr, ip->ip_dst.s_addr,                            WV_NETEVENT_ICMPSEND_START, WV_NET_SEND,                            ip->ip_src.s_addr, ip->ip_dst.s_addr)#endif  /* INCLUDE_WVNET */#endif	hlen = ip->ip_hl << 2;	m->m_data += hlen;	m->m_len -= hlen;	icp = mtod(m, struct icmp *);	icp->icmp_cksum = 0;	icp->icmp_cksum = in_cksum(m, ip->ip_len - hlen);	m->m_data -= hlen;	m->m_len += hlen;#ifdef ICMPPRINTFS	if (icmpprintfs)		printf("icmp_send dst %x src %x\n", ip->ip_dst, ip->ip_src);#endif	(void) ip_output(m, opts, NULL, 0, NULL);}    /*     * This routine handles the ICMP "need fragmentation" error which     * triggers the selection of a new MTU value for the path MTU discovery     * process. The new MTU value is equal to the suggested value from the     * ICMP error message (if any) or the next value from the current path     * MTU table. If the new MTU value is less than the acceptable minimum,     * the routine marks the corresponding route to disable the path MTU     * discovery process.     */LOCAL void ip_next_mtu    (    struct sockaddr * pDstAddr,     /* destination of original IP packet */    int nextmtu    )    {    struct rtentry * 	pDestRoute;    u_long 		oldmtu = 0;    u_long 		newmtu;    int 		loop;    pDestRoute = rtalloc1 (pDstAddr, 0);    if (pDestRoute && (pDestRoute->rt_flags & RTF_HOST) &&            !(pDestRoute->rt_rmx.rmx_locks & RTV_MTU))        {        oldmtu = pDestRoute->rt_rmx.rmx_mtu;        if (oldmtu == 0)            {            /* Current estimate unavailable - end discovery process. */            newmtu = 0;            }        else if (nextmtu == 0)            {            /* No value included in ICMP message. Use entry from table. */            for (loop = 0; loop < mtuTableSize; loop++)                 if (oldmtu > mtuTable [ (mtuTableSize - 1) - loop])                     break;            if (loop != mtuTableSize)                {                /* Set the new MTU value. */                newmtu = mtuTable [loop];                }            else                newmtu = 0;   /* Match not found - disable MTU discovery. */            }        else            newmtu = nextmtu;    /* Use value from ICMP message. */        if (newmtu < PATHMTU_MIN)            {            /* Set lock to disable path MTU discovery for this destination. */            pDestRoute->rt_rmx.rmx_locks |= RTV_MTU;            }        else if (oldmtu > newmtu)            {            /*             * Decrease the estimated MTU size to the new value. The test             * handles the (illegal) case where a downstream router sends             * a larger MTU size in the "need fragment" message.             */            pDestRoute->rt_rmx.rmx_mtu = newmtu;            }        }    if (pDestRoute)        {        RTFREE (pDestRoute)        }    return;    }/* ICMP socket option processing. */int icmp_ctloutput    (    int op,    struct socket *so,    int level,    int optname,    struct mbuf **mp    )    {    register struct mbuf *m = *mp;#if 0    /* For timer options (not yet supported). */    int optval;#endif    int optlen;    int error = 0;    switch (op)        {        case PRCO_SETOPT:            optlen = m->m_len;            switch (optname)                {                case SO_PATHMTU_TBL:                    if (m->m_len % sizeof (u_short))                        error = EINVAL;                    else                        {                         bcopy ((char *)mtod (m, u_short *),                               (char *)mtuTable, m->m_len);                        mtuTableSize = m->m_len / sizeof (u_short);                        }                    break;#if 0    /* Timers for increasing path MTU value (not yet supported). */                case SO_PATHMTU_LIFETIME:                    if (m->m_len != sizeof (int))                        error = EINVAL;                    else                        optval = *mtod (m, int *);                    break;                case SO_PATHMTU_TIMEOUT:                    break;#endif                default:                    error = ENOPROTOOPT;                    break;                }            if (m)                (void)m_free(m);            break;        case PRCO_GETOPT:            *mp = m = mBufClGet (M_WAIT, MT_SOOPTS, CL_SIZE_128, TRUE);            if (m == (struct mbuf *) NULL)                {                error = ENOBUFS;                break;                }            switch (optname)                {                case SO_PATHMTU_TBL:                    m->m_len = mtuTableSize * sizeof (u_short);                    bcopy ((char *)mtuTable, (char *)mtod(m, u_short *),                           (unsigned)m->m_len);                    break;#if 0    /* Timers for increasing path MTU value (not yet supported). */                case SO_PATHMTU_LIFETIME:                    m->m_len = sizeof (u_int);                    /* optval = lifetime; */                    *mtod (m, u_int *) = optval;                    break;                case SO_PATHMTU_TIMEOUT:                    break;#endif                default:                    error = ENOPROTOOPT;                    break;                }            break;        }    return (error);    }#ifdef SYSCTL_SUPPORTinticmp_sysctl(name, namelen, oldp, oldlenp, newp, newlen)	int *name;	u_int namelen;	void *oldp;	size_t *oldlenp;	void *newp;	size_t newlen;{/* * XXX - This event cannot currently occur: the icmp_sysctl() routine *       is only called by the Unix sysctl command which is not supported *       by VxWorks#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /@ WV_NET_INFO event @/    WV_NET_MARKER_1 (NET_AUX_EVENT, WV_NET_INFO, 5, 11,                      WV_NETEVENT_ICMPCTRL_START, name[0])#endif  /@ INCLUDE_WVNET @/#endif * XXX - end of unused event */	/* All sysctl names at this level are terminal. */	if (namelen != 1)            {/* * XXX - This event cannot currently occur: the icmp_sysctl() routine *       is only called by the Unix sysctl command which is not supported *       by VxWorks#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /@ WV_NET_ERROR event @/        WV_NET_MARKER_1 (NET_AUX_EVENT, WV_NET_ERROR, 18, 6,                          WV_NETEVENT_ICMPCTRL_BADLEN, namelen)#endif  /@ INCLUDE_WVNET @/#endif * XXX - end of unused event */            return (ENOTDIR);            }	switch (name[0]) {	case ICMPCTL_MASKREPL:		return (sysctl_int(oldp, oldlenp, newp, newlen, &icmpmaskrepl));	default:/* * XXX - This event cannot currently occur: the icmp_sysctl() routine *       is only called by the Unix sysctl command which is not supported *       by VxWorks#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /@ WV_NET_ERROR event @/            WV_NET_MARKER_1 (NET_AUX_EVENT, WV_NET_ERROR, 19, 7,                             WV_NETEVENT_ICMPCTRL_BADCMD, name[0]) #endif  /@ INCLUDE_WVNET @/#endif * XXX - end of unused event */		return (ENOPROTOOPT);	}	/* NOTREACHED */}#endif /* SYSCTL_SUPPORT */

⌨️ 快捷键说明

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