net.c 23 KB

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