📄 ethernet.c
字号:
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 + -