Diff for /embedaddon/dnsmasq/src/option.c between versions 1.1.1.2 and 1.1.1.3

version 1.1.1.2, 2014/06/15 16:31:38 version 1.1.1.3, 2016/11/02 09:57:01
Line 1 Line 1
/* dnsmasq is Copyright (c) 2000-2014 Simon Kelley/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
   
    This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
Line 146  struct myoption { Line 146  struct myoption {
 #define LOPT_DNSSEC_CHECK  334  #define LOPT_DNSSEC_CHECK  334
 #define LOPT_LOCAL_SERVICE 335  #define LOPT_LOCAL_SERVICE 335
 #define LOPT_DNSSEC_TIME   336  #define LOPT_DNSSEC_TIME   336
#define LOPT_LOOP_DETECT   337
 #define LOPT_IGNORE_ADDR   338
 #define LOPT_MINCTTL       339
 #define LOPT_DHCP_INOTIFY  340
 #define LOPT_DHOPT_INOTIFY 341
 #define LOPT_HOST_INOTIFY  342
 #define LOPT_DNSSEC_STAMP  343
 #define LOPT_TFTP_NO_FAIL  344
 #define LOPT_MAXPORT       345
 #define LOPT_CPE_ID        346
 #define LOPT_SCRIPT_ARP    347
 #define LOPT_DHCPTTL       348
 #define LOPT_TFTP_MTU      349
  
 #ifdef HAVE_GETOPT_LONG  #ifdef HAVE_GETOPT_LONG
 static const struct option opts[] =    static const struct option opts[] =  
 #else  #else
Line 158  static const struct myoption opts[] =  Line 171  static const struct myoption opts[] = 
     { "no-poll", 0, 0, 'n' },      { "no-poll", 0, 0, 'n' },
     { "help", 0, 0, 'w' },      { "help", 0, 0, 'w' },
     { "no-daemon", 0, 0, 'd' },      { "no-daemon", 0, 0, 'd' },
    { "log-queries", 0, 0, 'q' },    { "log-queries", 2, 0, 'q' },
     { "user", 2, 0, 'u' },      { "user", 2, 0, 'u' },
     { "group", 2, 0, 'g' },      { "group", 2, 0, 'g' },
     { "resolv-file", 2, 0, 'r' },      { "resolv-file", 2, 0, 'r' },
Line 180  static const struct myoption opts[] =  Line 193  static const struct myoption opts[] = 
     { "local-service", 0, 0, LOPT_LOCAL_SERVICE },      { "local-service", 0, 0, LOPT_LOCAL_SERVICE },
     { "bogus-priv", 0, 0, 'b' },      { "bogus-priv", 0, 0, 'b' },
     { "bogus-nxdomain", 1, 0, 'B' },      { "bogus-nxdomain", 1, 0, 'B' },
       { "ignore-address", 1, 0, LOPT_IGNORE_ADDR },
     { "selfmx", 0, 0, 'e' },      { "selfmx", 0, 0, 'e' },
     { "filterwin2k", 0, 0, 'f' },      { "filterwin2k", 0, 0, 'f' },
     { "pid-file", 2, 0, 'x' },      { "pid-file", 2, 0, 'x' },
Line 195  static const struct myoption opts[] =  Line 209  static const struct myoption opts[] = 
     { "local-ttl", 1, 0, 'T' },      { "local-ttl", 1, 0, 'T' },
     { "no-negcache", 0, 0, 'N' },      { "no-negcache", 0, 0, 'N' },
     { "addn-hosts", 1, 0, 'H' },      { "addn-hosts", 1, 0, 'H' },
       { "hostsdir", 1, 0, LOPT_HOST_INOTIFY },
     { "query-port", 1, 0, 'Q' },      { "query-port", 1, 0, 'Q' },
     { "except-interface", 1, 0, 'I' },      { "except-interface", 1, 0, 'I' },
     { "no-dhcp-interface", 1, 0, '2' },      { "no-dhcp-interface", 1, 0, '2' },
Line 226  static const struct myoption opts[] =  Line 241  static const struct myoption opts[] = 
     { "dhcp-ignore-names", 2, 0, LOPT_NO_NAMES },      { "dhcp-ignore-names", 2, 0, LOPT_NO_NAMES },
     { "enable-tftp", 2, 0, LOPT_TFTP },      { "enable-tftp", 2, 0, LOPT_TFTP },
     { "tftp-secure", 0, 0, LOPT_SECURE },      { "tftp-secure", 0, 0, LOPT_SECURE },
       { "tftp-no-fail", 0, 0, LOPT_TFTP_NO_FAIL },
     { "tftp-unique-root", 0, 0, LOPT_APREF },      { "tftp-unique-root", 0, 0, LOPT_APREF },
     { "tftp-root", 1, 0, LOPT_PREFIX },      { "tftp-root", 1, 0, LOPT_PREFIX },
     { "tftp-max", 1, 0, LOPT_TFTP_MAX },      { "tftp-max", 1, 0, LOPT_TFTP_MAX },
       { "tftp-mtu", 1, 0, LOPT_TFTP_MTU },
     { "tftp-lowercase", 0, 0, LOPT_TFTP_LC },      { "tftp-lowercase", 0, 0, LOPT_TFTP_LC },
     { "ptr-record", 1, 0, LOPT_PTR },      { "ptr-record", 1, 0, LOPT_PTR },
     { "naptr-record", 1, 0, LOPT_NAPTR },      { "naptr-record", 1, 0, LOPT_NAPTR },
Line 243  static const struct myoption opts[] =  Line 260  static const struct myoption opts[] = 
     { "interface-name", 1, 0, LOPT_INTNAME },      { "interface-name", 1, 0, LOPT_INTNAME },
     { "dhcp-hostsfile", 1, 0, LOPT_DHCP_HOST },      { "dhcp-hostsfile", 1, 0, LOPT_DHCP_HOST },
     { "dhcp-optsfile", 1, 0, LOPT_DHCP_OPTS },      { "dhcp-optsfile", 1, 0, LOPT_DHCP_OPTS },
       { "dhcp-hostsdir", 1, 0, LOPT_DHCP_INOTIFY },
       { "dhcp-optsdir", 1, 0, LOPT_DHOPT_INOTIFY },
     { "dhcp-no-override", 0, 0, LOPT_OVERRIDE },      { "dhcp-no-override", 0, 0, LOPT_OVERRIDE },
     { "tftp-port-range", 1, 0, LOPT_TFTPPORTS },      { "tftp-port-range", 1, 0, LOPT_TFTPPORTS },
     { "stop-dns-rebind", 0, 0, LOPT_REBIND },      { "stop-dns-rebind", 0, 0, LOPT_REBIND },
Line 252  static const struct myoption opts[] =  Line 271  static const struct myoption opts[] = 
     { "dhcp-broadcast", 2, 0, LOPT_BROADCAST },      { "dhcp-broadcast", 2, 0, LOPT_BROADCAST },
     { "neg-ttl", 1, 0, LOPT_NEGTTL },      { "neg-ttl", 1, 0, LOPT_NEGTTL },
     { "max-ttl", 1, 0, LOPT_MAXTTL },      { "max-ttl", 1, 0, LOPT_MAXTTL },
       { "min-cache-ttl", 1, 0, LOPT_MINCTTL },
     { "max-cache-ttl", 1, 0, LOPT_MAXCTTL },      { "max-cache-ttl", 1, 0, LOPT_MAXCTTL },
     { "dhcp-alternate-port", 2, 0, LOPT_ALTPORT },      { "dhcp-alternate-port", 2, 0, LOPT_ALTPORT },
     { "dhcp-scriptuser", 1, 0, LOPT_SCRIPTUSR },      { "dhcp-scriptuser", 1, 0, LOPT_SCRIPTUSR },
     { "min-port", 1, 0, LOPT_MINPORT },      { "min-port", 1, 0, LOPT_MINPORT },
       { "max-port", 1, 0, LOPT_MAXPORT },
     { "dhcp-fqdn", 0, 0, LOPT_DHCP_FQDN },      { "dhcp-fqdn", 0, 0, LOPT_DHCP_FQDN },
     { "cname", 1, 0, LOPT_CNAME },      { "cname", 1, 0, LOPT_CNAME },
     { "pxe-prompt", 1, 0, LOPT_PXE_PROMT },      { "pxe-prompt", 1, 0, LOPT_PXE_PROMT },
Line 265  static const struct myoption opts[] =  Line 286  static const struct myoption opts[] = 
     { "dhcp-proxy", 2, 0, LOPT_PROXY },      { "dhcp-proxy", 2, 0, LOPT_PROXY },
     { "dhcp-generate-names", 2, 0, LOPT_GEN_NAMES },      { "dhcp-generate-names", 2, 0, LOPT_GEN_NAMES },
     { "rebind-localhost-ok", 0, 0,  LOPT_LOC_REBND },      { "rebind-localhost-ok", 0, 0,  LOPT_LOC_REBND },
    { "add-mac", 0, 0, LOPT_ADD_MAC },    { "add-mac", 2, 0, LOPT_ADD_MAC },
     { "add-subnet", 2, 0, LOPT_ADD_SBNET },      { "add-subnet", 2, 0, LOPT_ADD_SBNET },
       { "add-cpe-id", 1, 0 , LOPT_CPE_ID },
     { "proxy-dnssec", 0, 0, LOPT_DNSSEC },      { "proxy-dnssec", 0, 0, LOPT_DNSSEC },
     { "dhcp-sequential-ip", 0, 0,  LOPT_INCR_ADDR },      { "dhcp-sequential-ip", 0, 0,  LOPT_INCR_ADDR },
     { "conntrack", 0, 0, LOPT_CONNTRACK },      { "conntrack", 0, 0, LOPT_CONNTRACK },
Line 289  static const struct myoption opts[] =  Line 311  static const struct myoption opts[] = 
     { "dnssec-debug", 0, 0, LOPT_DNSSEC_DEBUG },      { "dnssec-debug", 0, 0, LOPT_DNSSEC_DEBUG },
     { "dnssec-check-unsigned", 0, 0, LOPT_DNSSEC_CHECK },      { "dnssec-check-unsigned", 0, 0, LOPT_DNSSEC_CHECK },
     { "dnssec-no-timecheck", 0, 0, LOPT_DNSSEC_TIME },      { "dnssec-no-timecheck", 0, 0, LOPT_DNSSEC_TIME },
       { "dnssec-timestamp", 1, 0, LOPT_DNSSEC_STAMP },
 #ifdef OPTION6_PREFIX_CLASS   #ifdef OPTION6_PREFIX_CLASS 
     { "dhcp-prefix-class", 1, 0, LOPT_PREF_CLSS },      { "dhcp-prefix-class", 1, 0, LOPT_PREF_CLSS },
 #endif  #endif
Line 297  static const struct myoption opts[] =  Line 320  static const struct myoption opts[] = 
     { "quiet-dhcp", 0, 0, LOPT_QUIET_DHCP },      { "quiet-dhcp", 0, 0, LOPT_QUIET_DHCP },
     { "quiet-dhcp6", 0, 0, LOPT_QUIET_DHCP6 },      { "quiet-dhcp6", 0, 0, LOPT_QUIET_DHCP6 },
     { "quiet-ra", 0, 0, LOPT_QUIET_RA },      { "quiet-ra", 0, 0, LOPT_QUIET_RA },
       { "dns-loop-detect", 0, 0, LOPT_LOOP_DETECT },
       { "script-arp", 0, 0, LOPT_SCRIPT_ARP },
       { "dhcp-ttl", 1, 0 , LOPT_DHCPTTL },
     { NULL, 0, 0, 0 }      { NULL, 0, 0, 0 }
   };    };
   
Line 329  static struct { Line 355  static struct {
   { 'G', ARG_DUP, "<hostspec>", gettext_noop("Set address or hostname for a specified machine."), NULL },    { 'G', ARG_DUP, "<hostspec>", gettext_noop("Set address or hostname for a specified machine."), NULL },
   { LOPT_DHCP_HOST, ARG_DUP, "<path>", gettext_noop("Read DHCP host specs from file."), NULL },    { LOPT_DHCP_HOST, ARG_DUP, "<path>", gettext_noop("Read DHCP host specs from file."), NULL },
   { LOPT_DHCP_OPTS, ARG_DUP, "<path>", gettext_noop("Read DHCP option specs from file."), NULL },    { LOPT_DHCP_OPTS, ARG_DUP, "<path>", gettext_noop("Read DHCP option specs from file."), NULL },
     { LOPT_DHCP_INOTIFY, ARG_DUP, "<path>", gettext_noop("Read DHCP host specs from a directory."), NULL }, 
     { LOPT_DHOPT_INOTIFY, ARG_DUP, "<path>", gettext_noop("Read DHCP options from a directory."), NULL }, 
   { LOPT_TAG_IF, ARG_DUP, "tag-expression", gettext_noop("Evaluate conditional tag expression."), NULL },    { LOPT_TAG_IF, ARG_DUP, "tag-expression", gettext_noop("Evaluate conditional tag expression."), NULL },
   { 'h', OPT_NO_HOSTS, NULL, gettext_noop("Do NOT load %s file."), HOSTSFILE },    { 'h', OPT_NO_HOSTS, NULL, gettext_noop("Do NOT load %s file."), HOSTSFILE },
   { 'H', ARG_DUP, "<path>", gettext_noop("Specify a hosts file to be read in addition to %s."), HOSTSFILE },    { 'H', ARG_DUP, "<path>", gettext_noop("Specify a hosts file to be read in addition to %s."), HOSTSFILE },
     { LOPT_HOST_INOTIFY, ARG_DUP, "<path>", gettext_noop("Read hosts files from a directory."), NULL },
   { 'i', ARG_DUP, "<interface>", gettext_noop("Specify interface(s) to listen on."), NULL },    { 'i', ARG_DUP, "<interface>", gettext_noop("Specify interface(s) to listen on."), NULL },
   { 'I', ARG_DUP, "<interface>", gettext_noop("Specify interface(s) NOT to listen on.") , NULL },    { 'I', ARG_DUP, "<interface>", gettext_noop("Specify interface(s) NOT to listen on.") , NULL },
   { 'j', ARG_DUP, "set:<tag>,<class>", gettext_noop("Map DHCP user class to tag."), NULL },    { 'j', ARG_DUP, "set:<tag>,<class>", gettext_noop("Map DHCP user class to tag."), NULL },
Line 353  static struct { Line 382  static struct {
   { LOPT_FORCE, ARG_DUP, "<optspec>", gettext_noop("DHCP option sent even if the client does not request it."), NULL},    { LOPT_FORCE, ARG_DUP, "<optspec>", gettext_noop("DHCP option sent even if the client does not request it."), NULL},
   { 'p', ARG_ONE, "<integer>", gettext_noop("Specify port to listen for DNS requests on (defaults to 53)."), NULL },    { 'p', ARG_ONE, "<integer>", gettext_noop("Specify port to listen for DNS requests on (defaults to 53)."), NULL },
   { 'P', ARG_ONE, "<integer>", gettext_noop("Maximum supported UDP packet size for EDNS.0 (defaults to %s)."), "*" },    { 'P', ARG_ONE, "<integer>", gettext_noop("Maximum supported UDP packet size for EDNS.0 (defaults to %s)."), "*" },
  { 'q', OPT_LOG, NULL, gettext_noop("Log DNS queries."), NULL },  { 'q', ARG_DUP, NULL, gettext_noop("Log DNS queries."), NULL },
   { 'Q', ARG_ONE, "<integer>", gettext_noop("Force the originating port for upstream DNS queries."), NULL },    { 'Q', ARG_ONE, "<integer>", gettext_noop("Force the originating port for upstream DNS queries."), NULL },
   { 'R', OPT_NO_RESOLV, NULL, gettext_noop("Do NOT read resolv.conf."), NULL },    { 'R', OPT_NO_RESOLV, NULL, gettext_noop("Do NOT read resolv.conf."), NULL },
   { 'r', ARG_DUP, "<path>", gettext_noop("Specify path to resolv.conf (defaults to %s)."), RESOLVFILE },     { 'r', ARG_DUP, "<path>", gettext_noop("Specify path to resolv.conf (defaults to %s)."), RESOLVFILE }, 
Line 366  static struct { Line 395  static struct {
   { 'T', ARG_ONE, "<integer>", gettext_noop("Specify time-to-live in seconds for replies from /etc/hosts."), NULL },    { 'T', ARG_ONE, "<integer>", gettext_noop("Specify time-to-live in seconds for replies from /etc/hosts."), NULL },
   { LOPT_NEGTTL, ARG_ONE, "<integer>", gettext_noop("Specify time-to-live in seconds for negative caching."), NULL },    { LOPT_NEGTTL, ARG_ONE, "<integer>", gettext_noop("Specify time-to-live in seconds for negative caching."), NULL },
   { LOPT_MAXTTL, ARG_ONE, "<integer>", gettext_noop("Specify time-to-live in seconds for maximum TTL to send to clients."), NULL },    { LOPT_MAXTTL, ARG_ONE, "<integer>", gettext_noop("Specify time-to-live in seconds for maximum TTL to send to clients."), NULL },
     { LOPT_MAXCTTL, ARG_ONE, "<integer>", gettext_noop("Specify time-to-live ceiling for cache."), NULL },
     { LOPT_MINCTTL, ARG_ONE, "<integer>", gettext_noop("Specify time-to-live floor for cache."), NULL },
   { 'u', ARG_ONE, "<username>", gettext_noop("Change to this user after startup. (defaults to %s)."), CHUSER },     { 'u', ARG_ONE, "<username>", gettext_noop("Change to this user after startup. (defaults to %s)."), CHUSER }, 
   { 'U', ARG_DUP, "set:<tag>,<class>", gettext_noop("Map DHCP vendor class to tag."), NULL },    { 'U', ARG_DUP, "set:<tag>,<class>", gettext_noop("Map DHCP vendor class to tag."), NULL },
   { 'v', 0, NULL, gettext_noop("Display dnsmasq version and copyright information."), NULL },    { 'v', 0, NULL, gettext_noop("Display dnsmasq version and copyright information."), NULL },
   { 'V', ARG_DUP, "<ipaddr>,<ipaddr>,<netmask>", gettext_noop("Translate IPv4 addresses from upstream servers."), NULL },    { 'V', ARG_DUP, "<ipaddr>,<ipaddr>,<netmask>", gettext_noop("Translate IPv4 addresses from upstream servers."), NULL },
   { 'W', ARG_DUP, "<name>,<target>,...", gettext_noop("Specify a SRV record."), NULL },    { 'W', ARG_DUP, "<name>,<target>,...", gettext_noop("Specify a SRV record."), NULL },
  { 'w', 0, NULL, gettext_noop("Display this message. Use --help dhcp for known DHCP options."), NULL },  { 'w', 0, NULL, gettext_noop("Display this message. Use --help dhcp or --help dhcp6 for known DHCP options."), NULL },
   { 'x', ARG_ONE, "<path>", gettext_noop("Specify path of PID file (defaults to %s)."), RUNFILE },    { 'x', ARG_ONE, "<path>", gettext_noop("Specify path of PID file (defaults to %s)."), RUNFILE },
   { 'X', ARG_ONE, "<integer>", gettext_noop("Specify maximum number of DHCP leases (defaults to %s)."), "&" },    { 'X', ARG_ONE, "<integer>", gettext_noop("Specify maximum number of DHCP leases (defaults to %s)."), "&" },
   { 'y', OPT_LOCALISE, NULL, gettext_noop("Answer DNS queries based on the interface a query was sent to."), NULL },    { 'y', OPT_LOCALISE, NULL, gettext_noop("Answer DNS queries based on the interface a query was sent to."), NULL },
Line 389  static struct { Line 420  static struct {
   { '6', ARG_ONE, "<path>", gettext_noop("Shell script to run on DHCP lease creation and destruction."), NULL },    { '6', ARG_ONE, "<path>", gettext_noop("Shell script to run on DHCP lease creation and destruction."), NULL },
   { LOPT_LUASCRIPT, ARG_DUP, "path", gettext_noop("Lua script to run on DHCP lease creation and destruction."), NULL },    { LOPT_LUASCRIPT, ARG_DUP, "path", gettext_noop("Lua script to run on DHCP lease creation and destruction."), NULL },
   { LOPT_SCRIPTUSR, ARG_ONE, "<username>", gettext_noop("Run lease-change scripts as this user."), NULL },    { LOPT_SCRIPTUSR, ARG_ONE, "<username>", gettext_noop("Run lease-change scripts as this user."), NULL },
     { LOPT_SCRIPT_ARP, OPT_SCRIPT_ARP, NULL, gettext_noop("Call dhcp-script with changes to local ARP table."), NULL },
   { '7', ARG_DUP, "<path>", gettext_noop("Read configuration from all the files in this directory."), NULL },    { '7', ARG_DUP, "<path>", gettext_noop("Read configuration from all the files in this directory."), NULL },
   { '8', ARG_ONE, "<facilty>|<file>", gettext_noop("Log to this syslog facility or file. (defaults to DAEMON)"), NULL },    { '8', ARG_ONE, "<facilty>|<file>", gettext_noop("Log to this syslog facility or file. (defaults to DAEMON)"), NULL },
   { '9', OPT_LEASE_RO, NULL, gettext_noop("Do not use leasefile."), NULL },    { '9', OPT_LEASE_RO, NULL, gettext_noop("Do not use leasefile."), NULL },
Line 400  static struct { Line 432  static struct {
   { LOPT_PREFIX, ARG_DUP, "<dir>[,<iface>]", gettext_noop("Export files by TFTP only from the specified subtree."), NULL },    { LOPT_PREFIX, ARG_DUP, "<dir>[,<iface>]", gettext_noop("Export files by TFTP only from the specified subtree."), NULL },
   { LOPT_APREF, OPT_TFTP_APREF, NULL, gettext_noop("Add client IP address to tftp-root."), NULL },    { LOPT_APREF, OPT_TFTP_APREF, NULL, gettext_noop("Add client IP address to tftp-root."), NULL },
   { LOPT_SECURE, OPT_TFTP_SECURE, NULL, gettext_noop("Allow access only to files owned by the user running dnsmasq."), NULL },    { LOPT_SECURE, OPT_TFTP_SECURE, NULL, gettext_noop("Allow access only to files owned by the user running dnsmasq."), NULL },
     { LOPT_TFTP_NO_FAIL, OPT_TFTP_NO_FAIL, NULL, gettext_noop("Do not terminate the service if TFTP directories are inaccessible."), NULL },
   { LOPT_TFTP_MAX, ARG_ONE, "<integer>", gettext_noop("Maximum number of conncurrent TFTP transfers (defaults to %s)."), "#" },    { LOPT_TFTP_MAX, ARG_ONE, "<integer>", gettext_noop("Maximum number of conncurrent TFTP transfers (defaults to %s)."), "#" },
     { LOPT_TFTP_MTU, ARG_ONE, "<integer>", gettext_noop("Maximum MTU to use for TFTP transfers."), NULL },
   { LOPT_NOBLOCK, OPT_TFTP_NOBLOCK, NULL, gettext_noop("Disable the TFTP blocksize extension."), NULL },    { LOPT_NOBLOCK, OPT_TFTP_NOBLOCK, NULL, gettext_noop("Disable the TFTP blocksize extension."), NULL },
   { LOPT_TFTP_LC, OPT_TFTP_LC, NULL, gettext_noop("Convert TFTP filenames to lowercase"), NULL },    { LOPT_TFTP_LC, OPT_TFTP_LC, NULL, gettext_noop("Convert TFTP filenames to lowercase"), NULL },
   { LOPT_TFTPPORTS, ARG_ONE, "<start>,<end>", gettext_noop("Ephemeral port range for use by TFTP transfers."), NULL },    { LOPT_TFTPPORTS, ARG_ONE, "<start>,<end>", gettext_noop("Ephemeral port range for use by TFTP transfers."), NULL },
Line 414  static struct { Line 448  static struct {
   { LOPT_ALTPORT, ARG_ONE, "[=<ports>]", gettext_noop("Use alternative ports for DHCP."), NULL },    { LOPT_ALTPORT, ARG_ONE, "[=<ports>]", gettext_noop("Use alternative ports for DHCP."), NULL },
   { LOPT_NAPTR, ARG_DUP, "<name>,<naptr>", gettext_noop("Specify NAPTR DNS record."), NULL },    { LOPT_NAPTR, ARG_DUP, "<name>,<naptr>", gettext_noop("Specify NAPTR DNS record."), NULL },
   { LOPT_MINPORT, ARG_ONE, "<port>", gettext_noop("Specify lowest port available for DNS query transmission."), NULL },    { LOPT_MINPORT, ARG_ONE, "<port>", gettext_noop("Specify lowest port available for DNS query transmission."), NULL },
     { LOPT_MAXPORT, ARG_ONE, "<port>", gettext_noop("Specify highest port available for DNS query transmission."), NULL },
   { LOPT_DHCP_FQDN, OPT_DHCP_FQDN, NULL, gettext_noop("Use only fully qualified domain names for DHCP clients."), NULL },    { LOPT_DHCP_FQDN, OPT_DHCP_FQDN, NULL, gettext_noop("Use only fully qualified domain names for DHCP clients."), NULL },
   { LOPT_GEN_NAMES, ARG_DUP, "[=tag:<tag>]", gettext_noop("Generate hostnames based on MAC address for nameless clients."), NULL},    { LOPT_GEN_NAMES, ARG_DUP, "[=tag:<tag>]", gettext_noop("Generate hostnames based on MAC address for nameless clients."), NULL},
   { LOPT_PROXY, ARG_DUP, "[=<ipaddr>]...", gettext_noop("Use these DHCP relays as full proxies."), NULL },    { LOPT_PROXY, ARG_DUP, "[=<ipaddr>]...", gettext_noop("Use these DHCP relays as full proxies."), NULL },
   { LOPT_RELAY, ARG_DUP, "<local-addr>,<server>[,<interface>]", gettext_noop("Relay DHCP requests to a remote server"), NULL},    { LOPT_RELAY, ARG_DUP, "<local-addr>,<server>[,<interface>]", gettext_noop("Relay DHCP requests to a remote server"), NULL},
  { LOPT_CNAME, ARG_DUP, "<alias>,<target>", gettext_noop("Specify alias name for LOCAL DNS name."), NULL },  { LOPT_CNAME, ARG_DUP, "<alias>,<target>[,<ttl>]", gettext_noop("Specify alias name for LOCAL DNS name."), NULL },
   { LOPT_PXE_PROMT, ARG_DUP, "<prompt>,[<timeout>]", gettext_noop("Prompt to send to PXE clients."), NULL },    { LOPT_PXE_PROMT, ARG_DUP, "<prompt>,[<timeout>]", gettext_noop("Prompt to send to PXE clients."), NULL },
   { LOPT_PXE_SERV, ARG_DUP, "<service>", gettext_noop("Boot service for PXE menu."), NULL },    { LOPT_PXE_SERV, ARG_DUP, "<service>", gettext_noop("Boot service for PXE menu."), NULL },
   { LOPT_TEST, 0, NULL, gettext_noop("Check configuration syntax."), NULL },    { LOPT_TEST, 0, NULL, gettext_noop("Check configuration syntax."), NULL },
  { LOPT_ADD_MAC, OPT_ADD_MAC, NULL, gettext_noop("Add requestor's MAC address to forwarded DNS queries."), NULL },  { LOPT_ADD_MAC, ARG_DUP, "[=base64|text]", gettext_noop("Add requestor's MAC address to forwarded DNS queries."), NULL },
  { LOPT_ADD_SBNET, ARG_ONE, "<v4 pref>[,<v6 pref>]", gettext_noop("Add requestor's IP subnet to forwarded DNS queries."), NULL },  { LOPT_ADD_SBNET, ARG_ONE, "<v4 pref>[,<v6 pref>]", gettext_noop("Add specified IP subnet to forwarded DNS queries."), NULL },
   { LOPT_CPE_ID, ARG_ONE, "<text>", gettext_noop("Add client identification to forwarded DNS queries."), NULL },
   { LOPT_DNSSEC, OPT_DNSSEC_PROXY, NULL, gettext_noop("Proxy DNSSEC validation results from upstream nameservers."), NULL },    { LOPT_DNSSEC, OPT_DNSSEC_PROXY, NULL, gettext_noop("Proxy DNSSEC validation results from upstream nameservers."), NULL },
   { LOPT_INCR_ADDR, OPT_CONSEC_ADDR, NULL, gettext_noop("Attempt to allocate sequential IP addresses to DHCP clients."), NULL },    { LOPT_INCR_ADDR, OPT_CONSEC_ADDR, NULL, gettext_noop("Attempt to allocate sequential IP addresses to DHCP clients."), NULL },
   { LOPT_CONNTRACK, OPT_CONNTRACK, NULL, gettext_noop("Copy connection-track mark from queries to upstream connections."), NULL },    { LOPT_CONNTRACK, OPT_CONNTRACK, NULL, gettext_noop("Copy connection-track mark from queries to upstream connections."), NULL },
   { LOPT_FQDN, OPT_FQDN_UPDATE, NULL, gettext_noop("Allow DHCP clients to do their own DDNS updates."), NULL },    { LOPT_FQDN, OPT_FQDN_UPDATE, NULL, gettext_noop("Allow DHCP clients to do their own DDNS updates."), NULL },
   { LOPT_RA, OPT_RA, NULL, gettext_noop("Send router-advertisements for interfaces doing DHCPv6"), NULL },    { LOPT_RA, OPT_RA, NULL, gettext_noop("Send router-advertisements for interfaces doing DHCPv6"), NULL },
   { LOPT_DUID, ARG_ONE, "<enterprise>,<duid>", gettext_noop("Specify DUID_EN-type DHCPv6 server DUID"), NULL },    { LOPT_DUID, ARG_ONE, "<enterprise>,<duid>", gettext_noop("Specify DUID_EN-type DHCPv6 server DUID"), NULL },
  { LOPT_HOST_REC, ARG_DUP, "<name>,<address>", gettext_noop("Specify host (A/AAAA and PTR) records"), NULL },  { LOPT_HOST_REC, ARG_DUP, "<name>,<address>[,<ttl>]", gettext_noop("Specify host (A/AAAA and PTR) records"), NULL },
   { LOPT_RR, ARG_DUP, "<name>,<RR-number>,[<data>]", gettext_noop("Specify arbitrary DNS resource record"), NULL },    { LOPT_RR, ARG_DUP, "<name>,<RR-number>,[<data>]", gettext_noop("Specify arbitrary DNS resource record"), NULL },
   { LOPT_CLVERBIND, OPT_CLEVERBIND, NULL, gettext_noop("Bind to interfaces in use - check for new interfaces"), NULL },    { LOPT_CLVERBIND, OPT_CLEVERBIND, NULL, gettext_noop("Bind to interfaces in use - check for new interfaces"), NULL },
   { LOPT_AUTHSERV, ARG_ONE, "<NS>,<interface>", gettext_noop("Export local names to global DNS"), NULL },    { LOPT_AUTHSERV, ARG_ONE, "<NS>,<interface>", gettext_noop("Export local names to global DNS"), NULL },
Line 446  static struct { Line 482  static struct {
   { LOPT_DNSSEC_DEBUG, OPT_DNSSEC_DEBUG, NULL, gettext_noop("Disable upstream checking for DNSSEC debugging."), NULL },    { LOPT_DNSSEC_DEBUG, OPT_DNSSEC_DEBUG, NULL, gettext_noop("Disable upstream checking for DNSSEC debugging."), NULL },
   { LOPT_DNSSEC_CHECK, OPT_DNSSEC_NO_SIGN, NULL, gettext_noop("Ensure answers without DNSSEC are in unsigned zones."), NULL },    { LOPT_DNSSEC_CHECK, OPT_DNSSEC_NO_SIGN, NULL, gettext_noop("Ensure answers without DNSSEC are in unsigned zones."), NULL },
   { LOPT_DNSSEC_TIME, OPT_DNSSEC_TIME, NULL, gettext_noop("Don't check DNSSEC signature timestamps until first cache-reload"), NULL },    { LOPT_DNSSEC_TIME, OPT_DNSSEC_TIME, NULL, gettext_noop("Don't check DNSSEC signature timestamps until first cache-reload"), NULL },
     { LOPT_DNSSEC_STAMP, ARG_ONE, "<path>", gettext_noop("Timestamp file to verify system clock for DNSSEC"), NULL },
 #ifdef OPTION6_PREFIX_CLASS   #ifdef OPTION6_PREFIX_CLASS 
   { LOPT_PREF_CLSS, ARG_DUP, "set:tag,<class>", gettext_noop("Specify DHCPv6 prefix class"), NULL },    { LOPT_PREF_CLSS, ARG_DUP, "set:tag,<class>", gettext_noop("Specify DHCPv6 prefix class"), NULL },
 #endif  #endif
Line 453  static struct { Line 490  static struct {
   { LOPT_QUIET_DHCP, OPT_QUIET_DHCP, NULL, gettext_noop("Do not log routine DHCP."), NULL },    { LOPT_QUIET_DHCP, OPT_QUIET_DHCP, NULL, gettext_noop("Do not log routine DHCP."), NULL },
   { LOPT_QUIET_DHCP6, OPT_QUIET_DHCP6, NULL, gettext_noop("Do not log routine DHCPv6."), NULL },    { LOPT_QUIET_DHCP6, OPT_QUIET_DHCP6, NULL, gettext_noop("Do not log routine DHCPv6."), NULL },
   { LOPT_QUIET_RA, OPT_QUIET_RA, NULL, gettext_noop("Do not log RA."), NULL },    { LOPT_QUIET_RA, OPT_QUIET_RA, NULL, gettext_noop("Do not log RA."), NULL },
  { LOPT_LOCAL_SERVICE, OPT_LOCAL_SERVICE, NULL, gettext_noop("Accept queries only from directly-connected networks"), NULL },  { LOPT_LOCAL_SERVICE, OPT_LOCAL_SERVICE, NULL, gettext_noop("Accept queries only from directly-connected networks."), NULL },
   { LOPT_LOOP_DETECT, OPT_LOOP_DETECT, NULL, gettext_noop("Detect and remove DNS forwarding loops."), NULL },
   { LOPT_IGNORE_ADDR, ARG_DUP, "<ipaddr>", gettext_noop("Ignore DNS responses containing ipaddr."), NULL }, 
   { LOPT_DHCPTTL, ARG_ONE, "<ttl>", gettext_noop("Set TTL in DNS responses with DHCP-derived addresses."), NULL }, 
   { 0, 0, NULL, NULL, NULL }    { 0, 0, NULL, NULL, NULL }
 };   }; 
   
Line 697  static void do_usage(void) Line 737  static void do_usage(void)
   
 #define ret_err(x) do { strcpy(errstr, (x)); return 0; } while (0)  #define ret_err(x) do { strcpy(errstr, (x)); return 0; } while (0)
   
   static char *parse_mysockaddr(char *arg, union mysockaddr *addr) 
   {
     if (inet_pton(AF_INET, arg, &addr->in.sin_addr) > 0)
       addr->sa.sa_family = AF_INET;
   #ifdef HAVE_IPV6
     else if (inet_pton(AF_INET6, arg, &addr->in6.sin6_addr) > 0)
       addr->sa.sa_family = AF_INET6;
   #endif
     else
       return _("bad address");
      
     return NULL;
   }
   
 char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_addr, char *interface, int *flags)  char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_addr, char *interface, int *flags)
 {  {
   int source_port = 0, serv_port = NAMESERVER_PORT;    int source_port = 0, serv_port = NAMESERVER_PORT;
Line 1145  static int parse_dhcp_opt(char *errstr, char *arg, int Line 1199  static int parse_dhcp_opt(char *errstr, char *arg, int
               cp = comma;                cp = comma;
               comma = split(cp);                comma = split(cp);
               slash = split_chr(cp, '/');                slash = split_chr(cp, '/');
              inet_pton(AF_INET, cp, &in);              if (!inet_pton(AF_INET, cp, &in))
                 ret_err(_("bad IPv4 address"));
               if (!slash)                if (!slash)
                 {                  {
                   memcpy(op, &in, INADDRSZ);                    memcpy(op, &in, INADDRSZ);
Line 1462  static int one_opt(int option, char *arg, char *errstr Line 1517  static int one_opt(int option, char *arg, char *errstr
         struct list {          struct list {
           char *suffix;            char *suffix;
           struct list *next;            struct list *next;
        } *ignore_suffix = NULL, *li;        } *ignore_suffix = NULL, *match_suffix = NULL, *li;
                   
         comma = split(arg);          comma = split(arg);
         if (!(directory = opt_string_alloc(arg)))          if (!(directory = opt_string_alloc(arg)))
Line 1471  static int one_opt(int option, char *arg, char *errstr Line 1526  static int one_opt(int option, char *arg, char *errstr
         for (arg = comma; arg; arg = comma)           for (arg = comma; arg; arg = comma) 
           {            {
             comma = split(arg);              comma = split(arg);
            li = opt_malloc(sizeof(struct list));            if (strlen(arg) != 0)
            li->next = ignore_suffix;              {
            ignore_suffix = li;                li = opt_malloc(sizeof(struct list));
            /* Have to copy: buffer is overwritten */                if (*arg == '*')
            li->suffix = opt_string_alloc(arg);                  {
          };                    /* "*" with no suffix is a no-op */
                     if (arg[1] == 0)
                       free(li);
                     else
                       {
                         li->next = match_suffix;
                         match_suffix = li;
                         /* Have to copy: buffer is overwritten */
                         li->suffix = opt_string_alloc(arg+1);
                       }
                   }
                 else
                   {
                     li->next = ignore_suffix;
                     ignore_suffix = li;
                     /* Have to copy: buffer is overwritten */
                     li->suffix = opt_string_alloc(arg);
                   }
               }
           }
                   
         if (!(dir_stream = opendir(directory)))          if (!(dir_stream = opendir(directory)))
           die(_("cannot access directory %s: %s"), directory, EC_FILE);            die(_("cannot access directory %s: %s"), directory, EC_FILE);
