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