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

📄 ethernet.c

📁 完整的Bell实验室的嵌入式文件系统TFS
💻 C
📖 第 1 页 / 共 3 页
字号:
    if (IpToBin(IPadd,BinIpAddr) < 0)        return(-1);#endif    if (EtherToBin(Etheradd,BinEnetAddr) < 0)        return(-1);    /* Initialize a unique number based on MAC: */    UniqueIpId = xcrc16(BinEnetAddr,6);    return(0);}/* processPACKET(): *  This is the top level of the message processing after a complete *  packet has been received over ethernet.  It's all just a lot of *  parsing to determine whether the message is for this board's IP *  address (broadcast reception may be enabled), and the type of *  incoming protocol.  Once that is determined, the packet is either *  processed (TFTP, DHCP, ARP, ICMP-ECHO, etc...) or discarded. */voidprocessPACKET(struct ether_header *ehdr, ushort size){    int i;    ushort  *datap, udpport;    ulong   csum;    struct ip *ihdr;    struct Udphdr *uhdr;    printPkt(ehdr,size,ETHER_INCOMING);    if (ehdr->ether_type == ecs(ETHERTYPE_ARP)) {        processARP(ehdr,size);        return;    }    else if (ehdr->ether_type == ecs(ETHERTYPE_REVARP)) {        processRARP(ehdr,size);        return;    }    else if (ehdr->ether_type != ecs(ETHERTYPE_IP)) {        return;    }    /* If we are NOT in the middle of a DHCP or BOOTP transaction, then     * if destination MAC address is broadcast, return now.     */#if INCLUDE_DHCPBOOT    if ((DHCPState == DHCPSTATE_NOTUSED) &&        (!memcmp((char *)&(ehdr->ether_dhost),BroadcastAddr,6))) {        return;    }#else    if (!memcmp((char *)&(ehdr->ether_dhost),BroadcastAddr,6)) {        return;    }#endif    /* If source MAC address is this board, then assume we received our     * own outgoing broadcast message...     */    if (!memcmp((char *)&(ehdr->ether_shost),BinEnetAddr,6)) {        return;    }    ihdr = (struct ip *) (ehdr + 1);    /* If not version # 4, return now... */    if (getIP_V(ihdr->ip_vhl) != 4) {        return;    }    /* IP address filtering:     * At this point, the only packets accepted are those destined for this     * board's IP address, plus, DHCP, if active.     * also accepted.     */#if INCLUDE_DHCPBOOT    if (memcmp((char *)&(ihdr->ip_dst),BinIpAddr,4)) {        if (DHCPState == DHCPSTATE_NOTUSED)            return;        if (ihdr->ip_p != IP_UDP)            return;        uhdr = (struct Udphdr *)(ihdr+1);        if (uhdr->uh_dport != ecs(DhcpClientPort)) {            return;        }    }#else    if (memcmp((char *)&(ihdr->ip_dst),BinIpAddr,4)) {        return;    }#endif    /* Verify incoming IP header checksum...     * Refer to section 3.2 of TCP/IP Illustrated, Vol 1 for details.     */    csum = 0;    datap = (ushort *) ihdr;    for (i=0;i<(sizeof(struct ip)/sizeof(ushort));i++,datap++)        csum += *datap;    csum = (csum & 0xffff) + (csum >> 16);    if (csum != 0xffff) {        EtherIPERRCnt++;        if (EtherVerbose & SHOW_BADCSUM) {            printf("IP csum error: 0x%04x != 0xffff\n",(ushort)csum);            if (EtherVerbose & SHOW_BADCSUMV) {                int overbose = EtherVerbose;                EtherVerbose = SHOW_ALL;                printPkt(ehdr,size,ETHER_INCOMING);                EtherVerbose = overbose;            }        }           return;    }        if (ihdr->ip_p == IP_ICMP) {        processICMP(ehdr,size);        return;    }    else if (ihdr->ip_p == IP_TCP) {        processTCP(ehdr,size);        return;    }    else if (ihdr->ip_p != IP_UDP) {        int j;        SendICMPUnreachable(ehdr,ICMP_UNREACHABLE_PROTOCOL);        if (!(EtherVerbose & SHOW_INCOMING))            return;        for(j=0;protocols[j].pname;j++) {            if (ihdr->ip_p == protocols[j].pnum) {                printf("%s not supported\n",                    protocols[j].pname);                return;            }        }        printf("<%02x> protocol unrecognized\n", ihdr->ip_p);        return;    }    uhdr = (struct Udphdr *)(ihdr+1);    /* If non-zero, verify incoming UDP packet checksum...     * Refer to section 11.3 of TCP/IP Illustrated, Vol 1 for details.     */    if (uhdr->uh_sum) {        int     len;        struct  UdpPseudohdr    pseudohdr;        memcpy((char *)&pseudohdr.ip_src.s_addr,(char *)&ihdr->ip_src.s_addr,4);        memcpy((char *)&pseudohdr.ip_dst.s_addr,(char *)&ihdr->ip_dst.s_addr,4);        pseudohdr.zero = 0;        pseudohdr.proto = ihdr->ip_p;        pseudohdr.ulen = uhdr->uh_ulen;        csum = 0;        datap = (ushort *) &pseudohdr;        for (i=0;i<(sizeof(struct UdpPseudohdr)/sizeof(ushort));i++)            csum += *datap++;        /* If length is odd, pad and add one. */        len = ecs(uhdr->uh_ulen);        if (len & 1) {            uchar   *ucp;            ucp = (uchar *)uhdr;            ucp[len] = 0;            len++;        }        len >>= 1;        datap = (ushort *) uhdr;        for (i=0;i<len;i++)            csum += *datap++;        csum = (csum & 0xffff) + (csum >> 16);        if (csum != 0xffff) {            EtherUDPERRCnt++;            if (EtherVerbose & SHOW_BADCSUM) {                printf("UDP csum error: 0x%04x != 0xffff\n",(ushort)csum);                if (EtherVerbose & SHOW_BADCSUMV) {                    int overbose = EtherVerbose;                    EtherVerbose = SHOW_ALL;                    printPkt(ehdr,size,ETHER_INCOMING);                    printf("pseudohdr.ip_src: 0x%08lx\n",                        pseudohdr.ip_src.s_addr);                    printf("pseudohdr.ip_dst: 0x%08lx\n",                        pseudohdr.ip_dst.s_addr);                    printf("pseudohdr.zero: 0x%02x\n", pseudohdr.zero);                    printf("pseudohdr.proto: 0x%02x\n", pseudohdr.proto);                    printf("pseudohdr.ulen: 0x%04x\n", pseudohdr.ulen);                    EtherVerbose = overbose;                }            }               return;        }    }    udpport = ecs(uhdr->uh_dport);    if (udpport == MoncmdPort)        processMONCMD(ehdr,size);#if INCLUDE_DHCPBOOT    else if (udpport == DhcpClientPort)        processDHCP(ehdr,size);#endif#if INCLUDE_TFTP    else if ((udpport == TftpPort) || (udpport == TftpSrcPort))        processTFTP(ehdr,size);#endif    else {        if (EtherVerbose & SHOW_INCOMING) {            uchar *cp;            cp = (uchar *)&(ihdr->ip_src);            printf("  Unexpected IP pkt from %d.%d.%d.%d ",                cp[0],cp[1],cp[2],cp[3]);            printf("(sport=0x%x,dport=0x%x)\n",                ecs(uhdr->uh_sport),ecs(uhdr->uh_dport));        }        SendICMPUnreachable(ehdr,ICMP_UNREACHABLE_PORT);    }}voidprocessMONCMD(struct ether_header *ehdr,ushort size){    struct  ip *ihdr;    struct  Udphdr *uhdr;    char    *moncmd;    uchar   *src;    ihdr = (struct ip *)(ehdr + 1);    uhdr = (struct Udphdr *)(ihdr + 1);    moncmd = (char *)(uhdr + 1);    IPMonCmdHdr = ehdr;    src = (uchar *)&ihdr->ip_src;    if (!MFLAGS_NOMONCMDPRN())        printf("MONCMD (from %d.%d.%d.%d): ", src[0],src[1],src[2],src[3]);    IPMonCmdActive = 1;    docommand(moncmd,1);    SendIPMonChar(0,1);    stkchk("Post-sendIPmonchar");    IPMonCmdActive = 0;    writeprompt();}intSendIPMonChar(uchar c, int done){    static  int idx;    static  char linebuf[128];    int len, hdrlen;    struct ether_header *te;    struct ip *ti, *ri;    struct Udphdr *tu, *ru;    if (!IPMonCmdActive)        return(0);    /* While inside this function, clear the IPMonCmdActive flag to avoid     * recursion if an error message is to be printed...     */    IPMonCmdActive = 0;    /* Check for overflow and if detected, reset the buffer pointer...     */    if (idx >= sizeof(linebuf))        idx = 0;    linebuf[idx++] = c;    if ((!done) && (c != '\n')) {        IPMonCmdActive = 1;        return(0);    }    hdrlen = sizeof(struct ip) + sizeof(struct Udphdr);    len = idx + hdrlen ;    te = EtherCopy(IPMonCmdHdr);    ti = (struct ip *) (te + 1);    ri = (struct ip *) (IPMonCmdHdr + 1);    ti->ip_vhl = ri->ip_vhl;    ti->ip_tos = ri->ip_tos;    ti->ip_len = ecs(len);    ti->ip_id = ipId();    ti->ip_off = ri->ip_off;    ti->ip_ttl = UDP_TTL;    ti->ip_p = IP_UDP;    memcpy((char *)&(ti->ip_src.s_addr),(char *)&(ri->ip_dst.s_addr),        sizeof(struct in_addr));    memcpy((char *)&(ti->ip_dst.s_addr),(char *)&(ri->ip_src.s_addr),        sizeof(struct in_addr));    tu = (struct Udphdr *) (ti + 1);    ru = (struct Udphdr *) (ri + 1);    tu->uh_sport = ru->uh_dport;    tu->uh_dport = ru->uh_sport;    tu->uh_ulen = ecs((ushort)(sizeof(struct Udphdr) + idx));    memcpy((char *)(tu+1),linebuf,idx);    ipChksum(ti);       /* Compute checksum of ip hdr */    udpChksum(ti);      /* Compute UDP checksum */    sendBuffer(MONRESPSIZE);    idx = 0;    IPMonCmdActive = 1;    return(1);}/* *  printMem(p,n) */voidprintMem(uchar *base, int size){    int i, col;    uchar *cp, *cp1;    if (!(EtherVerbose & SHOW_HEX))        return;    cp = cp1 = base;    printf("  ");    for(col=1,i=0;i<size;i++,col++) {        printf("%02x ",*cp++);        if ((col == 8) || (col == 16)) {            printf("  ");            if (col == 16) {                col = 0;                if (EtherVerbose & SHOW_ASCII)                    prascii(cp1,16);                cp1 += 16;                printf("\n  ");            }        }    }    if ((EtherVerbose & SHOW_ASCII) && (col > 1)) {        int space;        space = (3 * (17 - col)) + (col <= 8 ? 4 : 2);        while(space--)            putchar(' ');        prascii(cp1,col-1);    }    printf("\n");    return;}/* *  printPkt(ehdr,len) */voidprintPkt(struct ether_header *ehdr, int len, int direction){    struct  arphdr *arpp;    char    *dir;    /* Filter based on verbosity level... */    if (direction == ETHER_INCOMING) {        if (!(EtherVerbose & SHOW_INCOMING))            return;        dir = "INCOMING";    }    else if (direction == ETHER_OUTGOING) {        if (!(EtherVerbose & SHOW_OUTGOING))            return;        dir = "OUTGOING";    }    else {        printf("printPkt() direction error\n");        dir = "???";    }    /* If direction is incoming and SHOW_BROADCAST is not set, then */    /* return here if the destination host is broadcast. */    if ((direction == ETHER_INCOMING) &&        (!(EtherVerbose & SHOW_BROADCAST)) &&        (!memcmp(ehdr->ether_dhost.ether_addr_octet,BroadcastAddr,6)))        return;    printf("\n%s PACKET (%d bytes):\n",dir,len);    printMem((char *)ehdr,len);    printf("  Destination Host = %02x:%02x:%02x:%02x:%02x:%02x\n",        ehdr->ether_dhost.ether_addr_octet[0],        ehdr->ether_dhost.ether_addr_octet[1],        ehdr->ether_dhost.ether_addr_octet[2],        ehdr->ether_dhost.ether_addr_octet[3],        ehdr->ether_dhost.ether_addr_octet[4],        ehdr->ether_dhost.ether_addr_octet[5]);    printf("  Source Host =      %02x:%02x:%02x:%02x:%02x:%02x\n",        ehdr->ether_shost.ether_addr_octet[0],        ehdr->ether_shost.ether_addr_octet[1],        ehdr->ether_shost.ether_addr_octet[2],        ehdr->ether_shost.ether_addr_octet[3],        ehdr->ether_shost.ether_addr_octet[4],        ehdr->ether_shost.ether_addr_octet[5]);    switch (ehdr->ether_type) {    case ecs(ETHERTYPE_IP):        printIp((struct ip *)(ehdr+1));        break;    case ecs(ETHERTYPE_PUP):        printf("  Type = PUP\n");

⌨️ 快捷键说明

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