xref: /dragonfly/contrib/dhcpcd/src/common.c (revision dda92f98)
1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3  * dhcpcd - DHCP client daemon
4  * Copyright (c) 2006-2020 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 const char *
42 hwaddr_ntoa(const void *hwaddr, size_t hwlen, char *buf, size_t buflen)
43 {
44 	const unsigned char *hp, *ep;
45 	char *p;
46 
47 	if (buf == NULL)
48 		return NULL;
49 
50 	if (hwlen * 3 > buflen) {
51 		errno = ENOBUFS;
52 		return NULL;
53 	}
54 
55 	hp = hwaddr;
56 	ep = hp + hwlen;
57 	p = buf;
58 
59 	while (hp < ep) {
60 		if (hp != hwaddr)
61 			*p ++= ':';
62 		p += snprintf(p, 3, "%.2x", *hp++);
63 	}
64 	*p ++= '\0';
65 	return buf;
66 }
67 
68 size_t
69 hwaddr_aton(uint8_t *buffer, const char *addr)
70 {
71 	char c[3];
72 	const char *p = addr;
73 	uint8_t *bp = buffer;
74 	size_t len = 0;
75 
76 	c[2] = '\0';
77 	while (*p != '\0') {
78 		/* Skip separators */
79 		c[0] = *p++;
80 		switch (c[0]) {
81 		case '\n':	/* long duid split on lines */
82 		case ':':	/* typical mac address */
83 		case '-':	/* uuid */
84 			continue;
85 		}
86 		c[1] = *p++;
87 		/* Ensure that digits are hex */
88 		if (isxdigit((unsigned char)c[0]) == 0 ||
89 		    isxdigit((unsigned char)c[1]) == 0)
90 		{
91 			errno = EINVAL;
92 			return 0;
93 		}
94 		/* We should have at least two entries 00:01 */
95 		if (len == 0 && *p == '\0') {
96 			errno = EINVAL;
97 			return 0;
98 		}
99 		if (bp)
100 			*bp++ = (uint8_t)strtol(c, NULL, 16);
101 		len++;
102 	}
103 	return len;
104 }
105 
106 size_t
107 read_hwaddr_aton(uint8_t **data, const char *path)
108 {
109 	FILE *fp;
110 	char *buf;
111 	size_t buf_len, len;
112 
113 	if ((fp = fopen(path, "r")) == NULL)
114 		return 0;
115 
116 	buf = NULL;
117 	buf_len = len = 0;
118 	*data = NULL;
119 	while (getline(&buf, &buf_len, fp) != -1) {
120 		if ((len = hwaddr_aton(NULL, buf)) != 0) {
121 			if (buf_len >= len)
122 				*data = (uint8_t *)buf;
123 			else {
124 				if ((*data = malloc(len)) == NULL)
125 					len = 0;
126 			}
127 			if (len != 0)
128 				(void)hwaddr_aton(*data, buf);
129 			if (buf_len < len)
130 				free(buf);
131 			break;
132 		}
133 	}
134 	fclose(fp);
135 	return len;
136 }
137 
138 int
139 is_root_local(void)
140 {
141 #ifdef ST_LOCAL
142 	struct statvfs vfs;
143 
144 	if (statvfs("/", &vfs) == -1)
145 		return -1;
146 	return vfs.f_flag & ST_LOCAL ? 1 : 0;
147 #else
148 	errno = ENOTSUP;
149 	return -1;
150 #endif
151 }
152