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

📄 if_ethersubr.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 2 页
字号:
		inq = &ipintrq;		break;	case ETHERTYPE_ARP:		schednetisr(NETISR_ARP);		inq = &arpintrq;		break;#endif#ifdef IPX	case ETHERTYPE_IPX:		schednetisr(NETISR_IPX);		inq = &ipxintrq;		break;#endif#ifdef NS	case 0x8137: /* Novell Ethernet_II Ethernet TYPE II */		schednetisr(NETISR_NS);		inq = &nsintrq;		break;#endif /* NS */#ifdef NETATALK        case ETHERTYPE_AT:                schednetisr(NETISR_ATALK);                inq = &atintrq1;                break;        case ETHERTYPE_AARP:		/* probably this should be done with a NETISR as well */                aarpinput((struct arpcom *)ifp, m); /* XXX */                return;#endif /* NETATALK */	default:#ifdef NS		checksum = mtod(m, ushort *);		/* Novell 802.3 */		if ((ether_type <= ETHERMTU) &&			((*checksum == 0xffff) || (*checksum == 0xE0E0))){			if(*checksum == 0xE0E0) {				m->m_pkthdr.len -= 3;				m->m_len -= 3;				m->m_data += 3;			}				schednetisr(NETISR_NS);				inq = &nsintrq;				break;		}#endif /* NS */#if defined (ISO) || defined (LLC) || defined(NETATALK)		if (ether_type > ETHERMTU)			goto dropanyway;		l = mtod(m, struct llc *);		switch (l->llc_dsap) {#ifdef NETATALK		case LLC_SNAP_LSAP:		    switch (l->llc_control) {		    case LLC_UI:			if (l->llc_ssap != LLC_SNAP_LSAP)			    goto dropanyway;				if (Bcmp(&(l->llc_snap_org_code)[0], at_org_code,				   sizeof(at_org_code)) == 0 &&			     ntohs(l->llc_snap_ether_type) == ETHERTYPE_AT) {			    inq = &atintrq2;			    m_adj( m, sizeof( struct llc ));			    schednetisr(NETISR_ATALK);			    break;			}			if (Bcmp(&(l->llc_snap_org_code)[0], aarp_org_code,				   sizeof(aarp_org_code)) == 0 &&			     ntohs(l->llc_snap_ether_type) == ETHERTYPE_AARP) {			    m_adj( m, sizeof( struct llc ));			    aarpinput((struct arpcom *)ifp, m); /* XXX */			    return;			}				    default:			goto dropanyway;		    }		    break;#endif /* NETATALK */#ifdef	ISO		case LLC_ISO_LSAP:			switch (l->llc_control) {			case LLC_UI:				/* LLC_UI_P forbidden in class 1 service */				if ((l->llc_dsap == LLC_ISO_LSAP) &&				    (l->llc_ssap == LLC_ISO_LSAP)) {					/* LSAP for ISO */					if (m->m_pkthdr.len > ether_type)						m_adj(m, ether_type - m->m_pkthdr.len);					m->m_data += 3;		/* XXX */					m->m_len -= 3;		/* XXX */					m->m_pkthdr.len -= 3;	/* XXX */					M_PREPEND(m, sizeof *eh, M_DONTWAIT);					if (m == 0)						return;					*mtod(m, struct ether_header *) = *eh;					IFDEBUG(D_ETHER)						printf("clnp packet");					ENDDEBUG					schednetisr(NETISR_ISO);					inq = &clnlintrq;					break;				}				goto dropanyway;			case LLC_XID:			case LLC_XID_P:				if(m->m_len < 6)					goto dropanyway;				l->llc_window = 0;				l->llc_fid = 9;				l->llc_class = 1;				l->llc_dsap = l->llc_ssap = 0;				/* Fall through to */			case LLC_TEST:			case LLC_TEST_P:			{				struct sockaddr sa;				register struct ether_header *eh2;				int i;				u_char c = l->llc_dsap;				l->llc_dsap = l->llc_ssap;				l->llc_ssap = c;				if (m->m_flags & (M_BCAST | M_MCAST))					bcopy((caddr_t)ac->ac_enaddr,					      (caddr_t)eh->ether_dhost, 6);				sa.sa_family = AF_UNSPEC;				sa.sa_len = sizeof(sa);				eh2 = (struct ether_header *)sa.sa_data;				for (i = 0; i < 6; i++) {					eh2->ether_shost[i] = c = eh->ether_dhost[i];					eh2->ether_dhost[i] =						eh->ether_dhost[i] = eh->ether_shost[i];					eh->ether_shost[i] = c;				}				ifp->if_output(ifp, m, &sa, NULL);				return;			}			default:				m_freem(m);				return;			}			break;#endif /* ISO */#ifdef LLC		case LLC_X25_LSAP:		{			if (m->m_pkthdr.len > ether_type)				m_adj(m, ether_type - m->m_pkthdr.len);			M_PREPEND(m, sizeof(struct sdl_hdr) , M_DONTWAIT);			if (m == 0)				return;			if ( !sdl_sethdrif(ifp, eh->ether_shost, LLC_X25_LSAP,					    eh->ether_dhost, LLC_X25_LSAP, 6,					    mtod(m, struct sdl_hdr *)))				panic("ETHER cons addr failure");			mtod(m, struct sdl_hdr *)->sdlhdr_len = ether_type;#ifdef LLC_DEBUG				printf("llc packet\n");#endif /* LLC_DEBUG */			schednetisr(NETISR_CCITT);			inq = &llcintrq;			break;		}#endif /* LLC */		dropanyway:		default:			m_freem(m);			return;		}#else /* ISO || LLC || NETATALK */	    m_freem(m);	    return;#endif /* ISO || LLC || NETATALK */	}	s = splimp();	if (IF_QFULL(inq)) {		IF_DROP(inq);		m_freem(m);	} else		IF_ENQUEUE(inq, m);	splx(s);}/* * Perform common duties while attaching to interface list */voidether_ifattach(ifp)	register struct ifnet *ifp;{	register struct ifaddr *ifa;	register struct sockaddr_dl *sdl;	ifp->if_type = IFT_ETHER;	ifp->if_addrlen = 6;	ifp->if_hdrlen = 14;	ifp->if_mtu = ETHERMTU;	if (ifp->if_baudrate == 0)	    ifp->if_baudrate = 10000000;	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;		}}static u_char ether_ipmulticast_min[6] = 	{ 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 };static u_char ether_ipmulticast_max[6] =	{ 0x01, 0x00, 0x5e, 0x7f, 0xff, 0xff };/* * 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 set_allmulti = 0;	int s = splimp();	switch (ifr->ifr_addr.sa_family) {	case AF_UNSPEC:		bcopy(ifr->ifr_addr.sa_data, addrlo, 6);		bcopy(addrlo, 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(ether_ipmulticast_min, addrlo, 6);			bcopy(ether_ipmulticast_max, addrhi, 6);                      set_allmulti = 1;		}		else {			ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo);			bcopy(addrlo, addrhi, 6);		}		break;#endif	default:		splx(s);		return (EAFNOSUPPORT);	}	/*	 * Verify that we have valid Ethernet multicast addresses.	 */	if ((addrlo[0] & 0x01) != 1 || (addrhi[0] & 0x01) != 1) {		splx(s);		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.	 */	enm = (struct ether_multi *)malloc(sizeof(*enm), M_IFMADDR, M_NOWAIT);	if (enm == NULL) {		splx(s);		return (ENOBUFS);	}	bcopy(addrlo, enm->enm_addrlo, 6);	bcopy(addrhi, 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);        if (set_allmulti)        	ac->ac_if.if_flags |= IFF_ALLMULTI;	/*	 * 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 unset_allmulti = 0;	int s = splimp();	switch (ifr->ifr_addr.sa_family) {	case AF_UNSPEC:		bcopy(ifr->ifr_addr.sa_data, addrlo, 6);		bcopy(addrlo, 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(ether_ipmulticast_min, addrlo, 6);			bcopy(ether_ipmulticast_max, addrhi, 6);                      unset_allmulti = 1;		}		else {			ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo);			bcopy(addrlo, addrhi, 6);		}		break;#endif	default:		splx(s);		return (EAFNOSUPPORT);	}	/*	 * Look up the address in our list.	 */	ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);	if (enm == NULL) {		splx(s);		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, M_IFMADDR);	ac->ac_multicnt--;	splx(s);      if (unset_allmulti)              ac->ac_if.if_flags &= ~IFF_ALLMULTI;	/*	 * Return ENETRESET to inform the driver that the list has changed	 * and its reception filter should be adjusted accordingly.	 */	return (ENETRESET);}SYSCTL_DECL(_net_link);SYSCTL_NODE(_net_link, IFT_ETHER, ether, CTLFLAG_RW, 0, "Ethernet");intether_ioctl(struct ifnet *ifp, int command, caddr_t data){	struct ifaddr *ifa = (struct ifaddr *) data;	struct ifreq *ifr = (struct ifreq *) data;	int error = 0;	switch (command) {	case SIOCSIFADDR:		ifp->if_flags |= IFF_UP;		switch (ifa->ifa_addr->sa_family) {#ifdef INET		case AF_INET:			ifp->if_init(ifp->if_softc);	/* before arpwhohas */			arp_ifinit((struct arpcom *)ifp, ifa);			break;#endif#ifdef IPX		/*		 * XXX - This code is probably wrong		 */		case AF_IPX:			{			register struct ipx_addr *ina = &(IA_SIPX(ifa)->sipx_addr);			struct arpcom *ac = (struct arpcom *) (ifp->if_softc);			if (ipx_nullhost(*ina))				ina->x_host =				    *(union ipx_host *) 			            ac->ac_enaddr;			else {				bcopy((caddr_t) ina->x_host.c_host,				      (caddr_t) ac->ac_enaddr,				      sizeof(ac->ac_enaddr));			}			/*			 * Set new address			 */			ifp->if_init(ifp->if_softc);			break;			}#endif#ifdef NS		/*		 * XXX - This code is probably wrong		 */		case AF_NS:		{			register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr);			struct arpcom *ac = (struct arpcom *) (ifp->if_softc);			if (ns_nullhost(*ina))				ina->x_host =				    *(union ns_host *) (ac->ac_enaddr);			else {				bcopy((caddr_t) ina->x_host.c_host,				      (caddr_t) ac->ac_enaddr,				      sizeof(ac->ac_enaddr));			}			/*			 * Set new address			 */			ifp->if_init(ifp->if_softc);			break;		}#endif		default:			ifp->if_init(ifp->if_softc);			break;		}		break;	case SIOCGIFADDR:		{			struct sockaddr *sa;			sa = (struct sockaddr *) & ifr->ifr_data;			bcopy(((struct arpcom *)ifp->if_softc)->ac_enaddr,			      (caddr_t) sa->sa_data, ETHER_ADDR_LEN);		}		break;	case SIOCSIFMTU:		/*		 * Set the interface MTU.		 */		if (ifr->ifr_mtu > ETHERMTU) {			error = EINVAL;		} else {			ifp->if_mtu = ifr->ifr_mtu;		}		break;	}	return (error);}

⌨️ 快捷键说明

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