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