cons_options() only needs to know a buffer and a length to
authorkrw <krw@openbsd.org>
Thu, 6 Jul 2017 16:56:52 +0000 (16:56 +0000)
committerkrw <krw@openbsd.org>
Thu, 6 Jul 2017 16:56:52 +0000 (16:56 +0000)
pack options into. Not all the gory details of interface_info.

Move some of the raw packet processing out of options.c's
do_packet() and into the more obvious dispatch.c's
packethandler().

Mention that RFC791 is why we use 576-byte UDP packets.

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

index 49d0e4d..ccbbe58 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dhclient.c,v 1.455 2017/07/05 16:17:42 krw Exp $      */
+/*     $OpenBSD: dhclient.c,v 1.456 2017/07/06 16:56:52 krw Exp $      */
 
 /*
  * Copyright 2004 Henning Brauer <henning@openbsd.org>
@@ -1520,10 +1520,10 @@ send_decline(struct interface_info *ifi)
 void
 make_discover(struct interface_info *ifi, struct client_lease *lease)
 {
-       struct option_data options[256];
-       struct dhcp_packet *packet = &ifi->sent_packet;
-       unsigned char discover = DHCPDISCOVER;
-       int i;
+       struct option_data       options[256];
+       struct dhcp_packet      *packet = &ifi->sent_packet;
+       unsigned char            discover = DHCPDISCOVER;
+       int                      i;
 
        memset(options, 0, sizeof(options));
        memset(packet, 0, sizeof(*packet));
@@ -1555,8 +1555,13 @@ make_discover(struct interface_info *ifi, struct client_lease *lease)
                        options[i].len = config->send_options[i].len;
                }
 
-       /* Set up the option buffer to fit in a minimal UDP packet. */
-       i = cons_options(ifi, options);
+       /*
+        * Set up the option buffer to fit in a 576-byte UDP packet, which
+        * RFC 791 says is the largest packet that *MUST* be accepted
+        * by any host.
+        */
+       i = cons_options(ifi->sent_packet.options, 576 - DHCP_FIXED_LEN,
+           options);
        if (i == -1 || packet->options[i] != DHO_END)
                fatalx("options do not fit in DHCPDISCOVER packet.");
        ifi->sent_packet_length = DHCP_FIXED_NON_UDP+i+1;
@@ -1583,10 +1588,10 @@ make_discover(struct interface_info *ifi, struct client_lease *lease)
 void
 make_request(struct interface_info *ifi, struct client_lease * lease)
 {
-       struct option_data options[256];
-       struct dhcp_packet *packet = &ifi->sent_packet;
-       unsigned char request = DHCPREQUEST;
-       int i;
+       struct option_data       options[256];
+       struct dhcp_packet      *packet = &ifi->sent_packet;
+       unsigned char            request = DHCPREQUEST;
+       int                      i;
 
        memset(options, 0, sizeof(options));
        memset(packet, 0, sizeof(*packet));
@@ -1626,8 +1631,13 @@ make_request(struct interface_info *ifi, struct client_lease * lease)
                        options[i].len = config->send_options[i].len;
                }
 
-       /* Set up the option buffer to fit in a minimal UDP packet. */
-       i = cons_options(ifi, options);
+       /*
+        * Set up the option buffer to fit in a 576-byte UDP packet, which
+        * RFC 791 says is the largest packet that *MUST* be accepted
+        * by any host.
+        */
+       i = cons_options(ifi->sent_packet.options, 576 - DHCP_FIXED_LEN,
+           options);
        if (i == -1 || packet->options[i] != DHO_END)
                fatalx("options do not fit in DHCPREQUEST packet.");
        ifi->sent_packet_length = DHCP_FIXED_NON_UDP+i+1;
@@ -1664,10 +1674,10 @@ make_request(struct interface_info *ifi, struct client_lease * lease)
 void
 make_decline(struct interface_info *ifi, struct client_lease *lease)
 {
-       struct option_data options[256];
-       struct dhcp_packet *packet = &ifi->sent_packet;
-       unsigned char decline = DHCPDECLINE;
-       int i;
+       struct option_data       options[256];
+       struct dhcp_packet      *packet = &ifi->sent_packet;
+       unsigned char            decline = DHCPDECLINE;
+       int                      i;
 
        memset(options, 0, sizeof(options));
        memset(packet, 0, sizeof(*packet));
@@ -1694,8 +1704,13 @@ make_decline(struct interface_info *ifi, struct client_lease *lease)
                options[i].len = config->send_options[i].len;
        }
 
-       /* Set up the option buffer to fit in a minimal UDP packet. */
-       i = cons_options(ifi, options);
+       /*
+        * Set up the option buffer to fit in a 576-byte UDP packet, which
+        * RFC 791 says is the largest packet that *MUST* be accepted
+        * by any host.
+        */
+       i = cons_options(ifi->sent_packet.options, 576 - DHCP_FIXED_LEN,
+           options);
        if (i == -1 || packet->options[i] != DHO_END)
                fatalx("options do not fit in DHCPDECLINE packet.");
        ifi->sent_packet_length = DHCP_FIXED_NON_UDP+i+1;
index 1003ddc..9ea0104 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dhcpd.h,v 1.203 2017/07/05 16:17:42 krw Exp $ */
+/*     $OpenBSD: dhcpd.h,v 1.204 2017/07/06 16:56:52 krw Exp $ */
 
 /*
  * Copyright (c) 2004 Henning Brauer <henning@openbsd.org>
@@ -170,7 +170,7 @@ extern struct in_addr deleting;
 extern struct in_addr adding;
 
 /* options.c */
