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

📄 if_subr.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* if_subr.c - common routines for network interface drivers *//* Copyright 1990 - 2002 Wind River Systems, Inc. */#include "copyright_wrs.h"/* * Copyright (c) 1982, 1989, 1993 *	The Regents of the University of California.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *	@(#)if_ethersubr.c	8.1 (Berkeley) 6/10/93 *//*modification history--------------------01q,23may02,vvv  removed unnecessary m_copy from ether_output (SPR #77775)01p,22apr02,wap  call ip_mloopback() rather than calling looutput() directly                 (SPR #72246)01o,15apr02,wap  reinstate netJobAdd removal changes01n,29mar02,wap  back out the previous change (needs more investigation)01m,21mar02,rae  remove unecessary netJobAdd() SPR #01l,21mar02,vvv  updated man page for copyFromMbufs (SPR #20787)01k,01nov01,rae  fixed compile warnings, corrected WV event (SPR #71284)01j,12oct01,rae  merge from truestack ver 01o, base 01h (SPR #69112 etc.)01i,17oct00,spm  updated ether_attach to report memory allocation failures01h,21aug98,n_s  updated if_omcast in ether_output () if_noproto in                  do_protocol_with_type (). spr2107401f,19sep97,vin  modified build_cluster to incorporate cluster blks,		 removed pointers to refcounts.01g,11aug97,vin  changed mBlkGet to use _pNetDpool.01e,10jul97,vin  removed unsupported revarpinput() code.01f,05jun97,vin  corrected processing for promiscuous interfaces in		 ether_input.01e,02jun97,spm  updated man page for bcopy_to_mbufs()01d,15may97,vin  reworked ether_input, cleanup, added copyFromMbufs().		 removed support for check_trailer().01c,16dec96,vin  removed unnecessary ntohs(). 01b,13nov96,vin  replaced m_gethdr with mBlkGet() in buildCluster.01a,03mar96,vin  created from BSD4.4 stuff,integrated with 02p of if_subr.c*/#include "vxWorks.h"#include "stdlib.h"#include "stdio.h"#include "tickLib.h"#include "logLib.h"#include "errno.h"#include "netinet/in.h"#include "netinet/in_systm.h"#include "netinet/in_var.h"#include "netinet/ip.h"#include "net/if.h"#include "net/if_arp.h"#include "netinet/if_ether.h"#include "net/if_subr.h"#include "netinet/in_var.h"#include "netinet/ip_var.h"    /* for ipintr() prototype */#include "net/mbuf.h"#include "net/route.h"#include "net/if_llc.h"#include "net/if_dl.h"#include "net/if_types.h"#include "lstLib.h"#include "netLib.h"#include "muxLib.h"#include "memPartLib.h"#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET#include "wvNetLib.h"#endif /* INCLUDE_WVNET */#endif#ifdef VIRTUAL_STACK#include "netinet/vsLib.h"#endiftypedef struct net_type    {    NODE     	node;    FUNCPTR     inputRtn;    int     	etherType;    } NET_TYPE;#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* Set common fields of event identifiers for this module. */LOCAL UCHAR wvNetModuleId = WV_NET_IFSUBR_MODULE;   /* Value for if_subr.c */LOCAL UCHAR wvNetLocalFilter = WV_NET_NONE;     /* Available event filter */LOCAL ULONG wvNetEventId;       /* Event identifier: see wvNetLib.h */#endif    /* INCLUDE_WVNET */#endif/* externs */#ifndef VIRTUAL_STACKextern	struct ifnet loif;extern  void ip_mloopback(struct ifnet *, struct mbuf *, struct sockaddr_in *,                          struct rtentry *rt);#endif /* VIRTUAL_STACK */u_char	etherbroadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };u_char	ether_ipmulticast_min[6] = { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 };u_char	ether_ipmulticast_max[6] = { 0x01, 0x00, 0x5e, 0x7f, 0xff, 0xff };#define senderr(e) { error = (e); goto bad;}LOCAL LIST netTypeList;/* * Ethernet output routine. * Encapsulate a packet of type family for the local net. * Use trailer local net encapsulation if enough data in first * packet leaves a multiple of 512 bytes of data in remainder. * Assumes that ifp is actually pointer to arpcom structure. */intether_output(ifp, m0, dst, rt0)	register struct ifnet *ifp;	struct mbuf *m0;	struct sockaddr *dst;	struct rtentry *rt0;{	u_short etype;	int s, error = 0; 	u_char edst[6];	register struct mbuf *m = m0;	register struct rtentry *rt;	register struct ether_header *eh;	int off, len = m->m_pkthdr.len;	struct arpcom *ac = (struct arpcom *)ifp;	if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))            {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_CRITICAL event */            WV_NET_EVENT_1 (NET_CORE_EVENT, WV_NET_CRITICAL, 2, 3,                            WV_NETEVENT_ETHEROUT_IFDOWN, WV_NET_SEND, ifp)#endif  /* INCLUDE_WVNET */#endif            senderr(ENETDOWN);            }	ifp->if_lastchange = tickGet();	if ((rt = rt0)) {		if ((rt->rt_flags & RTF_UP) == 0) {			if ((rt0 = rt = rtalloc1(dst, 1)))				rt->rt_refcnt--;			else {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_CRITICAL event */            WV_NET_DSTADDROUT_EVENT_1 (NET_CORE_EVENT, WV_NET_CRITICAL, 4, 5,                            ((struct sockaddr_in *)dst)->sin_addr.s_addr,                            WV_NETEVENT_ETHEROUT_NOROUTE, WV_NET_SEND,                            ((struct sockaddr_in *)dst)->sin_addr.s_addr)#endif  /* INCLUDE_WVNET */#endif                             senderr(EHOSTUNREACH);                             }		}		if (rt->rt_flags & RTF_GATEWAY) {			if (rt->rt_gwroute == 0)				goto lookup;			if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {				rtfree(rt); rt = rt0;			lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1);				if ((rt = rt->rt_gwroute) == 0) {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_CRITICAL event */            WV_NET_DSTADDROUT_EVENT_1 (NET_CORE_EVENT, WV_NET_CRITICAL, 4, 5,                       ((struct sockaddr_in *)rt->rt_gateway)->sin_addr.s_addr,                                    WV_NETEVENT_ETHEROUT_NOROUTE, WV_NET_SEND,                       ((struct sockaddr_in *)rt->rt_gateway)->sin_addr.s_addr)#endif  /* INCLUDE_WVNET */#endif                                    senderr(EHOSTUNREACH);                                }			}		}		if (rt->rt_flags & RTF_REJECT)			if (rt->rt_rmx.rmx_expire == 0 ||			    tickGet() < rt->rt_rmx.rmx_expire) {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_CRITICAL event */        WV_NET_EVENT_0 (NET_CORE_EVENT, WV_NET_CRITICAL, 5, 6,                        WV_NETEVENT_ETHEROUT_RTREJECT, WV_NET_SEND)#endif  /* INCLUDE_WVNET */#endif                            senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);                            }	}	switch (dst->sa_family) {#ifdef INET	case AF_INET:		if (!arpresolve(ac, rt, m, dst, edst))			return (0);	/* if not yet resolved */		/* If broadcasting on a simplex interface, loopback a copy */		if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))			ip_mloopback (ifp, m, (struct sockaddr_in *)dst,				      (struct rtentry*)rt);		off = m->m_pkthdr.len - m->m_len;		etype = ETHERTYPE_IP;		break;#endif	case AF_UNSPEC:		eh = (struct ether_header *)dst->sa_data; 		bcopy((caddr_t)eh->ether_dhost, (caddr_t)edst, sizeof (edst));		etype = eh->ether_type;		break;	default:		printf("%s%d: can't handle af%d\n", ifp->if_name, ifp->if_unit,			dst->sa_family);#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_ERROR event */                WV_NET_EVENT_1 (NET_CORE_EVENT, WV_NET_ERROR, 3, 7,                                WV_NETEVENT_ETHEROUT_AFNOTSUPP, WV_NET_SEND,                                dst->sa_family)#endif  /* INCLUDE_WVNET */#endif		senderr(EAFNOSUPPORT);	}	/*	 * Add local net header.  If no space in first mbuf,	 * allocate another.	 */	M_PREPEND(m, sizeof (struct ether_header), M_DONTWAIT);	if (m == 0)            {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_CRITICAL event */            WV_NET_EVENT_1 (NET_CORE_EVENT, WV_NET_CRITICAL, 3, 4,                            WV_NETEVENT_ETHEROUT_NOBUFS, WV_NET_SEND, ifp)#endif  /* INCLUDE_WVNET */#endif            senderr(ENOBUFS);            }	eh = mtod(m, struct ether_header *);	etype = htons(etype);	bcopy((caddr_t)&etype,(caddr_t)&eh->ether_type,		sizeof(eh->ether_type)); 	bcopy((caddr_t)edst, (caddr_t)eh->ether_dhost, sizeof (edst)); 	bcopy((caddr_t)ac->ac_enaddr, (caddr_t)eh->ether_shost,	    sizeof(eh->ether_shost));	s = splimp();	/*	 * Queue message on interface, and start output if interface	 * not yet active.	 */	if (IF_QFULL(&ifp->if_snd)) {		IF_DROP(&ifp->if_snd);		splx(s);#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_CRITICAL event */            WV_NET_EVENT_1 (NET_CORE_EVENT, WV_NET_CRITICAL, 3, 4,                            WV_NETEVENT_ETHEROUT_NOBUFS, WV_NET_SEND, ifp)#endif  /* INCLUDE_WVNET */#endif		senderr(ENOBUFS);	}	IF_ENQUEUE(&ifp->if_snd, m);	if ((ifp->if_flags & IFF_OACTIVE) == 0)		(*ifp->if_start)(ifp);	splx(s);	ifp->if_obytes += len + sizeof (struct ether_header);	if (m->m_flags & M_MCAST || m->m_flags & M_BCAST)		ifp->if_omcasts++;#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_NOTICE event */        WV_NET_EVENT_2 (NET_CORE_EVENT, WV_NET_NOTICE, 3, 12,                        WV_NETEVENT_ETHEROUT_FINISH, WV_NET_SEND, ifp, error)#endif  /* INCLUDE_WVNET */#endif	return (error);bad:	if (m)		m_freem(m);	return (error);}/********************************************************************************* do_protocol - check the link-level type field and process IP and ARP data** This routine must not be called at interrupt level.* Process a received Ethernet packet;* the packet is in the mbuf chain m without* the ether header, which is provided separately.** NOMANUAL*/voidether_input(ifp, eh, m)	struct ifnet *ifp;	register struct ether_header *eh;	struct mbuf *m;{	u_short 		etype;	struct arpcom *		ac = (struct arpcom *)ifp;#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_NOTICE event */        WV_NET_EVENT_1 (NET_CORE_EVENT, WV_NET_NOTICE, 4, 13,                        WV_NETEVENT_ETHERIN_START, WV_NET_RECV, ifp)#endif  /* INCLUDE_WVNET */#endif	if ((ifp->if_flags & IFF_UP) == 0) {		m_freem(m);		return;	}	ifp->if_lastchange = tickGet();	ifp->if_ibytes += m->m_pkthdr.len + sizeof (*eh);	if (eh->ether_dhost[0] & 1) {		if (bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,		    sizeof(etherbroadcastaddr)) == 0)			m->m_flags |= M_BCAST;		else			m->m_flags |= M_MCAST;		ifp->if_imcasts++;	}        if (ifp->if_flags & IFF_PROMISC)            {            /*             * do not hand over the non multicast packets to the ip stack             * if they are not destined to us, orelse it confuses the             * ip forwarding logic and keeps sending unnecessary redirects.             * If packets destined for other hosts have to be snooped they             * have to done through driver level hooks.             */                        if (!(m->m_flags & (M_BCAST | M_MCAST)))                {                if (bcmp ((caddr_t)ac->ac_enaddr, (caddr_t)eh->ether_dhost,                          sizeof(eh->ether_dhost)) != 0)                    {                    m_freem (m); 	/* free the packet chain */                    return;                     }                }            }        

⌨️ 快捷键说明

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