Commit 1e505122 authored by Simon Kelley's avatar Simon Kelley

Final form of configuration for EDNS0 MAC-address code.

parent 926332a7
...@@ -34,6 +34,17 @@ version 2.76 ...@@ -34,6 +34,17 @@ version 2.76
Add --max-port configuration. Thanks to Hans Dedecker for Add --max-port configuration. Thanks to Hans Dedecker for
the patch. 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 version 2.75
Fix reversion on 2.74 which caused 100% CPU use when a Fix reversion on 2.74 which caused 100% CPU use when a
......
...@@ -604,7 +604,7 @@ configured a zero is added in front of the label. ::1 becomes 0--1. ...@@ -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 The address range can be of the form
<ip address>,<ip address> or <ip address>/<netmask> <ip address>,<ip address> or <ip address>/<netmask>
.TP .TP
.B --add-mac .B --add-mac[=base64]
Add the MAC address of the requestor to DNS queries which are Add the MAC address of the requestor to DNS queries which are
forwarded upstream. This may be used to DNS filtering by the upstream 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 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 ...@@ -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 is not yet standardised, so this should be considered
experimental. Also note that exposing MAC addresses in this way may experimental. Also note that exposing MAC addresses in this way may
have security and privacy implications. The warning about caching 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 .TP
.B --add-subnet[[=[<IPv4 address>/]<IPv4 prefix length>][,[<IPv6 address>/]<IPv6 prefix length>]] .B --add-subnet[[=[<IPv4 address>/]<IPv4 prefix length>][,[<IPv6 address>/]<IPv6 prefix length>]]
Add a subnet address to the DNS queries which are forwarded Add a subnet address to the DNS queries which are forwarded
...@@ -1543,11 +1548,11 @@ At dnsmasq startup, the script will be invoked for ...@@ -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 all existing leases as they are read from the lease file. Expired
leases will be called with "del" and others with "old". When dnsmasq leases will be called with "del" and others with "old". When dnsmasq
receives a HUP signal, the script will be invoked for existing leases 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 There are four further actions which may appear as the first argument
to the script, "init" and "tftp". More may be added in the future, so 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 scripts should be written to ignore unknown actions. "init" is
described below in described below in
.B --leasefile-ro .B --leasefile-ro
...@@ -1555,6 +1560,11 @@ The "tftp" action is invoked when a TFTP file transfer completes: the ...@@ -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 arguments are the file size in bytes, the address to which the file
was sent, and the complete pathname of 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 .TP
.B --dhcp-luascript=<path> .B --dhcp-luascript=<path>
Specify a script written in Lua, to be run when leases are created, Specify a script written in Lua, to be run when leases are created,
...@@ -1601,10 +1611,24 @@ table holds the tags ...@@ -1601,10 +1611,24 @@ table holds the tags
.B file_name .B file_name
and and
.B file_size. .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 .TP
.B --dhcp-scriptuser .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. 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 .B \-9, --leasefile-ro
Completely suppress use of the lease database file. The file will not Completely suppress use of the lease database file. The file will not
be created, read, or written. Change the way the lease-change be created, read, or written. Change the way the lease-change
......
...@@ -117,6 +117,11 @@ int find_mac(union mysockaddr *addr, unsigned char *mac, int lazy, time_t now) ...@@ -117,6 +117,11 @@ 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 the database is less then INTERVAL old, look in there */
if (difftime(now, last) < INTERVAL) if (difftime(now, last) < INTERVAL)
{
/* addr == NULL -> just make cache up-to-date */
if (!addr)
return 0;
for (arp = arps; arp; arp = arp->next) for (arp = arps; arp; arp = arp->next)
{ {
if (addr->sa.sa_family == arp->family) if (addr->sa.sa_family == arp->family)
...@@ -140,6 +145,7 @@ int find_mac(union mysockaddr *addr, unsigned char *mac, int lazy, time_t now) ...@@ -140,6 +145,7 @@ int find_mac(union mysockaddr *addr, unsigned char *mac, int lazy, time_t now)
return arp->hwlen; return arp->hwlen;
} }
} }
}
/* Not found, try the kernel */ /* Not found, try the kernel */
if (!updated) if (!updated)
...@@ -209,7 +215,7 @@ int do_arp_script_run(void) ...@@ -209,7 +215,7 @@ int do_arp_script_run(void)
if (old) if (old)
{ {
#ifdef HAVE_SCRIPT #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); queue_arp(ACTION_ARP_OLD, old->hwaddr, old->hwlen, old->family, &old->addr);
#endif #endif
arp = old; arp = old;
...@@ -223,7 +229,7 @@ int do_arp_script_run(void) ...@@ -223,7 +229,7 @@ int do_arp_script_run(void)
if (arp->status == ARP_NEW) if (arp->status == ARP_NEW)
{ {
#ifdef HAVE_SCRIPT #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); queue_arp(ACTION_ARP, arp->hwaddr, arp->hwlen, arp->family, &arp->addr);
#endif #endif
arp->status = ARP_FOUND; arp->status = ARP_FOUND;
......
...@@ -260,10 +260,10 @@ int main (int argc, char **argv) ...@@ -260,10 +260,10 @@ int main (int argc, char **argv)
creating any file descriptors which shouldn't be leaked creating any file descriptors which shouldn't be leaked
to the lease-script init process. We need to call common_init to the lease-script init process. We need to call common_init
before lease_init to allocate buffers it uses. 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. */ conditions below. */
if (daemon->dhcp || daemon->doing_dhcp6 || daemon->relay4 || 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(); dhcp_common_init();
if (daemon->dhcp || daemon->doing_dhcp6) if (daemon->dhcp || daemon->doing_dhcp6)
...@@ -570,7 +570,7 @@ int main (int argc, char **argv) ...@@ -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. */ /* if we are to run scripts, we need to fork a helper before dropping root. */
daemon->helperfd = -1; daemon->helperfd = -1;
#ifdef HAVE_SCRIPT #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->lease_change_command || daemon->luascript))
daemon->helperfd = create_helper(pipewrite, err_pipe[1], script_uid, script_gid, max_fd); daemon->helperfd = create_helper(pipewrite, err_pipe[1], script_uid, script_gid, max_fd);
#endif #endif
...@@ -937,6 +937,9 @@ int main (int argc, char **argv) ...@@ -937,6 +937,9 @@ int main (int argc, char **argv)
while (helper_buf_empty() && do_script_run(now)); while (helper_buf_empty() && do_script_run(now));
# endif # endif
/* Refresh cache */
if (option_bool(OPT_SCRIPT_ARP))
find_mac(NULL, NULL, 0, now);
while (helper_buf_empty() && do_arp_script_run()); while (helper_buf_empty() && do_arp_script_run());
# ifdef HAVE_TFTP # ifdef HAVE_TFTP
......
...@@ -235,8 +235,9 @@ struct event_desc { ...@@ -235,8 +235,9 @@ struct event_desc {
#define OPT_LOOP_DETECT 50 #define OPT_LOOP_DETECT 50
#define OPT_EXTRALOG 51 #define OPT_EXTRALOG 51
#define OPT_TFTP_NO_FAIL 52 #define OPT_TFTP_NO_FAIL 52
#define OPT_DNS_CLIENT 53 #define OPT_SCRIPT_ARP 53
#define OPT_LAST 54 #define OPT_MAC_B64 54
#define OPT_LAST 55
/* extra flags for my_syslog, we use a couple of facilities since they are known /* 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. */ not to occupy the same bits as priorities, no matter how syslog.h is set up. */
......
...@@ -233,10 +233,6 @@ static size_t add_dns_client(struct dns_header *header, size_t plen, unsigned ch ...@@ -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); 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; return plen;
} }
...@@ -381,9 +377,13 @@ size_t add_edns0_config(struct dns_header *header, size_t plen, unsigned char *l ...@@ -381,9 +377,13 @@ size_t add_edns0_config(struct dns_header *header, size_t plen, unsigned char *l
if (option_bool(OPT_ADD_MAC)) if (option_bool(OPT_ADD_MAC))
plen = add_mac(header, plen, limit, source, now); 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); 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)) if (option_bool(OPT_CLIENT_SUBNET))
{ {
plen = add_source_addr(header, plen, limit, source); plen = add_source_addr(header, plen, limit, source);
......
...@@ -155,7 +155,8 @@ struct myoption { ...@@ -155,7 +155,8 @@ struct myoption {
#define LOPT_DNSSEC_STAMP 343 #define LOPT_DNSSEC_STAMP 343
#define LOPT_TFTP_NO_FAIL 344 #define LOPT_TFTP_NO_FAIL 344
#define LOPT_MAXPORT 345 #define LOPT_MAXPORT 345
#define LOPT_DNS_CLIENT_ID 355 #define LOPT_CPE_ID 346
#define LOPT_SCRIPT_ARP 347
#ifdef HAVE_GETOPT_LONG #ifdef HAVE_GETOPT_LONG
static const struct option opts[] = static const struct option opts[] =
...@@ -282,9 +283,9 @@ static const struct myoption opts[] = ...@@ -282,9 +283,9 @@ 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-dns-client", 2, 0 , LOPT_DNS_CLIENT_ID }, { "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 },
...@@ -317,6 +318,7 @@ static const struct myoption opts[] = ...@@ -317,6 +318,7 @@ static const struct myoption opts[] =
{ "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 }, { "dns-loop-detect", 0, 0, LOPT_LOOP_DETECT },
{ "script-arp", 0, 0, LOPT_SCRIPT_ARP },
{ NULL, 0, 0, 0 } { NULL, 0, 0, 0 }
}; };
...@@ -414,6 +416,7 @@ static struct { ...@@ -414,6 +416,7 @@ 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 },
...@@ -449,9 +452,9 @@ static struct { ...@@ -449,9 +452,9 @@ static struct {
{ 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]", 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_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_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 },
...@@ -2156,12 +2159,24 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma ...@@ -2156,12 +2159,24 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
} }
break; break;
case LOPT_DNS_CLIENT_ID: /* --add-dns-client */ case LOPT_CPE_ID: /* --add-dns-client */
set_option_bool(OPT_DNS_CLIENT);
if (arg) if (arg)
daemon->dns_client_id = opt_string_alloc(arg); daemon->dns_client_id = opt_string_alloc(arg);
break; 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 */ case 'u': /* --user */
daemon->username = opt_string_alloc(arg); daemon->username = opt_string_alloc(arg);
break; break;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment