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

📄 ethernet.c

📁 完整的Bell实验室的嵌入式文件系统TFS
💻 C
📖 第 1 页 / 共 3 页
字号:
/* ethernet.c: *  This code supports most of the generic ethernet/IP/ARP/UDP stuff. * *  General notice: *  This code is part of a boot-monitor package developed as a generic base *  platform for embedded system designs.  As such, it is likely to be *  distributed to various projects beyond the control of the original *  author.  Please notify the author of any enhancements made or bugs found *  so that all may benefit from the changes.  In addition, notification back *  to the author will allow the new user to pick up changes that may have *  been made by other users after this version of the code was distributed. * *  Note1: the majority of this code was edited with 4-space tabs. *  Note2: as more and more contributions are accepted, the term "author" *         is becoming a mis-representation of credit. * *  Original author:    Ed Sutter *  Email:              esutter@lucent.com *  Phone:              908-582-2351 */#include "config.h"#include "endian.h"#include "stddefs.h"#include "genlib.h"#if INCLUDE_ETHERNET#include "cpuio.h"#include "ether.h"#include "monflags.h"#include "cli.h"void ShowEthernetStats(void);void processMONCMD(struct ether_header *,ushort);int  SendIPMonChar(uchar,int);#if INCLUDE_DHCPBOOT#define dhcpStateCheck()    dhcpStateCheck()#define dhcpDisable()       dhcpDisable()#define ShowDhcpStats()     ShowDhcpStats()#else#define dhcpStateCheck()#define dhcpDisable()#define ShowDhcpStats()#endif#if INCLUDE_TFTP#define tftpStateCheck()    tftpStateCheck()#define tftpInit()          tftpInit()#define ShowTftpStats()     ShowTftpStats()#else#define tftpStateCheck()#define tftpInit()#define ShowTftpStats()#endifchar *Etheradd, *IPadd;     /* Pointers to ascii addresses */uchar BinIpAddr[4];         /* Space for binary IP address */uchar BinEnetAddr[6];       /* Space for binary MAC address */int EtherVerbose;           /* Verbosity flag (see ether.h). */int EtherIsActive;          /* Non-zero if ethernet is up. */int EtherIPERRCnt;          /* Number of IP errors detected. */int EtherUDPERRCnt;         /* Number of UDP errors detected. */int EtherXFRAMECnt;         /* Number of packets transmitted. */int EtherRFRAMECnt;         /* Number of packets received. */int EtherPollNesting;       /* Incremented when pollethernet() is called. */int MaxEtherPollNesting;    /* High-warter mark of EtherPollNesting. */int IPMonCmdActive;         /* Set if MONCMD is in progress. */ushort  UniqueIpId;struct  ether_header *IPMonCmdHdr;/* Ports used by the monitor have defaults, but can be redefined using * shell variables: */ushort  MoncmdPort;         /* shell var: MCMDPORT */ushort  DhcpClientPort;     /* shell var: DCLIPORT */ushort  DhcpServerPort;     /* shell var: DSRVPORT */ushort  TftpPort;           /* shell var: TFTPPORT */ushort  TftpSrcPort;        /* shell var: TFTPPORT */uchar BroadcastAddr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };struct  pinfo {    int pnum;    char    *pname;} protocols[] = {        { IP_IP,        "IP" },        { IP_ICMP,  "ICMP" },        { IP_IGMP,  "IGMP" },        { IP_GGP,       "GGP" },        { IP_TCP,       "TCP" },        { IP_PUP,       "PUP" },        { IP_UDP,       "UDP" },        { 0,0 },};char *EtherHelp[] = {    "Ethernet interface",    "-[ps:v:V] {on | off | stat}",    "Options...",    " -p {1|0}     promiscuous mode (1=on)",#ifdef SNOOP_ENABLED    " -s {MAC}     print all packets to/from MAC (snoop)",#endif    " -t           self-test ethernet interface",    " -v {flgs}    enable specific verbosity...",    "    a: enable ARP trace",    "    c: print csum errmsg",    "    C: dump csum errpkt",    "    d: enable DHCP trace",    "    i: incoming packets (minus broadcast)",    "    I: incoming packets (including broadcast)",    "    o: outgoing packets",    "    p: phy r/w accesses",    "    t: enable TFTP trace",    "    x: enable hex dump (requires i,I or o)",    "    X: same as 'x' plus ascii",    " -V        full verbosity (same as -v Iodtx)",    0};intEther(int argc,char *argv[]){    int i, len, opt;    /* Set up some defaults: */    EtherVerbose = 0;    while ((opt=getopt(argc,argv,"p:s:tv:V")) != -1) {        switch(opt) {        case 'p':   /* Promiscuous mode: accept all packets */            if (*optarg == '1')                enablePromiscuousReception();            else                disablePromiscuousReception();            return(CMD_SUCCESS);#ifdef SNOOP_ENABLED        case 's':            if (EtherToBin(optarg,snoopInfo.mac) < 0)                return(CMD_FAILURE);            enablePromiscuousReception();            snoopInfo.on = 1;            break;#endif        case 't':            enselftest(1);            return(CMD_SUCCESS);        case 'V':            EtherVerbose = SHOW_ALL;            break;        case 'v':            len = strlen(optarg);            for(i=0;i<len;i++) {                switch(optarg[i]) {                case 'a':                    EtherVerbose |= SHOW_ARP;                    EtherVerbose |= SHOW_BROADCAST;                    break;                case 'c':                    EtherVerbose |= SHOW_BADCSUM;                    break;                case 'C':                    EtherVerbose |= SHOW_BADCSUM;                    EtherVerbose |= SHOW_BADCSUMV;                    break;                case 'i':                    EtherVerbose |= SHOW_INCOMING;                    break;                case 'I':                    EtherVerbose |= SHOW_INCOMING;                    EtherVerbose |= SHOW_BROADCAST;                    break;                case 'o':                    EtherVerbose |= SHOW_OUTGOING;                    break;                case 'p':                    EtherVerbose |= SHOW_PHY;                    break;                case 'd':                    EtherVerbose |= SHOW_DHCP;                    break;                case 't':                    EtherVerbose |= SHOW_TFTP;                    break;                case 'x':                    EtherVerbose |= SHOW_HEX;                    break;                case 'X':                    EtherVerbose |= SHOW_HEX;                    EtherVerbose |= SHOW_ASCII;                    break;                default:                    printf("Bad 'v' arg\n");                    return(CMD_PARAM_ERROR);                }            }            break;        default:            return(CMD_PARAM_ERROR);        }    }    if (argc != optind+1) {        printf("Ethernet interface currently %sabled.\n",            EtherIsActive ? "en" : "dis");        return(CMD_SUCCESS);    }    if (!strcmp(argv[optind],"off")) {        enreset();        EtherIsActive = 0;        return(CMD_SUCCESS);    }    else if (!strcmp(argv[optind],"stat")) {        ShowEthernetStats();        ShowEtherdevStats();        ShowDhcpStats();        ShowTftpStats();        return(CMD_SUCCESS);    }    else if (strcmp(argv[optind],"on"))        return(CMD_PARAM_ERROR);    EthernetStartup(EtherVerbose,0);    return(CMD_SUCCESS);}voidShowEthernetStats(void){    printf("Ethernet currently %s\n",EtherIsActive ? "active" : "off");    printf("Transmitted frames:      %d\n",EtherXFRAMECnt);    printf("Received frames:         %d\n",EtherRFRAMECnt);    printf("IP hdr cksum errors:     %d\n",EtherIPERRCnt);    printf("UDP pkt cksum errors:    %d\n",EtherUDPERRCnt);    printf("Max pollethernet nest:   %d\n",MaxEtherPollNesting);}voidDisableEthernet(void){    EtherIsActive = 0;    IPMonCmdActive = 0;    DisableEtherdev();}intEthernetStartup(int verbose, int justreset){    char *ipa;    /* Initialize the retransmission delay calculator: */    RetransmitDelay(DELAY_INIT_DHCP);    EtherIPERRCnt = 0;    EtherXFRAMECnt = 0;    EtherRFRAMECnt = 0;    EtherUDPERRCnt = 0;    IPMonCmdActive = 0;    EtherPollNesting = 0;    EtherVerbose = verbose;    MaxEtherPollNesting = 0;    DHCPState = DHCPSTATE_NOTUSED;    /* Setup all the IP addresses used by the monitor... */    if (getAddresses() == -1)        return(-1);    /* If, after having set up all addresses, the content of the IPADD     * shell variable is 0.0.0.0, then don't startup ethernet, just return     * here.     */    ipa = getenv("IPADD");    if (ipa) {        if (!strcmp(ipa,"0.0.0.0"))            return(-1);    }    else        return(-1);    /* Call device specific startup code: */    EtherdevStartup(verbose);    /* Initialize some TFTP state... */    tftpInit();#if INCLUDE_DHCPBOOT    /* If EthernetStartup is called as a result of anything other than a     * target reset, don't startup any DHCP/BOOTP transaction...     */    if (!justreset)        dhcpDisable();#endif    EtherIsActive = 1;    return(0);}/* pollethernet(): *  Called at a few critical points in the monitor code to poll the *  ethernet device and keep track of the state of DHCP and TFTP. */intpollethernet(void){    int pcnt;    if ((!EtherIsActive) || (EtherPollNesting > 4))        return(0);    EtherPollNesting++;    if (EtherPollNesting > MaxEtherPollNesting)        MaxEtherPollNesting = EtherPollNesting;    pcnt = polletherdev();    dhcpStateCheck();    tftpStateCheck();    EtherPollNesting--;    return(pcnt);}/* getAddresses(): * Try getting ether/ip addresses from environment. * If not there, try getting them from some target-specific interface. * If not there, then get them from raw flash. * If not there, just use the hard-coded default. * Also, load all port numbers from shell variables, else default. * * Discussion regarding etheraddr[] and ipaddr[]... * The purpose of these two arrays is to provide a point in flash that is  * initialized to 0xff by the code (see reset.s).  This then allows some * other mechanism (bed of nails, etc..) to program these locations to some * other non-0xff value.  It is one of the alternatives provided by the * monitor code for storage of IP and MAC. */intgetAddresses(void){    char    *mcmdPort, *dcliPort, *dsrvPort, *tftpPort;    /* Set up port numbers: */    mcmdPort = getenv("MCMDPORT");    dcliPort = getenv("DCLIPORT");    dsrvPort = getenv("DSRVPORT");    tftpPort = getenv("TFTPPORT");    if (mcmdPort)        MoncmdPort = (ushort)strtol(mcmdPort,0,0);    else        MoncmdPort = IPPORT_MONCMD;    if (dcliPort)        DhcpClientPort = (ushort)strtol(dcliPort,0,0);    else        DhcpClientPort = IPPORT_DHCP_CLIENT;    if (dsrvPort)        DhcpServerPort = (ushort)strtol(dsrvPort,0,0);    else        DhcpServerPort = IPPORT_DHCP_SERVER;    if (tftpPort)        TftpPort = (ushort)strtol(tftpPort,0,0);    else        TftpPort = IPPORT_TFTP;             /* 69   */    TftpSrcPort = IPPORT_TFTPSRC;           /* 8888 */    /* Retrieve MAC address and store in shell variable ETHERADD...     * First see if the shell variable is already loaded.     * If not see if some target-specific interface has it.     * If not see if the the string is stored in raw flash (usually this     *   storage is initialized in reset.s of the target-specific code).     * Finally, as a last resort, use the default set up in config.h.     */    if (!(Etheradd = getenv("ETHERADD"))) {        if (!(Etheradd = extGetEtherAdd())) {            if (etheraddr[0] != 0xff)                Etheradd = etheraddr;            else {                if (!strcmp(DEFAULT_ETHERADD,"ETHER_OFF")) {                    printf("Ethernet disabled, must set MAC address\n");                    return(-1);                }                printf("WARNING: using default MAC address.\n");                Etheradd = DEFAULT_ETHERADD;            }        }        setenv("ETHERADD",Etheradd);    }    /* Apply the same logic as above to the IP address... */    if (!(IPadd = getenv("IPADD"))) {        if (!(IPadd = extGetIpAdd())) {            if (ipaddr[0] != 0xff)                IPadd = ipaddr;            else                IPadd = DEFAULT_IPADD;        }        setenv("IPADD",IPadd);    }    /* Convert addresses to binary: */#if INCLUDE_DHCPBOOT    if (DhcpIPCheck(IPadd) == -1)        return(-1);#else

⌨️ 快捷键说明

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