net.c 23 KB

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