X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=net%2Fnet.c;h=f96eb28b35ea2b90bc0d79b2677c3ccedb9778a6;hb=77a318545d57aefa844752465b94c7e09a3f26d0;hp=90315ca7e20e11dfa87610cd0a72fc7d1c2e9153;hpb=3e01d75ff25b3668191beb86ab32cb2d1fb7f73b;p=u-boot diff --git a/net/net.c b/net/net.c index 90315ca7e2..f96eb28b35 100644 --- a/net/net.c +++ b/net/net.c @@ -40,10 +40,10 @@ * * DHCP: * - * Prerequisites: - own ethernet address - * We want: - IP, Netmask, ServerIP, Gateway IP - * - bootfilename, lease time - * Next step: - TFTP + * Prerequisites: - own ethernet address + * We want: - IP, Netmask, ServerIP, Gateway IP + * - bootfilename, lease time + * Next step: - TFTP * * TFTP: * @@ -64,6 +64,13 @@ * derived from our own IP address) * We want: - load the boot file * Next step: none + * + * SNTP: + * + * Prerequisites: - own ethernet address + * - own IP address + * We want: - network time + * Next step: none */ @@ -79,8 +86,13 @@ #include #include #endif +#if defined(CONFIG_CMD_SNTP) +#include "sntp.h" +#endif + +#if defined(CONFIG_CMD_NET) -#if (CONFIG_COMMANDS & CFG_CMD_NET) +DECLARE_GLOBAL_DATA_PTR; #define ARP_TIMEOUT 5 /* Seconds before trying ARP again */ #ifndef CONFIG_NET_RETRY_COUNT @@ -98,7 +110,7 @@ IPaddr_t NetOurSubnetMask=0; /* Our subnet mask (0=unknown) */ IPaddr_t NetOurGatewayIP=0; /* Our gateways IP address */ IPaddr_t NetOurDNSIP=0; /* Our DNS IP address */ -#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_DNS2) +#if defined(CONFIG_BOOTP_DNS2) IPaddr_t NetOurDNS2IP=0; /* Our 2nd DNS IP address */ #endif char NetOurNISDomain[32]={0,}; /* Our NIS domain */ @@ -121,7 +133,7 @@ uchar NetBcastAddr[6] = /* Ethernet bcast address */ { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; uchar NetEtherNullAddr[6] = { 0, 0, 0, 0, 0, 0 }; -#if (CONFIG_COMMANDS & CFG_CMD_CDP) +#if defined(CONFIG_CMD_CDP) uchar NetCDPAddr[6] = /* Ethernet bcast address */ { 0x01, 0x00, 0x0c, 0xcc, 0xcc, 0xcc }; #endif @@ -138,16 +150,21 @@ ushort NetOurNativeVLAN = 0xFFFF; /* ditto */ char BootFile[128]; /* Boot File name */ -#if (CONFIG_COMMANDS & CFG_CMD_PING) +#if defined(CONFIG_CMD_PING) IPaddr_t NetPingIP; /* the ip address to ping */ static void PingStart(void); #endif -#if (CONFIG_COMMANDS & CFG_CMD_CDP) +#if defined(CONFIG_CMD_CDP) static void CDPStart(void); #endif +#if defined(CONFIG_CMD_SNTP) +IPaddr_t NetNtpServerIP; /* NTP server IP address */ +int NetTimeOffset=0; /* offset time from UTC */ +#endif + #ifdef CONFIG_NETCONSOLE void NcStart(void); int nc_input_packet(uchar *pkt, unsigned dest, unsigned src, unsigned len); @@ -170,7 +187,7 @@ static int net_check_prereq (proto_t protocol); IPaddr_t NetArpWaitPacketIP; IPaddr_t NetArpWaitReplyIP; uchar *NetArpWaitPacketMAC; /* MAC address of waiting packet's destination */ -uchar *NetArpWaitTxPacket; /* THE transmit packet */ +uchar *NetArpWaitTxPacket; /* THE transmit packet */ int NetArpWaitTxPacketSize; uchar NetArpWaitPacketBuf[PKTSIZE_ALIGN + PKTALIGN]; ulong NetArpWaitTimerStart; @@ -197,8 +214,8 @@ void ArpRequest (void) arp->ar_pln = 4; arp->ar_op = htons (ARPOP_REQUEST); - memcpy (&arp->ar_data[0], NetOurEther, 6); /* source ET addr */ - NetWriteIP ((uchar *) & arp->ar_data[6], NetOurIP); /* source IP addr */ + memcpy (&arp->ar_data[0], NetOurEther, 6); /* source ET addr */ + NetWriteIP ((uchar *) & arp->ar_data[6], NetOurIP); /* source IP addr */ for (i = 10; i < 16; ++i) { arp->ar_data[i] = 0; /* dest ET addr = 0 */ } @@ -207,8 +224,10 @@ void ArpRequest (void) (NetOurIP & NetOurSubnetMask)) { if (NetOurGatewayIP == 0) { puts ("## Warning: gatewayip needed but not set\n"); + NetArpWaitReplyIP = NetArpWaitPacketIP; + } else { + NetArpWaitReplyIP = NetOurGatewayIP; } - NetArpWaitReplyIP = NetOurGatewayIP; } else { NetArpWaitReplyIP = NetArpWaitPacketIP; } @@ -249,8 +268,6 @@ void ArpTimeoutCheck(void) int NetLoop(proto_t protocol) { - DECLARE_GLOBAL_DATA_PTR; - bd_t *bd = gd->bd; #ifdef CONFIG_NET_MULTI @@ -288,8 +305,10 @@ NetLoop(proto_t protocol) #ifdef CONFIG_NET_MULTI eth_set_current(); #endif - if (eth_init(bd) < 0) + if (eth_init(bd) < 0) { + eth_halt(); return(-1); + } restart: #ifdef CONFIG_NET_MULTI @@ -307,11 +326,14 @@ restart: */ switch (protocol) { -#if (CONFIG_COMMANDS & CFG_CMD_NFS) +#if defined(CONFIG_CMD_NFS) case NFS: #endif -#if (CONFIG_COMMANDS & CFG_CMD_PING) +#if defined(CONFIG_CMD_PING) case PING: +#endif +#if defined(CONFIG_CMD_SNTP) + case SNTP: #endif case NETCONS: case TFTP: @@ -322,17 +344,22 @@ restart: NetOurNativeVLAN = getenv_VLAN("nvlan"); switch (protocol) { -#if (CONFIG_COMMANDS & CFG_CMD_NFS) +#if defined(CONFIG_CMD_NFS) case NFS: #endif case NETCONS: case TFTP: NetServerIP = getenv_IPaddr ("serverip"); break; -#if (CONFIG_COMMANDS & CFG_CMD_PING) +#if defined(CONFIG_CMD_PING) case PING: /* nothing */ break; +#endif +#if defined(CONFIG_CMD_SNTP) + case SNTP: + /* nothing */ + break; #endif default: break; @@ -347,11 +374,11 @@ restart: */ NetOurIP = 0; NetServerIP = getenv_IPaddr ("serverip"); - NetOurVLAN = getenv_VLAN("vlan"); /* VLANs must be read */ - NetOurNativeVLAN = getenv_VLAN("nvlan"); - case CDP: - NetOurVLAN = getenv_VLAN("vlan"); /* VLANs must be read */ - NetOurNativeVLAN = getenv_VLAN("nvlan"); + NetOurVLAN = getenv_VLAN("vlan"); /* VLANs must be read */ + NetOurNativeVLAN = getenv_VLAN("nvlan"); + case CDP: + NetOurVLAN = getenv_VLAN("vlan"); /* VLANs must be read */ + NetOurNativeVLAN = getenv_VLAN("nvlan"); break; default: break; @@ -360,6 +387,7 @@ restart: switch (net_check_prereq (protocol)) { case 1: /* network not configured */ + eth_halt(); return (-1); #ifdef CONFIG_NET_MULTI @@ -378,9 +406,10 @@ restart: TftpStart(); break; -#if (CONFIG_COMMANDS & CFG_CMD_DHCP) +#if defined(CONFIG_CMD_DHCP) case DHCP: /* Start with a clean slate... */ + BootpTry = 0; NetOurIP = 0; NetServerIP = getenv_IPaddr ("serverip"); DhcpRequest(); /* Basically same as BOOTP */ @@ -396,17 +425,17 @@ restart: RarpTry = 0; RarpRequest (); break; -#if (CONFIG_COMMANDS & CFG_CMD_PING) +#if defined(CONFIG_CMD_PING) case PING: PingStart(); break; #endif -#if (CONFIG_COMMANDS & CFG_CMD_NFS) +#if defined(CONFIG_CMD_NFS) case NFS: NfsStart(); break; #endif -#if (CONFIG_COMMANDS & CFG_CMD_CDP) +#if defined(CONFIG_CMD_CDP) case CDP: CDPStart(); break; @@ -415,6 +444,11 @@ restart: case NETCONS: NcStart(); break; +#endif +#if defined(CONFIG_CMD_SNTP) + case SNTP: + SntpStart(); + break; #endif default: break; @@ -424,12 +458,12 @@ restart: break; } -#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII) +#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) #if defined(CFG_FAULT_ECHO_LINK_DOWN) && defined(CONFIG_STATUS_LED) && defined(STATUS_LED_RED) /* * Echo the inverted link state to the fault LED. */ - if(miiphy_link(CFG_FAULT_MII_ADDR)) { + if(miiphy_link(eth_get_dev()->name, CFG_FAULT_MII_ADDR)) { status_led_set (STATUS_LED_RED, STATUS_LED_OFF); } else { status_led_set (STATUS_LED_RED, STATUS_LED_ON); @@ -439,7 +473,7 @@ restart: /* * Main packet reception loop. Loop receiving packets until - * someone sets `NetQuit'. + * someone sets `NetState' to a state that terminates. */ for (;;) { WATCHDOG_RESET(); @@ -473,17 +507,19 @@ restart: if (timeHandler && ((get_timer(0) - timeStart) > timeDelta)) { thand_f *x; -#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII) -#if defined(CFG_FAULT_ECHO_LINK_DOWN) && defined(CONFIG_STATUS_LED) && defined(STATUS_LED_RED) +#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) +# if defined(CFG_FAULT_ECHO_LINK_DOWN) && \ + defined(CONFIG_STATUS_LED) && \ + defined(STATUS_LED_RED) /* * Echo the inverted link state to the fault LED. */ - if(miiphy_link(CFG_FAULT_MII_ADDR)) { + if(miiphy_link(eth_get_dev()->name, CFG_FAULT_MII_ADDR)) { status_led_set (STATUS_LED_RED, STATUS_LED_OFF); } else { status_led_set (STATUS_LED_RED, STATUS_LED_ON); } -#endif /* CFG_FAULT_ECHO_LINK_DOWN, ... */ +# endif /* CFG_FAULT_ECHO_LINK_DOWN, ... */ #endif /* CONFIG_MII, ... */ x = timeHandler; timeHandler = (thand_f *)0; @@ -536,9 +572,6 @@ startAgainHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len) void NetStartAgain (void) { -#ifdef CONFIG_NET_MULTI - DECLARE_GLOBAL_DATA_PTR; -#endif char *nretry; int noretry = 0, once = 0; @@ -654,7 +687,7 @@ NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport, int sport, int len) return 0; /* transmitted */ } -#if (CONFIG_COMMANDS & CFG_CMD_PING) +#if defined(CONFIG_CMD_PING) static ushort PingSeqNo; int PingSend(void) @@ -744,7 +777,7 @@ static void PingStart(void) } #endif /* CFG_CMD_PING */ -#if (CONFIG_COMMANDS & CFG_CMD_CDP) +#if defined(CONFIG_CMD_CDP) #define CDP_DEVICE_ID_TLV 0x0001 #define CDP_ADDRESS_TLV 0x0002 @@ -776,6 +809,7 @@ static ushort CDP_compute_csum(const uchar *buff, ushort len) int odd; ulong result = 0; ushort leftover; + ushort *p; if (len > 0) { odd = 1 & (ulong)buff; @@ -785,14 +819,19 @@ static ushort CDP_compute_csum(const uchar *buff, ushort len) buff++; } while (len > 1) { - result += *((const ushort *)buff)++; + p = (ushort *)buff; + result += *p++; + buff = (uchar *)p; if (result & 0x80000000) result = (result & 0xFFFF) + (result >> 16); len -= 2; } if (len) { leftover = (signed short)(*(const signed char *)buff); - /* * XXX CISCO SUCKS big time! (and blows too) */ + /* CISCO SUCKS big time! (and blows too): + * CDP uses the IP checksum algorithm with a twist; + * for the last byte it *sign* extends and sums. + */ result = (result & 0xffff0000) | ((result + leftover) & 0x0000ffff); } while (result >> 16) @@ -1101,7 +1140,7 @@ NetReceive(volatile uchar * inpkt, int len) IPaddr_t tmp; int x; uchar *pkt; -#if (CONFIG_COMMANDS & CFG_CMD_CDP) +#if defined(CONFIG_CMD_CDP) int iscdp; #endif ushort cti = 0, vlanid = VLAN_NONE, myvlanid, mynvlanid; @@ -1118,7 +1157,7 @@ NetReceive(volatile uchar * inpkt, int len) if (len < ETHER_HDR_SIZE) return; -#if (CONFIG_COMMANDS & CFG_CMD_CDP) +#if defined(CONFIG_CMD_CDP) /* keep track if packet is CDP */ iscdp = memcmp(et->et_dest, NetCDPAddr, 6) == 0; #endif @@ -1161,7 +1200,7 @@ NetReceive(volatile uchar * inpkt, int len) /* if no VLAN active */ if ((ntohs(NetOurVLAN) & VLAN_IDMASK) == VLAN_NONE -#if (CONFIG_COMMANDS & CFG_CMD_CDP) +#if defined(CONFIG_CMD_CDP) && iscdp == 0 #endif ) @@ -1179,7 +1218,7 @@ NetReceive(volatile uchar * inpkt, int len) printf("Receive from protocol 0x%x\n", x); #endif -#if (CONFIG_COMMANDS & CFG_CMD_CDP) +#if defined(CONFIG_CMD_CDP) if (iscdp) { CDPHandler((uchar *)ip, len); return; @@ -1291,6 +1330,7 @@ NetReceive(volatile uchar * inpkt, int len) #endif return; } + break; case PROT_RARP: #ifdef ET_DEBUG @@ -1370,20 +1410,40 @@ NetReceive(volatile uchar * inpkt, int len) switch (icmph->type) { case ICMP_REDIRECT: - if (icmph->code != ICMP_REDIR_HOST) + if (icmph->code != ICMP_REDIR_HOST) + return; + puts (" ICMP Host Redirect to "); + print_IPaddr(icmph->un.gateway); + putc(' '); return; - puts (" ICMP Host Redirect to "); - print_IPaddr(icmph->un.gateway); - putc(' '); - break; -#if (CONFIG_COMMANDS & CFG_CMD_PING) +#if defined(CONFIG_CMD_PING) case ICMP_ECHO_REPLY: /* * IP header OK. Pass the packet to the current handler. */ /* XXX point to ip packet */ (*packetHandler)((uchar *)ip, 0, 0, 0); - break; + return; + case ICMP_ECHO_REQUEST: +#ifdef ET_DEBUG + printf ("Got ICMP ECHO REQUEST, return %d bytes \n", + ETHER_HDR_SIZE + len); +#endif + memcpy (&et->et_dest[0], &et->et_src[0], 6); + memcpy (&et->et_src[ 0], NetOurEther, 6); + + ip->ip_sum = 0; + ip->ip_off = 0; + NetCopyIP((void*)&ip->ip_dst, &ip->ip_src); + NetCopyIP((void*)&ip->ip_src, &NetOurIP); + ip->ip_sum = ~NetCksum((uchar *)ip, IP_HDR_SIZE_NO_UDP >> 1); + + icmph->type = ICMP_ECHO_REPLY; + icmph->checksum = 0; + icmph->checksum = ~NetCksum((uchar *)icmph, + (len - IP_HDR_SIZE_NO_UDP) >> 1); + (void) eth_send((uchar *)et, ETHER_HDR_SIZE + len); + return; #endif default: return; @@ -1392,6 +1452,46 @@ NetReceive(volatile uchar * inpkt, int len) return; } +#ifdef CONFIG_UDP_CHECKSUM + if (ip->udp_xsum != 0) { + ulong xsum; + ushort *sumptr; + ushort sumlen; + + xsum = ip->ip_p; + xsum += (ntohs(ip->udp_len)); + xsum += (ntohl(ip->ip_src) >> 16) & 0x0000ffff; + xsum += (ntohl(ip->ip_src) >> 0) & 0x0000ffff; + xsum += (ntohl(ip->ip_dst) >> 16) & 0x0000ffff; + xsum += (ntohl(ip->ip_dst) >> 0) & 0x0000ffff; + + sumlen = ntohs(ip->udp_len); + sumptr = (ushort *) &(ip->udp_src); + + while (sumlen > 1) { + ushort sumdata; + + sumdata = *sumptr++; + xsum += ntohs(sumdata); + sumlen -= 2; + } + if (sumlen > 0) { + ushort sumdata; + + sumdata = *(unsigned char *) sumptr; + sumdata = (sumdata << 8) & 0xff00; + xsum += sumdata; + } + while ((xsum >> 16) != 0) { + xsum = (xsum & 0x0000ffff) + ((xsum >> 16) & 0x0000ffff); + } + if ((xsum != 0x00000000) && (xsum != 0x0000ffff)) { + printf(" UDP wrong checksum %08x %08x\n", xsum, ntohs(ip->udp_xsum)); + return; + } + } +#endif + #ifdef CONFIG_NETCONSOLE nc_input_packet((uchar *)ip +IP_HDR_SIZE, ntohs(ip->udp_dst), @@ -1416,7 +1516,7 @@ static int net_check_prereq (proto_t protocol) { switch (protocol) { /* Fall through */ -#if (CONFIG_COMMANDS & CFG_CMD_PING) +#if defined(CONFIG_CMD_PING) case PING: if (NetPingIP == 0) { puts ("*** ERROR: ping address not given\n"); @@ -1424,7 +1524,15 @@ static int net_check_prereq (proto_t protocol) } goto common; #endif -#if (CONFIG_COMMANDS & CFG_CMD_NFS) +#if defined(CONFIG_CMD_SNTP) + case SNTP: + if (NetNtpServerIP == 0) { + puts ("*** ERROR: NTP server address not given\n"); + return (1); + } + goto common; +#endif +#if defined(CONFIG_CMD_NFS) case NFS: #endif case NETCONS: @@ -1433,8 +1541,8 @@ static int net_check_prereq (proto_t protocol) puts ("*** ERROR: `serverip' not set\n"); return (1); } -#if (CONFIG_COMMANDS & CFG_CMD_PING) - common: +#if defined(CONFIG_CMD_PING) || defined(CONFIG_CMD_SNTP) + common: #endif if (NetOurIP == 0) { @@ -1491,10 +1599,11 @@ unsigned NetCksum(uchar * ptr, int len) { ulong xsum; + ushort *p = (ushort *)ptr; xsum = 0; while (len-- > 0) - xsum += *((ushort *)ptr)++; + xsum += *p++; xsum = (xsum & 0xffff) + (xsum >> 16); xsum = (xsum & 0xffff) + (xsum >> 16); return (xsum & 0xffff); @@ -1571,7 +1680,7 @@ NetSetIP(volatile uchar * xip, IPaddr_t dest, int dport, int sport, int len) ip->ip_sum = ~NetCksum((uchar *)ip, IP_HDR_SIZE_NO_UDP / 2); } -void copy_filename (uchar *dst, uchar *src, int size) +void copy_filename (char *dst, char *src, int size) { if (*src && (*src == '"')) { ++src;