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

📄 if_subr.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	etype = ntohs(eh->ether_type);        /* add code here to process IEEE802.3 LLC format, Hook!! */        /* demux the packet and hand off the ip layer */        do_protocol_with_type (etype, m , ac, m->m_pkthdr.len); }/* * Perform common duties while attaching to interface list */voidether_ifattach(ifp)	register struct ifnet *ifp;{	register struct ifaddr *ifa;	register struct sockaddr_dl *sdl;#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_VERBOSE event */        WV_NET_MARKER_1 (NET_AUX_EVENT, WV_NET_VERBOSE, 11, 14,                         WV_NETEVENT_ETHERIFATTACH_START, ifp)#endif  /* INCLUDE_WVNET */#endif	ifp->if_type = IFT_ETHER;	ifp->if_addrlen = 6;	ifp->if_hdrlen = 14;	ifp->if_mtu = ETHERMTU;	for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)		if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) &&		    sdl->sdl_family == AF_LINK) {			sdl->sdl_type = IFT_ETHER;			sdl->sdl_alen = ifp->if_addrlen;			bcopy((caddr_t)((struct arpcom *)ifp)->ac_enaddr,			      LLADDR(sdl), ifp->if_addrlen);			break;		}}/* * Add an Ethernet multicast address or range of addresses to the list for a * given interface. */intether_addmulti(ifr, ac)	struct ifreq *ifr;	register struct arpcom *ac;{	register struct ether_multi *enm;	struct sockaddr_in *sin;	u_char addrlo[6];	u_char addrhi[6];	int s = splimp();/* * XXX - This event cannot currently occur: the ether_addmulti() routine *       provides multicasting support which is not available for VxWorks *       BSD Ethernet drivers.#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /@ WV_NET_VERBOSE event @/        WV_NET_MARKER_1 (NET_AUX_EVENT, WV_NET_VERBOSE, 12, 15,                         WV_NETEVENT_ADDMULT_START, ac->ac_if)#endif  /@ INCLUDE_WVNET @/#endif * XXX - end of unused event */	switch (ifr->ifr_addr.sa_family) {	case AF_UNSPEC:		bcopy((char *)ifr->ifr_addr.sa_data, (char *)addrlo, 6);		bcopy((char *) addrlo, (char *)addrhi, 6);		break;#ifdef INET	case AF_INET:		sin = (struct sockaddr_in *)&(ifr->ifr_addr);		if (sin->sin_addr.s_addr == INADDR_ANY) {			/*			 * An IP address of INADDR_ANY means listen to all			 * of the Ethernet multicast addresses used for IP.			 * (This is for the sake of IP multicast routers.)			 */			bcopy((char *)ether_ipmulticast_min, (char *)addrlo, 6);			bcopy((char *)ether_ipmulticast_max, (char *)addrhi, 6);		}		else {			ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo);			bcopy((char *)addrlo, (char *)addrhi, 6);		}		break;#endif	default:		splx(s);#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_ERROR event */                WV_NET_MARKER_1 (NET_AUX_EVENT, WV_NET_ERROR, 4, 8,                                WV_NETEVENT_ADDMULT_AFNOTSUPP,                                ifr->ifr_addr.sa_family) #endif  /* INCLUDE_WVNET */#endif		return (EAFNOSUPPORT);	}	/*	 * Verify that we have valid Ethernet multicast addresses.	 */	if ((addrlo[0] & 0x01) != 1 || (addrhi[0] & 0x01) != 1) {		splx(s);#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_ERROR event */                WV_NET_MARKER_1 (NET_AUX_EVENT, WV_NET_ERROR, 5, 9,                                WV_NETEVENT_ADDMULT_BADADDR,                                ac->ac_if) #endif  /* INCLUDE_WVNET */#endif		return (EINVAL);	}	/*	 * See if the address range is already in the list.	 */	ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);	if (enm != NULL) {		/*		 * Found it; just increment the reference count.		 */		++enm->enm_refcount;		splx(s);		return (0);	}	/*	 * New address or range; malloc a new multicast record	 * and link it into the interface's multicast list.	 */        MALLOC (enm, struct ether_multi *, sizeof(*enm), MT_IFMADDR, 		M_DONTWAIT);	if (enm == NULL) {		splx(s);#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_EMERGENCY event */                WV_NET_MARKER_0 (NET_AUX_EVENT, WV_NET_EMERGENCY, 6, 1,                                 WV_NETEVENT_ADDMULT_NOBUFS)#endif  /* INCLUDE_WVNET */#endif		return (ENOBUFS);	}	bcopy((char *)addrlo, (char *)enm->enm_addrlo, 6);	bcopy((char *)addrhi, (char *)enm->enm_addrhi, 6);	enm->enm_ac = ac;	enm->enm_refcount = 1;	enm->enm_next = ac->ac_multiaddrs;	ac->ac_multiaddrs = enm;	ac->ac_multicnt++;	splx(s);	/*	 * Return ENETRESET to inform the driver that the list has changed	 * and its reception filter should be adjusted accordingly.	 */	return (ENETRESET);}/* * Delete a multicast address record. */intether_delmulti(ifr, ac)	struct ifreq *ifr;	register struct arpcom *ac;{	register struct ether_multi *enm;	register struct ether_multi **p;	struct sockaddr_in *sin;	u_char addrlo[6];	u_char addrhi[6];	int s = splimp();/* * XXX - This event cannot currently occur: the ether_delmulti() routine *       provides multicasting support which is not available for VxWorks *       BSD Ethernet drivers.#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /@ WV_NET_VERBOSE event @/        WV_NET_MARKER_1 (NET_AUX_EVENT, WV_NET_VERBOSE, 13, 16,                            WV_NETEVENT_DELMULT_START, ac->ac_if)#endif  /@ INCLUDE_WVNET @/#endif * XXX - end of unused event */	switch (ifr->ifr_addr.sa_family) {	case AF_UNSPEC:		bcopy((char *)ifr->ifr_addr.sa_data, (char *)addrlo, 6);		bcopy((char *)addrlo, (char *)addrhi, 6);		break;#ifdef INET	case AF_INET:		sin = (struct sockaddr_in *)&(ifr->ifr_addr);		if (sin->sin_addr.s_addr == INADDR_ANY) {			/*			 * An IP address of INADDR_ANY means stop listening			 * to the range of Ethernet multicast addresses used			 * for IP.			 */			bcopy((char *)ether_ipmulticast_min, (char *)addrlo, 6);			bcopy((char *)ether_ipmulticast_max, (char *)addrhi, 6);		}		else {			ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo);			bcopy((char *)addrlo, (char *)addrhi, 6);		}		break;#endif	default:		splx(s);#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_ERROR event */                WV_NET_MARKER_1 (NET_AUX_EVENT, WV_NET_ERROR, 6, 10,                                 WV_NETEVENT_DELMULT_AFNOTSUPP,                                 ifr->ifr_addr.sa_family)#endif  /* INCLUDE_WVNET */#endif		return (EAFNOSUPPORT);	}	/*	 * Look up the address in our list.	 */	ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);	if (enm == NULL) {		splx(s);#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_ERROR event */                WV_NET_MARKER_1 (NET_AUX_EVENT, WV_NET_ERROR, 7, 11,                                 WV_NETEVENT_DELMULT_BADADDR, ac->ac_if)#endif  /* INCLUDE_WVNET */#endif		return (ENXIO);	}	if (--enm->enm_refcount != 0) {		/*		 * Still some claims to this record.		 */		splx(s);		return (0);	}	/*	 * No remaining claims to this record; unlink and free it.	 */	for (p = &enm->enm_ac->ac_multiaddrs;	     *p != enm;	     p = &(*p)->enm_next)		continue;	*p = (*p)->enm_next;	FREE(enm, MT_IFMADDR);	ac->ac_multicnt--;	splx(s);	/*	 * Return ENETRESET to inform the driver that the list has changed	 * and its reception filter should be adjusted accordingly.	 */	return (ENETRESET);}/********************************************************************************* check_trailer - check ethernet frames that have trailers following them** Decypher the ethernet frames that are encoded via trailer protocol which* has a link level type field that contains a value which is an encoding of* the size of the data portion.  The original BSD 4.2 and 4.3 TCP/IP* implementations use the trailer protocol to accomplish more efficient* copying of data.  Basically the idea was to put the variable lenght protocol* headers (TCP, UDP, IP headers) at the end of a page aligned data and use* the link-level type field (ethernet type) to indicate both the use of a* specialized framing protocol as well as the length of the data following* the ethernet header.  The original link-level type field and the length* of the protocol headers following the data portion are attached between* the data portion (which should be of length multiple of 512 bytes) and* protocol headers.  (size of data portion == (type - 0x1000) * 415)** Upon return, 'pOff' will contain NULL if trailer protocol is not being* used.  Otherwise, 'pOff' points to the trailer header and 'pLen'* will contain the size of the frame.** NOMANUAL*/void check_trailer (eh, pData, pLen, pOff, ifp)    FAST struct ether_header 	*eh;	/* ethernet header */    FAST unsigned char 		*pData;	/* data immediately after 'eh' */    FAST int 			*pLen;	/* value/result input data length */    FAST int 			*pOff;	/* result -- points to trailer header */    FAST struct ifnet 		*ifp;	/* network interface */    {#if 0 /* XXX No support for trailers in BSD44 vxWorks */        FAST int resid;    eh->ether_type = ntohs((u_short)eh->ether_type);    if ((eh->ether_type >= ETHERTYPE_TRAIL)  &&	(eh->ether_type < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER))	{	*pOff = (eh->ether_type - ETHERTYPE_TRAIL) * 512;	if (*pOff >= ifp->if_mtu)	    return;		/* sanity */	eh->ether_type = ntohs (*(u_short *) (pData + *pOff));	resid          = ntohs (*(u_short *) (pData + *pOff + 2));	if ((*pOff + resid) > *pLen)	    return;		/* sanity */	*pLen = *pOff + resid;	}    else	*pOff = 0;#endif /* XXX No trailer support in BSD44 */        }/********************************************************************************* bcopy_to_mbufs - copy data into mbuf chain** Copies up to <totlen> bytes of data from <buf0> into a freshly allocated* mbuf. The <off0> parameter indicates the amount of trailer encapsulation,* which was formerly handled according to the trailer protocol described in* check_trailer(). Since trailer encapsulation is not supported in BSD 4.4,* that parameter is unused. The <width> argument supports machines which * have special byte alignment requirements when copying data from device * I/O buffers to main memory.  A macro function called 'copy_to_mbufs' is * provided in the "mbuf.h" file for compatability with SunOS, which doesn't * support the <width> parameter. This function uses mbuf clusters when possible* to enhance network throughput.** RETURNS: first mbuf or 0 if error** NOMANUAL*/struct mbuf *bcopy_to_mbufs (buf0, totlen, off0, ifp, width)    u_char		*buf0;		/* buffer to be copied into mbufs */    int			totlen;		/* number of bytes to be copied */    int			off0;		/* trailer protocol indicative */    struct ifnet	*ifp;		/* network interface */    int			width;		/* copy data by this unit width */    {    return (m_devget ((char *) buf0, totlen, width, ifp, NULL));    }/******************************************************************************** copyFromMbufs - copy data from an mbuf chain** This routine copies data from an mbuf chain into a given buffer.* The length of the data copied from the mbuf chain is returned.* The argument width is provided for machines that have special byte alignment* requirements when copying data to an I/O buffer of the device from main* memory. This routine frees the mbuf chain passed to it. ** This routine should not be used since it can cause unaligned memory accesses* resulting in target crashes.* * RETURNS: length of data copied.** NOMANUAL*/int copyFromMbufs    (    char * 		pIoBuf,		/* buffer to copy mbufs into */    struct mbuf * 	pMbuf,		/* pointer to an mbuf chain */

⌨️ 快捷键说明

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