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

📄 if_ether.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
 * In addition, a sanity check is performed on the sender * protocol address, to catch impersonators. * We no longer handle negotiations for use of trailer protocol: * Formerly, ARP replied for protocol type ETHERTYPE_TRAIL sent * along with IP replies if we wanted trailers sent to us, * and also sent them in response to IP replies. * This allowed either end to announce the desire to receive * trailer packets. * We no longer reply to requests for ETHERTYPE_TRAIL protocol either, * but formerly didn't normally send requests. */static voidin_arpinput(m)	struct mbuf *m;{	register struct ether_arp *ea;	register struct arpcom *ac = (struct arpcom *)m->m_pkthdr.rcvif;	struct ether_header *eh;	register struct llinfo_arp *la = 0;	register struct rtentry *rt;	struct in_ifaddr *ia, *maybe_ia = 0;	struct sockaddr_dl *sdl;	struct sockaddr sa;	struct in_addr isaddr, itaddr, myaddr;	int op;#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_NOTICE event */        WV_NET_EVENT_0 (NET_AUX_EVENT, WV_NET_NOTICE, 0, 12,                         WV_NETEVENT_ARPIN_START, WV_NET_RECV)#endif  /* INCLUDE_WVNET */#endif	ea = mtod(m, struct ether_arp *);	op = ntohs(ea->arp_op);	bcopy((caddr_t)ea->arp_spa, (caddr_t)&isaddr, sizeof (isaddr));	bcopy((caddr_t)ea->arp_tpa, (caddr_t)&itaddr, sizeof (itaddr));#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 */		if (ia->ia_ifp == &ac->ac_if) {			maybe_ia = ia;			if ((itaddr.s_addr == ia->ia_addr.sin_addr.s_addr) ||			     (isaddr.s_addr == ia->ia_addr.sin_addr.s_addr))				break;		}	if (maybe_ia == 0)		goto out;	myaddr = ia ? ia->ia_addr.sin_addr : maybe_ia->ia_addr.sin_addr;	if (!bcmp((caddr_t)ea->arp_sha, (caddr_t)ac->ac_enaddr,	    sizeof (ea->arp_sha)))		goto out;	/* it's from me, ignore it. */	if (!bcmp((caddr_t)ea->arp_sha, (caddr_t)etherbroadcastaddr,	    sizeof (ea->arp_sha))) {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_WARNING event */                WV_NET_DSTADDRIN_EVENT_1 (NET_AUX_EVENT, WV_NET_WARNING, 2, 9,                                          isaddr.s_addr,                                       WV_NETEVENT_ARPIN_BADADDR, WV_NET_RECV,                                          isaddr.s_addr)#endif  /* INCLUDE_WVNET */#endif		logMsg (		    "arp: ether address is broadcast for IP address %x!\n",		    (int)ntohl(isaddr.s_addr), 0,0,0,0,0);		goto out;	}	if (ETHER_MULTICAST(ea->arp_sha))	    {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_WARNING event */		WV_NET_DSTADDRIN_EVENT_1 (NET_AUX_EVENT, WV_NET_WARNING, 2, 9,					  isaddr.s_addr,				       WV_NETEVENT_ARPIN_BADADDR, WV_NET_RECV,					  isaddr.s_addr)#endif  /* INCLUDE_WVNET */#endif	     logMsg ("arp: ether address is multicast for IP address %x!\n",		     (int)ntohl (isaddr.s_addr), 0, 0, 0, 0, 0);	     goto out;	     }		if (isaddr.s_addr == myaddr.s_addr) {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_WARNING event */                WV_NET_DSTADDRIN_EVENT_1 (NET_AUX_EVENT, WV_NET_WARNING, 3, 10,                                          isaddr.s_addr,                                       WV_NETEVENT_ARPIN_BADADDR2, WV_NET_RECV,                                          isaddr.s_addr)#endif  /* INCLUDE_WVNET */#endif		logMsg(		   "duplicate IP address %08x sent from ethernet address %s\n",		   (int)ntohl(isaddr.s_addr), (int)ether_sprintf(ea->arp_sha),		   0,0,0,0);		itaddr = myaddr;		goto reply;	}	la = arplookup(isaddr.s_addr, itaddr.s_addr == myaddr.s_addr, 0);	if (la && (rt = la->la_rt) && (sdl = SDL(rt->rt_gateway))) {		if (sdl->sdl_alen &&		    bcmp((caddr_t)ea->arp_sha, LLADDR(sdl), sdl->sdl_alen))                    {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_WARNING event */                WV_NET_DSTADDRIN_EVENT_1 (NET_AUX_EVENT, WV_NET_WARNING, 4, 11,                                          isaddr.s_addr,                                       WV_NETEVENT_ARPIN_BADADDR3, WV_NET_RECV,                                          isaddr.s_addr)#endif  /* INCLUDE_WVNET */#endif			logMsg("arp info overwritten for %08x by %s\n",			    (int) ntohl(isaddr.s_addr), 			    (int) ether_sprintf(ea->arp_sha),0,0,0,0);                    }		bcopy((caddr_t)ea->arp_sha, LLADDR(sdl),		    sdl->sdl_alen = sizeof(ea->arp_sha));		if (rt->rt_expire)			rt->rt_expire = tickGet() + (sysClkRateGet() * 						     arpt_keep);		rt->rt_flags &= ~RTF_REJECT;		la->la_asked = 0;		if (la->la_hold) {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_NOTICE event */                   WV_NET_EVENT_1 (NET_CORE_EVENT, WV_NET_NOTICE, 1, 13,                                   WV_NETEVENT_ARPIN_DELAYEDSEND, WV_NET_SEND,                                   isaddr.s_addr)#endif  /* INCLUDE_WVNET */#endif			(*ac->ac_if.if_output)(&ac->ac_if, la->la_hold,				rt_key(rt), rt);			la->la_hold = 0;		}	}reply:	if (op != ARPOP_REQUEST) {	out:		m_freem(m);		return;	}	if (itaddr.s_addr == myaddr.s_addr) {		/* I am the target */		bcopy((caddr_t)ea->arp_sha, (caddr_t)ea->arp_tha,		    sizeof(ea->arp_sha));		bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->arp_sha,		    sizeof(ea->arp_sha));	} else {		la = arplookup(itaddr.s_addr, 0, SIN_PROXY);		if (la == 0)			goto out;		rt = la->la_rt;		bcopy((caddr_t)ea->arp_sha, (caddr_t)ea->arp_tha,		    sizeof(ea->arp_sha));		sdl = SDL(rt->rt_gateway);                /*                 * ARP entries added by a proxy server use a "wildcard"                 * hardware address (equal to the sending interface) to                 * support multiple proxy networks.                 */                if (rt->rt_flags & RTF_PROTO1)                    bcopy ((caddr_t)ac->ac_enaddr, (caddr_t)ea->arp_sha,                           sizeof(ea->arp_sha));                else                    bcopy (LLADDR(sdl), (caddr_t)ea->arp_sha,                           sizeof(ea->arp_sha));	}	bcopy((caddr_t)ea->arp_spa, (caddr_t)ea->arp_tpa, sizeof(ea->arp_spa));	bcopy((caddr_t)&itaddr, (caddr_t)ea->arp_spa, sizeof(ea->arp_spa));	ea->arp_op = htons(ARPOP_REPLY);	ea->arp_pro = htons(ETHERTYPE_IP); /* let's be sure! */	eh = (struct ether_header *)sa.sa_data;	bcopy((caddr_t)ea->arp_tha, (caddr_t)eh->ether_dhost,	    sizeof(eh->ether_dhost));	eh->ether_type = ETHERTYPE_ARP;	sa.sa_family = AF_UNSPEC;	sa.sa_len = sizeof(sa);#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_NOTICE event */        WV_NET_ADDROUT_EVENT_2 (NET_AUX_EVENT, WV_NET_NOTICE, 2, 14,                                isaddr.s_addr, itaddr.s_addr,                                WV_NETEVENT_ARPIN_REPLYSEND, WV_NET_SEND,                                itaddr.s_addr, isaddr.s_addr)#endif  /* INCLUDE_WVNET */#endif	(*ac->ac_if.if_output)(&ac->ac_if, m, &sa, (struct rtentry *)0);	return;}/* * Free an arp entry. */voidarptfree(la)	register struct llinfo_arp *la;{	register struct rtentry *rt = la->la_rt;	register struct sockaddr_dl *sdl;	if (rt == 0)            {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_EMERGENCY event */            WV_NET_MARKER_0 (NET_AUX_EVENT, WV_NET_EMERGENCY, 5, 5,                             WV_NETEVENT_ARPTFREE_PANIC)#endif  /* INCLUDE_WVNET */#endif		panic("arptfree");            }        if (rt->rt_refcnt > 0 && (sdl = SDL(rt->rt_gateway)) &&            sdl->sdl_family == AF_LINK) {                sdl->sdl_alen = 0;                la->la_asked = 0;                rt->rt_flags |= RTF_REJECT;        } #ifdef ROUTER_STACK        /* Let Fastpath know that the entry is being deleted */        FFL_CALL (ffLibMacEntryDeleted, \                  (GET_IPV4_FF_ID, rt_key(rt), rt->rt_gateway));#endif /* ROUTER_STACK */	rtrequest(RTM_DELETE, rt_key(rt), (struct sockaddr *)0, rt_mask(rt),	    0, (struct rtentry **)0);}/* * Lookup or enter a new address in arptab. */static struct llinfo_arp *arplookup(addr, create, proxy)	u_long addr;	int create, proxy;{	register struct rtentry *rt;#ifndef VIRTUAL_STACK	static struct sockaddr_inarp sin = {sizeof(sin), AF_INET };	sin.sin_addr.s_addr = addr;	sin.sin_other = proxy ? SIN_PROXY : 0;	rt = rtalloc1((struct sockaddr *)&sin, create);#else	arpSin.sin_len    = sizeof(arpSin);        arpSin.sin_family = AF_INET;	arpSin.sin_addr.s_addr = addr;	arpSin.sin_other = proxy ? SIN_PROXY : 0;	rt = rtalloc1((struct sockaddr *)&arpSin, create);#endif /* VIRTUAL_STACK */	if (rt == 0)		return (0);	rt->rt_refcnt--;	if ((rt->rt_flags & RTF_GATEWAY) || (rt->rt_flags & RTF_LLINFO) == 0 ||	    rt->rt_gateway->sa_family != AF_LINK) {		if (create)			logMsg("arptnew failed on %x\n", (int)ntohl(addr),			0,0,0,0,0);		return (0);	}	return ((struct llinfo_arp *)rt->rt_llinfo);}int arpioctl    (    int 	cmd,    caddr_t	data    )    {    register struct arpreq *		ar = (struct arpreq *)data;    register struct sockaddr_in *	soInAddr;    register struct llinfo_arp *	la = NULL;    register struct rtentry *		rt = NULL;    struct rtentry * 			pNewRt;    struct sockaddr_dl * 		sdl = NULL;    struct sockaddr_in 			rtmask;    struct sockaddr_in * 		pMask;    struct sockaddr_inarp 		ipaddr;    struct sockaddr_dl 			arpaddr;    int error = OK;    int flags = 0;    BOOL proxy = FALSE;    BOOL export = FALSE;#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_INFO event */    WV_NET_MARKER_1 (NET_AUX_EVENT, WV_NET_INFO, 3, 16,                     WV_NETEVENT_ARPIOCTL_START, cmd)#endif  /* INCLUDE_WVNET */#endif    if (ar->arp_pa.sa_family != AF_INET ||	ar->arp_ha.sa_family != AF_UNSPEC)        {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_ERROR event */        WV_NET_MARKER_2 (NET_AUX_EVENT, WV_NET_ERROR, 2, 7,                         WV_NETEVENT_ARPIOCTL_NOTSUPP,                         ar->arp_pa.sa_family, ar->arp_ha.sa_family)#endif  /* INCLUDE_WVNET */#endif	return (EAFNOSUPPORT);        }    soInAddr = (struct sockaddr_in *)&ar->arp_pa;    switch ((u_int) cmd) 	{	case SIOCSARP:            if (ar->arp_flags & ATF_PUBL)                {                flags |= RTF_ANNOUNCE;                proxy = TRUE;                }            /* Use a "wildcard" hardware address for proxy server entries. */            if (ar->arp_flags & ATF_PROXY)                flags |= RTF_PROTO1;            /* Search for existing entry with same address. */               bzero ( (char *)&ipaddr, sizeof (ipaddr));            ipaddr.sin_len = sizeof (ipaddr);            ipaddr.sin_family = AF_INET;            ipaddr.sin_addr.s_addr = soInAddr->sin_addr.s_addr;            rt = rtalloc1 ((struct sockaddr *)&ipaddr, 0);	    if (!rt)                {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_CRITICAL event */                WV_NET_EVENT_2 (NET_AUX_EVENT, WV_NET_CRITICAL, 1, 6,                                WV_NETEVENT_ARPIOCTL_SEARCHFAIL, WV_NET_SEND,                                cmd, soInAddr->sin_addr.s_addr)#endif  /* INCLUDE_WVNET */#endif                return (ENETUNREACH);                }	              if (rt && !(ar->arp_flags & ATF_INCOMPLETE))                 {                rt->rt_refcnt--;                if (soInAddr->sin_addr.s_addr ==                        ((struct sockaddr_in *)rt_key (rt))->sin_addr.s_addr)                    {                    /* Matching entry found. Check address type. */                    if ( (rt->rt_flags & RTF_GATEWAY) ||                               (rt->rt_flags & RTF_LLINFO) == 0 ||                                      rt->rt_gateway->sa_family != AF_LINK)                        {                        /* Host entry found: must create proxy entry. */                        if ( !(ar->arp_flags & ATF_PUBL))                            return (EINVAL);                        /*                          * Set flag to prevent replacement of current entry                          * by creating entry which includes SIN_PROXY flag.                         */                        export = TRUE;                        }                    }                /*                 * For remote hosts or networks, the gateway's associated                 * route entry contains the interface values.                 */                if (rt->rt_flags & RTF_GATEWAY)                    {                    if (rt->rt_gwroute == 0)                        return (EHOSTUNREACH);                    else                        sdl = SDL (rt->rt_gwroute->rt_gateway);                    }                else                    sdl = SDL (rt->rt_gateway);                if (sdl->sdl_family != AF_LINK)                    return (EINVAL);	        }            bzero ( (char *)&rtmask, sizeof (rtmask));            rtmask.sin_len = 8;            rtmask.sin_addr.s_addr = 0xffffffff;            bzero ( (char *)&ipaddr, sizeof (ipaddr));            ipaddr.sin_len = sizeof (ipaddr);            ipaddr.sin_family = AF_INET;

⌨️ 快捷键说明

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