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

📄 etherlib.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 2 页
字号:
/* etherLib.c - Ethernet raw I/O routines and hooks *//* Copyright 1984 - 1999 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------02q,29mar99,dat  documentation, removed refs to obsolete drivers (26119)02q,16mar99,spm  recovered orphaned code from tor1_0_1.sens1_1 (SPR #25770)02p,06oct98,spm  fixed buffer overrun in END input hook routine (SPR #22363)02o,27aug98,n_s  set unit number in fakeIF for endEtherInputHook. spr #22222.02n,14dec97,jdi  doc: cleanup.02m,08dec97,gnn  END code review fixes.02l,28oct97,gnn  fixed SPR 9606, caused by problems in the endEtherInputHook02k,27oct97,spm  corrected input hooks to handle mixed device types; added                 support for multiple hooks per END device02j,25oct97,kbw  making minor man page fixes02i,17oct97,vin  changes reflecting protocol recieveRtn changes.02h,09oct97,spm  fixed memory leak in END driver input hook handler02g,03oct97,gnn  removed necessity for endDriver global02f,25sep97,gnn  SENS beta feedback fixes02e,26aug97,spm  removed compiler warnings (SPR #7866)02d,19aug97,gnn  changes due to new buffering scheme.02c,12aug97,gnn  changes necessitated by MUX/END update.02b,02jun97,spm  corrected invalid mem width causing m_devget panic (SPR #8640)02a,15may97,gnn  removed some warnings.                 modified muxUnbind.01z,20mar97,spm  fixed memory leak in Ethernet hook routines01y,21jan97,gnn  changed MUX_PROTO_PROMISC to MUX_PROTO_SNARF.01x,17dec96,gnn  added code to handle the new etherHooks and END stuff.01w,22oct96,gnn  added etherTypeGet routine to heuristically figure out the                 proper ethertype for a packet given a pointer to it.                 This handles 802.3 addressing.01v,01nov95,jdi  doc: updated list of supported drivers (SPR 4545).01u,20jan93,jdi  documentation cleanup for 5.1.01t,13nov92,dnw  added includes of unixLib.h and hostLib.h01s,15aug92,elh  fixed bug in etherAddrResolve.01r,26may92,rrr  the tree shuffle		  -changed includes to have absolute path from h/01q,19nov91,rrr  shut up some ansi warnings.01p,15oct91,elh  added ether{Input,Output}HookDelete01o,04oct91,rrr  passed through the ansification filter                  -changed functions to ansi style		  -changed includes to have absolute path from h/		  -changed copyright notice01n,30apr91,jdi	 documentation tweaks.01m,05apr91,jdi	 documentation -- removed header parens and x-ref numbers;		 doc review by dnw.01l,04feb91,jaa	 documentation cleanup.01k,05oct90,dnw  documentation tweaks.01j,11apr90,hjb  de-linted.01i,19mar90,jdi  documentation cleanup.01h,20aug88,gae  documentation.01g,22jun88,dnw  name tweaks.01f,30may88,dnw  changed to v4 names.01e,05jan88,rdc  added include of systm.h01d,18nov87,ecs  documentation.01c,11nov87,dnw  added etherAddOutputHook().		 changed calling sequence to input hook routine.01b,05nov87,jlf  moved from netsrc to src		 documentation01a,28aug87,dnw  written*//*DESCRIPTIONThis library provides utilities that give direct access to Ethernet packets.Raw packets can be output directly to an interface using etherOutput().Incoming and outgoing packets can be examined or processed using the hooksetherInputHookAdd() and etherOutputHookAdd().  The input hook can be used toreceive raw packets that are not part of any of the supported networkprotocols.  The input and output hooks can also be used to build networkmonitoring and testing tools.Normally, the network should be accessed through the higher-level socketinterface provided in sockLib.  The routines in etherLib should rarely,if ever, be necessary for applications.CAVEATThe following VxWorks network drivers support both the input-hook andoutput-hook routines:    if_cpm - Motorola MC68EN360 QUICC network interface driver     if_eex - Intel EtherExpress 16     if_ei - Intel 82596 ethernet driver    if_elc - SMC 8013WC Ethernet driver    if_elt - 3Com 3C509 Ethernet driver    if_ene - Novell/Eagle NE2000 network driver    if_fn - Fujitsu MB86960 NICE Ethernet driver    if_ln - Advanced Micro Devices Am7990 LANCE Ethernet driver    if_sm - shared memory backplane network interface driver    if_sn - National Semiconductor DP83932B SONIC Ethernet driver    if_ultra - SMC Elite Ultra Ethernet network interface driver    if_gn - generic MUX interface layerThe following drivers support only the input-hook routines:    if_nic - National Semiconductor SNIC Chip (for HKV30)    if_sl - Serial Line IP (SLIP) network interface driverThe following drivers support only the output-hook routines:    if_ulip - network interface driver for User Level IP (VxSim)The following drivers do not support either the input-hook or output-hookroutines:    if_loop - software loopback network interface driverINCLUDE FILES: etherLib.hSEE ALSO:.pG "Network"*/#include "vxWorks.h"#include "lstLib.h"#include "net/mbuf.h"#include "net/if.h"#include "net/route.h"#include "netinet/if_ether.h"#include "net/if_llc.h"#include "net/systm.h"#include "inetLib.h"#include "net/unixLib.h"#include "hostLib.h"#include "end.h"#include "muxLib.h"#include "netBufLib.h"IMPORT unsigned char etherbroadcastaddr [];FUNCPTR etherInputHookRtn  = NULL;	/* NULL = none */FUNCPTR etherOutputHookRtn = NULL;	/* NULL = none */LOCAL BOOL endEtherInputHookRtn (void * pCookie, long type, M_BLK_ID pMblk,                                  LL_HDR_INFO * pLinkHdrInfo, void * pSpare);LOCAL BOOL etherInputHook (struct ifnet * pIf, char * buffer, int length);LOCAL BOOL etherOutputHook (struct ifnet * pIf, char * buffer, int length);/* locals */LOCAL LIST inputHookList;LOCAL LIST outputHookList;LOCAL BOOL etherInputHookActive = FALSE;typedef struct hook_entry    {    NODE node; /* We are contained in a linked list. */    FUNCPTR routine;    void* cookie; /* For use in END based systems. */    char name[8]; /* For use in END based systems. */    int unit;     /* For us in END based stuff */    } HOOK_ENTRY;/* defints */#define STREQ(A, B) (strcmp(A, B) == 0 ? 1 : 0)/* RFC 894 Header. */typedef struct enet_hdr    {    char dst [6];    char src [6];    USHORT type;    } ENET_HDR;/********************************************************************************* etherOutput - send a packet on an Ethernet interface** This routine sends a packet on the specified Ethernet interface by* calling the interface's output routine directly.** The first argument <pIf> is a pointer to a variable of type `struct ifnet'* which contains some useful information about the network interface.  A* routine named ifunit() can retrieve this pointer from the system in the* following way:* .CS*     struct ifnet *pIf;*     ...*     pIf = ifunit ("ln0");* .CE* If ifunit() returns a non-NULL pointer, it is a valid pointer to* the named network interface device structure of type `struct ifnet'.* In the above example, <pIf> points to the data structure that* describes the first LANCE network interface device if ifunit() is* successful.** The second argument <pEtherHeader> should contain a valid Ethernet address* of the machine for which the message contained in the argument <pData> is* intended.  If the Ethernet address of this machine is fixed and well-known* to the user, filling in the structure `ether_header' can be accomplished by* using bcopy() to copy the six-byte Ethernet address into the `ether_dhost'* field of the structure `ether_header'.  Alternatively, users can make use of* the routine etherAddrResolve() which will use ARP (Address Resolution* Protocol) to resolve the Ethernet address for a specified Internet* address.** RETURNS: OK, or ERROR if the routine runs out of mbufs.** SEE ALSO:* etherAddrResolve()*/STATUS etherOutput    (    struct ifnet *pIf,                  /* interface on which to send */    struct ether_header *pEtherHeader,  /* Ethernet header to send    */    FAST char *pData,                   /* data to send               */    FAST int dataLength                 /* # of bytes of data to send */    )    {    FAST struct mbuf *m;	/* ptr to current mbuf piece */    struct sockaddr dst;	/* destination address */    int oldLevel;    /* construct dst sockaddr required by interface output routine;     * all Ethernet drivers interpret address family AF_UNSPEC as raw     * Ethernet header (this is used by arp) */    dst.sa_family = AF_UNSPEC;    dst.sa_len = sizeof(dst);    *((struct ether_header *) dst.sa_data) = *pEtherHeader;    if ((m = bcopy_to_mbufs (pData, dataLength, 0, pIf, NONE)) == NULL)	return (ERROR);    /* call interface's output routine */    oldLevel = splnet ();    (* pIf->if_output) (pIf, m, &dst, (struct rtentry *)NULL);    splx (oldLevel);    return (OK);    }/********************************************************************************* etherInputHookAdd - add a routine to receive all Ethernet input packets** This routine adds a hook routine that will be called for every Ethernet* packet that is received.** The calling sequence of the input hook routine is:* .CS*     BOOL inputHook*          (*          struct ifnet *pIf,    /@ interface packet was received on @/*          char         *buffer, /@ received packet @/*          int          length   /@ length of received packet @/*          )* .CE* The hook routine should return TRUE if it has handled the input packet and* no further action should be taken with it.  It should return FALSE if it* has not handled the input packet and normal processing (for example, * Internet) should take place.** The packet is in a temporary buffer when the hook routine is called.* This buffer will be reused upon return from the hook.  If the hook* routine needs to retain the input packet, it should copy it elsewhere.** IMPLEMENTATION* A call to the function pointed to by the global function pointer* `etherInputHookRtn' should be invoked in the receive routine of every* network driver providing this service.  For example:* .CS*     ...*     #include "etherLib.h"*     ...*     xxxRecv ()*     ...*     /@ call input hook if any @/**         if ((etherInputHookRtn != NULL) &&*             (* etherInputHookRtn) (&ls->ls_if, (char *)eh, len))*             {*             return; /@ input hook has already processed this packet @/*             }* .CE** RETURNS: OK, always.*/STATUS etherInputHookAdd    (    FUNCPTR inputHook,   /* routine to receive Ethernet input */    char* pName,         /* name of device if MUX/END is being used */    int unit             /* unit of device if MUX/END is being used */    )    {    HOOK_ENTRY *pHookEnt;    HOOK_ENTRY *pHookCurr;    END_OBJ * 	pEnd;    if (pName != NULL) /* We are dealing with an END. */        {        if (etherInputHookActive == FALSE)            {            if (etherInputHookRtn == NULL)                lstInit (&inputHookList);            etherInputHookActive = TRUE;            }        /* Check for duplicate hook routine. */        for (pHookCurr = (HOOK_ENTRY *)lstFirst(&inputHookList);              pHookCurr != NULL;             pHookCurr = (HOOK_ENTRY *)lstNext(&pHookCurr->node))            {            if (STREQ(pHookCurr->name, pName) && (pHookCurr->unit == unit))                if (pHookCurr->routine == inputHook)                    return (ERROR);            }        pHookEnt = malloc (sizeof (HOOK_ENTRY));        if (pHookEnt == NULL)            return (ERROR);        pEnd = endFindByName (pName, unit);        if (pEnd == NULL) 		/* No such device. */            return (ERROR);        if (! (pEnd->snarfProto))     /* Bind protocol if not present. */            {            pHookEnt->cookie = muxBind (pName, unit,                                       endEtherInputHookRtn, NULL, NULL, NULL,                                      MUX_PROTO_SNARF, "etherInputHook", NULL);            if (pHookEnt->cookie == NULL)                {                free (pHookEnt);                return (ERROR);                }            }        strcpy (pHookEnt->name, pName);        pHookEnt->unit = unit;        pHookEnt->routine = inputHook;        lstAdd (&inputHookList, &pHookEnt->node);        }    else               /* Old style driver. */        {        pHookEnt = malloc(sizeof(HOOK_ENTRY));        if (pHookEnt == NULL)            return (ERROR);        if (etherInputHookRtn == NULL)            {            etherInputHookRtn = etherInputHook;            if (!etherInputHookActive)                lstInit (&inputHookList);            }        pHookEnt->routine = inputHook;        lstAdd(&inputHookList, &pHookEnt->node);        }    return (OK);    }/********************************************************************************* etherInputHookDelete - delete a network interface input hook routine** This routine deletes a network interface input hook.** RETURNS: N/A*/void etherInputHookDelete    (    FUNCPTR inputHook,    char *pName,    int unit    )    {    HOOK_ENTRY *pHookEnt;    extern LIST inputHookList;    NODE index;    if (pName != NULL)                       /* END case */        {        for (pHookEnt = (HOOK_ENTRY *)lstFirst(&inputHookList);             pHookEnt != NULL;             pHookEnt = (HOOK_ENTRY *)lstNext(&index))            {            index = pHookEnt->node;            if (STREQ(pHookEnt->name, pName) &&                (pHookEnt->routine == inputHook) &&                (pHookEnt->unit == unit))                {                if (lstCount (&inputHookList) == 1)                    {                    muxUnbind(pHookEnt->cookie, MUX_PROTO_SNARF,                              endEtherInputHookRtn);                    }

⌨️ 快捷键说明

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