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 eth_init(bd); 255 256 restart: 257 #ifdef CONFIG_NET_MULTI 258 memcpy (NetOurEther, eth_get_dev()->enetaddr, 6); 259 #else 260 memcpy (NetOurEther, bd->bi_enetaddr, 6); 261 #endif 262 263 NetState = NETLOOP_CONTINUE; 264 265 /* 266 * Start the ball rolling with the given start function. From 267 * here on, this code is a state machine driven by received 268 * packets and timer events. 269 */ 270 271 switch (protocol) { 272 #if (CONFIG_COMMANDS & CFG_CMD_PING) 273 case PING: 274 #endif 275 case TFTP: 276 NetCopyIP(&NetOurIP, &bd->bi_ip_addr); 277 NetOurGatewayIP = getenv_IPaddr ("gatewayip"); 278 NetOurSubnetMask= getenv_IPaddr ("netmask"); 279 280 switch (protocol) { 281 case TFTP: 282 NetServerIP = getenv_IPaddr ("serverip"); 283 break; 284 #if (CONFIG_COMMANDS & CFG_CMD_PING) 285 case PING: 286 /* nothing */ 287 break; 288 #endif 289 default: 290 break; 291 } 292 293 break; 294 case BOOTP: 295 case RARP: 296 /* 297 * initialize our IP addr to 0 in order to accept ANY 298 * IP addr assigned to us by the BOOTP / RARP server 299 */ 300 NetOurIP = 0; 301 NetServerIP = 0; 302 break; 303 default: 304 break; 305 } 306 307 switch (net_check_prereq (protocol)) { 308 case 1: 309 /* network not configured */ 310 return (-1); 311 312 #ifdef CONFIG_NET_MULTI 313 case 2: 314 /* network device not configured */ 315 break; 316 #endif /* CONFIG_NET_MULTI */ 317 318 case 0: 319 #ifdef CONFIG_NET_MULTI 320 NetDevExists = 1; 321 #endif 322 switch (protocol) { 323 case TFTP: 324 /* always use ARP to get server ethernet address */ 325 TftpStart(); 326 break; 327 328 #if (CONFIG_COMMANDS & CFG_CMD_DHCP) 329 case DHCP: 330 /* Start with a clean slate... */ 331 NetOurIP = 0; 332 NetServerIP = 0; 333 DhcpRequest(); /* Basically same as BOOTP */ 334 break; 335 #endif /* CFG_CMD_DHCP */ 336 337 case BOOTP: 338 BootpTry = 0; 339 BootpRequest (); 340 break; 341 342 case RARP: 343 RarpTry = 0; 344 RarpRequest (); 345 break; 346 #if (CONFIG_COMMANDS & CFG_CMD_PING) 347 case PING: 348 PingStart(); 349 break; 350 #endif 351 default: 352 break; 353 } 354 355 NetBootFileXferSize = 0; 356 break; 357 } 358 359 360 /* 361 * Main packet reception loop. Loop receiving packets until 362 * someone sets `NetQuit'. 363 */ 364 for (;;) { 365 WATCHDOG_RESET(); 366 #ifdef CONFIG_SHOW_ACTIVITY 367 { 368 extern void show_activity(int arg); 369 show_activity(1); 370 } 371 #endif 372 /* 373 * Check the ethernet for a new packet. The ethernet 374 * receive routine will process it. 375 */ 376 eth_rx(); 377 378 /* 379 * Abort if ctrl-c was pressed. 380 */ 381 if (ctrlc()) { 382 eth_halt(); 383 printf("\nAbort\n"); 384 return (-1); 385 } 386 387 ArpTimeoutCheck(); 388 389 /* 390 * Check for a timeout, and run the timeout handler 391 * if we have one. 392 */ 393 if (timeHandler && (get_timer(0) > timeValue)) { 394 thand_f *x; 395 396 x = timeHandler; 397 timeHandler = (thand_f *)0; 398 (*x)(); 399 } 400 401 402 switch (NetState) { 403 404 case NETLOOP_RESTART: 405 #ifdef CONFIG_NET_MULTI 406 NetRestarted = 1; 407 #endif 408 goto restart; 409 410 case NETLOOP_SUCCESS: 411 if (NetBootFileXferSize > 0) { 412 char buf[10]; 413 printf("Bytes transferred = %ld (%lx hex)\n", 414 NetBootFileXferSize, 415 NetBootFileXferSize); 416 sprintf(buf, "%lx", NetBootFileXferSize); 417 setenv("filesize", buf); 418 } 419 eth_halt(); 420 return NetBootFileXferSize; 421 422 case NETLOOP_FAIL: 423 return (-1); 424 } 425 } 426 } 427 428 /**********************************************************************/ 429 430 static void 431 startAgainTimeout(void) 432 { 433 NetState = NETLOOP_RESTART; 434 } 435 436 static void 437 startAgainHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len) 438 { 439 /* Totally ignore the packet */ 440 } 441 442 void 443 NetStartAgain(void) 444 { 445 #ifndef CONFIG_NET_MULTI 446 NetSetTimeout(10 * CFG_HZ, startAgainTimeout); 447 NetSetHandler(startAgainHandler); 448 #else 449 DECLARE_GLOBAL_DATA_PTR; 450 451 eth_halt(); 452 eth_try_another(!NetRestarted); 453 eth_init(gd->bd); 454 if (NetRestartWrap) 455 { 456 NetRestartWrap = 0; 457 if (NetDevExists) 458 { 459 NetSetTimeout(10 * CFG_HZ, startAgainTimeout); 460 NetSetHandler(startAgainHandler); 461 } 462 else 463 { 464 NetState = NETLOOP_FAIL; 465 } 466 } 467 else 468 { 469 NetState = NETLOOP_RESTART; 470 } 471 #endif 472 } 473 474 /**********************************************************************/ 475 /* 476 * Miscelaneous bits. 477 */ 478 479 void 480 NetSetHandler(rxhand_f * f) 481 { 482 packetHandler = f; 483 } 484 485 486 void 487 NetSetTimeout(int iv, thand_f * f) 488 { 489 if (iv == 0) { 490 timeHandler = (thand_f *)0; 491 } else { 492 timeHandler = f; 493 timeValue = get_timer(0) + iv; 494 } 495 } 496 497 498 void 499 NetSendPacket(volatile uchar * pkt, int len) 500 { 501 (void) eth_send(pkt, len); 502 } 503 504 int 505 NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport, int sport, int len) 506 { 507 /* convert to new style broadcast */ 508 if (dest == 0) 509 dest = 0xFFFFFFFF; 510 511 /* if broadcast, make the ether address a broadcast and don't do ARP */ 512 if (dest == 0xFFFFFFFF) 513 ether = NetBcastAddr; 514 515 /* if MAC address was not discovered yet, save the packet and do an ARP request */ 516 if (memcmp(ether, NetEtherNullAddr, 6) == 0) { 517 518 #ifdef ET_DEBUG 519 printf("sending ARP for %08lx\n", dest); 520 #endif 521 522 NetArpWaitPacketIP = dest; 523 NetArpWaitPacketMAC = ether; 524 NetSetEther (NetArpWaitTxPacket, NetArpWaitPacketMAC, PROT_IP); 525 NetSetIP (NetArpWaitTxPacket + ETHER_HDR_SIZE, dest, dport, sport, len); 526 memcpy(NetArpWaitTxPacket + ETHER_HDR_SIZE + IP_HDR_SIZE, 527 (uchar *)NetTxPacket + ETHER_HDR_SIZE + IP_HDR_SIZE, len); 528 529 /* size of the waiting packet */ 530 NetArpWaitTxPacketSize = ETHER_HDR_SIZE + IP_HDR_SIZE + len; 531 532 /* and do the ARP request */ 533 NetArpWaitTry = 1; 534 NetArpWaitTimerStart = get_timer(0); 535 ArpRequest(); 536 return 1; /* waiting */ 537 } 538 539 #ifdef ET_DEBUG 540 printf("sending UDP to %08lx/%02x:%02x:%02x:%02x:%02x:%02x\n", 541 dest, ether[0], ether[1], ether[2], ether[3], ether[4], ether[5]); 542 #endif 543 544 NetSetEther (NetTxPacket, ether, PROT_IP); 545 NetSetIP (NetTxPacket + ETHER_HDR_SIZE, dest, dport, sport, len); 546 (void) eth_send(NetTxPacket, ETHER_HDR_SIZE + IP_HDR_SIZE + len); 547 548 return 0; /* transmited */ 549 } 550 551 #if (CONFIG_COMMANDS & CFG_CMD_PING) 552 static ushort PingSeqNo; 553 554 int PingSend(void) 555 { 556 static uchar mac[6]; 557 volatile IP_t *ip; 558 volatile ushort *s; 559 560 /* XXX always send arp request */ 561 562 memcpy(mac, NetEtherNullAddr, 6); 563 564 #ifdef ET_DEBUG 565 printf("sending ARP for %08lx\n", NetPingIP); 566 #endif 567 568 NetArpWaitPacketIP = NetPingIP; 569 NetArpWaitPacketMAC = mac; 570 571 NetSetEther(NetArpWaitTxPacket, mac, PROT_IP); 572 573 ip = (volatile IP_t *)(NetArpWaitTxPacket + ETHER_HDR_SIZE); 574 575 /* 576 * Construct an IP and ICMP header. (need to set no fragment bit - XXX) 577 */ 578 ip->ip_hl_v = 0x45; /* IP_HDR_SIZE / 4 (not including UDP) */ 579 ip->ip_tos = 0; 580 ip->ip_len = htons(IP_HDR_SIZE_NO_UDP + 8); 581 ip->ip_id = htons(NetIPID++); 582 ip->ip_off = htons(0x4000); /* No fragmentation */ 583 ip->ip_ttl = 255; 584 ip->ip_p = 0x01; /* ICMP */ 585 ip->ip_sum = 0; 586 NetCopyIP((void*)&ip->ip_src, &NetOurIP); /* already in network byte order */ 587 NetCopyIP((void*)&ip->ip_dst, &NetPingIP); /* - "" - */ 588 ip->ip_sum = ~NetCksum((uchar *)ip, IP_HDR_SIZE_NO_UDP / 2); 589 590 s = &ip->udp_src; /* XXX ICMP starts here */ 591 s[0] = htons(0x0800); /* echo-request, code */ 592 s[1] = 0; /* checksum */ 593 s[2] = 0; /* identifier */ 594 s[3] = htons(PingSeqNo++); /* sequence number */ 595 s[1] = ~NetCksum((uchar *)s, 8/2); 596 597 /* size of the waiting packet */ 598 NetArpWaitTxPacketSize = ETHER_HDR_SIZE + IP_HDR_SIZE_NO_UDP + 8; 599 600 /* and do the ARP request */ 601 NetArpWaitTry = 1; 602 NetArpWaitTimerStart = get_timer(0); 603 ArpRequest(); 604 return 1; /* waiting */ 605 } 606 607 static void 608 PingTimeout (void) 609 { 610 eth_halt(); 611 NetState = NETLOOP_FAIL; /* we did not get the reply */ 612 } 613 614 static void 615 PingHandler (uchar * pkt, unsigned dest, unsigned src, unsigned len) 616 { 617 IPaddr_t tmp; 618 volatile IP_t *ip = (volatile IP_t *)pkt; 619 620 tmp = NetReadIP((void *)&ip->ip_src); 621 if (tmp != NetPingIP) 622 return; 623 624 NetState = NETLOOP_SUCCESS; 625 } 626 627 static void PingStart(void) 628 { 629 NetSetTimeout (10 * CFG_HZ, PingTimeout); 630 NetSetHandler (PingHandler); 631 632 PingSend(); 633 } 634 635 #endif 636 637 void 638 NetReceive(volatile uchar * pkt, int len) 639 { 640 Ethernet_t *et; 641 IP_t *ip; 642 ARP_t *arp; 643 IPaddr_t tmp; 644 int x; 645 646 NetRxPkt = pkt; 647 NetRxPktLen = len; 648 et = (Ethernet_t *)pkt; 649 650 x = ntohs(et->et_protlen); 651 652 if (x < 1514) { 653 /* 654 * Got a 802 packet. Check the other protocol field. 655 */ 656 x = ntohs(et->et_prot); 657 ip = (IP_t *)(pkt + E802_HDR_SIZE); 658 len -= E802_HDR_SIZE; 659 } else { 660 ip = (IP_t *)(pkt + ETHER_HDR_SIZE); 661 len -= ETHER_HDR_SIZE; 662 } 663 664 #ifdef ET_DEBUG 665 printf("Receive from protocol 0x%x\n", x); 666 #endif 667 668 switch (x) { 669 670 case PROT_ARP: 671 /* 672 * We have to deal with two types of ARP packets: 673 * - REQUEST packets will be answered by sending our 674 * IP address - if we know it. 675 * - REPLY packates are expected only after we asked 676 * for the TFTP server's or the gateway's ethernet 677 * address; so if we receive such a packet, we set 678 * the server ethernet address 679 */ 680 #ifdef ET_DEBUG 681 printf("Got ARP\n"); 682 #endif 683 arp = (ARP_t *)ip; 684 if (len < ARP_HDR_SIZE) { 685 printf("bad length %d < %d\n", len, ARP_HDR_SIZE); 686 return; 687 } 688 if (ntohs(arp->ar_hrd) != ARP_ETHER) { 689 return; 690 } 691 if (ntohs(arp->ar_pro) != PROT_IP) { 692 return; 693 } 694 if (arp->ar_hln != 6) { 695 return; 696 } 697 if (arp->ar_pln != 4) { 698 return; 699 } 700 701 if (NetOurIP == 0) { 702 return; 703 } 704 705 if (NetReadIP(&arp->ar_data[16]) != NetOurIP) { 706 return; 707 } 708 709 switch (ntohs(arp->ar_op)) { 710 case ARPOP_REQUEST: /* reply with our IP address */ 711 #ifdef ET_DEBUG 712 printf("Got ARP REQUEST, return our IP\n"); 713 #endif 714 NetSetEther((uchar *)et, et->et_src, PROT_ARP); 715 arp->ar_op = htons(ARPOP_REPLY); 716 memcpy (&arp->ar_data[10], &arp->ar_data[0], 6); 717 NetCopyIP(&arp->ar_data[16], &arp->ar_data[6]); 718 memcpy (&arp->ar_data[ 0], NetOurEther, 6); 719 NetCopyIP(&arp->ar_data[ 6], &NetOurIP); 720 (void) eth_send((uchar *)et, ((uchar *)arp-pkt) + ARP_HDR_SIZE); 721 return; 722 723 case ARPOP_REPLY: /* arp reply */ 724 /* are we waiting for a reply */ 725 if (!NetArpWaitPacketIP || !NetArpWaitPacketMAC) 726 break; 727 #ifdef ET_DEBUG 728 printf("Got ARP REPLY, set server/gtwy eth addr (%02x:%02x:%02x:%02x:%02x:%02x)\n", 729 arp->ar_data[0], arp->ar_data[1], 730 arp->ar_data[2], arp->ar_data[3], 731 arp->ar_data[4], arp->ar_data[5]); 732 #endif 733 734 tmp = NetReadIP(&arp->ar_data[6]); 735 736 /* matched waiting packet's address */ 737 if (tmp == NetArpWaitReplyIP) { 738 #ifdef ET_DEBUG 739 printf("Got it\n"); 740 #endif 741 /* save address for later use */ 742 memcpy(NetArpWaitPacketMAC, &arp->ar_data[0], 6); 743 744 /* modify header, and transmit it */ 745 memcpy(((Ethernet_t *)NetArpWaitTxPacket)->et_dest, NetArpWaitPacketMAC, 6); 746 (void) eth_send(NetArpWaitTxPacket, NetArpWaitTxPacketSize); 747 748 /* no arp request pending now */ 749 NetArpWaitPacketIP = 0; 750 NetArpWaitTxPacketSize = 0; 751 NetArpWaitPacketMAC = NULL; 752 753 } 754 return; 755 default: 756 #ifdef ET_DEBUG 757 printf("Unexpected ARP opcode 0x%x\n", ntohs(arp->ar_op)); 758 #endif 759 return; 760 } 761 762 case PROT_RARP: 763 #ifdef ET_DEBUG 764 printf("Got RARP\n"); 765 #endif 766 arp = (ARP_t *)ip; 767 if (len < ARP_HDR_SIZE) { 768 printf("bad length %d < %d\n", len, ARP_HDR_SIZE); 769 return; 770 } 771 772 if ((ntohs(arp->ar_op) != RARPOP_REPLY) || 773 (ntohs(arp->ar_hrd) != ARP_ETHER) || 774 (ntohs(arp->ar_pro) != PROT_IP) || 775 (arp->ar_hln != 6) || (arp->ar_pln != 4)) { 776 777 printf("invalid RARP header\n"); 778 } else { 779 NetCopyIP(&NetOurIP, &arp->ar_data[16]); 780 NetCopyIP(&NetServerIP, &arp->ar_data[ 6]); 781 memcpy (NetServerEther, &arp->ar_data[ 0], 6); 782 783 (*packetHandler)(0,0,0,0); 784 } 785 break; 786 787 case PROT_IP: 788 #ifdef ET_DEBUG 789 printf("Got IP\n"); 790 #endif 791 if (len < IP_HDR_SIZE) { 792 debug ("len bad %d < %d\n", len, IP_HDR_SIZE); 793 return; 794 } 795 if (len < ntohs(ip->ip_len)) { 796 printf("len bad %d < %d\n", len, ntohs(ip->ip_len)); 797 return; 798 } 799 len = ntohs(ip->ip_len); 800 #ifdef ET_DEBUG 801 printf("len=%d, v=%02x\n", len, ip->ip_hl_v & 0xff); 802 #endif 803 if ((ip->ip_hl_v & 0xf0) != 0x40) { 804 return; 805 } 806 if (ip->ip_off & htons(0x1fff)) { /* Can't deal w/ fragments */ 807 return; 808 } 809 if (!NetCksumOk((uchar *)ip, IP_HDR_SIZE_NO_UDP / 2)) { 810 printf("checksum bad\n"); 811 return; 812 } 813 tmp = NetReadIP(&ip->ip_dst); 814 if (NetOurIP && tmp != NetOurIP && tmp != 0xFFFFFFFF) { 815 return; 816 } 817 /* 818 * watch for ICMP host redirects 819 * 820 * There is no real handler code (yet). We just watch 821 * for ICMP host redirect messages. In case anybody 822 * sees these messages: please contact me 823 * (wd@denx.de), or - even better - send me the 824 * necessary fixes :-) 825 * 826 * Note: in all cases where I have seen this so far 827 * it was a problem with the router configuration, 828 * for instance when a router was configured in the 829 * BOOTP reply, but the TFTP server was on the same 830 * subnet. So this is probably a warning that your 831 * configuration might be wrong. But I'm not really 832 * sure if there aren't any other situations. 833 */ 834 if (ip->ip_p == IPPROTO_ICMP) { 835 ICMP_t *icmph = (ICMP_t *)&(ip->udp_src); 836 837 switch (icmph->type) { 838 case ICMP_REDIRECT: 839 if (icmph->code != ICMP_REDIR_HOST) 840 return; 841 puts (" ICMP Host Redirect to "); 842 print_IPaddr(icmph->un.gateway); 843 putc(' '); 844 break; 845 #if (CONFIG_COMMANDS & CFG_CMD_PING) 846 case ICMP_ECHO_REPLY: 847 /* 848 * IP header OK. Pass the packet to the current handler. 849 */ 850 /* XXX point to ip packet */ 851 (*packetHandler)((uchar *)ip, 0, 0, 0); 852 break; 853 #endif 854 default: 855 return; 856 } 857 } else if (ip->ip_p != IPPROTO_UDP) { /* Only UDP packets */ 858 return; 859 } 860 861 /* 862 * IP header OK. Pass the packet to the current handler. 863 */ 864 (*packetHandler)((uchar *)ip +IP_HDR_SIZE, 865 ntohs(ip->udp_dst), 866 ntohs(ip->udp_src), 867 ntohs(ip->udp_len) - 8); 868 869 break; 870 } 871 } 872 873 874 /**********************************************************************/ 875 876 static int net_check_prereq (proto_t protocol) 877 { 878 switch (protocol) { 879 /* Fall through */ 880 #if (CONFIG_COMMANDS & CFG_CMD_PING) 881 case PING: 882 if (NetPingIP == 0) { 883 puts ("*** ERROR: ping address not given\n"); 884 return (1); 885 } 886 goto common; 887 #endif 888 case TFTP: 889 if (NetServerIP == 0) { 890 puts ("*** ERROR: `serverip' not set\n"); 891 return (1); 892 } 893 894 #if (CONFIG_COMMANDS & CFG_CMD_PING) 895 common: 896 #endif 897 898 if (NetOurIP == 0) { 899 puts ("*** ERROR: `ipaddr' not set\n"); 900 return (1); 901 } 902 /* Fall through */ 903 904 case DHCP: 905 case RARP: 906 case BOOTP: 907 if (memcmp(NetOurEther, "\0\0\0\0\0\0", 6) == 0) { 908 #ifdef CONFIG_NET_MULTI 909 extern int eth_get_dev_index (void); 910 int num = eth_get_dev_index(); 911 912 switch (num) { 913 case -1: 914 puts ("*** ERROR: No ethernet found.\n"); 915 return (1); 916 case 0: 917 puts ("*** ERROR: `ethaddr' not set\n"); 918 break; 919 default: 920 printf ("*** ERROR: `eth%daddr' not set\n", 921 num); 922 break; 923 } 924 925 NetStartAgain (); 926 return (2); 927 #else 928 puts ("*** ERROR: `ethaddr' not set\n"); 929 return (1); 930 #endif 931 } 932 /* Fall through */ 933 default: 934 return(0); 935 } 936 return (0); /* OK */ 937 } 938 /**********************************************************************/ 939 940 int 941 NetCksumOk(uchar * ptr, int len) 942 { 943 return !((NetCksum(ptr, len) + 1) & 0xfffe); 944 } 945 946 947 unsigned 948 NetCksum(uchar * ptr, int len) 949 { 950 ulong xsum; 951 952 xsum = 0; 953 while (len-- > 0) 954 xsum += *((ushort *)ptr)++; 955 xsum = (xsum & 0xffff) + (xsum >> 16); 956 xsum = (xsum & 0xffff) + (xsum >> 16); 957 return (xsum & 0xffff); 958 } 959 960 961 void 962 NetSetEther(volatile uchar * xet, uchar * addr, uint prot) 963 { 964 Ethernet_t *et = (Ethernet_t *)xet; 965 966 memcpy (et->et_dest, addr, 6); 967 memcpy (et->et_src, NetOurEther, 6); 968 et->et_protlen = htons(prot); 969 } 970 971 972 void 973 NetSetIP(volatile uchar * xip, IPaddr_t dest, int dport, int sport, int len) 974 { 975 volatile IP_t *ip = (IP_t *)xip; 976 977 /* 978 * If the data is an odd number of bytes, zero the 979 * byte after the last byte so that the checksum 980 * will work. 981 */ 982 if (len & 1) 983 xip[IP_HDR_SIZE + len] = 0; 984 985 /* 986 * Construct an IP and UDP header. 987 (need to set no fragment bit - XXX) 988 */ 989 ip->ip_hl_v = 0x45; /* IP_HDR_SIZE / 4 (not including UDP) */ 990 ip->ip_tos = 0; 991 ip->ip_len = htons(IP_HDR_SIZE + len); 992 ip->ip_id = htons(NetIPID++); 993 ip->ip_off = htons(0x4000); /* No fragmentation */ 994 ip->ip_ttl = 255; 995 ip->ip_p = 17; /* UDP */ 996 ip->ip_sum = 0; 997 NetCopyIP((void*)&ip->ip_src, &NetOurIP); /* already in network byte order */ 998 NetCopyIP((void*)&ip->ip_dst, &dest); /* - "" - */ 999 ip->udp_src = htons(sport); 1000 ip->udp_dst = htons(dport); 1001 ip->udp_len = htons(8 + len); 1002 ip->udp_xsum = 0; 1003 ip->ip_sum = ~NetCksum((uchar *)ip, IP_HDR_SIZE_NO_UDP / 2); 1004 } 1005 1006 void copy_filename (uchar *dst, uchar *src, int size) 1007 { 1008 if (*src && (*src == '"')) { 1009 ++src; 1010 --size; 1011 } 1012 1013 while ((--size > 0) && *src && (*src != '"')) { 1014 *dst++ = *src++; 1015 } 1016 *dst = '\0'; 1017 } 1018 1019 #endif /* CFG_CMD_NET */ 1020 1021 void ip_to_string (IPaddr_t x, char *s) 1022 { 1023 x = ntohl(x); 1024 sprintf (s,"%d.%d.%d.%d", 1025 (int)((x >> 24) & 0xff), 1026 (int)((x >> 16) & 0xff), 1027 (int)((x >> 8) & 0xff), 1028 (int)((x >> 0) & 0xff) 1029 ); 1030 } 1031 1032 IPaddr_t string_to_ip(char *s) 1033 { 1034 IPaddr_t addr; 1035 char *e; 1036 int i; 1037 1038 if (s == NULL) 1039 return(0); 1040 1041 for (addr=0, i=0; i<4; ++i) { 1042 ulong val = s ? simple_strtoul(s, &e, 10) : 0; 1043 addr <<= 8; 1044 addr |= (val & 0xFF); 1045 if (s) { 1046 s = (*e) ? e+1 : e; 1047 } 1048 } 1049 1050 return (htonl(addr)); 1051 } 1052 1053 void print_IPaddr (IPaddr_t x) 1054 { 1055 char tmp[16]; 1056 1057 ip_to_string(x, tmp); 1058 1059 puts(tmp); 1060 } 1061 1062 IPaddr_t getenv_IPaddr (char *var) 1063 { 1064 return (string_to_ip(getenv(var))); 1065 } 1066