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 * NFS: 60 * 61 * Prerequisites: - own ethernet address 62 * - own IP address 63 * - name of bootfile (if unknown, we use a default name 64 * derived from our own IP address) 65 * We want: - load the boot file 66 * Next step: none 67 */ 68 69 70 #include <common.h> 71 #include <watchdog.h> 72 #include <command.h> 73 #include <net.h> 74 #include "bootp.h" 75 #include "tftp.h" 76 #include "rarp.h" 77 #include "nfs.h" 78 #ifdef CONFIG_STATUS_LED 79 #include <status_led.h> 80 #include <miiphy.h> 81 #endif 82 83 #if (CONFIG_COMMANDS & CFG_CMD_NET) 84 85 #define ARP_TIMEOUT 5 /* Seconds before trying ARP again */ 86 #ifndef CONFIG_NET_RETRY_COUNT 87 # define ARP_TIMEOUT_COUNT 5 /* # of timeouts before giving up */ 88 #else 89 # define ARP_TIMEOUT_COUNT (CONFIG_NET_RETRY_COUNT) 90 #endif 91 92 #if 0 93 #define ET_DEBUG 94 #endif 95 96 /** BOOTP EXTENTIONS **/ 97 98 IPaddr_t NetOurSubnetMask=0; /* Our subnet mask (0=unknown) */ 99 IPaddr_t NetOurGatewayIP=0; /* Our gateways IP address */ 100 IPaddr_t NetOurDNSIP=0; /* Our DNS IP address */ 101 #if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_DNS2) 102 IPaddr_t NetOurDNS2IP=0; /* Our 2nd DNS IP address */ 103 #endif 104 char NetOurNISDomain[32]={0,}; /* Our NIS domain */ 105 char NetOurHostName[32]={0,}; /* Our hostname */ 106 char NetOurRootPath[64]={0,}; /* Our bootpath */ 107 ushort NetBootFileSize=0; /* Our bootfile size in blocks */ 108 109 /** END OF BOOTP EXTENTIONS **/ 110 111 ulong NetBootFileXferSize; /* The actual transferred size of the bootfile (in bytes) */ 112 uchar NetOurEther[6]; /* Our ethernet address */ 113 uchar NetServerEther[6] = /* Boot server enet address */ 114 { 0, 0, 0, 0, 0, 0 }; 115 IPaddr_t NetOurIP; /* Our IP addr (0 = unknown) */ 116 IPaddr_t NetServerIP; /* Our IP addr (0 = unknown) */ 117 volatile uchar *NetRxPkt; /* Current receive packet */ 118 int NetRxPktLen; /* Current rx packet length */ 119 unsigned NetIPID; /* IP packet ID */ 120 uchar NetBcastAddr[6] = /* Ethernet bcast address */ 121 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 122 uchar NetEtherNullAddr[6] = 123 { 0, 0, 0, 0, 0, 0 }; 124 #if (CONFIG_COMMANDS & CFG_CMD_CDP) 125 uchar NetCDPAddr[6] = /* Ethernet bcast address */ 126 { 0x01, 0x00, 0x0c, 0xcc, 0xcc, 0xcc }; 127 #endif 128 int NetState; /* Network loop state */ 129 #ifdef CONFIG_NET_MULTI 130 int NetRestartWrap = 0; /* Tried all network devices */ 131 static int NetRestarted = 0; /* Network loop restarted */ 132 static int NetDevExists = 0; /* At least one device configured */ 133 #endif 134 135 /* XXX in both little & big endian machines 0xFFFF == ntohs(-1) */ 136 ushort NetOurVLAN = 0xFFFF; /* default is without VLAN */ 137 ushort NetOurNativeVLAN = 0xFFFF; /* ditto */ 138 139 char BootFile[128]; /* Boot File name */ 140 141 #if (CONFIG_COMMANDS & CFG_CMD_PING) 142 IPaddr_t NetPingIP; /* the ip address to ping */ 143 144 static void PingStart(void); 145 #endif 146 147 #if (CONFIG_COMMANDS & CFG_CMD_CDP) 148 static void CDPStart(void); 149 #endif 150 151 #ifdef CONFIG_NETCONSOLE 152 void NcStart(void); 153 int nc_input_packet(uchar *pkt, unsigned dest, unsigned src, unsigned len); 154 #endif 155 156 volatile uchar PktBuf[(PKTBUFSRX+1) * PKTSIZE_ALIGN + PKTALIGN]; 157 158 volatile uchar *NetRxPackets[PKTBUFSRX]; /* Receive packets */ 159 160 static rxhand_f *packetHandler; /* Current RX packet handler */ 161 static thand_f *timeHandler; /* Current timeout handler */ 162 static ulong timeStart; /* Time base value */ 163 static ulong timeDelta; /* Current timeout value */ 164 volatile uchar *NetTxPacket = 0; /* THE transmit packet */ 165 166 static int net_check_prereq (proto_t protocol); 167 168 /**********************************************************************/ 169 170 IPaddr_t NetArpWaitPacketIP; 171 IPaddr_t NetArpWaitReplyIP; 172 uchar *NetArpWaitPacketMAC; /* MAC address of waiting packet's destination */ 173 uchar *NetArpWaitTxPacket; /* THE transmit packet */ 174 int NetArpWaitTxPacketSize; 175 uchar NetArpWaitPacketBuf[PKTSIZE_ALIGN + PKTALIGN]; 176 ulong NetArpWaitTimerStart; 177 int NetArpWaitTry; 178 179 void ArpRequest (void) 180 { 181 int i; 182 volatile uchar *pkt; 183 ARP_t *arp; 184 185 #ifdef ET_DEBUG 186 printf ("ARP broadcast %d\n", NetArpWaitTry); 187 #endif 188 pkt = NetTxPacket; 189 190 pkt += NetSetEther (pkt, NetBcastAddr, PROT_ARP); 191 192 arp = (ARP_t *) pkt; 193 194 arp->ar_hrd = htons (ARP_ETHER); 195 arp->ar_pro = htons (PROT_IP); 196 arp->ar_hln = 6; 197 arp->ar_pln = 4; 198 arp->ar_op = htons (ARPOP_REQUEST); 199 200 memcpy (&arp->ar_data[0], NetOurEther, 6); /* source ET addr */ 201 NetWriteIP ((uchar *) & arp->ar_data[6], NetOurIP); /* source IP addr */ 202 for (i = 10; i < 16; ++i) { 203 arp->ar_data[i] = 0; /* dest ET addr = 0 */ 204 } 205 206 if ((NetArpWaitPacketIP & NetOurSubnetMask) != 207 (NetOurIP & NetOurSubnetMask)) { 208 if (NetOurGatewayIP == 0) { 209 puts ("## Warning: gatewayip needed but not set\n"); 210 } 211 NetArpWaitReplyIP = NetOurGatewayIP; 212 } else { 213 NetArpWaitReplyIP = NetArpWaitPacketIP; 214 } 215 216 NetWriteIP ((uchar *) & arp->ar_data[16], NetArpWaitReplyIP); 217 (void) eth_send (NetTxPacket, (pkt - NetTxPacket) + ARP_HDR_SIZE); 218 } 219 220 void ArpTimeoutCheck(void) 221 { 222 ulong t; 223 224 if (!NetArpWaitPacketIP) 225 return; 226 227 t = get_timer(0); 228 229 /* check for arp timeout */ 230 if ((t - NetArpWaitTimerStart) > ARP_TIMEOUT * CFG_HZ) { 231 NetArpWaitTry++; 232 233 if (NetArpWaitTry >= ARP_TIMEOUT_COUNT) { 234 puts ("\nARP Retry count exceeded; starting again\n"); 235 NetArpWaitTry = 0; 236 NetStartAgain(); 237 } else { 238 NetArpWaitTimerStart = t; 239 ArpRequest(); 240 } 241 } 242 } 243 244 /**********************************************************************/ 245 /* 246 * Main network processing loop. 247 */ 248 249 int 250 NetLoop(proto_t protocol) 251 { 252 DECLARE_GLOBAL_DATA_PTR; 253 254 bd_t *bd = gd->bd; 255 256 #ifdef CONFIG_NET_MULTI 257 NetRestarted = 0; 258 NetDevExists = 0; 259 #endif 260 261 /* XXX problem with bss workaround */ 262 NetArpWaitPacketMAC = NULL; 263 NetArpWaitTxPacket = NULL; 264 NetArpWaitPacketIP = 0; 265 NetArpWaitReplyIP = 0; 266 NetArpWaitTxPacket = NULL; 267 NetTxPacket = NULL; 268 269 if (!NetTxPacket) { 270 int i; 271 /* 272 * Setup packet buffers, aligned correctly. 273 */ 274 NetTxPacket = &PktBuf[0] + (PKTALIGN - 1); 275 NetTxPacket -= (ulong)NetTxPacket % PKTALIGN; 276 for (i = 0; i < PKTBUFSRX; i++) { 277 NetRxPackets[i] = NetTxPacket + (i+1)*PKTSIZE_ALIGN; 278 } 279 } 280 281 if (!NetArpWaitTxPacket) { 282 NetArpWaitTxPacket = &NetArpWaitPacketBuf[0] + (PKTALIGN - 1); 283 NetArpWaitTxPacket -= (ulong)NetArpWaitTxPacket % PKTALIGN; 284 NetArpWaitTxPacketSize = 0; 285 } 286 287 eth_halt(); 288 #ifdef CONFIG_NET_MULTI 289 eth_set_current(); 290 #endif 291 if (eth_init(bd) < 0) 292 return(-1); 293 294 restart: 295 #ifdef CONFIG_NET_MULTI 296 memcpy (NetOurEther, eth_get_dev()->enetaddr, 6); 297 #else 298 memcpy (NetOurEther, bd->bi_enetaddr, 6); 299 #endif 300 301 NetState = NETLOOP_CONTINUE; 302 303 /* 304 * Start the ball rolling with the given start function. From 305 * here on, this code is a state machine driven by received 306 * packets and timer events. 307 */ 308 309 switch (protocol) { 310 #if (CONFIG_COMMANDS & CFG_CMD_NFS) 311 case NFS: 312 #endif 313 #if (CONFIG_COMMANDS & CFG_CMD_PING) 314 case PING: 315 #endif 316 case NETCONS: 317 case TFTP: 318 NetCopyIP(&NetOurIP, &bd->bi_ip_addr); 319 NetOurGatewayIP = getenv_IPaddr ("gatewayip"); 320 NetOurSubnetMask= getenv_IPaddr ("netmask"); 321 NetOurVLAN = getenv_VLAN("vlan"); 322 NetOurNativeVLAN = getenv_VLAN("nvlan"); 323 324 switch (protocol) { 325 #if (CONFIG_COMMANDS & CFG_CMD_NFS) 326 case NFS: 327 #endif 328 case NETCONS: 329 case TFTP: 330 NetServerIP = getenv_IPaddr ("serverip"); 331 break; 332 #if (CONFIG_COMMANDS & CFG_CMD_PING) 333 case PING: 334 /* nothing */ 335 break; 336 #endif 337 default: 338 break; 339 } 340 341 break; 342 case BOOTP: 343 case RARP: 344 /* 345 * initialize our IP addr to 0 in order to accept ANY 346 * IP addr assigned to us by the BOOTP / RARP server 347 */ 348 NetOurIP = 0; 349 NetServerIP = getenv_IPaddr ("serverip"); 350 NetOurVLAN = getenv_VLAN("vlan"); /* VLANs must be read */ 351 NetOurNativeVLAN = getenv_VLAN("nvlan"); 352 case CDP: 353 NetOurVLAN = getenv_VLAN("vlan"); /* VLANs must be read */ 354 NetOurNativeVLAN = getenv_VLAN("nvlan"); 355 break; 356 default: 357 break; 358 } 359 360 switch (net_check_prereq (protocol)) { 361 case 1: 362 /* network not configured */ 363 return (-1); 364 365 #ifdef CONFIG_NET_MULTI 366 case 2: 367 /* network device not configured */ 368 break; 369 #endif /* CONFIG_NET_MULTI */ 370 371 case 0: 372 #ifdef CONFIG_NET_MULTI 373 NetDevExists = 1; 374 #endif 375 switch (protocol) { 376 case TFTP: 377 /* always use ARP to get server ethernet address */ 378 TftpStart(); 379 break; 380 381 #if (CONFIG_COMMANDS & CFG_CMD_DHCP) 382 case DHCP: 383 /* Start with a clean slate... */ 384 BootpTry = 0; 385 NetOurIP = 0; 386 NetServerIP = getenv_IPaddr ("serverip"); 387 DhcpRequest(); /* Basically same as BOOTP */ 388 break; 389 #endif /* CFG_CMD_DHCP */ 390 391 case BOOTP: 392 BootpTry = 0; 393 BootpRequest (); 394 break; 395 396 case RARP: 397 RarpTry = 0; 398 RarpRequest (); 399 break; 400 #if (CONFIG_COMMANDS & CFG_CMD_PING) 401 case PING: 402 PingStart(); 403 break; 404 #endif 405 #if (CONFIG_COMMANDS & CFG_CMD_NFS) 406 case NFS: 407 NfsStart(); 408 break; 409 #endif 410 #if (CONFIG_COMMANDS & CFG_CMD_CDP) 411 case CDP: 412 CDPStart(); 413 break; 414 #endif 415 #ifdef CONFIG_NETCONSOLE 416 case NETCONS: 417 NcStart(); 418 break; 419 #endif 420 default: 421 break; 422 } 423 424 NetBootFileXferSize = 0; 425 break; 426 } 427 428 #if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII) 429 #if defined(CFG_FAULT_ECHO_LINK_DOWN) && defined(CONFIG_STATUS_LED) && defined(STATUS_LED_RED) 430 /* 431 * Echo the inverted link state to the fault LED. 432 */ 433 if(miiphy_link(CFG_FAULT_MII_ADDR)) { 434 status_led_set (STATUS_LED_RED, STATUS_LED_OFF); 435 } else { 436 status_led_set (STATUS_LED_RED, STATUS_LED_ON); 437 } 438 #endif /* CFG_FAULT_ECHO_LINK_DOWN, ... */ 439 #endif /* CONFIG_MII, ... */ 440 441 /* 442 * Main packet reception loop. Loop receiving packets until 443 * someone sets `NetQuit'. 444 */ 445 for (;;) { 446 WATCHDOG_RESET(); 447 #ifdef CONFIG_SHOW_ACTIVITY 448 { 449 extern void show_activity(int arg); 450 show_activity(1); 451 } 452 #endif 453 /* 454 * Check the ethernet for a new packet. The ethernet 455 * receive routine will process it. 456 */ 457 eth_rx(); 458 459 /* 460 * Abort if ctrl-c was pressed. 461 */ 462 if (ctrlc()) { 463 eth_halt(); 464 puts ("\nAbort\n"); 465 return (-1); 466 } 467 468 ArpTimeoutCheck(); 469 470 /* 471 * Check for a timeout, and run the timeout handler 472 * if we have one. 473 */ 474 if (timeHandler && ((get_timer(0) - timeStart) > timeDelta)) { 475 thand_f *x; 476 477 #if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII) 478 #if defined(CFG_FAULT_ECHO_LINK_DOWN) && defined(CONFIG_STATUS_LED) && defined(STATUS_LED_RED) 479 /* 480 * Echo the inverted link state to the fault LED. 481 */ 482 if(miiphy_link(CFG_FAULT_MII_ADDR)) { 483 status_led_set (STATUS_LED_RED, STATUS_LED_OFF); 484 } else { 485 status_led_set (STATUS_LED_RED, STATUS_LED_ON); 486 } 487 #endif /* CFG_FAULT_ECHO_LINK_DOWN, ... */ 488 #endif /* CONFIG_MII, ... */ 489 x = timeHandler; 490 timeHandler = (thand_f *)0; 491 (*x)(); 492 } 493 494 495 switch (NetState) { 496 497 case NETLOOP_RESTART: 498 #ifdef CONFIG_NET_MULTI 499 NetRestarted = 1; 500 #endif 501 goto restart; 502 503 case NETLOOP_SUCCESS: 504 if (NetBootFileXferSize > 0) { 505 char buf[10]; 506 printf("Bytes transferred = %ld (%lx hex)\n", 507 NetBootFileXferSize, 508 NetBootFileXferSize); 509 sprintf(buf, "%lx", NetBootFileXferSize); 510 setenv("filesize", buf); 511 512 sprintf(buf, "%lX", (unsigned long)load_addr); 513 setenv("fileaddr", buf); 514 } 515 eth_halt(); 516 return NetBootFileXferSize; 517 518 case NETLOOP_FAIL: 519 return (-1); 520 } 521 } 522 } 523 524 /**********************************************************************/ 525 526 static void 527 startAgainTimeout(void) 528 { 529 NetState = NETLOOP_RESTART; 530 } 531 532 static void 533 startAgainHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len) 534 { 535 /* Totally ignore the packet */ 536 } 537 538 void NetStartAgain (void) 539 { 540 #ifdef CONFIG_NET_MULTI 541 DECLARE_GLOBAL_DATA_PTR; 542 #endif 543 char *nretry; 544 int noretry = 0, once = 0; 545 546 if ((nretry = getenv ("netretry")) != NULL) { 547 noretry = (strcmp (nretry, "no") == 0); 548 once = (strcmp (nretry, "once") == 0); 549 } 550 if (noretry) { 551 eth_halt (); 552 NetState = NETLOOP_FAIL; 553 return; 554 } 555 #ifndef CONFIG_NET_MULTI 556 NetSetTimeout (10 * CFG_HZ, startAgainTimeout); 557 NetSetHandler (startAgainHandler); 558 #else /* !CONFIG_NET_MULTI*/ 559 eth_halt (); 560 eth_try_another (!NetRestarted); 561 eth_init (gd->bd); 562 if (NetRestartWrap) { 563 NetRestartWrap = 0; 564 if (NetDevExists && !once) { 565 NetSetTimeout (10 * CFG_HZ, startAgainTimeout); 566 NetSetHandler (startAgainHandler); 567 } else { 568 NetState = NETLOOP_FAIL; 569 } 570 } else { 571 NetState = NETLOOP_RESTART; 572 } 573 #endif /* CONFIG_NET_MULTI */ 574 } 575 576 /**********************************************************************/ 577 /* 578 * Miscelaneous bits. 579 */ 580 581 void 582 NetSetHandler(rxhand_f * f) 583 { 584 packetHandler = f; 585 } 586 587 588 void 589 NetSetTimeout(ulong iv, thand_f * f) 590 { 591 if (iv == 0) { 592 timeHandler = (thand_f *)0; 593 } else { 594 timeHandler = f; 595 timeStart = get_timer(0); 596 timeDelta = iv; 597 } 598 } 599 600 601 void 602 NetSendPacket(volatile uchar * pkt, int len) 603 { 604 (void) eth_send(pkt, len); 605 } 606 607 int 608 NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport, int sport, int len) 609 { 610 uchar *pkt; 611 612 /* convert to new style broadcast */ 613 if (dest == 0) 614 dest = 0xFFFFFFFF; 615 616 /* if broadcast, make the ether address a broadcast and don't do ARP */ 617 if (dest == 0xFFFFFFFF) 618 ether = NetBcastAddr; 619 620 /* if MAC address was not discovered yet, save the packet and do an ARP request */ 621 if (memcmp(ether, NetEtherNullAddr, 6) == 0) { 622 623 #ifdef ET_DEBUG 624 printf("sending ARP for %08lx\n", dest); 625 #endif 626 NetArpWaitPacketIP = dest; 627 NetArpWaitPacketMAC = ether; 628 629 pkt = NetArpWaitTxPacket; 630 pkt += NetSetEther (pkt, NetArpWaitPacketMAC, PROT_IP); 631 632 NetSetIP (pkt, dest, dport, sport, len); 633 memcpy(pkt + IP_HDR_SIZE, (uchar *)NetTxPacket + (pkt - (uchar *)NetArpWaitTxPacket) + IP_HDR_SIZE, len); 634 635 /* size of the waiting packet */ 636 NetArpWaitTxPacketSize = (pkt - NetArpWaitTxPacket) + IP_HDR_SIZE + len; 637 638 /* and do the ARP request */ 639 NetArpWaitTry = 1; 640 NetArpWaitTimerStart = get_timer(0); 641 ArpRequest(); 642 return 1; /* waiting */ 643 } 644 645 #ifdef ET_DEBUG 646 printf("sending UDP to %08lx/%02x:%02x:%02x:%02x:%02x:%02x\n", 647 dest, ether[0], ether[1], ether[2], ether[3], ether[4], ether[5]); 648 #endif 649 650 pkt = (uchar *)NetTxPacket; 651 pkt += NetSetEther (pkt, ether, PROT_IP); 652 NetSetIP (pkt, dest, dport, sport, len); 653 (void) eth_send(NetTxPacket, (pkt - NetTxPacket) + IP_HDR_SIZE + len); 654 655 return 0; /* transmitted */ 656 } 657 658 #if (CONFIG_COMMANDS & CFG_CMD_PING) 659 static ushort PingSeqNo; 660 661 int PingSend(void) 662 { 663 static uchar mac[6]; 664 volatile IP_t *ip; 665 volatile ushort *s; 666 uchar *pkt; 667 668 /* XXX always send arp request */ 669 670 memcpy(mac, NetEtherNullAddr, 6); 671 672 #ifdef ET_DEBUG 673 printf("sending ARP for %08lx\n", NetPingIP); 674 #endif 675 676 NetArpWaitPacketIP = NetPingIP; 677 NetArpWaitPacketMAC = mac; 678 679 pkt = NetArpWaitTxPacket; 680 pkt += NetSetEther(pkt, mac, PROT_IP); 681 682 ip = (volatile IP_t *)pkt; 683 684 /* 685 * Construct an IP and ICMP header. (need to set no fragment bit - XXX) 686 */ 687 ip->ip_hl_v = 0x45; /* IP_HDR_SIZE / 4 (not including UDP) */ 688 ip->ip_tos = 0; 689 ip->ip_len = htons(IP_HDR_SIZE_NO_UDP + 8); 690 ip->ip_id = htons(NetIPID++); 691 ip->ip_off = htons(0x4000); /* No fragmentation */ 692 ip->ip_ttl = 255; 693 ip->ip_p = 0x01; /* ICMP */ 694 ip->ip_sum = 0; 695 NetCopyIP((void*)&ip->ip_src, &NetOurIP); /* already in network byte order */ 696 NetCopyIP((void*)&ip->ip_dst, &NetPingIP); /* - "" - */ 697 ip->ip_sum = ~NetCksum((uchar *)ip, IP_HDR_SIZE_NO_UDP / 2); 698 699 s = &ip->udp_src; /* XXX ICMP starts here */ 700 s[0] = htons(0x0800); /* echo-request, code */ 701 s[1] = 0; /* checksum */ 702 s[2] = 0; /* identifier */ 703 s[3] = htons(PingSeqNo++); /* sequence number */ 704 s[1] = ~NetCksum((uchar *)s, 8/2); 705 706 /* size of the waiting packet */ 707 NetArpWaitTxPacketSize = (pkt - NetArpWaitTxPacket) + IP_HDR_SIZE_NO_UDP + 8; 708 709 /* and do the ARP request */ 710 NetArpWaitTry = 1; 711 NetArpWaitTimerStart = get_timer(0); 712 ArpRequest(); 713 return 1; /* waiting */ 714 } 715 716 static void 717 PingTimeout (void) 718 { 719 eth_halt(); 720 NetState = NETLOOP_FAIL; /* we did not get the reply */ 721 } 722 723 static void 724 PingHandler (uchar * pkt, unsigned dest, unsigned src, unsigned len) 725 { 726 IPaddr_t tmp; 727 volatile IP_t *ip = (volatile IP_t *)pkt; 728 729 tmp = NetReadIP((void *)&ip->ip_src); 730 if (tmp != NetPingIP) 731 return; 732 733 NetState = NETLOOP_SUCCESS; 734 } 735 736 static void PingStart(void) 737 { 738 #if defined(CONFIG_NET_MULTI) 739 printf ("Using %s device\n", eth_get_name()); 740 #endif /* CONFIG_NET_MULTI */ 741 NetSetTimeout (10 * CFG_HZ, PingTimeout); 742 NetSetHandler (PingHandler); 743 744 PingSend(); 745 } 746 #endif /* CFG_CMD_PING */ 747 748 #if (CONFIG_COMMANDS & CFG_CMD_CDP) 749 750 #define CDP_DEVICE_ID_TLV 0x0001 751 #define CDP_ADDRESS_TLV 0x0002 752 #define CDP_PORT_ID_TLV 0x0003 753 #define CDP_CAPABILITIES_TLV 0x0004 754 #define CDP_VERSION_TLV 0x0005 755 #define CDP_PLATFORM_TLV 0x0006 756 #define CDP_NATIVE_VLAN_TLV 0x000a 757 #define CDP_APPLIANCE_VLAN_TLV 0x000e 758 #define CDP_TRIGGER_TLV 0x000f 759 #define CDP_POWER_CONSUMPTION_TLV 0x0010 760 #define CDP_SYSNAME_TLV 0x0014 761 #define CDP_SYSOBJECT_TLV 0x0015 762 #define CDP_MANAGEMENT_ADDRESS_TLV 0x0016 763 764 #define CDP_TIMEOUT (CFG_HZ/4) /* one packet every 250ms */ 765 766 static int CDPSeq; 767 static int CDPOK; 768 769 ushort CDPNativeVLAN; 770 ushort CDPApplianceVLAN; 771 772 static const uchar CDP_SNAP_hdr[8] = { 0xAA, 0xAA, 0x03, 0x00, 0x00, 0x0C, 0x20, 0x00 }; 773 774 static ushort CDP_compute_csum(const uchar *buff, ushort len) 775 { 776 ushort csum; 777 int odd; 778 ulong result = 0; 779 ushort leftover; 780 781 if (len > 0) { 782 odd = 1 & (ulong)buff; 783 if (odd) { 784 result = *buff << 8; 785 len--; 786 buff++; 787 } 788 while (len > 1) { 789 result += *((const ushort *)buff)++; 790 if (result & 0x80000000) 791 result = (result & 0xFFFF) + (result >> 16); 792 len -= 2; 793 } 794 if (len) { 795 leftover = (signed short)(*(const signed char *)buff); 796 /* * XXX CISCO SUCKS big time! (and blows too) */ 797 result = (result & 0xffff0000) | ((result + leftover) & 0x0000ffff); 798 } 799 while (result >> 16) 800 result = (result & 0xFFFF) + (result >> 16); 801 802 if (odd) 803 result = ((result >> 8) & 0xff) | ((result & 0xff) << 8); 804 } 805 806 /* add up 16-bit and 17-bit words for 17+c bits */ 807 result = (result & 0xffff) + (result >> 16); 808 /* add up 16-bit and 2-bit for 16+c bit */ 809 result = (result & 0xffff) + (result >> 16); 810 /* add up carry.. */ 811 result = (result & 0xffff) + (result >> 16); 812 813 /* negate */ 814 csum = ~(ushort)result; 815 816 /* run time endian detection */ 817 if (csum != htons(csum)) /* little endian */ 818 csum = htons(csum); 819 820 return csum; 821 } 822 823 int CDPSendTrigger(void) 824 { 825 volatile uchar *pkt; 826 volatile ushort *s; 827 volatile ushort *cp; 828 Ethernet_t *et; 829 int len; 830 ushort chksum; 831 #if defined(CONFIG_CDP_DEVICE_ID) || defined(CONFIG_CDP_PORT_ID) || \ 832 defined(CONFIG_CDP_VERSION) || defined(CONFIG_CDP_PLATFORM) 833 char buf[32]; 834 #endif 835 836 pkt = NetTxPacket; 837 et = (Ethernet_t *)pkt; 838 839 /* NOTE: trigger sent not on any VLAN */ 840 841 /* form ethernet header */ 842 memcpy(et->et_dest, NetCDPAddr, 6); 843 memcpy(et->et_src, NetOurEther, 6); 844 845 pkt += ETHER_HDR_SIZE; 846 847 /* SNAP header */ 848 memcpy((uchar *)pkt, CDP_SNAP_hdr, sizeof(CDP_SNAP_hdr)); 849 pkt += sizeof(CDP_SNAP_hdr); 850 851 /* CDP header */ 852 *pkt++ = 0x02; /* CDP version 2 */ 853 *pkt++ = 180; /* TTL */ 854 s = (volatile ushort *)pkt; 855 cp = s; 856 *s++ = htons(0); /* checksum (0 for later calculation) */ 857 858 /* CDP fields */ 859 #ifdef CONFIG_CDP_DEVICE_ID 860 *s++ = htons(CDP_DEVICE_ID_TLV); 861 *s++ = htons(CONFIG_CDP_DEVICE_ID); 862 memset(buf, 0, sizeof(buf)); 863 sprintf(buf, CONFIG_CDP_DEVICE_ID_PREFIX "%02X%02X%02X%02X%02X%02X", 864 NetOurEther[0] & 0xff, NetOurEther[1] & 0xff, 865 NetOurEther[2] & 0xff, NetOurEther[3] & 0xff, 866 NetOurEther[4] & 0xff, NetOurEther[5] & 0xff); 867 memcpy((uchar *)s, buf, 16); 868 s += 16 / 2; 869 #endif 870 871 #ifdef CONFIG_CDP_PORT_ID 872 *s++ = htons(CDP_PORT_ID_TLV); 873 memset(buf, 0, sizeof(buf)); 874 sprintf(buf, CONFIG_CDP_PORT_ID, eth_get_dev_index()); 875 len = strlen(buf); 876 if (len & 1) /* make it even */ 877 len++; 878 *s++ = htons(len + 4); 879 memcpy((uchar *)s, buf, len); 880 s += len / 2; 881 #endif 882 883 #ifdef CONFIG_CDP_CAPABILITIES 884 *s++ = htons(CDP_CAPABILITIES_TLV); 885 *s++ = htons(8); 886 *(ulong *)s = htonl(CONFIG_CDP_CAPABILITIES); 887 s += 2; 888 #endif 889 890 #ifdef CONFIG_CDP_VERSION 891 *s++ = htons(CDP_VERSION_TLV); 892 memset(buf, 0, sizeof(buf)); 893 strcpy(buf, CONFIG_CDP_VERSION); 894 len = strlen(buf); 895 if (len & 1) /* make it even */ 896 len++; 897 *s++ = htons(len + 4); 898 memcpy((uchar *)s, buf, len); 899 s += len / 2; 900 #endif 901 902 #ifdef CONFIG_CDP_PLATFORM 903 *s++ = htons(CDP_PLATFORM_TLV); 904 memset(buf, 0, sizeof(buf)); 905 strcpy(buf, CONFIG_CDP_PLATFORM); 906 len = strlen(buf); 907 if (len & 1) /* make it even */ 908 len++; 909 *s++ = htons(len + 4); 910 memcpy((uchar *)s, buf, len); 911 s += len / 2; 912 #endif 913 914 #ifdef CONFIG_CDP_TRIGGER 915 *s++ = htons(CDP_TRIGGER_TLV); 916 *s++ = htons(8); 917 *(ulong *)s = htonl(CONFIG_CDP_TRIGGER); 918 s += 2; 919 #endif 920 921 #ifdef CONFIG_CDP_POWER_CONSUMPTION 922 *s++ = htons(CDP_POWER_CONSUMPTION_TLV); 923 *s++ = htons(6); 924 *s++ = htons(CONFIG_CDP_POWER_CONSUMPTION); 925 #endif 926 927 /* length of ethernet packet */ 928 len = (uchar *)s - ((uchar *)NetTxPacket + ETHER_HDR_SIZE); 929 et->et_protlen = htons(len); 930 931 len = ETHER_HDR_SIZE + sizeof(CDP_SNAP_hdr); 932 chksum = CDP_compute_csum((uchar *)NetTxPacket + len, (uchar *)s - (NetTxPacket + len)); 933 if (chksum == 0) 934 chksum = 0xFFFF; 935 *cp = htons(chksum); 936 937 (void) eth_send(NetTxPacket, (uchar *)s - NetTxPacket); 938 return 0; 939 } 940 941 static void 942 CDPTimeout (void) 943 { 944 CDPSeq++; 945 946 if (CDPSeq < 3) { 947 NetSetTimeout (CDP_TIMEOUT, CDPTimeout); 948 CDPSendTrigger(); 949 return; 950 } 951 952 /* if not OK try again */ 953 if (!CDPOK) 954 NetStartAgain(); 955 else 956 NetState = NETLOOP_SUCCESS; 957 } 958 959 static void 960 CDPDummyHandler (uchar * pkt, unsigned dest, unsigned src, unsigned len) 961 { 962 /* nothing */ 963 } 964 965 static void 966 CDPHandler(const uchar * pkt, unsigned len) 967 { 968 const uchar *t; 969 const ushort *ss; 970 ushort type, tlen; 971 uchar applid; 972 ushort vlan, nvlan; 973 974 /* minimum size? */ 975 if (len < sizeof(CDP_SNAP_hdr) + 4) 976 goto pkt_short; 977 978 /* check for valid CDP SNAP header */ 979 if (memcmp(pkt, CDP_SNAP_hdr, sizeof(CDP_SNAP_hdr)) != 0) 980 return; 981 982 pkt += sizeof(CDP_SNAP_hdr); 983 len -= sizeof(CDP_SNAP_hdr); 984 985 /* Version of CDP protocol must be >= 2 and TTL != 0 */ 986 if (pkt[0] < 0x02 || pkt[1] == 0) 987 return; 988 989 /* if version is greater than 0x02 maybe we'll have a problem; output a warning */ 990 if (pkt[0] != 0x02) 991 printf("** WARNING: CDP packet received with a protocol version %d > 2\n", 992 pkt[0] & 0xff); 993 994 if (CDP_compute_csum(pkt, len) != 0) 995 return; 996 997 pkt += 4; 998 len -= 4; 999 1000 vlan = htons(-1); 1001 nvlan = htons(-1); 1002 while (len > 0) { 1003 if (len < 4) 1004 goto pkt_short; 1005 1006 ss = (const ushort *)pkt; 1007 type = ntohs(ss[0]); 1008 tlen = ntohs(ss[1]); 1009 if (tlen > len) { 1010 goto pkt_short; 1011 } 1012 1013 pkt += tlen; 1014 len -= tlen; 1015 1016 ss += 2; /* point ss to the data of the TLV */ 1017 tlen -= 4; 1018 1019 switch (type) { 1020 case CDP_DEVICE_ID_TLV: 1021 break; 1022 case CDP_ADDRESS_TLV: 1023 break; 1024 case CDP_PORT_ID_TLV: 1025 break; 1026 case CDP_CAPABILITIES_TLV: 1027 break; 1028 case CDP_VERSION_TLV: 1029 break; 1030 case CDP_PLATFORM_TLV: 1031 break; 1032 case CDP_NATIVE_VLAN_TLV: 1033 nvlan = *ss; 1034 break; 1035 case CDP_APPLIANCE_VLAN_TLV: 1036 t = (const uchar *)ss; 1037 while (tlen > 0) { 1038 if (tlen < 3) 1039 goto pkt_short; 1040 1041 applid = t[0]; 1042 ss = (const ushort *)(t + 1); 1043 1044 #ifdef CONFIG_CDP_APPLIANCE_VLAN_TYPE 1045 if (applid == CONFIG_CDP_APPLIANCE_VLAN_TYPE) 1046 vlan = *ss; 1047 #else 1048 vlan = ntohs(*ss); /* XXX will this work; dunno */ 1049 #endif 1050 t += 3; tlen -= 3; 1051 } 1052 break; 1053 case CDP_TRIGGER_TLV: 1054 break; 1055 case CDP_POWER_CONSUMPTION_TLV: 1056 break; 1057 case CDP_SYSNAME_TLV: 1058 break; 1059 case CDP_SYSOBJECT_TLV: 1060 break; 1061 case CDP_MANAGEMENT_ADDRESS_TLV: 1062 break; 1063 } 1064 } 1065 1066 CDPApplianceVLAN = vlan; 1067 CDPNativeVLAN = nvlan; 1068 1069 CDPOK = 1; 1070 return; 1071 1072 pkt_short: 1073 printf("** CDP packet is too short\n"); 1074 return; 1075 } 1076 1077 static void CDPStart(void) 1078 { 1079 #if defined(CONFIG_NET_MULTI) 1080 printf ("Using %s device\n", eth_get_name()); 1081 #endif 1082 CDPSeq = 0; 1083 CDPOK = 0; 1084 1085 CDPNativeVLAN = htons(-1); 1086 CDPApplianceVLAN = htons(-1); 1087 1088 NetSetTimeout (CDP_TIMEOUT, CDPTimeout); 1089 NetSetHandler (CDPDummyHandler); 1090 1091 CDPSendTrigger(); 1092 } 1093 #endif /* CFG_CMD_CDP */ 1094 1095 1096 void 1097 NetReceive(volatile uchar * inpkt, int len) 1098 { 1099 Ethernet_t *et; 1100 IP_t *ip; 1101 ARP_t *arp; 1102 IPaddr_t tmp; 1103 int x; 1104 uchar *pkt; 1105 #if (CONFIG_COMMANDS & CFG_CMD_CDP) 1106 int iscdp; 1107 #endif 1108 ushort cti = 0, vlanid = VLAN_NONE, myvlanid, mynvlanid; 1109 1110 #ifdef ET_DEBUG 1111 printf("packet received\n"); 1112 #endif 1113 1114 NetRxPkt = inpkt; 1115 NetRxPktLen = len; 1116 et = (Ethernet_t *)inpkt; 1117 1118 /* too small packet? */ 1119 if (len < ETHER_HDR_SIZE) 1120 return; 1121 1122 #if (CONFIG_COMMANDS & CFG_CMD_CDP) 1123 /* keep track if packet is CDP */ 1124 iscdp = memcmp(et->et_dest, NetCDPAddr, 6) == 0; 1125 #endif 1126 1127 myvlanid = ntohs(NetOurVLAN); 1128 if (myvlanid == (ushort)-1) 1129 myvlanid = VLAN_NONE; 1130 mynvlanid = ntohs(NetOurNativeVLAN); 1131 if (mynvlanid == (ushort)-1) 1132 mynvlanid = VLAN_NONE; 1133 1134 x = ntohs(et->et_protlen); 1135 1136 #ifdef ET_DEBUG 1137 printf("packet received\n"); 1138 #endif 1139 1140 if (x < 1514) { 1141 /* 1142 * Got a 802 packet. Check the other protocol field. 1143 */ 1144 x = ntohs(et->et_prot); 1145 1146 ip = (IP_t *)(inpkt + E802_HDR_SIZE); 1147 len -= E802_HDR_SIZE; 1148 1149 } else if (x != PROT_VLAN) { /* normal packet */ 1150 ip = (IP_t *)(inpkt + ETHER_HDR_SIZE); 1151 len -= ETHER_HDR_SIZE; 1152 1153 } else { /* VLAN packet */ 1154 VLAN_Ethernet_t *vet = (VLAN_Ethernet_t *)et; 1155 1156 #ifdef ET_DEBUG 1157 printf("VLAN packet received\n"); 1158 #endif 1159 /* too small packet? */ 1160 if (len < VLAN_ETHER_HDR_SIZE) 1161 return; 1162 1163 /* if no VLAN active */ 1164 if ((ntohs(NetOurVLAN) & VLAN_IDMASK) == VLAN_NONE 1165 #if (CONFIG_COMMANDS & CFG_CMD_CDP) 1166 && iscdp == 0 1167 #endif 1168 ) 1169 return; 1170 1171 cti = ntohs(vet->vet_tag); 1172 vlanid = cti & VLAN_IDMASK; 1173 x = ntohs(vet->vet_type); 1174 1175 ip = (IP_t *)(inpkt + VLAN_ETHER_HDR_SIZE); 1176 len -= VLAN_ETHER_HDR_SIZE; 1177 } 1178 1179 #ifdef ET_DEBUG 1180 printf("Receive from protocol 0x%x\n", x); 1181 #endif 1182 1183 #if (CONFIG_COMMANDS & CFG_CMD_CDP) 1184 if (iscdp) { 1185 CDPHandler((uchar *)ip, len); 1186 return; 1187 } 1188 #endif 1189 1190 if ((myvlanid & VLAN_IDMASK) != VLAN_NONE) { 1191 if (vlanid == VLAN_NONE) 1192 vlanid = (mynvlanid & VLAN_IDMASK); 1193 /* not matched? */ 1194 if (vlanid != (myvlanid & VLAN_IDMASK)) 1195 return; 1196 } 1197 1198 switch (x) { 1199 1200 case PROT_ARP: 1201 /* 1202 * We have to deal with two types of ARP packets: 1203 * - REQUEST packets will be answered by sending our 1204 * IP address - if we know it. 1205 * - REPLY packates are expected only after we asked 1206 * for the TFTP server's or the gateway's ethernet 1207 * address; so if we receive such a packet, we set 1208 * the server ethernet address 1209 */ 1210 #ifdef ET_DEBUG 1211 puts ("Got ARP\n"); 1212 #endif 1213 arp = (ARP_t *)ip; 1214 if (len < ARP_HDR_SIZE) { 1215 printf("bad length %d < %d\n", len, ARP_HDR_SIZE); 1216 return; 1217 } 1218 if (ntohs(arp->ar_hrd) != ARP_ETHER) { 1219 return; 1220 } 1221 if (ntohs(arp->ar_pro) != PROT_IP) { 1222 return; 1223 } 1224 if (arp->ar_hln != 6) { 1225 return; 1226 } 1227 if (arp->ar_pln != 4) { 1228 return; 1229 } 1230 1231 if (NetOurIP == 0) { 1232 return; 1233 } 1234 1235 if (NetReadIP(&arp->ar_data[16]) != NetOurIP) { 1236 return; 1237 } 1238 1239 switch (ntohs(arp->ar_op)) { 1240 case ARPOP_REQUEST: /* reply with our IP address */ 1241 #ifdef ET_DEBUG 1242 puts ("Got ARP REQUEST, return our IP\n"); 1243 #endif 1244 pkt = (uchar *)et; 1245 pkt += NetSetEther(pkt, et->et_src, PROT_ARP); 1246 arp->ar_op = htons(ARPOP_REPLY); 1247 memcpy (&arp->ar_data[10], &arp->ar_data[0], 6); 1248 NetCopyIP(&arp->ar_data[16], &arp->ar_data[6]); 1249 memcpy (&arp->ar_data[ 0], NetOurEther, 6); 1250 NetCopyIP(&arp->ar_data[ 6], &NetOurIP); 1251 (void) eth_send((uchar *)et, (pkt - (uchar *)et) + ARP_HDR_SIZE); 1252 return; 1253 1254 case ARPOP_REPLY: /* arp reply */ 1255 /* are we waiting for a reply */ 1256 if (!NetArpWaitPacketIP || !NetArpWaitPacketMAC) 1257 break; 1258 #ifdef ET_DEBUG 1259 printf("Got ARP REPLY, set server/gtwy eth addr (%02x:%02x:%02x:%02x:%02x:%02x)\n", 1260 arp->ar_data[0], arp->ar_data[1], 1261 arp->ar_data[2], arp->ar_data[3], 1262 arp->ar_data[4], arp->ar_data[5]); 1263 #endif 1264 1265 tmp = NetReadIP(&arp->ar_data[6]); 1266 1267 /* matched waiting packet's address */ 1268 if (tmp == NetArpWaitReplyIP) { 1269 #ifdef ET_DEBUG 1270 puts ("Got it\n"); 1271 #endif 1272 /* save address for later use */ 1273 memcpy(NetArpWaitPacketMAC, &arp->ar_data[0], 6); 1274 1275 #ifdef CONFIG_NETCONSOLE 1276 (*packetHandler)(0,0,0,0); 1277 #endif 1278 /* modify header, and transmit it */ 1279 memcpy(((Ethernet_t *)NetArpWaitTxPacket)->et_dest, NetArpWaitPacketMAC, 6); 1280 (void) eth_send(NetArpWaitTxPacket, NetArpWaitTxPacketSize); 1281 1282 /* no arp request pending now */ 1283 NetArpWaitPacketIP = 0; 1284 NetArpWaitTxPacketSize = 0; 1285 NetArpWaitPacketMAC = NULL; 1286 1287 } 1288 return; 1289 default: 1290 #ifdef ET_DEBUG 1291 printf("Unexpected ARP opcode 0x%x\n", ntohs(arp->ar_op)); 1292 #endif 1293 return; 1294 } 1295 1296 case PROT_RARP: 1297 #ifdef ET_DEBUG 1298 puts ("Got RARP\n"); 1299 #endif 1300 arp = (ARP_t *)ip; 1301 if (len < ARP_HDR_SIZE) { 1302 printf("bad length %d < %d\n", len, ARP_HDR_SIZE); 1303 return; 1304 } 1305 1306 if ((ntohs(arp->ar_op) != RARPOP_REPLY) || 1307 (ntohs(arp->ar_hrd) != ARP_ETHER) || 1308 (ntohs(arp->ar_pro) != PROT_IP) || 1309 (arp->ar_hln != 6) || (arp->ar_pln != 4)) { 1310 1311 puts ("invalid RARP header\n"); 1312 } else { 1313 NetCopyIP(&NetOurIP, &arp->ar_data[16]); 1314 if (NetServerIP == 0) 1315 NetCopyIP(&NetServerIP, &arp->ar_data[ 6]); 1316 memcpy (NetServerEther, &arp->ar_data[ 0], 6); 1317 1318 (*packetHandler)(0,0,0,0); 1319 } 1320 break; 1321 1322 case PROT_IP: 1323 #ifdef ET_DEBUG 1324 puts ("Got IP\n"); 1325 #endif 1326 if (len < IP_HDR_SIZE) { 1327 debug ("len bad %d < %d\n", len, IP_HDR_SIZE); 1328 return; 1329 } 1330 if (len < ntohs(ip->ip_len)) { 1331 printf("len bad %d < %d\n", len, ntohs(ip->ip_len)); 1332 return; 1333 } 1334 len = ntohs(ip->ip_len); 1335 #ifdef ET_DEBUG 1336 printf("len=%d, v=%02x\n", len, ip->ip_hl_v & 0xff); 1337 #endif 1338 if ((ip->ip_hl_v & 0xf0) != 0x40) { 1339 return; 1340 } 1341 if (ip->ip_off & htons(0x1fff)) { /* Can't deal w/ fragments */ 1342 return; 1343 } 1344 if (!NetCksumOk((uchar *)ip, IP_HDR_SIZE_NO_UDP / 2)) { 1345 puts ("checksum bad\n"); 1346 return; 1347 } 1348 tmp = NetReadIP(&ip->ip_dst); 1349 if (NetOurIP && tmp != NetOurIP && tmp != 0xFFFFFFFF) { 1350 return; 1351 } 1352 /* 1353 * watch for ICMP host redirects 1354 * 1355 * There is no real handler code (yet). We just watch 1356 * for ICMP host redirect messages. In case anybody 1357 * sees these messages: please contact me 1358 * (wd@denx.de), or - even better - send me the 1359 * necessary fixes :-) 1360 * 1361 * Note: in all cases where I have seen this so far 1362 * it was a problem with the router configuration, 1363 * for instance when a router was configured in the 1364 * BOOTP reply, but the TFTP server was on the same 1365 * subnet. So this is probably a warning that your 1366 * configuration might be wrong. But I'm not really 1367 * sure if there aren't any other situations. 1368 */ 1369 if (ip->ip_p == IPPROTO_ICMP) { 1370 ICMP_t *icmph = (ICMP_t *)&(ip->udp_src); 1371 1372 switch (icmph->type) { 1373 case ICMP_REDIRECT: 1374 if (icmph->code != ICMP_REDIR_HOST) 1375 return; 1376 puts (" ICMP Host Redirect to "); 1377 print_IPaddr(icmph->un.gateway); 1378 putc(' '); 1379 break; 1380 #if (CONFIG_COMMANDS & CFG_CMD_PING) 1381 case ICMP_ECHO_REPLY: 1382 /* 1383 * IP header OK. Pass the packet to the current handler. 1384 */ 1385 /* XXX point to ip packet */ 1386 (*packetHandler)((uchar *)ip, 0, 0, 0); 1387 break; 1388 #endif 1389 default: 1390 return; 1391 } 1392 } else if (ip->ip_p != IPPROTO_UDP) { /* Only UDP packets */ 1393 return; 1394 } 1395 1396 #ifdef CONFIG_NETCONSOLE 1397 nc_input_packet((uchar *)ip +IP_HDR_SIZE, 1398 ntohs(ip->udp_dst), 1399 ntohs(ip->udp_src), 1400 ntohs(ip->udp_len) - 8); 1401 #endif 1402 /* 1403 * IP header OK. Pass the packet to the current handler. 1404 */ 1405 (*packetHandler)((uchar *)ip +IP_HDR_SIZE, 1406 ntohs(ip->udp_dst), 1407 ntohs(ip->udp_src), 1408 ntohs(ip->udp_len) - 8); 1409 break; 1410 } 1411 } 1412 1413 1414 /**********************************************************************/ 1415 1416 static int net_check_prereq (proto_t protocol) 1417 { 1418 switch (protocol) { 1419 /* Fall through */ 1420 #if (CONFIG_COMMANDS & CFG_CMD_PING) 1421 case PING: 1422 if (NetPingIP == 0) { 1423 puts ("*** ERROR: ping address not given\n"); 1424 return (1); 1425 } 1426 goto common; 1427 #endif 1428 #if (CONFIG_COMMANDS & CFG_CMD_NFS) 1429 case NFS: 1430 #endif 1431 case NETCONS: 1432 case TFTP: 1433 if (NetServerIP == 0) { 1434 puts ("*** ERROR: `serverip' not set\n"); 1435 return (1); 1436 } 1437 #if (CONFIG_COMMANDS & CFG_CMD_PING) 1438 common: 1439 #endif 1440 1441 if (NetOurIP == 0) { 1442 puts ("*** ERROR: `ipaddr' not set\n"); 1443 return (1); 1444 } 1445 /* Fall through */ 1446 1447 case DHCP: 1448 case RARP: 1449 case BOOTP: 1450 case CDP: 1451 if (memcmp (NetOurEther, "\0\0\0\0\0\0", 6) == 0) { 1452 #ifdef CONFIG_NET_MULTI 1453 extern int eth_get_dev_index (void); 1454 int num = eth_get_dev_index (); 1455 1456 switch (num) { 1457 case -1: 1458 puts ("*** ERROR: No ethernet found.\n"); 1459 return (1); 1460 case 0: 1461 puts ("*** ERROR: `ethaddr' not set\n"); 1462 break; 1463 default: 1464 printf ("*** ERROR: `eth%daddr' not set\n", 1465 num); 1466 break; 1467 } 1468 1469 NetStartAgain (); 1470 return (2); 1471 #else 1472 puts ("*** ERROR: `ethaddr' not set\n"); 1473 return (1); 1474 #endif 1475 } 1476 /* Fall through */ 1477 default: 1478 return (0); 1479 } 1480 return (0); /* OK */ 1481 } 1482 /**********************************************************************/ 1483 1484 int 1485 NetCksumOk(uchar * ptr, int len) 1486 { 1487 return !((NetCksum(ptr, len) + 1) & 0xfffe); 1488 } 1489 1490 1491 unsigned 1492 NetCksum(uchar * ptr, int len) 1493 { 1494 ulong xsum; 1495 1496 xsum = 0; 1497 while (len-- > 0) 1498 xsum += *((ushort *)ptr)++; 1499 xsum = (xsum & 0xffff) + (xsum >> 16); 1500 xsum = (xsum & 0xffff) + (xsum >> 16); 1501 return (xsum & 0xffff); 1502 } 1503 1504 int 1505 NetEthHdrSize(void) 1506 { 1507 ushort myvlanid; 1508 1509 myvlanid = ntohs(NetOurVLAN); 1510 if (myvlanid == (ushort)-1) 1511 myvlanid = VLAN_NONE; 1512 1513 return ((myvlanid & VLAN_IDMASK) == VLAN_NONE) ? ETHER_HDR_SIZE : VLAN_ETHER_HDR_SIZE; 1514 } 1515 1516 int 1517 NetSetEther(volatile uchar * xet, uchar * addr, uint prot) 1518 { 1519 Ethernet_t *et = (Ethernet_t *)xet; 1520 ushort myvlanid; 1521 1522 myvlanid = ntohs(NetOurVLAN); 1523 if (myvlanid == (ushort)-1) 1524 myvlanid = VLAN_NONE; 1525 1526 memcpy (et->et_dest, addr, 6); 1527 memcpy (et->et_src, NetOurEther, 6); 1528 if ((myvlanid & VLAN_IDMASK) == VLAN_NONE) { 1529 et->et_protlen = htons(prot); 1530 return ETHER_HDR_SIZE; 1531 } else { 1532 VLAN_Ethernet_t *vet = (VLAN_Ethernet_t *)xet; 1533 1534 vet->vet_vlan_type = htons(PROT_VLAN); 1535 vet->vet_tag = htons((0 << 5) | (myvlanid & VLAN_IDMASK)); 1536 vet->vet_type = htons(prot); 1537 return VLAN_ETHER_HDR_SIZE; 1538 } 1539 } 1540 1541 void 1542 NetSetIP(volatile uchar * xip, IPaddr_t dest, int dport, int sport, int len) 1543 { 1544 volatile IP_t *ip = (IP_t *)xip; 1545 1546 /* 1547 * If the data is an odd number of bytes, zero the 1548 * byte after the last byte so that the checksum 1549 * will work. 1550 */ 1551 if (len & 1) 1552 xip[IP_HDR_SIZE + len] = 0; 1553 1554 /* 1555 * Construct an IP and UDP header. 1556 * (need to set no fragment bit - XXX) 1557 */ 1558 ip->ip_hl_v = 0x45; /* IP_HDR_SIZE / 4 (not including UDP) */ 1559 ip->ip_tos = 0; 1560 ip->ip_len = htons(IP_HDR_SIZE + len); 1561 ip->ip_id = htons(NetIPID++); 1562 ip->ip_off = htons(0x4000); /* No fragmentation */ 1563 ip->ip_ttl = 255; 1564 ip->ip_p = 17; /* UDP */ 1565 ip->ip_sum = 0; 1566 NetCopyIP((void*)&ip->ip_src, &NetOurIP); /* already in network byte order */ 1567 NetCopyIP((void*)&ip->ip_dst, &dest); /* - "" - */ 1568 ip->udp_src = htons(sport); 1569 ip->udp_dst = htons(dport); 1570 ip->udp_len = htons(8 + len); 1571 ip->udp_xsum = 0; 1572 ip->ip_sum = ~NetCksum((uchar *)ip, IP_HDR_SIZE_NO_UDP / 2); 1573 } 1574 1575 void copy_filename (uchar *dst, uchar *src, int size) 1576 { 1577 if (*src && (*src == '"')) { 1578 ++src; 1579 --size; 1580 } 1581 1582 while ((--size > 0) && *src && (*src != '"')) { 1583 *dst++ = *src++; 1584 } 1585 *dst = '\0'; 1586 } 1587 1588 #endif /* CFG_CMD_NET */ 1589 1590 void ip_to_string (IPaddr_t x, char *s) 1591 { 1592 x = ntohl (x); 1593 sprintf (s, "%d.%d.%d.%d", 1594 (int) ((x >> 24) & 0xff), 1595 (int) ((x >> 16) & 0xff), 1596 (int) ((x >> 8) & 0xff), (int) ((x >> 0) & 0xff) 1597 ); 1598 } 1599 1600 IPaddr_t string_to_ip(char *s) 1601 { 1602 IPaddr_t addr; 1603 char *e; 1604 int i; 1605 1606 if (s == NULL) 1607 return(0); 1608 1609 for (addr=0, i=0; i<4; ++i) { 1610 ulong val = s ? simple_strtoul(s, &e, 10) : 0; 1611 addr <<= 8; 1612 addr |= (val & 0xFF); 1613 if (s) { 1614 s = (*e) ? e+1 : e; 1615 } 1616 } 1617 1618 return (htonl(addr)); 1619 } 1620 1621 void VLAN_to_string(ushort x, char *s) 1622 { 1623 x = ntohs(x); 1624 1625 if (x == (ushort)-1) 1626 x = VLAN_NONE; 1627 1628 if (x == VLAN_NONE) 1629 strcpy(s, "none"); 1630 else 1631 sprintf(s, "%d", x & VLAN_IDMASK); 1632 } 1633 1634 ushort string_to_VLAN(char *s) 1635 { 1636 ushort id; 1637 1638 if (s == NULL) 1639 return htons(VLAN_NONE); 1640 1641 if (*s < '0' || *s > '9') 1642 id = VLAN_NONE; 1643 else 1644 id = (ushort)simple_strtoul(s, NULL, 10); 1645 1646 return htons(id); 1647 } 1648 1649 void print_IPaddr (IPaddr_t x) 1650 { 1651 char tmp[16]; 1652 1653 ip_to_string (x, tmp); 1654 1655 puts (tmp); 1656 } 1657 1658 IPaddr_t getenv_IPaddr (char *var) 1659 { 1660 return (string_to_ip(getenv(var))); 1661 } 1662 1663 ushort getenv_VLAN(char *var) 1664 { 1665 return (string_to_VLAN(getenv(var))); 1666 } 1667