diff options
author | 2017-07-07 14:53:06 +0000 | |
---|---|---|
committer | 2017-07-07 14:53:06 +0000 | |
commit | b414edd1ccbe5a071c29c03619d6475dd89a492e (patch) | |
tree | f0936691e2bdd1a947e8d26a36bb0847d06fce4f | |
parent | Add logic for running SD commands. Tested with a few different makes (diff) | |
download | wireguard-openbsd-b414edd1ccbe5a071c29c03619d6475dd89a492e.tar.xz wireguard-openbsd-b414edd1ccbe5a071c29c03619d6475dd89a492e.zip |
Rename cons_options() to pack_options(), and do_packet() to
unpack_options(). Store the unpacked options in a static
variable. Move remaining raw packet processing from unpack_options()
to packethandler().
No more struct interface_info knowledge in options.c
-rw-r--r-- | sbin/dhclient/dhclient.c | 8 | ||||
-rw-r--r-- | sbin/dhclient/dhcpd.h | 7 | ||||
-rw-r--r-- | sbin/dhclient/dispatch.c | 71 | ||||
-rw-r--r-- | sbin/dhclient/options.c | 104 |
4 files changed, 96 insertions, 94 deletions
diff --git a/sbin/dhclient/dhclient.c b/sbin/dhclient/dhclient.c index ccbbe58425d..94659f6aa21 100644 --- a/sbin/dhclient/dhclient.c +++ b/sbin/dhclient/dhclient.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dhclient.c,v 1.456 2017/07/06 16:56:52 krw Exp $ */ +/* $OpenBSD: dhclient.c,v 1.457 2017/07/07 14:53:06 krw Exp $ */ /* * Copyright 2004 Henning Brauer <henning@openbsd.org> @@ -1560,7 +1560,7 @@ make_discover(struct interface_info *ifi, struct client_lease *lease) * 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, + i = pack_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."); @@ -1636,7 +1636,7 @@ make_request(struct interface_info *ifi, struct client_lease * lease) * 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, + i = pack_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."); @@ -1709,7 +1709,7 @@ make_decline(struct interface_info *ifi, struct client_lease *lease) * 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, + i = pack_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."); diff --git a/sbin/dhclient/dhcpd.h b/sbin/dhclient/dhcpd.h index 9ea01048b1e..5b3e7f7caa6 100644 --- a/sbin/dhclient/dhcpd.h +++ b/sbin/dhclient/dhcpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dhcpd.h,v 1.204 2017/07/06 16:56:52 krw Exp $ */ +/* $OpenBSD: dhcpd.h,v 1.205 2017/07/07 14:53:06 krw Exp $ */ /* * Copyright (c) 2004 Henning Brauer <henning@openbsd.org> @@ -170,13 +170,12 @@ extern struct in_addr deleting; extern struct in_addr adding; /* options.c */ -int cons_options(unsigned char *, int, struct option_data *); +int pack_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); char *pretty_print_classless_routes(unsigned char *, size_t); -void do_packet(struct interface_info *, unsigned int, struct in_addr, - struct ether_addr *); +struct option_data *unpack_options(struct dhcp_packet *); /* conflex.c */ extern int lexline, lexchar; diff --git a/sbin/dhclient/dispatch.c b/sbin/dhclient/dispatch.c index a9d4fc8aba0..b3afeff1e7c 100644 --- a/sbin/dhclient/dispatch.c +++ b/sbin/dhclient/dispatch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dispatch.c,v 1.131 2017/07/06 16:56:52 krw Exp $ */ +/* $OpenBSD: dispatch.c,v 1.132 2017/07/07 14:53:07 krw Exp $ */ /* * Copyright 2004 Henning Brauer <henning@openbsd.org> @@ -205,7 +205,12 @@ packethandler(struct interface_info *ifi) struct in_addr ifrom; struct dhcp_packet *packet = &ifi->recv_packet; struct reject_elem *ap; + struct option_data *options; + char *type, *info; ssize_t result; + void (*handler)(struct interface_info *, + struct option_data *, char *); + int i, rslt; if ((result = receive_packet(ifi, &from, &hfrom)) == -1) { ifi->errors++; @@ -256,7 +261,69 @@ packethandler(struct interface_info *ifi) return; } - do_packet(ifi, from.sin_port, ifrom, &hfrom); + options = unpack_options(&ifi->recv_packet); + + /* + * RFC 6842 says if the server sends a client identifier + * that doesn't match then the packet must be dropped. + */ + i = DHO_DHCP_CLIENT_IDENTIFIER; + if ((options[i].len != 0) && + ((options[i].len != config->send_options[i].len) || + memcmp(options[i].data, config->send_options[i].data, + options[i].len) != 0)) { +#ifdef DEBUG + log_debug("Discarding packet with client-identifier " + "'%s'", pretty_print_option(i, &options[i], 0)); +#endif /* DEBUG */ + return; + } + + type = "<unknown>"; + handler = NULL; + + i = DHO_DHCP_MESSAGE_TYPE; + if (options[i].data != NULL) { + /* Always try a DHCP packet, even if a bad option was seen. */ + switch (options[i].data[0]) { + case DHCPOFFER: + handler = dhcpoffer; + type = "DHCPOFFER"; + break; + case DHCPNAK: + handler = dhcpnak; + type = "DHCPNACK"; + break; + case DHCPACK: + handler = dhcpack; + type = "DHCPACK"; + break; + default: +#ifdef DEBUG + log_debug("Discarding DHCP packet of unknown type " + "(%d)", options[i].data[0]); +#endif /* DEBUG */ + return; + } + } else if (packet->op == BOOTREPLY) { + handler = dhcpoffer; + type = "BOOTREPLY"; + } else { +#ifdef DEBUG + log_debug("Discarding packet which is neither DHCP nor BOOTP"); +#endif /* DEBUG */ + return; + } + + rslt = asprintf(&info, "%s from %s (%s)", type, inet_ntoa(ifrom), + ether_ntoa(&hfrom)); + if (rslt == -1) + fatalx("no memory for info string"); + + if (handler) + (*handler)(ifi, options, info); + + free(info); } void diff --git a/sbin/dhclient/options.c b/sbin/dhclient/options.c index 017940af84a..aa07efcee41 100644 --- a/sbin/dhclient/options.c +++ b/sbin/dhclient/options.c @@ -1,4 +1,4 @@ -/* $OpenBSD: options.c,v 1.93 2017/07/06 16:56:52 krw Exp $ */ +/* $OpenBSD: options.c,v 1.94 2017/07/07 14:53:07 krw Exp $ */ /* DHCP options parsing and reassembly. */ @@ -155,12 +155,12 @@ parse_option_buffer(struct option_data *options, unsigned char *buffer, } /* - * Copy as many options as fit in buflen bytes of buf. Return the + * Pack as many options as fit in buflen bytes of buf. Return the * offset of the start of the last option copied. A caller can check * to see if it's DHO_END to decide if all the options were copied. */ int -cons_options(unsigned char *buf, int buflen, struct option_data *options) +pack_options(unsigned char *buf, int buflen, struct option_data *options) { int ix, incr, length, bufix, code, lastopt = -1; @@ -627,100 +627,36 @@ toobig: return (optbuf); } -void -do_packet(struct interface_info *ifi, unsigned int from_port, - struct in_addr from, struct ether_addr *hfrom) +struct option_data * +unpack_options(struct dhcp_packet *packet) { - struct dhcp_packet *packet = &ifi->recv_packet; - struct option_data options[256]; - void (*handler)(struct interface_info *, struct option_data *, char *); - char *type, *info; - int i, rslt, options_valid = 1; + static struct option_data options[256]; + int i; - memset(options, 0, sizeof(options)); + for (i = 0; i < 256; i++) { + free(options[i].data); + options[i].data = NULL; + options[i].len = 0; + } if (memcmp(&packet->options, DHCP_OPTIONS_COOKIE, 4) == 0) { /* Parse the BOOTP/DHCP options field. */ - options_valid = parse_option_buffer(options, - &packet->options[4], sizeof(packet->options) - 4); + parse_option_buffer(options, &packet->options[4], + sizeof(packet->options) - 4); - /* Only DHCP packets have overload areas for options. */ - if (options_valid && - options[DHO_DHCP_MESSAGE_TYPE].data && + /* DHCP packets can also use overload areas for options. */ + if (options[DHO_DHCP_MESSAGE_TYPE].data && options[DHO_DHCP_OPTION_OVERLOAD].data) { if (options[DHO_DHCP_OPTION_OVERLOAD].data[0] & 1) - options_valid = parse_option_buffer(options, + parse_option_buffer(options, (unsigned char *)packet->file, sizeof(packet->file)); - if (options_valid && - options[DHO_DHCP_OPTION_OVERLOAD].data[0] & 2) - options_valid = parse_option_buffer(options, + if (options[DHO_DHCP_OPTION_OVERLOAD].data[0] & 2) + parse_option_buffer(options, (unsigned char *)packet->sname, sizeof(packet->sname)); } - - /* - * RFC 6842 says if the server sends a client identifier - * that doesn't match then the packet must be dropped. - */ - i = DHO_DHCP_CLIENT_IDENTIFIER; - if ((options[i].len != 0) && - ((options[i].len != config->send_options[i].len) || - memcmp(options[i].data, config->send_options[i].data, - options[i].len) != 0)) { -#ifdef DEBUG - log_debug("Discarding packet with client-identifier " - "'%s'", pretty_print_option(i, &options[i], 0)); -#endif /* DEBUG */ - goto done; - } - } - - type = "<unknown>"; - handler = NULL; - - if (options[DHO_DHCP_MESSAGE_TYPE].data) { - /* Always try a DHCP packet, even if a bad option was seen. */ - switch (options[DHO_DHCP_MESSAGE_TYPE].data[0]) { - case DHCPOFFER: - handler = dhcpoffer; - type = "DHCPOFFER"; - break; - case DHCPNAK: - handler = dhcpnak; - type = "DHCPNACK"; - break; - case DHCPACK: - handler = dhcpack; - type = "DHCPACK"; - break; - default: -#ifdef DEBUG - log_debug("Discarding DHCP packet of unknown type " - "(%d)", options[DHO_DHCP_MESSAGE_TYPE].data[0]); -#endif /* DEBUG */ - break; - } - } else if (options_valid && packet->op == BOOTREPLY) { - handler = dhcpoffer; - type = "BOOTREPLY"; - } else { -#ifdef DEBUG - log_debug("Discarding packet which is neither DHCP nor BOOTP"); -#endif /* DEBUG */ } - rslt = asprintf(&info, "%s from %s (%s)", type, inet_ntoa(from), - ether_ntoa(hfrom)); - if (rslt == -1) - fatalx("no memory for info string"); - - if (handler) - (*handler)(ifi, options, info); - - free(info); - -done: - for (i = 0; i < 256; i++) - free(options[i].data); + return options; } |