summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenneth R Westerback <krw@cvs.openbsd.org>2017-07-08 20:38:32 +0000
committerKenneth R Westerback <krw@cvs.openbsd.org>2017-07-08 20:38:32 +0000
commit72a91e0b11c9b9de0605480e11861c820402bc7a (patch)
tree9b6181e981f1fd8a1ba6638dbddc7ffa47d94da0
parent7ff62f27543d48fe91cd7c046e342fd39149d32a (diff)
Fold tables.c into options.c and stop exporting the one
table (dhcp_options) involved. Provide functions code_to_name(), name_to_code(), code_to_format() and replace direct access to dhcp_options with them. Eliminate unneeded 'struct option'. Unhook tables.c from Makefile.
-rw-r--r--sbin/dhclient/Makefile4
-rw-r--r--sbin/dhclient/clparse.c16
-rw-r--r--sbin/dhclient/dhclient.c31
-rw-r--r--sbin/dhclient/dhcpd.h13
-rw-r--r--sbin/dhclient/options.c388
5 files changed, 387 insertions, 65 deletions
diff --git a/sbin/dhclient/Makefile b/sbin/dhclient/Makefile
index 685425f0473..b0113857654 100644
--- a/sbin/dhclient/Makefile
+++ b/sbin/dhclient/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.19 2017/04/09 20:44:13 krw Exp $
+# $OpenBSD: Makefile,v 1.20 2017/07/08 20:38:31 krw Exp $
#
# Copyright (c) 1996, 1997 The Internet Software Consortium.
# All rights reserved.
@@ -33,7 +33,7 @@
.include <bsd.own.mk>
SRCS= dhclient.c clparse.c dispatch.c bpf.c options.c \
- conflex.c log.c packet.c tables.c \
+ conflex.c log.c packet.c \
parse.c privsep.c kroute.c
PROG= dhclient
diff --git a/sbin/dhclient/clparse.c b/sbin/dhclient/clparse.c
index 1cb8246ebd8..afe5db7b61e 100644
--- a/sbin/dhclient/clparse.c
+++ b/sbin/dhclient/clparse.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: clparse.c,v 1.118 2017/07/08 15:26:27 krw Exp $ */
+/* $OpenBSD: clparse.c,v 1.119 2017/07/08 20:38:31 krw Exp $ */
/* Parser for dhclient config and lease files. */
@@ -409,10 +409,8 @@ parse_option_list(FILE *cfile, uint8_t *list, size_t sz)
* lists. They are not really options and it makes no sense
* to request, require or ignore them.
*/
- for (i = 1; i < DHO_END; i++)
- if (!strcasecmp(dhcp_options[i].name, val))
- break;
+ i = name_to_code(val);
if (i == DHO_END) {
parse_warn("expecting option name.");
goto syntaxerror;
@@ -637,12 +635,8 @@ parse_option_decl(FILE *cfile, struct option_data *options)
}
/* Look up the actual option info. */
- fmt = NULL;
- for (code = 0; code < DHO_COUNT; code++)
- if (strcasecmp(dhcp_options[code].name, val) == 0)
- break;
-
- if (code > 255) {
+ code = name_to_code(val);
+ if (code == DHO_END) {
parse_warn("unknown option name.");
skip_to_semi(cfile);
return (-1);
@@ -650,7 +644,7 @@ parse_option_decl(FILE *cfile, struct option_data *options)
/* Parse the option data. */
do {
- for (fmt = dhcp_options[code].format; *fmt; fmt++) {
+ for (fmt = code_to_format(code); *fmt; fmt++) {
if (*fmt == 'A')
break;
switch (*fmt) {
diff --git a/sbin/dhclient/dhclient.c b/sbin/dhclient/dhclient.c
index 84e5007ea77..579be485671 100644
--- a/sbin/dhclient/dhclient.c
+++ b/sbin/dhclient/dhclient.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dhclient.c,v 1.460 2017/07/08 00:36:10 krw Exp $ */
+/* $OpenBSD: dhclient.c,v 1.461 2017/07/08 20:38:31 krw Exp $ */
/*
* Copyright 2004 Henning Brauer <henning@openbsd.org>
@@ -1187,7 +1187,7 @@ packet_to_lease(struct interface_info *ifi, struct option_data *options)
struct dhcp_packet *packet = &ifi->recv_packet;
char ifname[IF_NAMESIZE];
struct client_lease *lease;
- char *pretty, *buf;
+ char *pretty, *buf, *name;
int i;
lease = calloc(1, sizeof(struct client_lease));
@@ -1200,8 +1200,8 @@ packet_to_lease(struct interface_info *ifi, struct option_data *options)
for (i = 0; i < DHO_COUNT; i++) {
if (options[i].len == 0)
continue;
- if (!unknown_ok && strncmp("option-",
- dhcp_options[i].name, 7) != 0) {
+ name = code_to_name(i);
+ if (!unknown_ok && strncmp("option-", name, 7) != 0) {
log_warnx("lease declined: unknown option %d", i);
goto decline;
}
@@ -1215,7 +1215,7 @@ packet_to_lease(struct interface_info *ifi, struct option_data *options)
options[i].len);
if (buf == NULL || !res_hnok_list(buf)) {
log_warnx("Ignoring %s in offer: invalid host "
- "name(s)", dhcp_options[i].name);
+ "name(s)", name);
continue;
}
break;
@@ -1228,7 +1228,7 @@ packet_to_lease(struct interface_info *ifi, struct option_data *options)
*/
if (!res_hnok_list(pretty)) {
log_warnx("Ignoring %s in offer: invalid host "
- "name(s)", dhcp_options[i].name);
+ "name(s)", name);
continue;
}
break;
@@ -1236,7 +1236,7 @@ packet_to_lease(struct interface_info *ifi, struct option_data *options)
case DHO_NIS_DOMAIN:
if (!res_hnok(pretty)) {
log_warnx("Ignoring %s in offer: invalid host "
- "name", dhcp_options[i].name);
+ "name", name);
continue;
}
break;
@@ -1253,8 +1253,9 @@ packet_to_lease(struct interface_info *ifi, struct option_data *options)
*/
for (i = 0; i < config->required_option_count; i++) {
if (!lease->options[config->required_options[i]].len) {
+ name = code_to_name(i);
log_warnx("lease declined: %s required but missing",
- dhcp_options[i].name);
+ name);
goto decline;
}
}
@@ -1829,12 +1830,12 @@ append_statement(char *string, size_t sz, char *s1, char *s2)
}
char *
-lease_as_string(char *name, char *type, struct client_lease *lease)
+lease_as_string(char *ifname, char *type, struct client_lease *lease)
{
static char string[8192];
char timebuf[27]; /* to hold "6 2017/04/08 05:47:50 UTC;" */
struct option_data *opt;
- char *buf;
+ char *buf, *name;
size_t rslt;
int i;
@@ -1844,7 +1845,7 @@ lease_as_string(char *name, char *type, struct client_lease *lease)
strlcat(string, " {\n", sizeof(string));
strlcat(string, BOOTP_LEASE(lease) ? " bootp;\n" : "", sizeof(string));
- buf = pretty_print_string(name, strlen(name), 1);
+ buf = pretty_print_string(ifname, strlen(ifname), 1);
if (buf == NULL)
return (NULL);
append_statement(string, sizeof(string), " interface ", buf);
@@ -1880,12 +1881,13 @@ lease_as_string(char *name, char *type, struct client_lease *lease)
opt = &lease->options[i];
if (opt->len == 0)
continue;
+ name = code_to_name(i);
buf = pretty_print_option(i, opt, 1);
if (buf == NULL)
return (NULL);
strlcat(string, " option ", sizeof(string));
- strlcat(string, dhcp_options[i].name, sizeof(string));
+ strlcat(string, name, sizeof(string));
append_statement(string, sizeof(string), " ", buf);
}
@@ -2367,10 +2369,7 @@ apply_ignore_list(char *ignore_list)
if (*p == '\0')
continue;
- for (i = 1; i < DHO_END; i++)
- if (!strcasecmp(dhcp_options[i].name, p))
- break;
-
+ i = name_to_code(p);
if (i == DHO_END) {
log_info("Invalid option name: '%s'", p);
return;
diff --git a/sbin/dhclient/dhcpd.h b/sbin/dhclient/dhcpd.h
index dbdee34dc1d..45d504b706d 100644
--- a/sbin/dhclient/dhcpd.h
+++ b/sbin/dhclient/dhcpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: dhcpd.h,v 1.208 2017/07/08 00:36:10 krw Exp $ */
+/* $OpenBSD: dhcpd.h,v 1.209 2017/07/08 20:38:31 krw Exp $ */
/*
* Copyright (c) 2004 Henning Brauer <henning@openbsd.org>
@@ -44,11 +44,6 @@
#define INTERNALSIG INT_MAX
#define DB_TIMEFMT "%w %Y/%m/%d %T UTC"
-struct option {
- char *name;
- char *format;
-};
-
struct option_data {
unsigned int len;
uint8_t *data;
@@ -176,6 +171,9 @@ 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);
struct option_data *unpack_options(struct dhcp_packet *);
+char *code_to_name(int);
+char *code_to_format(int);
+int name_to_code(char *);
/* conflex.c */
extern int lexline, lexchar;
@@ -213,9 +211,6 @@ int interface_status(char *);
void get_hw_address(struct interface_info *);
void sendhup(void);
-/* tables.c */
-extern const struct option dhcp_options[DHO_COUNT];
-
/* dhclient.c */
extern char *path_dhclient_conf;
extern char *path_dhclient_db;
diff --git a/sbin/dhclient/options.c b/sbin/dhclient/options.c
index 1a2c5723d54..c0309e94fe9 100644
--- a/sbin/dhclient/options.c
+++ b/sbin/dhclient/options.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: options.c,v 1.96 2017/07/08 00:36:10 krw Exp $ */
+/* $OpenBSD: options.c,v 1.97 2017/07/08 20:38:31 krw Exp $ */
/* DHCP options parsing and reassembly. */
@@ -65,6 +65,338 @@ int parse_option_buffer(struct option_data *, unsigned char *, int);
int expand_search_domain_name(unsigned char *, size_t, int *, unsigned char *);
/*
+ * DHCP Option names, formats and codes, from RFC1533.
+ *
+ * Format codes:
+ *
+ * e - end of data
+ * I - IP address
+ * l - 32-bit signed integer
+ * L - 32-bit unsigned integer
+ * S - 16-bit unsigned integer
+ * B - 8-bit unsigned integer
+ * t - ASCII text
+ * f - flag (true or false)
+ * A - array of whatever precedes (e.g., IA means array of IP addresses)
+ * C - CIDR description
+ */
+
+static const struct {
+ char *name;
+ char *format;
+} dhcp_options[DHO_COUNT] = {
+ /* 0 */ { "pad", "" },
+ /* 1 */ { "subnet-mask", "I" },
+ /* 2 */ { "time-offset", "l" },
+ /* 3 */ { "routers", "IA" },
+ /* 4 */ { "time-servers", "IA" },
+ /* 5 */ { "ien116-name-servers", "IA" },
+ /* 6 */ { "domain-name-servers", "IA" },
+ /* 7 */ { "log-servers", "IA" },
+ /* 8 */ { "cookie-servers", "IA" },
+ /* 9 */ { "lpr-servers", "IA" },
+ /* 10 */ { "impress-servers", "IA" },
+ /* 11 */ { "resource-location-servers", "IA" },
+ /* 12 */ { "host-name", "t" },
+ /* 13 */ { "boot-size", "S" },
+ /* 14 */ { "merit-dump", "t" },
+ /* 15 */ { "domain-name", "t" },
+ /* 16 */ { "swap-server", "I" },
+ /* 17 */ { "root-path", "t" },
+ /* 18 */ { "extensions-path", "t" },
+ /* 19 */ { "ip-forwarding", "f" },
+ /* 20 */ { "non-local-source-routing", "f" },
+ /* 21 */ { "policy-filter", "IIA" },
+ /* 22 */ { "max-dgram-reassembly", "S" },
+ /* 23 */ { "default-ip-ttl", "B" },
+ /* 24 */ { "path-mtu-aging-timeout", "L" },
+ /* 25 */ { "path-mtu-plateau-table", "SA" },
+ /* 26 */ { "interface-mtu", "S" },
+ /* 27 */ { "all-subnets-local", "f" },
+ /* 28 */ { "broadcast-address", "I" },
+ /* 29 */ { "perform-mask-discovery", "f" },
+ /* 30 */ { "mask-supplier", "f" },
+ /* 31 */ { "router-discovery", "f" },
+ /* 32 */ { "router-solicitation-address", "I" },
+ /* 33 */ { "static-routes", "IIA" },
+ /* 34 */ { "trailer-encapsulation", "f" },
+ /* 35 */ { "arp-cache-timeout", "L" },
+ /* 36 */ { "ieee802-3-encapsulation", "f" },
+ /* 37 */ { "default-tcp-ttl", "B" },
+ /* 38 */ { "tcp-keepalive-interval", "L" },
+ /* 39 */ { "tcp-keepalive-garbage", "f" },
+ /* 40 */ { "nis-domain", "t" },
+ /* 41 */ { "nis-servers", "IA" },
+ /* 42 */ { "ntp-servers", "IA" },
+ /* 43 */ { "vendor-encapsulated-options", "X" },
+ /* 44 */ { "netbios-name-servers", "IA" },
+ /* 45 */ { "netbios-dd-server", "IA" },
+ /* 46 */ { "netbios-node-type", "B" },
+ /* 47 */ { "netbios-scope", "t" },
+ /* 48 */ { "font-servers", "IA" },
+ /* 49 */ { "x-display-manager", "IA" },
+ /* 50 */ { "dhcp-requested-address", "I" },
+ /* 51 */ { "dhcp-lease-time", "L" },
+ /* 52 */ { "dhcp-option-overload", "B" },
+ /* 53 */ { "dhcp-message-type", "B" },
+ /* 54 */ { "dhcp-server-identifier", "I" },
+ /* 55 */ { "dhcp-parameter-request-list", "BA" },
+ /* 56 */ { "dhcp-message", "t" },
+ /* 57 */ { "dhcp-max-message-size", "S" },
+ /* 58 */ { "dhcp-renewal-time", "L" },
+ /* 59 */ { "dhcp-rebinding-time", "L" },
+ /* 60 */ { "dhcp-class-identifier", "t" },
+ /* 61 */ { "dhcp-client-identifier", "X" },
+ /* 62 */ { NULL, NULL },
+ /* 63 */ { NULL, NULL },
+ /* 64 */ { "nisplus-domain", "t" },
+ /* 65 */ { "nisplus-servers", "IA" },
+ /* 66 */ { "tftp-server-name", "t" },
+ /* 67 */ { "bootfile-name", "t" },
+ /* 68 */ { "mobile-ip-home-agent", "IA" },
+ /* 69 */ { "smtp-server", "IA" },
+ /* 70 */ { "pop-server", "IA" },
+ /* 71 */ { "nntp-server", "IA" },
+ /* 72 */ { "www-server", "IA" },
+ /* 73 */ { "finger-server", "IA" },
+ /* 74 */ { "irc-server", "IA" },
+ /* 75 */ { "streettalk-server", "IA" },
+ /* 76 */ { "streettalk-directory-assistance-server", "IA" },
+ /* 77 */ { "user-class", "t" },
+ /* 78 */ { NULL, NULL },
+ /* 79 */ { NULL, NULL },
+ /* 80 */ { NULL, NULL },
+ /* 81 */ { NULL, NULL },
+ /* 82 */ { "relay-agent-information", "X" },
+ /* 83 */ { NULL, NULL },
+ /* 84 */ { NULL, NULL },
+ /* 85 */ { "nds-servers", "IA" },
+ /* 86 */ { "nds-tree-name", "X" },
+ /* 87 */ { "nds-context", "X" },
+ /* 88 */ { NULL, NULL },
+ /* 89 */ { NULL, NULL },
+ /* 90 */ { NULL, NULL },
+ /* 91 */ { NULL, NULL },
+ /* 92 */ { NULL, NULL },
+ /* 93 */ { NULL, NULL },
+ /* 94 */ { NULL, NULL },
+ /* 95 */ { NULL, NULL },
+ /* 96 */ { NULL, NULL },
+ /* 97 */ { NULL, NULL },
+ /* 98 */ { NULL, NULL },
+ /* 99 */ { NULL, NULL },
+ /* 100 */ { NULL, NULL },
+ /* 101 */ { NULL, NULL },
+ /* 102 */ { NULL, NULL },
+ /* 103 */ { NULL, NULL },
+ /* 104 */ { NULL, NULL },
+ /* 105 */ { NULL, NULL },
+ /* 106 */ { NULL, NULL },
+ /* 107 */ { NULL, NULL },
+ /* 108 */ { NULL, NULL },
+ /* 109 */ { NULL, NULL },
+ /* 110 */ { NULL, NULL },
+ /* 111 */ { NULL, NULL },
+ /* 112 */ { NULL, NULL },
+ /* 113 */ { NULL, NULL },
+ /* 114 */ { NULL, NULL },
+ /* 115 */ { NULL, NULL },
+ /* 116 */ { NULL, NULL },
+ /* 117 */ { NULL, NULL },
+ /* 118 */ { NULL, NULL },
+ /* 119 */ { "domain-search", "X" },
+ /* 120 */ { NULL, NULL },
+ /* 121 */ { "classless-static-routes", "CIA" },
+ /* 122 */ { NULL, NULL },
+ /* 123 */ { NULL, NULL },
+ /* 124 */ { NULL, NULL },
+ /* 125 */ { NULL, NULL },
+ /* 126 */ { NULL, NULL },
+ /* 127 */ { NULL, NULL },
+ /* 128 */ { NULL, NULL },
+ /* 129 */ { NULL, NULL },
+ /* 130 */ { NULL, NULL },
+ /* 131 */ { NULL, NULL },
+ /* 132 */ { NULL, NULL },
+ /* 133 */ { NULL, NULL },
+ /* 134 */ { NULL, NULL },
+ /* 135 */ { NULL, NULL },
+ /* 136 */ { NULL, NULL },
+ /* 137 */ { NULL, NULL },
+ /* 138 */ { NULL, NULL },
+ /* 139 */ { NULL, NULL },
+ /* 140 */ { NULL, NULL },
+ /* 141 */ { NULL, NULL },
+ /* 142 */ { NULL, NULL },
+ /* 143 */ { NULL, NULL },
+ /* 144 */ { "tftp-config-file", "t" },
+ /* 145 */ { NULL, NULL },
+ /* 146 */ { NULL, NULL },
+ /* 147 */ { NULL, NULL },
+ /* 148 */ { NULL, NULL },
+ /* 149 */ { NULL, NULL },
+ /* 150 */ { "voip-configuration-server", "IA" },
+ /* 151 */ { NULL, NULL },
+ /* 152 */ { NULL, NULL },
+ /* 153 */ { NULL, NULL },
+ /* 154 */ { NULL, NULL },
+ /* 155 */ { NULL, NULL },
+ /* 156 */ { NULL, NULL },
+ /* 157 */ { NULL, NULL },
+ /* 158 */ { NULL, NULL },
+ /* 159 */ { NULL, NULL },
+ /* 160 */ { NULL, NULL },
+ /* 161 */ { NULL, NULL },
+ /* 162 */ { NULL, NULL },
+ /* 163 */ { NULL, NULL },
+ /* 164 */ { NULL, NULL },
+ /* 165 */ { NULL, NULL },
+ /* 166 */ { NULL, NULL },
+ /* 167 */ { NULL, NULL },
+ /* 168 */ { NULL, NULL },
+ /* 169 */ { NULL, NULL },
+ /* 170 */ { NULL, NULL },
+ /* 171 */ { NULL, NULL },
+ /* 172 */ { NULL, NULL },
+ /* 173 */ { NULL, NULL },
+ /* 174 */ { NULL, NULL },
+ /* 175 */ { NULL, NULL },
+ /* 176 */ { NULL, NULL },
+ /* 177 */ { NULL, NULL },
+ /* 178 */ { NULL, NULL },
+ /* 179 */ { NULL, NULL },
+ /* 180 */ { NULL, NULL },
+ /* 181 */ { NULL, NULL },
+ /* 182 */ { NULL, NULL },
+ /* 183 */ { NULL, NULL },
+ /* 184 */ { NULL, NULL },
+ /* 185 */ { NULL, NULL },
+ /* 186 */ { NULL, NULL },
+ /* 187 */ { NULL, NULL },
+ /* 188 */ { NULL, NULL },
+ /* 189 */ { NULL, NULL },
+ /* 190 */ { NULL, NULL },
+ /* 191 */ { NULL, NULL },
+ /* 192 */ { NULL, NULL },
+ /* 193 */ { NULL, NULL },
+ /* 194 */ { NULL, NULL },
+ /* 195 */ { NULL, NULL },
+ /* 196 */ { NULL, NULL },
+ /* 197 */ { NULL, NULL },
+ /* 198 */ { NULL, NULL },
+ /* 199 */ { NULL, NULL },
+ /* 200 */ { NULL, NULL },
+ /* 201 */ { NULL, NULL },
+ /* 202 */ { NULL, NULL },
+ /* 203 */ { NULL, NULL },
+ /* 204 */ { NULL, NULL },
+ /* 205 */ { NULL, NULL },
+ /* 206 */ { NULL, NULL },
+ /* 207 */ { NULL, NULL },
+ /* 208 */ { NULL, NULL },
+ /* 209 */ { NULL, NULL },
+ /* 210 */ { NULL, NULL },
+ /* 211 */ { NULL, NULL },
+ /* 212 */ { NULL, NULL },
+ /* 213 */ { NULL, NULL },
+ /* 214 */ { NULL, NULL },
+ /* 215 */ { NULL, NULL },
+ /* 216 */ { NULL, NULL },
+ /* 217 */ { NULL, NULL },
+ /* 218 */ { NULL, NULL },
+ /* 219 */ { NULL, NULL },
+ /* 220 */ { NULL, NULL },
+ /* 221 */ { NULL, NULL },
+ /* 222 */ { NULL, NULL },
+ /* 223 */ { NULL, NULL },
+ /* 224 */ { NULL, NULL },
+ /* 225 */ { NULL, NULL },
+ /* 226 */ { NULL, NULL },
+ /* 227 */ { NULL, NULL },
+ /* 228 */ { NULL, NULL },
+ /* 229 */ { NULL, NULL },
+ /* 230 */ { NULL, NULL },
+ /* 231 */ { NULL, NULL },
+ /* 232 */ { NULL, NULL },
+ /* 233 */ { NULL, NULL },
+ /* 234 */ { NULL, NULL },
+ /* 235 */ { NULL, NULL },
+ /* 236 */ { NULL, NULL },
+ /* 237 */ { NULL, NULL },
+ /* 238 */ { NULL, NULL },
+ /* 239 */ { NULL, NULL },
+ /* 240 */ { NULL, NULL },
+ /* 241 */ { NULL, NULL },
+ /* 242 */ { NULL, NULL },
+ /* 243 */ { NULL, NULL },
+ /* 244 */ { NULL, NULL },
+ /* 245 */ { NULL, NULL },
+ /* 246 */ { NULL, NULL },
+ /* 247 */ { NULL, NULL },
+ /* 248 */ { NULL, NULL },
+ /* 249 */ { "classless-ms-static-routes", "CIA" },
+ /* 250 */ { NULL, NULL },
+ /* 251 */ { NULL, NULL },
+ /* 252 */ { "autoproxy-script", "t" },
+ /* 253 */ { NULL, NULL },
+ /* 254 */ { NULL, NULL },
+ /* 255 */ { "option-end", "e" },
+};
+
+char *
+code_to_name(int code)
+{
+ static char unknown[11]; /* "option-NNN" */
+ int ret;
+
+ if (code < 0 || code >= DHO_COUNT)
+ return "";
+
+ if (dhcp_options[code].name != NULL)
+ return dhcp_options[code].name;
+
+ ret = snprintf(unknown, sizeof(unknown), "option-%d", code);
+ if (ret == -1 || ret >= (int)sizeof(unknown))
+ return "";
+
+ return unknown;
+}
+
+int
+name_to_code(char *name)
+{
+ char unknown[11]; /* "option-NNN" */
+ int code, ret;
+
+ for (code = 1; code < DHO_END; code++) {
+ if (dhcp_options[code].name == NULL) {
+ ret = snprintf(unknown, sizeof(unknown), "option-%d",
+ code);
+ if (ret == -1 || ret >= (int)sizeof(unknown))
+ return DHO_END;
+ if (strcasecmp(unknown, name) == 0)
+ return code;
+ } else if (strcasecmp(dhcp_options[code].name, name) == 0) {
+ return code;
+ }
+ }
+
+ return DHO_END;
+}
+
+char *
+code_to_format(int code)
+{
+ if (code < 0 || code >= DHO_COUNT)
+ return "";
+
+ if (dhcp_options[code].format == NULL)
+ return "X";
+
+ return dhcp_options[code].format;
+}
+
+/*
* Parse options out of the specified buffer, storing addresses of
* option values in options. Return 0 if errors, 1 if not.
*/
@@ -72,8 +404,9 @@ int
parse_option_buffer(struct option_data *options, unsigned char *buffer,
int length)
{
- unsigned char *s, *t, *end = buffer + length;
- int len, code;
+ unsigned char *s, *t, *end = buffer + length;
+ char *name, *fmt;
+ int len, code;
for (s = buffer; *s != DHO_END && s < end; ) {
code = s[0];
@@ -84,6 +417,9 @@ parse_option_buffer(struct option_data *options, unsigned char *buffer,
continue;
}
+ name = code_to_name(code);
+ fmt = code_to_format(code);
+
/*
* All options other than DHO_PAD and DHO_END have a one-byte
* length field. It could be 0! Make sure that the length byte
@@ -95,12 +431,11 @@ parse_option_buffer(struct option_data *options, unsigned char *buffer,
; /* option data is all there. */
} else {
log_warnx("option %s (%d) larger than buffer.",
- dhcp_options[code].name, len);
+ name, len);
return (0);
}
} else {
- log_warnx("option %s has no length field.",
- dhcp_options[code].name);
+ log_warnx("option %s has no length field.", name);
return (0);
}
@@ -111,7 +446,7 @@ parse_option_buffer(struct option_data *options, unsigned char *buffer,
* a trailing NULL; however, the receiver of such options
* MUST be prepared to delete trailing nulls if they exist."
*/
- if (dhcp_options[code].format[0] == 't') {
+ if (fmt[0] == 't') {
while (len > 0 && s[len + 1] == '\0')
len--;
}
@@ -123,7 +458,7 @@ parse_option_buffer(struct option_data *options, unsigned char *buffer,
if (!options[code].data) {
if (!(t = calloc(1, len + 1)))
fatalx("Can't allocate storage for option %s.",
- dhcp_options[code].name);
+ name);
/*
* Copy and NUL-terminate the option (in case
* it's an ASCII string).
@@ -140,7 +475,7 @@ parse_option_buffer(struct option_data *options, unsigned char *buffer,
t = calloc(1, len + options[code].len + 1);
if (!t)
fatalx("Can't expand storage for option %s.",
- dhcp_options[code].name);
+ name);
memcpy(t, options[code].data, options[code].len);
memcpy(t + options[code].len, &s[2], len);
options[code].len += len;
@@ -419,7 +754,7 @@ pretty_print_option(unsigned int code, struct option_data *option,
struct in_addr foo;
unsigned char *data = option->data;
unsigned char *dp = data;
- char *op = optbuf, *buf;
+ char *op = optbuf, *buf, *name, *fmt;
int hunksize = 0, numhunk = -1, numelem = 0;
int i, j, k, opleft = sizeof(optbuf);
int len = option->len;
@@ -455,26 +790,26 @@ pretty_print_option(unsigned int code, struct option_data *option,
break;
}
+ name = code_to_name(code);
+ fmt = code_to_format(code);
+
/* Figure out the size of the data. */
- for (i = 0; dhcp_options[code].format[i]; i++) {
+ for (i = 0; fmt[i]; i++) {
if (!numhunk) {
log_warnx("%s: Excess information in format string: "
- "%s", dhcp_options[code].name,
- &(dhcp_options[code].format[i]));
+ "%s", name, &fmt[i]);
goto done;
}
numelem++;
- fmtbuf[i] = dhcp_options[code].format[i];
- switch (dhcp_options[code].format[i]) {
+ fmtbuf[i] = fmt[i];
+ switch (fmt[i]) {
case 'A':
--numelem;
fmtbuf[i] = 0;
numhunk = 0;
if (hunksize == 0) {
log_warnx("%s: no size indicator before A"
- " in format string: %s",
- dhcp_options[code].name,
- dhcp_options[code].format);
+ " in format string: %s", name, fmt);
goto done;
}
break;
@@ -512,23 +847,22 @@ pretty_print_option(unsigned int code, struct option_data *option,
case 'e':
break;
default:
- log_warnx("%s: garbage in format string: %s",
- dhcp_options[code].name,
- &(dhcp_options[code].format[i]));
+ log_warnx("%s: garbage in format string: %s", name,
+ &fmt[i]);
goto done;
}
}
/* Check for too few bytes. */
if (hunksize > len) {
- log_warnx("%s: expecting at least %d bytes; got %d",
- dhcp_options[code].name, hunksize, len);
+ log_warnx("%s: expecting at least %d bytes; got %d", name,
+ hunksize, len);
goto done;
}
/* Check for too many bytes. */
if (numhunk == -1 && hunksize < len) {
- log_warnx("%s: expecting only %d bytes: got %d",
- dhcp_options[code].name, hunksize, len);
+ log_warnx("%s: expecting only %d bytes: got %d", name,
+ hunksize, len);
goto done;
}
@@ -537,8 +871,8 @@ pretty_print_option(unsigned int code, struct option_data *option,
numhunk = len / hunksize;
/* See if we got an exact number of hunks. */
if (numhunk > 0 && numhunk * hunksize != len) {
- log_warnx("%s: expecting %d bytes: got %d",
- dhcp_options[code].name, numhunk * hunksize, len);
+ log_warnx("%s: expecting %d bytes: got %d", name,
+ numhunk * hunksize, len);
goto done;
}