net.c 23 KB

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