123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884
  1. From daniel@insu.com Thu Apr 27 14:14:55 2000
  2. Sender: root@iNsu.COM
  3. Message-ID: <39075669.FAEB20F2@insu.com>
  4. Date: Wed, 26 Apr 2000 16:49:45 -0400
  5. From: Daniel Shane <daniel@insu.com>
  6. X-Mailer: Mozilla 4.72 [en] (X11; U; Linux 2.2.14-5.0 i686)
  7. X-Accept-Language: en
  8. MIME-Version: 1.0
  9. Subject: Re: New feature added to etherboot
  10. References: <20000425170804.6677127D8A@Goffman.iNsu.COM>
  11. Content-Type: multipart/mixed;
  12. boundary="------------4734FDA0BF2F2FBDF8EB8DF6"
  13. This is a multi-part message in MIME format.
  14. --------------4734FDA0BF2F2FBDF8EB8DF6
  15. Content-Type: text/plain; charset=us-ascii
  16. Content-Transfer-Encoding: 7bit
  17. Ok, here is a diff for etherboot 4.6.0 that adds identifiers.
  18. To test this you need to use a class in the dhcpd.conf file and
  19. also send back a string in option 208.
  20. These identifiers prevent a client from booting from other DHCP
  21. servers when you have more than 1 in your network.
  22. In will also prevent any client, except the valid ones, to use this
  23. DHCP server.
  24. Here is a subset of my dhcpd.conf :
  25. option iNdiskless-state code 208 = text;
  26. class "iNdiskless-boot" {
  27. match if substring(option iNdiskless-state,0,4) = "BOOT";
  28. }
  29. class "iNdiskless-setup" {
  30. match if substring(option iNdiskless-state,0,5) = "SETUP";
  31. }
  32. subnet 10.4.1.0 netmask 255.255.255.0 {
  33. pool {
  34. allow members of "iNdiskless-boot";
  35. deny unknown clients;
  36. range 10.4.1.2 10.4.1.200;
  37. next-server 10.4.1.1;
  38. # Identify ourselves to the etherboot/DHCP client
  39. option iNdiskless-state "BOOT";
  40. host labo01 {
  41. hardware ethernet 00:80:c8:ec:04:1b;
  42. }
  43. host labo02 {
  44. hardware ethernet 00:4f:4c:04:45:d6;
  45. }
  46. host labo03 {
  47. hardware ethernet 00:50:ba:c8:db:d6;
  48. }
  49. }
  50. pool {
  51. allow members of "iNdiskless-setup";
  52. range 10.4.1.201 10.4.1.254;
  53. option iNdiskless-state "SETUP";
  54. # send another kernel to setup the diskless workstation
  55. }
  56. }
  57. Daniel Shane.
  58. --------------4734FDA0BF2F2FBDF8EB8DF6
  59. Content-Type: text/plain; charset=us-ascii;
  60. name="main.c.diff"
  61. Content-Transfer-Encoding: 7bit
  62. Content-Disposition: inline;
  63. filename="main.c.diff"
  64. --- etherboot-4.6.0/src/main.c Tue Apr 25 08:30:01 2000
  65. +++ etherboot-4.5.6-new/src/main.c Wed Apr 26 16:17:09 2000
  66. @@ -42,6 +42,23 @@ char *motd[RFC1533_VENDOR_NUMOFMOTD];
  67. #ifdef IMAGE_FREEBSD
  68. int freebsd_howto = 0;
  69. #endif
  70. +
  71. +#ifdef SERVER_IDENT
  72. +#ifdef DEFAULT_SERVER_IDENT
  73. +char server_ident[9] = DEFAULT_SERVER_IDENT;
  74. +#else
  75. +char server_ident[9] = {};
  76. +#endif
  77. +#endif
  78. +
  79. +#ifdef CLIENT_IDENT
  80. +#ifdef DEFAULT_CLIENT_IDENT
  81. +char client_ident[9] = DEFAULT_CLIENT_IDENT;
  82. +#else
  83. +char client_ident[9] = {};
  84. +#endif
  85. +#endif
  86. +
  87. int vendorext_isvalid;
  88. char config_buffer[TFTP_MAX_PACKET+1]; /* +1 for null byte */
  89. unsigned long netmask;
  90. @@ -63,61 +80,85 @@ char rfc1533_cookie[5] = { RFC1533_CO
  91. char rfc1533_cookie[] = { RFC1533_COOKIE};
  92. char rfc1533_end[]={RFC1533_END };
  93. static const char dhcpdiscover[]={
  94. - RFC2132_MSG_TYPE,1,DHCPDISCOVER,
  95. - RFC2132_MAX_SIZE,2,2,64,
  96. - RFC2132_PARAM_LIST,4,RFC1533_NETMASK,RFC1533_GATEWAY,
  97. - RFC1533_HOSTNAME,RFC1533_EXTENSIONPATH
  98. - };
  99. -static const char dhcprequest []={
  100. - RFC2132_MSG_TYPE,1,DHCPREQUEST,
  101. - RFC2132_SRV_ID,4,0,0,0,0,
  102. - RFC2132_REQ_ADDR,4,0,0,0,0,
  103. - RFC2132_MAX_SIZE,2,2,64,
  104. - /* request parameters */
  105. - RFC2132_PARAM_LIST,
  106. -#ifdef IMAGE_FREEBSD
  107. - /* 4 standard + 4 vendortags + 8 motd + 16 menu items */
  108. - 4 + 4 + 8 + 16,
  109. + RFC2132_MSG_TYPE,1,DHCPDISCOVER,
  110. + RFC2132_MAX_SIZE,2,2,64,
  111. +#ifdef CLIENT_IDENT
  112. + RFC1533_VENDOR_CLIENT_IDENT,8,0,0,0,0,0,0,0,0,
  113. +#endif
  114. + RFC2132_PARAM_LIST,
  115. +#ifdef SERVER_IDENT
  116. + 5,
  117. #else
  118. - /* 4 standard + 3 vendortags + 8 motd + 16 menu items */
  119. - 4 + 3 + 8 + 16,
  120. + 4,
  121. #endif
  122. - /* Standard parameters */
  123. - RFC1533_NETMASK, RFC1533_GATEWAY,
  124. - RFC1533_HOSTNAME, RFC1533_EXTENSIONPATH,
  125. - /* Etherboot vendortags */
  126. - RFC1533_VENDOR_MAGIC,
  127. +#ifdef SERVER_IDENT
  128. + RFC1533_VENDOR_SERVER_IDENT,
  129. +#endif
  130. + RFC1533_NETMASK,
  131. + RFC1533_GATEWAY,
  132. + RFC1533_HOSTNAME,
  133. + RFC1533_EXTENSIONPATH
  134. +};
  135. +static const char dhcprequest []={
  136. + RFC2132_MSG_TYPE,1,DHCPREQUEST,
  137. + RFC2132_SRV_ID,4,0,0,0,0,
  138. + RFC2132_REQ_ADDR,4,0,0,0,0,
  139. +#ifdef CLIENT_IDENT
  140. + RFC1533_VENDOR_CLIENT_IDENT,8,0,0,0,0,0,0,0,0,
  141. +#endif
  142. + RFC2132_MAX_SIZE,2,2,64,
  143. + /* request parameters */
  144. + RFC2132_PARAM_LIST,
  145. + /* 4 standard + 3 vendortags + 8 motd + 16 menu items */
  146. + 4 +
  147. + 3 +
  148. +#ifdef IMAGE_FREEBSD
  149. + 1 + /* One more vendortags for VENDOR_HOWTO */
  150. +#endif
  151. +#ifdef SERVER_IDENT
  152. + 1 + /* One more vendortags for VENDOR_SERVER_IDENT */
  153. +#endif
  154. + 8 +
  155. + 16,
  156. + /* Standard parameters */
  157. + RFC1533_NETMASK, RFC1533_GATEWAY,
  158. + RFC1533_HOSTNAME, RFC1533_EXTENSIONPATH,
  159. + /* Etherboot vendortags */
  160. + RFC1533_VENDOR_MAGIC,
  161. #ifdef IMAGE_FREEBSD
  162. - RFC1533_VENDOR_HOWTO,
  163. + RFC1533_VENDOR_HOWTO,
  164. #endif
  165. - RFC1533_VENDOR_MNUOPTS, RFC1533_VENDOR_SELECTION,
  166. - /* 8 MOTD entries */
  167. - RFC1533_VENDOR_MOTD,
  168. - RFC1533_VENDOR_MOTD+1,
  169. - RFC1533_VENDOR_MOTD+2,
  170. - RFC1533_VENDOR_MOTD+3,
  171. - RFC1533_VENDOR_MOTD+4,
  172. - RFC1533_VENDOR_MOTD+5,
  173. - RFC1533_VENDOR_MOTD+6,
  174. - RFC1533_VENDOR_MOTD+7,
  175. - /* 16 image entries */
  176. - RFC1533_VENDOR_IMG,
  177. - RFC1533_VENDOR_IMG+1,
  178. - RFC1533_VENDOR_IMG+2,
  179. - RFC1533_VENDOR_IMG+3,
  180. - RFC1533_VENDOR_IMG+4,
  181. - RFC1533_VENDOR_IMG+5,
  182. - RFC1533_VENDOR_IMG+6,
  183. - RFC1533_VENDOR_IMG+7,
  184. - RFC1533_VENDOR_IMG+8,
  185. - RFC1533_VENDOR_IMG+9,
  186. - RFC1533_VENDOR_IMG+10,
  187. - RFC1533_VENDOR_IMG+11,
  188. - RFC1533_VENDOR_IMG+12,
  189. - RFC1533_VENDOR_IMG+13,
  190. - RFC1533_VENDOR_IMG+14,
  191. - RFC1533_VENDOR_IMG+15,
  192. - };
  193. +#ifdef SERVER_IDENT
  194. + RFC1533_VENDOR_SERVER_IDENT,
  195. +#endif
  196. + RFC1533_VENDOR_MNUOPTS, RFC1533_VENDOR_SELECTION,
  197. + /* 8 MOTD entries */
  198. + RFC1533_VENDOR_MOTD,
  199. + RFC1533_VENDOR_MOTD+1,
  200. + RFC1533_VENDOR_MOTD+2,
  201. + RFC1533_VENDOR_MOTD+3,
  202. + RFC1533_VENDOR_MOTD+4,
  203. + RFC1533_VENDOR_MOTD+5,
  204. + RFC1533_VENDOR_MOTD+6,
  205. + RFC1533_VENDOR_MOTD+7,
  206. + /* 16 image entries */
  207. + RFC1533_VENDOR_IMG,
  208. + RFC1533_VENDOR_IMG+1,
  209. + RFC1533_VENDOR_IMG+2,
  210. + RFC1533_VENDOR_IMG+3,
  211. + RFC1533_VENDOR_IMG+4,
  212. + RFC1533_VENDOR_IMG+5,
  213. + RFC1533_VENDOR_IMG+6,
  214. + RFC1533_VENDOR_IMG+7,
  215. + RFC1533_VENDOR_IMG+8,
  216. + RFC1533_VENDOR_IMG+9,
  217. + RFC1533_VENDOR_IMG+10,
  218. + RFC1533_VENDOR_IMG+11,
  219. + RFC1533_VENDOR_IMG+12,
  220. + RFC1533_VENDOR_IMG+13,
  221. + RFC1533_VENDOR_IMG+14,
  222. + RFC1533_VENDOR_IMG+15,
  223. +};
  224. #endif /* NO_DHCP_SUPPORT */
  225. static const char broadcast[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
  226. @@ -176,6 +217,55 @@ done:
  227. break;
  228. }
  229. #endif
  230. +
  231. +#ifdef SHIFTED_IDENT_INPUT
  232. + if (getshift() & 3)
  233. + {
  234. +#endif
  235. +
  236. +#ifdef CLIENT_IDENT
  237. +# ifdef ASK_CLIENT_IDENT
  238. + {
  239. + char tmp_ident[9] = {};
  240. +# ifdef DEFAULT_CLIENT_IDENT
  241. + printf("Enter the client identifier (8 char max.) default [%s] : ",client_ident);
  242. +# else
  243. + printf("Enter the client identifier (8 char max.) : ");
  244. +# endif
  245. + getstr(tmp_ident,8);
  246. + if (strlen(tmp_ident) != 0)
  247. + memcpy(client_ident,tmp_ident,8);
  248. + else
  249. + printf("%s",client_ident);
  250. + putchar('\n');
  251. + }
  252. +# endif
  253. +#endif
  254. +
  255. +#ifdef SERVER_IDENT
  256. +# ifdef ASK_SERVER_IDENT
  257. + {
  258. + char tmp_ident[9] = {};
  259. +# ifdef DEFAULT_SERVER_IDENT
  260. + printf("Enter the server identifier (8 char max.) default [%s] : ",server_ident);
  261. +# else
  262. + printf("Enter the server identifier (8 char max.) : ");
  263. +# endif
  264. + getstr(tmp_ident,8);
  265. + if (strlen(tmp_ident) != 0)
  266. + memcpy(server_ident,tmp_ident,8);
  267. + else
  268. + printf("%s",server_ident);
  269. + putchar('\n');
  270. + }
  271. +# endif
  272. +#endif
  273. +
  274. +#ifdef SHIFTED_IDENT_INPUT
  275. + }
  276. +#endif
  277. +
  278. + print_config();
  279. #if (TRY_FLOPPY_FIRST > 0) && defined(FLOPPY)
  280. disk_init();
  281. printf("Trying floppy");
  282. @@ -188,7 +278,7 @@ done:
  283. }
  284. printf("no floppy\n");
  285. #endif /* TRY_FLOPPY_FIRST && FLOPPY */
  286. - print_config();
  287. + print_config();
  288. gateA20_set();
  289. #ifdef EMERGENCYDISKBOOT
  290. if (!eth_probe()) {
  291. @@ -663,6 +753,8 @@ BOOTP - Get my IP address and load infor
  292. int bootp()
  293. {
  294. int retry;
  295. + int offset = 0;
  296. +
  297. #ifndef NO_DHCP_SUPPORT
  298. int retry1;
  299. #endif /* NO_DHCP_SUPPORT */
  300. @@ -680,11 +772,18 @@ int bootp()
  301. bp.bp_xid = xid = starttime = currticks();
  302. memcpy(bp.bp_hwaddr, arptable[ARP_CLIENT].node, ETHER_ADDR_SIZE);
  303. #ifdef NO_DHCP_SUPPORT
  304. - memcpy(bp.bp_vend, rfc1533_cookie, 5); /* request RFC-style options */
  305. + memcpy(bp.bp_vend+offset, rfc1533_cookie, 5); /* request RFC-style options */
  306. + offset += sizeof rfc1533_cookie;
  307. #else
  308. - memcpy(bp.bp_vend, rfc1533_cookie, sizeof rfc1533_cookie); /* request RFC-style options */
  309. - memcpy(bp.bp_vend+sizeof rfc1533_cookie, dhcpdiscover, sizeof dhcpdiscover);
  310. - memcpy(bp.bp_vend+sizeof rfc1533_cookie +sizeof dhcpdiscover, rfc1533_end, sizeof rfc1533_end);
  311. + memcpy(bp.bp_vend+offset, rfc1533_cookie, sizeof rfc1533_cookie); /* request RFC-style options */
  312. + offset += sizeof rfc1533_cookie;
  313. + memcpy(bp.bp_vend+offset, dhcpdiscover, sizeof dhcpdiscover);
  314. + offset += sizeof dhcpdiscover;
  315. +#ifdef CLIENT_IDENT
  316. + memcpy(bp.bp_vend+13, client_ident, strlen(client_ident));
  317. +#endif
  318. + memcpy(bp.bp_vend+offset, rfc1533_end, sizeof rfc1533_end);
  319. + offset += sizeof rfc1533_end;
  320. #endif /* NO_DHCP_SUPPORT */
  321. for (retry = 0; retry < MAX_BOOTP_RETRIES; ) {
  322. @@ -715,19 +814,22 @@ int bootp()
  323. #else
  324. if (await_reply(AWAIT_BOOTP, 0, NULL, TIMEOUT)){
  325. if (dhcp_reply==DHCPOFFER){
  326. - dhcp_reply=0;
  327. - memcpy(bp.bp_vend, rfc1533_cookie, sizeof rfc1533_cookie);
  328. - memcpy(bp.bp_vend+sizeof rfc1533_cookie, dhcprequest, sizeof dhcprequest);
  329. - memcpy(bp.bp_vend+sizeof rfc1533_cookie +sizeof dhcprequest, rfc1533_end, sizeof rfc1533_end);
  330. - memcpy(bp.bp_vend+9, &dhcp_server, sizeof(in_addr));
  331. - memcpy(bp.bp_vend+15, &dhcp_addr, sizeof(in_addr));
  332. - for (retry1 = 0; retry1 < MAX_BOOTP_RETRIES;) {
  333. - udp_transmit(IP_BROADCAST, 0, BOOTP_SERVER,
  334. - sizeof(struct bootp_t), &bp);
  335. dhcp_reply=0;
  336. - if (await_reply(AWAIT_BOOTP, 0, NULL, TIMEOUT))
  337. - if (dhcp_reply==DHCPACK)
  338. - return(1);
  339. + memcpy(bp.bp_vend, rfc1533_cookie, sizeof rfc1533_cookie);
  340. + memcpy(bp.bp_vend+sizeof rfc1533_cookie, dhcprequest, sizeof dhcprequest);
  341. + memcpy(bp.bp_vend+sizeof rfc1533_cookie +sizeof dhcprequest, rfc1533_end, sizeof rfc1533_end);
  342. + memcpy(bp.bp_vend+9, &dhcp_server, sizeof(in_addr));
  343. + memcpy(bp.bp_vend+15, &dhcp_addr, sizeof(in_addr));
  344. +#ifdef CLIENT_IDENT
  345. + memcpy(bp.bp_vend+21, client_ident, strlen(client_ident));
  346. +#endif
  347. + for (retry1 = 0; retry1 < MAX_BOOTP_RETRIES;) {
  348. + udp_transmit(IP_BROADCAST, 0, BOOTP_SERVER,
  349. + sizeof(struct bootp_t), &bp);
  350. + dhcp_reply=0;
  351. + if (await_reply(AWAIT_BOOTP, 0, NULL, TIMEOUT))
  352. + if (dhcp_reply==DHCPACK)
  353. + return(1);
  354. rfc951_sleep(++retry1);
  355. }
  356. } else
  357. @@ -750,6 +852,7 @@ AWAIT_REPLY - Wait until we get a respon
  358. **************************************************************************/
  359. int await_reply(int type, int ival, void *ptr, int timeout)
  360. {
  361. + int result;
  362. unsigned long time;
  363. struct iphdr *ip;
  364. struct udphdr *udp;
  365. @@ -757,6 +860,7 @@ int await_reply(int type, int ival, void
  366. struct bootp_t *bootpreply;
  367. struct rpc_t *rpc;
  368. unsigned short ptype;
  369. + unsigned int min_packetlen;
  370. unsigned int protohdrlen = ETHER_HDR_SIZE + sizeof(struct iphdr) +
  371. sizeof(struct udphdr);
  372. @@ -766,35 +870,35 @@ int await_reply(int type, int ival, void
  373. * needs a negligible amount of time. */
  374. for (;;) {
  375. if (eth_poll()) { /* We have something! */
  376. - /* Check for ARP - No IP hdr */
  377. + /* Check for ARP - No IP hdr */
  378. if (nic.packetlen >= ETHER_HDR_SIZE) {
  379. ptype = ((unsigned short) nic.packet[12]) << 8
  380. | ((unsigned short) nic.packet[13]);
  381. } else continue; /* what else could we do with it? */
  382. if ((nic.packetlen >= ETHER_HDR_SIZE +
  383. - sizeof(struct arprequest)) &&
  384. - (ptype == ARP) ) {
  385. + sizeof(struct arprequest)) &&
  386. + (ptype == ARP) ) {
  387. unsigned long tmp;
  388. -
  389. +
  390. arpreply = (struct arprequest *)
  391. &nic.packet[ETHER_HDR_SIZE];
  392. if ((arpreply->opcode == ntohs(ARP_REPLY)) &&
  393. - !memcmp(arpreply->sipaddr, ptr, sizeof(in_addr)) &&
  394. - (type == AWAIT_ARP)) {
  395. + !memcmp(arpreply->sipaddr, ptr, sizeof(in_addr)) &&
  396. + (type == AWAIT_ARP)) {
  397. memcpy(arptable[ival].node, arpreply->shwaddr, ETHER_ADDR_SIZE);
  398. return(1);
  399. }
  400. memcpy(&tmp, arpreply->tipaddr, sizeof(in_addr));
  401. if ((arpreply->opcode == ntohs(ARP_REQUEST)) &&
  402. - (tmp == arptable[ARP_CLIENT].ipaddr.s_addr)) {
  403. + (tmp == arptable[ARP_CLIENT].ipaddr.s_addr)) {
  404. arpreply->opcode = htons(ARP_REPLY);
  405. memcpy(arpreply->tipaddr, arpreply->sipaddr, sizeof(in_addr));
  406. memcpy(arpreply->thwaddr, arpreply->shwaddr, ETHER_ADDR_SIZE);
  407. memcpy(arpreply->sipaddr, &arptable[ARP_CLIENT].ipaddr, sizeof(in_addr));
  408. memcpy(arpreply->shwaddr, arptable[ARP_CLIENT].node, ETHER_ADDR_SIZE);
  409. eth_transmit(arpreply->thwaddr, ARP,
  410. - sizeof(struct arprequest),
  411. - arpreply);
  412. + sizeof(struct arprequest),
  413. + arpreply);
  414. #ifdef MDEBUG
  415. memcpy(&tmp, arpreply->tipaddr, sizeof(in_addr));
  416. printf("Sent ARP reply to: %I\n",tmp);
  417. @@ -802,20 +906,20 @@ int await_reply(int type, int ival, void
  418. }
  419. continue;
  420. }
  421. -
  422. +
  423. if (type == AWAIT_QDRAIN) {
  424. continue;
  425. }
  426. -
  427. - /* Check for RARP - No IP hdr */
  428. +
  429. + /* Check for RARP - No IP hdr */
  430. if ((type == AWAIT_RARP) &&
  431. - (nic.packetlen >= ETHER_HDR_SIZE +
  432. - sizeof(struct arprequest)) &&
  433. - (ptype == RARP)) {
  434. + (nic.packetlen >= ETHER_HDR_SIZE +
  435. + sizeof(struct arprequest)) &&
  436. + (ptype == RARP)) {
  437. arpreply = (struct arprequest *)
  438. &nic.packet[ETHER_HDR_SIZE];
  439. if ((arpreply->opcode == ntohs(RARP_REPLY)) &&
  440. - !memcmp(arpreply->thwaddr, ptr, ETHER_ADDR_SIZE)) {
  441. + !memcmp(arpreply->thwaddr, ptr, ETHER_ADDR_SIZE)) {
  442. memcpy(arptable[ARP_SERVER].node, arpreply->shwaddr, ETHER_ADDR_SIZE);
  443. memcpy(& arptable[ARP_SERVER].ipaddr, arpreply->sipaddr, sizeof(in_addr));
  444. memcpy(& arptable[ARP_CLIENT].ipaddr, arpreply->tipaddr, sizeof(in_addr));
  445. @@ -823,64 +927,72 @@ int await_reply(int type, int ival, void
  446. }
  447. continue;
  448. }
  449. -
  450. - /* Anything else has IP header */
  451. +
  452. + /* Anything else has IP header */
  453. if ((nic.packetlen < protohdrlen) ||
  454. - (ptype != IP) ) continue;
  455. + (ptype != IP) ) continue;
  456. ip = (struct iphdr *)&nic.packet[ETHER_HDR_SIZE];
  457. if ((ip->verhdrlen != 0x45) ||
  458. - ipchksum((unsigned short *)ip, sizeof(struct iphdr)) ||
  459. - (ip->protocol != IP_UDP)) continue;
  460. + ipchksum((unsigned short *)ip, sizeof(struct iphdr)) ||
  461. + (ip->protocol != IP_UDP)) continue;
  462. udp = (struct udphdr *)&nic.packet[ETHER_HDR_SIZE +
  463. - sizeof(struct iphdr)];
  464. -
  465. - /* BOOTP ? */
  466. + sizeof(struct iphdr)];
  467. +
  468. + /* BOOTP ? */
  469. bootpreply = (struct bootp_t *)&nic.packet[ETHER_HDR_SIZE];
  470. - if ((type == AWAIT_BOOTP) &&
  471. - (nic.packetlen >= (ETHER_HDR_SIZE +
  472. -#ifdef NO_DHCP_SUPPORT
  473. - sizeof(struct bootp_t))) &&
  474. +#ifdef NO_DHCP_SUPPORT
  475. + min_packetlen = ETHER_HDR_SIZE + sizeof(struct bootp_t);
  476. #else
  477. - sizeof(struct bootp_t))-DHCP_OPT_LEN) &&
  478. -#endif /* NO_DHCP_SUPPORT */
  479. - (ntohs(udp->dest) == BOOTP_CLIENT) &&
  480. - (bootpreply->bp_op == BOOTP_REPLY) &&
  481. - (bootpreply->bp_xid == xid)) {
  482. - arptable[ARP_CLIENT].ipaddr.s_addr =
  483. - bootpreply->bp_yiaddr.s_addr;
  484. + min_packetlen = ETHER_HDR_SIZE + sizeof(struct bootp_t) - DHCP_OPT_LEN;
  485. +#endif
  486. + if (
  487. + (type == AWAIT_BOOTP) &&
  488. + (nic.packetlen >= min_packetlen) &&
  489. + (ntohs(udp->dest) == BOOTP_CLIENT) &&
  490. + (bootpreply->bp_op == BOOTP_REPLY) &&
  491. + (bootpreply->bp_xid == xid)
  492. + ) {
  493. + arptable[ARP_CLIENT].ipaddr.s_addr = bootpreply->bp_yiaddr.s_addr;
  494. #ifndef NO_DHCP_SUPPORT
  495. dhcp_addr.s_addr = bootpreply->bp_yiaddr.s_addr;
  496. #endif /* NO_DHCP_SUPPORT */
  497. netmask = default_netmask();
  498. - arptable[ARP_SERVER].ipaddr.s_addr =
  499. - bootpreply->bp_siaddr.s_addr;
  500. + arptable[ARP_SERVER].ipaddr.s_addr = bootpreply->bp_siaddr.s_addr;
  501. memset(arptable[ARP_SERVER].node, 0, ETHER_ADDR_SIZE); /* Kill arp */
  502. - arptable[ARP_GATEWAY].ipaddr.s_addr =
  503. - bootpreply->bp_giaddr.s_addr;
  504. + arptable[ARP_GATEWAY].ipaddr.s_addr = bootpreply->bp_giaddr.s_addr;
  505. memset(arptable[ARP_GATEWAY].node, 0, ETHER_ADDR_SIZE); /* Kill arp */
  506. if (bootpreply->bp_file[0]) {
  507. memcpy(kernel_buf, bootpreply->bp_file, 128);
  508. kernel = kernel_buf;
  509. }
  510. memcpy((char *)BOOTP_DATA_ADDR, (char *)bootpreply, sizeof(struct bootpd_t));
  511. - decode_rfc1533(BOOTP_DATA_ADDR->bootp_reply.bp_vend,
  512. -#ifdef NO_DHCP_SUPPORT
  513. - 0, BOOTP_VENDOR_LEN +
  514. - MAX_BOOTP_EXTLEN, 1);
  515. -#else
  516. - 0, DHCP_OPT_LEN, 1);
  517. -#endif /* NO_DHCP_SUPPORT */
  518. - return(1);
  519. +#ifdef NO_DHCP_SUPPORT
  520. + if (decode_rfc1533(BOOTP_DATA_ADDR->bootp_reply.bp_vend,
  521. + 0, BOOTP_VENDOR_LEN +
  522. + MAX_BOOTP_EXTLEN, 1)) {
  523. + return(1);
  524. + }
  525. + else {
  526. + continue;
  527. + }
  528. +#else
  529. + if (decode_rfc1533(BOOTP_DATA_ADDR->bootp_reply.bp_vend,
  530. + 0, DHCP_OPT_LEN, 1)) {
  531. + return(1);
  532. + }
  533. + else {
  534. + continue;
  535. + }
  536. }
  537. -
  538. +#endif /* NO_DHCP_SUPPORT */
  539. #ifdef DOWNLOAD_PROTO_TFTP
  540. - /* TFTP ? */
  541. + /* TFTP ? */
  542. if ((type == AWAIT_TFTP) &&
  543. - (ntohs(udp->dest) == ival)) return(1);
  544. + (ntohs(udp->dest) == ival)) return(1);
  545. #endif /* DOWNLOAD_PROTO_TFTP */
  546. -
  547. +
  548. #ifdef DOWNLOAD_PROTO_NFS
  549. - /* RPC ? */
  550. + /* RPC ? */
  551. rpc = (struct rpc_t *)&nic.packet[ETHER_HDR_SIZE];
  552. if ((type == AWAIT_RPC) &&
  553. (ntohs(udp->dest) == ival) &&
  554. @@ -889,19 +1001,19 @@ int await_reply(int type, int ival, void
  555. return (1);
  556. }
  557. #endif /* DOWNLOAD_PROTO_NFS */
  558. -
  559. +
  560. } else {
  561. - /* Check for abort key only if the Rx queue is empty -
  562. - * as long as we have something to process, don't
  563. - * assume that something failed. It is unlikely that
  564. - * we have no processing time left between packets. */
  565. + /* Check for abort key only if the Rx queue is empty -
  566. + * as long as we have something to process, don't
  567. + * assume that something failed. It is unlikely that
  568. + * we have no processing time left between packets. */
  569. if (iskey() && (getchar() == ESC))
  570. #ifdef EMERGENCYDISKBOOT
  571. exit(0);
  572. #else
  573. - longjmp(jmp_bootmenu,1);
  574. + longjmp(jmp_bootmenu,1);
  575. #endif
  576. - /* Do the timeout after at least a full queue walk. */
  577. + /* Do the timeout after at least a full queue walk. */
  578. if ((timeout == 0) || (currticks() > time)) {
  579. break;
  580. }
  581. @@ -914,13 +1026,15 @@ int await_reply(int type, int ival, void
  582. DECODE_RFC1533 - Decodes RFC1533 header
  583. **************************************************************************/
  584. int decode_rfc1533(p, block, len, eof)
  585. - register unsigned char *p;
  586. - int block, len, eof;
  587. + register unsigned char *p;
  588. + int block, len, eof;
  589. {
  590. static unsigned char *extdata = NULL, *extend = NULL;
  591. unsigned char *extpath = NULL;
  592. unsigned char *endp;
  593. -
  594. +#ifdef SERVER_IDENT
  595. + char rcvd_server_ident[9] = {};
  596. +#endif
  597. if (block == 0) {
  598. #ifdef IMAGE_MENU
  599. memset(imagelist, 0, sizeof(imagelist));
  600. @@ -1002,11 +1116,16 @@ int decode_rfc1533(p, block, len, eof)
  601. }
  602. #endif
  603. #ifdef MOTD
  604. - else if (c >= RFC1533_VENDOR_MOTD &&
  605. + else if (c >= RFC1533_VENDOR_MOTD &&
  606. c < RFC1533_VENDOR_MOTD +
  607. RFC1533_VENDOR_NUMOFMOTD)
  608. motd[c - RFC1533_VENDOR_MOTD] = p;
  609. #endif
  610. +#ifdef SERVER_IDENT
  611. + else if (c == RFC1533_VENDOR_SERVER_IDENT) {
  612. + memcpy(rcvd_server_ident,p+2,TAG_LEN(p));
  613. + }
  614. +#endif
  615. else {
  616. #if 0
  617. unsigned char *q;
  618. @@ -1018,6 +1137,30 @@ int decode_rfc1533(p, block, len, eof)
  619. }
  620. p += TAG_LEN(p) + 2;
  621. }
  622. +#if defined(SERVER_IDENT) && defined(DBG_IDENT)
  623. + if (strcasecmp(rcvd_server_ident,server_ident)) {
  624. + char ip[16];
  625. +
  626. + inet_ntoa(dhcp_server,ip);
  627. + printf("[%s]: Option %d (%s), invalid response. Wanted (%s).\n",
  628. + ip,
  629. + RFC1533_VENDOR_SERVER_IDENT,
  630. + rcvd_server_ident,
  631. + server_ident);
  632. + strcpy(rcvd_server_ident,"");
  633. + return(0);
  634. + }
  635. + else {
  636. + char ip[16];
  637. +
  638. + inet_ntoa(dhcp_server,ip);
  639. + printf("[%s]: Option %d (%s), valid response.\n",
  640. + ip,
  641. + RFC1533_VENDOR_SERVER_IDENT,
  642. + rcvd_server_ident);
  643. + strcpy(rcvd_server_ident,"");
  644. + }
  645. +#endif
  646. extdata = extend = endp;
  647. if (block == 0 && extpath != NULL) {
  648. char fname[64];
  649. @@ -1103,3 +1246,4 @@ void cleanup(void)
  650. * c-basic-offset: 8
  651. * End:
  652. */
  653. +
  654. --------------4734FDA0BF2F2FBDF8EB8DF6
  655. Content-Type: text/plain; charset=us-ascii;
  656. name="misc.c.diff"
  657. Content-Transfer-Encoding: 7bit
  658. Content-Disposition: inline;
  659. filename="misc.c.diff"
  660. --- etherboot-4.6.0/src/misc.c Tue Apr 25 08:30:25 2000
  661. +++ etherboot-4.5.6-new/src/misc.c Wed Apr 26 16:26:38 2000
  662. @@ -140,9 +140,11 @@ void printf(const char *fmt, ...)
  663. #ifdef IMAGE_MENU
  664. /**************************************************************************
  665. -INET_ATON - Convert an ascii x.x.x.x to binary form
  666. +INET_NTOA - Convert an ascii x.x.x.x to binary form
  667. **************************************************************************/
  668. -int inet_aton(char *p, in_addr *i)
  669. +int inet_aton(p, i)
  670. + char *p;
  671. + in_addr *i;
  672. {
  673. unsigned long ip = 0;
  674. int val;
  675. @@ -165,7 +167,19 @@ int inet_aton(char *p, in_addr *i)
  676. #endif /* IMAGE_MENU */
  677. -int getdec(char **ptr)
  678. +#if defined(CLIENT_IDENT) || defined (SERVER_IDENT)
  679. +/**************************************************************************
  680. +INET_NTOA - Convert a binary form to an ascii x.x.x.x form
  681. +**************************************************************************/
  682. +char *inet_ntoa(in_addr i, char *p)
  683. +{
  684. + sprintf(p,"%d.%d.%d.%d",i.s_addr>>24,i.s_addr<<8>>24,i.s_addr<<16>>24,i.s_addr<<24>>24);
  685. + return p;
  686. +}
  687. +#endif
  688. +
  689. +int getdec(ptr)
  690. + char **ptr;
  691. {
  692. char *p = *ptr;
  693. int ret=0;
  694. @@ -308,6 +322,45 @@ iskey(void)
  695. return 0;
  696. }
  697. #endif /* ETHERBOOT32 */
  698. +
  699. +/**************************************************************************
  700. +GETSTR - Read a string of size bytes from the keyboard
  701. +(without echoing the final return)
  702. +**************************************************************************/
  703. +void getstr(char *s, int size)
  704. +{
  705. + int i=0;
  706. + char c;
  707. +
  708. + while(1) {
  709. + c = getc();
  710. +
  711. +
  712. + if (c == 13)
  713. + {
  714. + s[i]='\0';
  715. + break;
  716. + }
  717. + else if (
  718. + ((c >= 'a') && (c <='z')) ||
  719. + ((c >= 'A') && (c <='Z')) ||
  720. + ((c >= '0') && (c <='9'))
  721. + ) {
  722. + if (i==8) {
  723. + putchar(8);
  724. + putchar(s[i-1]=c);
  725. + }
  726. + else
  727. + putchar(s[i++]=c);
  728. + }
  729. + else if ( c == 8 ) {
  730. + if (i != 0) {
  731. + --i;
  732. + s[i]='\0';
  733. + putchar(8);
  734. + putchar(32);
  735. + putchar(8);
  736. + }
  737. + }
  738. + }
  739. +}
  740. /*
  741. * Local variables:
  742. --------------4734FDA0BF2F2FBDF8EB8DF6
  743. Content-Type: text/plain; charset=us-ascii;
  744. name="Config.diff"
  745. Content-Transfer-Encoding: 7bit
  746. Content-Disposition: inline;
  747. filename="Config.diff"
  748. --- etherboot-4.6.0/src/Config Tue Apr 25 08:30:57 2000
  749. +++ etherboot-4.5.6-new/src/Config Wed Apr 26 15:55:57 2000
  750. @@ -59,6 +59,27 @@
  751. # may no longer be appropriate. You might need to set
  752. # MAX_ARP_RETRIES, MAX_BOOTP_RETRIES, MAX_TFTP_RETRIES
  753. # and MAX_RPC_RETRIES to a larger value.
  754. +# -DDEFAULT_CLIENT_IDENT
  755. +# The default client identifier that is sent to the
  756. +# DHCP server to identify itself.
  757. +# -DDEFAULT_SERVER_IDENT
  758. +# The expected response that the client will wait
  759. +# for when a DHCP server responds to the the initial
  760. +# client discovery.
  761. +# -DASK_CLIENT_IDENT
  762. +# -DASK_SERVER_IDENT
  763. +# If these are set, the boot process will include
  764. +# a question period where you can manualy specify
  765. +# the client and/or server identifiers.
  766. +# -DSHIFTED_IDENT_INPUT
  767. +# If this is set then the boot process will only
  768. +# ask for the identifiers if one of the shift keys
  769. +# is pressed. Else it will send the default identifiers
  770. +# automatically
  771. +# -DDBG_IDENT
  772. +# This will give show all the DHCP responses with
  773. +# their identifiers.
  774. +#
  775. #
  776. # Etherboot/32 only options:
  777. # -DAOUT_IMAGE - Add a.out kernel boot support (generic)
  778. @@ -147,6 +168,14 @@ CFLAGS32+= -DASK_BOOT=3 -DANS_DEFAULT=AN
  779. # Change download protocol to NFS. Only available for Etherboot/32 for now.
  780. # CFLAGS32+= -DDOWNLOAD_PROTO_NFS
  781. +
  782. +# If you have more than one DHCP server you might want to
  783. +# enable these to be able to sort out which one you want to
  784. +# respond to.
  785. +CFLAGS32+= -DDEFAULT_CLIENT_IDENT=\"BOOT\" -DDEFAULT_SERVER_IDENT=\"BOOT\"
  786. +CFLAGS32+= -DASK_CLIENT_IDENT -DASK_SERVER_IDENT
  787. +CFLAGS32+= -DSHIFTED_IDENT_INPUT
  788. +CFLAGS32+= -DDBG_IDENT
  789. # These flags affect the loader that is prepended to the Etherboot image
  790. LCONFIG+= -DMOVEROM
  791. --------------4734FDA0BF2F2FBDF8EB8DF6
  792. Content-Type: text/plain; charset=us-ascii;
  793. name="etherboot.h.diff"
  794. Content-Transfer-Encoding: 7bit
  795. Content-Disposition: inline;
  796. filename="etherboot.h.diff"
  797. --- etherboot-4.6.0/src/etherboot.h Tue Apr 25 08:30:55 2000
  798. +++ etherboot-4.5.6-new/src/etherboot.h Wed Apr 26 16:07:16 2000
  799. @@ -8,6 +8,14 @@ Author: Martin Renters
  800. #include "osdep.h"
  801. +#if (! defined(NO_DHCP_SUPPORT)) && (defined(ASK_CLIENT_IDENT) || defined(DEFAULT_CLIENT_IDENT))
  802. +# define CLIENT_IDENT
  803. +#endif
  804. +
  805. +#if (! defined(NO_DHCP_SUPPORT)) && (defined(ASK_SERVER_IDENT) || defined(DEFAULT_SERVER_IDENT))
  806. +# define SERVER_IDENT
  807. +#endif
  808. +
  809. /* These could be customised for different languages perhaps */
  810. #define ASK_PROMPT "Boot from (N)etwork or from (L)ocal? "
  811. #define ANS_NETWORK 'N'
  812. @@ -224,6 +232,12 @@ Author: Martin Renters
  813. #ifdef IMAGE_FREEBSD
  814. #define RFC1533_VENDOR_HOWTO 132
  815. #endif
  816. +#ifdef CLIENT_IDENT
  817. +#define RFC1533_VENDOR_CLIENT_IDENT 208
  818. +#endif
  819. +#ifdef SERVER_IDENT
  820. +#define RFC1533_VENDOR_SERVER_IDENT 208
  821. +#endif
  822. #define RFC1533_VENDOR_MNUOPTS 160
  823. #define RFC1533_VENDOR_SELECTION 176
  824. #define RFC1533_VENDOR_MOTD 184
  825. @@ -477,11 +491,13 @@ extern int getdec P((char **));
  826. extern void printf P((const char *, ...));
  827. extern char *sprintf P((char *, const char *, ...));
  828. extern int inet_aton P((char *p, in_addr *i));
  829. +extern char *inet_ntoa P((in_addr i, char *p));
  830. extern void gateA20_set P((void));
  831. extern void gateA20_unset P((void));
  832. extern void putchar P((int));
  833. extern int getchar P((void));
  834. extern int iskey P((void));
  835. +extern void getstr P((char *s, int size));
  836. /* start*.S */
  837. extern int getc P((void));
  838. @@ -528,8 +544,10 @@ extern int hostnamelen;
  839. extern unsigned long netmask;
  840. extern int jmp_bootmenu[10];
  841. extern struct arptable_t arptable[MAX_ARP];
  842. -#ifdef IMAGE_MENU
  843. +#ifdef MOTD
  844. extern char *motd[RFC1533_VENDOR_NUMOFMOTD];
  845. +#endif
  846. +#ifdef IMAGE_MENU
  847. extern int menutmo,menudefault;
  848. extern unsigned char *defparams;
  849. extern int defparams_max;
  850. --------------4734FDA0BF2F2FBDF8EB8DF6--