Line 1493  static int one_opt(int option, char *arg, char *errstr Line 1567  static int one_opt(int option, char *arg, char *errstr
                 ent->d_name[0] == '.')                  ent->d_name[0] == '.')
               continue;                continue;
   
               if (match_suffix)
                 {
                   for (li = match_suffix; li; li = li->next)
                     {
                       /* check for required suffices */
                       size_t ls = strlen(li->suffix);
                       if (len > ls &&
                           strcmp(li->suffix, &ent->d_name[len - ls]) == 0)
                         break;
                     }
                   if (!li)
                     continue;
                 }
               
             for (li = ignore_suffix; li; li = li->next)              for (li = ignore_suffix; li; li = li->next)
               {                {
                 /* check for proscribed suffices */                  /* check for proscribed suffices */
Line 1528  static int one_opt(int option, char *arg, char *errstr Line 1616  static int one_opt(int option, char *arg, char *errstr
             free(ignore_suffix->suffix);              free(ignore_suffix->suffix);
             free(ignore_suffix);              free(ignore_suffix);
           }            }
                      for(; match_suffix; match_suffix = li)
           {
             li = match_suffix->next;
             free(match_suffix->suffix);
             free(match_suffix);
           }
         break;          break;
       }        }
   
Line 1536  static int one_opt(int option, char *arg, char *errstr Line 1629  static int one_opt(int option, char *arg, char *errstr
       set_option_bool(OPT_CLIENT_SUBNET);        set_option_bool(OPT_CLIENT_SUBNET);
       if (arg)        if (arg)
         {          {
             char *err, *end;
           comma = split(arg);            comma = split(arg);
          if (!atoi_check(arg, &daemon->addr4_netmask) || 
              (comma && !atoi_check(comma, &daemon->addr6_netmask)))          struct mysubnet* new = opt_malloc(sizeof(struct mysubnet));
             ret_err(gen_err);          if ((end = split_chr(arg, '/')))
             {
               /* has subnet+len */
               err = parse_mysockaddr(arg, &new->addr);
               if (err)
                 ret_err(err);
               if (!atoi_check(end, &new->mask))
                 ret_err(gen_err);
               new->addr_used = 1;
             } 
           else if (!atoi_check(arg, &new->mask))
             ret_err(gen_err);
             
           daemon->add_subnet4 = new;
 
           if (comma)
             {
               new = opt_malloc(sizeof(struct mysubnet));
               if ((end = split_chr(comma, '/')))
                 {
                   /* has subnet+len */
                   err = parse_mysockaddr(comma, &new->addr);
                   if (err)
                     ret_err(err);
                   if (!atoi_check(end, &new->mask))
                     ret_err(gen_err);
                   new->addr_used = 1;
                 }
               else
                 {
                   if (!atoi_check(comma, &new->mask))
                     ret_err(gen_err);
                 }
           
               daemon->add_subnet6 = new;
             }
         }          }
       break;        break;
   
Line 1667  static int one_opt(int option, char *arg, char *errstr Line 1796  static int one_opt(int option, char *arg, char *errstr
       break;        break;
 #endif /* HAVE_DHCP */  #endif /* HAVE_DHCP */
   
    case LOPT_DHCP_HOST: /* --dhcp-hostfile */    case LOPT_DHCP_HOST:     /* --dhcp-hostsfile */
    case LOPT_DHCP_OPTS: /* --dhcp-optsfile */    case LOPT_DHCP_OPTS:     /* --dhcp-optsfile */
    case 'H': /* --addn-hosts */    case LOPT_DHCP_INOTIFY:  /* --dhcp-hostsdir */
     case LOPT_DHOPT_INOTIFY: /* --dhcp-optsdir */
     case LOPT_HOST_INOTIFY:  /* --hostsdir */
     case 'H':                /* --addn-hosts */
       {        {
         struct hostsfile *new = opt_malloc(sizeof(struct hostsfile));          struct hostsfile *new = opt_malloc(sizeof(struct hostsfile));
         static unsigned int hosts_index = SRC_AH;          static unsigned int hosts_index = SRC_AH;
Line 1691  static int one_opt(int option, char *arg, char *errstr Line 1823  static int one_opt(int option, char *arg, char *errstr
             new->next = daemon->dhcp_opts_file;              new->next = daemon->dhcp_opts_file;
             daemon->dhcp_opts_file = new;              daemon->dhcp_opts_file = new;
           }                   }       
           else 
             {
               new->next = daemon->dynamic_dirs;
               daemon->dynamic_dirs = new; 
               if (option == LOPT_DHCP_INOTIFY)
                 new->flags |= AH_DHCP_HST;
               else if (option == LOPT_DHOPT_INOTIFY)
                 new->flags |= AH_DHCP_OPT;
               else if (option == LOPT_HOST_INOTIFY)
                 new->flags |= AH_HOSTS;
             }
           
         break;          break;
       }        }
               
Line 1847  static int one_opt(int option, char *arg, char *errstr Line 1991  static int one_opt(int option, char *arg, char *errstr
                   comma = split(arg);                     comma = split(arg); 
                   daemon->soa_retry = (u32)atoi(arg);                    daemon->soa_retry = (u32)atoi(arg);
                   if (comma)                    if (comma)
                    {                    daemon->soa_expiry = (u32)atoi(comma);
                      arg = comma; 
                      comma = split(arg);  
                      daemon->soa_expiry = (u32)atoi(arg); 
                    } 
                 }                  }
             }              }
         }          }
