1e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt/* 2e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * dhcpcd - DHCP client daemon 3a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt * Copyright (c) 2006-2012 Roy Marples <roy@marples.name> 4e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * All rights reserved 5e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 6e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * Redistribution and use in source and binary forms, with or without 7e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * modification, are permitted provided that the following conditions 8e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * are met: 9e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * 1. Redistributions of source code must retain the above copyright 10e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * notice, this list of conditions and the following disclaimer. 11e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * 2. Redistributions in binary form must reproduce the above copyright 12e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * notice, this list of conditions and the following disclaimer in the 13e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * documentation and/or other materials provided with the distribution. 14e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * 15e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * SUCH DAMAGE. 26e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt */ 27e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 28e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <sys/types.h> 29e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <sys/utsname.h> 30e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 31e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <arpa/inet.h> 32e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 33e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <ctype.h> 34e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <errno.h> 35e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <getopt.h> 36e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <paths.h> 37e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <stdio.h> 38e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <stdlib.h> 39e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <string.h> 40e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <syslog.h> 41e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <unistd.h> 42e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <time.h> 43e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 44e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "config.h" 45e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "common.h" 46e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "if-options.h" 47e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "net.h" 48e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "platform.h" 49e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 50e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt/* These options only make sense in the config file, so don't use any 51e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt valid short options for them */ 52e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#define O_BASE MAX('z', 'Z') + 1 53e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#define O_ARPING O_BASE + 1 54e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#define O_FALLBACK O_BASE + 2 55e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#define O_DESTINATION O_BASE + 3 56a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt#define O_NOIPV6RS O_BASE + 4 57a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt#define O_IPV6_RA_FORK O_BASE + 5 58e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 59e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtconst struct option cf_options[] = { 60e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"background", no_argument, NULL, 'b'}, 61e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"script", required_argument, NULL, 'c'}, 62e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"debug", no_argument, NULL, 'd'}, 63e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"env", required_argument, NULL, 'e'}, 64e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"config", required_argument, NULL, 'f'}, 65e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"reconfigure", no_argument, NULL, 'g'}, 66e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"hostname", optional_argument, NULL, 'h'}, 67e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"vendorclassid", optional_argument, NULL, 'i'}, 68e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"release", no_argument, NULL, 'k'}, 69e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"leasetime", required_argument, NULL, 'l'}, 70e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"metric", required_argument, NULL, 'm'}, 71e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"rebind", no_argument, NULL, 'n'}, 72e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"option", required_argument, NULL, 'o'}, 73e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"persistent", no_argument, NULL, 'p'}, 74e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"quiet", no_argument, NULL, 'q'}, 75e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"request", optional_argument, NULL, 'r'}, 76e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"inform", optional_argument, NULL, 's'}, 77e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"timeout", required_argument, NULL, 't'}, 78e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"userclass", required_argument, NULL, 'u'}, 79e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"vendor", required_argument, NULL, 'v'}, 80e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"waitip", no_argument, NULL, 'w'}, 81e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"exit", no_argument, NULL, 'x'}, 82e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"allowinterfaces", required_argument, NULL, 'z'}, 83e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"reboot", required_argument, NULL, 'y'}, 84e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"noarp", no_argument, NULL, 'A'}, 85e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"nobackground", no_argument, NULL, 'B'}, 86e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"nohook", required_argument, NULL, 'C'}, 87e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"duid", no_argument, NULL, 'D'}, 88e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"lastlease", no_argument, NULL, 'E'}, 89e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"fqdn", optional_argument, NULL, 'F'}, 90e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"nogateway", no_argument, NULL, 'G'}, 91e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"xidhwaddr", no_argument, NULL, 'H'}, 92e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"clientid", optional_argument, NULL, 'I'}, 93e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"broadcast", no_argument, NULL, 'J'}, 94e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"nolink", no_argument, NULL, 'K'}, 95e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"noipv4ll", no_argument, NULL, 'L'}, 96e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"nooption", optional_argument, NULL, 'O'}, 97e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"require", required_argument, NULL, 'Q'}, 98e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"static", required_argument, NULL, 'S'}, 99e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"test", no_argument, NULL, 'T'}, 100e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"dumplease", no_argument, NULL, 'U'}, 101e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"variables", no_argument, NULL, 'V'}, 102e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"whitelist", required_argument, NULL, 'W'}, 103e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"blacklist", required_argument, NULL, 'X'}, 104e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"denyinterfaces", required_argument, NULL, 'Z'}, 105e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"arping", required_argument, NULL, O_ARPING}, 106e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"destination", required_argument, NULL, O_DESTINATION}, 107e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {"fallback", required_argument, NULL, O_FALLBACK}, 108a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt {"noipv6rs", no_argument, NULL, O_NOIPV6RS}, 109a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt {"ipv6ra_fork", no_argument, NULL, O_IPV6_RA_FORK}, 110e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt {NULL, 0, NULL, '\0'} 111e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt}; 112e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 113e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatic int 114e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtatoint(const char *s) 115e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 116e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt char *t; 117e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt long n; 118e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 119e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt errno = 0; 120e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt n = strtol(s, &t, 0); 121e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if ((errno != 0 && n == 0) || s == t || 122e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt (errno == ERANGE && (n == LONG_MAX || n == LONG_MIN))) 123e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt { 124e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt syslog(LOG_ERR, "`%s' out of range", s); 125e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 126e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 127e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 128e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return (int)n; 129e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 130e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 131e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatic char * 132e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtadd_environ(struct if_options *ifo, const char *value, int uniq) 133e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 134e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt char **newlist; 135e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt char **lst = ifo->environ; 136e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt size_t i = 0, l, lv; 137e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt char *match = NULL, *p; 138e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 139e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt match = xstrdup(value); 140e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt p = strchr(match, '='); 141e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (p) 142e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt *p++ = '\0'; 143e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt l = strlen(match); 144e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 145e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt while (lst && lst[i]) { 146e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (match && strncmp(lst[i], match, l) == 0) { 147e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (uniq) { 148e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt free(lst[i]); 149e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt lst[i] = xstrdup(value); 150e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } else { 151e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* Append a space and the value to it */ 152e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt l = strlen(lst[i]); 153e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt lv = strlen(p); 154e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt lst[i] = xrealloc(lst[i], l + lv + 2); 155e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt lst[i][l] = ' '; 156e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt memcpy(lst[i] + l + 1, p, lv); 157e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt lst[i][l + lv + 1] = '\0'; 158e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 159e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt free(match); 160e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return lst[i]; 161e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 162e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt i++; 163e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 164e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 165e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt newlist = xrealloc(lst, sizeof(char *) * (i + 2)); 166e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt newlist[i] = xstrdup(value); 167e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt newlist[i + 1] = NULL; 168e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->environ = newlist; 169e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt free(match); 170e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return newlist[i]; 171e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 172e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 173e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#define parse_string(buf, len, arg) parse_string_hwaddr(buf, len, arg, 0) 174e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatic ssize_t 175e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtparse_string_hwaddr(char *sbuf, ssize_t slen, const char *str, int clid) 176e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 177e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ssize_t l; 178e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt const char *p; 179e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt int i, punt_last = 0; 180e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt char c[4]; 181e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 182e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* If surrounded by quotes then it's a string */ 183e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (*str == '"') { 184e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt str++; 185e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt l = strlen(str); 186e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt p = str + l - 1; 187e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (*p == '"') 188e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt punt_last = 1; 189e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } else { 190e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt l = hwaddr_aton(NULL, str); 191e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (l > 1) { 192e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (l > slen) { 193e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt errno = ENOBUFS; 194e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 195e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 196e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt hwaddr_aton((uint8_t *)sbuf, str); 197e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return l; 198e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 199e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 200e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 201e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* Process escapes */ 202e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt l = 0; 203e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* If processing a string on the clientid, first byte should be 204e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * 0 to indicate a non hardware type */ 205e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (clid && *str) { 206e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt *sbuf++ = 0; 207e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt l++; 208e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 209e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt c[3] = '\0'; 210e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt while (*str) { 211e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (++l > slen) { 212e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt errno = ENOBUFS; 213e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 214e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 215e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (*str == '\\') { 216e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt str++; 217e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt switch(*str) { 218e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case '\0': 219e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 220e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'b': 221e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt *sbuf++ = '\b'; 222e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt str++; 223e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 224e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'n': 225e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt *sbuf++ = '\n'; 226e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt str++; 227e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 228e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'r': 229e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt *sbuf++ = '\r'; 230e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt str++; 231e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 232e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 't': 233e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt *sbuf++ = '\t'; 234e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt str++; 235e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 236e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'x': 237e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* Grab a hex code */ 238e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt c[1] = '\0'; 239e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt for (i = 0; i < 2; i++) { 240e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (isxdigit((unsigned char)*str) == 0) 241e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 242e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt c[i] = *str++; 243e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 244e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (c[1] != '\0') { 245e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt c[2] = '\0'; 246e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt *sbuf++ = strtol(c, NULL, 16); 247e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } else 248e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt l--; 249e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 250e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case '0': 251e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* Grab an octal code */ 252e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt c[2] = '\0'; 253e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt for (i = 0; i < 3; i++) { 254e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (*str < '0' || *str > '7') 255e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 256e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt c[i] = *str++; 257e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 258e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (c[2] != '\0') { 259e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt i = strtol(c, NULL, 8); 260e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (i > 255) 261e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt i = 255; 262e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt *sbuf ++= i; 263e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } else 264e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt l--; 265e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 266e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt default: 267e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt *sbuf++ = *str++; 268e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 269e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } else 270e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt *sbuf++ = *str++; 271e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 272e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (punt_last) { 273e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt *--sbuf = '\0'; 274e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt l--; 275e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 276e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return l; 277e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 278e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 279e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatic char ** 280e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtsplitv(int *argc, char **argv, const char *arg) 281e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 282e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt char **v = argv; 283e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt char *o = xstrdup(arg), *p, *t; 284e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 285e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt p = o; 286e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt while ((t = strsep(&p, ", "))) { 287e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt (*argc)++; 288e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt v = xrealloc(v, sizeof(char *) * ((*argc))); 289e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt v[(*argc) - 1] = xstrdup(t); 290e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 291e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt free(o); 292e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return v; 293e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 294e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 295e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatic int 296e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtparse_addr(struct in_addr *addr, struct in_addr *net, const char *arg) 297e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 298e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt char *p; 299e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt int i; 300e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 301e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (arg == NULL || *arg == '\0') { 302e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (addr != NULL) 303e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt addr->s_addr = 0; 304e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (net != NULL) 305e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt net->s_addr = 0; 306e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return 0; 307e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 308e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if ((p = strchr(arg, '/')) != NULL) { 309e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt *p++ = '\0'; 310e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (net != NULL && 311e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt (sscanf(p, "%d", &i) != 1 || 312e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt inet_cidrtoaddr(i, net) != 0)) 313e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt { 314e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt syslog(LOG_ERR, "`%s' is not a valid CIDR", p); 315e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 316e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 317e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 318e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 319e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (addr != NULL && inet_aton(arg, addr) == 0) { 320e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt syslog(LOG_ERR, "`%s' is not a valid IP address", arg); 321e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 322e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 323e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (p != NULL) 324e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt *--p = '/'; 325e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt else if (net != NULL) 326e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt net->s_addr = get_netmask(addr->s_addr); 327e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return 0; 328e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 329e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 330e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatic int 331e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtparse_option(struct if_options *ifo, int opt, const char *arg) 332e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 333e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt int i; 334e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt char *p = NULL, *np; 335e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ssize_t s; 336e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct in_addr addr, addr2; 337e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct rt *rt; 338e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 339e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt switch(opt) { 3400d3a47d979ac35a49b2a2da9e80e16bd37aab877repo sync case 'a': /* FALLTHROUGH */ 341e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'f': /* FALLTHROUGH */ 342e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'g': /* FALLTHROUGH */ 343e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'n': /* FALLTHROUGH */ 344e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'x': /* FALLTHROUGH */ 345e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'T': /* FALLTHROUGH */ 346e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'U': /* We need to handle non interface options */ 347e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 348e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'b': 349e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->options |= DHCPCD_BACKGROUND; 350e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 351e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'c': 352e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt strlcpy(ifo->script, arg, sizeof(ifo->script)); 353e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 354e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'd': 355e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->options |= DHCPCD_DEBUG; 356e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 357e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'e': 358e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt add_environ(ifo, arg, 1); 359e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 360e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'h': 361e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (arg) { 362e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt s = parse_string(ifo->hostname, 363e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt HOSTNAME_MAX_LEN, arg); 364e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (s == -1) { 365e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt syslog(LOG_ERR, "hostname: %m"); 366e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 367e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 368e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (s != 0 && ifo->hostname[0] == '.') { 369e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt syslog(LOG_ERR, 370e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt "hostname cannot begin with ."); 371e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 372e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 373e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->hostname[s] = '\0'; 374e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 375e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (ifo->hostname[0] == '\0') 376e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->options &= ~DHCPCD_HOSTNAME; 377e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt else 378e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->options |= DHCPCD_HOSTNAME; 379e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 380e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'i': 381e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (arg) 382e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt s = parse_string((char *)ifo->vendorclassid + 1, 383e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt VENDORCLASSID_MAX_LEN, arg); 384e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt else 385e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt s = 0; 386e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (s == -1) { 387e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt syslog(LOG_ERR, "vendorclassid: %m"); 388e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 389e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 390e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt *ifo->vendorclassid = (uint8_t)s; 391e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 392e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'k': 393e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->options |= DHCPCD_RELEASE; 394e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 395e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'l': 396e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (*arg == '-') { 397e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt syslog(LOG_ERR, 398e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt "leasetime must be a positive value"); 399e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 400e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 401e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt errno = 0; 402e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->leasetime = (uint32_t)strtol(arg, NULL, 0); 403e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (errno == EINVAL || errno == ERANGE) { 404e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt syslog(LOG_ERR, "`%s' out of range", arg); 405e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 406e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 407e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 408e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'm': 409e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->metric = atoint(arg); 410e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (ifo->metric < 0) { 411e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt syslog(LOG_ERR, "metric must be a positive value"); 412e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 413e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 414e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 415e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'o': 416e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (make_option_mask(ifo->requestmask, arg, 1) != 0) { 417e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt syslog(LOG_ERR, "unknown option `%s'", arg); 418e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 419e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 420e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 421e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'p': 422e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->options |= DHCPCD_PERSISTENT; 423e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 424e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'q': 425e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->options |= DHCPCD_QUIET; 426e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 427e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'r': 428e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (parse_addr(&ifo->req_addr, NULL, arg) != 0) 429e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 430e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->options |= DHCPCD_REQUEST; 431e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->req_mask.s_addr = 0; 432e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 433e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 's': 434e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (arg && *arg != '\0') { 435e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (parse_addr(&ifo->req_addr, &ifo->req_mask, 436e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt arg) != 0) 437e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 438e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } else { 439e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->req_addr.s_addr = 0; 440e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->req_mask.s_addr = 0; 441e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 442e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->options |= DHCPCD_INFORM | DHCPCD_PERSISTENT; 443e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->options &= ~(DHCPCD_ARP | DHCPCD_STATIC); 444e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 445e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 't': 446e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->timeout = atoint(arg); 447e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (ifo->timeout < 0) { 448e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt syslog(LOG_ERR, "timeout must be a positive value"); 449e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 450e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 451e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 452e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'u': 453e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt s = USERCLASS_MAX_LEN - ifo->userclass[0] - 1; 454e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt s = parse_string((char *)ifo->userclass + 455e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->userclass[0] + 2, 456e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt s, arg); 457e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (s == -1) { 458e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt syslog(LOG_ERR, "userclass: %m"); 459e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 460e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 461e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (s != 0) { 462e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->userclass[ifo->userclass[0] + 1] = s; 463e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->userclass[0] += s + 1; 464e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 465e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 466e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'v': 467e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt p = strchr(arg, ','); 468e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (!p || !p[1]) { 469e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt syslog(LOG_ERR, "invalid vendor format"); 470e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 471e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 472e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 473e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* If vendor starts with , then it is not encapsulated */ 474e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (p == arg) { 475e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt arg++; 476e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt s = parse_string((char *)ifo->vendor + 1, 477e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt VENDOR_MAX_LEN, arg); 478e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (s == -1) { 479e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt syslog(LOG_ERR, "vendor: %m"); 480e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 481e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 482e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->vendor[0] = (uint8_t)s; 483e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->options |= DHCPCD_VENDORRAW; 484e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 485e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 486e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 487e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* Encapsulated vendor options */ 488e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (ifo->options & DHCPCD_VENDORRAW) { 489e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->options &= ~DHCPCD_VENDORRAW; 490e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->vendor[0] = 0; 491e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 492e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 493e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt *p = '\0'; 494e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt i = atoint(arg); 495e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt arg = p + 1; 496e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (i < 1 || i > 254) { 497e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt syslog(LOG_ERR, "vendor option should be between" 498e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt " 1 and 254 inclusive"); 499e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 500e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 501e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt s = VENDOR_MAX_LEN - ifo->vendor[0] - 2; 502e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (inet_aton(arg, &addr) == 1) { 503e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (s < 6) { 504e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt s = -1; 505e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt errno = ENOBUFS; 506e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } else 507e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt memcpy(ifo->vendor + ifo->vendor[0] + 3, 508e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt &addr.s_addr, sizeof(addr.s_addr)); 509e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } else { 510e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt s = parse_string((char *)ifo->vendor + 511e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->vendor[0] + 3, s, arg); 512e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 513e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (s == -1) { 514e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt syslog(LOG_ERR, "vendor: %m"); 515e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 516e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 517e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (s != 0) { 518e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->vendor[ifo->vendor[0] + 1] = i; 519e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->vendor[ifo->vendor[0] + 2] = s; 520e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->vendor[0] += s + 2; 521e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 522e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 523e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'w': 524e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->options |= DHCPCD_WAITIP; 525e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 526e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'y': 527e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->reboot = atoint(arg); 528e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (ifo->reboot < 0) { 529e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt syslog(LOG_ERR, "reboot must be a positive value"); 530e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 531e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 532e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 533e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'z': 534e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifav = splitv(&ifac, ifav, arg); 535e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 536e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'A': 537e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->options &= ~DHCPCD_ARP; 538e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* IPv4LL requires ARP */ 539e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->options &= ~DHCPCD_IPV4LL; 540e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 541e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'B': 542e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->options &= ~DHCPCD_DAEMONISE; 543e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 544e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'C': 545e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* Commas to spaces for shell */ 546e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt while ((p = strchr(arg, ','))) 547e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt *p = ' '; 548e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt s = strlen("skip_hooks=") + strlen(arg) + 1; 549e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt p = xmalloc(sizeof(char) * s); 550e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt snprintf(p, s, "skip_hooks=%s", arg); 551e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt add_environ(ifo, p, 0); 552e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt free(p); 553e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 554e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'D': 555e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->options |= DHCPCD_CLIENTID | DHCPCD_DUID; 556e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 557e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'E': 558e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->options |= DHCPCD_LASTLEASE; 559e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 560e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'F': 561e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (!arg) { 562e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->fqdn = FQDN_BOTH; 563e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 564e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 565e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (strcmp(arg, "none") == 0) 566e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->fqdn = FQDN_NONE; 567e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt else if (strcmp(arg, "ptr") == 0) 568e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->fqdn = FQDN_PTR; 569e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt else if (strcmp(arg, "both") == 0) 570e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->fqdn = FQDN_BOTH; 571e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt else if (strcmp(arg, "disable") == 0) 572e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->fqdn = FQDN_DISABLE; 573e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt else { 574e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt syslog(LOG_ERR, "invalid value `%s' for FQDN", arg); 575e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 576e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 577e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 578e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'G': 579e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->options &= ~DHCPCD_GATEWAY; 580e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 581e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'H': 582e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->options |= DHCPCD_XID_HWADDR; 583e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 584e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'I': 585e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* Strings have a type of 0 */; 586e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->clientid[1] = 0; 587e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (arg) 588e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt s = parse_string_hwaddr((char *)ifo->clientid + 1, 589e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt CLIENTID_MAX_LEN, arg, 1); 590e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt else 591e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt s = 0; 592e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (s == -1) { 593e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt syslog(LOG_ERR, "clientid: %m"); 594e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 595e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 596e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->options |= DHCPCD_CLIENTID; 597e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->clientid[0] = (uint8_t)s; 598e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 599e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'J': 600e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->options |= DHCPCD_BROADCAST; 601e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 602e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'K': 603e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->options &= ~DHCPCD_LINK; 604e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 605e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'L': 606e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->options &= ~DHCPCD_IPV4LL; 607e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 608e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'O': 609e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (make_option_mask(ifo->requestmask, arg, -1) != 0 || 610e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt make_option_mask(ifo->requiremask, arg, -1) != 0 || 611e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt make_option_mask(ifo->nomask, arg, 1) != 0) 612e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt { 613e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt syslog(LOG_ERR, "unknown option `%s'", arg); 614e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 615e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 616e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 617e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'Q': 618e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (make_option_mask(ifo->requiremask, arg, 1) != 0 || 619e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt make_option_mask(ifo->requestmask, arg, 1) != 0) 620e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt { 621e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt syslog(LOG_ERR, "unknown option `%s'", arg); 622e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 623e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 624e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 625e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'S': 626e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt p = strchr(arg, '='); 627e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (p == NULL) { 628e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt syslog(LOG_ERR, "static assignment required"); 629e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 630e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 631e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt p++; 632e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (strncmp(arg, "ip_address=", strlen("ip_address=")) == 0) { 633a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt if (parse_addr(&ifo->req_addr, 634a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt ifo->req_mask.s_addr == 0 ? &ifo->req_mask : NULL, 635a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt p) != 0) 636e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 637e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 638e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->options |= DHCPCD_STATIC; 639e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->options &= ~DHCPCD_INFORM; 640a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt } else if (strncmp(arg, "subnet_mask=", strlen("subnet_mask=")) == 0) { 641a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt if (parse_addr(&ifo->req_mask, NULL, p) != 0) 642a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt return -1; 643e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } else if (strncmp(arg, "routes=", strlen("routes=")) == 0 || 644e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt strncmp(arg, "static_routes=", strlen("static_routes=")) == 0 || 645e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt strncmp(arg, "classless_static_routes=", strlen("classless_static_routes=")) == 0 || 646e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt strncmp(arg, "ms_classless_static_routes=", strlen("ms_classless_static_routes=")) == 0) 647e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt { 648e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt np = strchr(p, ' '); 649e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (np == NULL) { 650e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt syslog(LOG_ERR, "all routes need a gateway"); 651e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 652e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 653e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt *np++ = '\0'; 654e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt while (*np == ' ') 655e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt np++; 656e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (ifo->routes == NULL) { 657e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt rt = ifo->routes = xmalloc(sizeof(*rt)); 658e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } else { 659e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt rt = ifo->routes; 660e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt while (rt->next) 661e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt rt = rt->next; 662e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt rt->next = xmalloc(sizeof(*rt)); 663e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt rt = rt->next; 664e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 665e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt rt->next = NULL; 666e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (parse_addr(&rt->dest, &rt->net, p) == -1 || 667e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt parse_addr(&rt->gate, NULL, np) == -1) 668e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 669e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } else if (strncmp(arg, "routers=", strlen("routers=")) == 0) { 670e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (ifo->routes == NULL) { 671e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt rt = ifo->routes = xzalloc(sizeof(*rt)); 672e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } else { 673e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt rt = ifo->routes; 674e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt while (rt->next) 675e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt rt = rt->next; 676e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt rt->next = xmalloc(sizeof(*rt)); 677e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt rt = rt->next; 678e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 679e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt rt->dest.s_addr = INADDR_ANY; 680e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt rt->net.s_addr = INADDR_ANY; 681e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt rt->next = NULL; 682e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (parse_addr(&rt->gate, NULL, p) == -1) 683e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 684e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } else { 685e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt s = 0; 686e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (ifo->config != NULL) { 687e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt while (ifo->config[s] != NULL) { 688e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (strncmp(ifo->config[s], arg, 689e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt p - arg) == 0) 690e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt { 691e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt free(ifo->config[s]); 692e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->config[s] = xstrdup(arg); 693e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return 1; 694e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 695e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt s++; 696e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 697e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 698e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->config = xrealloc(ifo->config, 699e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt sizeof(char *) * (s + 2)); 700e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->config[s] = xstrdup(arg); 701e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->config[s + 1] = NULL; 702e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 703e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 704e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'W': 705e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (parse_addr(&addr, &addr2, arg) != 0) 706e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 707e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (strchr(arg, '/') == NULL) 708e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt addr2.s_addr = INADDR_BROADCAST; 709e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->whitelist = xrealloc(ifo->whitelist, 710e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt sizeof(in_addr_t) * (ifo->whitelist_len + 2)); 711e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->whitelist[ifo->whitelist_len++] = addr.s_addr; 712e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->whitelist[ifo->whitelist_len++] = addr2.s_addr; 713e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 714e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'X': 715e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (parse_addr(&addr, &addr2, arg) != 0) 716e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 717e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (strchr(arg, '/') == NULL) 718e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt addr2.s_addr = INADDR_BROADCAST; 719e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->blacklist = xrealloc(ifo->blacklist, 720e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt sizeof(in_addr_t) * (ifo->blacklist_len + 2)); 721e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->blacklist[ifo->blacklist_len++] = addr.s_addr; 722e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->blacklist[ifo->blacklist_len++] = addr2.s_addr; 723e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 724e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 'Z': 725e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifdv = splitv(&ifdc, ifdv, arg); 726e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 727e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case O_ARPING: 728e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (parse_addr(&addr, NULL, arg) != 0) 729e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 730e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->arping = xrealloc(ifo->arping, 731e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt sizeof(in_addr_t) * (ifo->arping_len + 1)); 732e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->arping[ifo->arping_len++] = addr.s_addr; 733e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 734e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case O_DESTINATION: 735e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (make_option_mask(ifo->dstmask, arg, 2) != 0) { 736e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (errno == EINVAL) 737e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt syslog(LOG_ERR, "option `%s' does not take" 738e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt " an IPv4 address", arg); 739e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt else 740e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt syslog(LOG_ERR, "unknown option `%s'", arg); 741e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 742e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 743e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 744e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case O_FALLBACK: 745e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt free(ifo->fallback); 746e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->fallback = xstrdup(arg); 747e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 748a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt case O_NOIPV6RS: 749a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt ifo->options &= ~DHCPCD_IPV6RS; 750a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt break; 751a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt case O_IPV6_RA_FORK: 752a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt ifo->options &= ~DHCPCD_IPV6RA_REQRDNSS; 753a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt break; 754e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt default: 755e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return 0; 756e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 757e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 758e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return 1; 759e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 760e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 761e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatic int 762e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtparse_config_line(struct if_options *ifo, const char *opt, char *line) 763e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 764e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt unsigned int i; 765e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 766e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt for (i = 0; i < sizeof(cf_options) / sizeof(cf_options[0]); i++) { 767e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (!cf_options[i].name || 768e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt strcmp(cf_options[i].name, opt) != 0) 769e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt continue; 770e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 771e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (cf_options[i].has_arg == required_argument && !line) { 772e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt fprintf(stderr, 773e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt PACKAGE ": option requires an argument -- %s\n", 774e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt opt); 775e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 776e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 777e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 778e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return parse_option(ifo, cf_options[i].val, line); 779e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 780e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 781e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt fprintf(stderr, PACKAGE ": unknown option -- %s\n", opt); 782e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 783e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 784e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 785e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstruct if_options * 786e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtread_config(const char *file, 787e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt const char *ifname, const char *ssid, const char *profile) 788e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 789e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct if_options *ifo; 790e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt FILE *f; 791e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt char *line, *option, *p, *platform; 792e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt int skip = 0, have_profile = 0; 793e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct utsname utn; 794e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 795e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* Seed our default options */ 796e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo = xzalloc(sizeof(*ifo)); 797a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt ifo->options |= DHCPCD_GATEWAY | DHCPCD_DAEMONISE | DHCPCD_LINK; 798a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt ifo->options |= DHCPCD_ARP | DHCPCD_IPV4LL; 79938cb7a7feff88d58fb4a565ba7f12cd4469af243Lorenzo Colitti#ifndef ANDROID 80038cb7a7feff88d58fb4a565ba7f12cd4469af243Lorenzo Colitti /* On Android, don't enable IPv6 RS processing. This is because we 80138cb7a7feff88d58fb4a565ba7f12cd4469af243Lorenzo Colitti * already process RAs in the kernel and netd and because we've seen 80238cb7a7feff88d58fb4a565ba7f12cd4469af243Lorenzo Colitti * dhcpcd crashes when parsing certain RA options. 80338cb7a7feff88d58fb4a565ba7f12cd4469af243Lorenzo Colitti * See http://b/15268738 and http://b/15779617 . */ 804a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt ifo->options |= DHCPCD_IPV6RS | DHCPCD_IPV6RA_REQRDNSS; 80538cb7a7feff88d58fb4a565ba7f12cd4469af243Lorenzo Colitti#endif 806e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->timeout = DEFAULT_TIMEOUT; 807e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->reboot = DEFAULT_REBOOT; 808e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->metric = -1; 809e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt strlcpy(ifo->script, SCRIPT, sizeof(ifo->script)); 810e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt gethostname(ifo->hostname, HOSTNAME_MAX_LEN); 811e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* Ensure that the hostname is NULL terminated */ 812e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->hostname[HOSTNAME_MAX_LEN] = '\0'; 813e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (strcmp(ifo->hostname, "(none)") == 0 || 814e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt strcmp(ifo->hostname, "localhost") == 0) 815e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->hostname[0] = '\0'; 816e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 817e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt platform = hardware_platform(); 81875d23348894a57d2fda048cfd71a198f9c3ba59fDmitry Shmidt#ifndef ANDROID 819e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (uname(&utn) == 0) 820e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->vendorclassid[0] = snprintf((char *)ifo->vendorclassid + 1, 821e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt VENDORCLASSID_MAX_LEN, 822e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt "%s-%s:%s-%s:%s%s%s", PACKAGE, VERSION, 823e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt utn.sysname, utn.release, utn.machine, 824e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt platform ? ":" : "", platform ? platform : ""); 825e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt else 82675d23348894a57d2fda048cfd71a198f9c3ba59fDmitry Shmidt#endif 827e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->vendorclassid[0] = snprintf((char *)ifo->vendorclassid + 1, 828e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt VENDORCLASSID_MAX_LEN, "%s-%s", PACKAGE, VERSION); 829e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 830e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* Parse our options file */ 831e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt f = fopen(file ? file : CONFIG, "r"); 832e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (f == NULL) { 833e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (file != NULL) 834e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt syslog(LOG_ERR, "fopen `%s': %m", file); 835e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return ifo; 836e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 837e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 838e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt while ((line = get_line(f))) { 839e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt option = strsep(&line, " \t"); 840e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* Trim trailing whitespace */ 841e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (line && *line) { 842e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt p = line + strlen(line) - 1; 843e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt while (p != line && 844e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt (*p == ' ' || *p == '\t') && 845e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt *(p - 1) != '\\') 846e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt *p-- = '\0'; 847e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 848e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* Start of an interface block, skip if not ours */ 849e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (strcmp(option, "interface") == 0) { 850e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (ifname && line && strcmp(line, ifname) == 0) 851e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt skip = 0; 852e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt else 853e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt skip = 1; 854e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt continue; 855e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 856e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* Start of an ssid block, skip if not ours */ 857e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (strcmp(option, "ssid") == 0) { 858e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (ssid && line && strcmp(line, ssid) == 0) 859e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt skip = 0; 860e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt else 861e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt skip = 1; 862e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt continue; 863e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 864e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* Start of a profile block, skip if not ours */ 865e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (strcmp(option, "profile") == 0) { 866e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (profile && line && strcmp(line, profile) == 0) { 867e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt skip = 0; 868e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt have_profile = 1; 869e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } else 870e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt skip = 1; 871e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt continue; 872e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 873e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (skip) 874e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt continue; 875e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt parse_config_line(ifo, option, line); 876e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 877e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt fclose(f); 878e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 879e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (profile && !have_profile) { 880e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt free_options(ifo); 881e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt errno = ENOENT; 882e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo = NULL; 883e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 884e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 885e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* Terminate the encapsulated options */ 886e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (ifo && ifo->vendor[0] && !(ifo->options & DHCPCD_VENDORRAW)) { 887e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->vendor[0]++; 888e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->vendor[ifo->vendor[0]] = DHO_END; 889e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 890e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return ifo; 891e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 892e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 893e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtint 894e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtadd_options(struct if_options *ifo, int argc, char **argv) 895e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 896e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt int oi, opt, r = 1; 897e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 898e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt optind = 0; 899e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt while ((opt = getopt_long(argc, argv, IF_OPTS, cf_options, &oi)) != -1) 900e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt { 901e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt r = parse_option(ifo, opt, optarg); 902e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (r != 1) 903e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 904e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 905e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* Terminate the encapsulated options */ 906e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (r == 1 && ifo->vendor[0] && !(ifo->options & DHCPCD_VENDORRAW)) { 907e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->vendor[0]++; 908e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifo->vendor[ifo->vendor[0]] = DHO_END; 909e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 910e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return r; 911e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 912e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 913e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtvoid 914e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtfree_options(struct if_options *ifo) 915e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 916e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt size_t i; 917e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 918e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (ifo) { 919e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (ifo->environ) { 920e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt i = 0; 921e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt while (ifo->environ[i]) 922e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt free(ifo->environ[i++]); 923e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt free(ifo->environ); 924e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 925e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (ifo->config) { 926e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt i = 0; 927e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt while (ifo->config[i]) 928e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt free(ifo->config[i++]); 929e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt free(ifo->config); 930e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 931e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt free_routes(ifo->routes); 932e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt free(ifo->arping); 933e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt free(ifo->blacklist); 934e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt free(ifo->fallback); 935e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt free(ifo); 936e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 937e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 938