]> git.ipfire.org Git - people/ms/dnsmasq.git/commitdiff
Final form of configuration for EDNS0 MAC-address code.
authorSimon Kelley <simon@thekelleys.org.uk>
Mon, 25 Jan 2016 21:29:23 +0000 (21:29 +0000)
committerSimon Kelley <simon@thekelleys.org.uk>
Mon, 25 Jan 2016 21:29:23 +0000 (21:29 +0000)
CHANGELOG
man/dnsmasq.8
src/arp.c
src/dnsmasq.c
src/dnsmasq.h
src/edns0.c
src/option.c

index bc1e930f98be38af8ce06fd7cfa6be38d7e7c73a..5feb47c3c3162b3d9c3f5ff3bfdbb9abfafa74db 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -33,7 +33,18 @@ version 2.76
 
             Add --max-port configuration. Thanks to Hans Dedecker for
            the patch.
+
+           Add --script-arp and two new functions for the dhcp-script.
+           These are "arp" and "arp-old" which announce the arrival and
+           removal of entries in the ARP or nieghbour tables.
+
+           Extend --add-mac to allow a new encoding of the MAC address 
+           as base64, by configurting --add-mac=base64
+
+           Add --add-cpe-id option.
+
        
+           
        
 version 2.75
             Fix reversion on 2.74 which caused 100% CPU use when a 
index 103a81350e4ad7afc10e25eb98462bee3887acf8..b6fe6b4c0b7b61be1d258eef35103f62e13f4c66 100644 (file)
@@ -604,7 +604,7 @@ configured a zero is added in front of the label. ::1 becomes 0--1.
 The address range can be of the form
 <ip address>,<ip address> or <ip address>/<netmask>
 .TP
-.B --add-mac
+.B --add-mac[=base64]
 Add the MAC address of the requestor to DNS queries which are
 forwarded upstream. This may be used to DNS filtering by the upstream
 server. The MAC address can only be added if the requestor is on the same
