1 /* 2 * Copied from Linux Monitor (LiMon) - Networking. 3 * 4 * Copyright 1994 - 2000 Neil Russell. 5 * (See License) 6 * Copyright 2000 Roland Borde 7 * Copyright 2000 Paolo Scaffardi 8 * Copyright 2000-2002 Wolfgang Denk, wd@denx.de 9 */ 10 11 /* 12 * General Desription: 13 * 14 * The user interface supports commands for BOOTP, RARP, and TFTP. 15 * Also, we support ARP internally. Depending on available data, 16 * these interact as follows: 17 * 18 * BOOTP: 19 * 20 * Prerequisites: - own ethernet address 21 * We want: - own IP address 22 * - TFTP server IP address 23 * - name of bootfile 24 * Next step: ARP 25 * 26 * RARP: 27 * 28 * Prerequisites: - own ethernet address 29 * We want: - own IP address 30 * - TFTP server IP address 31 * Next step: ARP 32 * 33 * ARP: 34 * 35 * Prerequisites: - own ethernet address 36 * - own IP address 37 * - TFTP server IP address 38 * We want: - TFTP server ethernet address 39 * Next step: TFTP 40 * 41 * DHCP: 42 * 43 * Prerequisites: - own ethernet address 44 * We want: - IP, Netmask, ServerIP, Gateway IP 45 * - bootfilename, lease time 46 * Next step: - TFTP 47 * 48 * TFTP: 49 * 50 * Prerequisites: - own ethernet address 51 * - own IP address 52 * - TFTP server IP address 53 * - TFTP server ethernet address 54 * - name of bootfile (if unknown, we use a default name 55 * derived from our own IP address) 56 * We want: - load the boot file 57 * Next step: none 58 */ 59 60 61 #include <common.h> 62 #include <watchdog.h> 63 #include <command.h> 64 #include <net.h> 65 #include "bootp.h" 66 #include "tftp.h" 67 #include "rarp.h" 68 69 #if (CONFIG_COMMANDS & CFG_CMD_NET) 70 71 #define ARP_TIMEOUT 5 /* Seconds before trying ARP again */ 72 #ifndef CONFIG_NET_RETRY_COUNT 73 # define ARP_TIMEOUT_COUNT 5 /* # of timeouts before giving up */ 74 #else 75 # define ARP_TIMEOUT_COUNT (CONFIG_NET_RETRY_COUNT) 76 #endif 77 78 #if 0 79 #define ET_DEBUG 80 #endif 81 82 /** BOOTP EXTENTIONS **/ 83 84 IPaddr_t NetOurSubnetMask=0; /* Our subnet mask (0=unknown) */ 85 IPaddr_t NetOurGatewayIP=0; /* Our gateways IP address */ 86 IPaddr_t NetOurDNSIP=0; /* Our DNS IP address */ 87 char NetOurNISDomain[32]={0,}; /* Our NIS domain */ 88 char NetOurHostName[32]={0,}; /* Our hostname */ 89 char NetOurRootPath[64]={0,}; /* Our bootpath */ 90 ushort NetBootFileSize=0; /* Our bootfile size in blocks */ 91 92 /** END OF BOOTP EXTENTIONS **/ 93 94 ulong NetBootFileXferSize; /* The actual transferred size of the bootfile (in bytes) */ 95 uchar NetOurEther[6]; /* Our ethernet address */ 96 uchar NetServerEther[6] = /* Boot server enet address */ 97 { 0, 0, 0, 0, 0, 0 }; 98 IPaddr_t NetOurIP; /* Our IP addr (0 = unknown) */ 99 IPaddr_t NetServerIP; /* Our IP addr (0 = unknown) */ 100 volatile uchar *NetRxPkt; /* Current receive packet */ 101 int NetRxPktLen; /* Current rx packet length */ 102 unsigned NetIPID; /* IP packet ID */ 103 uchar NetBcastAddr[6] = /* Ethernet bcast address */ 104 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 105 uchar NetEtherNullAddr[6] = 106 { 0, 0, 0, 0, 0, 0 }; 107 int NetState; /* Network loop state */ 108 #ifdef CONFIG_NET_MULTI 109 int NetRestartWrap = 0; /* Tried all network devices */ 110 static int NetRestarted = 0; /* Network loop restarted */ 111 static int NetDevExists = 0; /* At least one device configured */ 112 #endif 113 114 char BootFile[128]; /* Boot File name */ 115 116 #if (CONFIG_COMMANDS & CFG_CMD_PING) 117 IPaddr_t NetPingIP; /* the ip address to ping */ 118 119 static void PingStart(void); 120 #endif 121 122 volatile uchar PktBuf[(PKTBUFSRX+1) * PKTSIZE_ALIGN + PKTALIGN]; 123 124 volatile uchar *NetRxPackets[PKTBUFSRX]; /* Receive packets */ 125 126 static rxhand_f *packetHandler; /* Current RX packet handler */ 127 static thand_f *timeHandler; /* Current timeout handler */ 128 static ulong timeValue; /* Current timeout value */ 129 volatile uchar *NetTxPacket = 0; /* THE transmit packet */ 130 131 static int net_check_prereq (proto_t protocol); 132 133 /**********************************************************************/ 134 135 IPaddr_t NetArpWaitPacketIP; 136 IPaddr_t NetArpWaitReplyIP; 137 uchar *NetArpWaitPacketMAC; /* MAC address of waiting packet's destination */ 138 uchar *NetArpWaitTxPacket; /* THE transmit packet */ 139 int NetArpWaitTxPacketSize; 140 uchar NetArpWaitPacketBuf[PKTSIZE_ALIGN + PKTALIGN]; 141 ulong NetArpWaitTimerStart; 142 int NetArpWaitTry; 143 144 void ArpRequest(void) 145 { 146 int i; 147 volatile uchar *pkt; 148 ARP_t * arp; 149 150 #ifdef ET_DEBUG 151 printf("ARP broadcast %d\n", NetArpWaitTry); 152 #endif 153 pkt = NetTxPacket; 154 155 NetSetEther(pkt, NetBcastAddr, PROT_ARP); 156 pkt += ETHER_HDR_SIZE; 157 158 arp = (ARP_t *)pkt; 159 160 arp->ar_hrd = htons(ARP_ETHER); 161 arp->ar_pro = htons(PROT_IP); 162 arp->ar_hln = 6; 163 arp->ar_pln = 4; 164 arp->ar_op = htons(ARPOP_REQUEST); 165 166 memcpy (&arp->ar_data[0], NetOurEther, 6); /* source ET addr */ 167 NetWriteIP((uchar*)&arp->ar_data[6], NetOurIP); /* source IP addr */ 168 for (i=10; i<16; ++i) { 169 arp->ar_data[i] = 0; /* dest ET addr = 0 */ 170 } 171 172 if((NetArpWaitPacketIP & NetOurSubnetMask) != (NetOurIP & NetOurSubnetMask)) { 173 if (NetOurGatewayIP == 0) { 174 puts ("## Warning: gatewayip needed but not set\n"); 175 } 176 NetArpWaitReplyIP = NetOurGatewayIP; 177 } else 178 NetArpWaitReplyIP = NetArpWaitPacketIP; 179 180 NetWriteIP((uchar*)&arp->ar_data[16], NetArpWaitReplyIP); 181 (void) eth_send(NetTxPacket, ETHER_HDR_SIZE + ARP_HDR_SIZE); 182 } 183 184 void ArpTimeoutCheck(void) 185 { 186 ulong t; 187 188 if (!NetArpWaitPacketIP) 189 return; 190 191 t = get_timer(0); 192 193 /* check for arp timeout */ 194 if ((t - NetArpWaitTimerStart) > ARP_TIMEOUT * CFG_HZ) { 195 NetArpWaitTry++; 196 197 if (NetArpWaitTry >= ARP_TIMEOUT_COUNT) { 198 puts ("\nARP Retry count exceeded; starting again\n"); 199 NetArpWaitTry = 0; 200 NetStartAgain(); 201 } else { 202 NetArpWaitTimerStart = t; 203 ArpRequest(); 204 } 205 } 206 } 207 208 /**********************************************************************/ 209 /* 210 * Main network processing loop. 211 */ 212 213 int 214 NetLoop(proto_t protocol) 215 { 216 DECLARE_GLOBAL_DATA_PTR; 217 218 bd_t *bd = gd->bd; 219 220 #ifdef CONFIG_NET_MULTI 221 NetRestarted = 0; 222 NetDevExists = 0; 223 #endif 224 225 /* XXX problem with bss workaround */ 226 NetArpWaitPacketMAC = NULL; 227 NetArpWaitTxPacket = NULL; 228 NetArpWaitPacketIP = 0; 229 NetArpWaitReplyIP = 0; 230 NetArpWaitTxPacket = NULL; 231 NetTxPacket = NULL; 232 233 if (!NetTxPacket) { 234 int i; 235 236 /* 237 * Setup packet buffers, aligned correctly. 238 */ 239 NetTxPacket = &PktBuf[0] + (PKTALIGN - 1); 240 NetTxPacket -= (ulong)NetTxPacket % PKTALIGN; 241 for (i = 0; i < PKTBUFSRX; i++) { 242 NetRxPackets[i] = NetTxPacket + (i+1)*PKTSIZE_ALIGN; 243 } 244 245 } 246 247 if (!NetArpWaitTxPacket) { 248 NetArpWaitTxPacket = &NetArpWaitPacketBuf[0] + (PKTALIGN - 1); 249 NetArpWaitTxPacket -= (ulong)NetArpWaitTxPacket % PKTALIGN; 250 NetArpWaitTxPacketSize = 0; 251 } 252 253 eth_halt(); 254 if(eth_init(bd) < 0) 255 return(-1); 256 257 restart: 258 #ifdef CONFIG_NET_MULTI 259 memcpy (NetOurEther, eth_get_dev()->enetaddr, 6); 260 #else 261 memcpy (NetOurEther, bd->bi_enetaddr, 6); 262 #endif 263 264 NetState = NETLOOP_CONTINUE; 265 266 /* 267 * Start the ball rolling with the given start function. From 268 * here on, this code is a state machine driven by received 269 * packets and timer events. 270 */ 271 272 switch (protocol) { 273 #if (CONFIG_COMMANDS & CFG_CMD_PING) 274 case PING: 275 #endif 276 case TFTP: 277 NetCopyIP(&NetOurIP, &bd->bi_ip_addr); 278 NetOurGatewayIP = getenv_IPaddr ("gatewayip"); 279 NetOurSubnetMask= getenv_IPaddr ("netmask"); 280 281 switch (protocol) { 282 case TFTP: 283 NetServerIP = getenv_IPaddr ("serverip"); 284 break; 285 #if (CONFIG_COMMANDS & CFG_CMD_PING) 286 case PING: 287 /* nothing */ 288 break; 289 #endif 290 default: 291 break; 292 } 293 294 break; 295 case BOOTP: 296 case RARP: 297 /* 298 * initialize our IP addr to 0 in order to accept ANY 299 * IP addr assigned to us by the BOOTP / RARP server 300 */ 301 NetOurIP = 0; 302 NetServerIP = 0; 303 break; 304 default: 305 break; 306 } 307 308 switch (net_check_prereq (protocol)) { 309 case 1: 310 /* network not configured */ 311 return (-1); 312 313 #ifdef CONFIG_NET_MULTI 314 case 2: 315 /* network device not configured */ 316 break; 317 #endif /* CONFIG_NET_MULTI */ 318 319 case 0: 320 #ifdef CONFIG_NET_MULTI 321 NetDevExists = 1; 322 #endif 323 switch (protocol) { 324 case TFTP: 325 /* always use ARP to get server ethernet address */ 326 TftpStart(); 327 break; 328 329 #if (CONFIG_COMMANDS & CFG_CMD_DHCP) 330 case DHCP: 331 /* Start with a clean slate... */ 332 NetOurIP = 0; 333 NetServerIP = 0; 334 DhcpRequest(); /* Basically same as BOOTP */ 335 break; 336 #endif /* CFG_CMD_DHCP */ 337 338 case BOOTP: 339 BootpTry = 0; 340 BootpRequest (); 341 break; 342 343 case RARP: 344 RarpTry = 0; 345 RarpRequest (); 346 break; 347 #if (CONFIG_COMMANDS & CFG_CMD_PING) 348 case PING: 349 PingStart(); 350 break; 351 #endif 352 default: 353 break; 354 } 355 356 NetBootFileXferSize = 0; 357 break; 358 } 359 360 361 /* 362 * Main packet reception loop. Loop receiving packets until 363 * someone sets `NetQuit'. 364 */ 365 for (;;) { 366 WATCHDOG_RESET(); 367 #ifdef CONFIG_SHOW_ACTIVITY 368 { 369 extern void show_activity(int arg); 370 show_activity(1); 371 } 372 #endif 373 /* 374 * Check the ethernet for a new packet. The ethernet 375 * receive routine will process it. 376 */ 377 eth_rx(); 378 379 /* 380 * Abort if ctrl-c was pressed. 381 */ 382 if (ctrlc()) { 383 eth_halt(); 384 printf("\nAbort\n"); 385 return (-1); 386 } 387 388 ArpTimeoutCheck(); 389 390 /* 391 * Check for a timeout, and run the timeout handler 392 * if we have one. 393 */ 394 if (timeHandler && (get_timer(0) > timeValue)) { 395 thand_f *x; 396 397 x = timeHandler; 398 timeHandler = (thand_f *)0; 399 (*x)(); 400 } 401 402 403 switch (NetState) { 404 405 case NETLOOP_RESTART: 406 #ifdef CONFIG_NET_MULTI 407 NetRestarted = 1; 408 #endif 409 goto restart; 410 411 case NETLOOP_SUCCESS: 412 if (NetBootFileXferSize > 0) { 413 char buf[10]; 414 printf("Bytes transferred = %ld (%lx hex)\n", 415 NetBootFileXferSize, 416 NetBootFileXferSize); 417 sprintf(buf, "%lx", NetBootFileXferSize); 418 setenv("filesize", buf); 419 } 420 eth_halt(); 421 return NetBootFileXferSize; 422 423 case NETLOOP_FAIL: 424 return (-1); 425 } 426 } 427 } 428 429 /**********************************************************************/ 430 431 static void 432 startAgainTimeout(void) 433 { 434 NetState = NETLOOP_RESTART; 435 } 436 437 static void 438 startAgainHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len) 439 { 440 /* Totally ignore the packet */ 441 } 442 443 void 444 NetStartAgain(void) 445 { 446 #ifndef CONFIG_NET_MULTI 447 NetSetTimeout(10 * CFG_HZ, startAgainTimeout); 448 NetSetHandler(startAgainHandler); 449 #else 450 DECLARE_GLOBAL_DATA_PTR; 451 452 eth_halt(); 453 eth_try_another(!NetRestarted); 454 eth_init(gd->bd); 455 if (NetRestartWrap) 456 { 457 NetRestartWrap = 0; 458 if (NetDevExists) 459 { 460 NetSetTimeout(10 * CFG_HZ, startAgainTimeout); 461 NetSetHandler(startAgainHandler); 462 } 463 else 464 { 465 NetState = NETLOOP_FAIL; 466 } 467 } 468 else 469 { 470 NetState = NETLOOP_RESTART; 471 } 472 #endif 473 } 474 475 /**********************************************************************/ 476 /* 477 * Miscelaneous bits. 478 */ 479 480 void 481 NetSetHandler(rxhand_f * f) 482 { 483 packetHandler = f; 484 } 485 486 487 void 488 NetSetTimeout(int iv, thand_f * f) 489 { 490 if (iv == 0) { 491 timeHandler = (thand_f *)0; 492 } else { 493 timeHandler = f; 494 timeValue = get_timer(0) + iv; 495 } 496 } 497 498 499 void 500 NetSendPacket(volatile uchar * pkt, int len) 501 { 502 (void) eth_send(pkt, len); 503 } 504 505 int 506 NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport, int sport, int len) 507 { 508 /* convert to new style broadcast */ 509 if (dest == 0) 510 dest = 0xFFFFFFFF; 511 512 /* if broadcast, make the ether address a broadcast and don't do ARP */ 513 if (dest == 0xFFFFFFFF) 514 ether = NetBcastAddr; 515 516 /* if MAC address was not discovered yet, save the packet and do an ARP request */ 517 if (memcmp(ether, NetEtherNullAddr, 6) == 0) { 518 519 #ifdef ET_DEBUG 520 printf("sending ARP for %08lx\n", dest); 521 #endif 522 523 NetArpWaitPacketIP = dest; 524 NetArpWaitPacketMAC = ether; 525 NetSetEther (NetArpWaitTxPacket, NetArpWaitPacketMAC, PROT_IP); 526 NetSetIP (NetArpWaitTxPacket + ETHER_HDR_SIZE, dest, dport, sport, len); 527 memcpy(NetArpWaitTxPacket + ETHER_HDR_SIZE + IP_HDR_SIZE, 528 (uchar *)NetTxPacket + ETHER_HDR_SIZE + IP_HDR_SIZE, len); 529 530 /* size of the waiting packet */ 531 NetArpWaitTxPacketSize = ETHER_HDR_SIZE + IP_HDR_SIZE + len; 532 533 /* and do the ARP request */ 534 NetArpWaitTry = 1; 535 NetArpWaitTimerStart = get_timer(0); 536 ArpRequest(); 537 return 1; /* waiting */ 538 } 539 540 #ifdef ET_DEBUG 541 printf("sending UDP to %08lx/%02x:%02x:%02x:%02x:%02x:%02x\n", 542 dest, ether[0], ether[1], ether[2], ether[3], ether[4], ether[5]); 543 #endif 544 545 NetSetEther (NetTxPacket, ether, PROT_IP); 546 NetSetIP (NetTxPacket + ETHER_HDR_SIZE, dest, dport, sport, len); 547 (void) eth_send(NetTxPacket, ETHER_HDR_SIZE + IP_HDR_SIZE + len); 548 549 return 0; /* transmited */ 550 } 551 552 #if (CONFIG_COMMANDS & CFG_CMD_PING) 553 static ushort PingSeqNo; 554 555 int PingSend(void) 556 { 557 static uchar mac[6]; 558 volatile IP_t *ip; 559 volatile ushort *s; 560 561 /* XXX always send arp request */ 562 563 memcpy(mac, NetEtherNullAddr, 6); 564 565 #ifdef ET_DEBUG 566 printf("sending ARP for %08lx\n", NetPingIP); 567 #endif 568 569 NetArpWaitPacketIP = NetPingIP; 570 NetArpWaitPacketMAC = mac; 571 572 NetSetEther(NetArpWaitTxPacket, mac, PROT_IP); 573 574 ip = (volatile IP_t *)(NetArpWaitTxPacket + ETHER_HDR_SIZE); 575 576 /* 577 * Construct an IP and ICMP header. (need to set no fragment bit - XXX) 578 */ 579 ip->ip_hl_v = 0x45; /* IP_HDR_SIZE / 4 (not including UDP) */ 580 ip->ip_tos = 0; 581 ip->ip_len = htons(IP_HDR_SIZE_NO_UDP + 8); 582 ip->ip_id = htons(NetIPID++); 583 ip->ip_off = htons(0x4000); /* No fragmentation */ 584 ip->ip_ttl = 255; 585 ip->ip_p = 0x01; /* ICMP */ 586 ip->ip_sum = 0; 587 NetCopyIP((void*)&ip->ip_src, &NetOurIP); /* already in network byte order */ 588 NetCopyIP((void*)&ip->ip_dst, &NetPingIP); /* - "" - */ 589 ip->ip_sum = ~NetCksum((uchar *)ip, IP_HDR_SIZE_NO_UDP / 2); 590 591 s = &ip->udp_src; /* XXX ICMP starts here */ 592 s[0] = htons(0x0800); /* echo-request, code */ 593 s[1] = 0; /* checksum */ 594 s[2] = 0; /* identifier */ 595 s[3] = htons(PingSeqNo++); /* sequence number */ 596 s[1] = ~NetCksum((uchar *)s, 8/2); 597 598 /* size of the waiting packet */ 599 NetArpWaitTxPacketSize = ETHER_HDR_SIZE + IP_HDR_SIZE_NO_UDP + 8; 600 601 /* and do the ARP request */ 602 NetArpWaitTry = 1; 603 NetArpWaitTimerStart = get_timer(0); 604 ArpRequest(); 605 return 1; /* waiting */ 606 } 607 608 static void 609 PingTimeout (void) 610 { 611 eth_halt(); 612 NetState = NETLOOP_FAIL; /* we did not get the reply */ 613 } 614 615 static void 616 PingHandler (uchar * pkt, unsigned dest, unsigned src, unsigned len) 617 { 618 IPaddr_t tmp; 619 volatile IP_t *ip = (volatile IP_t *)pkt; 620 621 tmp = NetReadIP((void *)&ip->ip_src); 622 if (tmp != NetPingIP) 623 return; 624 625 NetState = NETLOOP_SUCCESS; 626 } 627 628 static void PingStart(void) 629 { 630 NetSetTimeout (10 * CFG_HZ, PingTimeout); 631 NetSetHandler (PingHandler); 632 633 PingSend(); 634 } 635 636 #endif 637 638 void 639 NetReceive(volatile uchar * pkt, int len) 640 { 641 Ethernet_t *et; 642 IP_t *ip; 643 ARP_t *arp; 644 IPaddr_t tmp; 645 int x; 646 647 NetRxPkt = pkt; 648 NetRxPktLen = len; 649 et = (Ethernet_t *)pkt; 650 651 x = ntohs(et->et_protlen); 652 653 if (x < 1514) { 654 /* 655 * Got a 802 packet. Check the other protocol field. 656 */ 657 x = ntohs(et->et_prot); 658 ip = (IP_t *)(pkt + E802_HDR_SIZE); 659 len -= E802_HDR_SIZE; 660 } else { 661 ip = (IP_t *)(pkt + ETHER_HDR_SIZE); 662 len -= ETHER_HDR_SIZE; 663 } 664 665 #ifdef ET_DEBUG 666 printf("Receive from protocol 0x%x\n", x); 667 #endif 668 669 switch (x) { 670 671 case PROT_ARP: 672 /* 673 * We have to deal with two types of ARP packets: 674 * - REQUEST packets will be answered by sending our 675 * IP address - if we know it. 676 * - REPLY packates are expected only after we asked 677 * for the TFTP server's or the gateway's ethernet 678 * address; so if we receive such a packet, we set 679 * the server ethernet address 680 */ 681 #ifdef ET_DEBUG 682 printf("Got ARP\n"); 683 #endif 684 arp = (ARP_t *)ip; 685 if (len < ARP_HDR_SIZE) { 686 printf("bad length %d < %d\n", len, ARP_HDR_SIZE); 687 return; 688 } 689 if (ntohs(arp->ar_hrd) != ARP_ETHER) { 690 return; 691 } 692 if (ntohs(arp->ar_pro) != PROT_IP) { 693 return; 694 } 695 if (arp->ar_hln != 6) { 696 return; 697 } 698 if (arp->ar_pln != 4) { 699 return; 700 } 701 702 if (NetOurIP == 0) { 703 return; 704 } 705 706 if (NetReadIP(&arp->ar_data[16]) != NetOurIP) { 707 return; 708 } 709 710 switch (ntohs(arp->ar_op)) { 711 case ARPOP_REQUEST: /* reply with our IP address */ 712 #ifdef ET_DEBUG 713 printf("Got ARP REQUEST, return our IP\n"); 714 #endif 715 NetSetEther((uchar *)et, et->et_src, PROT_ARP); 716 arp->ar_op = htons(ARPOP_REPLY); 717 memcpy (&arp->ar_data[10], &arp->ar_data[0], 6); 718 NetCopyIP(&arp->ar_data[16], &arp->ar_data[6]); 719 memcpy (&arp->ar_data[ 0], NetOurEther, 6); 720 NetCopyIP(&arp->ar_data[ 6], &NetOurIP); 721 (void) eth_send((uchar *)et, ((uchar *)arp-pkt) + ARP_HDR_SIZE); 722 return; 723 724 case ARPOP_REPLY: /* arp reply */ 725 /* are we waiting for a reply */ 726 if (!NetArpWaitPacketIP || !NetArpWaitPacketMAC) 727 break; 728 #ifdef ET_DEBUG 729 printf("Got ARP REPLY, set server/gtwy eth addr (%02x:%02x:%02x:%02x:%02x:%02x)\n", 730 arp->ar_data[0], arp->ar_data[1], 731 arp->ar_data[2], arp->ar_data[3], 732 arp->ar_data[4], arp->ar_data[5]); 733 #endif 734 735 tmp = NetReadIP(&arp->ar_data[6]); 736 737 /* matched waiting packet's address */ 738 if (tmp == NetArpWaitReplyIP) { 739 #ifdef ET_DEBUG 740 printf("Got it\n"); 741 #endif 742 /* save address for later use */ 743 memcpy(NetArpWaitPacketMAC, &arp->ar_data[0], 6); 744 745 /* modify header, and transmit it */ 746 memcpy(((Ethernet_t *)NetArpWaitTxPacket)->et_dest, NetArpWaitPacketMAC, 6); 747 (void) eth_send(NetArpWaitTxPacket, NetArpWaitTxPacketSize); 748 749 /* no arp request pending now */ 750 NetArpWaitPacketIP = 0; 751 NetArpWaitTxPacketSize = 0; 752 NetArpWaitPacketMAC = NULL; 753 754 } 755 return; 756 default: 757 #ifdef ET_DEBUG 758 printf("Unexpected ARP opcode 0x%x\n", ntohs(arp->ar_op)); 759 #endif 760 return; 761 } 762 763 case PROT_RARP: 764 #ifdef ET_DEBUG 765 printf("Got RARP\n"); 766 #endif 767 arp = (ARP_t *)ip; 768 if (len < ARP_HDR_SIZE) { 769 printf("bad length %d < %d\n", len, ARP_HDR_SIZE); 770 return; 771 } 772 773 if ((ntohs(arp->ar_op) != RARPOP_REPLY) || 774 (ntohs(arp->ar_hrd) != ARP_ETHER) || 775 (ntohs(arp->ar_pro) != PROT_IP) || 776 (arp->ar_hln != 6) || (arp->ar_pln != 4)) { 777 778 printf("invalid RARP header\n"); 779 } else { 780 NetCopyIP(&NetOurIP, &arp->ar_data[16]); 781 NetCopyIP(&NetServerIP, &arp->ar_data[ 6]); 782 memcpy (NetServerEther, &arp->ar_data[ 0], 6); 783 784 (*packetHandler)(0,0,0,0); 785 } 786 break; 787 788 case PROT_IP: 789 #ifdef ET_DEBUG 790 printf("Got IP\n"); 791 #endif 792 if (len < IP_HDR_SIZE) { 793 debug ("len bad %d < %d\n", len, IP_HDR_SIZE); 794 return; 795 } 796 if (len < ntohs(ip->ip_len)) { 797 printf("len bad %d < %d\n", len, ntohs(ip->ip_len)); 798 return; 799 } 800 len = ntohs(ip->ip_len); 801 #ifdef ET_DEBUG 802 printf("len=%d, v=%02x\n", len, ip->ip_hl_v & 0xff); 803 #endif 804 if ((ip->ip_hl_v & 0xf0) != 0x40) { 805 return; 806 } 807 if (ip->ip_off & htons(0x1fff)) { /* Can't deal w/ fragments */ 808 return; 809 } 810 if (!NetCksumOk((uchar *)ip, IP_HDR_SIZE_NO_UDP / 2)) { 811 printf("checksum bad\n"); 812 return; 813 } 814 tmp = NetReadIP(&ip->ip_dst); 815 if (NetOurIP && tmp != NetOurIP && tmp != 0xFFFFFFFF) { 816 return; 817 } 818 /* 819 * watch for ICMP host redirects 820 * 821 * There is no real handler code (yet). We just watch 822 * for ICMP host redirect messages. In case anybody 823 * sees these messages: please contact me 824 * (wd@denx.de), or - even better - send me the 825 * necessary fixes :-) 826 * 827 * Note: in all cases where I have seen this so far 828 * it was a problem with the router configuration, 829 * for instance when a router was configured in the 830 * BOOTP reply, but the TFTP server was on the same 831 * subnet. So this is probably a warning that your 832 * configuration might be wrong. But I'm not really 833 * sure if there aren't any other situations. 834 */ 835 if (ip->ip_p == IPPROTO_ICMP) { 836 ICMP_t *icmph = (ICMP_t *)&(ip->udp_src); 837 838 switch (icmph->type) { 839 case ICMP_REDIRECT: 840 if (icmph->code != ICMP_REDIR_HOST) 841 return; 842 puts (" ICMP Host Redirect to "); 843 print_IPaddr(icmph->un.gateway); 844 putc(' '); 845 break; 846 #if (CONFIG_COMMANDS & CFG_CMD_PING) 847 case ICMP_ECHO_REPLY: 848 /* 849 * IP header OK. Pass the packet to the current handler. 850 */ 851 /* XXX point to ip packet */ 852 (*packetHandler)((uchar *)ip, 0, 0, 0); 853 break; 854 #endif 855 default: 856 return; 857 } 858 } else if (ip->ip_p != IPPROTO_UDP) { /* Only UDP packets */ 859 return; 860 } 861 862 /* 863 * IP header OK. Pass the packet to the current handler. 864 */ 865 (*packetHandler)((uchar *)ip +IP_HDR_SIZE, 866 ntohs(ip->udp_dst), 867 ntohs(ip->udp_src), 868 ntohs(ip->udp_len) - 8); 869 870 break; 871 } 872 } 873 874 875 /**********************************************************************/ 876 877 static int net_check_prereq (proto_t protocol) 878 { 879 switch (protocol) { 880 /* Fall through */ 881 #if (CONFIG_COMMANDS & CFG_CMD_PING) 882 case PING: 883 if (NetPingIP == 0) { 884 puts ("*** ERROR: ping address not given\n"); 885 return (1); 886 } 887 goto common; 888 #endif 889 case TFTP: 890 if (NetServerIP == 0) { 891 puts ("*** ERROR: `serverip' not set\n"); 892 return (1); 893 } 894 895 #if (CONFIG_COMMANDS & CFG_CMD_PING) 896 common: 897 #endif 898 899 if (NetOurIP == 0) { 900 puts ("*** ERROR: `ipaddr' not set\n"); 901 return (1); 902 } 903 /* Fall through */ 904 905 case DHCP: 906 case RARP: 907 case BOOTP: 908 if (memcmp(NetOurEther, "\0\0\0\0\0\0", 6) == 0) { 909 #ifdef CONFIG_NET_MULTI 910 extern int eth_get_dev_index (void); 911 int num = eth_get_dev_index(); 912 913 switch (num) { 914 case -1: 915 puts ("*** ERROR: No ethernet found.\n"); 916 return (1); 917 case 0: 918 puts ("*** ERROR: `ethaddr' not set\n"); 919 break; 920 default: 921 printf ("*** ERROR: `eth%daddr' not set\n", 922 num); 923 break; 924 } 925 926 NetStartAgain (); 927 return (2); 928 #else 929 puts ("*** ERROR: `ethaddr' not set\n"); 930 return (1); 931 #endif 932 } 933 /* Fall through */ 934 default: 935 return(0); 936 } 937 return (0); /* OK */ 938 } 939 /**********************************************************************/ 940 941 int 942 NetCksumOk(uchar * ptr, int len) 943 { 944 return !((NetCksum(ptr, len) + 1) & 0xfffe); 945 } 946 947 948 unsigned 949 NetCksum(uchar * ptr, int len) 950 { 951 ulong xsum; 952 953 xsum = 0; 954 while (len-- > 0) 955 xsum += *((ushort *)ptr)++; 956 xsum = (xsum & 0xffff) + (xsum >> 16); 957 xsum = (xsum & 0xffff) + (xsum >> 16); 958 return (xsum & 0xffff); 959 } 960 961 962 void 963 NetSetEther(volatile uchar * xet, uchar * addr, uint prot) 964 { 965 Ethernet_t *et = (Ethernet_t *)xet; 966 967 memcpy (et->et_dest, addr, 6); 968 memcpy (et->et_src, NetOurEther, 6); 969 et->et_protlen = htons(prot); 970 } 971 972 973 void 974 NetSetIP(volatile uchar * xip, IPaddr_t dest, int dport, int sport, int len) 975 { 976 volatile IP_t *ip = (IP_t *)xip; 977 978 /* 979 * If the data is an odd number of bytes, zero the 980 * byte after the last byte so that the checksum 981 * will work. 982 */ 983 if (len & 1) 984 xip[IP_HDR_SIZE + len] = 0; 985 986 /* 987 * Construct an IP and UDP header. 988 (need to set no fragment bit - XXX) 989 */ 990 ip->ip_hl_v = 0x45; /* IP_HDR_SIZE / 4 (not including UDP) */ 991 ip->ip_tos = 0; 992 ip->ip_len = htons(IP_HDR_SIZE + len); 993 ip->ip_id = htons(NetIPID++); 994 ip->ip_off = htons(0x4000); /* No fragmentation */ 995 ip->ip_ttl = 255; 996 ip->ip_p = 17; /* UDP */ 997 ip->ip_sum = 0; 998 NetCopyIP((void*)&ip->ip_src, &NetOurIP); /* already in network byte order */ 999 NetCopyIP((void*)&ip->ip_dst, &dest); /* - "" - */ 1000 ip->udp_src = htons(sport); 1001 ip->udp_dst = htons(dport); 1002 ip->udp_len = htons(8 + len); 1003 ip->udp_xsum = 0; 1004 ip->ip_sum = ~NetCksum((uchar *)ip, IP_HDR_SIZE_NO_UDP / 2); 1005 } 1006 1007 void copy_filename (uchar *dst, uchar *src, int size) 1008 { 1009 if (*src && (*src == '"')) { 1010 ++src; 1011 --size; 1012 } 1013 1014 while ((--size > 0) && *src && (*src != '"')) { 1015 *dst++ = *src++; 1016 } 1017 *dst = '\0'; 1018 } 1019 1020 #endif /* CFG_CMD_NET */ 1021 1022 void ip_to_string (IPaddr_t x, char *s) 1023 { 1024 x = ntohl(x); 1025 sprintf (s,"%d.%d.%d.%d", 1026 (int)((x >> 24) & 0xff), 1027 (int)((x >> 16) & 0xff), 1028 (int)((x >> 8) & 0xff), 1029 (int)((x >> 0) & 0xff) 1030 ); 1031 } 1032 1033 IPaddr_t string_to_ip(char *s) 1034 { 1035 IPaddr_t addr; 1036 char *e; 1037 int i; 1038 1039 if (s == NULL) 1040 return(0); 1041 1042 for (addr=0, i=0; i<4; ++i) { 1043 ulong val = s ? simple_strtoul(s, &e, 10) : 0; 1044 addr <<= 8; 1045 addr |= (val & 0xFF); 1046 if (s) { 1047 s = (*e) ? e+1 : e; 1048 } 1049 } 1050 1051 return (htonl(addr)); 1052 } 1053 1054 void print_IPaddr (IPaddr_t x) 1055 { 1056 char tmp[16]; 1057 1058 ip_to_string(x, tmp); 1059 1060 puts(tmp); 1061 } 1062 1063 IPaddr_t getenv_IPaddr (char *var) 1064 { 1065 return (string_to_ip(getenv(var))); 1066 } 1067