1 /* SPDX-License-Identifier: BSD-2-Clause */
3 * dhcpcd - DHCP client daemon
4 * Copyright (c) 2006-2021 Roy Marples <roy@marples.name>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/utsname.h>
42 #include "dhcp-common.h"
50 dhcp_get_hostname(char *buf, size_t buf_len, const struct if_options *ifo)
53 if (ifo->hostname[0] == '\0') {
54 if (gethostname(buf, buf_len) != 0)
56 buf[buf_len - 1] = '\0';
58 strlcpy(buf, ifo->hostname, buf_len);
60 /* Deny sending of these local hostnames */
61 if (buf[0] == '\0' || buf[0] == '.' ||
62 strcmp(buf, "(none)") == 0 ||
63 strcmp(buf, "localhost") == 0 ||
64 strncmp(buf, "localhost.", strlen("localhost.")) == 0)
67 /* Shorten the hostname if required */
68 if (ifo->options & DHCPCD_HOSTNAME_SHORT) {
71 hp = strchr(buf, '.');
80 dhcp_print_option_encoding(const struct dhcp_opt *opt, int cols)
88 if (opt->type & OT_EMBED)
90 if (opt->type & OT_ENCAP)
92 if (opt->type & OT_INDEX)
94 if (opt->type & OT_ARRAY)
96 if (opt->type & OT_UINT8)
98 else if (opt->type & OT_INT8)
100 else if (opt->type & OT_UINT16)
102 else if (opt->type & OT_INT16)
104 else if (opt->type & OT_UINT32)
106 else if (opt->type & OT_INT32)
108 else if (opt->type & OT_ADDRIPV4)
109 printf(" ipaddress");
110 else if (opt->type & OT_ADDRIPV6)
111 printf(" ip6address");
112 else if (opt->type & OT_FLAG)
114 else if (opt->type & OT_BITFLAG)
116 else if (opt->type & OT_RFC1035)
118 else if (opt->type & OT_DOMAIN)
120 else if (opt->type & OT_ASCII)
122 else if (opt->type & OT_RAW)
124 else if (opt->type & OT_BINHEX)
126 else if (opt->type & OT_STRING)
128 if (opt->type & OT_RFC3361)
130 if (opt->type & OT_RFC3442)
132 if (opt->type & OT_REQUEST)
134 if (opt->type & OT_NOREQ)
135 printf(" norequest");
140 vivso_find(uint32_t iana_en, const void *arg)
142 const struct interface *ifp;
144 struct dhcp_opt *opt;
147 for (i = 0, opt = ifp->options->vivso_override;
148 i < ifp->options->vivso_override_len;
150 if (opt->option == iana_en)
152 for (i = 0, opt = ifp->ctx->vivso;
153 i < ifp->ctx->vivso_len;
155 if (opt->option == iana_en)
161 dhcp_vendor(char *str, size_t len)
167 if (uname(&utn) == -1)
168 return (ssize_t)snprintf(str, len, "%s-%s",
172 "%s-%s:%s-%s:%s", PACKAGE, VERSION,
173 utn.sysname, utn.release, utn.machine);
174 if (l == -1 || (size_t)(l + 1) > len)
178 l = if_machinearch(p + 1, len - 1);
179 if (l == -1 || (size_t)(l + 1) > len)
187 make_option_mask(const struct dhcp_opt *dopts, size_t dopts_len,
188 const struct dhcp_opt *odopts, size_t odopts_len,
189 uint8_t *mask, const char *opts, int add)
192 const struct dhcp_opt *opt;
199 o = p = strdup(opts);
200 while ((token = strsep(&p, ", "))) {
203 if (strncmp(token, "dhcp6_", 6) == 0)
205 if (strncmp(token, "nd_", 3) == 0)
208 for (i = 0, opt = odopts; i < odopts_len; i++, opt++) {
209 if (opt->var == NULL || opt->option == 0)
210 continue; /* buggy dhcpcd-definitions.conf */
211 if (strcmp(opt->var, token) == 0)
214 n = (unsigned int)strtou(token, NULL, 0,
216 if (e == 0 && opt->option == n)
223 for (i = 0, opt = dopts; i < dopts_len; i++, opt++) {
224 if (strcmp(opt->var, token) == 0)
227 n = (unsigned int)strtou(token, NULL, 0,
229 if (e == 0 && opt->option == n)
236 if (!match || !opt->option) {
241 if (add == 2 && !(opt->type & OT_ADDRIPV4)) {
246 if (add == 1 || add == 2)
247 add_option_mask(mask, opt->option);
249 del_option_mask(mask, opt->option);
256 encode_rfc1035(const char *src, uint8_t *dst)
263 if (src == NULL || *src == '\0')
270 /* Silence bogus GCC warnings */
276 for (; *src; src++) {
280 /* Skip the trailing . */
285 *lp = (uint8_t)(p - lp - 1);
291 *p++ = (uint8_t)*src;
296 *lp = (uint8_t)(p - lp - 1);
307 /* Decode an RFC1035 DNS search order option into a space
308 * separated string. Returns length of string (including
309 * terminating zero) or zero on error. out may be NULL
310 * to just determine output length. */
312 decode_rfc1035(char *out, size_t len, const uint8_t *p, size_t pl)
315 size_t start_len, l, d_len, o_len;
316 const uint8_t *r, *q = p, *e;
329 /* Check we are inside our length again in-case
330 * the name isn't fully qualified (ie, not terminated) */
331 while (q < e && (l = (size_t)*q++)) {
333 if (ltype == 0x80 || ltype == 0x40) {
334 /* Currently reserved for future use as noted
335 * in RFC1035 4.1.4 as the 10 and 01
340 else if (ltype == 0xc0) { /* pointer */
347 /* save source of first jump. */
361 /* straightforward name segment, add with '.' */
366 if (l > NS_MAXLABEL) {
386 /* Don't count the trailing NUL */
387 if (d_len > NS_MAXDNAME + 1) {
393 /* change last dot to space */
394 if (out && out != start)
400 /* change last space to zero terminator */
404 else if (start_len > 0)
408 /* Remove the trailing NUL */
412 return (ssize_t)o_len;
415 /* Check for a valid name as per RFC952 and RFC1123 section 2.1 */
417 valid_domainname(char *lbl, int type)
421 int start, len, errset;
423 if (lbl == NULL || *lbl == '\0') {
433 c = (unsigned char)*lbl++;
437 if (lbl - 1 == slbl) /* No space at start */
439 if (!(type & OT_ARRAY))
441 /* Skip to the next label */
456 if (((c == '-' || c == '_') &&
457 !start && *lbl != ' ' && *lbl != '\0') ||
460 if (++len > NS_MAXLABEL) {
474 /* At least one valid domain, return it */
482 * Prints a chunk of data to a string.
483 * PS_SHELL goes as it is these days, it's upto the target to validate it.
484 * PS_SAFE has all non ascii and non printables changes to escaped octal.
486 static const char hexchrs[] = "0123456789abcdef";
488 print_string(char *dst, size_t len, int type, const uint8_t *data, size_t dl)
501 if (type & OT_BINHEX) {
503 if (len == 0 || len == 1) {
507 *dst++ = hexchrs[(c & 0xF0) >> 4];
508 *dst++ = hexchrs[(c & 0x0F)];
514 if (type & OT_ASCII && (!isascii(c))) {
518 if (!(type & (OT_ASCII | OT_RAW | OT_ESCSTRING | OT_ESCFILE)) &&
519 (!isascii(c) && !isprint(c)))
524 if ((type & (OT_ESCSTRING | OT_ESCFILE) &&
525 (c == '\\' || !isascii(c) || !isprint(c))) ||
526 (type & OT_ESCFILE && (c == '/' || c == ' ')))
531 if (len == 0 || len == 1) {
535 *dst++ = '\\'; *dst++ = '\\';
547 *dst++ = (char)(((c >> 6) & 03) + '0');
548 *dst++ = (char)(((c >> 3) & 07) + '0');
549 *dst++ = (char)(( c & 07) + '0');
574 /* Now we've printed it, validate the domain */
575 if (type & OT_DOMAIN && !valid_domainname(odst, type)) {
582 return (ssize_t)bytes;
587 dhcp_optlen(const struct dhcp_opt *opt, size_t dl)
591 if (opt->type & OT_ADDRIPV6)
593 else if (opt->type & (OT_INT32 | OT_UINT32 | OT_ADDRIPV4))
594 sz = sizeof(uint32_t);
595 else if (opt->type & (OT_INT16 | OT_UINT16))
596 sz = sizeof(uint16_t);
597 else if (opt->type & (OT_INT8 | OT_UINT8 | OT_BITFLAG))
598 sz = sizeof(uint8_t);
599 else if (opt->type & OT_FLAG)
602 /* All other types are variable length */
604 if ((size_t)opt->len > dl) {
608 return (ssize_t)opt->len;
617 /* Trim any extra data.
618 * Maybe we need a setting to reject DHCP options with extra data? */
619 if (opt->type & OT_ARRAY)
620 return (ssize_t)(dl - (dl % sz));
625 print_option(FILE *fp, const char *prefix, const struct dhcp_opt *opt,
627 const uint8_t *data, size_t dl, const char *ifname)
630 const uint8_t *e, *t;
639 /* Ensure a valid length */
640 dl = (size_t)dhcp_optlen(opt, dl);
641 if ((ssize_t)dl == -1)
644 if (fgetpos(fp, &fp_pos) == -1)
646 if (fprintf(fp, "%s", prefix) == -1)
649 /* We printed something, so always goto err from now-on
650 * to terminate the string. */
652 if (fprintf(fp, "_%s", opt->var) == -1)
655 if (fputc('=', fp) == EOF)
660 if (opt->type & OT_RFC1035) {
661 char domain[NS_MAXDNAME];
663 sl = decode_rfc1035(domain, sizeof(domain), data, dl);
668 if (valid_domainname(domain, opt->type) == -1)
670 return efprintf(fp, "%s", domain);
674 if (opt->type & OT_RFC3361)
675 return print_rfc3361(fp, data, dl);
677 if (opt->type & OT_RFC3442)
678 return print_rfc3442(fp, data, dl);
681 if (opt->type & OT_STRING) {
684 if (print_string(buf, sizeof(buf), opt->type, data, dl) == -1)
686 return efprintf(fp, "%s", buf);
689 if (opt->type & OT_FLAG)
690 return efprintf(fp, "1");
692 if (opt->type & OT_BITFLAG) {
693 /* bitflags are a string, MSB first, such as ABCDEFGH
694 * where A is 10000000, B is 01000000, etc. */
695 for (l = 0, sl = sizeof(opt->bitflags) - 1;
696 l < sizeof(opt->bitflags);
699 /* Don't print NULL or 0 flags */
700 if (opt->bitflags[l] != '\0' &&
701 opt->bitflags[l] != '0' &&
704 if (fputc(opt->bitflags[l], fp) == EOF)
715 if (fputc(' ', fp) == EOF)
718 if (opt->type & OT_UINT8) {
719 if (fprintf(fp, "%u", *data) == -1)
722 } else if (opt->type & OT_INT8) {
723 if (fprintf(fp, "%d", *data) == -1)
726 } else if (opt->type & OT_UINT16) {
727 memcpy(&u16, data, sizeof(u16));
729 if (fprintf(fp, "%u", u16) == -1)
732 } else if (opt->type & OT_INT16) {
733 memcpy(&u16, data, sizeof(u16));
734 s16 = (int16_t)ntohs(u16);
735 if (fprintf(fp, "%d", s16) == -1)
738 } else if (opt->type & OT_UINT32) {
739 memcpy(&u32, data, sizeof(u32));
741 if (fprintf(fp, "%u", u32) == -1)
744 } else if (opt->type & OT_INT32) {
745 memcpy(&u32, data, sizeof(u32));
746 s32 = (int32_t)ntohl(u32);
747 if (fprintf(fp, "%d", s32) == -1)
750 } else if (opt->type & OT_ADDRIPV4) {
751 memcpy(&addr.s_addr, data, sizeof(addr.s_addr));
752 if (fprintf(fp, "%s", inet_ntoa(addr)) == -1)
754 data += sizeof(addr.s_addr);
755 } else if (opt->type & OT_ADDRIPV6) {
756 char buf[INET6_ADDRSTRLEN];
758 if (inet_ntop(AF_INET6, data, buf, sizeof(buf)) == NULL)
760 if (fprintf(fp, "%s", buf) == -1)
762 if (data[0] == 0xfe && (data[1] & 0xc0) == 0x80) {
763 if (fprintf(fp,"%%%s", ifname) == -1)
774 if (fputc('\0', fp) == EOF)
779 (void)fsetpos(fp, &fp_pos);
784 dhcp_set_leasefile(char *leasefile, size_t len, int family,
785 const struct interface *ifp)
787 char ssid[1 + (IF_SSIDLEN * 4) + 1]; /* - prefix and NUL terminated. */
789 if (ifp->name[0] == '\0') {
790 strlcpy(leasefile, ifp->ctx->pidfile, len);
805 print_string(ssid + 1, sizeof(ssid) - 1,
807 (const uint8_t *)ifp->ssid, ifp->ssid_len);
810 return snprintf(leasefile, len,
811 family == AF_INET ? LEASEFILE : LEASEFILE6,
816 dhcp_envoption(struct dhcpcd_ctx *ctx, FILE *fp, const char *prefix,
817 const char *ifname, struct dhcp_opt *opt,
818 const uint8_t *(*dgetopt)(struct dhcpcd_ctx *,
819 size_t *, unsigned int *, size_t *,
820 const uint8_t *, size_t, struct dhcp_opt **),
821 const uint8_t *od, size_t ol)
828 struct dhcp_opt *eopt, *oopt;
831 /* If no embedded or encapsulated options, it's easy */
832 if (opt->embopts_len == 0 && opt->encopts_len == 0) {
833 if (opt->type & OT_RESERVED)
835 if (print_option(fp, prefix, opt, 1, od, ol, ifname) == -1)
836 logerr("%s: %s %d", ifname, __func__, opt->option);
840 /* Create a new prefix based on the option */
841 if (opt->type & OT_INDEX) {
842 if (asprintf(&pfx, "%s_%s%d",
843 prefix, opt->var, ++opt->index) == -1)
846 if (asprintf(&pfx, "%s_%s", prefix, opt->var) == -1)
854 /* Embedded options are always processed first as that
855 * is a fixed layout */
856 for (i = 0, eopt = opt->embopts; i < opt->embopts_len; i++, eopt++) {
857 eo = dhcp_optlen(eopt, ol);
859 logerrx("%s: %s %d.%d/%zu: "
860 "malformed embedded option",
861 ifname, __func__, opt->option,
866 /* An option was expected, but there is no data
868 * This may not be an error as some options like
869 * DHCP FQDN in RFC4702 have a string as the last
870 * option which is optional. */
871 if (ol != 0 || !(eopt->type & OT_OPTIONAL))
872 logerrx("%s: %s %d.%d/%zu: "
873 "missing embedded option",
874 ifname, __func__, opt->option,
878 /* Use the option prefix if the embedded option
880 * This avoids new_fqdn_fqdn which would be silly. */
881 if (!(eopt->type & OT_RESERVED)) {
882 ov = strcmp(opt->var, eopt->var);
883 if (print_option(fp, pfx, eopt, ov, od, (size_t)eo,
885 logerr("%s: %s %d.%d/%zu",
887 opt->option, eopt->option, i);
893 /* Enumerate our encapsulated options */
894 if (opt->encopts_len && ol > 0) {
895 /* Zero any option indexes
896 * We assume that referenced encapsulated options are NEVER
897 * recursive as the index order could break. */
898 for (i = 0, eopt = opt->encopts;
899 i < opt->encopts_len;
903 if (eopt->type & OT_OPTION) {
904 dgetopt(ctx, NULL, &eoc, NULL, NULL, 0, &oopt);
910 while ((eod = dgetopt(ctx, &eos, &eoc, &eol, od, ol, &oopt))) {
911 for (i = 0, eopt = opt->encopts;
912 i < opt->encopts_len;
915 if (eopt->option != eoc)
917 if (eopt->type & OT_OPTION) {
922 dhcp_envoption(ctx, fp, pfx, ifname,
923 eopt->type & OT_OPTION ? oopt:eopt,
936 dhcp_zero_index(struct dhcp_opt *opt)
942 for (i = 0, o = opt->embopts; i < opt->embopts_len; i++, o++)
944 for (i = 0, o = opt->encopts; i < opt->encopts_len; i++, o++)
949 dhcp_readfile(struct dhcpcd_ctx *ctx, const char *file, void *data, size_t len)
953 if (ctx->options & DHCPCD_PRIVSEP &&
954 !(ctx->options & DHCPCD_PRIVSEPROOT))
955 return ps_root_readfile(ctx, file, data, len);
960 return readfile(file, data, len);
964 dhcp_writefile(struct dhcpcd_ctx *ctx, const char *file, mode_t mode,
965 const void *data, size_t len)
969 if (ctx->options & DHCPCD_PRIVSEP &&
970 !(ctx->options & DHCPCD_PRIVSEPROOT))
971 return ps_root_writefile(ctx, file, mode, data, len);
976 return writefile(file, mode, data, len);
980 dhcp_filemtime(struct dhcpcd_ctx *ctx, const char *file, time_t *time)
984 if (ctx->options & DHCPCD_PRIVSEP &&
985 !(ctx->options & DHCPCD_PRIVSEPROOT))
986 return (int)ps_root_filemtime(ctx, file, time);
991 return filemtime(file, time);
995 dhcp_unlink(struct dhcpcd_ctx *ctx, const char *file)
999 if (ctx->options & DHCPCD_PRIVSEP &&
1000 !(ctx->options & DHCPCD_PRIVSEPROOT))
1001 return (int)ps_root_unlink(ctx, file);
1006 return unlink(file);
1010 dhcp_read_hwaddr_aton(struct dhcpcd_ctx *ctx, uint8_t **data, const char *file)
1016 bytes = dhcp_readfile(ctx, file, buf, sizeof(buf));
1017 if (bytes == -1 || bytes == sizeof(buf))
1021 len = hwaddr_aton(NULL, buf);
1024 *data = malloc(len);
1027 hwaddr_aton(*data, buf);