📄 net.c
字号:
} if (SWAP16(arp->ar_pro) != PROT_IP) { return; } if (arp->ar_hln != 6) { return; } if (arp->ar_pln != 4) { return; } if (NetOurIP == 0) {#ifdef ET_DEBUG printf("We don't know our own IP -> Nothing to do\n");#endif return; } { IPaddr_t ip = NetReadIP((uchar*)&arp->ar_data[16]); if (ip != NetOurIP) {#ifdef ET_DEBUG printf("Requested IP is not ours\n");#endif return; } } switch (SWAP16(arp->ar_op)) { case ARPOP_REQUEST: /* reply with our Ether address */#ifdef ET_DEBUG printf("Got ARP REQUEST, return our EtherAddr.\n");#endif NetSetEther((uchar *)et, et->et_src, PROT_ARP); arp->ar_op = SWAP16(ARPOP_REPLY); NetCopyEther(&arp->ar_data[0], NetOurEther); NetWriteIP( &arp->ar_data[6], NetOurIP); NetCopyEther(&arp->ar_data[10], NetOurEther); NetWriteIP( &arp->ar_data[16], NetOurIP); NetSendPacket((uchar *)et,((uchar *)arp-pkt)+ARP_HDR_SIZE); return; case ARPOP_REPLY: /* set TFTP server eth addr */#ifdef ET_DEBUG printf("Got ARP REPLY, set server/gtwy eth addr\n");#endif /* check if target ether is ours */ if ( memcmp(NetOurEther, &(arp->ar_data[10]), 6) != 0 ) {#ifdef ET_DEBUG printf(" Reply is not for us. Ignoring it...\n");#endif return; } NetCopyEther(NetServerEther, &arp->ar_data[0]); printf("eth addr: "); NetPrintEther(NetServerEther); (*packetHandler)(0,0,0,0); /* start TFTP */ return; default:#ifdef ET_DEBUG printf("Unexpected ARP opcode 0x%x\n", SWAP16(arp->ar_op));#endif return; } case PROT_RARP:#ifdef ET_DEBUG printf("Got RARP\n");#endif arp = (ARP_t *)ip; if (len < ARP_HDR_SIZE) { printf("bad length %d < %d\n", len, ARP_HDR_SIZE); return; } if ((SWAP16(arp->ar_op) != RARPOP_REPLY) || (SWAP16(arp->ar_hrd) != ARP_ETHER) || (SWAP16(arp->ar_pro) != PROT_IP) || (arp->ar_hln != 6) || (arp->ar_pln != 4)) { printf("invalid RARP header\n"); } else { NetOurIP = NetReadIP((uchar*)&arp->ar_data[16]); NetServerIP = NetReadIP((uchar*)&arp->ar_data[6]); NetCopyEther(NetServerEther, &arp->ar_data[0]); (*packetHandler)(0,0,0,0); } break; case PROT_IP:#ifdef ET_DEBUG printf("Got IP\n");#endif if (len < IP_HDR_SIZE) { debug ("len bad %d < %d\n", len, IP_HDR_SIZE); return; } if (len < SWAP16(ip->ip_len)) { printf("len bad %d < %d\n", len, SWAP16(ip->ip_len)); return; } len = SWAP16(ip->ip_len);#ifdef ET_DEBUG printf("len=%d, v=%02x\n", len, ip->ip_hl_v & 0xff);#endif if ((ip->ip_hl_v & 0xf0) != 0x40) { printf("version bad %x\n", ip->ip_hl_v & 0xf0); return; } if (ip->ip_off & SWAP16c(0x1fff)) { /* Can't deal w/ fragments */ printf("can't deal with fragments\n"); return; } if (!NetCksumOk((uchar *)ip, IP_HDR_SIZE_NO_UDP / 2)) { printf("checksum bad\n"); return; } if (NetOurIP) { IPaddr_t ipaddr = NetReadIP((uchar*)&ip->ip_dst); if (ipaddr != NetOurIP && ipaddr != 0xFFFFFFFF) {#ifdef ET_DEBUG printf("ip packet not for us\n"); print_IPaddr(ipaddr);#endif return; } } /* * watch for ICMP host redirects * * There is no real handler code (yet). We just watch * for ICMP host redirect messages. In case anybody * sees these messages: please contact me * (wd@denx.de), or - even better - send me the * necessary fixes :-) * * Note: in all cases where I have seen this so far * it was a problem with the router configuration, * for instance when a router was configured in the * BOOTP reply, but the TFTP server was on the same * subnet. So this is probably a warning that your * configuration might be wrong. But I'm not really * sure if there aren't any other situations. */ if (ip->ip_p == IPPROTO_ICMP) { ICMP_t *icmph = (ICMP_t *)&(ip->udp_src); if (icmph->type != ICMP_REDIRECT) return; if (icmph->code != ICMP_REDIR_HOST) return; puts (" ICMP Host Redirect to "); print_IPaddr(icmph->un.gateway); putc(' '); } else if (ip->ip_p != IPPROTO_UDP) { /* Only UDP packets */ return; } /* * IP header OK. Pass the packet to the current handler. */ (*packetHandler)((uchar *)ip +IP_HDR_SIZE, SWAP16(ip->udp_dst), SWAP16(ip->udp_src), SWAP16(ip->udp_len) - 8); break; default:#ifdef ET_DEBUG printf("Got unknown protocol %04x\n",x);#endif }}/**********************************************************************/static int net_check_prereq (proto_t protocol){ switch (protocol) { case ARP: /* nothing to do */ break; case TFTP: if (NetServerIP == 0) { puts ("*** ERROR: `serverip' not set\n"); return (1); } if (NetOurIP == 0) { puts ("*** ERROR: `ipaddr' not set\n"); return (1); } /* Fall through */ case DHCP: case RARP: case BOOTP: if (memcmp(NetOurEther, "\0\0\0\0\0\0", 6) == 0) { puts ("*** ERROR: `ethaddr' not set\n"); return (1); } /* Fall through */ } return (0); /* OK */}/**********************************************************************/intNetCksumOk(uchar * ptr, int len){ return !((NetCksum(ptr, len) + 1) & 0xfffe);}unsignedNetCksum(uchar * ptr, int len){ ulong xsum; xsum = 0; while (len-- > 0) xsum += *((ushort *)ptr)++; xsum = (xsum & 0xffff) + (xsum >> 16); xsum = (xsum & 0xffff) + (xsum >> 16); return (xsum & 0xffff);}voidNetCopyEther(volatile uchar * to, uchar * from){ int i; for (i = 0; i < 6; i++) *to++ = *from++;}voidNetWriteIP(volatile uchar * to, IPaddr_t ip){ int i; for (i = 0; i < 4; i++) { *to++ = ip >> 24; ip <<= 8; }}IPaddr_tNetReadIP(volatile uchar * from){ IPaddr_t ip; int i; ip = 0; for (i = 0; i < 4; i++) ip = (ip << 8) | *from++; return ip;}voidNetCopyIP(volatile uchar * to, volatile uchar *from){ int i; for (i = 0; i < 4; i++) *to++ = *from++;}voidNetSetEther(volatile uchar * xet, uchar * addr, uint prot){ volatile Ethernet_t *et = (Ethernet_t *)xet; NetCopyEther(et->et_dest, addr); NetCopyEther(et->et_src, NetOurEther); et->et_protlen = SWAP16(prot);}voidNetSetIP(volatile uchar * xip, IPaddr_t dest, int dport, int sport, int len){ volatile IP_t *ip = (IP_t *)xip; /* * If the data is an odd number of bytes, zero the * byte after the last byte so that the checksum * will work. */ if (len & 1) xip[IP_HDR_SIZE + len] = 0; /* * Construct an IP and UDP header. (need to set no fragment bit - XXX) */ ip->ip_hl_v = 0x45; /* IP_HDR_SIZE / 4 (not including UDP) */ ip->ip_tos = 0; ip->ip_len = SWAP16(IP_HDR_SIZE + len); ip->ip_id = SWAP16(NetIPID++); ip->ip_off = SWAP16c(0x4000); /* No fragmentation */ ip->ip_ttl = 255; ip->ip_p = 17; /* UDP */ ip->ip_sum = 0; NetWriteIP((uchar*)&ip->ip_src, NetOurIP); NetWriteIP((uchar*)&ip->ip_dst, dest); ip->udp_src = SWAP16(sport); ip->udp_dst = SWAP16(dport); ip->udp_len = SWAP16(8 + len); ip->udp_xsum = 0; ip->ip_sum = ~NetCksum((uchar *)ip, IP_HDR_SIZE_NO_UDP / 2);}void copy_filename (uchar *dst, uchar *src, int size){ if (*src && (*src == '"')) { ++src; --size; } while ((--size > 0) && *src && (*src != '"')) { *dst++ = *src++; } *dst = '\0';}#endif /* CFG_CMD_NET */void ip_to_string (IPaddr_t x, char *s){ sprintf (s,"%d.%d.%d.%d", (int)((x >> 24) & 0xff), (int)((x >> 16) & 0xff), (int)((x >> 8) & 0xff), (int)((x >> 0) & 0xff) );}void print_IPaddr (IPaddr_t x){ char tmp[12]; ip_to_string(x, tmp); puts(tmp);}voidNetPrintEther(volatile uchar * addr){ int i; for (i = 0; i < 6; i++) { printf("%02x", *(addr+i)); if (i != 5) printf(":"); } printf("\n");}#ifdef ET_DEBUGvoidhexdump(uchar * data, unsigned long size){ unsigned long i = 0; for (i = 0; i < size; i++) { if ( ((i % 16) == 0) && (i != 0) ) { printf("\n"); } printf("%02x ", *(data+i)); } printf("\n\n");}#endif /* ET_DEBUG */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -