1/*
2 * dhcpcd - DHCP client daemon
3 * Copyright (c) 2006-2010 Roy Marples <roy@marples.name>
4 * All rights reserved
5
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <ctype.h>
29#include <errno.h>
30#include <fcntl.h>
31#include <stdlib.h>
32#include <string.h>
33#include <unistd.h>
34
35#include "common.h"
36#include "dhcp.h"
37
38#define REQUEST	(1 << 0)
39#define UINT8	(1 << 1)
40#define UINT16	(1 << 2)
41#define SINT16	(1 << 3)
42#define UINT32	(1 << 4)
43#define SINT32	(1 << 5)
44#define IPV4	(1 << 6)
45#define STRING	(1 << 7)
46#define PAIR	(1 << 8)
47#define ARRAY	(1 << 9)
48#define RFC3361	(1 << 10)
49#define RFC3397	(1 << 11)
50#define RFC3442 (1 << 12)
51
52#define IPV4R	IPV4 | REQUEST
53
54#define DAD	"Duplicate address detected"
55
56/* Our aggregate option buffer.
57 * We ONLY use this when options are split, which for most purposes is
58 * practically never. See RFC3396 for details. */
59static uint8_t *opt_buffer;
60
61struct dhcp_opt {
62	uint8_t option;
63	int type;
64	const char *var;
65};
66
67static const struct dhcp_opt const dhcp_opts[] = {
68	{ 1,	IPV4 | REQUEST,	"subnet_mask" },
69		/* RFC 3442 states that the CSR has to come before all other
70		 * routes. For completeness, we also specify static routes,
71	 	 * then routers. */
72	{ 121,  RFC3442,	"classless_static_routes" },
73	{ 249,  RFC3442,	"ms_classless_static_routes" },
74	{ 33,	IPV4 | ARRAY | REQUEST,	"static_routes" },
75	{ 3,	IPV4 | ARRAY | REQUEST,	"routers" },
76	{ 2,	UINT32,		"time_offset" },
77	{ 4,	IPV4 | ARRAY,	"time_servers" },
78	{ 5,	IPV4 | ARRAY,	"ien116_name_servers" },
79	{ 6,	IPV4 | ARRAY,	"domain_name_servers" },
80	{ 7,	IPV4 | ARRAY,	"log_servers" },
81	{ 8,	IPV4 | ARRAY,	"cookie_servers" },
82	{ 9, 	IPV4 | ARRAY,	"lpr_servers" },
83	{ 10,	IPV4 | ARRAY,	"impress_servers" },
84	{ 11,	IPV4 | ARRAY,	"resource_location_servers" },
85	{ 12,	STRING,		"host_name" },
86	{ 13,	UINT16,		"boot_size" },
87	{ 14,	STRING,		"merit_dump" },
88	{ 15,	STRING,		"domain_name" },
89	{ 16,	IPV4,		"swap_server" },
90	{ 17,	STRING,		"root_path" },
91	{ 18,	STRING,		"extensions_path" },
92	{ 19,	UINT8,		"ip_forwarding" },
93	{ 20,	UINT8,		"non_local_source_routing" },
94	{ 21,	IPV4 | ARRAY,	"policy_filter" },
95	{ 22,	SINT16,		"max_dgram_reassembly" },
96	{ 23,	UINT16,		"default_ip_ttl" },
97	{ 24,	UINT32,		"path_mtu_aging_timeout" },
98	{ 25,	UINT16 | ARRAY,	"path_mtu_plateau_table" },
99	{ 26,	UINT16,		"interface_mtu" },
100	{ 27,	UINT8,		"all_subnets_local" },
101	{ 28,	IPV4 | REQUEST,	"broadcast_address" },
102	{ 29,	UINT8,		"perform_mask_discovery" },
103	{ 30,	UINT8,		"mask_supplier" },
104	{ 31,	UINT8,		"router_discovery" },
105	{ 32,	IPV4,		"router_solicitation_address" },
106	{ 34,	UINT8,		"trailer_encapsulation" },
107	{ 35, 	UINT32,		"arp_cache_timeout" },
108	{ 36,	UINT16,		"ieee802_3_encapsulation" },
109	{ 37,	UINT8,		"default_tcp_ttl" },
110	{ 38,	UINT32,		"tcp_keepalive_interval" },
111	{ 39,	UINT8,		"tcp_keepalive_garbage" },
112	{ 40,	STRING,		"nis_domain" },
113	{ 41,	IPV4 | ARRAY,	"nis_servers" },
114	{ 42,	IPV4 | ARRAY,	"ntp_servers" },
115	{ 43,	STRING,		"vendor_encapsulated_options" },
116	{ 44,	IPV4 | ARRAY,	"netbios_name_servers" },
117	{ 45,	IPV4,		"netbios_dd_server" },
118	{ 46,	UINT8,		"netbios_node_type" },
119	{ 47,	STRING,		"netbios_scope" },
120	{ 48,	IPV4 | ARRAY,	"font_servers" },
121	{ 49,	IPV4 | ARRAY,	"x_display_manager" },
122	{ 50, 	IPV4,		"dhcp_requested_address" },
123	{ 51,	UINT32 | REQUEST,	"dhcp_lease_time" },
124	{ 52,	UINT8,		"dhcp_option_overload" },
125	{ 53,	UINT8,		"dhcp_message_type" },
126	{ 54,	IPV4,		"dhcp_server_identifier" },
127	{ 55,	UINT8 | ARRAY,	"dhcp_parameter_request_list" },
128	{ 56,	STRING,		"dhcp_message" },
129	{ 57,	UINT16,		"dhcp_max_message_size" },
130	{ 58,	UINT32 | REQUEST,	"dhcp_renewal_time" },
131	{ 59,	UINT32 | REQUEST,	"dhcp_rebinding_time" },
132	{ 64,	STRING,		"nisplus_domain" },
133	{ 65,	IPV4 | ARRAY,	"nisplus_servers" },
134	{ 66,	STRING,		"tftp_server_name" },
135	{ 67,	STRING,		"bootfile_name" },
136	{ 68,	IPV4 | ARRAY,	"mobile_ip_home_agent" },
137	{ 69,	IPV4 | ARRAY,	"smtp_server" },
138	{ 70,	IPV4 | ARRAY,	"pop_server" },
139	{ 71,	IPV4 | ARRAY,	"nntp_server" },
140	{ 72,	IPV4 | ARRAY,	"www_server" },
141	{ 73,	IPV4 | ARRAY,	"finger_server" },
142	{ 74,	IPV4 | ARRAY,	"irc_server" },
143	{ 75,	IPV4 | ARRAY,	"streettalk_server" },
144	{ 76,	IPV4 | ARRAY,	"streettalk_directory_assistance_server" },
145	{ 77,	STRING,		"user_class" },
146	{ 81,	STRING | RFC3397,	"fqdn_name" },
147	{ 85,	IPV4 | ARRAY,	"nds_servers" },
148	{ 86,	STRING,		"nds_tree_name" },
149	{ 87,	STRING,		"nds_context" },
150	{ 88,	STRING | RFC3397,	"bcms_controller_names" },
151	{ 89,	IPV4 | ARRAY,	"bcms_controller_address" },
152	{ 91,	UINT32,		"client_last_transaction_time" },
153	{ 92,	IPV4 | ARRAY,	"associated_ip" },
154	{ 98,	STRING,		"uap_servers" },
155	{ 112,	IPV4 | ARRAY,	"netinfo_server_address" },
156	{ 113,	STRING,		"netinfo_server_tag" },
157	{ 114,	STRING,		"default_url" },
158	{ 118,	IPV4,		"subnet_selection" },
159	{ 119,	STRING | RFC3397,	"domain_search" },
160	{ 0, 0, NULL }
161};
162
163static int
164valid_length(uint8_t option, int dl, int *type)
165{
166	const struct dhcp_opt *opt;
167	ssize_t sz;
168
169	if (dl == 0)
170		return -1;
171
172	for (opt = dhcp_opts; opt->option; opt++) {
173		if (opt->option != option)
174			continue;
175
176		if (type)
177			*type = opt->type;
178
179		if (opt->type == 0 ||
180		    opt->type & STRING ||
181		    opt->type & RFC3442)
182			return 0;
183
184		sz = 0;
185		if (opt->type & UINT32 || opt->type & IPV4)
186			sz = sizeof(uint32_t);
187		if (opt->type & UINT16)
188			sz = sizeof(uint16_t);
189		if (opt->type & UINT8)
190			sz = sizeof(uint8_t);
191		if (opt->type & IPV4 || opt->type & ARRAY)
192			return dl % sz;
193		return (dl == sz ? 0 : -1);
194	}
195
196	/* unknown option, so let it pass */
197	return 0;
198}
199
200#ifdef DEBUG_MEMORY
201static void
202free_option_buffer(void)
203{
204	free(opt_buffer);
205}
206#endif
207
208#define get_option_raw(dhcp, opt) get_option(dhcp, opt, NULL, NULL)
209static const uint8_t *
210get_option(const struct dhcp_message *dhcp, uint8_t opt, int *len, int *type)
211{
212	const uint8_t *p = dhcp->options;
213	const uint8_t *e = p + sizeof(dhcp->options);
214	uint8_t l, ol = 0;
215	uint8_t o = 0;
216	uint8_t overl = 0;
217	uint8_t *bp = NULL;
218	const uint8_t *op = NULL;
219	int bl = 0;
220
221	while (p < e) {
222		o = *p++;
223		if (o == opt) {
224			if (op) {
225				if (!opt_buffer) {
226					opt_buffer = xmalloc(sizeof(*dhcp));
227#ifdef DEBUG_MEMORY
228					atexit(free_option_buffer);
229#endif
230				}
231				if (!bp)
232					bp = opt_buffer;
233				memcpy(bp, op, ol);
234				bp += ol;
235			}
236			ol = *p;
237			op = p + 1;
238			bl += ol;
239		}
240		switch (o) {
241		case DHO_PAD:
242			continue;
243		case DHO_END:
244			if (overl & 1) {
245				/* bit 1 set means parse boot file */
246				overl &= ~1;
247				p = dhcp->bootfile;
248				e = p + sizeof(dhcp->bootfile);
249			} else if (overl & 2) {
250				/* bit 2 set means parse server name */
251				overl &= ~2;
252				p = dhcp->servername;
253				e = p + sizeof(dhcp->servername);
254			} else
255				goto exit;
256			break;
257		case DHO_OPTIONSOVERLOADED:
258			/* Ensure we only get this option once */
259			if (!overl)
260				overl = p[1];
261			break;
262		}
263		l = *p++;
264		p += l;
265	}
266
267exit:
268	if (valid_length(opt, bl, type) == -1) {
269		errno = EINVAL;
270		return NULL;
271	}
272	if (len)
273		*len = bl;
274	if (bp) {
275		memcpy(bp, op, ol);
276		return (const uint8_t *)opt_buffer;
277	}
278	if (op)
279		return op;
280	errno = ENOENT;
281	return NULL;
282}
283
284int
285get_option_addr(struct in_addr *a, const struct dhcp_message *dhcp,
286    uint8_t option)
287{
288	const uint8_t *p = get_option_raw(dhcp, option);
289
290	if (!p)
291		return -1;
292	memcpy(&a->s_addr, p, sizeof(a->s_addr));
293	return 0;
294}
295
296int
297get_option_uint32(uint32_t *i, const struct dhcp_message *dhcp, uint8_t option)
298{
299	const uint8_t *p = get_option_raw(dhcp, option);
300	uint32_t d;
301
302	if (!p)
303		return -1;
304	memcpy(&d, p, sizeof(d));
305	*i = ntohl(d);
306	return 0;
307}
308
309int
310get_option_uint16(uint16_t *i, const struct dhcp_message *dhcp, uint8_t option)
311{
312	const uint8_t *p = get_option_raw(dhcp, option);
313	uint16_t d;
314
315	if (!p)
316		return -1;
317	memcpy(&d, p, sizeof(d));
318	*i = ntohs(d);
319	return 0;
320}
321
322int
323get_option_uint8(uint8_t *i, const struct dhcp_message *dhcp, uint8_t option)
324{
325	const uint8_t *p = get_option_raw(dhcp, option);
326
327	if (!p)
328		return -1;
329	if (i)
330		*i = *(p);
331	return 0;
332}
333
334static struct rt *
335decode_rfc3442_rt(int dl, const uint8_t *data)
336{
337	const uint8_t *p = data;
338	const uint8_t *e;
339	uint8_t cidr;
340	size_t ocets;
341	struct rt *routes = NULL;
342	struct rt *rt = NULL;
343
344	/* Minimum is 5 -first is CIDR and a router length of 4 */
345	if (dl < 5)
346		return NULL;
347
348	e = p + dl;
349	while (p < e) {
350		cidr = *p++;
351		if (cidr > 32) {
352			free_routes(routes);
353			errno = EINVAL;
354			return NULL;
355		}
356
357		if (rt) {
358			rt->next = xzalloc(sizeof(*rt));
359			rt = rt->next;
360		} else {
361			routes = rt = xzalloc(sizeof(*routes));
362		}
363		rt->next = NULL;
364
365		ocets = (cidr + 7) / 8;
366		/* If we have ocets then we have a destination and netmask */
367		if (ocets > 0) {
368			memcpy(&rt->dest.s_addr, p, ocets);
369			p += ocets;
370			rt->net.s_addr = htonl(~0U << (32 - cidr));
371		}
372
373		/* Finally, snag the router */
374		memcpy(&rt->gate.s_addr, p, 4);
375		p += 4;
376	}
377	return routes;
378}
379
380
381/* This calculates the netmask that we should use for static routes.
382 * This IS different from the calculation used to calculate the netmask
383 * for an interface address. */
384static uint32_t
385route_netmask(uint32_t ip_in)
386{
387	/* used to be unsigned long - check if error */
388	uint32_t p = ntohl(ip_in);
389	uint32_t t;
390
391	if (IN_CLASSA(p))
392		t = ~IN_CLASSA_NET;
393	else {
394		if (IN_CLASSB(p))
395			t = ~IN_CLASSB_NET;
396		else {
397			if (IN_CLASSC(p))
398				t = ~IN_CLASSC_NET;
399			else
400				t = 0;
401		}
402	}
403
404	while (t & p)
405		t >>= 1;
406
407	return (htonl(~t));
408}
409
410/* We need to obey routing options.
411 * If we have a CSR then we only use that.
412 * Otherwise we add static routes and then routers. */
413struct rt *
414get_option_routes(const struct dhcp_message *dhcp,
415    const char *ifname, int *opts)
416{
417	const uint8_t *p;
418	const uint8_t *e;
419	struct rt *routes = NULL;
420	struct rt *route = NULL;
421	int len;
422
423	/* If we have CSR's then we MUST use these only */
424	p = get_option(dhcp, DHO_CSR, &len, NULL);
425	/* Check for crappy MS option */
426	if (!p)
427		p = get_option(dhcp, DHO_MSCSR, &len, NULL);
428	if (p) {
429		routes = decode_rfc3442_rt(len, p);
430		if (routes && !(*opts & DHCPCD_CSR_WARNED)) {
431			*opts |= DHCPCD_CSR_WARNED;
432			return routes;
433		}
434	}
435
436	/* OK, get our static routes first. */
437	p = get_option(dhcp, DHO_STATICROUTE, &len, NULL);
438	if (p) {
439		e = p + len;
440		while (p < e) {
441			if (route) {
442				route->next = xmalloc(sizeof(*route));
443				route = route->next;
444			} else
445				routes = route = xmalloc(sizeof(*routes));
446			route->next = NULL;
447			memcpy(&route->dest.s_addr, p, 4);
448			p += 4;
449			memcpy(&route->gate.s_addr, p, 4);
450			p += 4;
451			route->net.s_addr = route_netmask(route->dest.s_addr);
452		}
453	}
454
455	/* Now grab our routers */
456	p = get_option(dhcp, DHO_ROUTER, &len, NULL);
457	if (p) {
458		e = p + len;
459		while (p < e) {
460			if (route) {
461				route->next = xzalloc(sizeof(*route));
462				route = route->next;
463			} else
464				routes = route = xzalloc(sizeof(*route));
465			memcpy(&route->gate.s_addr, p, 4);
466			p += 4;
467		}
468	}
469
470	return routes;
471}
472
473static size_t
474encode_rfc1035(const char *src, uint8_t *dst)
475{
476	uint8_t *p = dst;
477	uint8_t *lp = p++;
478
479	if (*src == '\0')
480		return 0;
481	for (; *src; src++) {
482		if (*src == '\0')
483			break;
484		if (*src == '.') {
485			/* Skip the trailing . */
486			if (src[1] == '\0')
487				break;
488			*lp = p - lp - 1;
489			if (*lp == '\0')
490				return p - dst;
491			lp = p++;
492		} else
493			*p++ = (uint8_t)*src;
494	}
495	*lp = p - lp - 1;
496	*p++ = '\0';
497	return p - dst;
498}
499
500#define PUTADDR(_type, _val)						      \
501	{								      \
502		*p++ = _type;						      \
503		*p++ = 4;						      \
504		memcpy(p, &_val.s_addr, 4);				      \
505		p += 4;							      \
506	}
507
508int
509dhcp_message_add_addr(struct dhcp_message *dhcp,
510    uint8_t type, struct in_addr addr)
511{
512	uint8_t *p;
513	size_t len;
514
515	p = dhcp->options;
516	while (*p != DHO_END) {
517		p++;
518		p += *p + 1;
519	}
520
521	len = p - (uint8_t *)dhcp;
522	if (len + 6 > sizeof(*dhcp)) {
523		errno = ENOMEM;
524		return -1;
525	}
526
527	PUTADDR(type, addr);
528	*p = DHO_END;
529	return 0;
530}
531
532ssize_t
533make_message(struct dhcp_message **message,
534    const struct interface *iface,
535    uint8_t type)
536{
537	struct dhcp_message *dhcp;
538	uint8_t *m, *lp, *p;
539	uint8_t *n_params = NULL;
540	time_t up = uptime() - iface->start_uptime;
541	uint32_t ul;
542	uint16_t sz;
543	size_t len;
544	const char *hp;
545	const struct dhcp_opt *opt;
546	const struct if_options *ifo = iface->state->options;
547	const struct dhcp_lease *lease = &iface->state->lease;
548
549	dhcp = xzalloc(sizeof (*dhcp));
550	m = (uint8_t *)dhcp;
551	p = dhcp->options;
552
553	if ((type == DHCP_INFORM || type == DHCP_RELEASE ||
554		(type == DHCP_REQUEST &&
555		    iface->net.s_addr == lease->net.s_addr &&
556		    (iface->state->new == NULL ||
557			iface->state->new->cookie == htonl(MAGIC_COOKIE)))))
558	{
559		dhcp->ciaddr = iface->addr.s_addr;
560		/* In-case we haven't actually configured the address yet */
561		if (type == DHCP_INFORM && iface->addr.s_addr == 0)
562			dhcp->ciaddr = lease->addr.s_addr;
563	}
564
565	dhcp->op = DHCP_BOOTREQUEST;
566	dhcp->hwtype = iface->family;
567	switch (iface->family) {
568	case ARPHRD_ETHER:
569	case ARPHRD_IEEE802:
570		dhcp->hwlen = iface->hwlen;
571		memcpy(&dhcp->chaddr, &iface->hwaddr, iface->hwlen);
572		break;
573	}
574
575	if (ifo->options & DHCPCD_BROADCAST &&
576	    dhcp->ciaddr == 0 &&
577	    type != DHCP_DECLINE &&
578	    type != DHCP_RELEASE)
579		dhcp->flags = htons(BROADCAST_FLAG);
580
581	if (type != DHCP_DECLINE && type != DHCP_RELEASE) {
582		if (up < 0 || up > (time_t)UINT16_MAX)
583			dhcp->secs = htons((uint16_t)UINT16_MAX);
584		else
585			dhcp->secs = htons(up);
586	}
587	dhcp->xid = iface->state->xid;
588	dhcp->cookie = htonl(MAGIC_COOKIE);
589
590	*p++ = DHO_MESSAGETYPE;
591	*p++ = 1;
592	*p++ = type;
593
594	if (iface->clientid) {
595		*p++ = DHO_CLIENTID;
596		memcpy(p, iface->clientid, iface->clientid[0] + 1);
597		p += iface->clientid[0] + 1;
598	}
599
600	if (lease->addr.s_addr && lease->cookie == htonl(MAGIC_COOKIE)) {
601		if (type == DHCP_DECLINE ||
602		    (type == DHCP_REQUEST &&
603			lease->addr.s_addr != iface->addr.s_addr))
604		{
605			PUTADDR(DHO_IPADDRESS, lease->addr);
606			if (lease->server.s_addr)
607				PUTADDR(DHO_SERVERID, lease->server);
608		}
609
610		if (type == DHCP_RELEASE) {
611			if (lease->server.s_addr)
612				PUTADDR(DHO_SERVERID, lease->server);
613		}
614	}
615
616	if (type == DHCP_DECLINE) {
617		*p++ = DHO_MESSAGE;
618		len = strlen(DAD);
619		*p++ = len;
620		memcpy(p, DAD, len);
621		p += len;
622	}
623
624	if (type == DHCP_DISCOVER && ifo->options & DHCPCD_REQUEST)
625		PUTADDR(DHO_IPADDRESS, ifo->req_addr);
626
627	if (type == DHCP_DISCOVER ||
628	    type == DHCP_INFORM ||
629	    type == DHCP_REQUEST)
630	{
631		*p++ = DHO_MAXMESSAGESIZE;
632		*p++ = 2;
633		sz = get_mtu(iface->name);
634		if (sz < MTU_MIN) {
635			if (set_mtu(iface->name, MTU_MIN) == 0)
636				sz = MTU_MIN;
637		} else if (sz > MTU_MAX) {
638			/* Even though our MTU could be greater than
639			 * MTU_MAX (1500) dhcpcd does not presently
640			 * handle DHCP packets any bigger. */
641			sz = MTU_MAX;
642		}
643		sz = htons(sz);
644		memcpy(p, &sz, 2);
645		p += 2;
646
647		if (ifo->userclass[0]) {
648			*p++ = DHO_USERCLASS;
649			memcpy(p, ifo->userclass, ifo->userclass[0] + 1);
650			p += ifo->userclass[0] + 1;
651		}
652
653		if (ifo->vendorclassid[0]) {
654			*p++ = DHO_VENDORCLASSID;
655			memcpy(p, ifo->vendorclassid,
656			    ifo->vendorclassid[0] + 1);
657			p += ifo->vendorclassid[0] + 1;
658		}
659
660
661		if (type != DHCP_INFORM) {
662			if (ifo->leasetime != 0) {
663				*p++ = DHO_LEASETIME;
664				*p++ = 4;
665				ul = htonl(ifo->leasetime);
666				memcpy(p, &ul, 4);
667				p += 4;
668			}
669		}
670
671		/* Regardless of RFC2132, we should always send a hostname
672		 * upto the first dot (the short hostname) as otherwise
673		 * confuses some DHCP servers when updating DNS.
674		 * The FQDN option should be used if a FQDN is required. */
675		if (ifo->options & DHCPCD_HOSTNAME && ifo->hostname[0]) {
676			*p++ = DHO_HOSTNAME;
677			hp = strchr(ifo->hostname, '.');
678			if (hp)
679				len = hp - ifo->hostname;
680			else
681				len = strlen(ifo->hostname);
682			*p++ = len;
683			memcpy(p, ifo->hostname, len);
684			p += len;
685		}
686		if (ifo->fqdn != FQDN_DISABLE && ifo->hostname[0]) {
687			/* IETF DHC-FQDN option (81), RFC4702 */
688			*p++ = DHO_FQDN;
689			lp = p;
690			*p++ = 3;
691			/*
692			 * Flags: 0000NEOS
693			 * S: 1 => Client requests Server to update
694			 *         a RR in DNS as well as PTR
695			 * O: 1 => Server indicates to client that
696			 *         DNS has been updated
697			 * E: 1 => Name data is DNS format
698			 * N: 1 => Client requests Server to not
699			 *         update DNS
700			 */
701			*p++ = (ifo->fqdn & 0x09) | 0x04;
702			*p++ = 0; /* from server for PTR RR */
703			*p++ = 0; /* from server for A RR if S=1 */
704			ul = encode_rfc1035(ifo->hostname, p);
705			*lp += ul;
706			p += ul;
707		}
708
709		/* vendor is already encoded correctly, so just add it */
710		if (ifo->vendor[0]) {
711			*p++ = DHO_VENDOR;
712			memcpy(p, ifo->vendor, ifo->vendor[0] + 1);
713			p += ifo->vendor[0] + 1;
714		}
715
716		*p++ = DHO_PARAMETERREQUESTLIST;
717		n_params = p;
718		*p++ = 0;
719		for (opt = dhcp_opts; opt->option; opt++) {
720			if (!(opt->type & REQUEST ||
721				has_option_mask(ifo->requestmask, opt->option)))
722				continue;
723			if (type == DHCP_INFORM &&
724			    (opt->option == DHO_RENEWALTIME ||
725				opt->option == DHO_REBINDTIME))
726				continue;
727			*p++ = opt->option;
728		}
729		*n_params = p - n_params - 1;
730	}
731	*p++ = DHO_END;
732
733#ifdef BOOTP_MESSAGE_LENTH_MIN
734	/* Some crappy DHCP servers think they have to obey the BOOTP minimum
735	 * message length.
736	 * They are wrong, but we should still cater for them. */
737	while (p - m < BOOTP_MESSAGE_LENTH_MIN)
738		*p++ = DHO_PAD;
739#endif
740
741	*message = dhcp;
742	return p - m;
743}
744
745void
746get_lease(struct dhcp_lease *lease, const struct dhcp_message *dhcp)
747{
748	struct timeval now;
749
750	lease->cookie = dhcp->cookie;
751	/* BOOTP does not set yiaddr for replies when ciaddr is set. */
752	if (dhcp->yiaddr)
753		lease->addr.s_addr = dhcp->yiaddr;
754	else
755		lease->addr.s_addr = dhcp->ciaddr;
756	if (get_option_addr(&lease->net, dhcp, DHO_SUBNETMASK) == -1)
757		lease->net.s_addr = get_netmask(lease->addr.s_addr);
758	if (get_option_addr(&lease->brd, dhcp, DHO_BROADCAST) == -1)
759		lease->brd.s_addr = lease->addr.s_addr | ~lease->net.s_addr;
760	if (get_option_uint32(&lease->leasetime, dhcp, DHO_LEASETIME) == 0) {
761		/* Ensure that we can use the lease */
762		get_monotonic(&now);
763		if (now.tv_sec + (time_t)lease->leasetime < now.tv_sec)
764			lease->leasetime = ~0U; /* Infinite lease */
765	} else
766		lease->leasetime = ~0U; /* Default to infinite lease */
767	if (get_option_uint32(&lease->renewaltime, dhcp, DHO_RENEWALTIME) != 0)
768		lease->renewaltime = 0;
769	if (get_option_uint32(&lease->rebindtime, dhcp, DHO_REBINDTIME) != 0)
770		lease->rebindtime = 0;
771	if (get_option_addr(&lease->server, dhcp, DHO_SERVERID) != 0)
772		lease->server.s_addr = INADDR_ANY;
773}
774