1ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat/* dnsmasq is Copyright (c) 2000-2009 Simon Kelley 2ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 3ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat This program is free software; you can redistribute it and/or modify 4ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat it under the terms of the GNU General Public License as published by 5ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat the Free Software Foundation; version 2 dated June, 1991, or 6ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat (at your option) version 3 dated 29 June, 2007. 7ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 8ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat This program is distributed in the hope that it will be useful, 9ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat but WITHOUT ANY WARRANTY; without even the implied warranty of 10ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat GNU General Public License for more details. 12ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 13ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat You should have received a copy of the GNU General Public License 14ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat along with this program. If not, see <http://www.gnu.org/licenses/>. 15ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat*/ 16ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 17ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat/* define this to get facilitynames */ 18ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define SYSLOG_NAMES 19ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#include "dnsmasq.h" 20ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#include <setjmp.h> 21ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 22ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatstatic volatile int mem_recover = 0; 23ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatstatic jmp_buf mem_jmp; 24ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatstatic void one_file(char *file, int nest, int hard_opt); 25ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 26ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat/* Solaris headers don't have facility names. */ 27ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#ifdef HAVE_SOLARIS_NETWORK 28ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatstatic const struct { 29ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *c_name; 30ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat unsigned int c_val; 31ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat} facilitynames[] = { 32ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "kern", LOG_KERN }, 33ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "user", LOG_USER }, 34ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "mail", LOG_MAIL }, 35ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "daemon", LOG_DAEMON }, 36ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "auth", LOG_AUTH }, 37ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "syslog", LOG_SYSLOG }, 38ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "lpr", LOG_LPR }, 39ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "news", LOG_NEWS }, 40ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "uucp", LOG_UUCP }, 41ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "audit", LOG_AUDIT }, 42ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "cron", LOG_CRON }, 43ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "local0", LOG_LOCAL0 }, 44ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "local1", LOG_LOCAL1 }, 45ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "local2", LOG_LOCAL2 }, 46ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "local3", LOG_LOCAL3 }, 47ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "local4", LOG_LOCAL4 }, 48ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "local5", LOG_LOCAL5 }, 49ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "local6", LOG_LOCAL6 }, 50ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "local7", LOG_LOCAL7 }, 51ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { NULL, 0 } 52ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat}; 53ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#endif 54ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 55ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#ifndef HAVE_GETOPT_LONG 56ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatstruct myoption { 57ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat const char *name; 58ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat int has_arg; 59ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat int *flag; 60ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat int val; 61ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat}; 62ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#endif 63ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 64ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define OPTSTRING "951yZDNLERKzowefnbvhdkqr:m:p:c:l:s:i:t:u:g:a:x:S:C:A:T:H:Q:I:B:F:G:O:M:X:V:U:j:P:J:W:Y:2:4:6:7:8:0:3:" 65ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 66ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat/* options which don't have a one-char version */ 67ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_RELOAD 256 68ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_NO_NAMES 257 69ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_TFTP 258 70ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_SECURE 259 71ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_PREFIX 260 72ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_PTR 261 73ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_BRIDGE 262 74ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_TFTP_MAX 263 75ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_FORCE 264 76ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_NOBLOCK 265 77ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_LOG_OPTS 266 78ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_MAX_LOGS 267 79ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_CIRCUIT 268 80ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_REMOTE 269 81ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_SUBSCR 270 82ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_INTNAME 271 83ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_BANK 272 84ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_DHCP_HOST 273 85ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_APREF 274 86ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_OVERRIDE 275 87ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_TFTPPORTS 276 88ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_REBIND 277 89ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_NOLAST 278 90ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_OPTS 279 91ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_DHCP_OPTS 280 92ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_MATCH 281 93ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_BROADCAST 282 94ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_NEGTTL 283 95ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_ALTPORT 284 96ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_SCRIPTUSR 285 97ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_LOCAL 286 98ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_NAPTR 287 99ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_MINPORT 288 100ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_DHCP_FQDN 289 101ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_CNAME 290 102ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_PXE_PROMT 291 103ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_PXE_SERV 292 104ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define LOPT_TEST 293 10568cd69ecff2d0f533a45a4218386a416cb201b71Lorenzo Colitti#define LOPT_LISTNMARK 294 106ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 107ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#ifdef HAVE_GETOPT_LONG 108ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatstatic const struct option opts[] = 109ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#else 110ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatstatic const struct myoption opts[] = 111ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#endif 112ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 113ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "version", 0, 0, 'v' }, 114ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "no-hosts", 0, 0, 'h' }, 115ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "no-poll", 0, 0, 'n' }, 116ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "help", 0, 0, 'w' }, 117ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "no-daemon", 0, 0, 'd' }, 118ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "log-queries", 0, 0, 'q' }, 119ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "user", 2, 0, 'u' }, 120ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "group", 2, 0, 'g' }, 121ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "resolv-file", 2, 0, 'r' }, 122ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "mx-host", 1, 0, 'm' }, 123ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "mx-target", 1, 0, 't' }, 124ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "cache-size", 2, 0, 'c' }, 125ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "port", 1, 0, 'p' }, 126ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "dhcp-leasefile", 2, 0, 'l' }, 127ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "dhcp-lease", 1, 0, 'l' }, 128ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "dhcp-host", 1, 0, 'G' }, 129ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "dhcp-range", 1, 0, 'F' }, 130ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "dhcp-option", 1, 0, 'O' }, 131ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "dhcp-boot", 1, 0, 'M' }, 132ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "domain", 1, 0, 's' }, 133ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "domain-suffix", 1, 0, 's' }, 134ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "interface", 1, 0, 'i' }, 135ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "listen-address", 1, 0, 'a' }, 136ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "bogus-priv", 0, 0, 'b' }, 137ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "bogus-nxdomain", 1, 0, 'B' }, 138ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "selfmx", 0, 0, 'e' }, 139ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "filterwin2k", 0, 0, 'f' }, 140ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "pid-file", 2, 0, 'x' }, 141ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "strict-order", 0, 0, 'o' }, 142ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "server", 1, 0, 'S' }, 143ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "local", 1, 0, LOPT_LOCAL }, 144ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "address", 1, 0, 'A' }, 145ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "conf-file", 2, 0, 'C' }, 146ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "no-resolv", 0, 0, 'R' }, 147ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "expand-hosts", 0, 0, 'E' }, 148ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "localmx", 0, 0, 'L' }, 149ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "local-ttl", 1, 0, 'T' }, 150ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "no-negcache", 0, 0, 'N' }, 151ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "addn-hosts", 1, 0, 'H' }, 152ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "query-port", 1, 0, 'Q' }, 153ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "except-interface", 1, 0, 'I' }, 154ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "no-dhcp-interface", 1, 0, '2' }, 155ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "domain-needed", 0, 0, 'D' }, 156ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "dhcp-lease-max", 1, 0, 'X' }, 157ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "bind-interfaces", 0, 0, 'z' }, 158ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "read-ethers", 0, 0, 'Z' }, 159ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "alias", 1, 0, 'V' }, 160ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "dhcp-vendorclass", 1, 0, 'U' }, 161ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "dhcp-userclass", 1, 0, 'j' }, 162ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "dhcp-ignore", 1, 0, 'J' }, 163ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "edns-packet-max", 1, 0, 'P' }, 164ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "keep-in-foreground", 0, 0, 'k' }, 165ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "dhcp-authoritative", 0, 0, 'K' }, 166ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "srv-host", 1, 0, 'W' }, 167ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "localise-queries", 0, 0, 'y' }, 168ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "txt-record", 1, 0, 'Y' }, 169ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "enable-dbus", 0, 0, '1' }, 170ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "bootp-dynamic", 2, 0, '3' }, 171ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "dhcp-mac", 1, 0, '4' }, 172ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "no-ping", 0, 0, '5' }, 173ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "dhcp-script", 1, 0, '6' }, 174ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "conf-dir", 1, 0, '7' }, 175ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "log-facility", 1, 0 ,'8' }, 176ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "leasefile-ro", 0, 0, '9' }, 177ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "dns-forward-max", 1, 0, '0' }, 178ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "clear-on-reload", 0, 0, LOPT_RELOAD }, 179ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "dhcp-ignore-names", 2, 0, LOPT_NO_NAMES }, 180ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "enable-tftp", 0, 0, LOPT_TFTP }, 181ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "tftp-secure", 0, 0, LOPT_SECURE }, 182ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "tftp-unique-root", 0, 0, LOPT_APREF }, 183ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "tftp-root", 1, 0, LOPT_PREFIX }, 184ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "tftp-max", 1, 0, LOPT_TFTP_MAX }, 185ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "ptr-record", 1, 0, LOPT_PTR }, 186ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "naptr-record", 1, 0, LOPT_NAPTR }, 187ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "bridge-interface", 1, 0 , LOPT_BRIDGE }, 188ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "dhcp-option-force", 1, 0, LOPT_FORCE }, 189ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "tftp-no-blocksize", 0, 0, LOPT_NOBLOCK }, 190ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "log-dhcp", 0, 0, LOPT_LOG_OPTS }, 191ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "log-async", 2, 0, LOPT_MAX_LOGS }, 192ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "dhcp-circuitid", 1, 0, LOPT_CIRCUIT }, 193ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "dhcp-remoteid", 1, 0, LOPT_REMOTE }, 194ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "dhcp-subscrid", 1, 0, LOPT_SUBSCR }, 195ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "interface-name", 1, 0, LOPT_INTNAME }, 196ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "dhcp-hostsfile", 1, 0, LOPT_DHCP_HOST }, 197ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "dhcp-optsfile", 1, 0, LOPT_DHCP_OPTS }, 198ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "dhcp-no-override", 0, 0, LOPT_OVERRIDE }, 199ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "tftp-port-range", 1, 0, LOPT_TFTPPORTS }, 200ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "stop-dns-rebind", 0, 0, LOPT_REBIND }, 201ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "all-servers", 0, 0, LOPT_NOLAST }, 202ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "dhcp-match", 1, 0, LOPT_MATCH }, 203ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "dhcp-broadcast", 1, 0, LOPT_BROADCAST }, 204ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "neg-ttl", 1, 0, LOPT_NEGTTL }, 205ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "dhcp-alternate-port", 2, 0, LOPT_ALTPORT }, 206ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "dhcp-scriptuser", 1, 0, LOPT_SCRIPTUSR }, 207ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "min-port", 1, 0, LOPT_MINPORT }, 208ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "dhcp-fqdn", 0, 0, LOPT_DHCP_FQDN }, 209ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "cname", 1, 0, LOPT_CNAME }, 210ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "pxe-prompt", 1, 0, LOPT_PXE_PROMT }, 211ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "pxe-service", 1, 0, LOPT_PXE_SERV }, 21268cd69ecff2d0f533a45a4218386a416cb201b71Lorenzo Colitti#ifdef __ANDROID__ 21368cd69ecff2d0f533a45a4218386a416cb201b71Lorenzo Colitti { "listen-mark", 1, 0, LOPT_LISTNMARK }, 21468cd69ecff2d0f533a45a4218386a416cb201b71Lorenzo Colitti#endif /* __ANDROID__ */ 215ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "test", 0, 0, LOPT_TEST }, 216ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { NULL, 0, 0, 0 } 217ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat }; 218ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 219ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat/* These must have more the one '1' bit */ 220ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define ARG_DUP 3 221ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define ARG_ONE 5 222ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define ARG_USED_CL 7 223ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define ARG_USED_FILE 9 224ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 225ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatstatic struct { 226ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat int opt; 227ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat unsigned int rept; 228ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char * const flagdesc; 229ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char * const desc; 230ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char * const arg; 231ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat} usage[] = { 232ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'a', ARG_DUP, "ipaddr", gettext_noop("Specify local address(es) to listen on."), NULL }, 233ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'A', ARG_DUP, "/domain/ipaddr", gettext_noop("Return ipaddr for all hosts in specified domains."), NULL }, 234ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'b', OPT_BOGUSPRIV, NULL, gettext_noop("Fake reverse lookups for RFC1918 private address ranges."), NULL }, 235ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'B', ARG_DUP, "ipaddr", gettext_noop("Treat ipaddr as NXDOMAIN (defeats Verisign wildcard)."), NULL }, 236ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'c', ARG_ONE, "cachesize", gettext_noop("Specify the size of the cache in entries (defaults to %s)."), "$" }, 237ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'C', ARG_DUP, "path", gettext_noop("Specify configuration file (defaults to %s)."), CONFFILE }, 238ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'd', OPT_DEBUG, NULL, gettext_noop("Do NOT fork into the background: run in debug mode."), NULL }, 239ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'D', OPT_NODOTS_LOCAL, NULL, gettext_noop("Do NOT forward queries with no domain part."), NULL }, 240ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'e', OPT_SELFMX, NULL, gettext_noop("Return self-pointing MX records for local hosts."), NULL }, 241ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'E', OPT_EXPAND, NULL, gettext_noop("Expand simple names in /etc/hosts with domain-suffix."), NULL }, 242ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'f', OPT_FILTER, NULL, gettext_noop("Don't forward spurious DNS requests from Windows hosts."), NULL }, 243ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'F', ARG_DUP, "ipaddr,ipaddr,time", gettext_noop("Enable DHCP in the range given with lease duration."), NULL }, 244ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'g', ARG_ONE, "groupname", gettext_noop("Change to this group after startup (defaults to %s)."), CHGRP }, 245ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'G', ARG_DUP, "<hostspec>", gettext_noop("Set address or hostname for a specified machine."), NULL }, 246ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { LOPT_DHCP_HOST, ARG_ONE, "<filename>", gettext_noop("Read DHCP host specs from file"), NULL }, 247ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { LOPT_DHCP_OPTS, ARG_ONE, "<filename>", gettext_noop("Read DHCP option specs from file"), NULL }, 248ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'h', OPT_NO_HOSTS, NULL, gettext_noop("Do NOT load %s file."), HOSTSFILE }, 249ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'H', ARG_DUP, "path", gettext_noop("Specify a hosts file to be read in addition to %s."), HOSTSFILE }, 250ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'i', ARG_DUP, "interface", gettext_noop("Specify interface(s) to listen on."), NULL }, 251ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'I', ARG_DUP, "int", gettext_noop("Specify interface(s) NOT to listen on.") , NULL }, 252ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'j', ARG_DUP, "<tag>,<class>", gettext_noop("Map DHCP user class to tag."), NULL }, 253ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { LOPT_CIRCUIT, ARG_DUP, "<tag>,<circuit>", gettext_noop("Map RFC3046 circuit-id to tag."), NULL }, 254ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { LOPT_REMOTE, ARG_DUP, "<tag>,<remote>", gettext_noop("Map RFC3046 remote-id to tag."), NULL }, 255ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { LOPT_SUBSCR, ARG_DUP, "<tag>,<remote>", gettext_noop("Map RFC3993 subscriber-id to tag."), NULL }, 256ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'J', ARG_DUP, "=<id>[,<id>]", gettext_noop("Don't do DHCP for hosts with tag set."), NULL }, 257ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { LOPT_BROADCAST, ARG_DUP, "=<id>[,<id>]", gettext_noop("Force broadcast replies for hosts with tag set."), NULL }, 258ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'k', OPT_NO_FORK, NULL, gettext_noop("Do NOT fork into the background, do NOT run in debug mode."), NULL }, 259ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'K', OPT_AUTHORITATIVE, NULL, gettext_noop("Assume we are the only DHCP server on the local network."), NULL }, 260ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'l', ARG_ONE, "path", gettext_noop("Specify where to store DHCP leases (defaults to %s)."), LEASEFILE }, 261ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'L', OPT_LOCALMX, NULL, gettext_noop("Return MX records for local hosts."), NULL }, 262ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'm', ARG_DUP, "host_name,target,pref", gettext_noop("Specify an MX record."), NULL }, 263ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'M', ARG_DUP, "<bootp opts>", gettext_noop("Specify BOOTP options to DHCP server."), NULL }, 264ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'n', OPT_NO_POLL, NULL, gettext_noop("Do NOT poll %s file, reload only on SIGHUP."), RESOLVFILE }, 265ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'N', OPT_NO_NEG, NULL, gettext_noop("Do NOT cache failed search results."), NULL }, 266ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'o', OPT_ORDER, NULL, gettext_noop("Use nameservers strictly in the order given in %s."), RESOLVFILE }, 267ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'O', ARG_DUP, "<optspec>", gettext_noop("Specify options to be sent to DHCP clients."), NULL }, 268ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { LOPT_FORCE, ARG_DUP, "<optspec>", gettext_noop("DHCP option sent even if the client does not request it."), NULL}, 269ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'p', ARG_ONE, "number", gettext_noop("Specify port to listen for DNS requests on (defaults to 53)."), NULL }, 270ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'P', ARG_ONE, "<size>", gettext_noop("Maximum supported UDP packet size for EDNS.0 (defaults to %s)."), "*" }, 271ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'q', OPT_LOG, NULL, gettext_noop("Log DNS queries."), NULL }, 272ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'Q', ARG_ONE, "number", gettext_noop("Force the originating port for upstream DNS queries."), NULL }, 273ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'R', OPT_NO_RESOLV, NULL, gettext_noop("Do NOT read resolv.conf."), NULL }, 274ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'r', ARG_DUP, "path", gettext_noop("Specify path to resolv.conf (defaults to %s)."), RESOLVFILE }, 275ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'S', ARG_DUP, "/domain/ipaddr", gettext_noop("Specify address(es) of upstream servers with optional domains."), NULL }, 276ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { LOPT_LOCAL, ARG_DUP, "/domain/", gettext_noop("Never forward queries to specified domains."), NULL }, 277ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 's', ARG_DUP, "<domain>[,<range>]", gettext_noop("Specify the domain to be assigned in DHCP leases."), NULL }, 278ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 't', ARG_ONE, "host_name", gettext_noop("Specify default target in an MX record."), NULL }, 279ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'T', ARG_ONE, "time", gettext_noop("Specify time-to-live in seconds for replies from /etc/hosts."), NULL }, 280ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { LOPT_NEGTTL, ARG_ONE, "time", gettext_noop("Specify time-to-live in seconds for negative caching."), NULL }, 281ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'u', ARG_ONE, "username", gettext_noop("Change to this user after startup. (defaults to %s)."), CHUSER }, 282ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'U', ARG_DUP, "<id>,<class>", gettext_noop("Map DHCP vendor class to tag."), NULL }, 283ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'v', 0, NULL, gettext_noop("Display dnsmasq version and copyright information."), NULL }, 284ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'V', ARG_DUP, "addr,addr,mask", gettext_noop("Translate IPv4 addresses from upstream servers."), NULL }, 285ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'W', ARG_DUP, "name,target,...", gettext_noop("Specify a SRV record."), NULL }, 286ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'w', 0, NULL, gettext_noop("Display this message. Use --help dhcp for known DHCP options."), NULL }, 287ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'x', ARG_ONE, "path", gettext_noop("Specify path of PID file (defaults to %s)."), RUNFILE }, 288ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'X', ARG_ONE, "number", gettext_noop("Specify maximum number of DHCP leases (defaults to %s)."), "&" }, 289ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'y', OPT_LOCALISE, NULL, gettext_noop("Answer DNS queries based on the interface a query was sent to."), NULL }, 290ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'Y', ARG_DUP, "name,txt....", gettext_noop("Specify TXT DNS record."), NULL }, 291ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { LOPT_PTR, ARG_DUP, "name,target", gettext_noop("Specify PTR DNS record."), NULL }, 292ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { LOPT_INTNAME, ARG_DUP, "name,interface", gettext_noop("Give DNS name to IPv4 address of interface."), NULL }, 293ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'z', OPT_NOWILD, NULL, gettext_noop("Bind only to interfaces in use."), NULL }, 294ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 'Z', OPT_ETHERS, NULL, gettext_noop("Read DHCP static host information from %s."), ETHERSFILE }, 295ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { '1', OPT_DBUS, NULL, gettext_noop("Enable the DBus interface for setting upstream servers, etc."), NULL }, 296ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { '2', ARG_DUP, "interface", gettext_noop("Do not provide DHCP on this interface, only provide DNS."), NULL }, 297ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { '3', ARG_DUP, "[=<id>[,<id>]]", gettext_noop("Enable dynamic address allocation for bootp."), NULL }, 298ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { '4', ARG_DUP, "<id>,<mac address>", gettext_noop("Map MAC address (with wildcards) to option set."), NULL }, 299ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { LOPT_BRIDGE, ARG_DUP, "iface,alias,..", gettext_noop("Treat DHCP requests on aliases as arriving from interface."), NULL }, 300ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { '5', OPT_NO_PING, NULL, gettext_noop("Disable ICMP echo address checking in the DHCP server."), NULL }, 301ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { '6', ARG_ONE, "path", gettext_noop("Script to run on DHCP lease creation and destruction."), NULL }, 302ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { '7', ARG_DUP, "path", gettext_noop("Read configuration from all the files in this directory."), NULL }, 303ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { '8', ARG_ONE, "<facilty>|<file>", gettext_noop("Log to this syslog facility or file. (defaults to DAEMON)"), NULL }, 304ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { '9', OPT_LEASE_RO, NULL, gettext_noop("Do not use leasefile."), NULL }, 305ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { '0', ARG_ONE, "<queries>", gettext_noop("Maximum number of concurrent DNS queries. (defaults to %s)"), "!" }, 306ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { LOPT_RELOAD, OPT_RELOAD, NULL, gettext_noop("Clear DNS cache when reloading %s."), RESOLVFILE }, 307ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { LOPT_NO_NAMES, ARG_DUP, "[=<id>[,<id>]]", gettext_noop("Ignore hostnames provided by DHCP clients."), NULL }, 308ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { LOPT_OVERRIDE, OPT_NO_OVERRIDE, NULL, gettext_noop("Do NOT reuse filename and server fields for extra DHCP options."), NULL }, 309ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { LOPT_TFTP, OPT_TFTP, NULL, gettext_noop("Enable integrated read-only TFTP server."), NULL }, 310ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { LOPT_PREFIX, ARG_ONE, "<directory>", gettext_noop("Export files by TFTP only from the specified subtree."), NULL }, 311ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { LOPT_APREF, OPT_TFTP_APREF, NULL, gettext_noop("Add client IP address to tftp-root."), NULL }, 312ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { LOPT_SECURE, OPT_TFTP_SECURE, NULL, gettext_noop("Allow access only to files owned by the user running dnsmasq."), NULL }, 313ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { LOPT_TFTP_MAX, ARG_ONE, "<connections>", gettext_noop("Maximum number of conncurrent TFTP transfers (defaults to %s)."), "#" }, 314ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { LOPT_NOBLOCK, OPT_TFTP_NOBLOCK, NULL, gettext_noop("Disable the TFTP blocksize extension."), NULL }, 315ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { LOPT_TFTPPORTS, ARG_ONE, "<start>,<end>", gettext_noop("Ephemeral port range for use by TFTP transfers."), NULL }, 316ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { LOPT_LOG_OPTS, OPT_LOG_OPTS, NULL, gettext_noop("Extra logging for DHCP."), NULL }, 317ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { LOPT_MAX_LOGS, ARG_ONE, "[=<log lines>]", gettext_noop("Enable async. logging; optionally set queue length."), NULL }, 318ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { LOPT_REBIND, OPT_NO_REBIND, NULL, gettext_noop("Stop DNS rebinding. Filter private IP ranges when resolving."), NULL }, 319ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { LOPT_NOLAST, OPT_ALL_SERVERS, NULL, gettext_noop("Always perform DNS queries to all servers."), NULL }, 320ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { LOPT_MATCH, ARG_DUP, "<netid>,<optspec>", gettext_noop("Set tag if client includes matching option in request."), NULL }, 321ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { LOPT_ALTPORT, ARG_ONE, "[=<ports>]", gettext_noop("Use alternative ports for DHCP."), NULL }, 322ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { LOPT_SCRIPTUSR, ARG_ONE, "<username>", gettext_noop("Run lease-change script as this user."), NULL }, 323ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { LOPT_NAPTR, ARG_DUP, "<name>,<naptr>", gettext_noop("Specify NAPTR DNS record."), NULL }, 324ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { LOPT_MINPORT, ARG_ONE, "<port>", gettext_noop("Specify lowest port available for DNS query transmission."), NULL }, 325ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { LOPT_DHCP_FQDN, OPT_DHCP_FQDN, NULL, gettext_noop("Use only fully qualified domain names for DHCP clients."), NULL }, 326ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { LOPT_CNAME, ARG_DUP, "<alias>,<target>", gettext_noop("Specify alias name for LOCAL DNS name."), NULL }, 327ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { LOPT_PXE_PROMT, ARG_DUP, "<prompt>,[<timeout>]", gettext_noop("Prompt to send to PXE clients."), NULL }, 328ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { LOPT_PXE_SERV, ARG_DUP, "<service>", gettext_noop("Boot service for PXE menu."), NULL }, 32968cd69ecff2d0f533a45a4218386a416cb201b71Lorenzo Colitti { LOPT_LISTNMARK, ARG_ONE, NULL, gettext_noop("Socket mark to use for listen sockets."), NULL }, 330ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { LOPT_TEST, 0, NULL, gettext_noop("Check configuration syntax."), NULL }, 331ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 0, 0, NULL, NULL, NULL } 332ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat}; 333ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 334ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#ifdef HAVE_DHCP 335ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat/* makes options which take a list of addresses */ 336ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define OT_ADDR_LIST 0x80 337ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat/* DHCP-internal options, for logging. not valid in config file */ 338ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define OT_INTERNAL 0x40 339ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#define OT_NAME 0x20 340ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 341ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatstatic const struct { 342ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *name; 343ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat unsigned char val, size; 344ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat} opttab[] = { 345ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "netmask", 1, OT_ADDR_LIST }, 346ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "time-offset", 2, 4 }, 347ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "router", 3, OT_ADDR_LIST }, 348ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "dns-server", 6, OT_ADDR_LIST }, 349ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "log-server", 7, OT_ADDR_LIST }, 350ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "lpr-server", 9, OT_ADDR_LIST }, 351ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "hostname", 12, OT_INTERNAL | OT_NAME }, 352ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "boot-file-size", 13, 2 }, 353ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "domain-name", 15, OT_NAME }, 354ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "swap-server", 16, OT_ADDR_LIST }, 355ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "root-path", 17, 0 }, 356ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "extension-path", 18, 0 }, 357ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "ip-forward-enable", 19, 1 }, 358ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "non-local-source-routing", 20, 1 }, 359ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "policy-filter", 21, OT_ADDR_LIST }, 360ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "max-datagram-reassembly", 22, 2 }, 361ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "default-ttl", 23, 1 }, 362ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "mtu", 26, 2 }, 363ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "all-subnets-local", 27, 1 }, 364ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "broadcast", 28, OT_INTERNAL | OT_ADDR_LIST }, 365ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "router-discovery", 31, 1 }, 366ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "router-solicitation", 32, OT_ADDR_LIST }, 367ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "static-route", 33, OT_ADDR_LIST }, 368ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "trailer-encapsulation", 34, 1 }, 369ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "arp-timeout", 35, 4 }, 370ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "ethernet-encap", 36, 1 }, 371ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "tcp-ttl", 37, 1 }, 372ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "tcp-keepalive", 38, 4 }, 373ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "nis-domain", 40, 0 }, 374ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "nis-server", 41, OT_ADDR_LIST }, 375ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "ntp-server", 42, OT_ADDR_LIST }, 376ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "vendor-encap", 43, OT_INTERNAL }, 377ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "netbios-ns", 44, OT_ADDR_LIST }, 378ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "netbios-dd", 45, OT_ADDR_LIST }, 379ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "netbios-nodetype", 46, 1 }, 380ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "netbios-scope", 47, 0 }, 381ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "x-windows-fs", 48, OT_ADDR_LIST }, 382ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "x-windows-dm", 49, OT_ADDR_LIST }, 383ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "requested-address", 50, OT_INTERNAL | OT_ADDR_LIST }, 384ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "lease-time", 51, OT_INTERNAL }, 385ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "option-overload", 52, OT_INTERNAL }, 386ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "message-type", 53, OT_INTERNAL, }, 387ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "server-identifier", 54, OT_INTERNAL | OT_ADDR_LIST }, 388ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "parameter-request", 55, OT_INTERNAL }, 389ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "message", 56, OT_INTERNAL }, 390ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "max-message-size", 57, OT_INTERNAL }, 391ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "T1", 58, OT_INTERNAL }, 392ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "T2", 59, OT_INTERNAL }, 393ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "vendor-class", 60, 0 }, 394ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "client-id", 61,OT_INTERNAL }, 395ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "nis+-domain", 64, 0 }, 396ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "nis+-server", 65, OT_ADDR_LIST }, 397ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "tftp-server", 66, 0 }, 398ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "bootfile-name", 67, 0 }, 399ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "mobile-ip-home", 68, OT_ADDR_LIST }, 400ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "smtp-server", 69, OT_ADDR_LIST }, 401ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "pop3-server", 70, OT_ADDR_LIST }, 402ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "nntp-server", 71, OT_ADDR_LIST }, 403ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "irc-server", 74, OT_ADDR_LIST }, 404ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "user-class", 77, 0 }, 405ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "FQDN", 81, OT_INTERNAL }, 406ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "agent-id", 82, OT_INTERNAL }, 407ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "client-arch", 93, 2 }, 408ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "client-interface-id", 94, 0 }, 409ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "client-machine-id", 97, 0 }, 410ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "subnet-select", 118, OT_INTERNAL }, 411ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "domain-search", 119, 0 }, 412ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "sip-server", 120, 0 }, 413ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "classless-static-route", 121, 0 }, 414ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { "server-ip-address", 255, OT_ADDR_LIST }, /* special, internal only, sets siaddr */ 415ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { NULL, 0, 0 } 416ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat}; 417ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 418ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatchar *option_string(unsigned char opt, int *is_ip, int *is_name) 419ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat{ 420ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat int i; 421ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 422ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (i = 0; opttab[i].name; i++) 423ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (opttab[i].val == opt) 424ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 425ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (is_ip) 426ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat *is_ip = !!(opttab[i].size & OT_ADDR_LIST); 427ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (is_name) 428ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat *is_name = !!(opttab[i].size & OT_NAME); 429ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat return opttab[i].name; 430ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 431ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 432ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat return NULL; 433ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat} 434ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 435ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#endif 436ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 437ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat/* We hide metacharaters in quoted strings by mapping them into the ASCII control 438ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat character space. Note that the \0, \t \b \r \033 and \n characters are carefully placed in the 439ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat following sequence so that they map to themselves: it is therefore possible to call 440ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat unhide_metas repeatedly on string without breaking things. 441ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat The transformation gets undone by opt_canonicalise, atoi_check and opt_string_alloc, and a 442ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat couple of other places. 443ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat Note that space is included here so that 444ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat --dhcp-option=3, string 445ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat has five characters, whilst 446ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat --dhcp-option=3," string" 447ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat has six. 448ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat*/ 449ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 450ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatstatic const char meta[] = "\000123456 \b\t\n78\r90abcdefABCDE\033F:,."; 451ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 452ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatstatic char hide_meta(char c) 453ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat{ 454ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat unsigned int i; 455ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 456ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (i = 0; i < (sizeof(meta) - 1); i++) 457ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (c == meta[i]) 458ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat return (char)i; 459ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 460ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat return c; 461ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat} 462ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 463ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatstatic char unhide_meta(char cr) 464ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat{ 465ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat unsigned int c = cr; 466ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 467ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (c < (sizeof(meta) - 1)) 468ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat cr = meta[c]; 469ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 470ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat return cr; 471ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat} 472ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 473ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatstatic void unhide_metas(char *cp) 474ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat{ 475ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (cp) 476ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for(; *cp; cp++) 477ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat *cp = unhide_meta(*cp); 478ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat} 479ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 480ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatstatic void *opt_malloc(size_t size) 481ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat{ 482ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat void *ret; 483ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 484ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (mem_recover) 485ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 486ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat ret = whine_malloc(size); 487ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!ret) 488ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat longjmp(mem_jmp, 1); 489ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 490ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 491ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat ret = safe_malloc(size); 492ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 493ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat return ret; 494ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat} 495ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 496ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatstatic char *opt_string_alloc(char *cp) 497ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat{ 498ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *ret = NULL; 499ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 500ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (cp && strlen(cp) != 0) 501ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 502ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat ret = opt_malloc(strlen(cp)+1); 503ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat strcpy(ret, cp); 504ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 505ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* restore hidden metachars */ 506ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat unhide_metas(ret); 507ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 508ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 509ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat return ret; 510ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat} 511ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 512ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 513ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat/* find next comma, split string with zero and eliminate spaces. 514ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat return start of string following comma */ 515ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 516ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatstatic char *split_chr(char *s, char c) 517ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat{ 518ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *comma, *p; 519ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 520ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!s || !(comma = strchr(s, c))) 521ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat return NULL; 522ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 523ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat p = comma; 524ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat *comma = ' '; 525ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 526ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (; isspace((int)*comma); comma++); 527ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 528ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (; (p >= s) && isspace((int)*p); p--) 529ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat *p = 0; 530ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 531ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat return comma; 532ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat} 533ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 534ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatstatic char *split(char *s) 535ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat{ 536ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat return split_chr(s, ','); 537ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat} 538ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 539ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatstatic char *canonicalise_opt(char *s) 540ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat{ 541ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *ret; 542ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat int nomem; 543ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 544ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!s) 545ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat return 0; 546ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 547ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat unhide_metas(s); 548ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!(ret = canonicalise(s, &nomem)) && nomem) 549ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 550ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (mem_recover) 551ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat longjmp(mem_jmp, 1); 552ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 553ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat die(_("could not get memory"), NULL, EC_NOMEM); 554ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 555ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 556ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat return ret; 557ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat} 558ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 559ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatstatic int atoi_check(char *a, int *res) 560ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat{ 561ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *p; 562ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 563ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!a) 564ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat return 0; 565ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 566ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat unhide_metas(a); 567ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 568ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (p = a; *p; p++) 569ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (*p < '0' || *p > '9') 570ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat return 0; 571ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 572ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat *res = atoi(a); 573ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat return 1; 574ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat} 575ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 576ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatstatic int atoi_check16(char *a, int *res) 577ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat{ 578ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!(atoi_check(a, res)) || 579ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat *res < 0 || 580ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat *res > 0xffff) 581ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat return 0; 582ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 583ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat return 1; 584ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat} 585ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 586ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatstatic void add_txt(char *name, char *txt) 587ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat{ 588ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat size_t len = strlen(txt); 589ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct txt_record *r = opt_malloc(sizeof(struct txt_record)); 590ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 591ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat r->name = opt_string_alloc(name); 592ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat r->next = daemon->txt; 593ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->txt = r; 594ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat r->class = C_CHAOS; 595ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat r->txt = opt_malloc(len+1); 596ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat r->len = len+1; 597ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat *(r->txt) = len; 598ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat memcpy((r->txt)+1, txt, len); 599ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat} 600ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 601ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatstatic void do_usage(void) 602ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat{ 603ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char buff[100]; 604ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat int i, j; 605ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 606ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct { 607ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char handle; 608ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat int val; 609ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } tab[] = { 610ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { '$', CACHESIZ }, 611ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { '*', EDNS_PKTSZ }, 612ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { '&', MAXLEASES }, 613ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { '!', FTABSIZ }, 614ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { '\0', 0 } 615ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat }; 616ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 617ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat printf(_("Usage: dnsmasq [options]\n\n")); 618ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#ifndef HAVE_GETOPT_LONG 619ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat printf(_("Use short options only on the command line.\n")); 620ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#endif 621ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat printf(_("Valid options are:\n")); 622ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 623ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (i = 0; usage[i].opt != 0; i++) 624ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 625ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *desc = usage[i].flagdesc; 626ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *eq = "="; 627ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 628ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!desc || *desc == '[') 629ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat eq = ""; 630ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 631ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!desc) 632ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat desc = ""; 633ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 634ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for ( j = 0; opts[j].name; j++) 635ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (opts[j].val == usage[i].opt) 636ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 637ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (usage[i].opt < 256) 638ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat sprintf(buff, "-%c, ", usage[i].opt); 639ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 640ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat sprintf(buff, " "); 641ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 642ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat sprintf(buff+4, "--%s%s%s", opts[j].name, eq, desc); 643ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat printf("%-36.36s", buff); 644ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 645ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (usage[i].arg) 646ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 647ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat strcpy(buff, usage[i].arg); 648ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (j = 0; tab[j].handle; j++) 649ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (tab[j].handle == *(usage[i].arg)) 650ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat sprintf(buff, "%d", tab[j].val); 651ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 652ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat printf(_(usage[i].desc), buff); 653ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat printf("\n"); 654ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 655ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat} 656ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 657ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#ifdef HAVE_DHCP 658ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatstatic void display_opts(void) 659ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat{ 660ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat int i; 661ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 662ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat printf(_("Known DHCP options:\n")); 663ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 664ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (i = 0; opttab[i].name; i++) 665ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!(opttab[i].size & OT_INTERNAL)) 666ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat printf("%3d %s\n", opttab[i].val, opttab[i].name); 667ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat} 668ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 669ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat/* This is too insanely large to keep in-line in the switch */ 670ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatstatic char *parse_dhcp_opt(char *arg, int flags) 671ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat{ 672ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct dhcp_opt *new = opt_malloc(sizeof(struct dhcp_opt)); 673ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char lenchar = 0, *cp; 674ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat int i, addrs, digs, is_addr, is_hex, is_dec, is_string, dots; 675ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *comma = NULL, *problem = NULL; 676ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct dhcp_netid *np = NULL; 677ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat unsigned char opt_len = 0; 678ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 679ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->len = 0; 680ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->flags = flags; 681ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->netid = NULL; 682ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->val = NULL; 683ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->opt = 0; 684ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 685ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat while (arg) 686ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 687ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat comma = split(arg); 688ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 689ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (cp = arg; *cp; cp++) 690ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (*cp < '0' || *cp > '9') 691ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 692ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 693ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!*cp) 694ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 695ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->opt = atoi(arg); 696ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat opt_len = 0; 697ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 698ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 699ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 700ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (strstr(arg, "option:") == arg) 701ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 702ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (i = 0; opttab[i].name; i++) 703ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!(opttab[i].size & OT_INTERNAL) && 704ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat strcasecmp(opttab[i].name, arg+7) == 0) 705ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 706ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->opt = opttab[i].val; 707ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat opt_len = opttab[i].size; 708ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 709ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 710ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* option:<optname> must follow tag and vendor string. */ 711ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 712ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 713ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (strstr(arg, "vendor:") == arg) 714ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 715ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->u.vendor_class = (unsigned char *)opt_string_alloc(arg+7); 716ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->flags |= DHOPT_VENDOR; 717ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 718ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (strstr(arg, "encap:") == arg) 719ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 720ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->u.encap = atoi(arg+6); 721ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->flags |= DHOPT_ENCAPSULATE; 722ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 723ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 724ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 725ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->netid = opt_malloc(sizeof (struct dhcp_netid)); 726ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* allow optional "net:" for consistency */ 727ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (strstr(arg, "net:") == arg) 728ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->netid->net = opt_string_alloc(arg+4); 729ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 730ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->netid->net = opt_string_alloc(arg); 731ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->netid->next = np; 732ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat np = new->netid; 733ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 734ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 735ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat arg = comma; 736ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 737ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 738ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (new->opt == 0) 739ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat problem = _("bad dhcp-option"); 740ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (comma) 741ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 742ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* characterise the value */ 743ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char c; 744ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat is_addr = is_hex = is_dec = is_string = 1; 745ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat addrs = digs = 1; 746ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat dots = 0; 747ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (cp = comma; (c = *cp); cp++) 748ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (c == ',') 749ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 750ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat addrs++; 751ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat is_dec = is_hex = 0; 752ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 753ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (c == ':') 754ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 755ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat digs++; 756ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat is_dec = is_addr = 0; 757ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 758ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (c == '/') 759ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 760ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat is_dec = is_hex = 0; 761ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (cp == comma) /* leading / means a pathname */ 762ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat is_addr = 0; 763ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 764ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (c == '.') 765ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 766ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat is_dec = is_hex = 0; 767ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat dots++; 768ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 769ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (c == '-') 770ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat is_hex = is_addr = 0; 771ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (c == ' ') 772ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat is_dec = is_hex = 0; 773ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (!(c >='0' && c <= '9')) 774ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 775ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat is_addr = 0; 776ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (cp[1] == 0 && is_dec && 777ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat (c == 'b' || c == 's' || c == 'i')) 778ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 779ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat lenchar = c; 780ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat *cp = 0; 781ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 782ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 783ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat is_dec = 0; 784ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!((c >='A' && c <= 'F') || 785ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat (c >='a' && c <= 'f') || 786ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat (c == '*' && (flags & DHOPT_MATCH)))) 787ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat is_hex = 0; 788ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 789ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 790ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* We know that some options take addresses */ 791ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 792ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (opt_len & OT_ADDR_LIST) 793ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 794ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat is_string = is_dec = is_hex = 0; 795ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!is_addr || dots == 0) 796ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat problem = _("bad IP address"); 797ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 798ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 799ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (is_hex && digs > 1) 800ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 801ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->len = digs; 802ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->val = opt_malloc(new->len); 803ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat parse_hex(comma, new->val, digs, (flags & DHOPT_MATCH) ? &new->u.wildcard_mask : NULL, NULL); 804ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->flags |= DHOPT_HEX; 805ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 806ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (is_dec) 807ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 808ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat int i, val = atoi(comma); 809ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* assume numeric arg is 1 byte except for 810ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat options where it is known otherwise. 811ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat For vendor class option, we have to hack. */ 812ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (opt_len != 0) 813ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->len = opt_len; 814ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (val & 0xffff0000) 815ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->len = 4; 816ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (val & 0xff00) 817ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->len = 2; 818ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 819ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->len = 1; 820ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 821ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (lenchar == 'b') 822ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->len = 1; 823ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (lenchar == 's') 824ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->len = 2; 825ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (lenchar == 'i') 826ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->len = 4; 827ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 828ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->val = opt_malloc(new->len); 829ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (i=0; i<new->len; i++) 830ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->val[i] = val>>((new->len - i - 1)*8); 831ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 832ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (is_addr) 833ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 834ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct in_addr in; 835ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat unsigned char *op; 836ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *slash; 837ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* max length of address/subnet descriptor is five bytes, 838ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat add one for the option 120 enc byte too */ 839ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->val = op = opt_malloc((5 * addrs) + 1); 840ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->flags |= DHOPT_ADDR; 841ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 842ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!(new->flags & DHOPT_ENCAPSULATE) && new->opt == 120) 843ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 844ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat *(op++) = 1; /* RFC 3361 "enc byte" */ 845ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->flags &= ~DHOPT_ADDR; 846ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 847ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat while (addrs--) 848ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 849ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat cp = comma; 850ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat comma = split(cp); 851ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat slash = split_chr(cp, '/'); 852ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat in.s_addr = inet_addr(cp); 853ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!slash) 854ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 855ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat memcpy(op, &in, INADDRSZ); 856ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat op += INADDRSZ; 857ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 858ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 859ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 860ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat unsigned char *p = (unsigned char *)∈ 861ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat int netsize = atoi(slash); 862ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat *op++ = netsize; 863ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (netsize > 0) 864ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat *op++ = *p++; 865ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (netsize > 8) 866ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat *op++ = *p++; 867ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (netsize > 16) 868ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat *op++ = *p++; 869ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (netsize > 24) 870ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat *op++ = *p++; 871ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->flags &= ~DHOPT_ADDR; /* cannot re-write descriptor format */ 872ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 873ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 874ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->len = op - new->val; 875ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 876ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (is_string) 877ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 878ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* text arg */ 879ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if ((new->opt == 119 || new->opt == 120) && !(new->flags & DHOPT_ENCAPSULATE)) 880ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 881ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* dns search, RFC 3397, or SIP, RFC 3361 */ 882ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat unsigned char *q, *r, *tail; 883ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat unsigned char *p, *m = NULL, *newp; 884ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat size_t newlen, len = 0; 885ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat int header_size = (new->opt == 119) ? 0 : 1; 886ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 887ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat arg = comma; 888ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat comma = split(arg); 889ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 890ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat while (arg && *arg) 891ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 892ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *dom; 893ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!(dom = arg = canonicalise_opt(arg))) 894ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 895ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat problem = _("bad domain in dhcp-option"); 896ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 897ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 898ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 899ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat newp = opt_malloc(len + strlen(arg) + 2 + header_size); 900ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (m) 901ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat memcpy(newp, m, header_size + len); 902ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat m = newp; 903ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat p = m + header_size; 904ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat q = p + len; 905ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 906ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* add string on the end in RFC1035 format */ 907ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat while (*arg) 908ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 909ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat unsigned char *cp = q++; 910ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat int j; 911ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (j = 0; *arg && (*arg != '.'); arg++, j++) 912ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat *q++ = *arg; 913ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat *cp = j; 914ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (*arg) 915ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat arg++; 916ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 917ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat *q++ = 0; 918ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat free(dom); 919ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 920ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* Now tail-compress using earlier names. */ 921ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat newlen = q - p; 922ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (tail = p + len; *tail; tail += (*tail) + 1) 923ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (r = p; r - p < (int)len; r += (*r) + 1) 924ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (strcmp((char *)r, (char *)tail) == 0) 925ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 926ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat PUTSHORT((r - p) | 0xc000, tail); 927ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat newlen = tail - p; 928ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat goto end; 929ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 930ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat end: 931ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat len = newlen; 932ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 933ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat arg = comma; 934ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat comma = split(arg); 935ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 936ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 937ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* RFC 3361, enc byte is zero for names */ 938ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (new->opt == 120) 939ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat m[0] = 0; 940ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->len = (int) len + header_size; 941ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->val = m; 942ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 943ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 944ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 945ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->len = strlen(comma); 946ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* keep terminating zero on string */ 947ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->val = (unsigned char *)opt_string_alloc(comma); 948ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->flags |= DHOPT_STRING; 949ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 950ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 951ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 952ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 953ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if ((new->len > 255) || (new->len > 253 && (new->flags & (DHOPT_VENDOR | DHOPT_ENCAPSULATE)))) 954ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat problem = _("dhcp-option too long"); 955ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 956ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!problem) 957ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 958ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (flags == DHOPT_MATCH) 959ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 960ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if ((new->flags & (DHOPT_ENCAPSULATE | DHOPT_VENDOR)) || 961ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat !new->netid || 962ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->netid->next) 963ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat problem = _("illegal dhcp-match"); 964ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 965ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 966ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->next = daemon->dhcp_match; 967ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->dhcp_match = new; 968ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 969ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 970ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 971ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 972ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->next = daemon->dhcp_opts; 973ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->dhcp_opts = new; 974ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 975ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 976ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 977ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat return problem; 978ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat} 979ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 980ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#endif 981ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 982ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatstatic char *one_opt(int option, char *arg, char *gen_prob, int nest) 983ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat{ 984ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat int i; 985ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *comma, *problem = NULL;; 986ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 987ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (option == '?') 988ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat return gen_prob; 989ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 990ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (i=0; usage[i].opt != 0; i++) 991ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (usage[i].opt == option) 992ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 993ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat int rept = usage[i].rept; 994ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 995ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (nest == 0) 996ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 997ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* command line */ 998ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (rept == ARG_USED_CL) 999ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat return _("illegal repeated flag"); 1000ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (rept == ARG_ONE) 1001ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat usage[i].rept = ARG_USED_CL; 1002ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1003ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 1004ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1005ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* allow file to override command line */ 1006ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (rept == ARG_USED_FILE) 1007ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat return _("illegal repeated keyword"); 1008ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (rept == ARG_USED_CL || rept == ARG_ONE) 1009ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat usage[i].rept = ARG_USED_FILE; 1010ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1011ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1012ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (rept != ARG_DUP && rept != ARG_ONE && rept != ARG_USED_CL) 1013ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1014ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->options |= rept; 1015ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat return NULL; 1016ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1017ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1018ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1019ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1020ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1021ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat switch (option) 1022ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1023ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'C': /* --conf-file */ 1024ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1025ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *file = opt_string_alloc(arg); 1026ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (file) 1027ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1028ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat one_file(file, nest, 0); 1029ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat free(file); 1030ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1031ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1032ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1033ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1034ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case '7': /* --conf-dir */ 1035ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1036ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat DIR *dir_stream; 1037ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct dirent *ent; 1038ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *directory, *path; 1039ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct list { 1040ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *suffix; 1041ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct list *next; 1042ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } *ignore_suffix = NULL, *li; 1043ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1044ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat comma = split(arg); 1045ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!(directory = opt_string_alloc(arg))) 1046ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1047ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1048ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (arg = comma; arg; arg = comma) 1049ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1050ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat comma = split(arg); 1051ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat li = opt_malloc(sizeof(struct list)); 1052ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat li->next = ignore_suffix; 1053ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat ignore_suffix = li; 1054ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* Have to copy: buffer is overwritten */ 1055ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat li->suffix = opt_string_alloc(arg); 1056ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat }; 1057ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1058ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!(dir_stream = opendir(directory))) 1059ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat die(_("cannot access directory %s: %s"), directory, EC_FILE); 1060ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1061ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat while ((ent = readdir(dir_stream))) 1062ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1063ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat size_t len = strlen(ent->d_name); 1064ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct stat buf; 1065ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1066ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* ignore emacs backups and dotfiles */ 1067ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (len == 0 || 1068ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat ent->d_name[len - 1] == '~' || 1069ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat (ent->d_name[0] == '#' && ent->d_name[len - 1] == '#') || 1070ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat ent->d_name[0] == '.') 1071ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat continue; 1072ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1073ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (li = ignore_suffix; li; li = li->next) 1074ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1075ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* check for proscribed suffices */ 1076ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat size_t ls = strlen(li->suffix); 1077ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (len > ls && 1078ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat strcmp(li->suffix, &ent->d_name[len - ls]) == 0) 1079ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1080ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1081ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (li) 1082ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat continue; 1083ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1084ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat path = opt_malloc(strlen(directory) + len + 2); 1085ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat strcpy(path, directory); 1086ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat strcat(path, "/"); 1087ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat strcat(path, ent->d_name); 1088ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1089ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (stat(path, &buf) == -1) 1090ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat die(_("cannot access %s: %s"), path, EC_FILE); 1091ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* only reg files allowed. */ 1092ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!S_ISREG(buf.st_mode)) 1093ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat continue; 1094ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1095ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* dir is one level, so files must be readable */ 1096ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat one_file(path, nest + 1, 0); 1097ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat free(path); 1098ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1099ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1100ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat closedir(dir_stream); 1101ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat free(directory); 1102ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for(; ignore_suffix; ignore_suffix = li) 1103ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1104ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat li = ignore_suffix->next; 1105ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat free(ignore_suffix->suffix); 1106ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat free(ignore_suffix); 1107ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1108ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1109ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1110ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1111ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1112ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case '8': /* --log-facility */ 1113ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* may be a filename */ 1114ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (strchr(arg, '/')) 1115ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->log_file = opt_string_alloc(arg); 1116ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 11175658bcb797978c3472335d93554405aba8236f66San Mehat { 11185658bcb797978c3472335d93554405aba8236f66San Mehat#ifdef __ANDROID__ 11195658bcb797978c3472335d93554405aba8236f66San Mehat problem = "Android does not support log facilities"; 11205658bcb797978c3472335d93554405aba8236f66San Mehat#else 1121ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (i = 0; facilitynames[i].c_name; i++) 1122ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (hostname_isequal((char *)facilitynames[i].c_name, arg)) 1123ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1124ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1125ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (facilitynames[i].c_name) 1126ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->log_fac = facilitynames[i].c_val; 1127ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 1128ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat problem = "bad log facility"; 11295658bcb797978c3472335d93554405aba8236f66San Mehat#endif 1130ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1131ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1132ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1133ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'x': /* --pid-file */ 1134ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->runfile = opt_string_alloc(arg); 1135ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1136ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1137ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case LOPT_DHCP_HOST: /* --dhcp-hostfile */ 1138ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (daemon->dhcp_hosts_file) 1139ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat problem = _("only one dhcp-hostsfile allowed"); 1140ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 1141ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->dhcp_hosts_file = opt_string_alloc(arg); 1142ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1143ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1144ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case LOPT_DHCP_OPTS: /* --dhcp-optsfile */ 1145ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (daemon->dhcp_opts_file) 1146ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat problem = _("only one dhcp-optsfile allowed"); 1147ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 1148ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->dhcp_opts_file = opt_string_alloc(arg); 1149ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1150ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1151ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'r': /* --resolv-file */ 1152ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1153ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *name = opt_string_alloc(arg); 1154ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct resolvc *new, *list = daemon->resolv_files; 1155ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1156ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (list && list->is_default) 1157ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1158ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* replace default resolv file - possibly with nothing */ 1159ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (name) 1160ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1161ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat list->is_default = 0; 1162ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat list->name = name; 1163ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1164ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 1165ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat list = NULL; 1166ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1167ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (name) 1168ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1169ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new = opt_malloc(sizeof(struct resolvc)); 1170ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->next = list; 1171ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->name = name; 1172ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->is_default = 0; 1173ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->mtime = 0; 1174ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->logged = 0; 1175ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat list = new; 1176ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1177ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->resolv_files = list; 1178ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1179ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1180ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1181ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'm': /* --mx-host */ 1182ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1183ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat int pref = 1; 1184ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct mx_srv_record *new; 1185ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *name, *target = NULL; 1186ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1187ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if ((comma = split(arg))) 1188ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1189ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *prefstr; 1190ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if ((prefstr = split(comma)) && !atoi_check16(prefstr, &pref)) 1191ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat problem = _("bad MX preference"); 1192ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1193ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1194ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!(name = canonicalise_opt(arg)) || 1195ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat (comma && !(target = canonicalise_opt(comma)))) 1196ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat problem = _("bad MX name"); 1197ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1198ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new = opt_malloc(sizeof(struct mx_srv_record)); 1199ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->next = daemon->mxnames; 1200ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->mxnames = new; 1201ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->issrv = 0; 1202ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->name = name; 1203ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->target = target; /* may be NULL */ 1204ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->weight = pref; 1205ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1206ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1207ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1208ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 't': /* --mx-target */ 1209ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!(daemon->mxtarget = canonicalise_opt(arg))) 1210ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat problem = _("bad MX target"); 1211ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1212ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1213ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#ifdef HAVE_DHCP 1214ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'l': /* --dhcp-leasefile */ 1215ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->lease_file = opt_string_alloc(arg); 1216ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1217ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1218ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case '6': /* --dhcp-script */ 1219ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# if defined(NO_FORK) 1220ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat problem = _("cannot run scripts under uClinux"); 1221ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# elif !defined(HAVE_SCRIPT) 1222ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat problem = _("recompile with HAVE_SCRIPT defined to enable lease-change scripts"); 1223ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# else 1224ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->lease_change_command = opt_string_alloc(arg); 1225ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# endif 1226ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1227ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#endif 1228ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1229ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'H': /* --addn-hosts */ 1230ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1231ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct hostsfile *new = opt_malloc(sizeof(struct hostsfile)); 1232ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat static int hosts_index = 1; 1233ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->fname = opt_string_alloc(arg); 1234ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->index = hosts_index++; 1235ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->flags = 0; 1236ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->next = daemon->addn_hosts; 1237ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->addn_hosts = new; 1238ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1239ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1240ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1241ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 's': /* --domain */ 1242ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (strcmp (arg, "#") == 0) 1243ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->options |= OPT_RESOLV_DOMAIN; 1244ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 1245ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1246ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *d; 1247ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat comma = split(arg); 1248ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!(d = canonicalise_opt(arg))) 1249ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = '?'; 1250ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 1251ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1252ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (comma) 1253ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1254ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct cond_domain *new = safe_malloc(sizeof(struct cond_domain)); 1255ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat unhide_metas(comma); 1256ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if ((arg = split_chr(comma, '/'))) 1257ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1258ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat int mask; 1259ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if ((new->start.s_addr = inet_addr(comma)) == (in_addr_t)-1 || 1260ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat !atoi_check(arg, &mask)) 1261ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = '?'; 1262ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 1263ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1264ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat mask = (1 << (32 - mask)) - 1; 1265ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->start.s_addr = ntohl(htonl(new->start.s_addr) & ~mask); 1266ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->end.s_addr = new->start.s_addr | htonl(mask); 1267ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1268ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1269ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if ((arg = split(comma))) 1270ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1271ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if ((new->start.s_addr = inet_addr(comma)) == (in_addr_t)-1 || 1272ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat (new->end.s_addr = inet_addr(arg)) == (in_addr_t)-1) 1273ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = '?'; 1274ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1275ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if ((new->start.s_addr = new->end.s_addr = inet_addr(comma)) == (in_addr_t)-1) 1276ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = '?'; 1277ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1278ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->domain = d; 1279ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->next = daemon->cond_domain; 1280ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->cond_domain = new; 1281ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1282ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 1283ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->domain_suffix = d; 1284ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1285ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1286ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1287ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1288ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'u': /* --user */ 1289ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->username = opt_string_alloc(arg); 1290ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1291ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1292ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'g': /* --group */ 1293ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->groupname = opt_string_alloc(arg); 1294ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->group_set = 1; 1295ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1296ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1297ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#ifdef HAVE_DHCP 1298ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case LOPT_SCRIPTUSR: /* --scriptuser */ 1299ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->scriptuser = opt_string_alloc(arg); 1300ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1301ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#endif 1302ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1303ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'i': /* --interface */ 1304ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat do { 1305ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct iname *new = opt_malloc(sizeof(struct iname)); 1306ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat comma = split(arg); 1307ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->next = daemon->if_names; 1308ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->if_names = new; 1309ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* new->name may be NULL if someone does 1310ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat "interface=" to disable all interfaces except loop. */ 1311ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->name = opt_string_alloc(arg); 1312ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->isloop = new->used = 0; 1313ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat arg = comma; 1314ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } while (arg); 1315ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1316ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1317ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'I': /* --except-interface */ 1318ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case '2': /* --no-dhcp-interface */ 1319ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat do { 1320ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct iname *new = opt_malloc(sizeof(struct iname)); 1321ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat comma = split(arg); 1322ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->name = opt_string_alloc(arg); 1323ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (option == 'I') 1324ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1325ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->next = daemon->if_except; 1326ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->if_except = new; 1327ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1328ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 1329ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1330ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->next = daemon->dhcp_except; 1331ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->dhcp_except = new; 1332ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1333ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat arg = comma; 1334ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } while (arg); 1335ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1336ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1337ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'B': /* --bogus-nxdomain */ 1338ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1339ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct in_addr addr; 1340ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat unhide_metas(arg); 1341ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (arg && (addr.s_addr = inet_addr(arg)) != (in_addr_t)-1) 1342ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1343ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct bogus_addr *baddr = opt_malloc(sizeof(struct bogus_addr)); 1344ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat baddr->next = daemon->bogus_addr; 1345ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->bogus_addr = baddr; 1346ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat baddr->addr = addr; 1347ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1348ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 1349ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = '?'; /* error */ 1350ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1351ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1352ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1353ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'a': /* --listen-address */ 1354ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat do { 1355ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct iname *new = opt_malloc(sizeof(struct iname)); 1356ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat comma = split(arg); 1357ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat unhide_metas(arg); 1358ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->next = daemon->if_addrs; 1359513aae2733f6a7fa18d564934a79875dd73bc0a0Lorenzo Colitti if (arg && 1360513aae2733f6a7fa18d564934a79875dd73bc0a0Lorenzo Colitti parse_addr(AF_INET, arg, &new->addr) != 0 && 1361513aae2733f6a7fa18d564934a79875dd73bc0a0Lorenzo Colitti parse_addr(AF_INET6, arg, &new->addr) != 0) 1362ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1363ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = '?'; /* error */ 1364ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1365ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1366ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1367ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->if_addrs = new; 1368ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat arg = comma; 1369ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } while (arg); 1370ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1371ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1372ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'S': /* --server */ 1373ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case LOPT_LOCAL: /* --local */ 1374ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'A': /* --address */ 1375ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1376ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct server *serv, *newlist = NULL; 1377ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1378ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat unhide_metas(arg); 1379ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1380ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (arg && *arg == '/') 1381ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1382ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *end; 1383ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat arg++; 1384ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat while ((end = split_chr(arg, '/'))) 1385ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1386ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *domain = NULL; 1387ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* # matches everything and becomes a zero length domain string */ 1388ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (strcmp(arg, "#") == 0) 1389ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat domain = ""; 1390ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (strlen (arg) != 0 && !(domain = canonicalise_opt(arg))) 1391ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = '?'; 1392ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat serv = opt_malloc(sizeof(struct server)); 1393ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat memset(serv, 0, sizeof(struct server)); 1394ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat serv->next = newlist; 1395ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat newlist = serv; 1396ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat serv->domain = domain; 1397ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat serv->flags = domain ? SERV_HAS_DOMAIN : SERV_FOR_NODOTS; 1398ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat arg = end; 1399ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1400ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!newlist) 1401ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1402ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = '?'; 1403ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1404ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1405ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1406ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1407ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 1408ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1409ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat newlist = opt_malloc(sizeof(struct server)); 1410ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat memset(newlist, 0, sizeof(struct server)); 1411ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1412ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1413ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (option == 'A') 1414ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1415ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat newlist->flags |= SERV_LITERAL_ADDRESS; 1416ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!(newlist->flags & SERV_TYPE)) 1417ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = '?'; 1418ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1419ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1420ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!arg || !*arg) 1421ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1422ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat newlist->flags |= SERV_NO_ADDR; /* no server */ 1423ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (newlist->flags & SERV_LITERAL_ADDRESS) 1424ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = '?'; 1425ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1426ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 1427ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1428ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat int source_port = 0, serv_port = NAMESERVER_PORT; 1429ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *portno, *source; 1430ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1431ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if ((source = split_chr(arg, '@')) && /* is there a source. */ 1432ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat (portno = split_chr(source, '#')) && 1433ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat !atoi_check16(portno, &source_port)) 1434ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat problem = _("bad port"); 1435ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1436ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if ((portno = split_chr(arg, '#')) && /* is there a port no. */ 1437ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat !atoi_check16(portno, &serv_port)) 1438ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat problem = _("bad port"); 1439ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1440513aae2733f6a7fa18d564934a79875dd73bc0a0Lorenzo Colitti if (parse_addr(AF_INET, arg, &newlist->addr) == 0) 1441ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1442ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat newlist->addr.in.sin_port = htons(serv_port); 1443ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#ifdef HAVE_SOCKADDR_SA_LEN 1444ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat newlist->source_addr.in.sin_len = newlist->addr.in.sin_len = sizeof(struct sockaddr_in); 1445ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#endif 1446ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (source) 1447ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1448ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat newlist->flags |= SERV_HAS_SOURCE; 1449513aae2733f6a7fa18d564934a79875dd73bc0a0Lorenzo Colitti if (parse_addr(AF_INET, source, &newlist->addr) != 0) 1450ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1451ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#if defined(SO_BINDTODEVICE) 1452ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat newlist->source_addr.in.sin_addr.s_addr = INADDR_ANY; 1453ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat strncpy(newlist->interface, source, IF_NAMESIZE); 1454ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#else 1455ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat problem = _("interface binding not supported"); 1456ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#endif 1457ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1458ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1459ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 1460ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat newlist->source_addr.in.sin_addr.s_addr = INADDR_ANY; 1461513aae2733f6a7fa18d564934a79875dd73bc0a0Lorenzo Colitti 1462513aae2733f6a7fa18d564934a79875dd73bc0a0Lorenzo Colitti newlist->source_addr.in.sin_port = htons(source_port); 1463513aae2733f6a7fa18d564934a79875dd73bc0a0Lorenzo Colitti newlist->source_addr.sa.sa_family = AF_INET; 1464ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1465ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#ifdef HAVE_IPV6 1466513aae2733f6a7fa18d564934a79875dd73bc0a0Lorenzo Colitti else if (parse_addr(AF_INET6, arg, &newlist->addr) == 0) 1467ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1468ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat newlist->addr.in6.sin6_port = htons(serv_port); 1469ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (source) 1470ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1471ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat newlist->flags |= SERV_HAS_SOURCE; 1472513aae2733f6a7fa18d564934a79875dd73bc0a0Lorenzo Colitti if (parse_addr(AF_INET6, source, &newlist->source_addr) != 0) 1473ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1474ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#if defined(SO_BINDTODEVICE) 1475ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat newlist->source_addr.in6.sin6_addr = in6addr_any; 1476ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat strncpy(newlist->interface, source, IF_NAMESIZE); 1477ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#else 1478ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat problem = _("interface binding not supported"); 1479ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#endif 1480ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1481ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1482ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 1483ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat newlist->source_addr.in6.sin6_addr = in6addr_any; 1484513aae2733f6a7fa18d564934a79875dd73bc0a0Lorenzo Colitti 1485513aae2733f6a7fa18d564934a79875dd73bc0a0Lorenzo Colitti newlist->source_addr.in6.sin6_port = htons(source_port); 1486513aae2733f6a7fa18d564934a79875dd73bc0a0Lorenzo Colitti newlist->source_addr.sa.sa_family = AF_INET6; 1487ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1488ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#endif 1489ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 1490ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = '?'; /* error */ 1491ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1492ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1493ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1494ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat serv = newlist; 1495ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat while (serv->next) 1496ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1497ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat serv->next->flags = serv->flags; 1498ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat serv->next->addr = serv->addr; 1499ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat serv->next->source_addr = serv->source_addr; 1500ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat serv = serv->next; 1501ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1502ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat serv->next = daemon->servers; 1503ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->servers = newlist; 1504ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1505ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1506ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1507ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'c': /* --cache-size */ 1508ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1509ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat int size; 1510ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1511ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!atoi_check(arg, &size)) 1512ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = '?'; 1513ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 1514ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1515ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* zero is OK, and means no caching. */ 1516ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1517ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (size < 0) 1518ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat size = 0; 1519ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (size > 10000) 1520ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat size = 10000; 1521ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1522ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->cachesize = size; 1523ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1524ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1525ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1526ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1527ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'p': /* --port */ 1528ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!atoi_check16(arg, &daemon->port)) 1529ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = '?'; 1530ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1531ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1532ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case LOPT_MINPORT: /* --min-port */ 1533ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!atoi_check16(arg, &daemon->min_port)) 1534ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = '?'; 1535ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1536ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1537ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case '0': /* --dns-forward-max */ 1538ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!atoi_check(arg, &daemon->ftabsize)) 1539ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = '?'; 1540ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1541ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1542ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case LOPT_MAX_LOGS: /* --log-async */ 1543ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->max_logs = LOG_MAX; /* default */ 1544ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (arg && !atoi_check(arg, &daemon->max_logs)) 1545ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = '?'; 1546ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (daemon->max_logs > 100) 1547ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->max_logs = 100; 1548ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1549ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1550ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'P': /* --edns-packet-max */ 1551ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1552ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat int i; 1553ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!atoi_check(arg, &i)) 1554ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = '?'; 1555ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->edns_pktsz = (unsigned short)i; 1556ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1557ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1558ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1559ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'Q': /* --query-port */ 1560ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!atoi_check16(arg, &daemon->query_port)) 1561ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = '?'; 1562ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* if explicitly set to zero, use single OS ephemeral port 1563ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat and disable random ports */ 1564ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (daemon->query_port == 0) 1565ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->osport = 1; 1566ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1567ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1568ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'T': /* --local-ttl */ 1569ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case LOPT_NEGTTL: /* --neg-ttl */ 1570ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1571ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat int ttl; 1572ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!atoi_check(arg, &ttl)) 1573ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = '?'; 1574ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (option == LOPT_NEGTTL) 1575ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->neg_ttl = (unsigned long)ttl; 1576ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 1577ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->local_ttl = (unsigned long)ttl; 1578ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1579ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1580ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1581ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#ifdef HAVE_DHCP 1582ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'X': /* --dhcp-lease-max */ 1583ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!atoi_check(arg, &daemon->dhcp_max)) 1584ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = '?'; 1585ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1586ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#endif 1587ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1588ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case LOPT_BRIDGE: /* --bridge-interface */ 1589ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1590ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct dhcp_bridge *new = opt_malloc(sizeof(struct dhcp_bridge)); 1591ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!(comma = split(arg))) 1592ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1593ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat problem = _("bad bridge-interface"); 1594ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1595ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1596ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1597ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat strncpy(new->iface, arg, IF_NAMESIZE); 1598ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->alias = NULL; 1599ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->next = daemon->bridges; 1600ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->bridges = new; 1601ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1602ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat do { 1603ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat arg = comma; 1604ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat comma = split(arg); 1605ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (strlen(arg) != 0) 1606ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1607ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct dhcp_bridge *b = opt_malloc(sizeof(struct dhcp_bridge)); 1608ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat b->next = new->alias; 1609ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->alias = b; 1610ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat strncpy(b->iface, arg, IF_NAMESIZE); 1611ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1612ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } while (comma); 1613ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1614ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1615ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1616ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1617ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#ifdef HAVE_DHCP 1618ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'F': /* --dhcp-range */ 1619ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1620ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat int k, leasepos = 2; 1621ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *cp, *a[5] = { NULL, NULL, NULL, NULL, NULL }; 1622ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct dhcp_context *new = opt_malloc(sizeof(struct dhcp_context)); 1623ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1624ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->next = daemon->dhcp; 1625ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->lease_time = DEFLEASE; 1626ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->addr_epoch = 0; 1627ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->netmask.s_addr = 0; 1628ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->broadcast.s_addr = 0; 1629ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->router.s_addr = 0; 1630ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->netid.net = NULL; 1631ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->filter = NULL; 1632ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->flags = 0; 1633ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1634ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat gen_prob = _("bad dhcp-range"); 1635ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1636ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!arg) 1637ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1638ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = '?'; 1639ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1640ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1641ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1642ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat while(1) 1643ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1644ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (cp = arg; *cp; cp++) 1645ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!(*cp == ' ' || *cp == '.' || (*cp >='0' && *cp <= '9'))) 1646ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1647ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1648ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (*cp != ',' && (comma = split(arg))) 1649ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1650ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (strstr(arg, "net:") == arg) 1651ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1652ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct dhcp_netid *tt = opt_malloc(sizeof (struct dhcp_netid)); 1653ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat tt->net = opt_string_alloc(arg+4); 1654ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat tt->next = new->filter; 1655ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->filter = tt; 1656ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1657ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 1658ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1659ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (new->netid.net) 1660ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat problem = _("only one netid tag allowed"); 1661ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 1662ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->netid.net = opt_string_alloc(arg); 1663ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1664ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat arg = comma; 1665ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1666ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 1667ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1668ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat a[0] = arg; 1669ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1670ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1671ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1672ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1673ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (k = 1; k < 5; k++) 1674ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!(a[k] = split(a[k-1]))) 1675ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1676ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1677ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if ((k < 2) || ((new->start.s_addr = inet_addr(a[0])) == (in_addr_t)-1)) 1678ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = '?'; 1679ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (strcmp(a[1], "static") == 0) 1680ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1681ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->end = new->start; 1682ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->flags |= CONTEXT_STATIC; 1683ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1684ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (strcmp(a[1], "proxy") == 0) 1685ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1686ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->end = new->start; 1687ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->flags |= CONTEXT_PROXY; 1688ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1689ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if ((new->end.s_addr = inet_addr(a[1])) == (in_addr_t)-1) 1690ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = '?'; 1691ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1692ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (ntohl(new->start.s_addr) > ntohl(new->end.s_addr)) 1693ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1694ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct in_addr tmp = new->start; 1695ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->start = new->end; 1696ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->end = tmp; 1697ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1698ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1699ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (option != '?' && k >= 3 && strchr(a[2], '.') && 1700ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat ((new->netmask.s_addr = inet_addr(a[2])) != (in_addr_t)-1)) 1701ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1702ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->flags |= CONTEXT_NETMASK; 1703ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat leasepos = 3; 1704ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!is_same_net(new->start, new->end, new->netmask)) 1705ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat problem = _("inconsistent DHCP range"); 1706ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1707ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->dhcp = new; 1708ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1709ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (k >= 4 && strchr(a[3], '.') && 1710ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat ((new->broadcast.s_addr = inet_addr(a[3])) != (in_addr_t)-1)) 1711ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1712ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->flags |= CONTEXT_BRDCAST; 1713ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat leasepos = 4; 1714ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1715ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1716ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (k >= leasepos+1) 1717ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1718ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (strcmp(a[leasepos], "infinite") == 0) 1719ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->lease_time = 0xffffffff; 1720ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 1721ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1722ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat int fac = 1; 1723ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (strlen(a[leasepos]) > 0) 1724ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1725ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat switch (a[leasepos][strlen(a[leasepos]) - 1]) 1726ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1727ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'd': 1728ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'D': 1729ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat fac *= 24; 1730ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* fall though */ 1731ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'h': 1732ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'H': 1733ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat fac *= 60; 1734ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* fall through */ 1735ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'm': 1736ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'M': 1737ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat fac *= 60; 1738ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* fall through */ 1739ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 's': 1740ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'S': 1741ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat a[leasepos][strlen(a[leasepos]) - 1] = 0; 1742ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1743ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1744ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->lease_time = atoi(a[leasepos]) * fac; 1745ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* Leases of a minute or less confuse 1746ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat some clients, notably Apple's */ 1747ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (new->lease_time < 120) 1748ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->lease_time = 120; 1749ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1750ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1751ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1752ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1753ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1754ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1755ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case LOPT_BANK: 1756ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'G': /* --dhcp-host */ 1757ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1758ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat int j, k = 0; 1759ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *a[6] = { NULL, NULL, NULL, NULL, NULL, NULL }; 1760ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct dhcp_config *new; 1761ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct in_addr in; 1762ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1763ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new = opt_malloc(sizeof(struct dhcp_config)); 1764ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1765ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->next = daemon->dhcp_conf; 1766ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->flags = (option == LOPT_BANK) ? CONFIG_BANK : 0; 1767ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->hwaddr = NULL; 1768ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1769ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if ((a[0] = arg)) 1770ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (k = 1; k < 6; k++) 1771ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!(a[k] = split(a[k-1]))) 1772ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1773ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1774ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (j = 0; j < k; j++) 1775ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (strchr(a[j], ':')) /* ethernet address, netid or binary CLID */ 1776ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1777ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *arg = a[j]; 1778ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1779ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if ((arg[0] == 'i' || arg[0] == 'I') && 1780ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat (arg[1] == 'd' || arg[1] == 'D') && 1781ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat arg[2] == ':') 1782ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1783ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (arg[3] == '*') 1784ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->flags |= CONFIG_NOCLID; 1785ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 1786ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1787ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat int len; 1788ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat arg += 3; /* dump id: */ 1789ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (strchr(arg, ':')) 1790ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat len = parse_hex(arg, (unsigned char *)arg, -1, NULL, NULL); 1791ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 1792ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1793ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat unhide_metas(arg); 1794ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat len = (int) strlen(arg); 1795ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1796ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1797ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if ((new->clid = opt_malloc(len))) 1798ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1799ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->flags |= CONFIG_CLID; 1800ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->clid_len = len; 1801ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat memcpy(new->clid, arg, len); 1802ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1803ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1804ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1805ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (strstr(arg, "net:") == arg) 1806ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1807ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat int len = strlen(arg + 4) + 1; 1808ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if ((new->netid.net = opt_malloc(len))) 1809ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1810ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->flags |= CONFIG_NETID; 1811ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat strcpy(new->netid.net, arg+4); 1812ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat unhide_metas(new->netid.net); 1813ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1814ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1815ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 1816ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1817ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct hwaddr_config *newhw = opt_malloc(sizeof(struct hwaddr_config)); 1818ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat newhw->next = new->hwaddr; 1819ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->hwaddr = newhw; 1820ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat newhw->hwaddr_len = parse_hex(a[j], newhw->hwaddr, DHCP_CHADDR_MAX, 1821ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat &newhw->wildcard_mask, &newhw->hwaddr_type); 1822ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1823ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1824ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (strchr(a[j], '.') && (in.s_addr = inet_addr(a[j])) != (in_addr_t)-1) 1825ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1826ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->addr = in; 1827ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->flags |= CONFIG_ADDR; 1828ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1829ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 1830ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1831ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *cp, *lastp = NULL, last = 0; 1832ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat int fac = 1; 1833ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1834ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (strlen(a[j]) > 1) 1835ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1836ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat lastp = a[j] + strlen(a[j]) - 1; 1837ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat last = *lastp; 1838ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat switch (last) 1839ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1840ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'd': 1841ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'D': 1842ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat fac *= 24; 1843ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* fall through */ 1844ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'h': 1845ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'H': 1846ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat fac *= 60; 1847ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* fall through */ 1848ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'm': 1849ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'M': 1850ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat fac *= 60; 1851ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* fall through */ 1852ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 's': 1853ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'S': 1854ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat *lastp = 0; 1855ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1856ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1857ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1858ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (cp = a[j]; *cp; cp++) 1859ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!isdigit((int)*cp) && *cp != ' ') 1860ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1861ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1862ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (*cp) 1863ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1864ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (lastp) 1865ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat *lastp = last; 1866ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (strcmp(a[j], "infinite") == 0) 1867ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1868ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->lease_time = 0xffffffff; 1869ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->flags |= CONFIG_TIME; 1870ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1871ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (strcmp(a[j], "ignore") == 0) 1872ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->flags |= CONFIG_DISABLE; 1873ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 1874ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1875ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!(new->hostname = canonicalise_opt(a[j])) || 1876ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat !legal_hostname(new->hostname)) 1877ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat problem = _("bad DHCP host name"); 1878ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 1879ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->flags |= CONFIG_NAME; 1880ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->domain = NULL; 1881ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1882ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1883ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 1884ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1885ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->lease_time = atoi(a[j]) * fac; 1886ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* Leases of a minute or less confuse 1887ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat some clients, notably Apple's */ 1888ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (new->lease_time < 120) 1889ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->lease_time = 120; 1890ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->flags |= CONFIG_TIME; 1891ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1892ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1893ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1894ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->dhcp_conf = new; 1895ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1896ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1897ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1898ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'O': /* --dhcp-option */ 1899ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case LOPT_FORCE: /* --dhcp-option-force */ 1900ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case LOPT_OPTS: 1901ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case LOPT_MATCH: /* --dhcp-match */ 1902ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat problem = parse_dhcp_opt(arg, 1903ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option == LOPT_FORCE ? DHOPT_FORCE : 1904ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat (option == LOPT_MATCH ? DHOPT_MATCH : 1905ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat (option == LOPT_OPTS ? DHOPT_BANK : 0))); 1906ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1907ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1908ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'M': /* --dhcp-boot */ 1909ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1910ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct dhcp_netid *id = NULL; 1911ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat while (arg && strstr(arg, "net:") == arg) 1912ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1913ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct dhcp_netid *newid = opt_malloc(sizeof(struct dhcp_netid)); 1914ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat newid->next = id; 1915ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat id = newid; 1916ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat comma = split(arg); 1917ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat newid->net = opt_string_alloc(arg+4); 1918ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat arg = comma; 1919ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat }; 1920ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1921ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!arg) 1922ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = '?'; 1923ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 1924ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1925ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *dhcp_file, *dhcp_sname = NULL; 1926ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct in_addr dhcp_next_server; 1927ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat comma = split(arg); 1928ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat dhcp_file = opt_string_alloc(arg); 1929ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat dhcp_next_server.s_addr = 0; 1930ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (comma) 1931ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1932ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat arg = comma; 1933ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat comma = split(arg); 1934ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat dhcp_sname = opt_string_alloc(arg); 1935ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (comma) 1936ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1937ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat unhide_metas(comma); 1938ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if ((dhcp_next_server.s_addr = inet_addr(comma)) == (in_addr_t)-1) 1939ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = '?'; 1940ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1941ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1942ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (option != '?') 1943ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1944ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct dhcp_boot *new = opt_malloc(sizeof(struct dhcp_boot)); 1945ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->file = dhcp_file; 1946ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->sname = dhcp_sname; 1947ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->next_server = dhcp_next_server; 1948ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->netid = id; 1949ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->next = daemon->boot_config; 1950ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->boot_config = new; 1951ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1952ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1953ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1954ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1955ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1956ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1957ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case LOPT_PXE_PROMT: /* --pxe-prompt */ 1958ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1959ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct dhcp_opt *new = opt_malloc(sizeof(struct dhcp_opt)); 1960ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat int timeout; 1961ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1962ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->netid = NULL; 1963ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->opt = 10; /* PXE_MENU_PROMPT */ 1964ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1965ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat while (arg && strstr(arg, "net:") == arg) 1966ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1967ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct dhcp_netid *nn = opt_malloc(sizeof (struct dhcp_netid)); 1968ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat comma = split(arg); 1969ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat nn->next = new->netid; 1970ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->netid = nn; 1971ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat nn->net = opt_string_alloc(arg+4); 1972ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat arg = comma; 1973ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1974ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1975ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!arg) 1976ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = '?'; 1977ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 1978ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 1979ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat comma = split(arg); 1980ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat unhide_metas(arg); 1981ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->len = strlen(arg) + 1; 1982ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->val = opt_malloc(new->len); 1983ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat memcpy(new->val + 1, arg, new->len - 1); 1984ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1985ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->u.vendor_class = (unsigned char *)"PXEClient"; 1986ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->flags = DHOPT_VENDOR; 1987ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1988ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (comma && atoi_check(comma, &timeout)) 1989ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat *(new->val) = timeout; 1990ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 1991ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat *(new->val) = 255; 1992ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1993ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->next = daemon->dhcp_opts; 1994ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->dhcp_opts = new; 1995ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->enable_pxe = 1; 1996ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 1997ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 1998ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 1999ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2000ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2001ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case LOPT_PXE_SERV: /* --pxe-service */ 2002ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2003ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct pxe_service *new = opt_malloc(sizeof(struct pxe_service)); 2004ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *CSA[] = { "x86PC", "PC98", "IA64_EFI", "Alpha", "Arc_x86", "Intel_Lean_Client", 2005ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat "IA32_EFI", "BC_EFI", "Xscale_EFI", "x86-64_EFI", NULL }; 2006ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat static int boottype = 32768; 2007ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2008ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->netid = NULL; 2009ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->server.s_addr = 0; 2010ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2011ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat while (arg && strstr(arg, "net:") == arg) 2012ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2013ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct dhcp_netid *nn = opt_malloc(sizeof (struct dhcp_netid)); 2014ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat comma = split(arg); 2015ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat nn->next = new->netid; 2016ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->netid = nn; 2017ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat nn->net = opt_string_alloc(arg+4); 2018ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat arg = comma; 2019ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2020ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2021ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (arg && (comma = split(arg))) 2022ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2023ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (i = 0; CSA[i]; i++) 2024ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (strcasecmp(CSA[i], arg) == 0) 2025ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 2026ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2027ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (CSA[i] || atoi_check(arg, &i)) 2028ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2029ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat arg = comma; 2030ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat comma = split(arg); 2031ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2032ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->CSA = i; 2033ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->menu = opt_string_alloc(arg); 2034ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2035ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (comma) 2036ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2037ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat arg = comma; 2038ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat comma = split(arg); 2039ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (atoi_check(arg, &i)) 2040ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2041ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->type = i; 2042ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->basename = NULL; 2043ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2044ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 2045ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2046ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->type = boottype++; 2047ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->basename = opt_string_alloc(arg); 2048ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2049ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2050ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (comma && (new->server.s_addr = inet_addr(comma)) == (in_addr_t)-1) 2051ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = '?'; 2052ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2053ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* Order matters */ 2054ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->next = NULL; 2055ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!daemon->pxe_services) 2056ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->pxe_services = new; 2057ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 2058ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2059ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct pxe_service *s; 2060ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (s = daemon->pxe_services; s->next; s = s->next); 2061ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat s->next = new; 2062ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2063ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2064ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->enable_pxe = 1; 2065ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 2066ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2067ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2068ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2069ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2070ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = '?'; 2071ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 2072ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2073ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2074ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case '4': /* --dhcp-mac */ 2075ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2076ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!(comma = split(arg))) 2077ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = '?'; 2078ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 2079ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2080ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct dhcp_mac *new = opt_malloc(sizeof(struct dhcp_mac)); 2081ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (strstr(arg, "net:") == arg) 2082ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->netid.net = opt_string_alloc(arg+4); 2083ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 2084ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->netid.net = opt_string_alloc(arg); 2085ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat unhide_metas(comma); 2086ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->hwaddr_len = parse_hex(comma, new->hwaddr, DHCP_CHADDR_MAX, &new->mask, &new->hwaddr_type); 2087ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->next = daemon->dhcp_macs; 2088ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->dhcp_macs = new; 2089ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2090ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2091ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 2092ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2093ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'U': /* --dhcp-vendorclass */ 2094ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'j': /* --dhcp-userclass */ 2095ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case LOPT_CIRCUIT: /* --dhcp-circuitid */ 2096ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case LOPT_REMOTE: /* --dhcp-remoteid */ 2097ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case LOPT_SUBSCR: /* --dhcp-subscrid */ 2098ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2099ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!(comma = split(arg))) 2100ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = '?'; 2101ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 2102ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2103ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *p; 2104ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat int dig = 0; 2105ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct dhcp_vendor *new = opt_malloc(sizeof(struct dhcp_vendor)); 2106ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (strstr(arg, "net:") == arg) 2107ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->netid.net = opt_string_alloc(arg+4); 2108ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 2109ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->netid.net = opt_string_alloc(arg); 2110ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* check for hex string - must digits may include : must not have nothing else, 2111ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat only allowed for agent-options. */ 2112ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (p = comma; *p; p++) 2113ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (isxdigit((int)*p)) 2114ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat dig = 1; 2115ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (*p != ':') 2116ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 2117ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat unhide_metas(comma); 2118ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (option == 'U' || option == 'j' || *p || !dig) 2119ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2120ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->len = strlen(comma); 2121ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->data = opt_malloc(new->len); 2122ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat memcpy(new->data, comma, new->len); 2123ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2124ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 2125ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2126ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->len = parse_hex(comma, (unsigned char *)comma, strlen(comma), NULL, NULL); 2127ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->data = opt_malloc(new->len); 2128ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat memcpy(new->data, comma, new->len); 2129ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2130ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2131ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat switch (option) 2132ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2133ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'j': 2134ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->match_type = MATCH_USER; 2135ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 2136ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'U': 2137ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->match_type = MATCH_VENDOR; 2138ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 2139ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case LOPT_CIRCUIT: 2140ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->match_type = MATCH_CIRCUIT; 2141ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 2142ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case LOPT_REMOTE: 2143ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->match_type = MATCH_REMOTE; 2144ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 2145ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case LOPT_SUBSCR: 2146ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->match_type = MATCH_SUBSCRIBER; 2147ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 2148ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2149ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->next = daemon->dhcp_vendors; 2150ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->dhcp_vendors = new; 2151ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2152ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 2153ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2154ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2155ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case LOPT_ALTPORT: /* --dhcp-alternate-port */ 2156ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!arg) 2157ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2158ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->dhcp_server_port = DHCP_SERVER_ALTPORT; 2159ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->dhcp_client_port = DHCP_CLIENT_ALTPORT; 2160ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2161ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 2162ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2163ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat comma = split(arg); 2164ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!atoi_check16(arg, &daemon->dhcp_server_port) || 2165ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat (comma && !atoi_check16(comma, &daemon->dhcp_client_port))) 2166ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat problem = _("invalid port number"); 2167ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!comma) 2168ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->dhcp_client_port = daemon->dhcp_server_port+1; 2169ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2170ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 2171ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2172ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'J': /* --dhcp-ignore */ 2173ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case LOPT_NO_NAMES: /* --dhcp-ignore-names */ 2174ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case LOPT_BROADCAST: /* --dhcp-broadcast */ 2175ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case '3': /* --bootp-dynamic */ 2176ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2177ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct dhcp_netid_list *new = opt_malloc(sizeof(struct dhcp_netid_list)); 2178ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct dhcp_netid *list = NULL; 2179ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (option == 'J') 2180ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2181ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->next = daemon->dhcp_ignore; 2182ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->dhcp_ignore = new; 2183ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2184ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (option == LOPT_BROADCAST) 2185ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2186ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->next = daemon->force_broadcast; 2187ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->force_broadcast = new; 2188ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2189ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (option == '3') 2190ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2191ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->next = daemon->bootp_dynamic; 2192ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->bootp_dynamic = new; 2193ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2194ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 2195ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2196ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->next = daemon->dhcp_ignore_names; 2197ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->dhcp_ignore_names = new; 2198ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2199ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2200ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat while (arg) { 2201ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct dhcp_netid *member = opt_malloc(sizeof(struct dhcp_netid)); 2202ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat comma = split(arg); 2203ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat member->next = list; 2204ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat list = member; 2205ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (strstr(arg, "net:") == arg) 2206ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat member->net = opt_string_alloc(arg+4); 2207ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 2208ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat member->net = opt_string_alloc(arg); 2209ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat arg = comma; 2210ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2211ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2212ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->list = list; 2213ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 2214ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2215ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#endif 2216ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2217ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'V': /* --alias */ 2218ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2219ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *dash, *a[3] = { NULL, NULL, NULL }; 2220ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat int k = 0; 2221ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct doctor *new = opt_malloc(sizeof(struct doctor)); 2222ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->next = daemon->doctors; 2223ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->doctors = new; 2224ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->mask.s_addr = 0xffffffff; 2225ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->end.s_addr = 0; 2226ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2227ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if ((a[0] = arg)) 2228ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (k = 1; k < 3; k++) 2229ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2230ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!(a[k] = split(a[k-1]))) 2231ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 2232ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat unhide_metas(a[k]); 2233ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2234ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2235ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat dash = split_chr(a[0], '-'); 2236ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2237ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if ((k < 2) || 2238ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat ((new->in.s_addr = inet_addr(a[0])) == (in_addr_t)-1) || 2239ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat ((new->out.s_addr = inet_addr(a[1])) == (in_addr_t)-1)) 2240ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = '?'; 2241ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2242ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (k == 3) 2243ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->mask.s_addr = inet_addr(a[2]); 2244ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2245ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (dash && 2246ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat ((new->end.s_addr = inet_addr(dash)) == (in_addr_t)-1 || 2247ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat !is_same_net(new->in, new->end, new->mask) || 2248ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat ntohl(new->in.s_addr) > ntohl(new->end.s_addr))) 2249ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat problem = _("invalid alias range"); 2250ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2251ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 2252ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2253ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2254ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case LOPT_INTNAME: /* --interface-name */ 2255ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2256ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct interface_name *new, **up; 2257ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *domain = NULL; 2258ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2259ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat comma = split(arg); 2260ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2261ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!comma || !(domain = canonicalise_opt(arg))) 2262ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat problem = _("bad interface name"); 2263ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2264ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new = opt_malloc(sizeof(struct interface_name)); 2265ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->next = NULL; 2266ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* Add to the end of the list, so that first name 2267ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat of an interface is used for PTR lookups. */ 2268ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (up = &daemon->int_names; *up; up = &((*up)->next)); 2269ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat *up = new; 2270ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->name = domain; 2271ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->intr = opt_string_alloc(comma); 2272ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 2273ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2274ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2275ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case LOPT_CNAME: /* --cname */ 2276ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2277ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct cname *new; 2278ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2279ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!(comma = split(arg))) 2280ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = '?'; 2281ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 2282ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2283ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *alias = canonicalise_opt(arg); 2284ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *target = canonicalise_opt(comma); 2285ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2286ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!alias || !target) 2287ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat problem = _("bad CNAME"); 2288ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 2289ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2290ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (new = daemon->cnames; new; new = new->next) 2291ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (hostname_isequal(new->alias, arg)) 2292ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat problem = _("duplicate CNAME"); 2293ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new = opt_malloc(sizeof(struct cname)); 2294ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->next = daemon->cnames; 2295ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->cnames = new; 2296ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->alias = alias; 2297ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->target = target; 2298ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2299ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2300ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 2301ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2302ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2303ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case LOPT_PTR: /* --ptr-record */ 2304ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2305ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct ptr_record *new; 2306ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *dom, *target = NULL; 2307ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2308ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat comma = split(arg); 2309ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2310ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!(dom = canonicalise_opt(arg)) || 2311ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat (comma && !(target = canonicalise_opt(comma)))) 2312ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat problem = _("bad PTR record"); 2313ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 2314ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2315ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new = opt_malloc(sizeof(struct ptr_record)); 2316ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->next = daemon->ptr; 2317ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->ptr = new; 2318ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->name = dom; 2319ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->ptr = target; 2320ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2321ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 2322ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2323ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2324ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case LOPT_NAPTR: /* --naptr-record */ 2325ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2326ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *a[7] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; 2327ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat int k = 0; 2328ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct naptr *new; 2329ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat int order, pref; 2330ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *name, *replace = NULL; 2331ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2332ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if ((a[0] = arg)) 2333ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (k = 1; k < 7; k++) 2334ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!(a[k] = split(a[k-1]))) 2335ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 2336ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2337ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2338ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (k < 6 || 2339ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat !(name = canonicalise_opt(a[0])) || 2340ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat !atoi_check16(a[1], &order) || 2341ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat !atoi_check16(a[2], &pref) || 2342ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat (k == 7 && !(replace = canonicalise_opt(a[6])))) 2343ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat problem = _("bad NAPTR record"); 2344ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 2345ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2346ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new = opt_malloc(sizeof(struct naptr)); 2347ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->next = daemon->naptr; 2348ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->naptr = new; 2349ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->name = name; 2350ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->flags = opt_string_alloc(a[3]); 2351ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->services = opt_string_alloc(a[4]); 2352ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->regexp = opt_string_alloc(a[5]); 2353ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->replace = replace; 2354ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->order = order; 2355ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->pref = pref; 2356ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2357ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 2358ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2359ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2360ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'Y': /* --txt-record */ 2361ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2362ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct txt_record *new; 2363ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat unsigned char *p, *q; 2364ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2365ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if ((comma = split(arg))) 2366ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat comma--; 2367ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2368ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat gen_prob = _("TXT record string too long"); 2369ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2370ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if ((q = (unsigned char *)comma)) 2371ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat while (1) 2372ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2373ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat size_t len; 2374ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if ((p = (unsigned char *)strchr((char*)q+1, ','))) 2375ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2376ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if ((len = p - q - 1) > 255) 2377ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = '?'; 2378ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat *q = len; 2379ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (q = q+1; q < p; q++) 2380ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat *q = unhide_meta(*q); 2381ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2382ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 2383ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2384ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if ((len = strlen((char *)q+1)) > 255) 2385ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = '?'; 2386ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat *q = len; 2387ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (q = q+1; *q; q++) 2388ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat *q = unhide_meta(*q); 2389ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 2390ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2391ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2392ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2393ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new = opt_malloc(sizeof(struct txt_record)); 2394ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->next = daemon->txt; 2395ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->txt = new; 2396ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->class = C_IN; 2397ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (comma) 2398ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2399ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->len = q - ((unsigned char *)comma); 2400ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->txt = opt_malloc(new->len); 2401ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat memcpy(new->txt, comma, new->len); 2402ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2403ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 2404ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2405ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat static char empty[] = ""; 2406ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->len = 1; 2407ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->txt = empty; 2408ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2409ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2410ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* ensure arg is terminated */ 2411ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (comma) 2412ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat *comma = 0; 2413ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2414ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!(new->name = canonicalise_opt(arg))) 2415ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2416ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat problem = _("bad TXT record"); 2417ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 2418ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2419ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2420ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 2421ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2422ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2423ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat case 'W': /* --srv-host */ 2424ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2425ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat int port = 1, priority = 0, weight = 0; 2426ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *name, *target = NULL; 2427ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct mx_srv_record *new; 2428ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2429ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat comma = split(arg); 2430ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2431ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!(name = canonicalise_opt(arg))) 2432ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat problem = _("bad SRV record"); 2433ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2434ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (comma) 2435ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2436ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat arg = comma; 2437ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat comma = split(arg); 2438ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!(target = canonicalise_opt(arg)) 2439ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat) problem = _("bad SRV target"); 2440ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2441ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (comma) 2442ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2443ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat arg = comma; 2444ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat comma = split(arg); 2445ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!atoi_check16(arg, &port)) 2446ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat problem = _("invalid port number"); 2447ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2448ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (comma) 2449ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2450ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat arg = comma; 2451ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat comma = split(arg); 2452ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!atoi_check16(arg, &priority)) 2453ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat problem = _("invalid priority"); 2454ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2455ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (comma) 2456ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2457ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat arg = comma; 2458ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat comma = split(arg); 2459ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!atoi_check16(arg, &weight)) 2460ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat problem = _("invalid weight"); 2461ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2462ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2463ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2464ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2465ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2466ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new = opt_malloc(sizeof(struct mx_srv_record)); 2467ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->next = daemon->mxnames; 2468ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->mxnames = new; 2469ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->issrv = 1; 2470ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->name = name; 2471ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->target = target; 2472ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->srvport = port; 2473ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->priority = priority; 2474ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat new->weight = weight; 2475ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 2476ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2477ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 247868cd69ecff2d0f533a45a4218386a416cb201b71Lorenzo Colitti case LOPT_LISTNMARK: /* --listen-mark */ 247968cd69ecff2d0f533a45a4218386a416cb201b71Lorenzo Colitti { 248068cd69ecff2d0f533a45a4218386a416cb201b71Lorenzo Colitti char *endptr; 248168cd69ecff2d0f533a45a4218386a416cb201b71Lorenzo Colitti uint32_t mark = strtoul(arg, &endptr, 0); 2482f7ba4d22f2e3b7110629280d1ffe97216f5c3ecdErik Kline // my_syslog(LOG_WARNING, "passed-in mark: %s", arg); 248368cd69ecff2d0f533a45a4218386a416cb201b71Lorenzo Colitti if (!*endptr) 248468cd69ecff2d0f533a45a4218386a416cb201b71Lorenzo Colitti daemon->listen_mark = mark; 248568cd69ecff2d0f533a45a4218386a416cb201b71Lorenzo Colitti else 248668cd69ecff2d0f533a45a4218386a416cb201b71Lorenzo Colitti problem = _("invalid mark"); 2487f7ba4d22f2e3b7110629280d1ffe97216f5c3ecdErik Kline // my_syslog(LOG_WARNING, "daemon->listen_mark: 0x%x, *endptr=%d", daemon->listen_mark, *endptr); 248868cd69ecff2d0f533a45a4218386a416cb201b71Lorenzo Colitti break; 248968cd69ecff2d0f533a45a4218386a416cb201b71Lorenzo Colitti } 249068cd69ecff2d0f533a45a4218386a416cb201b71Lorenzo Colitti 2491ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat default: 2492f7ba4d22f2e3b7110629280d1ffe97216f5c3ecdErik Kline return _("unsupported option (check that dnsmasq was compiled with DHCP support)"); 2493ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2494ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2495ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2496ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (problem) 2497ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat return problem; 2498ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2499ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (option == '?') 2500ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat return gen_prob; 2501ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2502ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat return NULL; 2503ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat} 2504ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2505ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatstatic void one_file(char *file, int nest, int hard_opt) 2506ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat{ 2507ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat volatile int lineno = 0; 2508ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat int i, option; 2509ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat FILE *f; 2510ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *p, *arg, *start, *buff = daemon->namebuff; 2511ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat static struct fileread { 2512ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat dev_t dev; 2513ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat ino_t ino; 2514ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct fileread *next; 2515ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } *filesread = NULL; 2516ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct stat statbuf; 2517ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2518ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* ignore repeated files. */ 2519ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (hard_opt == 0 && stat(file, &statbuf) == 0) 2520ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2521ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct fileread *r; 2522ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2523ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (r = filesread; r; r = r->next) 2524ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (r->dev == statbuf.st_dev && r->ino == statbuf.st_ino) 2525ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat return; 2526ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2527ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat r = safe_malloc(sizeof(struct fileread)); 2528ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat r->next = filesread; 2529ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat filesread = r; 2530ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat r->dev = statbuf.st_dev; 2531ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat r->ino = statbuf.st_ino; 2532ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2533ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2534ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (nest > 20) 2535ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat die(_("files nested too deep in %s"), file, EC_BADCONF); 2536ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2537ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!(f = fopen(file, "r"))) 2538ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2539ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (errno == ENOENT && nest == 0) 2540ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat return; /* No conffile, all done. */ 2541ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 2542ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2543ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *str = _("cannot read %s: %s"); 2544ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (hard_opt != 0) 2545ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2546ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat my_syslog(LOG_ERR, str, file, strerror(errno)); 2547ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat return; 2548ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2549ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 2550ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat die(str, file, EC_FILE); 2551ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2552ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2553ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2554ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat while (fgets(buff, MAXDNAME, f)) 2555ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2556ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat int white; 2557ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat unsigned int lastquote; 2558ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *errmess; 2559ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2560ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* Memory allocation failure longjmps here if mem_recover == 1 */ 2561ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (hard_opt) 2562ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2563ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (setjmp(mem_jmp)) 2564ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat continue; 2565ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat mem_recover = 1; 2566ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2567ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2568ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat lineno++; 2569ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat errmess = NULL; 2570ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2571ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* Implement quotes, inside quotes we allow \\ \" \n and \t 2572ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat metacharacters get hidden also strip comments */ 2573ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2574ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (white = 1, lastquote = 0, p = buff; *p; p++) 2575ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2576ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (*p == '"') 2577ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2578ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat memmove(p, p+1, strlen(p+1)+1); 2579ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for(; *p && *p != '"'; p++) 2580ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2581ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (*p == '\\' && strchr("\"tnebr\\", p[1])) 2582ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2583ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (p[1] == 't') 2584ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat p[1] = '\t'; 2585ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (p[1] == 'n') 2586ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat p[1] = '\n'; 2587ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (p[1] == 'b') 2588ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat p[1] = '\b'; 2589ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (p[1] == 'r') 2590ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat p[1] = '\r'; 2591ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (p[1] == 'e') /* escape */ 2592ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat p[1] = '\033'; 2593ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat memmove(p, p+1, strlen(p+1)+1); 2594ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2595ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat *p = hide_meta(*p); 2596ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2597ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (*p == '"') 2598ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2599ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat memmove(p, p+1, strlen(p+1)+1); 2600ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat lastquote = p - buff; 2601ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2602ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 2603ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2604ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat errmess = _("missing \""); 2605ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat goto oops; 2606ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2607ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2608ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2609ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (white && *p == '#') 2610ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2611ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat *p = 0; 2612ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 2613ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2614ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat white = isspace((int)unhide_meta(*p)); 2615ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2616ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2617ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* fgets gets end of line char too. */ 2618ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat while (strlen(buff) > lastquote && isspace((int)unhide_meta(buff[strlen(buff)-1]))) 2619ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat buff[strlen(buff)-1] = 0; 2620ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2621ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (*buff == 0) 2622ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat continue; 2623ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2624ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (hard_opt != 0) 2625ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat arg = buff; 2626ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if ((p=strchr(buff, '='))) 2627ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2628ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* allow spaces around "=" */ 2629ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat arg = p+1; 2630ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (; p >= buff && (isspace((int)*p) || *p == '='); p--) 2631ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat *p = 0; 2632ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2633ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 2634ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat arg = NULL; 2635ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2636ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (hard_opt != 0) 2637ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = hard_opt; 2638ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 2639ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2640ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* skip leading space */ 2641ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (start = buff; *start && isspace((int)*start); start++); 2642ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2643ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (option = 0, i = 0; opts[i].name; i++) 2644ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (strcmp(opts[i].name, start) == 0) 2645ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2646ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = opts[i].val; 2647ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 2648ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2649ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2650ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!option) 2651ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat errmess = _("bad option"); 2652ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (opts[i].has_arg == 0 && arg) 2653ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat errmess = _("extraneous parameter"); 2654ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (opts[i].has_arg == 1 && !arg) 2655ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat errmess = _("missing parameter"); 2656ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2657ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2658ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!errmess) 2659ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2660ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (arg) 2661ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (; isspace((int)*arg); arg++); 2662ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2663ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat errmess = one_opt(option, arg, _("error"), nest + 1); 2664ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2665ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2666ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (errmess) 2667ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2668ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat oops: 2669ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat sprintf(buff, _("%s at line %d of %%s"), errmess, lineno); 2670ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (hard_opt != 0) 2671ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat my_syslog(LOG_ERR, buff, file); 2672ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 2673ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat die(buff, file, EC_BADCONF); 2674ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2675ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2676ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2677ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat mem_recover = 1; 2678ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat fclose(f); 2679ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat} 2680ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2681ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#ifdef HAVE_DHCP 2682ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatvoid reread_dhcp(void) 2683ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat{ 2684ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (daemon->dhcp_hosts_file) 2685ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2686ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct dhcp_config *configs, *cp, **up; 2687ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2688ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* remove existing... */ 2689ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (up = &daemon->dhcp_conf, configs = daemon->dhcp_conf; configs; configs = cp) 2690ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2691ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat cp = configs->next; 2692ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2693ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (configs->flags & CONFIG_BANK) 2694ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2695ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct hwaddr_config *mac, *tmp; 2696ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2697ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (mac = configs->hwaddr; mac; mac = tmp) 2698ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2699ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat tmp = mac->next; 2700ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat free(mac); 2701ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2702ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (configs->flags & CONFIG_CLID) 2703ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat free(configs->clid); 2704ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (configs->flags & CONFIG_NETID) 2705ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat free(configs->netid.net); 2706ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (configs->flags & CONFIG_NAME) 2707ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat free(configs->hostname); 2708ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2709ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2710ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat *up = configs->next; 2711ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat free(configs); 2712ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2713ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 2714ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat up = &configs->next; 2715ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2716ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2717ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat one_file(daemon->dhcp_hosts_file, 1, LOPT_BANK); 2718ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat my_syslog(MS_DHCP | LOG_INFO, _("read %s"), daemon->dhcp_hosts_file); 2719ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2720ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2721ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (daemon->dhcp_opts_file) 2722ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2723ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct dhcp_opt *opts, *cp, **up; 2724ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct dhcp_netid *id, *next; 2725ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2726ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (up = &daemon->dhcp_opts, opts = daemon->dhcp_opts; opts; opts = cp) 2727ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2728ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat cp = opts->next; 2729ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2730ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (opts->flags & DHOPT_BANK) 2731ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2732ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if ((opts->flags & DHOPT_VENDOR)) 2733ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat free(opts->u.vendor_class); 2734ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat free(opts->val); 2735ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (id = opts->netid; id; id = next) 2736ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2737ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat next = id->next; 2738ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat free(id->net); 2739ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat free(id); 2740ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2741ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat *up = opts->next; 2742ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat free(opts); 2743ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2744ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 2745ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat up = &opts->next; 2746ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2747ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2748ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat one_file(daemon->dhcp_opts_file, 1, LOPT_OPTS); 2749ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat my_syslog(MS_DHCP | LOG_INFO, _("read %s"), daemon->dhcp_opts_file); 2750ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2751ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat} 2752ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#endif 2753ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2754ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatvoid read_opts(int argc, char **argv, char *compile_opts) 2755ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat{ 2756ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *buff = opt_malloc(MAXDNAME); 2757ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat int option, nest = 0, testmode = 0; 2758ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *errmess, *arg, *conffile = CONFFILE; 2759ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2760ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat opterr = 0; 2761ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2762ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon = opt_malloc(sizeof(struct daemon)); 2763ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat memset(daemon, 0, sizeof(struct daemon)); 2764ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->namebuff = buff; 2765ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2766ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* Set defaults - everything else is zero or NULL */ 2767ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->cachesize = CACHESIZ; 2768ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->ftabsize = FTABSIZ; 2769ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->port = NAMESERVER_PORT; 2770ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->dhcp_client_port = DHCP_CLIENT_PORT; 2771ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->dhcp_server_port = DHCP_SERVER_PORT; 2772ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->default_resolv.is_default = 1; 2773ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->default_resolv.name = RESOLVFILE; 2774ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->resolv_files = &daemon->default_resolv; 2775ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->username = CHUSER; 2776ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->runfile = RUNFILE; 2777ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->dhcp_max = MAXLEASES; 2778ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->edns_pktsz = EDNS_PKTSZ; 2779ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->log_fac = -1; 2780ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat add_txt("version.bind", "dnsmasq-" VERSION ); 2781ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat add_txt("authors.bind", "Simon Kelley"); 2782ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat add_txt("copyright.bind", COPYRIGHT); 2783ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2784ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat while (1) 2785ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2786ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#ifdef HAVE_GETOPT_LONG 2787ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = getopt_long(argc, argv, OPTSTRING, opts, NULL); 2788ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#else 2789ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat option = getopt(argc, argv, OPTSTRING); 2790ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#endif 2791ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2792ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (option == -1) 2793ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 2794ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2795ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* Copy optarg so that argv doesn't get changed */ 2796ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (optarg) 2797ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2798ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat strncpy(buff, optarg, MAXDNAME); 2799ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat buff[MAXDNAME-1] = 0; 2800ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat arg = buff; 2801ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2802ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 2803ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat arg = NULL; 2804ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2805ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* command-line only stuff */ 2806ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (option == LOPT_TEST) 2807ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat testmode = 1; 2808ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (option == 'w') 2809ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2810ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (argc != 3 || strcmp(argv[2], "dhcp") != 0) 2811ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat do_usage(); 2812ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#ifdef HAVE_DHCP 2813ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 2814ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat display_opts(); 2815ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#endif 2816ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat exit(0); 2817ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2818ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (option == 'v') 2819ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2820ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat printf(_("Dnsmasq version %s %s\n"), VERSION, COPYRIGHT); 2821ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat printf(_("Compile time options %s\n\n"), compile_opts); 2822ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat printf(_("This software comes with ABSOLUTELY NO WARRANTY.\n")); 2823ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat printf(_("Dnsmasq is free software, and you are welcome to redistribute it\n")); 2824ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat printf(_("under the terms of the GNU General Public License, version 2 or 3.\n")); 2825ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat exit(0); 2826ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2827ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (option == 'C') 2828ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2829ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat conffile = opt_string_alloc(arg); 2830ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat nest++; 2831ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2832ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else 2833ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2834ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#ifdef HAVE_GETOPT_LONG 2835ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat errmess = one_opt(option, arg, _("try --help"), 0); 2836ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#else 2837ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat errmess = one_opt(option, arg, _("try -w"), 0); 2838ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#endif 2839ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (errmess) 2840ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat die(_("bad command line options: %s"), errmess, EC_BADCONF); 2841ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2842ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2843ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2844ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (conffile) 2845ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat one_file(conffile, nest, 0); 2846ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2847ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* port might not be known when the address is parsed - fill in here */ 2848ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (daemon->servers) 2849ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2850ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct server *tmp; 2851ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (tmp = daemon->servers; tmp; tmp = tmp->next) 2852ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!(tmp->flags & SERV_HAS_SOURCE)) 2853ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2854ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (tmp->source_addr.sa.sa_family == AF_INET) 2855ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat tmp->source_addr.in.sin_port = htons(daemon->query_port); 2856ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#ifdef HAVE_IPV6 2857ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (tmp->source_addr.sa.sa_family == AF_INET6) 2858ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat tmp->source_addr.in6.sin6_port = htons(daemon->query_port); 2859ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#endif 2860ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2861ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2862ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2863ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (daemon->if_addrs) 2864ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2865ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct iname *tmp; 2866ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for(tmp = daemon->if_addrs; tmp; tmp = tmp->next) 2867ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (tmp->addr.sa.sa_family == AF_INET) 2868ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat tmp->addr.in.sin_port = htons(daemon->port); 2869ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#ifdef HAVE_IPV6 2870ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (tmp->addr.sa.sa_family == AF_INET6) 2871ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat tmp->addr.in6.sin6_port = htons(daemon->port); 2872ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#endif /* IPv6 */ 2873ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2874ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2875ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* only one of these need be specified: the other defaults to the host-name */ 2876ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if ((daemon->options & OPT_LOCALMX) || daemon->mxnames || daemon->mxtarget) 2877ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2878ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct mx_srv_record *mx; 2879ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2880ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (gethostname(buff, MAXDNAME) == -1) 2881ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat die(_("cannot get host-name: %s"), NULL, EC_MISC); 2882ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2883ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (mx = daemon->mxnames; mx; mx = mx->next) 2884ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!mx->issrv && hostname_isequal(mx->name, buff)) 2885ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 2886ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2887ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if ((daemon->mxtarget || (daemon->options & OPT_LOCALMX)) && !mx) 2888ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2889ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat mx = opt_malloc(sizeof(struct mx_srv_record)); 2890ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat mx->next = daemon->mxnames; 2891ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat mx->issrv = 0; 2892ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat mx->target = NULL; 2893ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat mx->name = opt_string_alloc(buff); 2894ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->mxnames = mx; 2895ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2896ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2897ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!daemon->mxtarget) 2898ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->mxtarget = opt_string_alloc(buff); 2899ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2900ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (mx = daemon->mxnames; mx; mx = mx->next) 2901ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!mx->issrv && !mx->target) 2902ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat mx->target = daemon->mxtarget; 2903ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2904ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2905ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!(daemon->options & OPT_NO_RESOLV) && 2906ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->resolv_files && 2907ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat daemon->resolv_files->next && 2908ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat (daemon->options & OPT_NO_POLL)) 2909ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat die(_("only one resolv.conf file allowed in no-poll mode."), NULL, EC_BADCONF); 2910ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2911ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (daemon->options & OPT_RESOLV_DOMAIN) 2912ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2913ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *line; 2914ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat FILE *f; 2915ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2916ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if ((daemon->options & OPT_NO_RESOLV) || 2917ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat !daemon->resolv_files || 2918ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat (daemon->resolv_files)->next) 2919ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat die(_("must have exactly one resolv.conf to read domain from."), NULL, EC_BADCONF); 2920ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2921ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!(f = fopen((daemon->resolv_files)->name, "r"))) 2922ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat die(_("failed to read %s: %s"), (daemon->resolv_files)->name, EC_FILE); 2923ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2924ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat while ((line = fgets(buff, MAXDNAME, f))) 2925ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2926ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat char *token = strtok(line, " \t\n\r"); 2927ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2928ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!token || strcmp(token, "search") != 0) 2929ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat continue; 2930ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2931ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if ((token = strtok(NULL, " \t\n\r")) && 2932ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat (daemon->domain_suffix = canonicalise_opt(token))) 2933ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat break; 2934ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2935ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2936ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat fclose(f); 2937ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2938ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (!daemon->domain_suffix) 2939ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat die(_("no search directive found in %s"), (daemon->resolv_files)->name, EC_MISC); 2940ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2941ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2942ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (daemon->domain_suffix) 2943ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2944ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat /* add domain for any srv record without one. */ 2945ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat struct mx_srv_record *srv; 2946ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2947ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat for (srv = daemon->mxnames; srv; srv = srv->next) 2948ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (srv->issrv && 2949ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat strchr(srv->name, '.') && 2950ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat strchr(srv->name, '.') == strrchr(srv->name, '.')) 2951ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2952ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat strcpy(buff, srv->name); 2953ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat strcat(buff, "."); 2954ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat strcat(buff, daemon->domain_suffix); 2955ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat free(srv->name); 2956ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat srv->name = opt_string_alloc(buff); 2957ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2958ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2959ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat else if (daemon->options & OPT_DHCP_FQDN) 2960ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat die(_("there must be a default domain when --dhcp-fqdn is set"), NULL, EC_BADCONF); 2961ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat 2962ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat if (testmode) 2963ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat { 2964ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat fprintf(stderr, "dnsmasq: %s.\n", _("syntax check OK")); 2965ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat exit(0); 2966ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat } 2967ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat} 2968