@@ -612,7 +612,12 @@ subnet as the dnsmasq server. Note that the mechanism used to achieve this (an E
 is not yet standardised, so this should be considered
 experimental. Also note that exposing MAC addresses in this way may
 have security and privacy implications. The warning about caching
-given for --add-subnet applies to --add-mac too.
+given for --add-subnet applies to --add-mac too. An alternative encoding of the 
+MAC, as base64, is enabled by adding the "base64" parameter.
+.TP
+.B --add-cpe-id=<string>
+Add a arbitrary identifying string to o DNS queries which are
+forwarded upstream.
 .TP 
 .B --add-subnet[[=[<IPv4 address>/]<IPv4 prefix length>][,[<IPv6 address>/]<IPv6 prefix length>]]
 Add a subnet address to the DNS queries which are forwarded
@@ -1543,11 +1548,11 @@ At dnsmasq startup, the script will be invoked for
 all existing leases as they are read from the lease file. Expired
 leases will be called with "del" and others with "old". When dnsmasq
 receives a HUP signal, the script will be invoked for existing leases
-with an "old " event.
+with an "old" event.
 
 
-There are two further actions which may appear as the first argument
-to the script, "init" and "tftp". More may be added in the future, so
+There are four further actions which may appear as the first argument
+to the script, "init", "arp", "arp-old" and "tftp". More may be added in the future, so
 scripts should be written to ignore unknown actions. "init" is
 described below in 
 .B --leasefile-ro
@@ -1555,6 +1560,11 @@ The "tftp" action is invoked when a TFTP file transfer completes: the
 arguments are the file size in bytes, the address to which the file
 was sent, and the complete pathname of the file.
  
+The "arp" and "arp-old" actions are only called if enabled with
+.B --script-arp
+They are are supplied with a MAC address and IP address as arguments. "arp" indicates
+the arrival of a new entry in the ARP or neighbour table, and arp-old indicates the deletion of same.
+
 .TP
 .B --dhcp-luascript=<path>
 Specify a script written in Lua, to be run when leases are created,
@@ -1601,10 +1611,24 @@ table holds the tags
 .B file_name
 and 
 .B file_size.
+
+The 
+.B arp
+and
+.B arp-old
+functions are called only when enabled with
+.B --script-arp
+and have a table which holds the tags
+.B mac_addres
+and
+.B client_address.
 .TP
 .B --dhcp-scriptuser
 Specify the user as which to run the lease-change script or Lua script. This defaults to root, but can be changed to another user using this flag. 
-.TP 
+.TP
+.B --script-arp
+Enable the "arp" and "arp-old" functions in the dhcp-script and dhcp-luascript.
+.TP
 .B \-9, --leasefile-ro
 Completely suppress use of the lease database file. The file will not
 be created, read, or written. Change the way the lease-change
index d70d2afa745e2a733fdda414a1113b42b22c005e..d837ea3204538c7376692da0a821c9d7e8fc849a 100644 (file)
--- a/src/arp.c
+++ b/src/arp.c
@@ -117,30 +117,36 @@ int find_mac(union mysockaddr *addr, unsigned char *mac, int lazy, time_t now)
   
   /* If the database is less then INTERVAL old, look in there */
   if (difftime(now, last) < INTERVAL)
-    for (arp = arps; arp; arp = arp->next)
-      {
-       if (addr->sa.sa_family == arp->family)
-         {
-           if (arp->addr.addr.addr4.s_addr != addr->in.sin_addr.s_addr)
-             continue;
-         }
+    {
+      /* addr == NULL -> just make cache up-to-date */
+      if (!addr)
+       return 0;
+
+      for (arp = arps; arp; arp = arp->next)
+       {
+         if (addr->sa.sa_family == arp->family)
+           {
+             if (arp->addr.addr.addr4.s_addr != addr->in.sin_addr.s_addr)
+               continue;
+           }
 #ifdef HAVE_IPV6
-       else
-         {
-           if (!IN6_ARE_ADDR_EQUAL(&arp->addr.addr.addr6, &addr->in6.sin6_addr))
-             continue;
-         }
+         else
+           {
+             if (!IN6_ARE_ADDR_EQUAL(&arp->addr.addr.addr6, &addr->in6.sin6_addr))
+               continue;
+           }
 #endif
-       
-       /* Only accept positive entries unless in lazy mode. */
-       if (arp->status != ARP_EMPTY || lazy || updated)
-         {
-           if (mac && arp->hwlen != 0)
-             memcpy(mac, arp->hwaddr, arp->hwlen);
-           return arp->hwlen;
-         }
-      }
-  
+         
+         /* Only accept positive entries unless in lazy mode. */
+         if (arp->status != ARP_EMPTY || lazy || updated)
+           {
+             if (mac && arp->hwlen != 0)
+               memcpy(mac, arp->hwaddr, arp->hwlen);
+             return arp->hwlen;
+           }
+       }
+    }
+
   /* Not found, try the kernel */
   if (!updated)
      {
@@ -209,7 +215,7 @@ int do_arp_script_run(void)
   if (old)
     {
 #ifdef HAVE_SCRIPT
-      if (option_bool(OPT_DNS_CLIENT))
+      if (option_bool(OPT_SCRIPT_ARP))
        queue_arp(ACTION_ARP_OLD, old->hwaddr, old->hwlen, old->family, &old->addr);
 #endif
       arp = old;
@@ -223,7 +229,7 @@ int do_arp_script_run(void)
     if (arp->status == ARP_NEW)
       {
 #ifdef HAVE_SCRIPT
-       if (option_bool(OPT_DNS_CLIENT))
+       if (option_bool(OPT_SCRIPT_ARP))
          queue_arp(ACTION_ARP, arp->hwaddr, arp->hwlen, arp->family, &arp->addr);
 #endif
        arp->status = ARP_FOUND;
index 0bb3e03420051893aa52cb4e269f5997cf73966c..96aa7802aecd8b28db6e4d92d69d57384cd6b432 100644 (file)
@@ -260,10 +260,10 @@ int main (int argc, char **argv)
      creating any file descriptors which shouldn't be leaked
      to the lease-script init process. We need to call common_init
      before lease_init to allocate buffers it uses.
-     The script subsystrm relies on DHCP buffers, hence the last two
+     The script subsystem relies on DHCP buffers, hence the last two
      conditions below. */  
   if (daemon->dhcp || daemon->doing_dhcp6 || daemon->relay4 || 
-      daemon->relay6 || option_bool(OPT_TFTP) || option_bool(OPT_DNS_CLIENT))
+      daemon->relay6 || option_bool(OPT_TFTP) || option_bool(OPT_SCRIPT_ARP))
     {
       dhcp_common_init();
       if (daemon->dhcp || daemon->doing_dhcp6)
@@ -570,7 +570,7 @@ int main (int argc, char **argv)
    /* if we are to run scripts, we need to fork a helper before dropping root. */
   daemon->helperfd = -1;
 #ifdef HAVE_SCRIPT 
-  if ((daemon->dhcp || daemon->dhcp6 || option_bool(OPT_TFTP) || option_bool(OPT_DNS_CLIENT)) && 
+  if ((daemon->dhcp || daemon->dhcp6 || option_bool(OPT_TFTP) || option_bool(OPT_SCRIPT_ARP)) && 
       (daemon->lease_change_command || daemon->luascript))
       daemon->helperfd = create_helper(pipewrite, err_pipe[1], script_uid, script_gid, max_fd);
 #endif
@@ -937,6 +937,9 @@ int main (int argc, char **argv)
       while (helper_buf_empty() && do_script_run(now)); 
 #    endif
 
+      /* Refresh cache */
+      if (option_bool(OPT_SCRIPT_ARP))
+       find_mac(NULL, NULL, 0, now);
       while (helper_buf_empty() && do_arp_script_run());
 
 #    ifdef HAVE_TFTP
index fd483a65a89593359e37645004e7a37ed8a378c1..9d4d6b38ecc75df30d6e014c32945172ac1cc319 100644 (file)
@@ -235,8 +235,9 @@ struct event_desc {
 #define OPT_LOOP_DETECT    50
 #define OPT_EXTRALOG       51
 #define OPT_TFTP_NO_FAIL   52
-#define OPT_DNS_CLIENT     53
-#define OPT_LAST           54
+#define OPT_SCRIPT_ARP     53
+#define OPT_MAC_B64        54
+#define OPT_LAST           55
 
 /* extra flags for my_syslog, we use a couple of facilities since they are known 
    not to occupy the same bits as priorities, no matter how syslog.h is set up. */
index 7e8fe64c286252bbce5202736880d6a4d5810a6f..b95005f41c02881c260e7a851d0757ebac94a179 100644 (file)
@@ -233,10 +233,6 @@ static size_t add_dns_client(struct dns_header *header, size_t plen, unsigned ch
       plen = add_pseudoheader(header, plen, limit, PACKETSZ, EDNS0_OPTION_NOMDEVICEID, (unsigned char *)encode, 8, 0); 
     }
 
-  if (daemon->dns_client_id)
-    plen = add_pseudoheader(header, plen, limit, PACKETSZ, EDNS0_OPTION_NOMCPEID, 
-                           (unsigned char *)daemon->dns_client_id, strlen(daemon->dns_client_id), 0);
-
   return plen; 
 }
 
@@ -381,8 +377,12 @@ size_t add_edns0_config(struct dns_header *header, size_t plen, unsigned char *l
   if (option_bool(OPT_ADD_MAC))
     plen  = add_mac(header, plen, limit, source, now);
   
-  if (option_bool(OPT_DNS_CLIENT))
+  if (option_bool(OPT_MAC_B64))
     plen = add_dns_client(header, plen, limit, source, now);
+
+  if (daemon->dns_client_id)
+    plen = add_pseudoheader(header, plen, limit, PACKETSZ, EDNS0_OPTION_NOMCPEID, 
+                           (unsigned char *)daemon->dns_client_id, strlen(daemon->dns_client_id), 0);
   
   if (option_bool(OPT_CLIENT_SUBNET))
     {
index f40e9e24eaecb347e78cc3b7de0c4252a28a8172..ac35e7c8e720fd504ee31a8edf9e8892bc9af1e2 100644 (file)
@@ -155,7 +155,8 @@ struct myoption {
 #define LOPT_DNSSEC_STAMP  343
 #define LOPT_TFTP_NO_FAIL  344
 #define LOPT_MAXPORT       345
-#define LOPT_DNS_CLIENT_ID 355
+#define LOPT_CPE_ID        346
+#define LOPT_SCRIPT_ARP    347
 
 #ifdef HAVE_GETOPT_LONG
 static const struct option opts[] =  
@@ -282,9 +283,9 @@ static const struct myoption opts[] =
     { "dhcp-proxy", 2, 0, LOPT_PROXY },
     { "dhcp-generate-names", 2, 0, LOPT_GEN_NAMES },
     { "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-dns-client", 2, 0 , LOPT_DNS_CLIENT_ID },
+    { "add-cpe-id", 1, 0 , LOPT_CPE_ID },
     { "proxy-dnssec", 0, 0, LOPT_DNSSEC },
     { "dhcp-sequential-ip", 0, 0,  LOPT_INCR_ADDR },
     { "conntrack", 0, 0, LOPT_CONNTRACK },
@@ -317,6 +318,7 @@ static const struct myoption opts[] =
     { "quiet-dhcp6", 0, 0, LOPT_QUIET_DHCP6 },
     { "quiet-ra", 0, 0, LOPT_QUIET_RA },
     { "dns-loop-detect", 0, 0, LOPT_LOOP_DETECT },
+    { "script-arp", 0, 0, LOPT_SCRIPT_ARP },
     { NULL, 0, 0, 0 }
   };
 
@@ -414,6 +416,7 @@ static struct {
   { '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_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 },
   { '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 },
@@ -449,9 +452,9 @@ static struct {
   { 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_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]", gettext_noop("Add requestor's MAC address 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_DNS_CLIENT_ID, ARG_ONE, "<proxyname>", gettext_noop("Add client identification 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_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 },
@@ -2156,12 +2159,24 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
        }
       break;
       
-    case LOPT_DNS_CLIENT_ID: /* --add-dns-client */
-       set_option_bool(OPT_DNS_CLIENT);
-       if (arg)
+    case LOPT_CPE_ID: /* --add-dns-client */
+      if (arg)
        daemon->dns_client_id = opt_string_alloc(arg);
       break;
 
+    case LOPT_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
+           ret_err(gen_err);
+       }
+      break;
+
     case 'u':  /* --user */
       daemon->username = opt_string_alloc(arg);
       break;