main.c 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172
  1. /*
  2. * GRUB -- GRand Unified Bootloader
  3. * Copyright (C) 2000,2001,2002 Free Software Foundation, Inc.
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19. /* Based on "src/main.c" in etherboot-5.0.5. */
  20. /**************************************************************************
  21. ETHERBOOT - BOOTP/TFTP Bootstrap Program
  22. Author: Martin Renters
  23. Date: Dec/93
  24. Literature dealing with the network protocols:
  25. ARP - RFC826
  26. RARP - RFC903
  27. UDP - RFC768
  28. BOOTP - RFC951, RFC2132 (vendor extensions)
  29. DHCP - RFC2131, RFC2132 (options)
  30. TFTP - RFC1350, RFC2347 (options), RFC2348 (blocksize), RFC2349 (tsize)
  31. RPC - RFC1831, RFC1832 (XDR), RFC1833 (rpcbind/portmapper)
  32. NFS - RFC1094, RFC1813 (v3, useful for clarifications, not implemented)
  33. **************************************************************************/
  34. #define GRUB 1
  35. #include <etherboot.h>
  36. #include <nic.h>
  37. /* #define DEBUG 1 */
  38. struct arptable_t arptable[MAX_ARP];
  39. /* Set if the user pushes Control-C. */
  40. int ip_abort = 0;
  41. /* Set if an ethernet card is probed and IP addresses are set. */
  42. int network_ready = 0;
  43. struct rom_info rom;
  44. static int vendorext_isvalid;
  45. static unsigned long netmask;
  46. static struct bootpd_t bootp_data;
  47. static unsigned long xid;
  48. #define BOOTP_DATA_ADDR (&bootp_data)
  49. #ifndef NO_DHCP_SUPPORT
  50. #endif /* NO_DHCP_SUPPORT */
  51. /* äEth */
  52. static unsigned char vendorext_magic[] = {0xE4, 0x45, 0x74, 0x68};
  53. static const unsigned char broadcast[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
  54. #ifdef NO_DHCP_SUPPORT
  55. static unsigned char rfc1533_cookie[5] = {RFC1533_COOKIE, RFC1533_END};
  56. #else /* ! NO_DHCP_SUPPORT */
  57. static int dhcp_reply;
  58. static in_addr dhcp_server = {0L};
  59. static in_addr dhcp_addr = {0L};
  60. static unsigned char rfc1533_cookie[] = {RFC1533_COOKIE};
  61. static unsigned char rfc1533_end[] = {RFC1533_END};
  62. static const unsigned char dhcpdiscover[] =
  63. {
  64. RFC2132_MSG_TYPE, 1, DHCPDISCOVER,
  65. RFC2132_MAX_SIZE,2, /* request as much as we can */
  66. ETH_MAX_MTU / 256, ETH_MAX_MTU % 256,
  67. RFC2132_PARAM_LIST, 4, RFC1533_NETMASK, RFC1533_GATEWAY,
  68. RFC1533_HOSTNAME, RFC1533_EXTENSIONPATH
  69. };
  70. static const unsigned char dhcprequest[] =
  71. {
  72. RFC2132_MSG_TYPE, 1, DHCPREQUEST,
  73. RFC2132_SRV_ID, 4, 0, 0, 0, 0,
  74. RFC2132_REQ_ADDR, 4, 0, 0, 0, 0,
  75. RFC2132_MAX_SIZE, 2, /* request as much as we can */
  76. ETH_MAX_MTU / 256, ETH_MAX_MTU % 256,
  77. /* request parameters */
  78. RFC2132_PARAM_LIST,
  79. /* 4 standard + 2 vendortags */
  80. 4 + 2,
  81. /* Standard parameters */
  82. RFC1533_NETMASK, RFC1533_GATEWAY,
  83. RFC1533_HOSTNAME, RFC1533_EXTENSIONPATH,
  84. /* Etherboot vendortags */
  85. RFC1533_VENDOR_MAGIC,
  86. RFC1533_VENDOR_CONFIGFILE,
  87. };
  88. #endif /* ! NO_DHCP_SUPPORT */
  89. static unsigned short ipchksum (unsigned short *ip, int len);
  90. static unsigned short udpchksum (struct iphdr *packet);
  91. void
  92. print_network_configuration (void)
  93. {
  94. if (! eth_probe ())
  95. grub_printf ("No ethernet card found.\n");
  96. else if (! network_ready)
  97. grub_printf ("Not initialized yet.\n");
  98. else
  99. {
  100. etherboot_printf ("Address: %@\n", arptable[ARP_CLIENT].ipaddr.s_addr);
  101. etherboot_printf ("Netmask: %@\n", netmask);
  102. etherboot_printf ("Server: %@\n", arptable[ARP_SERVER].ipaddr.s_addr);
  103. etherboot_printf ("Gateway: %@\n", arptable[ARP_GATEWAY].ipaddr.s_addr);
  104. }
  105. }
  106. /**************************************************************************
  107. DEFAULT_NETMASK - Return default netmask for IP address
  108. **************************************************************************/
  109. static inline unsigned long
  110. default_netmask (void)
  111. {
  112. int net = ntohl (arptable[ARP_CLIENT].ipaddr.s_addr) >> 24;
  113. if (net <= 127)
  114. return (htonl (0xff000000));
  115. else if (net < 192)
  116. return (htonl (0xffff0000));
  117. else
  118. return (htonl (0xffffff00));
  119. }
  120. /* ifconfig - configure network interface. */
  121. int
  122. ifconfig (char *ip, char *sm, char *gw, char *svr)
  123. {
  124. in_addr tmp;
  125. if (sm)
  126. {
  127. if (! inet_aton (sm, &tmp))
  128. return 0;
  129. netmask = tmp.s_addr;
  130. }
  131. if (ip)
  132. {
  133. if (! inet_aton (ip, &arptable[ARP_CLIENT].ipaddr))
  134. return 0;
  135. if (! netmask && ! sm)
  136. netmask = default_netmask ();
  137. }
  138. if (gw && ! inet_aton (gw, &arptable[ARP_GATEWAY].ipaddr))
  139. return 0;
  140. /* Clear out the ARP entry. */
  141. grub_memset (arptable[ARP_GATEWAY].node, 0, ETH_ALEN);
  142. if (svr && ! inet_aton (svr, &arptable[ARP_SERVER].ipaddr))
  143. return 0;
  144. /* Likewise. */
  145. grub_memset (arptable[ARP_SERVER].node, 0, ETH_ALEN);
  146. if (ip || sm)
  147. {
  148. if (IP_BROADCAST == (netmask | arptable[ARP_CLIENT].ipaddr.s_addr)
  149. || netmask == (netmask | arptable[ARP_CLIENT].ipaddr.s_addr)
  150. || ! netmask)
  151. network_ready = 0;
  152. else
  153. network_ready = 1;
  154. }
  155. return 1;
  156. }
  157. /**************************************************************************
  158. UDP_TRANSMIT - Send a UDP datagram
  159. **************************************************************************/
  160. int
  161. udp_transmit (unsigned long destip, unsigned int srcsock,
  162. unsigned int destsock, int len, const void *buf)
  163. {
  164. struct iphdr *ip;
  165. struct udphdr *udp;
  166. struct arprequest arpreq;
  167. int arpentry, i;
  168. int retry;
  169. ip = (struct iphdr *) buf;
  170. udp = (struct udphdr *) ((unsigned long) buf + sizeof (struct iphdr));
  171. ip->verhdrlen = 0x45;
  172. ip->service = 0;
  173. ip->len = htons (len);
  174. ip->ident = 0;
  175. ip->frags = 0;
  176. ip->ttl = 60;
  177. ip->protocol = IP_UDP;
  178. ip->chksum = 0;
  179. ip->src.s_addr = arptable[ARP_CLIENT].ipaddr.s_addr;
  180. ip->dest.s_addr = destip;
  181. ip->chksum = ipchksum ((unsigned short *) buf, sizeof (struct iphdr));
  182. udp->src = htons (srcsock);
  183. udp->dest = htons (destsock);
  184. udp->len = htons (len - sizeof (struct iphdr));
  185. udp->chksum = 0;
  186. udp->chksum = htons (udpchksum (ip));
  187. if (udp->chksum == 0)
  188. udp->chksum = 0xffff;
  189. if (destip == IP_BROADCAST)
  190. {
  191. eth_transmit (broadcast, IP, len, buf);
  192. }
  193. else
  194. {
  195. if (((destip & netmask)
  196. != (arptable[ARP_CLIENT].ipaddr.s_addr & netmask))
  197. && arptable[ARP_GATEWAY].ipaddr.s_addr)
  198. destip = arptable[ARP_GATEWAY].ipaddr.s_addr;
  199. for (arpentry = 0; arpentry < MAX_ARP; arpentry++)
  200. if (arptable[arpentry].ipaddr.s_addr == destip)
  201. break;
  202. if (arpentry == MAX_ARP)
  203. {
  204. etherboot_printf ("%@ is not in my arp table!\n", destip);
  205. return 0;
  206. }
  207. for (i = 0; i < ETH_ALEN; i++)
  208. if (arptable[arpentry].node[i])
  209. break;
  210. if (i == ETH_ALEN)
  211. {
  212. /* Need to do arp request. */
  213. #ifdef DEBUG
  214. grub_printf ("arp request.\n");
  215. #endif
  216. arpreq.hwtype = htons (1);
  217. arpreq.protocol = htons (IP);
  218. arpreq.hwlen = ETH_ALEN;
  219. arpreq.protolen = 4;
  220. arpreq.opcode = htons (ARP_REQUEST);
  221. grub_memmove (arpreq.shwaddr, arptable[ARP_CLIENT].node,
  222. ETH_ALEN);
  223. grub_memmove (arpreq.sipaddr, (char *) &arptable[ARP_CLIENT].ipaddr,
  224. sizeof (in_addr));
  225. grub_memset (arpreq.thwaddr, 0, ETH_ALEN);
  226. grub_memmove (arpreq.tipaddr, (char *) &destip, sizeof (in_addr));
  227. for (retry = 1; retry <= MAX_ARP_RETRIES; retry++)
  228. {
  229. long timeout;
  230. eth_transmit (broadcast, ARP, sizeof (arpreq), &arpreq);
  231. timeout = rfc2131_sleep_interval (TIMEOUT, retry);
  232. if (await_reply (AWAIT_ARP, arpentry, arpreq.tipaddr, timeout))
  233. goto xmit;
  234. if (ip_abort)
  235. return 0;
  236. }
  237. return 0;
  238. }
  239. xmit:
  240. eth_transmit (arptable[arpentry].node, IP, len, buf);
  241. }
  242. return 1;
  243. }
  244. /**************************************************************************
  245. TFTP - Download extended BOOTP data, or kernel image
  246. **************************************************************************/
  247. static int
  248. tftp (const char *name, int (*fnc) (unsigned char *, int, int, int))
  249. {
  250. int retry = 0;
  251. static unsigned short iport = 2000;
  252. unsigned short oport = 0;
  253. unsigned short len, block = 0, prevblock = 0;
  254. int bcounter = 0;
  255. struct tftp_t *tr;
  256. struct tftpreq_t tp;
  257. int rc;
  258. int packetsize = TFTP_DEFAULTSIZE_PACKET;
  259. /* Clear out the Rx queue first. It contains nothing of interest,
  260. * except possibly ARP requests from the DHCP/TFTP server. We use
  261. * polling throughout Etherboot, so some time may have passed since we
  262. * last polled the receive queue, which may now be filled with
  263. * broadcast packets. This will cause the reply to the packets we are
  264. * about to send to be lost immediately. Not very clever. */
  265. await_reply (AWAIT_QDRAIN, 0, NULL, 0);
  266. tp.opcode = htons (TFTP_RRQ);
  267. len = (grub_sprintf ((char *) tp.u.rrq, "%s%coctet%cblksize%c%d",
  268. name, 0, 0, 0, TFTP_MAX_PACKET)
  269. + sizeof (tp.ip) + sizeof (tp.udp) + sizeof (tp.opcode) + 1);
  270. if (! udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr, ++iport,
  271. TFTP_PORT, len, &tp))
  272. return 0;
  273. for (;;)
  274. {
  275. long timeout;
  276. #ifdef CONGESTED
  277. timeout = rfc2131_sleep_interval (block ? TFTP_REXMT : TIMEOUT, retry);
  278. #else
  279. timeout = rfc2131_sleep_interval (TIMEOUT, retry);
  280. #endif
  281. if (! await_reply (AWAIT_TFTP, iport, NULL, timeout))
  282. {
  283. if (! block && retry++ < MAX_TFTP_RETRIES)
  284. {
  285. /* Maybe initial request was lost. */
  286. if (! udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr,
  287. ++iport, TFTP_PORT, len, &tp))
  288. return 0;
  289. continue;
  290. }
  291. #ifdef CONGESTED
  292. if (block && ((retry += TFTP_REXMT) < TFTP_TIMEOUT))
  293. {
  294. /* We resend our last ack. */
  295. #ifdef MDEBUG
  296. grub_printf ("<REXMT>\n");
  297. #endif
  298. udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr,
  299. iport, oport,
  300. TFTP_MIN_PACKET, &tp);
  301. continue;
  302. }
  303. #endif
  304. /* Timeout. */
  305. break;
  306. }
  307. tr = (struct tftp_t *) &nic.packet[ETH_HLEN];
  308. if (tr->opcode == ntohs (TFTP_ERROR))
  309. {
  310. grub_printf ("TFTP error %d (%s)\n",
  311. ntohs (tr->u.err.errcode),
  312. tr->u.err.errmsg);
  313. break;
  314. }
  315. if (tr->opcode == ntohs (TFTP_OACK))
  316. {
  317. char *p = tr->u.oack.data, *e;
  318. /* Shouldn't happen. */
  319. if (prevblock)
  320. /* Ignore it. */
  321. continue;
  322. len = ntohs (tr->udp.len) - sizeof (struct udphdr) - 2;
  323. if (len > TFTP_MAX_PACKET)
  324. goto noak;
  325. e = p + len;
  326. while (*p != '\000' && p < e)
  327. {
  328. if (! grub_strcmp ("blksize", p))
  329. {
  330. p += 8;
  331. if ((packetsize = getdec (&p)) < TFTP_DEFAULTSIZE_PACKET)
  332. goto noak;
  333. while (p < e && *p)
  334. p++;
  335. if (p < e)
  336. p++;
  337. }
  338. else
  339. {
  340. noak:
  341. tp.opcode = htons (TFTP_ERROR);
  342. tp.u.err.errcode = 8;
  343. len = (grub_sprintf ((char *) tp.u.err.errmsg,
  344. "RFC1782 error")
  345. + sizeof (tp.ip) + sizeof (tp.udp)
  346. + sizeof (tp.opcode) + sizeof (tp.u.err.errcode)
  347. + 1);
  348. udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr,
  349. iport, ntohs (tr->udp.src),
  350. len, &tp);
  351. return 0;
  352. }
  353. }
  354. if (p > e)
  355. goto noak;
  356. /* This ensures that the packet does not get processed as data! */
  357. block = tp.u.ack.block = 0;
  358. }
  359. else if (tr->opcode == ntohs (TFTP_DATA))
  360. {
  361. len = ntohs (tr->udp.len) - sizeof (struct udphdr) - 4;
  362. /* Shouldn't happen. */
  363. if (len > packetsize)
  364. /* Ignore it. */
  365. continue;
  366. block = ntohs (tp.u.ack.block = tr->u.data.block);
  367. }
  368. else
  369. /* Neither TFTP_OACK nor TFTP_DATA. */
  370. break;
  371. if ((block || bcounter) && (block != prevblock + 1))
  372. /* Block order should be continuous */
  373. tp.u.ack.block = htons (block = prevblock);
  374. /* Should be continuous. */
  375. tp.opcode = htons (TFTP_ACK);
  376. oport = ntohs (tr->udp.src);
  377. /* Ack. */
  378. udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr, iport,
  379. oport, TFTP_MIN_PACKET, &tp);
  380. if ((unsigned short) (block - prevblock) != 1)
  381. /* Retransmission or OACK, don't process via callback
  382. * and don't change the value of prevblock. */
  383. continue;
  384. prevblock = block;
  385. /* Is it the right place to zero the timer? */
  386. retry = 0;
  387. if ((rc = fnc (tr->u.data.download,
  388. ++bcounter, len, len < packetsize)) >= 0)
  389. return rc;
  390. /* End of data. */
  391. if (len < packetsize)
  392. return 1;
  393. }
  394. return 0;
  395. }
  396. /**************************************************************************
  397. RARP - Get my IP address and load information
  398. **************************************************************************/
  399. int
  400. rarp (void)
  401. {
  402. int retry;
  403. /* arp and rarp requests share the same packet structure. */
  404. struct arprequest rarpreq;
  405. /* Make sure that an ethernet is probed. */
  406. if (! eth_probe ())
  407. return 0;
  408. /* Clear the ready flag. */
  409. network_ready = 0;
  410. grub_memset (&rarpreq, 0, sizeof (rarpreq));
  411. rarpreq.hwtype = htons (1);
  412. rarpreq.protocol = htons (IP);
  413. rarpreq.hwlen = ETH_ALEN;
  414. rarpreq.protolen = 4;
  415. rarpreq.opcode = htons (RARP_REQUEST);
  416. grub_memmove ((char *) &rarpreq.shwaddr, arptable[ARP_CLIENT].node,
  417. ETH_ALEN);
  418. /* sipaddr is already zeroed out */
  419. grub_memmove ((char *) &rarpreq.thwaddr, arptable[ARP_CLIENT].node,
  420. ETH_ALEN);
  421. /* tipaddr is already zeroed out */
  422. for (retry = 0; retry < MAX_ARP_RETRIES; ++retry)
  423. {
  424. long timeout;
  425. eth_transmit (broadcast, RARP, sizeof (rarpreq), &rarpreq);
  426. timeout = rfc2131_sleep_interval (TIMEOUT, retry);
  427. if (await_reply (AWAIT_RARP, 0, rarpreq.shwaddr, timeout))
  428. break;
  429. if (ip_abort)
  430. return 0;
  431. }
  432. if (retry < MAX_ARP_RETRIES)
  433. {
  434. network_ready = 1;
  435. return 1;
  436. }
  437. return 0;
  438. }
  439. /**************************************************************************
  440. BOOTP - Get my IP address and load information
  441. **************************************************************************/
  442. int
  443. bootp (void)
  444. {
  445. int retry;
  446. #ifndef NO_DHCP_SUPPORT
  447. int reqretry;
  448. #endif /* ! NO_DHCP_SUPPORT */
  449. struct bootpip_t ip;
  450. unsigned long starttime;
  451. /* Make sure that an ethernet is probed. */
  452. if (! eth_probe ())
  453. return 0;
  454. /* Clear the ready flag. */
  455. network_ready = 0;
  456. #ifdef DEBUG
  457. grub_printf ("network is ready.\n");
  458. #endif
  459. grub_memset (&ip, 0, sizeof (struct bootpip_t));
  460. ip.bp.bp_op = BOOTP_REQUEST;
  461. ip.bp.bp_htype = 1;
  462. ip.bp.bp_hlen = ETH_ALEN;
  463. starttime = currticks ();
  464. /* Use lower 32 bits of node address, more likely to be
  465. distinct than the time since booting */
  466. grub_memmove (&xid, &arptable[ARP_CLIENT].node[2], sizeof(xid));
  467. ip.bp.bp_xid = xid += htonl (starttime);
  468. grub_memmove (ip.bp.bp_hwaddr, arptable[ARP_CLIENT].node, ETH_ALEN);
  469. #ifdef DEBUG
  470. etherboot_printf ("bp_op = %d\n", ip.bp.bp_op);
  471. etherboot_printf ("bp_htype = %d\n", ip.bp.bp_htype);
  472. etherboot_printf ("bp_hlen = %d\n", ip.bp.bp_hlen);
  473. etherboot_printf ("bp_xid = %d\n", ip.bp.bp_xid);
  474. etherboot_printf ("bp_hwaddr = %!\n", ip.bp.bp_hwaddr);
  475. etherboot_printf ("bp_hops = %d\n", (int) ip.bp.bp_hops);
  476. etherboot_printf ("bp_secs = %d\n", (int) ip.bp.bp_hwaddr);
  477. #endif
  478. #ifdef NO_DHCP_SUPPORT
  479. /* Request RFC-style options. */
  480. grub_memmove (ip.bp.bp_vend, rfc1533_cookie, 5);
  481. #else
  482. /* Request RFC-style options. */
  483. grub_memmove (ip.bp.bp_vend, rfc1533_cookie, sizeof rfc1533_cookie);
  484. grub_memmove (ip.bp.bp_vend + sizeof rfc1533_cookie, dhcpdiscover,
  485. sizeof dhcpdiscover);
  486. grub_memmove (ip.bp.bp_vend + sizeof rfc1533_cookie + sizeof dhcpdiscover,
  487. rfc1533_end, sizeof rfc1533_end);
  488. #endif /* ! NO_DHCP_SUPPORT */
  489. for (retry = 0; retry < MAX_BOOTP_RETRIES;)
  490. {
  491. long timeout;
  492. #ifdef DEBUG
  493. grub_printf ("retry = %d\n", retry);
  494. #endif
  495. /* Clear out the Rx queue first. It contains nothing of
  496. * interest, except possibly ARP requests from the DHCP/TFTP
  497. * server. We use polling throughout Etherboot, so some time
  498. * may have passed since we last polled the receive queue,
  499. * which may now be filled with broadcast packets. This will
  500. * cause the reply to the packets we are about to send to be
  501. * lost immediately. Not very clever. */
  502. await_reply (AWAIT_QDRAIN, 0, NULL, 0);
  503. udp_transmit (IP_BROADCAST, BOOTP_CLIENT, BOOTP_SERVER,
  504. sizeof (struct bootpip_t), &ip);
  505. timeout = rfc2131_sleep_interval (TIMEOUT, retry++);
  506. #ifdef NO_DHCP_SUPPORT
  507. if (await_reply (AWAIT_BOOTP, 0, NULL, timeout))
  508. {
  509. network_ready = 1;
  510. return 1;
  511. }
  512. #else /* ! NO_DHCP_SUPPORT */
  513. if (await_reply (AWAIT_BOOTP, 0, NULL, timeout))
  514. {
  515. if (dhcp_reply != DHCPOFFER)
  516. {
  517. network_ready = 1;
  518. return 1;
  519. }
  520. dhcp_reply = 0;
  521. #ifdef DEBUG
  522. etherboot_printf ("bp_op = %d\n", (int) ip.bp.bp_op);
  523. etherboot_printf ("bp_htype = %d\n", (int) ip.bp.bp_htype);
  524. etherboot_printf ("bp_hlen = %d\n", (int) ip.bp.bp_hlen);
  525. etherboot_printf ("bp_xid = %d\n", (int) ip.bp.bp_xid);
  526. etherboot_printf ("bp_hwaddr = %!\n", ip.bp.bp_hwaddr);
  527. etherboot_printf ("bp_hops = %d\n", (int) ip.bp.bp_hops);
  528. etherboot_printf ("bp_secs = %d\n", (int) ip.bp.bp_hwaddr);
  529. #endif
  530. grub_memmove (ip.bp.bp_vend, rfc1533_cookie, sizeof rfc1533_cookie);
  531. grub_memmove (ip.bp.bp_vend + sizeof rfc1533_cookie,
  532. dhcprequest, sizeof dhcprequest);
  533. grub_memmove (ip.bp.bp_vend + sizeof rfc1533_cookie
  534. + sizeof dhcprequest,
  535. rfc1533_end, sizeof rfc1533_end);
  536. grub_memmove (ip.bp.bp_vend + 9, (char *) &dhcp_server,
  537. sizeof (in_addr));
  538. grub_memmove (ip.bp.bp_vend + 15, (char *) &dhcp_addr,
  539. sizeof (in_addr));
  540. #ifdef DEBUG
  541. grub_printf ("errnum = %d\n", errnum);
  542. #endif
  543. for (reqretry = 0; reqretry < MAX_BOOTP_RETRIES;)
  544. {
  545. int ret;
  546. #ifdef DEBUG
  547. grub_printf ("reqretry = %d\n", reqretry);
  548. #endif
  549. ret = udp_transmit (IP_BROADCAST, BOOTP_CLIENT, BOOTP_SERVER,
  550. sizeof (struct bootpip_t), &ip);
  551. if (! ret)
  552. grub_printf ("udp_transmit failed.\n");
  553. dhcp_reply = 0;
  554. timeout = rfc2131_sleep_interval (TIMEOUT, reqretry++);
  555. if (await_reply (AWAIT_BOOTP, 0, NULL, timeout))
  556. if (dhcp_reply == DHCPACK)
  557. {
  558. network_ready = 1;
  559. return 1;
  560. }
  561. #ifdef DEBUG
  562. grub_printf ("dhcp_reply = %d\n", dhcp_reply);
  563. #endif
  564. if (ip_abort)
  565. return 0;
  566. }
  567. }
  568. #endif /* ! NO_DHCP_SUPPORT */
  569. if (ip_abort)
  570. return 0;
  571. ip.bp.bp_secs = htons ((currticks () - starttime) / TICKS_PER_SEC);
  572. }
  573. /* Timeout. */
  574. return 0;
  575. }
  576. /**************************************************************************
  577. UDPCHKSUM - Checksum UDP Packet (one of the rare cases when assembly is
  578. actually simpler...)
  579. RETURNS: checksum, 0 on checksum error. This
  580. allows for using the same routine for RX and TX summing:
  581. RX if (packet->udp.chksum && udpchksum(packet))
  582. error("checksum error");
  583. TX packet->udp.chksum=0;
  584. if (0==(packet->udp.chksum=udpchksum(packet)))
  585. packet->upd.chksum=0xffff;
  586. **************************************************************************/
  587. static inline void
  588. dosum (unsigned short *start, unsigned int len, unsigned short *sum)
  589. {
  590. __asm__ __volatile__
  591. ("clc\n"
  592. "1:\tlodsw\n\t"
  593. "xchg %%al,%%ah\n\t" /* convert to host byte order */
  594. "adcw %%ax,%0\n\t" /* add carry of previous iteration */
  595. "loop 1b\n\t"
  596. "adcw $0,%0" /* add carry of last iteration */
  597. : "=b" (*sum), "=S"(start), "=c"(len)
  598. : "0"(*sum), "1"(start), "2"(len)
  599. : "ax", "cc"
  600. );
  601. }
  602. /* UDP sum:
  603. * proto, src_ip, dst_ip, udp_dport, udp_sport, 2*udp_len, payload
  604. */
  605. static unsigned short
  606. udpchksum (struct iphdr *packet)
  607. {
  608. int len = ntohs (packet->len);
  609. unsigned short rval;
  610. /* add udplength + protocol number */
  611. rval = (len - sizeof (struct iphdr)) + IP_UDP;
  612. /* pad to an even number of bytes */
  613. if (len % 2) {
  614. ((char *) packet)[len++] = 0;
  615. }
  616. /* sum over src/dst ipaddr + udp packet */
  617. len -= (char *) &packet->src - (char *) packet;
  618. dosum ((unsigned short *) &packet->src, len >> 1, &rval);
  619. /* take one's complement */
  620. return ~rval;
  621. }
  622. /**************************************************************************
  623. AWAIT_REPLY - Wait until we get a response for our request
  624. **************************************************************************/
  625. int
  626. await_reply (int type, int ival, void *ptr, int timeout)
  627. {
  628. unsigned long time;
  629. struct iphdr *ip;
  630. struct udphdr *udp;
  631. struct arprequest *arpreply;
  632. struct bootp_t *bootpreply;
  633. unsigned short ptype;
  634. unsigned int protohdrlen = (ETH_HLEN + sizeof (struct iphdr)
  635. + sizeof (struct udphdr));
  636. /* Clear the abort flag. */
  637. ip_abort = 0;
  638. time = timeout + currticks ();
  639. /* The timeout check is done below. The timeout is only checked if
  640. * there is no packet in the Rx queue. This assumes that eth_poll()
  641. * needs a negligible amount of time. */
  642. for (;;)
  643. {
  644. if (eth_poll ())
  645. {
  646. /* We have something! */
  647. /* Check for ARP - No IP hdr. */
  648. if (nic.packetlen >= ETH_HLEN)
  649. {
  650. ptype = (((unsigned short) nic.packet[12]) << 8
  651. | ((unsigned short) nic.packet[13]));
  652. }
  653. else
  654. /* What else could we do with it? */
  655. continue;
  656. if (nic.packetlen >= ETH_HLEN + sizeof (struct arprequest)
  657. && ptype == ARP)
  658. {
  659. unsigned long tmp;
  660. arpreply = (struct arprequest *) &nic.packet[ETH_HLEN];
  661. if (arpreply->opcode == htons (ARP_REPLY)
  662. && ! grub_memcmp (arpreply->sipaddr, ptr, sizeof (in_addr))
  663. && type == AWAIT_ARP)
  664. {
  665. grub_memmove ((char *) arptable[ival].node,
  666. arpreply->shwaddr,
  667. ETH_ALEN);
  668. return 1;
  669. }
  670. grub_memmove ((char *) &tmp, arpreply->tipaddr,
  671. sizeof (in_addr));
  672. if (arpreply->opcode == htons (ARP_REQUEST)
  673. && tmp == arptable[ARP_CLIENT].ipaddr.s_addr)
  674. {
  675. arpreply->opcode = htons (ARP_REPLY);
  676. grub_memmove (arpreply->tipaddr, arpreply->sipaddr,
  677. sizeof (in_addr));
  678. grub_memmove (arpreply->thwaddr, (char *) arpreply->shwaddr,
  679. ETH_ALEN);
  680. grub_memmove (arpreply->sipaddr,
  681. (char *) &arptable[ARP_CLIENT].ipaddr,
  682. sizeof (in_addr));
  683. grub_memmove (arpreply->shwaddr,
  684. arptable[ARP_CLIENT].node,
  685. ETH_ALEN);
  686. eth_transmit (arpreply->thwaddr, ARP,
  687. sizeof (struct arprequest),
  688. arpreply);
  689. #ifdef MDEBUG
  690. grub_memmove (&tmp, arpreply->tipaddr, sizeof (in_addr));
  691. etherboot_printf ("Sent ARP reply to: %@\n", tmp);
  692. #endif /* MDEBUG */
  693. }
  694. continue;
  695. }
  696. if (type == AWAIT_QDRAIN)
  697. continue;
  698. /* Check for RARP - No IP hdr. */
  699. if (type == AWAIT_RARP
  700. && nic.packetlen >= ETH_HLEN + sizeof (struct arprequest)
  701. && ptype == RARP)
  702. {
  703. arpreply = (struct arprequest *) &nic.packet[ETH_HLEN];
  704. if (arpreply->opcode == htons (RARP_REPLY)
  705. && ! grub_memcmp (arpreply->thwaddr, ptr, ETH_ALEN))
  706. {
  707. grub_memmove ((char *) arptable[ARP_SERVER].node,
  708. arpreply->shwaddr, ETH_ALEN);
  709. grub_memmove ((char *) &arptable[ARP_SERVER].ipaddr,
  710. arpreply->sipaddr, sizeof (in_addr));
  711. grub_memmove ((char *) &arptable[ARP_CLIENT].ipaddr,
  712. arpreply->tipaddr, sizeof (in_addr));
  713. return 1;
  714. }
  715. continue;
  716. }
  717. /* Anything else has IP header. */
  718. if (nic.packetlen < protohdrlen || ptype != IP)
  719. continue;
  720. ip = (struct iphdr *) &nic.packet[ETH_HLEN];
  721. if (ip->verhdrlen != 0x45
  722. || ipchksum ((unsigned short *) ip, sizeof (struct iphdr))
  723. || ip->protocol != IP_UDP)
  724. continue;
  725. /*
  726. - Till Straumann <Till.Straumann@TU-Berlin.de>
  727. added udp checksum (safer on a wireless link)
  728. added fragmentation check: I had a corrupted image
  729. in memory due to fragmented TFTP packets - took me
  730. 3 days to find the cause for this :-(
  731. */
  732. /* If More Fragments bit and Fragment Offset field
  733. are non-zero then packet is fragmented */
  734. if (ip->frags & htons(0x3FFF))
  735. {
  736. grub_printf ("ALERT: got a fragmented packet - reconfigure your server\n");
  737. continue;
  738. }
  739. udp = (struct udphdr *) &nic.packet[(ETH_HLEN
  740. + sizeof (struct iphdr))];
  741. if (udp->chksum && udpchksum (ip))
  742. {
  743. grub_printf ("UDP checksum error\n");
  744. continue;
  745. }
  746. /* BOOTP ? */
  747. bootpreply = (struct bootp_t *)
  748. &nic.packet[(ETH_HLEN + sizeof (struct iphdr)
  749. + sizeof (struct udphdr))];
  750. if (type == AWAIT_BOOTP
  751. #ifdef NO_DHCP_SUPPORT
  752. && (nic.packetlen
  753. >= (ETH_HLEN + sizeof (struct bootp_t) - BOOTP_VENDOR_LEN))
  754. #else
  755. && (nic.packetlen
  756. >= (ETH_HLEN + sizeof (struct bootp_t) - DHCP_OPT_LEN))
  757. #endif /* ! NO_DHCP_SUPPORT */
  758. && udp->dest == htons (BOOTP_CLIENT)
  759. && bootpreply->bp_op == BOOTP_REPLY
  760. && bootpreply->bp_xid == xid
  761. && (! grub_memcmp (broadcast, bootpreply->bp_hwaddr, ETH_ALEN)
  762. || ! grub_memcmp (arptable[ARP_CLIENT].node,
  763. bootpreply->bp_hwaddr, ETH_ALEN)))
  764. {
  765. #ifdef DEBUG
  766. grub_printf ("BOOTP packet was received.\n");
  767. #endif
  768. arptable[ARP_CLIENT].ipaddr.s_addr
  769. = bootpreply->bp_yiaddr.s_addr;
  770. #ifndef NO_DHCP_SUPPORT
  771. dhcp_addr.s_addr = bootpreply->bp_yiaddr.s_addr;
  772. #ifdef DEBUG
  773. etherboot_printf ("dhcp_addr = %@\n", dhcp_addr.s_addr);
  774. #endif
  775. #endif /* ! NO_DHCP_SUPPORT */
  776. netmask = default_netmask ();
  777. arptable[ARP_SERVER].ipaddr.s_addr
  778. = bootpreply->bp_siaddr.s_addr;
  779. /* Kill arp. */
  780. grub_memset (arptable[ARP_SERVER].node, 0, ETH_ALEN);
  781. arptable[ARP_GATEWAY].ipaddr.s_addr
  782. = bootpreply->bp_giaddr.s_addr;
  783. /* Kill arp. */
  784. grub_memset (arptable[ARP_GATEWAY].node, 0, ETH_ALEN);
  785. grub_memmove ((char *) BOOTP_DATA_ADDR, (char *) bootpreply,
  786. sizeof (struct bootpd_t));
  787. #ifdef NO_DHCP_SUPPORT
  788. decode_rfc1533 (BOOTP_DATA_ADDR->bootp_reply.bp_vend,
  789. 0, BOOTP_VENDOR_LEN + MAX_BOOTP_EXTLEN, 1);
  790. #else
  791. decode_rfc1533 (BOOTP_DATA_ADDR->bootp_reply.bp_vend,
  792. 0, DHCP_OPT_LEN + MAX_BOOTP_EXTLEN, 1);
  793. #endif /* ! NO_DHCP_SUPPORT */
  794. return 1;
  795. }
  796. /* TFTP ? */
  797. if (type == AWAIT_TFTP && ntohs (udp->dest) == ival)
  798. return 1;
  799. }
  800. else
  801. {
  802. /* Check for abort key only if the Rx queue is empty -
  803. * as long as we have something to process, don't
  804. * assume that something failed. It is unlikely that
  805. * we have no processing time left between packets. */
  806. if (checkkey () != -1 && ASCII_CHAR (getkey ()) == CTRL_C)
  807. {
  808. ip_abort = 1;
  809. return 0;
  810. }
  811. /* Do the timeout after at least a full queue walk. */
  812. if ((timeout == 0) || (currticks() > time))
  813. {
  814. break;
  815. }
  816. }
  817. }
  818. return 0;
  819. }
  820. /**************************************************************************
  821. DECODE_RFC1533 - Decodes RFC1533 header
  822. **************************************************************************/
  823. int
  824. decode_rfc1533 (unsigned char *p, int block, int len, int eof)
  825. {
  826. static unsigned char *extdata = NULL, *extend = NULL;
  827. unsigned char *extpath = NULL;
  828. unsigned char *endp;
  829. if (block == 0)
  830. {
  831. vendorext_isvalid = 0;
  832. if (grub_memcmp (p, rfc1533_cookie, 4))
  833. /* no RFC 1533 header found */
  834. return 0;
  835. p += 4;
  836. endp = p + len;
  837. }
  838. else
  839. {
  840. if (block == 1)
  841. {
  842. if (grub_memcmp (p, rfc1533_cookie, 4))
  843. /* no RFC 1533 header found */
  844. return 0;
  845. p += 4;
  846. len -= 4;
  847. }
  848. if (extend + len
  849. <= ((unsigned char *)
  850. &(BOOTP_DATA_ADDR->bootp_extension[MAX_BOOTP_EXTLEN])))
  851. {
  852. grub_memmove (extend, p, len);
  853. extend += len;
  854. }
  855. else
  856. {
  857. grub_printf ("Overflow in vendor data buffer! Aborting...\n");
  858. *extdata = RFC1533_END;
  859. return 0;
  860. }
  861. p = extdata;
  862. endp = extend;
  863. }
  864. if (! eof)
  865. return -1;
  866. while (p < endp)
  867. {
  868. unsigned char c = *p;
  869. if (c == RFC1533_PAD)
  870. {
  871. p++;
  872. continue;
  873. }
  874. else if (c == RFC1533_END)
  875. {
  876. endp = p;
  877. continue;
  878. }
  879. else if (c == RFC1533_NETMASK)
  880. {
  881. grub_memmove ((char *) &netmask, p + 2, sizeof (in_addr));
  882. }
  883. else if (c == RFC1533_GATEWAY)
  884. {
  885. /* This is a little simplistic, but it will
  886. usually be sufficient.
  887. Take only the first entry. */
  888. if (TAG_LEN (p) >= sizeof (in_addr))
  889. grub_memmove ((char *) &arptable[ARP_GATEWAY].ipaddr, p + 2,
  890. sizeof (in_addr));
  891. }
  892. else if (c == RFC1533_EXTENSIONPATH)
  893. extpath = p;
  894. #ifndef NO_DHCP_SUPPORT
  895. else if (c == RFC2132_MSG_TYPE)
  896. {
  897. dhcp_reply = *(p + 2);
  898. }
  899. else if (c == RFC2132_SRV_ID)
  900. {
  901. grub_memmove ((char *) &dhcp_server, p + 2, sizeof (in_addr));
  902. #ifdef DEBUG
  903. etherboot_printf ("dhcp_server = %@\n", dhcp_server.s_addr);
  904. #endif
  905. }
  906. #endif /* ! NO_DHCP_SUPPORT */
  907. else if (c == RFC1533_VENDOR_MAGIC
  908. && TAG_LEN(p) >= 6
  909. && ! grub_memcmp (p + 2, vendorext_magic, 4)
  910. && p[6] == RFC1533_VENDOR_MAJOR)
  911. vendorext_isvalid++;
  912. /* GRUB now handles its own tag. Get the name of a configuration
  913. file from the network. Cool... */
  914. else if (c == RFC1533_VENDOR_CONFIGFILE)
  915. {
  916. int l = TAG_LEN (p);
  917. /* Eliminate the trailing NULs according to RFC 2132. */
  918. while (*(p + 2 + l - 1) == '\000' && l > 0)
  919. l--;
  920. /* XXX: Should check if LEN is less than the maximum length
  921. of CONFIG_FILE. This kind of robustness will be a goal
  922. in GRUB 1.0. */
  923. grub_memmove (config_file, p + 2, l);
  924. config_file[l] = 0;
  925. }
  926. p += TAG_LEN (p) + 2;
  927. }
  928. extdata = extend = endp;
  929. /* Perhaps we can eliminate this because we doesn't require so
  930. much information, but I leave this alone. */
  931. if (block == 0 && extpath != NULL)
  932. {
  933. char fname[64];
  934. int fnamelen = TAG_LEN (extpath);
  935. while (*(extpath + 2 + fnamelen - 1) == '\000' && fnamelen > 0)
  936. fnamelen--;
  937. if (fnamelen + 1 > sizeof (fname))
  938. {
  939. grub_printf ("Too long file name for Extensions Path\n");
  940. return 0;
  941. }
  942. else if (! fnamelen)
  943. {
  944. grub_printf ("Empty file name for Extensions Path\n");
  945. return 0;
  946. }
  947. grub_memmove (fname, extpath + 2, fnamelen);
  948. fname[fnamelen] = '\000';
  949. grub_printf ("Loading BOOTP-extension file: %s\n", fname);
  950. tftp (fname, decode_rfc1533);
  951. }
  952. /* Proceed with next block. */
  953. return -1;
  954. }
  955. /**************************************************************************
  956. IPCHKSUM - Checksum IP Header
  957. **************************************************************************/
  958. static unsigned short
  959. ipchksum (unsigned short *ip, int len)
  960. {
  961. unsigned long sum = 0;
  962. len >>= 1;
  963. while (len--)
  964. {
  965. sum += *(ip++);
  966. if (sum > 0xFFFF)
  967. sum -= 0xFFFF;
  968. }
  969. return (~sum) & 0x0000FFFF;
  970. }
  971. #define TWO_SECOND_DIVISOR (2147483647l/TICKS_PER_SEC)
  972. /**************************************************************************
  973. RFC2131_SLEEP_INTERVAL - sleep for expotentially longer times
  974. **************************************************************************/
  975. long
  976. rfc2131_sleep_interval (int base, int exp)
  977. {
  978. static long seed = 0;
  979. long q;
  980. unsigned long tmo;
  981. #ifdef BACKOFF_LIMIT
  982. if (exp > BACKOFF_LIMIT)
  983. exp = BACKOFF_LIMIT;
  984. #endif
  985. if (!seed)
  986. /* Initialize linear congruential generator */
  987. seed = (currticks () + *((long *) &arptable[ARP_CLIENT].node)
  988. + ((short *) arptable[ARP_CLIENT].node)[2]);
  989. /* simplified version of the LCG given in Bruce Schneier's
  990. "Applied Cryptography" */
  991. q = seed / 53668;
  992. if ((seed = 40014 * (seed - 53668 * q) - 12211 *q ) < 0)
  993. seed += 2147483563L;
  994. tmo = (base << exp) + (TICKS_PER_SEC - (seed / TWO_SECOND_DIVISOR));
  995. return tmo;
  996. }
  997. /**************************************************************************
  998. CLEANUP - shut down networking
  999. **************************************************************************/
  1000. void
  1001. cleanup_net (void)
  1002. {
  1003. if (network_ready)
  1004. {
  1005. /* Stop receiving packets. */
  1006. eth_disable ();
  1007. network_ready = 0;
  1008. }
  1009. }