Line 1906  static int one_opt(int option, char *arg, char *errstr Line 2046  static int one_opt(int option, char *arg, char *errstr
                               else                                else
                                 {                                  {
                                    /* generate the equivalent of                                     /* generate the equivalent of
                                       local=/<domain>/  
                                       local=/xxx.yyy.zzz.in-addr.arpa/ */                                        local=/xxx.yyy.zzz.in-addr.arpa/ */
                                   struct server *serv = add_rev4(new->start, msize);                                    struct server *serv = add_rev4(new->start, msize);
                                   serv->flags |= SERV_NO_ADDR;                                    serv->flags |= SERV_NO_ADDR;
   
                                     /* local=/<domain>/ */
                                     serv = opt_malloc(sizeof(struct server));
                                     memset(serv, 0, sizeof(struct server));
                                     serv->domain = d;
                                     serv->flags = SERV_HAS_DOMAIN | SERV_NO_ADDR;
                                     serv->next = daemon->servers;
                                     daemon->servers = serv;
                                 }                                  }
                             }                              }
                         }                          }
Line 1943  static int one_opt(int option, char *arg, char *errstr Line 2090  static int one_opt(int option, char *arg, char *errstr
                               else                                 else 
                                 {                                  {
                                   /* generate the equivalent of                                    /* generate the equivalent of
                                      local=/<domain>/  
                                      local=/xxx.yyy.zzz.ip6.arpa/ */                                       local=/xxx.yyy.zzz.ip6.arpa/ */
                                   struct server *serv = add_rev6(&new->start6, msize);                                    struct server *serv = add_rev6(&new->start6, msize);
                                   serv->flags |= SERV_NO_ADDR;                                    serv->flags |= SERV_NO_ADDR;
                                     
                                     /* local=/<domain>/ */
                                     serv = opt_malloc(sizeof(struct server));
                                     memset(serv, 0, sizeof(struct server));
                                     serv->domain = d;
                                     serv->flags = SERV_HAS_DOMAIN | SERV_NO_ADDR;
                                     serv->next = daemon->servers;
                                     daemon->servers = serv;
                                 }                                  }
                             }                              }
                         }                          }
