dhclient - Sequential options processing more friendly.
authorAntonio Huete Jimenez <tuxillo@quantumachine.net>
Sat, 4 Aug 2012 18:23:47 +0000 (20:23 +0200)
committerAntonio Huete Jimenez <tuxillo@quantumachine.net>
Sun, 19 Aug 2012 14:30:47 +0000 (16:30 +0200)
- Starting DHCP packet options with DHO_DHCP_MESSAGE_TYPE. Now
  DHCP-specific options always come after the option identifying
  the packet as DHCP rather than BOOTP. Makes at least Nortel NetIP
  DHCP server happier. Clean up some code and parameter passing.

Taken-from: OpenBSD

sbin/dhclient/dhclient.c
sbin/dhclient/dhcp.h
sbin/dhclient/dhcpd.h
sbin/dhclient/options.c

index 7688efb..2f5b3ca 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: src/sbin/dhclient/dhclient.c,v 1.140 2011/04/17 20:06:08 phessler Exp $       */
+/*     $OpenBSD: src/sbin/dhclient/dhclient.c,v 1.141 2011/05/11 14:38:36 krw Exp $    */
 
 /*
  * Copyright 2004 Henning Brauer <henning@openbsd.org>
@@ -1185,8 +1185,7 @@ make_discover(struct client_lease *lease)
                }
 
        /* Set up the option buffer to fit in a minimal UDP packet. */
-       i = cons_options(client->packet.options, 576 - DHCP_FIXED_LEN,
-           options);
+       i = cons_options(options);
        if (i == -1 || client->packet.options[i] != DHO_END)
                error("options do not fit in DHCPDISCOVER packet.");
        client->packet_length = DHCP_FIXED_NON_UDP+i+1;
@@ -1254,8 +1253,7 @@ make_request(struct client_lease * lease)
                }
 
        /* Set up the option buffer to fit in a minimal UDP packet. */
-       i = cons_options(client->packet.options, 576 - DHCP_FIXED_LEN,
-           options);
+       i = cons_options(options);
        if (i == -1 || client->packet.options[i] != DHO_END)
                error("options do not fit in DHCPREQUEST packet.");
        client->packet_length = DHCP_FIXED_NON_UDP+i+1;
@@ -1322,8 +1320,7 @@ make_decline(struct client_lease *lease)
        }
 
        /* Set up the option buffer to fit in a minimal UDP packet. */
-       i = cons_options(client->packet.options, 576 - DHCP_FIXED_LEN,
-           options);
+       i = cons_options(options);
        if (i == -1 || client->packet.options[i] != DHO_END)
                error("options do not fit in DHCPDECLINE packet.");
        client->packet_length = DHCP_FIXED_NON_UDP+i+1;
index 02ff9f6..fa6f53f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: src/sbin/dhclient/dhcp.h,v 1.8 2010/10/15 09:51:15 jsg Exp $  */
+/*     $OpenBSD: src/sbin/dhclient/dhcp.h,v 1.9 2011/05/11 14:38:36 krw Exp $  */
 
 /* Protocol structures... */
 
@@ -86,7 +86,8 @@ struct dhcp_packet {
 
 /* Magic cookie validating dhcp options field (and bootp vendor
    extensions field). */
-#define DHCP_OPTIONS_COOKIE    "\143\202\123\143"
+#define DHCP_OPTIONS_COOKIE            "\143\202\123\143"
+#define DHCP_OPTIONS_MESSAGE_TYPE      "\065\001\000"
 
 /* DHCP Option codes: */
 
index 7d0d47b..75f4332 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: src/sbin/dhclient/dhcpd.h,v 1.72 2011/04/04 11:14:52 krw Exp $        */
+/*     $OpenBSD: src/sbin/dhclient/dhcpd.h,v 1.73 2011/05/11 14:38:36 krw Exp $        */
 
 /*
  * Copyright (c) 2004 Henning Brauer <henning@openbsd.org>
@@ -205,7 +205,7 @@ extern struct client_state *client;
 extern struct client_config *config;
 
 /* options.c */
-int cons_options(unsigned char *, const int, struct option_data *);
+int cons_options(struct option_data *);
 char *pretty_print_option(unsigned int, unsigned char *, int, int, int);
 void do_packet(int, unsigned int, struct iaddr, struct hardware *);
 
index 14a9858..3db0db2 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: src/sbin/dhclient/options.c,v 1.38 2011/04/17 19:57:23 phessler Exp $ */
+/*     $OpenBSD: src/sbin/dhclient/options.c,v 1.39 2011/05/11 14:38:36 krw Exp $      */
 
 /* DHCP options parsing and reassembly. */
 
@@ -131,18 +131,24 @@ parse_option_buffer(struct option_data *options, unsigned char *buffer,
  * to see if it's DHO_END to decide if all the options were copied.
  */
 int
-cons_options(unsigned char *buf, const int buflen, struct option_data *options)
+cons_options(struct option_data *options)
 {
+       unsigned char *buf = client->packet.options;
+       int buflen = 576 - DHCP_FIXED_LEN;
        int ix, incr, length, bufix, code, lastopt = -1;
 
        bzero(buf, buflen);
 
-       if (buflen > 3)
-               memcpy(buf, DHCP_OPTIONS_COOKIE, 4);
-       bufix = 4;
+       memcpy(buf, DHCP_OPTIONS_COOKIE, 4);
+       if (options[DHO_DHCP_MESSAGE_TYPE].data) {
+               memcpy(&buf[4], DHCP_OPTIONS_MESSAGE_TYPE, 3);
+               buf[6] = options[DHO_DHCP_MESSAGE_TYPE].data[0];
+               bufix = 7;
+       } else
+               bufix = 4;
 
        for (code = DHO_SUBNET_MASK; code < DHO_END; code++) {
-               if (!options[code].data)
+               if (!options[code].data || code == DHO_DHCP_MESSAGE_TYPE)
                        continue;
 
                length = options[code].len;