-int cons_options(struct interface_info *, struct option_data *);
+int cons_options(unsigned char *, int, struct option_data *);
 char *pretty_print_option(unsigned int, struct option_data *, int);
 char *pretty_print_domain_search(unsigned char *, size_t);
 char *pretty_print_string(unsigned char *, size_t, int);
index 325f6b6..a9d4fc8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dispatch.c,v 1.130 2017/07/01 23:27:56 krw Exp $      */
+/*     $OpenBSD: dispatch.c,v 1.131 2017/07/06 16:56:52 krw Exp $      */
 
 /*
  * Copyright 2004 Henning Brauer <henning@openbsd.org>
@@ -53,6 +53,8 @@
 #include <netinet/in.h>
 #include <netinet/if_ether.h>
 
+#include <arpa/inet.h>
+
 #include <errno.h>
 #include <ifaddrs.h>
 #include <imsg.h>
@@ -198,10 +200,12 @@ dispatch(struct interface_info *ifi, int routefd)
 void
 packethandler(struct interface_info *ifi)
 {
-       struct sockaddr_in from;
-       struct ether_addr hfrom;
-       struct in_addr ifrom;
-       ssize_t result;
+       struct sockaddr_in       from;
+       struct ether_addr        hfrom;
+       struct in_addr           ifrom;
+       struct dhcp_packet      *packet = &ifi->recv_packet;
+       struct reject_elem      *ap;
+       ssize_t                  result;
 
        if ((result = receive_packet(ifi, &from, &hfrom)) == -1) {
                ifi->errors++;
@@ -219,6 +223,39 @@ packethandler(struct interface_info *ifi)
 
        ifrom.s_addr = from.sin_addr.s_addr;
 
+       if (packet->hlen != ETHER_ADDR_LEN) {
+#ifdef DEBUG
+               log_debug("Discarding packet with hlen != %s (%u)",
+                   ifi->name, packet->hlen);
+#endif /* DEBUG */
+               return;
+       } else if (memcmp(&ifi->hw_address, packet->chaddr,
+           sizeof(ifi->hw_address))) {
+#ifdef DEBUG
+               log_debug("Discarding packet with chaddr != %s (%s)",
+                   ifi->name,
+                   ether_ntoa((struct ether_addr *)packet->chaddr));
+#endif /* DEBUG */
+               return;
+       }
+
+       if (ifi->xid != packet->xid) {
+#ifdef DEBUG
+               log_debug("Discarding packet with XID != %u (%u)", ifi->xid,
+                   packet->xid);
+#endif /* DEBUG */
+               return;
+       }
+
+       TAILQ_FOREACH(ap, &config->reject_list, next)
+           if (ifrom.s_addr == ap->addr.s_addr) {
+#ifdef DEBUG
+                   log_debug("Discarding packet from address on reject "
+                       "list (%s)", inet_ntoa(ifrom));
+#endif /* DEBUG */
+                   return;
+           }
+
        do_packet(ifi, from.sin_port, ifrom, &hfrom);
 }
 
index 612632f..017940a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: options.c,v 1.92 2017/06/15 17:06:17 krw Exp $        */
+/*     $OpenBSD: options.c,v 1.93 2017/07/06 16:56:52 krw Exp $        */
 
 /* DHCP options parsing and reassembly. */
 
@@ -160,10 +160,8 @@ 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(struct interface_info *ifi, struct option_data *options)
+cons_options(unsigned char *buf, int buflen, struct option_data *options)
 {
-       unsigned char *buf = ifi->sent_packet.options;
-       int buflen = 576 - DHCP_FIXED_LEN;
        int ix, incr, length, bufix, code, lastopt = -1;
 
        memset(buf, 0, buflen);
@@ -635,44 +633,10 @@ do_packet(struct interface_info *ifi, unsigned int from_port,
 {
        struct dhcp_packet *packet = &ifi->recv_packet;
        struct option_data options[256];
-       struct reject_elem *ap;
        void (*handler)(struct interface_info *, struct option_data *, char *);
        char *type, *info;
        int i, rslt, options_valid = 1;
 
-       if (packet->hlen != ETHER_ADDR_LEN) {
-#ifdef DEBUG
-               log_debug("Discarding packet with hlen != %s (%u)",
-                   ifi->name, packet->hlen);
-#endif /* DEBUG */
-               return;
-       } else if (memcmp(&ifi->hw_address, packet->chaddr,
-           sizeof(ifi->hw_address))) {
-#ifdef DEBUG
-               log_debug("Discarding packet with chaddr != %s (%s)",
-                   ifi->name,
-                   ether_ntoa((struct ether_addr *)packet->chaddr));
-#endif /* DEBUG */
-               return;
-       }
-
-       if (ifi->xid != packet->xid) {
-#ifdef DEBUG
-               log_debug("Discarding packet with XID != %u (%u)", ifi->xid,
-                   packet->xid);
-#endif /* DEBUG */
-               return;
-       }
-
-       TAILQ_FOREACH(ap, &config->reject_list, next)
-               if (from.s_addr == ap->addr.s_addr) {
-#ifdef DEBUG
-                       log_debug("Discarding packet from address on reject "
-                           "list (%s)", inet_ntoa(from));
-#endif /* DEBUG */
-                       return;
-               }
-
        memset(options, 0, sizeof(options));
 
        if (memcmp(&packet->options, DHCP_OPTIONS_COOKIE, 4) == 0) {