net.c 23 KB

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