1*8d36e1dfSRoy Marples /* SPDX-License-Identifier: BSD-2-Clause */ 27827cba2SAaron LI /* 37827cba2SAaron LI * dhcpcd - DHCP client daemon 4*8d36e1dfSRoy Marples * Copyright (c) 2006-2019 Roy Marples <roy@marples.name> 57827cba2SAaron LI * All rights reserved 67827cba2SAaron LI 77827cba2SAaron LI * Redistribution and use in source and binary forms, with or without 87827cba2SAaron LI * modification, are permitted provided that the following conditions 97827cba2SAaron LI * are met: 107827cba2SAaron LI * 1. Redistributions of source code must retain the above copyright 117827cba2SAaron LI * notice, this list of conditions and the following disclaimer. 127827cba2SAaron LI * 2. Redistributions in binary form must reproduce the above copyright 137827cba2SAaron LI * notice, this list of conditions and the following disclaimer in the 147827cba2SAaron LI * documentation and/or other materials provided with the distribution. 157827cba2SAaron LI * 167827cba2SAaron LI * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 177827cba2SAaron LI * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 187827cba2SAaron LI * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 197827cba2SAaron LI * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 207827cba2SAaron LI * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 217827cba2SAaron LI * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 227827cba2SAaron LI * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 237827cba2SAaron LI * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 247827cba2SAaron LI * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 257827cba2SAaron LI * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 267827cba2SAaron LI * SUCH DAMAGE. 277827cba2SAaron LI */ 287827cba2SAaron LI 297827cba2SAaron LI #include <sys/param.h> 307827cba2SAaron LI #include <sys/time.h> 317827cba2SAaron LI #ifdef __sun 327827cba2SAaron LI #include <sys/sysmacros.h> 337827cba2SAaron LI #endif 347827cba2SAaron LI 357827cba2SAaron LI #include <assert.h> 367827cba2SAaron LI #include <ctype.h> 377827cba2SAaron LI #include <err.h> 387827cba2SAaron LI #include <errno.h> 397827cba2SAaron LI #include <fcntl.h> 407827cba2SAaron LI #include <limits.h> 417827cba2SAaron LI #ifdef BSD 427827cba2SAaron LI # include <paths.h> 437827cba2SAaron LI #endif 447827cba2SAaron LI #include <stdarg.h> 457827cba2SAaron LI #include <stdint.h> 467827cba2SAaron LI #include <stdio.h> 477827cba2SAaron LI #include <stdlib.h> 487827cba2SAaron LI #include <string.h> 497827cba2SAaron LI #include <time.h> 507827cba2SAaron LI #include <unistd.h> 517827cba2SAaron LI 527827cba2SAaron LI #include "common.h" 537827cba2SAaron LI #include "dhcpcd.h" 547827cba2SAaron LI #include "if-options.h" 557827cba2SAaron LI #include "logerr.h" 567827cba2SAaron LI 577827cba2SAaron LI /* Most route(4) messages are less than 256 bytes. */ 587827cba2SAaron LI #define IOVEC_BUFSIZ 256 597827cba2SAaron LI 607827cba2SAaron LI const char * 617827cba2SAaron LI hwaddr_ntoa(const void *hwaddr, size_t hwlen, char *buf, size_t buflen) 627827cba2SAaron LI { 637827cba2SAaron LI const unsigned char *hp, *ep; 647827cba2SAaron LI char *p; 657827cba2SAaron LI 667827cba2SAaron LI if (buf == NULL) 677827cba2SAaron LI return NULL; 687827cba2SAaron LI 697827cba2SAaron LI if (hwlen * 3 > buflen) { 707827cba2SAaron LI errno = ENOBUFS; 717827cba2SAaron LI return NULL; 727827cba2SAaron LI } 737827cba2SAaron LI 747827cba2SAaron LI hp = hwaddr; 757827cba2SAaron LI ep = hp + hwlen; 767827cba2SAaron LI p = buf; 777827cba2SAaron LI 787827cba2SAaron LI while (hp < ep) { 797827cba2SAaron LI if (hp != hwaddr) 807827cba2SAaron LI *p ++= ':'; 817827cba2SAaron LI p += snprintf(p, 3, "%.2x", *hp++); 827827cba2SAaron LI } 837827cba2SAaron LI *p ++= '\0'; 847827cba2SAaron LI return buf; 857827cba2SAaron LI } 867827cba2SAaron LI 877827cba2SAaron LI size_t 887827cba2SAaron LI hwaddr_aton(uint8_t *buffer, const char *addr) 897827cba2SAaron LI { 907827cba2SAaron LI char c[3]; 917827cba2SAaron LI const char *p = addr; 927827cba2SAaron LI uint8_t *bp = buffer; 937827cba2SAaron LI size_t len = 0; 947827cba2SAaron LI 957827cba2SAaron LI c[2] = '\0'; 967827cba2SAaron LI while (*p != '\0') { 977827cba2SAaron LI /* Skip separators */ 987827cba2SAaron LI c[0] = *p++; 997827cba2SAaron LI switch (c[0]) { 1007827cba2SAaron LI case '\n': /* long duid split on lines */ 1017827cba2SAaron LI case ':': /* typical mac address */ 1027827cba2SAaron LI case '-': /* uuid */ 1037827cba2SAaron LI continue; 1047827cba2SAaron LI } 1057827cba2SAaron LI c[1] = *p++; 1067827cba2SAaron LI /* Ensure that digits are hex */ 1077827cba2SAaron LI if (isxdigit((unsigned char)c[0]) == 0 || 1087827cba2SAaron LI isxdigit((unsigned char)c[1]) == 0) 1097827cba2SAaron LI { 1107827cba2SAaron LI errno = EINVAL; 1117827cba2SAaron LI return 0; 1127827cba2SAaron LI } 1137827cba2SAaron LI /* We should have at least two entries 00:01 */ 1147827cba2SAaron LI if (len == 0 && *p == '\0') { 1157827cba2SAaron LI errno = EINVAL; 1167827cba2SAaron LI return 0; 1177827cba2SAaron LI } 1187827cba2SAaron LI if (bp) 1197827cba2SAaron LI *bp++ = (uint8_t)strtol(c, NULL, 16); 1207827cba2SAaron LI len++; 1217827cba2SAaron LI } 1227827cba2SAaron LI return len; 1237827cba2SAaron LI } 1247827cba2SAaron LI 1257827cba2SAaron LI size_t 1267827cba2SAaron LI read_hwaddr_aton(uint8_t **data, const char *path) 1277827cba2SAaron LI { 1287827cba2SAaron LI FILE *fp; 1297827cba2SAaron LI char *buf; 1307827cba2SAaron LI size_t buf_len, len; 1317827cba2SAaron LI 1327827cba2SAaron LI if ((fp = fopen(path, "r")) == NULL) 1337827cba2SAaron LI return 0; 1347827cba2SAaron LI 1357827cba2SAaron LI buf = NULL; 1367827cba2SAaron LI buf_len = len = 0; 1377827cba2SAaron LI *data = NULL; 1387827cba2SAaron LI while (getline(&buf, &buf_len, fp) != -1) { 1397827cba2SAaron LI if ((len = hwaddr_aton(NULL, buf)) != 0) { 1407827cba2SAaron LI if (buf_len >= len) 1417827cba2SAaron LI *data = (uint8_t *)buf; 1427827cba2SAaron LI else { 1437827cba2SAaron LI if ((*data = malloc(len)) == NULL) 1447827cba2SAaron LI len = 0; 1457827cba2SAaron LI } 1467827cba2SAaron LI if (len != 0) 1477827cba2SAaron LI (void)hwaddr_aton(*data, buf); 1487827cba2SAaron LI if (buf_len < len) 1497827cba2SAaron LI free(buf); 1507827cba2SAaron LI break; 1517827cba2SAaron LI } 1527827cba2SAaron LI } 1537827cba2SAaron LI fclose(fp); 1547827cba2SAaron LI return len; 1557827cba2SAaron LI } 156