Line 2009  static int one_opt(int option, char *arg, char *errstr Line 2163  static int one_opt(int option, char *arg, char *errstr
         }          }
       break;        break;
               
       case LOPT_CPE_ID: /* --add-dns-client */
         if (arg)
           daemon->dns_client_id = opt_string_alloc(arg);
         break;
   
       case LOPT_ADD_MAC: /* --add-mac */
         if (!arg)
           set_option_bool(OPT_ADD_MAC);
         else
           {
             unhide_metas(arg);
             if (strcmp(arg, "base64") == 0)
               set_option_bool(OPT_MAC_B64);
             else if (strcmp(arg, "text") == 0)
               set_option_bool(OPT_MAC_HEX);
             else
               ret_err(gen_err);
           }
         break;
   
     case 'u':  /* --user */      case 'u':  /* --user */
       daemon->username = opt_string_alloc(arg);        daemon->username = opt_string_alloc(arg);
       break;        break;
Line 2070  static int one_opt(int option, char *arg, char *errstr Line 2244  static int one_opt(int option, char *arg, char *errstr
       break;        break;
               
     case 'B':  /* --bogus-nxdomain */      case 'B':  /* --bogus-nxdomain */
      {    case LOPT_IGNORE_ADDR: /* --ignore-address */
      {
         struct in_addr addr;          struct in_addr addr;
         unhide_metas(arg);          unhide_metas(arg);
         if (arg && (inet_pton(AF_INET, arg, &addr) > 0))          if (arg && (inet_pton(AF_INET, arg, &addr) > 0))
           {            {
             struct bogus_addr *baddr = opt_malloc(sizeof(struct bogus_addr));              struct bogus_addr *baddr = opt_malloc(sizeof(struct bogus_addr));
            baddr->next = daemon->bogus_addr;            if (option == 'B')
            daemon->bogus_addr = baddr;              {
                 baddr->next = daemon->bogus_addr;
                 daemon->bogus_addr = baddr;
               }
             else
               {
                 baddr->next = daemon->ignore_addr;
                 daemon->ignore_addr = baddr;
               }
             baddr->addr = addr;              baddr->addr = addr;
           }            }
         else          else
Line 2171  static int one_opt(int option, char *arg, char *errstr Line 2354  static int one_opt(int option, char *arg, char *errstr
           {            {
             newlist = opt_malloc(sizeof(struct server));              newlist = opt_malloc(sizeof(struct server));
             memset(newlist, 0, sizeof(struct server));              memset(newlist, 0, sizeof(struct server));
   #ifdef HAVE_LOOP
               newlist->uid = rand32();
   #endif
           }            }
                   
         if (servers_only && option == 'S')          if (servers_only && option == 'S')
Line 2189  static int one_opt(int option, char *arg, char *errstr Line 2375  static int one_opt(int option, char *arg, char *errstr
           {            {
             if (!(newlist->flags & SERV_NO_REBIND))              if (!(newlist->flags & SERV_NO_REBIND))
               newlist->flags |= SERV_NO_ADDR; /* no server */                newlist->flags |= SERV_NO_ADDR; /* no server */
             if (newlist->flags & SERV_LITERAL_ADDRESS)  
               ret_err(gen_err);  
           }            }
   
         else if (strcmp(arg, "#") == 0)          else if (strcmp(arg, "#") == 0)
Line 2352  static int one_opt(int option, char *arg, char *errstr Line 2536  static int one_opt(int option, char *arg, char *errstr
         ret_err(gen_err);          ret_err(gen_err);
       break;        break;
   
       case LOPT_MAXPORT:  /* --max-port */
         if (!atoi_check16(arg, &daemon->max_port))
           ret_err(gen_err);
         break;
   
     case '0':  /* --dns-forward-max */      case '0':  /* --dns-forward-max */
       if (!atoi_check(arg, &daemon->ftabsize))        if (!atoi_check(arg, &daemon->ftabsize))
         ret_err(gen_err);          ret_err(gen_err);
       break;          break;  
           
       case 'q': /* --log-queries */
         set_option_bool(OPT_LOG);
         if (arg && strcmp(arg, "extra") == 0)
           set_option_bool(OPT_EXTRALOG);
         break;
   
     case LOPT_MAX_LOGS:  /* --log-async */      case LOPT_MAX_LOGS:  /* --log-async */
       daemon->max_logs = LOG_MAX; /* default */        daemon->max_logs = LOG_MAX; /* default */
       if (arg && !atoi_check(arg, &daemon->max_logs))        if (arg && !atoi_check(arg, &daemon->max_logs))
Line 2386  static int one_opt(int option, char *arg, char *errstr Line 2581  static int one_opt(int option, char *arg, char *errstr
     case 'T':         /* --local-ttl */      case 'T':         /* --local-ttl */
     case LOPT_NEGTTL: /* --neg-ttl */      case LOPT_NEGTTL: /* --neg-ttl */
     case LOPT_MAXTTL: /* --max-ttl */      case LOPT_MAXTTL: /* --max-ttl */
       case LOPT_MINCTTL: /* --min-cache-ttl */
     case LOPT_MAXCTTL: /* --max-cache-ttl */      case LOPT_MAXCTTL: /* --max-cache-ttl */
     case LOPT_AUTHTTL: /* --auth-ttl */      case LOPT_AUTHTTL: /* --auth-ttl */
       case LOPT_DHCPTTL: /* --dhcp-ttl */
       {        {
         int ttl;          int ttl;
         if (!atoi_check(arg, &ttl))          if (!atoi_check(arg, &ttl))
Line 2396  static int one_opt(int option, char *arg, char *errstr Line 2593  static int one_opt(int option, char *arg, char *errstr
           daemon->neg_ttl = (unsigned long)ttl;            daemon->neg_ttl = (unsigned long)ttl;
         else if (option == LOPT_MAXTTL)          else if (option == LOPT_MAXTTL)
           daemon->max_ttl = (unsigned long)ttl;            daemon->max_ttl = (unsigned long)ttl;
           else if (option == LOPT_MINCTTL)
             {
               if (ttl > TTL_FLOOR_LIMIT)
                 ttl = TTL_FLOOR_LIMIT;
               daemon->min_cache_ttl = (unsigned long)ttl;
             }
         else if (option == LOPT_MAXCTTL)          else if (option == LOPT_MAXCTTL)
           daemon->max_cache_ttl = (unsigned long)ttl;            daemon->max_cache_ttl = (unsigned long)ttl;
         else if (option == LOPT_AUTHTTL)          else if (option == LOPT_AUTHTTL)
           daemon->auth_ttl = (unsigned long)ttl;            daemon->auth_ttl = (unsigned long)ttl;
           else if (option == LOPT_DHCPTTL)
             {
               daemon->dhcp_ttl = (unsigned long)ttl;
               daemon->use_dhcp_ttl = 1;
             }
         else          else
           daemon->local_ttl = (unsigned long)ttl;            daemon->local_ttl = (unsigned long)ttl;
         break;          break;
Line 2418  static int one_opt(int option, char *arg, char *errstr Line 2626  static int one_opt(int option, char *arg, char *errstr
         ret_err(gen_err);          ret_err(gen_err);
       break;          break;  
   
       case LOPT_TFTP_MTU:  /*  --tftp-mtu */
         if (!atoi_check(arg, &daemon->tftp_mtu))
           ret_err(gen_err);
         break;
   
     case LOPT_PREFIX: /* --tftp-prefix */      case LOPT_PREFIX: /* --tftp-prefix */
       comma = split(arg);        comma = split(arg);
       if (comma)        if (comma)
Line 2560  static int one_opt(int option, char *arg, char *errstr Line 2773  static int one_opt(int option, char *arg, char *errstr
                 leasepos = 3;                  leasepos = 3;
                 if (!is_same_net(new->start, new->end, new->netmask))                  if (!is_same_net(new->start, new->end, new->netmask))
                   ret_err(_("inconsistent DHCP range"));                    ret_err(_("inconsistent DHCP range"));
              }                
                           
            if (k >= 4 && strchr(a[3], '.') &&                  if (k >= 4 && strchr(a[3], '.') &&  
                (inet_pton(AF_INET, a[3], &new->broadcast) > 0))                    (inet_pton(AF_INET, a[3], &new->broadcast) > 0))
              {                  {
                new->flags |= CONTEXT_BRDCAST;                    new->flags |= CONTEXT_BRDCAST;
                leasepos = 4;                    leasepos = 4;
                   }
               }                }
           }            }
 #ifdef HAVE_DHCP6  #ifdef HAVE_DHCP6
Line 2583  static int one_opt(int option, char *arg, char *errstr Line 2797  static int one_opt(int option, char *arg, char *errstr
                 if (strcmp(a[leasepos], "static") == 0)                  if (strcmp(a[leasepos], "static") == 0)
                   new->flags |= CONTEXT_STATIC | CONTEXT_DHCP;                    new->flags |= CONTEXT_STATIC | CONTEXT_DHCP;
                 else if (strcmp(a[leasepos], "ra-only") == 0 || strcmp(a[leasepos], "slaac") == 0 )                  else if (strcmp(a[leasepos], "ra-only") == 0 || strcmp(a[leasepos], "slaac") == 0 )
                  new->flags |= CONTEXT_RA_ONLY | CONTEXT_RA;                  new->flags |= CONTEXT_RA;
                 else if (strcmp(a[leasepos], "ra-names") == 0)                  else if (strcmp(a[leasepos], "ra-names") == 0)
                   new->flags |= CONTEXT_RA_NAME | CONTEXT_RA;                    new->flags |= CONTEXT_RA_NAME | CONTEXT_RA;
                   else if (strcmp(a[leasepos], "ra-advrouter") == 0)
                     new->flags |= CONTEXT_RA_ROUTER | CONTEXT_RA;
                 else if (strcmp(a[leasepos], "ra-stateless") == 0)                  else if (strcmp(a[leasepos], "ra-stateless") == 0)
                   new->flags |= CONTEXT_RA_STATELESS | CONTEXT_DHCP | CONTEXT_RA;                    new->flags |= CONTEXT_RA_STATELESS | CONTEXT_DHCP | CONTEXT_RA;
                   else if (strcmp(a[leasepos], "off-link") == 0)
                     new->flags |= CONTEXT_RA_OFF_LINK;
                 else if (leasepos == 1 && inet_pton(AF_INET6, a[leasepos], &new->end6))                  else if (leasepos == 1 && inet_pton(AF_INET6, a[leasepos], &new->end6))
                   new->flags |= CONTEXT_DHCP;                     new->flags |= CONTEXT_DHCP; 
                 else if (strstr(a[leasepos], "constructor:") == a[leasepos])                  else if (strstr(a[leasepos], "constructor:") == a[leasepos])
Line 2615  static int one_opt(int option, char *arg, char *errstr Line 2833  static int one_opt(int option, char *arg, char *errstr
                           
             if (new->prefix != 64)              if (new->prefix != 64)
               {                {
                if ((new->flags & (CONTEXT_RA_ONLY | CONTEXT_RA_NAME | CONTEXT_RA_STATELESS)))                if (new->flags & CONTEXT_RA)
                   ret_err(_("prefix length must be exactly 64 for RA subnets"));                    ret_err(_("prefix length must be exactly 64 for RA subnets"));
                 else if (new->flags & CONTEXT_TEMPLATE)                  else if (new->flags & CONTEXT_TEMPLATE)
                   ret_err(_("prefix length must be exactly 64 for subnet constructors"));                    ret_err(_("prefix length must be exactly 64 for subnet constructors"));
Line 2652  static int one_opt(int option, char *arg, char *errstr Line 2870  static int one_opt(int option, char *arg, char *errstr
                   
         if (leasepos < k)          if (leasepos < k)
           {            {
               if (leasepos != k-1)
                 ret_err(_("bad dhcp-range"));
               
             if (strcmp(a[leasepos], "infinite") == 0)              if (strcmp(a[leasepos], "infinite") == 0)
               new->lease_time = 0xffffffff;                new->lease_time = 0xffffffff;
             else if (strcmp(a[leasepos], "deprecated") == 0)              else if (strcmp(a[leasepos], "deprecated") == 0)
Line 2746  static int one_opt(int option, char *arg, char *errstr Line 2967  static int one_opt(int option, char *arg, char *errstr
                         }                          }
   
                       if (len == -1)                        if (len == -1)
   
                         ret_err(_("bad hex constant"));                          ret_err(_("bad hex constant"));
                       else if ((new->clid = opt_malloc(len)))                        else if ((new->clid = opt_malloc(len)))
                         {                          {
Line 3078  static int one_opt(int option, char *arg, char *errstr Line 3298  static int one_opt(int option, char *arg, char *errstr
        {         {
          struct pxe_service *new = opt_malloc(sizeof(struct pxe_service));           struct pxe_service *new = opt_malloc(sizeof(struct pxe_service));
          char *CSA[] = { "x86PC", "PC98", "IA64_EFI", "Alpha", "Arc_x86", "Intel_Lean_Client",           char *CSA[] = { "x86PC", "PC98", "IA64_EFI", "Alpha", "Arc_x86", "Intel_Lean_Client",
                         "IA32_EFI", "BC_EFI", "Xscale_EFI", "x86-64_EFI", NULL };                           "IA32_EFI", "x86-64_EFI", "Xscale_EFI", "BC_EFI",
                          "ARM32_EFI", "ARM64_EFI", NULL };  
          static int boottype = 32768;           static int boottype = 32768;
                     
          new->netid = NULL;           new->netid = NULL;
Line 3439  static int one_opt(int option, char *arg, char *errstr Line 3660  static int one_opt(int option, char *arg, char *errstr
             (!(inet_pton(AF_INET, a[1], &new->out) > 0)))              (!(inet_pton(AF_INET, a[1], &new->out) > 0)))
           option = '?';            option = '?';
                   
        if (k == 3)        if (k == 3 && !inet_pton(AF_INET, a[2], &new->mask))
          inet_pton(AF_INET, a[2], &new->mask);          option = '?';
                   
         if (dash &&           if (dash && 
             (!(inet_pton(AF_INET, dash, &new->end) > 0) ||              (!(inet_pton(AF_INET, dash, &new->end) > 0) ||
Line 3490  static int one_opt(int option, char *arg, char *errstr Line 3711  static int one_opt(int option, char *arg, char *errstr
     case LOPT_CNAME: /* --cname */      case LOPT_CNAME: /* --cname */
       {        {
         struct cname *new;          struct cname *new;
        char *alias;        char *alias, *target, *ttls;
        char *target;        int ttl = -1;
   
         if (!(comma = split(arg)))          if (!(comma = split(arg)))
           ret_err(gen_err);            ret_err(gen_err);
                   
           if ((ttls = split(comma)) && !atoi_check(ttls, &ttl))
             ret_err(_("bad TTL"));
           
         alias = canonicalise_opt(arg);          alias = canonicalise_opt(arg);
         target = canonicalise_opt(comma);          target = canonicalise_opt(comma);
                           
Line 3511  static int one_opt(int option, char *arg, char *errstr Line 3735  static int one_opt(int option, char *arg, char *errstr
             daemon->cnames = new;              daemon->cnames = new;
             new->alias = alias;              new->alias = alias;
             new->target = target;              new->target = target;
               new->ttl = ttl;
           }            }
               
         break;          break;
Line 3576  static int one_opt(int option, char *arg, char *errstr Line 3801  static int one_opt(int option, char *arg, char *errstr
     case LOPT_RR: /* dns-rr */      case LOPT_RR: /* dns-rr */
       {        {
         struct txt_record *new;          struct txt_record *new;
        size_t len = len;        size_t len = 0;
         char *data;          char *data;
         int val;          int val;
   
Line 3684  static int one_opt(int option, char *arg, char *errstr Line 3909  static int one_opt(int option, char *arg, char *errstr
                     if (!atoi_check16(arg, &priority))                      if (!atoi_check16(arg, &priority))
                       ret_err(_("invalid priority"));                        ret_err(_("invalid priority"));
                                                   
                    if (comma)                    if (comma && !atoi_check16(comma, &weight))
                      {                      ret_err(_("invalid weight"));
                        arg = comma; 
                        comma = split(arg); 
                        if (!atoi_check16(arg, &weight)) 
                          ret_err(_("invalid weight")); 
                      } 
                   }                    }
               }                }
           }            }
Line 3711  static int one_opt(int option, char *arg, char *errstr Line 3931  static int one_opt(int option, char *arg, char *errstr
       {        {
         struct host_record *new = opt_malloc(sizeof(struct host_record));          struct host_record *new = opt_malloc(sizeof(struct host_record));
         memset(new, 0, sizeof(struct host_record));          memset(new, 0, sizeof(struct host_record));
                new->ttl = -1;
 
         if (!arg || !(comma = split(arg)))          if (!arg || !(comma = split(arg)))
           ret_err(_("Bad host-record"));            ret_err(_("Bad host-record"));
                   
         while (arg)          while (arg)
           {            {
             struct all_addr addr;              struct all_addr addr;
            if (inet_pton(AF_INET, arg, &addr))            char *dig;
 
             for (dig = arg; *dig != 0; dig++)
               if (*dig < '0' || *dig > '9')
                 break;
             if (*dig == 0)
               new->ttl = atoi(arg);
             else if (inet_pton(AF_INET, arg, &addr))
               new->addr = addr.addr.addr4;                new->addr = addr.addr.addr4;
 #ifdef HAVE_IPV6  #ifdef HAVE_IPV6
             else if (inet_pton(AF_INET6, arg, &addr))              else if (inet_pton(AF_INET6, arg, &addr))
Line 3760  static int one_opt(int option, char *arg, char *errstr Line 3988  static int one_opt(int option, char *arg, char *errstr
       }        }
   
 #ifdef HAVE_DNSSEC  #ifdef HAVE_DNSSEC
       case LOPT_DNSSEC_STAMP:
         daemon->timestamp_file = opt_string_alloc(arg); 
         break;
   
     case LOPT_TRUST_ANCHOR:      case LOPT_TRUST_ANCHOR:
       {        {
         struct ds_config *new = opt_malloc(sizeof(struct ds_config));          struct ds_config *new = opt_malloc(sizeof(struct ds_config));
Line 3958  static void read_file(char *file, FILE *f, int hard_op Line 4190  static void read_file(char *file, FILE *f, int hard_op
   fclose(f);    fclose(f);
 }  }
   
   #ifdef HAVE_DHCP
   int option_read_dynfile(char *file, int flags)
   {
     my_syslog(MS_DHCP | LOG_INFO, _("read %s"), file);
     
     if (flags & AH_DHCP_HST)
       return one_file(file, LOPT_BANK);
     else if (flags & AH_DHCP_OPT)
       return one_file(file, LOPT_OPTS);
     
     return 0;
   }
   #endif
   
 static int one_file(char *file, int hard_opt)  static int one_file(char *file, int hard_opt)
 {  {
   FILE *f;    FILE *f;
Line 4055  struct hostsfile *expand_filelist(struct hostsfile *li Line 4301  struct hostsfile *expand_filelist(struct hostsfile *li
                           
             /* don't read this as a file */              /* don't read this as a file */
             ah->flags |= AH_INACTIVE;              ah->flags |= AH_INACTIVE;
            
             if (!(dir_stream = opendir(ah->fname)))              if (!(dir_stream = opendir(ah->fname)))
               my_syslog(LOG_ERR, _("cannot access directory %s: %s"),                 my_syslog(LOG_ERR, _("cannot access directory %s: %s"), 
                         ah->fname, strerror(errno));                          ah->fname, strerror(errno));
Line 4267  void read_opts(int argc, char **argv, char *compile_op Line 4513  void read_opts(int argc, char **argv, char *compile_op
   daemon->soa_refresh = SOA_REFRESH;    daemon->soa_refresh = SOA_REFRESH;
   daemon->soa_retry = SOA_RETRY;    daemon->soa_retry = SOA_RETRY;
   daemon->soa_expiry = SOA_EXPIRY;    daemon->soa_expiry = SOA_EXPIRY;
     daemon->max_port = MAX_PORT;
   
   add_txt("version.bind", "dnsmasq-" VERSION, 0 );    add_txt("version.bind", "dnsmasq-" VERSION, 0 );
   add_txt("authors.bind", "Simon Kelley", 0);    add_txt("authors.bind", "Simon Kelley", 0);
   add_txt("copyright.bind", COPYRIGHT, 0);    add_txt("copyright.bind", COPYRIGHT, 0);
Line 4354  void read_opts(int argc, char **argv, char *compile_op Line 4602  void read_opts(int argc, char **argv, char *compile_op
     }      }
   
   if (conffile)    if (conffile)
    one_file(conffile, conffile_opt);    {
       one_file(conffile, conffile_opt);
       if (conffile_opt == 0)
         free(conffile);
     }
   
   /* port might not be known when the address is parsed - fill in here */    /* port might not be known when the address is parsed - fill in here */
   if (daemon->servers)    if (daemon->servers)
Line 4369  void read_opts(int argc, char **argv, char *compile_op Line 4621  void read_opts(int argc, char **argv, char *compile_op
             else if (tmp->source_addr.sa.sa_family == AF_INET6)              else if (tmp->source_addr.sa.sa_family == AF_INET6)
               tmp->source_addr.in6.sin6_port = htons(daemon->query_port);                tmp->source_addr.in6.sin6_port = htons(daemon->query_port);
 #endif   #endif 
          }           }
    }    } 
       
     if (daemon->host_records)
       {
         struct host_record *hr;
         
         for (hr = daemon->host_records; hr; hr = hr->next)
           if (hr->ttl == -1)
             hr->ttl = daemon->local_ttl;
       }
   
     if (daemon->cnames)
       {
         struct cname *cn;
         
         for (cn = daemon->cnames; cn; cn = cn->next)
           if (cn->ttl == -1)
             cn->ttl = daemon->local_ttl;
       }
   
   if (daemon->if_addrs)    if (daemon->if_addrs)
     {        {  
       struct iname *tmp;        struct iname *tmp;

Removed from v.1.1.1.2  
changed lines
  Added in v.1.1.1.3


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>