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

📄 if_ether.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
		}		/* Announce a new entry if requested. */		if (rt->rt_flags & RTF_ANNOUNCE)			arprequest((struct arpcom *)rt->rt_ifp,			    &SIN(rt_key(rt))->sin_addr.s_addr,			    &SIN(rt_key(rt))->sin_addr.s_addr,			    (u_char *)LLADDR(SDL(gate)));		/*FALLTHROUGH*/	case RTM_RESOLVE:		if (gate->sa_family != AF_LINK ||		    gate->sa_len < sizeof(null_sdl)) {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_WARNING event */                WV_NET_MARKER_2 (NET_AUX_EVENT, WV_NET_WARNING, 1, 8,                                 WV_NETEVENT_ARPRTREQ_BADGATE,                                 gate->sa_family, gate->sa_len)#endif  /* INCLUDE_WVNET */#endif			logMsg("arp_rtrequest: bad gateway value",0,0,0,0,0,0);			break;		}		SDL(gate)->sdl_type = rt->rt_ifp->if_type;		SDL(gate)->sdl_index = rt->rt_ifp->if_index;		if (la != 0)			break; /* This happens on a route change */		/*		 * Case 2:  This route may come from cloning, or a manual route		 * add with a LL address.		 */				if (arp_inuse >= arpMaxEntries)                   arpEntryDelete ();		R_Malloc(la, struct llinfo_arp *, sizeof(*la));		rt->rt_llinfo = (caddr_t)la;		if (la == 0) {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_EMERGENCY event */            WV_NET_MARKER_0 (NET_AUX_EVENT, WV_NET_EMERGENCY, 1, 1,                             WV_NETEVENT_ARPRTREQ_FAIL)#endif  /* INCLUDE_WVNET */#endif			logMsg("arp_rtrequest: malloc failed\n",0,0,0,0,0,0);			break;		}		arp_inuse++, arp_allocated++;		Bzero(la, sizeof(*la));		la->la_rt = rt;		rt->rt_flags |= RTF_LLINFO;#ifdef VIRTUAL_STACK		insque(la, &_llinfo_arp);#else		insque(la, &llinfo_arp);#endif /* VIRTUAL_STACK */		ifAddr = rt->rt_ifp->if_addrlist;		/* 		 * Find destination address in list of addresses assigned to		 * interface.		 */		while (ifAddr)		    {		    if (SIN(rt_key(rt))->sin_addr.s_addr ==		        (IA_SIN(ifAddr))->sin_addr.s_addr) 			{		    /*		     * This test used to be		     *	if (loif.if_flags & IFF_UP)		     * It allowed local traffic to be forced		     * through the hardware by configuring the loopback down.		     * However, it causes problems during network configuration		     * for boards that can't receive packets they send.		     * It is now necessary to clear "useloopback" and remove		     * the route to force traffic out to the hardware.		     */			rt->rt_expire = 0;			Bcopy(((struct arpcom *)rt->rt_ifp)->ac_enaddr,				LLADDR(SDL(gate)), SDL(gate)->sdl_alen = 6);			if (useloopback)				rt->rt_ifp = loif;                        break;			}                    ifAddr = ifAddr->ifa_next;		    }		break;	case RTM_DELETE:		if (la == 0)			break;		arp_inuse--;		remque(la);		rt->rt_llinfo = 0;		rt->rt_flags &= ~RTF_LLINFO;		if (la->la_hold)			m_freem(la->la_hold);		Free((caddr_t)la);	}}/* * Broadcast an ARP packet, asking who has addr on interface ac. */voidarpwhohas(ac, addr)	register struct arpcom *ac;	register struct in_addr *addr;{	arprequest(ac, &ac->ac_ipaddr.s_addr, &addr->s_addr, ac->ac_enaddr);}/* * Broadcast an ARP request. Caller specifies: *	- arp header source ip address *	- arp header target ip address *	- arp header source ethernet address */static voidarprequest(ac, sip, tip, enaddr)	register struct arpcom *ac;	register u_long *sip, *tip;	register u_char *enaddr;{	register struct mbuf *m;	register struct ether_header *eh;	register struct ether_arp *ea;	struct sockaddr sa;	if ((m = mHdrClGet(M_DONTWAIT, MT_DATA, 			   sizeof(*ea), TRUE)) == NULL)            {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_EMERGENCY event */            WV_NET_MARKER_0 (NET_AUX_EVENT, WV_NET_EMERGENCY, 2, 2,                             WV_NETEVENT_ARPREQ_FAIL)#endif  /* INCLUDE_WVNET */#endif	    return;            }	m->m_len = sizeof(*ea);	m->m_pkthdr.len = sizeof(*ea);	MH_ALIGN(m, sizeof(*ea));	ea = mtod(m, struct ether_arp *);	eh = (struct ether_header *)sa.sa_data;	bzero((caddr_t)ea, sizeof (*ea));	bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,	    sizeof(eh->ether_dhost));	eh->ether_type = ETHERTYPE_ARP;		/* if_output will swap */	ea->arp_hrd = htons(ARPHRD_ETHER);	ea->arp_pro = htons(ETHERTYPE_IP);	ea->arp_hln = sizeof(ea->arp_sha);	/* hardware address length */	ea->arp_pln = sizeof(ea->arp_spa);	/* protocol address length */	ea->arp_op = htons(ARPOP_REQUEST);	bcopy((caddr_t)enaddr, (caddr_t)ea->arp_sha, sizeof(ea->arp_sha));	bcopy((caddr_t)sip, (caddr_t)ea->arp_spa, sizeof(ea->arp_spa));	bcopy((caddr_t)tip, (caddr_t)ea->arp_tpa, sizeof(ea->arp_tpa));	sa.sa_family = AF_UNSPEC;	sa.sa_len = sizeof(sa);	(*ac->ac_if.if_output)(&ac->ac_if, m, &sa, (struct rtentry *)0);#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_VERBOSE event */        WV_NET_MARKER_0 (NET_AUX_EVENT, WV_NET_VERBOSE, 8, 18,                         WV_NETEVENT_ARPREQ_SEND)#endif  /* INCLUDE_WVNET */#endif}/* * Resolve an IP address into an ethernet address.  If success, * desten is filled in.  If there is no entry in arptab, * set one up and broadcast a request for the IP address. * Hold onto this mbuf and resend it once the address * is finally resolved.  A return value of 1 indicates * that desten has been filled in and the packet should be sent * normally; a 0 return indicates that the packet has been * taken over here, either now or for later transmission. */intarpresolve(ac, rt, m, dst, desten)	register struct arpcom *ac;	register struct rtentry *rt;	struct mbuf *m;	register struct sockaddr *dst;	register u_char *desten;{	register struct llinfo_arp *la;	struct sockaddr_dl *sdl;	int alen;                          /* Length of MAC address */	u_long lna;                        /* Host portion if IP address */	struct ifnet *pIf = &ac->ac_if;	USHORT *pSrc = NULL;	USHORT *pDst = NULL;#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_VERBOSE event */            WV_NET_DSTADDROUT_MARKER_1 (NET_AUX_EVENT, WV_NET_VERBOSE, 9, 19,                               ((struct sockaddr_in *)dst)->sin_addr.s_addr,                                        WV_NETEVENT_ARPRESOLV_START,                               ((struct sockaddr_in *)dst)->sin_addr.s_addr)#endif  /* INCLUDE_WVNET */#endif	if (m != NULL)		/* check if mbuf is not null */	    {	    if (m->m_flags & M_BCAST)		{	/* broadcast */		pDst = (USHORT *)desten;		pDst[0] = 0xFFFF;		pDst[1] = 0xFFFF;		pDst[2] = 0xFFFF;		return (1);		}	    if (m->m_flags & M_MCAST)		{	/* multicast */		ETHER_MAP_IP_MULTICAST(&SIN(dst)->sin_addr, desten);		return(1);		}	    }		if (rt)		la = (struct llinfo_arp *)rt->rt_llinfo;	else {		if ((la = arplookup(SIN(dst)->sin_addr.s_addr, 1, 0)))			rt = la->la_rt;	}	if (la == 0 || rt == 0) {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_EMERGENCY event */            WV_NET_DSTADDROUT_EVENT_1 (NET_AUX_EVENT, WV_NET_EMERGENCY, 3, 3,                               ((struct sockaddr_in *)dst)->sin_addr.s_addr,                                    WV_NETEVENT_ARPLOOK_FAIL, WV_NET_SEND,                               ((struct sockaddr_in *)dst)->sin_addr.s_addr)#endif  /* INCLUDE_WVNET */#endif		logMsg ("arpresolve: lookup failed (resource shortage or \n \network configuration error -- check netmask)\n",0,0,0,0,0,0);		m_freem(m);		return (0);	}	sdl = SDL(rt->rt_gateway);	/*	 * Check the address family and length is valid, the address	 * is resolved; otherwise, try to resolve.	 */	if ((rt->rt_expire == 0 || !TICK_GEQ (tickGet(), rt->rt_expire)) &&	    sdl->sdl_family == AF_LINK && sdl->sdl_alen != 0) {		pSrc = (USHORT *)LLADDR(sdl);		pDst = (USHORT *)desten;		pDst[0] = pSrc[0];		pDst[1] = pSrc[1];		pDst[2] = pSrc[2];		return 1;	}        /*	 * For shared memory interface using a BSD driver, resolve using	 * smNetAddrResolve. All other BSD drivers will have if_resolve	 * equal to NULL.	 */	if ((pIf->pCookie == NULL) && (pIf->if_resolve) &&	    ((*pIf->if_resolve) (pIf, (struct in_addr *) &(SIN(dst)->sin_addr),				 desten, NULL) == 0))	    return (1);	/* If IFF_NOARP then make LL addr from IP host addr */	 	if (ac->ac_if.if_flags & IFF_NOARP) 	    {	    /* Set expiration of Route/ARP entry */	    if (rt->rt_expire == 0)		{		rt->rt_expire = tickGet ();		}	    /* Set length of MAC address.  Default to Ethernet length. */	    alen = (sdl->sdl_alen > 0 ? sdl->sdl_alen : 		    sizeof (struct ether_addr));	    if (alen < 3)		{		return (0);		}	    bcopy((caddr_t)ac->ac_enaddr, (char *)desten, alen - 3);	    lna = in_lnaof(SIN(dst)->sin_addr);	    desten[alen - 1]     = lna & 0xff;	    desten[alen - 1 - 1] = (lna >> 8) & 0xff;	    desten[alen - 1 - 2] = (lna >> 16) & 0x7f;	    return (1);	    }	/*	 * There is an arptab entry, but no ethernet address	 * response yet.  Replace the held mbuf with this	 * latest one.	 */	if (la->la_hold)		m_freem(la->la_hold);	la->la_hold = m;	if (rt->rt_expire) {		rt->rt_flags &= ~RTF_REJECT;		if (arpRxmitTicks < 0)		    arpRxmitTicks = ARP_RXMIT_TICKS_DFLT;		if (la->la_asked == 0 || 		    (tickGet () - rt->rt_expire >= arpRxmitTicks)) {			rt->rt_expire = tickGet();			if (la->la_asked++ < arp_maxtries)				arpwhohas(ac, &(SIN(dst)->sin_addr));			else {				rt->rt_flags |= RTF_REJECT;				rt->rt_expire += (sysClkRateGet() * arpt_down);				la->la_asked = 0;			}		}	}	return (0);}/* * Common length and type checks are done here, * then the protocol-specific routine is called. */#ifdef VIRTUAL_STACKvoid arpintr    (    int stackNum    )#elsevoid arpintr()#endif /* VIRTUAL_STACK */    {    register struct mbuf *m;    register struct arphdr *ar;    int s;#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_VERBOSE event */        WV_NET_MARKER_0 (NET_AUX_EVENT, WV_NET_VERBOSE, 10, 20,                             WV_NETEVENT_ARPINTR_START)#endif  /* INCLUDE_WVNET */#endif#ifdef VIRTUAL_STACK    /* Set the correct virtual stack context for the input processing. */    virtualStackNumTaskIdSet (stackNum);#endif /* VIRTUAL_STACK */    s = splnet ();    while (arpintrq.ifq_head)        {        IF_DEQUEUE (&arpintrq, m);        if (m == 0 || (m->m_flags & M_PKTHDR) == 0)            {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_EMERGENCY event */            WV_NET_EVENT_0 (NET_AUX_EVENT, WV_NET_EMERGENCY, 4, 4,                            WV_NETEVENT_ARPINTR_FAIL, WV_NET_RECV)#endif  /* INCLUDE_WVNET */#endif            panic("arpintr");            }#ifdef VIRTUAL_STACK                /*                 * (tNetTask) Set the virtual stack ID so the received                 * packet will be processed by the correct stack.                 */                virtualStackNumTaskIdSet(m->m_pkthdr.rcvif->vsNum);#endif /* VIRTUAL_STACK */        if (m->m_len >= sizeof(struct arphdr) &&                (ar = mtod(m, struct arphdr *)) &&                 ntohs(ar->ar_hrd) == ARPHRD_ETHER &&            m->m_len >= sizeof(struct arphdr) + 2 * (ar->ar_hln + ar->ar_pln))            {            switch (ntohs(ar->ar_pro))                {                case ETHERTYPE_IP:                case ETHERTYPE_IPTRAILERS:#ifdef PROXY_HOOK                    if (proxyArpHook == NULL ||                        (* proxyArpHook)                         ( (struct arpcom *)m->m_pkthdr.rcvif, m) == FALSE)#endif                        in_arpinput(m);                    continue;                }            }        m_freem(m);        }    splx (s);    }/* * ARP for Internet protocols on 10 Mb/s Ethernet. * Algorithm is that given in RFC 826.

⌨️ 快捷键说明

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