xref: /dragonfly/contrib/dhcpcd/src/common.c (revision 8e11cefe)
1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3  * dhcpcd - DHCP client daemon
4  * Copyright (c) 2006-2019 Roy Marples <roy@marples.name>
5  * All rights reserved
6 
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
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.
15  *
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
26  * SUCH DAMAGE.
27  */
28 
29 #include <sys/statvfs.h>
30 
31 #include <ctype.h>
32 #include <errno.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 
36 #include "common.h"
37 #include "dhcpcd.h"
38 #include "if-options.h"
39 #include "logerr.h"
40 
41 /* Most route(4) messages are less than 256 bytes. */
42 #define IOVEC_BUFSIZ	256
43 
44 const char *
45 hwaddr_ntoa(const void *hwaddr, size_t hwlen, char *buf, size_t buflen)
46 {
47 	const unsigned char *hp, *ep;
48 	char *p;
49 
50 	if (buf == NULL)
51 		return NULL;
52 
53 	if (hwlen * 3 > buflen) {
54 		errno = ENOBUFS;
55 		return NULL;
56 	}
57 
58 	hp = hwaddr;
59 	ep = hp + hwlen;
60 	p = buf;
61 
62 	while (hp < ep) {
63 		if (hp != hwaddr)
64 			*p ++= ':';
65 		p += snprintf(p, 3, "%.2x", *hp++);
66 	}
67 	*p ++= '\0';
68 	return buf;
69 }
70 
71 size_t
72 hwaddr_aton(uint8_t *buffer, const char *addr)
73 {
74 	char c[3];
75 	const char *p = addr;
76 	uint8_t *bp = buffer;
77 	size_t len = 0;
78 
79 	c[2] = '\0';
80 	while (*p != '\0') {
81 		/* Skip separators */
82 		c[0] = *p++;
83 		switch (c[0]) {
84 		case '\n':	/* long duid split on lines */
85 		case ':':	/* typical mac address */
86 		case '-':	/* uuid */
87 			continue;
88 		}
89 		c[1] = *p++;
90 		/* Ensure that digits are hex */
91 		if (isxdigit((unsigned char)c[0]) == 0 ||
92 		    isxdigit((unsigned char)c[1]) == 0)
93 		{
94 			errno = EINVAL;
95 			return 0;
96 		}
97 		/* We should have at least two entries 00:01 */
98 		if (len == 0 && *p == '\0') {
99 			errno = EINVAL;
100 			return 0;
101 		}
102 		if (bp)
103 			*bp++ = (uint8_t)strtol(c, NULL, 16);
104 		len++;
105 	}
106 	return len;
107 }
108 
109 size_t
110 read_hwaddr_aton(uint8_t **data, const char *path)
111 {
112 	FILE *fp;
113 	char *buf;
114 	size_t buf_len, len;
115 
116 	if ((fp = fopen(path, "r")) == NULL)
117 		return 0;
118 
119 	buf = NULL;
120 	buf_len = len = 0;
121 	*data = NULL;
122 	while (getline(&buf, &buf_len, fp) != -1) {
123 		if ((len = hwaddr_aton(NULL, buf)) != 0) {
124 			if (buf_len >= len)
125 				*data = (uint8_t *)buf;
126 			else {
127 				if ((*data = malloc(len)) == NULL)
128 					len = 0;
129 			}
130 			if (len != 0)
131 				(void)hwaddr_aton(*data, buf);
132 			if (buf_len < len)
133 				free(buf);
134 			break;
135 		}
136 	}
137 	fclose(fp);
138 	return len;
139 }
140 
141 int
142 is_root_local(void)
143 {
144 #ifdef ST_LOCAL
145 	struct statvfs vfs;
146 
147 	if (statvfs("/", &vfs) == -1)
148 		return -1;
149 	return vfs.f_flag & ST_LOCAL ? 1 : 0;
150 #else
151 	errno = ENOTSUP;
152 	return -1;
153 #endif
154 }
155