dnsmasq: Update to 2.75
Message ID | 1438458997-6193-1-git-send-email-fischerm42@t-online.de |
---|---|
State | Not Applicable |
Delegated to: | Michael Tremer |
Headers |
Return-Path: <development-bounces@lists.ipfire.org> Received: from mail01.ipfire.org (mail01.tremer.info [172.28.1.200]) by septima.ipfire.org (Postfix) with ESMTP id C3F1261D6A for <patchwork@ipfire.org>; Sat, 1 Aug 2015 21:56:39 +0200 (CEST) Received: from hedwig.ipfire.org (localhost [IPv6:::1]) by mail01.ipfire.org (Postfix) with ESMTP id 9FE5023FD; Sat, 1 Aug 2015 21:56:39 +0200 (CEST) Received: from Devel.localdomain (p578D114D.dip0.t-ipconnect.de [87.141.17.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) by mail01.ipfire.org (Postfix) with ESMTPSA id DAB6A21B2; Sat, 1 Aug 2015 21:56:37 +0200 (CEST) From: fischerm42@t-online.de To: development@lists.ipfire.org Subject: [PATCH] dnsmasq: Update to 2.75 Date: Sat, 1 Aug 2015 21:56:36 +0200 Message-Id: <1438458997-6193-1-git-send-email-fischerm42@t-online.de> X-Mailer: git-send-email 2.5.0 X-BeenThere: development@lists.ipfire.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: IPFire development talk <development.lists.ipfire.org> List-Unsubscribe: <http://lists.ipfire.org/mailman/options/development>, <mailto:development-request@lists.ipfire.org?subject=unsubscribe> List-Archive: <http://lists.ipfire.org/pipermail/development/> List-Post: <mailto:development@lists.ipfire.org> List-Help: <mailto:development-request@lists.ipfire.org?subject=help> List-Subscribe: <http://lists.ipfire.org/mailman/listinfo/development>, <mailto:development-request@lists.ipfire.org?subject=subscribe> Errors-To: development-bounces@lists.ipfire.org Sender: "Development" <development-bounces@lists.ipfire.org> |
Message
Matthias Fischer
Aug. 2, 2015, 5:56 a.m. UTC
From: Matthias Fischer <fischerm42@t-online.de> Signed-off-by: Matthias Fischer <fischerm42@t-online.de> --- lfs/dnsmasq | 6 +- ...5-Add-support-to-read-ISC-DHCP-lease-file.patch | 349 ++++++++++++++++++++ ...q-Add-support-to-read-ISC-DHCP-lease-file.patch | 365 --------------------- 3 files changed, 352 insertions(+), 368 deletions(-) create mode 100644 src/patches/dnsmasq-2.75-Add-support-to-read-ISC-DHCP-lease-file.patch delete mode 100644 src/patches/dnsmasq-Add-support-to-read-ISC-DHCP-lease-file.patch
Comments
Hi, I don't know if you saw this, but I have pushed the same changes just minutes before you sent this patch yesterday :) Should we agree that you are the maintainer of dnsmasq in IPFire 2 from now on so that these clashes do not happen? Does not make sense to do the work twice. On the plus side: The changes are exactly the same. You only renamed the patch file and I didn't. So that is good :) Best, -Michael On Sat, 2015-08-01 at 21:56 +0200, fischerm42@t-online.de wrote: > From: Matthias Fischer <fischerm42@t-online.de> > > Signed-off-by: Matthias Fischer <fischerm42@t-online.de> > --- > lfs/dnsmasq | 6 +- > ...5-Add-support-to-read-ISC-DHCP-lease-file.patch | 349 > ++++++++++++++++++++ > ...q-Add-support-to-read-ISC-DHCP-lease-file.patch | 365 ----------- > ---------- > 3 files changed, 352 insertions(+), 368 deletions(-) > create mode 100644 src/patches/dnsmasq-2.75-Add-support-to-read-ISC > -DHCP-lease-file.patch > delete mode 100644 src/patches/dnsmasq-Add-support-to-read-ISC-DHCP > -lease-file.patch > > diff --git a/lfs/dnsmasq b/lfs/dnsmasq > index e4410cc..24cb92a 100644 > --- a/lfs/dnsmasq > +++ b/lfs/dnsmasq > @@ -24,7 +24,7 @@ > > include Config > > -VER = 2.73 > +VER = 2.75 > > THISAPP = dnsmasq-$(VER) > DL_FILE = $(THISAPP).tar.xz > @@ -43,7 +43,7 @@ objects = $(DL_FILE) > > $(DL_FILE) = $(DL_FROM)/$(DL_FILE) > > -$(DL_FILE)_MD5 = b8bfe96d22945c8cf4466826ba9b21bd > +$(DL_FILE)_MD5 = 887236f1ddde6eb57cdb9d01916c9f72 > > install : $(TARGET) > > @@ -73,7 +73,7 @@ $(subst %,%_MD5,$(objects)) : > $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) > @$(PREBUILD) > @rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar axf > $(DIR_DL)/$(DL_FILE) > - cd $(DIR_APP) && patch -Np1 -i > $(DIR_SRC)/src/patches/dnsmasq-Add-support-to-read-ISC-DHCP-lease > -file.patch > + cd $(DIR_APP) && patch -Np0 -i > $(DIR_SRC)/src/patches/dnsmasq-2.75-Add-support-to-read-ISC-DHCP > -lease-file.patch > cd $(DIR_APP) && sed -i src/config.h \ > -e 's|/\* #define HAVE_IDN \*/|#define HAVE_IDN|g' \ > -e 's|/\* #define HAVE_DNSSEC \*/|#define > HAVE_DNSSEC|g' \ > diff --git a/src/patches/dnsmasq-2.75-Add-support-to-read-ISC-DHCP > -lease-file.patch b/src/patches/dnsmasq-2.75-Add-support-to-read-ISC > -DHCP-lease-file.patch > new file mode 100644 > index 0000000..4810e5d > --- /dev/null > +++ b/src/patches/dnsmasq-2.75-Add-support-to-read-ISC-DHCP-lease > -file.patch > @@ -0,0 +1,349 @@ > +--- Makefile Thu Jul 30 21:59:07 2015 > ++++ Makefile Sat Aug 01 17:44:39 2015 > +@@ -73,7 +73,7 @@ > + dnsmasq.o dhcp.o lease.o rfc2131.o netlink.o dbus.o bpf.o \ > + helper.o tftp.o log.o conntrack.o dhcp6.o rfc3315.o \ > + dhcp-common.o outpacket.o radv.o slaac.o auth.o ipset.o \ > +- domain.o dnssec.o blockdata.o tables.o loop.o inotify.o > poll.o > ++ domain.o dnssec.o blockdata.o tables.o loop.o inotify.o > poll.o isc.o > + > + hdrs = dnsmasq.h config.h dhcp-protocol.h dhcp6-protocol.h \ > + dns-protocol.h radv-protocol.h ip6addr.h > +--- src/cache.c Thu Jul 30 21:59:07 2015 > ++++ src/cache.c Sat Aug 01 18:20:04 2015 > +@@ -17,7 +17,7 @@ > + #include "dnsmasq.h" > + > + static struct crec *cache_head = NULL, *cache_tail = NULL, > **hash_table = NULL; > +-#ifdef HAVE_DHCP > ++#if (defined HAVE_DHCP) || (defined HAVE_ISC_READER) > + static struct crec *dhcp_spare = NULL; > + #endif > + static struct crec *new_chain = NULL; > +@@ -222,6 +222,9 @@ > + crecp->flags &= ~F_BIGNAME; > + } > + > ++ if (crecp->flags & F_DHCP) > ++ free(crecp->name.namep); > ++ > + #ifdef HAVE_DNSSEC > + cache_blockdata_free(crecp); > + #endif > +@@ -1151,7 +1154,7 @@ > + > + } > + > +-#ifdef HAVE_DHCP > ++#if (defined HAVE_DHCP) || (defined HAVE_ISC_READER) > + struct in_addr a_record_from_hosts(char *name, time_t now) > + { > + struct crec *crecp = NULL; > +@@ -1294,7 +1297,11 @@ > + else > + crec->ttd = ttd; > + crec->addr.addr = *host_address; > ++#ifdef HAVE_ISC_READER > ++ crec->name.namep = strdup(host_name); > ++#else > + crec->name.namep = host_name; > ++#endif > + crec->uid = next_uid(); > + cache_hash(crec); > + > +--- src/dnsmasq.c Thu Jul 30 21:59:07 2015 > ++++ src/dnsmasq.c Sat Aug 01 17:51:19 2015 > +@@ -980,8 +980,13 @@ > + /* poll_resolv doesn't need to reload first time through, > since > + that's queued anyway. */ > + > +- poll_resolv(0, daemon->last_resolv != 0, now); > ++ poll_resolv(0, daemon->last_resolv != 0, now); > + daemon->last_resolv = now; > ++ > ++#ifdef HAVE_ISC_READER > ++ if (daemon->lease_file && !daemon->dhcp) > ++ load_dhcp(now); > ++#endif > + } > + #endif > + > +--- src/dnsmasq.h Thu Jul 30 21:59:07 2015 > ++++ src/dnsmasq.h Sat Aug 01 17:53:12 2015 > +@@ -1513,6 +1513,11 @@ > + void set_dynamic_inotify(int flag, int total_size, struct crec > **rhash, int revhashsz); > + #endif > + > ++/* isc.c */ > ++#ifdef HAVE_ISC_READER > ++void load_dhcp(time_t now); > ++#endif > ++ > + /* poll.c */ > + void poll_reset(void); > + int poll_check(int fd, short event); > +--- src/isc.c Sat Aug 01 18:07:12 2015 > ++++ src/isc.c Sat Aug 01 17:54:27 2015 > +@@ -0,0 +1,251 @@ > ++/* dnsmasq is Copyright (c) 2014 John Volpe, Simon Kelley and > ++ Michael Tremer > ++ > ++ 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 > ++ the Free Software Foundation; version 2 dated June, 1991, or > ++ (at your option) version 3 dated 29 June, 2007. > ++ > ++ This program is distributed in the hope that it will be useful, > ++ but WITHOUT ANY WARRANTY; without even the implied warranty of > ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > ++ GNU General Public License for more details. > ++ > ++ You should have received a copy of the GNU General Public License > ++ along with this program. If not, see < > http://www.gnu.org/licenses/>. > ++ > ++ Code in this file is based on contributions by John Volpe and > ++ Simon Kelley. Updated for recent versions of dnsmasq by > ++ Michael Tremer. > ++*/ > ++ > ++#include "dnsmasq.h" > ++ > ++#ifdef HAVE_ISC_READER > ++#define MAXTOK 50 > ++ > ++struct isc_dhcp_lease { > ++ char* name; > ++ char* fqdn; > ++ time_t expires; > ++ struct in_addr addr; > ++ struct isc_dhcp_lease* next; > ++}; > ++ > ++static struct isc_dhcp_lease* dhcp_lease_new(const char* hostname) > { > ++ struct isc_dhcp_lease* lease = > whine_malloc(sizeof(*lease)); > ++ > ++ lease->name = strdup(hostname); > ++ if (daemon->domain_suffix) { > ++ asprintf(&lease->fqdn, "%s.%s", hostname, daemon > ->domain_suffix); > ++ } > ++ lease->expires = 0; > ++ lease->next = NULL; > ++ > ++ return lease; > ++} > ++ > ++static void dhcp_lease_free(struct isc_dhcp_lease* lease) { > ++ if (!lease) > ++ return; > ++ > ++ if (lease->name) > ++ free(lease->name); > ++ if (lease->fqdn) > ++ free(lease->fqdn); > ++ free(lease); > ++} > ++ > ++static int next_token(char* token, int buffsize, FILE* fp) { > ++ int c, count = 0; > ++ char* cp = token; > ++ > ++ while ((c = getc(fp)) != EOF) { > ++ if (c == '#') { > ++ do { > ++ c = getc(fp); > ++ } while (c != '\n' && c != EOF); > ++ } > ++ > ++ if (c == ' ' || c == '\t' || c == '\n' || c == ';') > { > ++ if (count) > ++ break; > ++ } else if ((c != '"') && (count < buffsize - 1)) { > ++ *cp++ = c; > ++ count++; > ++ } > ++ } > ++ > ++ *cp = 0; > ++ return count ? 1 : 0; > ++} > ++ > ++static long get_utc_offset() { > ++ time_t t = time(NULL); > ++ struct tm* time_struct = localtime(&t); > ++ > ++ return time_struct->tm_gmtoff; > ++} > ++ > ++static time_t parse_lease_time(const char* token_date, const char* > token_time) { > ++ time_t time = (time_t)(-1); > ++ struct tm lease_time; > ++ > ++ if (sscanf(token_date, "%d/%d/%d", &lease_time.tm_year, > &lease_time.tm_mon, &lease_time.tm_mday) == 3) { > ++ lease_time.tm_year -= 1900; > ++ lease_time.tm_mon -= 1; > ++ > ++ if (sscanf(token_time, "%d:%d:%d", > &lease_time.tm_hour, &lease_time.tm_min, &lease_time.tm_sec) == 3) { > ++ time = mktime(&lease_time) + > get_utc_offset(); > ++ } > ++ } > ++ > ++ return time; > ++} > ++ > ++static struct isc_dhcp_lease* find_lease(const char* hostname, > struct isc_dhcp_lease* leases) { > ++ struct isc_dhcp_lease* lease = leases; > ++ > ++ while (lease) { > ++ if (strcmp(hostname, lease->name) == 0) { > ++ return lease; > ++ } > ++ lease = lease->next; > ++ } > ++ > ++ return NULL; > ++} > ++ > ++static off_t lease_file_size = (off_t)0; > ++static ino_t lease_file_inode = (ino_t)0; > ++ > ++void load_dhcp(time_t now) { > ++ struct isc_dhcp_lease* leases = NULL; > ++ > ++ struct stat statbuf; > ++ if (stat(daemon->lease_file, &statbuf) == -1) { > ++ return; > ++ } > ++ > ++ /* Do nothing if the lease file has not changed. */ > ++ if ((statbuf.st_size <= lease_file_size) && (statbuf.st_ino > == lease_file_inode)) > ++ return; > ++ > ++ lease_file_size = statbuf.st_size; > ++ lease_file_inode = statbuf.st_ino; > ++ > ++ FILE* fp = fopen(daemon->lease_file, "r"); > ++ if (!fp) { > ++ my_syslog(LOG_ERR, _("failed to load %s:%s"), > daemon->lease_file, strerror(errno)); > ++ return; > ++ } > ++ > ++ my_syslog(LOG_INFO, _("reading %s"), daemon->lease_file); > ++ > ++ char* hostname = daemon->namebuff; > ++ struct in_addr host_address; > ++ time_t time_starts = -1; > ++ time_t time_ends = -1; > ++ int nomem; > ++ > ++ char token[MAXTOK]; > ++ while ((next_token(token, MAXTOK, fp))) { > ++ if (strcmp(token, "lease") == 0) { > ++ hostname[0] = '\0'; > ++ > ++ if (next_token(token, MAXTOK, fp) && > ((host_address.s_addr = inet_addr(token)) != (in_addr_t)-1)) { > ++ if (next_token(token, MAXTOK, fp) > && *token == '{') { > ++ while (next_token(token, > MAXTOK, fp) && *token != '}') { > ++ if ((strcmp(token, > "client-hostname") == 0) || (strcmp(token, "hostname") == 0)) { > ++ if > (next_token(hostname, MAXDNAME, fp)) { > ++ if > (!canonicalise(hostname, &nomem)) { > ++ > *hostname = 0; > ++ > my_syslog(LOG_ERR, _("bad name in %s"), daemon->lease_file); > ++ } > ++ } > ++ } else if > ((strcmp(token, "starts") == 0) || (strcmp(token, "ends") == 0)) { > ++ char > token_date[MAXTOK]; > ++ char > token_time[MAXTOK]; > ++ > ++ int > is_starts = strcmp(token, "starts") == 0; > ++ > ++ // Throw > away the weekday and parse the date. > ++ if > (next_token(token, MAXTOK, fp) && next_token(token_date, MAXTOK, fp) > && next_token(token_time, MAXTOK, fp)) { > ++ tim > e_t time = parse_lease_time(token_date, token_time); > ++ > ++ if > (is_starts) > ++ > time_starts = time; > ++ els > e > ++ > time_ends = time; > ++ } > ++ } > ++ } > ++ > ++ if (!*hostname) > ++ continue; > ++ > ++ if ((time_starts == -1) || > (time_ends == -1)) > ++ continue; > ++ > ++ if (difftime(now, > time_ends) > 0) > ++ continue; > ++ > ++ char* dot = > strchr(hostname, '.'); > ++ if (dot) { > ++ if (!daemon > ->domain_suffix || hostname_isequal(dot + 1, daemon->domain_suffix)) > { > ++ my_syslog(L > OG_WARNING, > ++ _(" > Ignoring DHCP lease for %s because it has an illegal domain part"), > ++ hos > tname); > ++ continue; > ++ } > ++ *dot = 0; > ++ } > ++ > ++ // Search for an existing > lease in the list > ++ // with the given host name > and update the data > ++ // if needed. > ++ struct isc_dhcp_lease* > lease = find_lease(hostname, leases); > ++ > ++ // If no lease already > exists, we create a new one > ++ // and append it to the > list. > ++ if (!lease) { > ++ lease = > dhcp_lease_new(hostname); > ++ > ++ lease->next = > leases; > ++ leases = lease; > ++ } > ++ > ++ // Only update more recent > leases. > ++ if (lease->expires > > time_ends) > ++ continue; > ++ > ++ lease->addr = host_address; > ++ lease->expires = time_ends; > ++ } > ++ } > ++ } > ++ } > ++ > ++ fclose(fp); > ++ > ++ // Drop all entries. > ++ cache_unhash_dhcp(); > ++ > ++ while (leases) { > ++ struct isc_dhcp_lease *lease = leases; > ++ leases = lease->next; > ++ > ++ if (lease->fqdn) { > ++ cache_add_dhcp_entry(lease->fqdn, AF_INET, > (struct all_addr*)&lease->addr.s_addr, lease->expires); > ++ } > ++ > ++ if (lease->name) { > ++ cache_add_dhcp_entry(lease->name, AF_INET, > (struct all_addr*)&lease->addr.s_addr, lease->expires); > ++ } > ++ > ++ // Cleanup > ++ dhcp_lease_free(lease); > ++ } > ++} > ++ > ++#endif > +--- src/option.c Thu Jul 30 21:59:07 2015 > ++++ src/option.c Sat Aug 01 17:55:30 2015 > +@@ -1699,7 +1699,7 @@ > + ret_err(_("bad MX target")); > + break; > + > +-#ifdef HAVE_DHCP > ++#if (defined HAVE_DHCP) || (defined HAVE_ISC_READER) > + case 'l': /* --dhcp-leasefile */ > + daemon->lease_file = opt_string_alloc(arg); > + break; > diff --git a/src/patches/dnsmasq-Add-support-to-read-ISC-DHCP-lease > -file.patch b/src/patches/dnsmasq-Add-support-to-read-ISC-DHCP-lease > -file.patch > deleted file mode 100644 > index 1a89b36..0000000 > --- a/src/patches/dnsmasq-Add-support-to-read-ISC-DHCP-lease > -file.patch > +++ /dev/null > @@ -1,365 +0,0 @@ > -diff --git a/Makefile b/Makefile > -index 2910320b6452..0a76ce3c5154 100644 > ---- a/Makefile > -+++ b/Makefile > -@@ -73,7 +73,7 @@ objs = cache.o rfc1035.o util.o option.o forward.o > network.o \ > - dnsmasq.o dhcp.o lease.o rfc2131.o netlink.o dbus.o bpf.o \ > - helper.o tftp.o log.o conntrack.o dhcp6.o rfc3315.o \ > - dhcp-common.o outpacket.o radv.o slaac.o auth.o ipset.o \ > -- domain.o dnssec.o blockdata.o tables.o loop.o inotify.o > -+ domain.o dnssec.o blockdata.o tables.o loop.o inotify.o > isc.o > - > - hdrs = dnsmasq.h config.h dhcp-protocol.h dhcp6-protocol.h \ > - dns-protocol.h radv-protocol.h ip6addr.h > -diff --git a/src/cache.c b/src/cache.c > -index 117ae279fd4e..6ee7ee362e6c 100644 > ---- a/src/cache.c > -+++ b/src/cache.c > -@@ -17,7 +17,7 @@ > - #include "dnsmasq.h" > - > - static struct crec *cache_head = NULL, *cache_tail = NULL, > **hash_table = NULL; > --#ifdef HAVE_DHCP > -+#if (defined HAVE_DHCP) || (defined HAVE_ISC_READER) > - static struct crec *dhcp_spare = NULL; > - #endif > - static struct crec *new_chain = NULL; > -@@ -222,6 +222,9 @@ static void cache_free(struct crec *crecp) > - crecp->flags &= ~F_BIGNAME; > - } > - > -+ if (crecp->flags & F_DHCP) > -+ free(crecp->name.namep); > -+ > - #ifdef HAVE_DNSSEC > - cache_blockdata_free(crecp); > - #endif > -@@ -1151,7 +1154,7 @@ void cache_reload(void) > - > - } > - > --#ifdef HAVE_DHCP > -+#if (defined HAVE_DHCP) || (defined HAVE_ISC_READER) > - struct in_addr a_record_from_hosts(char *name, time_t now) > - { > - struct crec *crecp = NULL; > -@@ -1229,7 +1232,7 @@ void cache_add_dhcp_entry(char *host_name, int > prot, > - addrlen = sizeof(struct in6_addr); > - } > - #endif > -- > -+ > - inet_ntop(prot, host_address, daemon->addrbuff, ADDRSTRLEN); > - > - while ((crec = cache_find_by_name(crec, host_name, 0, flags | > F_CNAME))) > -@@ -1294,7 +1297,11 @@ void cache_add_dhcp_entry(char *host_name, > int prot, > - else > - crec->ttd = ttd; > - crec->addr.addr = *host_address; > -+#ifdef HAVE_ISC_READER > -+ crec->name.namep = strdup(host_name); > -+#else > - crec->name.namep = host_name; > -+#endif > - crec->uid = next_uid(); > - cache_hash(crec); > - > -diff --git a/src/dnsmasq.c b/src/dnsmasq.c > -index e903a24c8105..eefc7f939933 100644 > ---- a/src/dnsmasq.c > -+++ b/src/dnsmasq.c > -@@ -970,6 +970,11 @@ int main (int argc, char **argv) > - > - poll_resolv(0, daemon->last_resolv != 0, now); > - daemon->last_resolv = now; > -+ > -+#ifdef HAVE_ISC_READER > -+ if (daemon->lease_file && !daemon->dhcp) > -+ load_dhcp(now); > -+#endif > - } > - #endif > - > -diff --git a/src/dnsmasq.h b/src/dnsmasq.h > -index 89e758b56a0a..c5edd6fdf7f5 100644 > ---- a/src/dnsmasq.h > -+++ b/src/dnsmasq.h > -@@ -1502,3 +1502,8 @@ void inotify_dnsmasq_init(); > - int inotify_check(time_t now); > - void set_dynamic_inotify(int flag, int total_size, struct crec > **rhash, int revhashsz); > - #endif > -+ > -+/* isc.c */ > -+#ifdef HAVE_ISC_READER > -+void load_dhcp(time_t now); > -+#endif > -diff --git a/src/isc.c b/src/isc.c > -new file mode 100644 > -index 000000000000..51064426f17f > ---- /dev/null > -+++ b/src/isc.c > -@@ -0,0 +1,251 @@ > -+/* dnsmasq is Copyright (c) 2014 John Volpe, Simon Kelley and > -+ Michael Tremer > -+ > -+ 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 > -+ the Free Software Foundation; version 2 dated June, 1991, or > -+ (at your option) version 3 dated 29 June, 2007. > -+ > -+ This program is distributed in the hope that it will be useful, > -+ but WITHOUT ANY WARRANTY; without even the implied warranty of > -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > -+ GNU General Public License for more details. > -+ > -+ You should have received a copy of the GNU General Public License > -+ along with this program. If not, see < > http://www.gnu.org/licenses/>. > -+ > -+ Code in this file is based on contributions by John Volpe and > -+ Simon Kelley. Updated for recent versions of dnsmasq by > -+ Michael Tremer. > -+*/ > -+ > -+#include "dnsmasq.h" > -+ > -+#ifdef HAVE_ISC_READER > -+#define MAXTOK 50 > -+ > -+struct isc_dhcp_lease { > -+ char* name; > -+ char* fqdn; > -+ time_t expires; > -+ struct in_addr addr; > -+ struct isc_dhcp_lease* next; > -+}; > -+ > -+static struct isc_dhcp_lease* dhcp_lease_new(const char* hostname) > { > -+ struct isc_dhcp_lease* lease = > whine_malloc(sizeof(*lease)); > -+ > -+ lease->name = strdup(hostname); > -+ if (daemon->domain_suffix) { > -+ asprintf(&lease->fqdn, "%s.%s", hostname, daemon > ->domain_suffix); > -+ } > -+ lease->expires = 0; > -+ lease->next = NULL; > -+ > -+ return lease; > -+} > -+ > -+static void dhcp_lease_free(struct isc_dhcp_lease* lease) { > -+ if (!lease) > -+ return; > -+ > -+ if (lease->name) > -+ free(lease->name); > -+ if (lease->fqdn) > -+ free(lease->fqdn); > -+ free(lease); > -+} > -+ > -+static int next_token(char* token, int buffsize, FILE* fp) { > -+ int c, count = 0; > -+ char* cp = token; > -+ > -+ while ((c = getc(fp)) != EOF) { > -+ if (c == '#') { > -+ do { > -+ c = getc(fp); > -+ } while (c != '\n' && c != EOF); > -+ } > -+ > -+ if (c == ' ' || c == '\t' || c == '\n' || c == ';') > { > -+ if (count) > -+ break; > -+ } else if ((c != '"') && (count < buffsize - 1)) { > -+ *cp++ = c; > -+ count++; > -+ } > -+ } > -+ > -+ *cp = 0; > -+ return count ? 1 : 0; > -+} > -+ > -+static long get_utc_offset() { > -+ time_t t = time(NULL); > -+ struct tm* time_struct = localtime(&t); > -+ > -+ return time_struct->tm_gmtoff; > -+} > -+ > -+static time_t parse_lease_time(const char* token_date, const char* > token_time) { > -+ time_t time = (time_t)(-1); > -+ struct tm lease_time; > -+ > -+ if (sscanf(token_date, "%d/%d/%d", &lease_time.tm_year, > &lease_time.tm_mon, &lease_time.tm_mday) == 3) { > -+ lease_time.tm_year -= 1900; > -+ lease_time.tm_mon -= 1; > -+ > -+ if (sscanf(token_time, "%d:%d:%d", > &lease_time.tm_hour, &lease_time.tm_min, &lease_time.tm_sec) == 3) { > -+ time = mktime(&lease_time) + > get_utc_offset(); > -+ } > -+ } > -+ > -+ return time; > -+} > -+ > -+static struct isc_dhcp_lease* find_lease(const char* hostname, > struct isc_dhcp_lease* leases) { > -+ struct isc_dhcp_lease* lease = leases; > -+ > -+ while (lease) { > -+ if (strcmp(hostname, lease->name) == 0) { > -+ return lease; > -+ } > -+ lease = lease->next; > -+ } > -+ > -+ return NULL; > -+} > -+ > -+static off_t lease_file_size = (off_t)0; > -+static ino_t lease_file_inode = (ino_t)0; > -+ > -+void load_dhcp(time_t now) { > -+ struct isc_dhcp_lease* leases = NULL; > -+ > -+ struct stat statbuf; > -+ if (stat(daemon->lease_file, &statbuf) == -1) { > -+ return; > -+ } > -+ > -+ /* Do nothing if the lease file has not changed. */ > -+ if ((statbuf.st_size <= lease_file_size) && (statbuf.st_ino > == lease_file_inode)) > -+ return; > -+ > -+ lease_file_size = statbuf.st_size; > -+ lease_file_inode = statbuf.st_ino; > -+ > -+ FILE* fp = fopen(daemon->lease_file, "r"); > -+ if (!fp) { > -+ my_syslog(LOG_ERR, _("failed to load %s:%s"), > daemon->lease_file, strerror(errno)); > -+ return; > -+ } > -+ > -+ my_syslog(LOG_INFO, _("reading %s"), daemon->lease_file); > -+ > -+ char* hostname = daemon->namebuff; > -+ struct in_addr host_address; > -+ time_t time_starts = -1; > -+ time_t time_ends = -1; > -+ int nomem; > -+ > -+ char token[MAXTOK]; > -+ while ((next_token(token, MAXTOK, fp))) { > -+ if (strcmp(token, "lease") == 0) { > -+ hostname[0] = '\0'; > -+ > -+ if (next_token(token, MAXTOK, fp) && > ((host_address.s_addr = inet_addr(token)) != (in_addr_t)-1)) { > -+ if (next_token(token, MAXTOK, fp) > && *token == '{') { > -+ while (next_token(token, > MAXTOK, fp) && *token != '}') { > -+ if ((strcmp(token, > "client-hostname") == 0) || (strcmp(token, "hostname") == 0)) { > -+ if > (next_token(hostname, MAXDNAME, fp)) { > -+ if > (!canonicalise(hostname, &nomem)) { > -+ > *hostname = 0; > -+ > my_syslog(LOG_ERR, _("bad name in %s"), daemon->lease_file); > -+ } > -+ } > -+ } else if > ((strcmp(token, "starts") == 0) || (strcmp(token, "ends") == 0)) { > -+ char > token_date[MAXTOK]; > -+ char > token_time[MAXTOK]; > -+ > -+ int > is_starts = strcmp(token, "starts") == 0; > -+ > -+ // Throw > away the weekday and parse the date. > -+ if > (next_token(token, MAXTOK, fp) && next_token(token_date, MAXTOK, fp) > && next_token(token_time, MAXTOK, fp)) { > -+ tim > e_t time = parse_lease_time(token_date, token_time); > -+ > -+ if > (is_starts) > -+ > time_starts = time; > -+ els > e > -+ > time_ends = time; > -+ } > -+ } > -+ } > -+ > -+ if (!*hostname) > -+ continue; > -+ > -+ if ((time_starts == -1) || > (time_ends == -1)) > -+ continue; > -+ > -+ if (difftime(now, > time_ends) > 0) > -+ continue; > -+ > -+ char* dot = > strchr(hostname, '.'); > -+ if (dot) { > -+ if (!daemon > ->domain_suffix || hostname_isequal(dot + 1, daemon->domain_suffix)) > { > -+ my_syslog(L > OG_WARNING, > -+ _(" > Ignoring DHCP lease for %s because it has an illegal domain part"), > -+ hos > tname); > -+ continue; > -+ } > -+ *dot = 0; > -+ } > -+ > -+ // Search for an existing > lease in the list > -+ // with the given host name > and update the data > -+ // if needed. > -+ struct isc_dhcp_lease* > lease = find_lease(hostname, leases); > -+ > -+ // If no lease already > exists, we create a new one > -+ // and append it to the > list. > -+ if (!lease) { > -+ lease = > dhcp_lease_new(hostname); > -+ > -+ lease->next = > leases; > -+ leases = lease; > -+ } > -+ > -+ // Only update more recent > leases. > -+ if (lease->expires > > time_ends) > -+ continue; > -+ > -+ lease->addr = host_address; > -+ lease->expires = time_ends; > -+ } > -+ } > -+ } > -+ } > -+ > -+ fclose(fp); > -+ > -+ // Drop all entries. > -+ cache_unhash_dhcp(); > -+ > -+ while (leases) { > -+ struct isc_dhcp_lease *lease = leases; > -+ leases = lease->next; > -+ > -+ if (lease->fqdn) { > -+ cache_add_dhcp_entry(lease->fqdn, AF_INET, > (struct all_addr*)&lease->addr.s_addr, lease->expires); > -+ } > -+ > -+ if (lease->name) { > -+ cache_add_dhcp_entry(lease->name, AF_INET, > (struct all_addr*)&lease->addr.s_addr, lease->expires); > -+ } > -+ > -+ // Cleanup > -+ dhcp_lease_free(lease); > -+ } > -+} > -+ > -+#endif > -diff --git a/src/option.c b/src/option.c > -index cb4e76ba0aa2..f6420fcbb7ab 100644 > ---- a/src/option.c > -+++ b/src/option.c > -@@ -1693,7 +1693,7 @@ static int one_opt(int option, char *arg, char > *errstr, char *gen_err, int comma > - ret_err(_("bad MX target")); > - break; > - > --#ifdef HAVE_DHCP > -+#if (defined HAVE_DHCP) || (defined HAVE_ISC_READER) > - case 'l': /* --dhcp-leasefile */ > - daemon->lease_file = opt_string_alloc(arg); > - break;