├── .gitignore ├── Android.mk ├── CHANGELOG ├── CHANGELOG.archive ├── COPYING ├── COPYING-v3 ├── FAQ ├── Makefile ├── README.md ├── VERSION ├── bld ├── Android.mk ├── bloat-o-meter ├── get-version ├── install-man ├── install-mo └── pkg-wrapper ├── contrib ├── CPE-WAN │ └── README ├── MacOSX-launchd │ ├── launchd-README.txt │ └── uk.org.thekelleys.dnsmasq.plist ├── Solaris10 │ ├── README │ ├── README-sparc │ ├── README.create_package │ ├── create_package │ └── dnsmasq.xml ├── Suse │ ├── README │ ├── README.susefirewall │ ├── dnsmasq-SuSE.patch │ ├── dnsmasq-suse.spec │ └── rc.dnsmasq-suse ├── conntrack │ └── README ├── dbus-test │ └── dbus-test.py ├── dns-loc │ ├── README │ └── dnsmasq2-loc-rfc1876.patch ├── dnslist │ ├── dhcp.css │ ├── dnslist.pl │ └── dnslist.tt2 ├── dnsmasq_MacOSX-pre10.4 │ ├── DNSmasq │ ├── README.rtf │ └── StartupParameters.plist ├── dynamic-dnsmasq │ └── dynamic-dnsmasq.pl ├── lease-access │ ├── README │ └── lease.access.patch ├── mactable │ └── macscript ├── openvpn │ ├── README │ ├── dhclient-enter-hooks │ └── dnsmasq.patch ├── port-forward │ ├── dnsmasq-portforward │ └── portforward ├── slackware-dnsmasq │ ├── dnsmasq.SlackBuild │ ├── dnsmasq.leasedir.diff.gz │ ├── doinst.sh.gz │ ├── rc.dnsmasq.gz │ └── slack-desc ├── static-arp │ └── static-arp ├── systemd │ ├── README │ ├── dbus_activation │ └── dnsmasq.service ├── try-all-ns │ ├── README │ ├── README-2.47 │ ├── dnsmasq-2.35-try-all-ns.patch │ ├── dnsmasq-2.47_no_nxdomain_until_end.patch │ └── dnsmasq-2.68-try-all-ns ├── webmin │ ├── README │ └── dnsmasq.wbm └── wrt │ ├── Makefile │ ├── README │ ├── dhcp_lease_time.1 │ ├── dhcp_lease_time.c │ ├── dhcp_release.1 │ ├── dhcp_release.c │ └── lease_update.sh ├── dbus ├── DBus-interface └── dnsmasq.conf ├── debian ├── changelog ├── conffiles ├── control ├── copyright ├── dbus.conf ├── default ├── dnsmasq-base.conffiles ├── dnsmasq-base.postinst ├── dnsmasq-base.postrm ├── init ├── insserv ├── postinst ├── postrm ├── prerm ├── readme ├── readme.dnsmasq.d ├── resolvconf ├── resolvconf-package ├── rules ├── source │ └── format └── systemd.service ├── dnsmasq.conf.example ├── doc.html ├── logo ├── README ├── favicon.ico ├── icon.png └── icon.svg ├── man ├── dnsmasq.8 ├── es │ └── dnsmasq.8 └── fr │ └── dnsmasq.8 ├── po ├── de.po ├── es.po ├── fi.po ├── fr.po ├── id.po ├── it.po ├── no.po ├── pl.po ├── pt_BR.po └── ro.po ├── setup.html ├── src ├── auth.c ├── blockdata.c ├── bpf.c ├── cache.c ├── config.h ├── conntrack.c ├── dbus.c ├── dhcp-common.c ├── dhcp-protocol.h ├── dhcp.c ├── dhcp6-protocol.h ├── dhcp6.c ├── dns-protocol.h ├── dnsmasq.c ├── dnsmasq.h ├── dnssec.c ├── domain.c ├── forward.c ├── helper.c ├── htree.c ├── inotify.c ├── ip6addr.h ├── ipset.c ├── lease.c ├── log.c ├── loop.c ├── netlink.c ├── network.c ├── option.c ├── outpacket.c ├── radv-protocol.h ├── radv.c ├── rfc1035.c ├── rfc2131.c ├── rfc3315.c ├── slaac.c ├── tables.c ├── tftp.c └── util.c └── trust-anchors.conf /.gitignore: -------------------------------------------------------------------------------- 1 | src/*.o 2 | src/*.mo 3 | src/dnsmasq.pot 4 | src/dnsmasq 5 | src/dnsmasq_baseline 6 | src/.copts_* 7 | contrib/wrt/dhcp_lease_time 8 | contrib/wrt/dhcp_release 9 | debian/base/ 10 | debian/daemon/ 11 | debian/files 12 | debian/substvars 13 | debian/utils-substvars 14 | debian/utils/ 15 | -------------------------------------------------------------------------------- /Android.mk: -------------------------------------------------------------------------------- 1 | ifneq ($(TARGET_SIMULATOR),true) 2 | include $(call all-subdir-makefiles) 3 | endif 4 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # dnsmasq is Copyright (c) 2000-2015 Simon Kelley 2 | # 3 | # This program is free software; you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation; version 2 dated June, 1991, or 6 | # (at your option) version 3 dated 29 June, 2007. 7 | # 8 | # This program is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this program. If not, see . 15 | 16 | # NOTE: Building the i18n targets requires GNU-make 17 | 18 | 19 | # Variables you may well want to override. 20 | 21 | PREFIX = /usr/local 22 | BINDIR = $(PREFIX)/sbin 23 | MANDIR = $(PREFIX)/share/man 24 | LOCALEDIR = $(PREFIX)/share/locale 25 | BUILDDIR = $(SRC) 26 | DESTDIR = 27 | CFLAGS = -Wall -W -O2 28 | LDFLAGS = 29 | COPTS = 30 | RPM_OPT_FLAGS = 31 | LIBS = 32 | 33 | ################################################################# 34 | 35 | # Variables you might want to override. 36 | 37 | PKG_CONFIG = pkg-config 38 | INSTALL = install 39 | MSGMERGE = msgmerge 40 | MSGFMT = msgfmt 41 | XGETTEXT = xgettext 42 | 43 | SRC = src 44 | PO = po 45 | MAN = man 46 | 47 | ################################################################# 48 | 49 | # pmake way. (NB no spaces to keep gmake 3.82 happy) 50 | top!=pwd 51 | # GNU make way. 52 | top?=$(CURDIR) 53 | 54 | dbus_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DBUS $(PKG_CONFIG) --cflags dbus-1` 55 | dbus_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DBUS $(PKG_CONFIG) --libs dbus-1` 56 | idn_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_IDN $(PKG_CONFIG) --cflags libidn` 57 | idn_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_IDN $(PKG_CONFIG) --libs libidn` 58 | ct_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_CONNTRACK $(PKG_CONFIG) --cflags libnetfilter_conntrack` 59 | ct_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_CONNTRACK $(PKG_CONFIG) --libs libnetfilter_conntrack` 60 | lua_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LUASCRIPT $(PKG_CONFIG) --cflags lua5.1` 61 | lua_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LUASCRIPT $(PKG_CONFIG) --libs lua5.1` 62 | nettle_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DNSSEC $(PKG_CONFIG) --cflags nettle hogweed` 63 | nettle_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DNSSEC $(PKG_CONFIG) --libs nettle hogweed` 64 | gmp_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DNSSEC NO_GMP --copy -lgmp` 65 | sunos_libs = `if uname | grep SunOS >/dev/null 2>&1; then echo -lsocket -lnsl -lposix4; fi` 66 | version = -DVERSION='\"`$(top)/bld/get-version $(top)`\"' 67 | 68 | sum?=$(shell $(CC) -DDNSMASQ_COMPILE_OPTS $(COPTS) -E $(top)/$(SRC)/dnsmasq.h | ( md5sum 2>/dev/null || md5 ) | cut -f 1 -d ' ') 69 | sum!=$(CC) -DDNSMASQ_COMPILE_OPTS $(COPTS) -E $(top)/$(SRC)/dnsmasq.h | ( md5sum 2>/dev/null || md5 ) | cut -f 1 -d ' ' 70 | copts_conf = .copts_$(sum) 71 | 72 | objs = cache.o rfc1035.o util.o option.o forward.o network.o \ 73 | dnsmasq.o dhcp.o lease.o rfc2131.o netlink.o dbus.o bpf.o \ 74 | helper.o tftp.o log.o conntrack.o dhcp6.o rfc3315.o \ 75 | dhcp-common.o outpacket.o radv.o slaac.o auth.o ipset.o \ 76 | domain.o dnssec.o blockdata.o tables.o loop.o inotify.o htree.o 77 | 78 | hdrs = dnsmasq.h config.h dhcp-protocol.h dhcp6-protocol.h \ 79 | dns-protocol.h radv-protocol.h ip6addr.h 80 | 81 | all : $(BUILDDIR) 82 | @cd $(BUILDDIR) && $(MAKE) \ 83 | top="$(top)" \ 84 | build_cflags="$(version) $(dbus_cflags) $(idn_cflags) $(ct_cflags) $(lua_cflags) $(nettle_cflags)" \ 85 | build_libs="$(dbus_libs) $(idn_libs) $(ct_libs) $(lua_libs) $(sunos_libs) $(nettle_libs) $(gmp_libs)" \ 86 | -f $(top)/Makefile dnsmasq 87 | 88 | mostly_clean : 89 | rm -f $(BUILDDIR)/*.mo $(BUILDDIR)/*.pot 90 | rm -f $(BUILDDIR)/.copts_* $(BUILDDIR)/*.o $(BUILDDIR)/dnsmasq.a $(BUILDDIR)/dnsmasq 91 | 92 | clean : mostly_clean 93 | rm -f $(BUILDDIR)/dnsmasq_baseline 94 | rm -f core */core 95 | rm -f *~ contrib/*/*~ */*~ 96 | 97 | install : all install-common 98 | 99 | install-common : 100 | $(INSTALL) -d $(DESTDIR)$(BINDIR) -d $(DESTDIR)$(MANDIR)/man8 101 | $(INSTALL) -m 644 $(MAN)/dnsmasq.8 $(DESTDIR)$(MANDIR)/man8 102 | $(INSTALL) -m 755 $(BUILDDIR)/dnsmasq $(DESTDIR)$(BINDIR) 103 | 104 | all-i18n : $(BUILDDIR) 105 | @cd $(BUILDDIR) && $(MAKE) \ 106 | top="$(top)" \ 107 | i18n=-DLOCALEDIR=\'\"$(LOCALEDIR)\"\' \ 108 | build_cflags="$(version) $(dbus_cflags) $(ct_cflags) $(lua_cflags) $(nettle_cflags) `$(PKG_CONFIG) --cflags libidn`" \ 109 | build_libs="$(dbus_libs) $(ct_libs) $(lua_libs) $(sunos_libs) $(nettle_libs) $(gmp_libs) `$(PKG_CONFIG) --libs libidn`" \ 110 | -f $(top)/Makefile dnsmasq 111 | for f in `cd $(PO); echo *.po`; do \ 112 | cd $(top) && cd $(BUILDDIR) && $(MAKE) top="$(top)" -f $(top)/Makefile $${f%.po}.mo; \ 113 | done 114 | 115 | install-i18n : all-i18n install-common 116 | cd $(BUILDDIR); $(top)/bld/install-mo $(DESTDIR)$(LOCALEDIR) $(INSTALL) 117 | cd $(MAN); ../bld/install-man $(DESTDIR)$(MANDIR) $(INSTALL) 118 | 119 | merge : 120 | @cd $(BUILDDIR) && $(MAKE) -f $(top)/Makefile dnsmasq.pot 121 | for f in `cd $(PO); echo *.po`; do \ 122 | echo -n msgmerge $(PO)/$$f && $(MSGMERGE) --no-wrap -U $(PO)/$$f $(BUILDDIR)/dnsmasq.pot; \ 123 | done 124 | 125 | # Cannonicalise .po file. 126 | %.po : 127 | @cd $(BUILDDIR) && $(MAKE) -f $(top)/Makefile dnsmasq.pot 128 | mv $(PO)/$*.po $(PO)/$*.po.orig && $(MSGMERGE) --no-wrap $(PO)/$*.po.orig $(BUILDDIR)/dnsmasq.pot >$(PO)/$*.po; 129 | 130 | $(BUILDDIR): 131 | mkdir -p $(BUILDDIR) 132 | 133 | # rules below are helpers for size tracking 134 | 135 | baseline : mostly_clean all 136 | @cd $(BUILDDIR) && \ 137 | mv dnsmasq dnsmasq_baseline 138 | 139 | bloatcheck : $(BUILDDIR)/dnsmasq_baseline mostly_clean all 140 | @cd $(BUILDDIR) && \ 141 | $(top)/bld/bloat-o-meter dnsmasq_baseline dnsmasq; \ 142 | size dnsmasq_baseline dnsmasq 143 | 144 | # rules below are targets in recusive makes with cwd=$(BUILDDIR) 145 | 146 | $(copts_conf): $(hdrs) 147 | @rm -f *.o .copts_* 148 | @touch $@ 149 | 150 | $(objs:.o=.c) $(hdrs): 151 | ln -s $(top)/$(SRC)/$@ . 152 | 153 | $(objs): $(copts_conf) $(hdrs) 154 | 155 | .c.o: 156 | $(CC) $(CFLAGS) $(COPTS) $(i18n) $(build_cflags) $(RPM_OPT_FLAGS) -c $< 157 | 158 | dnsmasq : $(objs) 159 | $(CC) $(LDFLAGS) -o $@ $(objs) $(build_libs) $(LIBS) 160 | 161 | dnsmasq.pot : $(objs:.o=.c) $(hdrs) 162 | $(XGETTEXT) -d dnsmasq --foreign-user --omit-header --keyword=_ -o $@ -i $(objs:.o=.c) 163 | 164 | %.mo : $(top)/$(PO)/%.po dnsmasq.pot 165 | $(MSGMERGE) -o - $(top)/$(PO)/$*.po dnsmasq.pot | $(MSGFMT) -o $*.mo - 166 | 167 | .PHONY : all clean mostly_clean install install-common all-i18n install-i18n merge baseline bloatcheck 168 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | DNSMASQ fork for improving --ipsets, --server, and --address performance 2 | ======================================================================== 3 | 4 | Dnsmasq matches domain names for --ipsets, --server, and --address options by 5 | iterates over linked list. It is good enough for general use, but slows down as 6 | the domain names to be matched grows. 7 | 8 | Here introduce a modified dnsmasq for fast lookup ipset/server/address options. 9 | The match time is constant regardless the size of rules. 10 | 11 | 12 | root 13 | | 14 | +---------------------+ 15 | com org 16 | | | 17 | +------------------+ +-------------+ 18 | yahoo google twitter debian freebsd 19 | | | | | 20 | www mail +---------+ www 21 | cn jp uk us 22 | | 23 | ftp 24 | 25 | 26 | The lookup steps over domain name hierarchy top-down. All labels are stored in 27 | open addressing hash tables. Sub-level labels that belong to different parent 28 | nodes are stored separately. e.g. yahoo, google, and twitter are in one hash 29 | table, while debian and freebsd are in another. 30 | 31 | The hash table size is power of 2, two hash functions are used to compute hash 32 | bucket. For locating a particular label from hash table, two hash values are 33 | compared first, only if they are match, should the more expensive string 34 | comparison be used to confirm the search. 35 | 36 | 37 | Precompiled OpenWrt packages 38 | ---------------------------- 39 | 40 | For OpenWrt Chaos Calmer 15.05 on ar71xx and mt7620 platform: 41 | 42 | [dnsmasq-full_2.72-5_ar71xx_Chaos_Calmer_15.05.ipk](https://ipfs.io/ipfs/QmYktJLB7f1CmM4sLzZBTBTBSVxu3HD6wjfZE3bqHzBK48/dnsmasq-full_2.72-5_ar71xx_Chaos_Calmer_15.05.ipk) 43 | 44 | [dnsmasq-full_2.72-5_ramips_24kec_Chaos_Calmer_15.05.ipk](https://ipfs.io/ipfs/QmYktJLB7f1CmM4sLzZBTBTBSVxu3HD6wjfZE3bqHzBK48/dnsmasq-full_2.72-5_ramips_24kec_Chaos_Calmer_15.05.ipk) 45 | 46 | For LEDE 17.01 on mt7628NN platform(GL-MT300N-V2): 47 | 48 | [dnsmasq-full_2.73-11_mipsel_24kc_LEDE_17.01.ipk](https://ipfs.io/ipfs/QmYktJLB7f1CmM4sLzZBTBTBSVxu3HD6wjfZE3bqHzBK48/dnsmasq-full_2.73-11_mipsel_24kc_LEDE_17.01.ipk) 49 | 50 | sha1sum 51 | 0a1a7c13714e982b2cf98b33fe16d572f3d1a58d dnsmasq-full_2.72-5_ar71xx_Chaos_Calmer_15.05.ipk 52 | 58b1b3e9447f55ae26dc6a5834cea826ae7a51c1 dnsmasq-full_2.72-5_ramips_24kec_Chaos_Calmer_15.05.ipk 53 | c0788585e4ca68b3b8a9107bbbfd89bcaabc0479 dnsmasq-full_2.73-11_mipsel_24kc_LEDE_17.01.ipk 54 | 55 | 56 | Example usage 57 | ------------- 58 | 59 | Use DNS blackhole to block malware site: 60 | 61 | address=/example.com/ 62 | 63 | Force google DNS as upstream server for special domain: 64 | 65 | server=/example.com/8.8.8.8 66 | 67 | Add all IPs of a paticular domain to IPSET: 68 | 69 | ipset=/example.com/example-ipset 70 | -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | $Format:%d$ 2 | -------------------------------------------------------------------------------- /bld/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := external/dnsmasq/src 2 | 3 | ######################### 4 | 5 | include $(CLEAR_VARS) 6 | LOCAL_SRC_FILES := bpf.c cache.c dbus.c dhcp.c dnsmasq.c \ 7 | forward.c helper.c lease.c log.c \ 8 | netlink.c network.c option.c rfc1035.c \ 9 | rfc2131.c tftp.c util.c conntrack.c \ 10 | dhcp6.c rfc3315.c dhcp-common.c outpacket.c \ 11 | radv.c slaac.c auth.c ipset.c domain.c \ 12 | dnssec.c dnssec-openssl.c blockdata.c tables.c \ 13 | loop.c inotify.c 14 | 15 | LOCAL_MODULE := dnsmasq 16 | 17 | LOCAL_C_INCLUDES := external/dnsmasq/src 18 | 19 | LOCAL_CFLAGS := -O2 -g -W -Wall -D__ANDROID__ -DNO_IPV6 -DNO_TFTP -DNO_SCRIPT 20 | LOCAL_SYSTEM_SHARED_LIBRARIES := libc libcutils 21 | 22 | LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog 23 | 24 | include $(BUILD_EXECUTABLE) 25 | -------------------------------------------------------------------------------- /bld/bloat-o-meter: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2004 Matt Mackall 4 | # 5 | # Inspired by perl Bloat-O-Meter (c) 1997 by Andi Kleen 6 | # 7 | # This software may be used and distributed according to the terms 8 | # of the GNU General Public License, incorporated herein by reference. 9 | 10 | import sys, os#, re 11 | 12 | def usage(): 13 | sys.stderr.write("usage: %s [-t] file1 file2\n" % sys.argv[0]) 14 | sys.exit(-1) 15 | 16 | f1, f2 = (None, None) 17 | flag_timing, dashes = (False, False) 18 | 19 | for f in sys.argv[1:]: 20 | if f.startswith("-"): 21 | if f == "--": # sym_args 22 | dashes = True 23 | break 24 | if f == "-t": # timings 25 | flag_timing = True 26 | else: 27 | if not os.path.exists(f): 28 | sys.stderr.write("Error: file '%s' does not exist\n" % f) 29 | usage() 30 | if f1 is None: 31 | f1 = f 32 | elif f2 is None: 33 | f2 = f 34 | if flag_timing: 35 | import time 36 | if f1 is None or f2 is None: 37 | usage() 38 | 39 | sym_args = " ".join(sys.argv[3 + flag_timing + dashes:]) 40 | def getsizes(file): 41 | sym, alias, lut = {}, {}, {} 42 | for l in os.popen("readelf -W -s %s %s" % (sym_args, file)).readlines(): 43 | l = l.strip() 44 | if not (len(l) and l[0].isdigit() and len(l.split()) == 8): 45 | continue 46 | num, value, size, typ, bind, vis, ndx, name = l.split() 47 | if ndx == "UND": continue # skip undefined 48 | if typ in ["SECTION", "FILES"]: continue # skip sections and files 49 | if "." in name: name = "static." + name.split(".")[0] 50 | value = int(value, 16) 51 | size = int(size, 16) if size.startswith('0x') else int(size) 52 | if vis != "DEFAULT" and bind != "GLOBAL": # see if it is an alias 53 | alias[(value, size)] = {"name" : name} 54 | else: 55 | sym[name] = {"addr" : value, "size": size} 56 | lut[(value, size)] = 0 57 | for addr, sz in iter(alias.keys()): 58 | # If the non-GLOBAL sym has an implementation elsewhere then 59 | # it's an alias, disregard it. 60 | if not (addr, sz) in lut: 61 | # If this non-GLOBAL sym does not have an implementation at 62 | # another address, then treat it as a normal symbol. 63 | sym[alias[(addr, sz)]["name"]] = {"addr" : addr, "size": sz} 64 | for l in os.popen("readelf -W -S " + file).readlines(): 65 | x = l.split() 66 | if len(x)<6: continue 67 | # Should take these into account too! 68 | #if x[1] not in [".text", ".rodata", ".symtab", ".strtab"]: continue 69 | if x[1] not in [".rodata"]: continue 70 | sym[x[1]] = {"addr" : int(x[3], 16), "size" : int(x[5], 16)} 71 | return sym 72 | 73 | if flag_timing: 74 | start_t1 = int(time.time() * 1e9) 75 | old = getsizes(f1) 76 | if flag_timing: 77 | end_t1 = int(time.time() * 1e9) 78 | start_t2 = int(time.time() * 1e9) 79 | new = getsizes(f2) 80 | if flag_timing: 81 | end_t2 = int(time.time() * 1e9) 82 | start_t3 = int(time.time() * 1e9) 83 | grow, shrink, add, remove, up, down = 0, 0, 0, 0, 0, 0 84 | delta, common = [], {} 85 | 86 | for name in iter(old.keys()): 87 | if name in new: 88 | common[name] = 1 89 | 90 | for name in old: 91 | if name not in common: 92 | remove += 1 93 | sz = old[name]["size"] 94 | down += sz 95 | delta.append((-sz, name)) 96 | 97 | for name in new: 98 | if name not in common: 99 | add += 1 100 | sz = new[name]["size"] 101 | up += sz 102 | delta.append((sz, name)) 103 | 104 | for name in common: 105 | d = new[name].get("size", 0) - old[name].get("size", 0) 106 | if d>0: grow, up = grow+1, up+d 107 | elif d<0: shrink, down = shrink+1, down-d 108 | else: 109 | continue 110 | delta.append((d, name)) 111 | 112 | delta.sort() 113 | delta.reverse() 114 | if flag_timing: 115 | end_t3 = int(time.time() * 1e9) 116 | 117 | print("%-48s %7s %7s %+7s" % ("function", "old", "new", "delta")) 118 | for d, n in delta: 119 | if d: 120 | old_sz = old.get(n, {}).get("size", "-") 121 | new_sz = new.get(n, {}).get("size", "-") 122 | print("%-48s %7s %7s %+7d" % (n, old_sz, new_sz, d)) 123 | print("-"*78) 124 | total="(add/remove: %s/%s grow/shrink: %s/%s up/down: %s/%s)%%sTotal: %s bytes"\ 125 | % (add, remove, grow, shrink, up, -down, up-down) 126 | print(total % (" "*(80-len(total)))) 127 | if flag_timing: 128 | print("\n%d/%d; %d Parse origin/new; processing nsecs" % 129 | (end_t1-start_t1, end_t2-start_t2, end_t3-start_t3)) 130 | print("total nsecs: %d" % (end_t3-start_t1)) 131 | -------------------------------------------------------------------------------- /bld/get-version: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Determine the version string to build into a binary. 4 | # When building in the git repository, we can use the output 5 | # of "git describe" which gives an unequivocal answer. 6 | # 7 | # Failing that, we use the contents of the VERSION file 8 | # which has a set of references substituted into it by git. 9 | # If we can find one which matches $v[0-9].* then we assume it's 10 | # a version-number tag, else we just use the whole string. 11 | # If there is more than one v[0-9].* tag, sort them and use the 12 | # first. This favours, eg v2.63 over 2.63rc6. 13 | 14 | if which git >/dev/null 2>&1 && [ -d $1/.git ]; then 15 | cd $1; git describe | sed 's/^v//' 16 | elif grep '\$Format:%d\$' $1/VERSION >/dev/null 2>&1; then 17 | # unsubstituted VERSION, but no git available. 18 | echo UNKNOWN 19 | else 20 | vers=`cat $1/VERSION | sed 's/[(), ]/,/ g' | tr ',' '\n' | grep ^v[0-9]` 21 | 22 | if [ $? -eq 0 ]; then 23 | echo "${vers}" | sort | head -n 1 | sed 's/^v//' 24 | else 25 | cat $1/VERSION 26 | fi 27 | fi 28 | 29 | exit 0 30 | 31 | -------------------------------------------------------------------------------- /bld/install-man: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for f in *; do 4 | if [ -d $f ]; then 5 | $2 -m 755 -d $1/$f/man8 6 | $2 -m 644 $f/dnsmasq.8 $1/$f/man8 7 | echo installing $f/man8/dnsmasq.8 8 | fi 9 | done 10 | -------------------------------------------------------------------------------- /bld/install-mo: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for f in *.mo; do 4 | $2 -m 755 -d $1/${f%.mo}/LC_MESSAGES 5 | $2 -m 644 $f $1/${f%.mo}/LC_MESSAGES/dnsmasq.mo 6 | echo installing ${f%.mo}/LC_MESSAGES/dnsmasq.mo 7 | done 8 | 9 | 10 | -------------------------------------------------------------------------------- /bld/pkg-wrapper: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | search=$1 4 | shift 5 | pkg=$1 6 | shift 7 | op=$1 8 | shift 9 | 10 | in=`cat` 11 | 12 | if grep "^\#[[:space:]]*define[[:space:]]*$search" config.h >/dev/null 2>&1 || \ 13 | echo $in | grep $search >/dev/null 2>&1; then 14 | # Nasty, nasty, in --copy, arg 2 is another config to search for, use with NO_GMP 15 | if [ $op = "--copy" ]; then 16 | if grep "^\#[[:space:]]*define[[:space:]]*$pkg" config.h >/dev/null 2>&1 || \ 17 | echo $in | grep $pkg >/dev/null 2>&1; then 18 | pkg="" 19 | else 20 | pkg="$*" 21 | fi 22 | elif grep "^\#[[:space:]]*define[[:space:]]*${search}_STATIC" config.h >/dev/null 2>&1 || \ 23 | echo $in | grep ${search}_STATIC >/dev/null 2>&1; then 24 | pkg=`$pkg --static $op $*` 25 | else 26 | pkg=`$pkg $op $*` 27 | fi 28 | 29 | if grep "^\#[[:space:]]*define[[:space:]]*${search}_STATIC" config.h >/dev/null 2>&1 || \ 30 | echo $in | grep ${search}_STATIC >/dev/null 2>&1; then 31 | if [ $op = "--libs" ] || [ $op = "--copy" ]; then 32 | echo "-Wl,-Bstatic $pkg -Wl,-Bdynamic" 33 | else 34 | echo "$pkg" 35 | fi 36 | else 37 | echo "$pkg" 38 | fi 39 | fi 40 | 41 | -------------------------------------------------------------------------------- /contrib/CPE-WAN/README: -------------------------------------------------------------------------------- 1 | Dnsmasq from version 2.52 has a couple of rather application-specific 2 | features designed to allow for implementation of the DHCP part of CPE 3 | WAN management protocol. 4 | 5 | http://www.broadband-forum.org/technical/download/TR-069_Amendment-2.pdf 6 | http://en.wikipedia.org/wiki/TR-069 7 | 8 | The relevant sections are F.2.1 "Gateway Requirements" and F.2.5 "DHCP 9 | Vendor Options". 10 | 11 | First, dnsmasq checks for DHCP requests which contain an option-125 12 | vendor-class option which in turn holds a vendor section for IANA 13 | enterprise number 3561 which contains sub-options codes 1 and 2. If 14 | this is present then the network-tag "cpewan-id" is set. 15 | This allows dnsmasq to be configured to reply with the correct 16 | GatewayManufacturerOUI, GatewaySerialNumber and GatewayProductClass like this: 17 | 18 | dhcp-option=cpewan-id,vi-encap:3561,4,"" 19 | dhcp-option=cpewan-id,vi-encap:3561,5,"" 20 | dhcp-option=cpewan-id,vi-encap:3561,6,"" 21 | 22 | Second, the received sub-options 1, 2, and 3 are passed to the DHCP 23 | lease-change script as the environment variables DNSMASQ_CPEWAN_OUI, 24 | DNSMASQ_CPEWAN_SERIAL, and DNSMASQ_CPEWAN_CLASS respectively. This allows 25 | the script to be used to maintain a ManageableDevice table as 26 | specified in F.2.1. Note that this data is not retained in dnsmasq's 27 | internal DHCP lease database, so it is not available on every call to 28 | the script (this is the same as some other data such as vendor and 29 | user classes). It will however be available for at least the "add" 30 | call, and should be stored then against the IP address as primary 31 | key for future use. 32 | 33 | 34 | This feature was added to dnsmasq under sponsorship from Ericsson. 35 | 36 | 37 | -------------------------------------------------------------------------------- /contrib/MacOSX-launchd/launchd-README.txt: -------------------------------------------------------------------------------- 1 | This is a launchd item for Mac OS X and Mac OS X Server. 2 | For more information about launchd, the 3 | "System wide and per-user daemon/agent manager", see the launchd 4 | man page, or the wikipedia page: http://en.wikipedia.org/wiki/Launchd 5 | 6 | This launchd item uses the following flags: 7 | --keep-in-foreground - this is crucial for use with launchd 8 | --log-queries - this is optional and you can remove it 9 | --log-facility=/var/log/dnsmasq.log - again optional instead of system.log 10 | 11 | To use this launchd item for dnsmasq: 12 | 13 | If you don't already have a folder /Library/LaunchDaemons, then create one: 14 | sudo mkdir /Library/LaunchDaemons 15 | sudo chown root:admin /Library/LaunchDaemons 16 | sudo chmod 775 /Library/LaunchDaemons 17 | 18 | Copy uk.org.thekelleys.dnsmasq.plist there and then set ownership/permissions: 19 | sudo cp uk.org.thekelleys.dnsmasq.plist /Library/LaunchDaemons/ 20 | sudo chown root:admin /Library/LaunchDaemons/uk.org.thekelleys.dnsmasq.plist 21 | sudo chmod 644 /Library/LaunchDaemons/uk.org.thekelleys.dnsmasq.plist 22 | 23 | Optionally, edit your dnsmasq configuration file to your liking. 24 | 25 | To start the launchd job, which starts dnsmaq, reboot or use the command: 26 | sudo launchctl load /Library/LaunchDaemons/uk.org.thekelleys.dnsmasq.plist 27 | 28 | To stop the launchd job, which stops dnsmasq, use the command: 29 | sudo launchctl unload /Library/LaunchDaemons/uk.org.thekelleys.dnsmasq.plist 30 | 31 | If you want to permanently stop the launchd job, so it doesn't start the job even after a reboot, use the following command: 32 | sudo launchctl unload -w /Library/LaunchDaemons/uk.org.thekelleys.dnsmasq.plist 33 | 34 | If you make a change to the configuration file, you should relaunch dnsmasq; 35 | to do this unload and then load again: 36 | 37 | sudo launchctl unload /Library/LaunchDaemons/uk.org.thekelleys.dnsmasq.plist 38 | sudo launchctl load /Library/LaunchDaemons/uk.org.thekelleys.dnsmasq.plist 39 | -------------------------------------------------------------------------------- /contrib/MacOSX-launchd/uk.org.thekelleys.dnsmasq.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Label 6 | uk.org.thekelleys.dnsmasq 7 | ProgramArguments 8 | 9 | /usr/local/sbin/dnsmasq 10 | --keep-in-foreground 11 | 12 | RunAtLoad 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /contrib/Solaris10/README: -------------------------------------------------------------------------------- 1 | From: David Connelly 2 | Date: Mon, Apr 7, 2008 at 3:31 AM 3 | Subject: Solaris 10 service manifest 4 | To: dnsmasq-discuss@lists.thekelleys.org.uk 5 | 6 | 7 | I've found dnsmasq much easier to set up on my home server running Solaris 8 | 10 than the stock dhcp/dns server, which is probably overkill anyway for my 9 | simple home network needs. Since Solaris now uses SMF (Service Management 10 | Facility) to manage services I thought I'd create a simple service manifest 11 | for the dnsmasq service. The manifest currently assumes that dnsmasq has 12 | been installed in '/usr/local/sbin/dnsmasq' and the configuration file in 13 | '/usr/local/etc/dnsmasq.conf', so you may have to adjust these paths for 14 | your local installation. Here are the steps I followed to install and enable 15 | the dnsmasq service: 16 | # svccfg import dnsmasq.xml 17 | # svcadm enable dnsmasq 18 | 19 | To confirm that the service is enabled and online: 20 | 21 | # svcs -l dnsmasq 22 | 23 | I've just started learning about SMF so if anyone has any 24 | corrections/feedback they are more than welcome. 25 | 26 | Thanks, 27 | David 28 | 29 | -------------------------------------------------------------------------------- /contrib/Solaris10/README-sparc: -------------------------------------------------------------------------------- 1 | Hi Simon, 2 | 3 | I just wanted to let you know that I have built a Solaris .pkg install package of your dnsmasq utility for people to use. Feel free to point them in my direction if you have people who want this sort of thing. 4 | 5 | http://ejesconsulting.wordpress.com/2010/05/12/gnu-dnsmasq-for-opensolaris-sparc/ 6 | 7 | Thanks 8 | -evan 9 | -------------------------------------------------------------------------------- /contrib/Solaris10/README.create_package: -------------------------------------------------------------------------------- 1 | Ok, script attached ... seems to be working ok for me, 2 | tried to install and remove a few times. It does the 3 | right thing with the smf when installing, you can then 4 | simply enable the service. Upon removal it cleans up the 5 | files but won't clean up the services (I think until 6 | a reboot) ... I've only started looking at the new 7 | packages stuff in the last day or two, so I could be 8 | missing something, but I can't find any way to force 9 | a proper cleanup. 10 | 11 | It requires that you have a writable repository setup 12 | as per the docs on the opensolaris website and it will 13 | create a dnsmasq package (package name is a variable 14 | in the script). The script takes a version number for 15 | the package and assumes that it's in the contrib/Solaris10 16 | directory, it then works out the base tree directory 17 | from $0. 18 | 19 | i.e. $ contrib/Solaris10/create_package 2.52-1 20 | or $ cd contrib/Solaris10; ./create_package 2.52-1 21 | 22 | It's a bit more complex than it could be because I 23 | prefer putting the daemon in /usr/sbin and the config 24 | in /etc, so the script will actually create a new 25 | version of the existing contrib dnsmasq.xml. 26 | -------------------------------------------------------------------------------- /contrib/Solaris10/create_package: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # For our package, and for the SMF script, we need to define where we 5 | # want things to go... 6 | # 7 | BIN_DIR="/usr/sbin" 8 | CONF_DIR="/etc" 9 | MAN_DIR="/usr/share/man/man8" 10 | 11 | PACKAGE_NAME="dnsmasq" 12 | 13 | # 14 | # Since we know we are in the contrib directory we can work out where 15 | # the rest of the tree is... 16 | # 17 | BASEDIR="`dirname $0`/../.." 18 | 19 | # 20 | # We need a version number to use for the package creation... 21 | # 22 | if [ $# != 1 ]; then 23 | echo "Usage: $0 " >&2 24 | exit 1 25 | fi 26 | VERSION="$1" 27 | 28 | # 29 | # First thing we do is fix-up the smf file to use the paths we prefer... 30 | # 31 | if [ ! -f "${BASEDIR}/contrib/Solaris10/dnsmasq.xml" ]; then 32 | echo "$0: unable to find contrib/Solaris10/dnsmasq.xml" >&2 33 | exit 1 34 | fi 35 | 36 | echo "Fixing up smf file ... \c" 37 | cat "${BASEDIR}/contrib/Solaris10/dnsmasq.xml" | \ 38 | sed -e "s%/usr/local/etc%${CONF_DIR}%" \ 39 | -e "s%/usr/local/sbin%${BIN_DIR}%" \ 40 | -e "s%/usr/local/man%${MAN_DIR}%" > ${BASEDIR}/contrib/Solaris10/dnsmasq-pkg.xml 41 | echo "done." 42 | 43 | echo "Creating packaging file ... \c" 44 | cat <${BASEDIR}/contrib/Solaris10/dnsmasq_package.inc 45 | # 46 | # header 47 | # 48 | set name=pkg.name value="dnsmasq" 49 | set name=pkg.description value="dnsmasq daemon - dns, dhcp, tftp etc" 50 | set name=pkg.detailed_url value="http://www.thekelleys.org.uk/dnsmasq/doc.html" 51 | set name=info.maintainer value="TBD (tbd@tbd.com)" 52 | set name=info.upstream value="dnsmasq-discuss@lists.thekelleys.org.uk" 53 | set name=info.upstream_url value="http://www.thekelleys.org.uk/dnsmasq/doc.html" 54 | # 55 | # dependencies ... none? 56 | # 57 | 58 | # 59 | # directories 60 | # 61 | dir mode=0755 owner=root group=bin path=${BIN_DIR}/ 62 | dir mode=0755 owner=root group=sys path=${CONF_DIR}/ 63 | dir mode=0755 owner=root group=sys path=${MAN_DIR}/ 64 | dir mode=0755 owner=root group=sys path=/var/ 65 | dir mode=0755 owner=root group=sys path=/var/svc 66 | dir mode=0755 owner=root group=sys path=/var/svc/manifest 67 | dir mode=0755 owner=root group=sys path=/var/svc/manifest/network 68 | 69 | # 70 | # files 71 | # 72 | file ${BASEDIR}/src/dnsmasq mode=0555 owner=root group=bin path=${BIN_DIR}/dnsmasq 73 | file ${BASEDIR}/man/dnsmasq.8 mode=0555 owner=root group=bin path=${MAN_DIR}/dnsmasq.8 74 | file ${BASEDIR}/dnsmasq.conf.example mode=0644 owner=root group=sys path=${CONF_DIR}/dnsmasq.conf preserve=strawberry 75 | file ${BASEDIR}/contrib/Solaris10/dnsmasq-pkg.xml mode=0644 owner=root group=sys path=/var/svc/manifest/network/dnsmasq.xml restart_fmri=svc:/system/manifest-import:default 76 | 77 | EOF 78 | echo "done." 79 | 80 | echo "Creating package..." 81 | eval `pkgsend open ${PACKAGE_NAME}@${VERSION}` 82 | pkgsend include ${BASEDIR}/contrib/Solaris10/dnsmasq_package.inc 83 | if [ "$?" = 0 ]; then 84 | pkgsend close 85 | else 86 | echo "Errors" 87 | fi 88 | -------------------------------------------------------------------------------- /contrib/Solaris10/dnsmasq.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 19 | 23 | 24 | 25 | 26 | 29 | 30 | 31 | 32 | 35 | 36 | 37 | 38 | 39 | 40 | 44 | 45 | 49 | 50 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /contrib/Suse/README: -------------------------------------------------------------------------------- 1 | This packaging is now unmaintained in the dnsmasq source: dnsmasq is 2 | included in Suse proper, and up-to-date packages are now available 3 | from 4 | 5 | ftp://ftp.suse.com/pub/people/ug/ 6 | 7 | -------------------------------------------------------------------------------- /contrib/Suse/README.susefirewall: -------------------------------------------------------------------------------- 1 | This is a patch against SuSEfirewall2-3.1-206 (SuSE 9.x and older) 2 | It fixes the depancy from the dns daemon name 'named' 3 | After appending the patch, the SuSEfirewall is again able to autodetect 4 | the dnsmasq named service. 5 | This is a very old bug in the SuSEfirewall script. 6 | The SuSE people think the name of the dns server will allways 'named' 7 | 8 | 9 | --- /sbin/SuSEfirewall2.orig 2004-01-23 13:30:09.000000000 +0100 10 | +++ /sbin/SuSEfirewall2 2004-01-23 13:31:56.000000000 +0100 11 | @@ -764,7 +764,7 @@ 12 | echo 'FW_ALLOW_INCOMING_HIGHPORTS_UDP should be set to yes, if you are running a DNS server!' 13 | 14 | test "$FW_SERVICE_AUTODETECT" = yes -o "$FW_SERVICE_AUTODETECT" = dmz -o "$FW_SERVICE_AUTODETECT" = ext && { 15 | - test "$FW_SERVICE_DNS" = no -a '!' "$START_NAMED" = no && check_srv named && { 16 | + test "$FW_SERVICE_DNS" = no -a '!' "$START_NAMED" = no && check_srv dnsmasq && { 17 | echo -e 'Warning: detected activated named, enabling FW_SERVICE_DNS! 18 | You still have to allow tcp/udp port 53 on internal, dmz and/or external.' 19 | FW_SERVICE_DNS=$FW_SERVICE_AUTODETECT 20 | @@ -878,7 +878,7 @@ 21 | test -e /etc/resolv.conf || echo "Warning: /etc/resolv.conf not found" 22 | # Get ports/IP bindings of NAMED/SQUID 23 | test "$FW_SERVICE_DNS" = yes -o "$FW_SERVICE_DNS" = dmz -o "$FW_SERVICE_DNS" = ext -o "$START_NAMED" = yes && DNS_PORT=`$LSOF -i -n -P | \ 24 | - $AWK -F: '/^named .* UDP / {print $2}'| $GREP -vw 53 | $SORT -un` 25 | + $AWK -F: '/^dnsmasq .* UDP / {print $2}'| $GREP -vw 53 | $SORT -un` 26 | test "$FW_SERVICE_SQUID" = yes -o "$FW_SERVICE_SQUID" = dmz -o "$FW_SERVICE_SQUID" = ext -o "$START_SQUID" = yes && SQUID_PORT=`$LSOF -i -n -P | \ 27 | $AWK -F: '/^squid .* UDP/ {print $2}'| $SORT -un` 28 | -------------------------------------------------------------------------------- /contrib/Suse/dnsmasq-SuSE.patch: -------------------------------------------------------------------------------- 1 | --- man/dnsmasq.8 2004-08-08 20:57:56.000000000 +0200 2 | +++ man/dnsmasq.8 2004-08-12 00:40:01.000000000 +0200 3 | @@ -69,7 +69,7 @@ 4 | .TP 5 | .B \-g, --group= 6 | Specify the group which dnsmasq will run 7 | -as. The defaults to "dip", if available, to facilitate access to 8 | +as. The defaults to "dialout", if available, to facilitate access to 9 | /etc/ppp/resolv.conf which is not normally world readable. 10 | .TP 11 | .B \-v, --version 12 | --- src/config.h 2004-08-11 11:39:18.000000000 +0200 13 | +++ src/config.h 2004-08-12 00:40:01.000000000 +0200 14 | @@ -44,7 +44,7 @@ 15 | #endif 16 | #define DEFLEASE 3600 /* default lease time, 1 hour */ 17 | #define CHUSER "nobody" 18 | -#define CHGRP "dip" 19 | +#define CHGRP "dialout" 20 | #define DHCP_SERVER_PORT 67 21 | #define DHCP_CLIENT_PORT 68 22 | 23 | 24 | -------------------------------------------------------------------------------- /contrib/Suse/dnsmasq-suse.spec: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # 3 | # General 4 | # 5 | ############################################################################### 6 | 7 | Name: dnsmasq 8 | Version: 2.33 9 | Release: 1 10 | Copyright: GPL 11 | Group: Productivity/Networking/DNS/Servers 12 | Vendor: Simon Kelley 13 | Packager: Simon Kelley 14 | URL: http://www.thekelleys.org.uk/dnsmasq 15 | Provides: dns_daemon 16 | Conflicts: bind bind8 bind9 17 | PreReq: %fillup_prereq %insserv_prereq 18 | Autoreqprov: on 19 | Source0: %{name}-%{version}.tar.bz2 20 | BuildRoot: /var/tmp/%{name}-%{version} 21 | Summary: A lightweight caching nameserver 22 | 23 | %description 24 | Dnsmasq is lightweight, easy to configure DNS forwarder and DHCP server. It 25 | is designed to provide DNS and, optionally, DHCP, to a small network. It can 26 | serve the names of local machines which are not in the global DNS. The DHCP 27 | server integrates with the DNS server and allows machines with DHCP-allocated 28 | addresses to appear in the DNS with names configured either in each host or 29 | in a central configuration file. Dnsmasq supports static and dynamic DHCP 30 | leases and BOOTP for network booting of diskless machines. 31 | 32 | 33 | 34 | ############################################################################### 35 | # 36 | # Build 37 | # 38 | ############################################################################### 39 | 40 | %prep 41 | %setup -q 42 | patch -p0 2 | 3 | DHCP Clients 4 | 5 | 6 | 7 | 8 |

DHCP Clients (updated [% updated %])

9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | [% FOREACH host IN hosts %] 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | [% END %] 30 |
HostnameIP AddressEthernet AddressDHCP Client IDStatusSinceLease Expires
[% host.hostname %][% host.ip_addr %][% host.ether_addr %][% host.text_client_id %] ([% host.raw_client_id %])[% IF host.online %]Online[% ELSE %]Offline[% END %][% host.since %][% host.text_lease %]
31 | 32 | 33 | -------------------------------------------------------------------------------- /contrib/dnsmasq_MacOSX-pre10.4/DNSmasq: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . /etc/rc.common 3 | 4 | StartService() { 5 | if [ "${DNSMASQ:=-NO-}" = "-YES-" ] ; then 6 | /usr/local/sbin/dnsmasq -q -n 7 | fi 8 | } 9 | 10 | StopService() { 11 | pid=`GetPID dnsmasq` 12 | if [ $? -eq 0 ]; then 13 | kill $pid 14 | fi 15 | } 16 | 17 | RestartService() { 18 | StopService "$@" 19 | StartService "$@" 20 | } 21 | 22 | RunService "$1" 23 | -------------------------------------------------------------------------------- /contrib/dnsmasq_MacOSX-pre10.4/README.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf100 2 | {\fonttbl\f0\fswiss\fcharset77 Helvetica;\f1\fnil\fcharset77 Monaco;} 3 | {\colortbl;\red255\green255\blue255;} 4 | \paperw11900\paperh16840\margl1440\margr1440\vieww11120\viewh10100\viewkind0 5 | \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural 6 | 7 | \f0\fs24 \cf0 1. If you've used DNSenabler, or if you're using Mac OS X Server, or if you have in any other way activated Mac OS X's built-in DHCP and/or DNS servers, disable them. This would usually involve checking that they are either set to -NO- or absent altogether in 8 | \f1 /etc/hostconfig 9 | \f0 . If you've never done anything to do with DNS or DHCP servers on a client version of MacOS X, you won't need to worry about this; it will already be configured for you.\ 10 | \ 11 | 2. Add a configuration item to 12 | \f1 /etc/hostconfig 13 | \f0 as follows:\ 14 | \ 15 | 16 | \f1 DNSMASQ=-YES- 17 | \f0 \ 18 | \ 19 | 3. Create a system-wide StartupItems directory for dnsmasq:\ 20 | \ 21 | 22 | \f1 sudo mkdir -p /Library/StartupItems/DNSmasq\ 23 | 24 | \f0 \ 25 | 4. Copy the files 26 | \f1 DNSmasq 27 | \f0 and 28 | \f1 StartupParameters.plist 29 | \f0 into this directory, and make sure the former is executable:\ 30 | \ 31 | 32 | \f1 sudo cp DNSmasq StartupParameters.plist /Library/StartupItems/DNSmasq\ 33 | sudo chmod 755 /Library/StartupItems/DNSmasq/DNSmasq\ 34 | 35 | \f0 \ 36 | 5. Start the service:\ 37 | \ 38 | 39 | \f1 sudo /Library/StartupItems/DNSmasq/DNSmasq start\ 40 | 41 | \f0 \cf0 \ 42 | That should be all...} -------------------------------------------------------------------------------- /contrib/dnsmasq_MacOSX-pre10.4/StartupParameters.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Description 6 | DNSmasq 7 | OrderPreference 8 | None 9 | Provides 10 | 11 | DNSmasq 12 | 13 | Uses 14 | 15 | Network 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /contrib/dynamic-dnsmasq/dynamic-dnsmasq.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # dynamic-dnsmasq.pl - update dnsmasq's internal dns entries dynamically 3 | # Copyright (C) 2004 Peter Willis 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | # 19 | # the purpose of this script is to be able to update dnsmasq's dns 20 | # records from a remote dynamic dns client. 21 | # 22 | # basic use of this script: 23 | # dynamic-dnsmasq.pl add testaccount 1234 testaccount.mydomain.com 24 | # dynamic-dnsmasq.pl listen & 25 | # 26 | # this script tries to emulate DynDNS.org's dynamic dns service, so 27 | # technically you should be able to use any DynDNS.org client to 28 | # update the records here. tested and confirmed to work with ddnsu 29 | # 1.3.1. just point the client's host to the IP of this machine, 30 | # port 9020, and include the hostname, user and pass, and it should 31 | # work. 32 | # 33 | # make sure "addn-hosts=/etc/dyndns-hosts" is in your /etc/dnsmasq.conf 34 | # file and "nopoll" is commented out. 35 | 36 | use strict; 37 | use IO::Socket; 38 | use MIME::Base64; 39 | use DB_File; 40 | use Fcntl; 41 | 42 | my $accountdb = "accounts.db"; 43 | my $recordfile = "/etc/dyndns-hosts"; 44 | my $dnsmasqpidfile = "/var/run/dnsmasq.pid"; # if this doesn't exist, will look for process in /proc 45 | my $listenaddress = "0.0.0.0"; 46 | my $listenport = 9020; 47 | 48 | # no editing past this point should be necessary 49 | 50 | if ( @ARGV < 1 ) { 51 | die "Usage: $0 ADD|DEL|LISTUSERS|WRITEHOSTSFILE|LISTEN\n"; 52 | } elsif ( lc $ARGV[0] eq "add" ) { 53 | die "Usage: $0 ADD USER PASS HOSTNAME\n" unless @ARGV == 4; 54 | add_acct($ARGV[1], $ARGV[2], $ARGV[3]); 55 | } elsif ( lc $ARGV[0] eq "del" ) { 56 | die "Usage: $0 DEL USER\n" unless @ARGV == 2; 57 | print "Are you sure you want to delete user \"$ARGV[1]\"? [N/y] "; 58 | my $resp = ; 59 | chomp $resp; 60 | if ( lc substr($resp,0,1) eq "y" ) { 61 | del_acct($ARGV[1]); 62 | } 63 | } elsif ( lc $ARGV[0] eq "listusers" or lc $ARGV[0] eq "writehostsfile" ) { 64 | my $X = tie my %h, "DB_File", $accountdb, O_RDWR|O_CREAT, 0600, $DB_HASH; 65 | my $fh; 66 | if ( lc $ARGV[0] eq "writehostsfile" ) { 67 | open($fh, ">$recordfile") || die "Couldn't open recordfile \"$recordfile\": $!\n"; 68 | flock($fh, 2); 69 | seek($fh, 0, 0); 70 | truncate($fh, 0); 71 | } 72 | while ( my ($key, $val) = each %h ) { 73 | my ($pass, $domain, $ip) = split("\t",$val); 74 | if ( lc $ARGV[0] eq "listusers" ) { 75 | print "user $key, hostname $domain, ip $ip\n"; 76 | } else { 77 | if ( defined $ip ) { 78 | print $fh "$ip\t$domain\n"; 79 | } 80 | } 81 | } 82 | if ( lc $ARGV[0] eq "writehostsfile" ) { 83 | flock($fh, 8); 84 | close($fh); 85 | dnsmasq_rescan_configs(); 86 | } 87 | undef $X; 88 | untie %h; 89 | } elsif ( lc $ARGV[0] eq "listen" ) { 90 | listen_for_updates(); 91 | } 92 | 93 | sub listen_for_updates { 94 | my $sock = IO::Socket::INET->new(Listen => 5, 95 | LocalAddr => $listenaddress, LocalPort => $listenport, 96 | Proto => 'tcp', ReuseAddr => 1, 97 | MultiHomed => 1) || die "Could not open listening socket: $!\n"; 98 | $SIG{'CHLD'} = 'IGNORE'; 99 | while ( my $client = $sock->accept() ) { 100 | my $p = fork(); 101 | if ( $p != 0 ) { 102 | next; 103 | } 104 | $SIG{'CHLD'} = 'DEFAULT'; 105 | my @headers; 106 | my %cgi; 107 | while ( <$client> ) { 108 | s/(\r|\n)//g; 109 | last if $_ eq ""; 110 | push @headers, $_; 111 | } 112 | foreach my $header (@headers) { 113 | if ( $header =~ /^GET \/nic\/update\?([^\s].+) HTTP\/1\.[01]$/ ) { 114 | foreach my $element (split('&', $1)) { 115 | $cgi{(split '=', $element)[0]} = (split '=', $element)[1]; 116 | } 117 | } elsif ( $header =~ /^Authorization: basic (.+)$/ ) { 118 | unless ( defined $cgi{'hostname'} ) { 119 | print_http_response($client, undef, "badsys"); 120 | exit(1); 121 | } 122 | if ( !exists $cgi{'myip'} ) { 123 | $cgi{'myip'} = $client->peerhost(); 124 | } 125 | my ($user,$pass) = split ":", MIME::Base64::decode($1); 126 | if ( authorize($user, $pass, $cgi{'hostname'}, $cgi{'myip'}) == 0 ) { 127 | print_http_response($client, $cgi{'myip'}, "good"); 128 | update_dns(\%cgi); 129 | } else { 130 | print_http_response($client, undef, "badauth"); 131 | exit(1); 132 | } 133 | last; 134 | } 135 | } 136 | exit(0); 137 | } 138 | return(0); 139 | } 140 | 141 | sub add_acct { 142 | my ($user, $pass, $hostname) = @_; 143 | my $X = tie my %h, "DB_File", $accountdb, O_RDWR|O_CREAT, 0600, $DB_HASH; 144 | $X->put($user, join("\t", ($pass, $hostname))); 145 | undef $X; 146 | untie %h; 147 | } 148 | 149 | sub del_acct { 150 | my ($user, $pass, $hostname) = @_; 151 | my $X = tie my %h, "DB_File", $accountdb, O_RDWR|O_CREAT, 0600, $DB_HASH; 152 | $X->del($user); 153 | undef $X; 154 | untie %h; 155 | } 156 | 157 | 158 | sub authorize { 159 | my $user = shift; 160 | my $pass = shift; 161 | my $hostname = shift; 162 | my $ip = shift;; 163 | my $X = tie my %h, "DB_File", $accountdb, O_RDWR|O_CREAT, 0600, $DB_HASH; 164 | my ($spass, $shost) = split("\t", $h{$user}); 165 | if ( defined $h{$user} and ($spass eq $pass) and ($shost eq $hostname) ) { 166 | $X->put($user, join("\t", $spass, $shost, $ip)); 167 | undef $X; 168 | untie %h; 169 | return(0); 170 | } 171 | undef $X; 172 | untie %h; 173 | return(1); 174 | } 175 | 176 | sub print_http_response { 177 | my $sock = shift; 178 | my $ip = shift; 179 | my $response = shift; 180 | print $sock "HTTP/1.0 200 OK\n"; 181 | my @tmp = split /\s+/, scalar gmtime(); 182 | print $sock "Date: $tmp[0], $tmp[2] $tmp[1] $tmp[4] $tmp[3] GMT\n"; 183 | print $sock "Server: Peter's Fake DynDNS.org Server/1.0\n"; 184 | print $sock "Content-Type: text/plain; charset=ISO-8859-1\n"; 185 | print $sock "Connection: close\n"; 186 | print $sock "Transfer-Encoding: chunked\n"; 187 | print $sock "\n"; 188 | #print $sock "12\n"; # this was part of the dyndns response but i'm not sure what it is 189 | print $sock "$response", defined($ip)? " $ip" : "" . "\n"; 190 | } 191 | 192 | sub update_dns { 193 | my $hashref = shift; 194 | my @records; 195 | my $found = 0; 196 | # update the addn-hosts file 197 | open(FILE, "+<$recordfile") || die "Couldn't open recordfile \"$recordfile\": $!\n"; 198 | flock(FILE, 2); 199 | while ( ) { 200 | if ( /^(\d+\.\d+\.\d+\.\d+)\s+$$hashref{'hostname'}\n$/si ) { 201 | if ( $1 ne $$hashref{'myip'} ) { 202 | push @records, "$$hashref{'myip'}\t$$hashref{'hostname'}\n"; 203 | $found = 1; 204 | } 205 | } else { 206 | push @records, $_; 207 | } 208 | } 209 | unless ( $found ) { 210 | push @records, "$$hashref{'myip'}\t$$hashref{'hostname'}\n"; 211 | } 212 | sysseek(FILE, 0, 0); 213 | truncate(FILE, 0); 214 | syswrite(FILE, join("", @records)); 215 | flock(FILE, 8); 216 | close(FILE); 217 | dnsmasq_rescan_configs(); 218 | return(0); 219 | } 220 | 221 | sub dnsmasq_rescan_configs { 222 | # send the HUP signal to dnsmasq 223 | if ( -r $dnsmasqpidfile ) { 224 | open(PID,"<$dnsmasqpidfile") || die "Could not open PID file \"$dnsmasqpidfile\": $!\n"; 225 | my $pid = ; 226 | close(PID); 227 | chomp $pid; 228 | if ( kill(0, $pid) ) { 229 | kill(1, $pid); 230 | } else { 231 | goto LOOKFORDNSMASQ; 232 | } 233 | } else { 234 | LOOKFORDNSMASQ: 235 | opendir(DIR,"/proc") || die "Couldn't opendir /proc: $!\n"; 236 | my @dirs = grep(/^\d+$/, readdir(DIR)); 237 | closedir(DIR); 238 | foreach my $process (@dirs) { 239 | if ( open(FILE,"; 241 | close(FILE); 242 | if ( (split(/\0/,$cmdline))[0] =~ /dnsmasq/ ) { 243 | kill(1, $process); 244 | } 245 | } 246 | } 247 | } 248 | return(0); 249 | } 250 | -------------------------------------------------------------------------------- /contrib/lease-access/README: -------------------------------------------------------------------------------- 1 | Hello, 2 | 3 | For some specific application I needed to deny access to a MAC address 4 | to a lease. For this reason I modified the dhcp-script behavior and is 5 | called with an extra parameter "access" once a dhcp request or discover 6 | is received. In that case if the exit code of the script is zero, 7 | dnsmasq continues normally, and if non-zero the packet is ignored. 8 | 9 | This was not added as a security feature but as a mean to handle 10 | differently some addresses. It is also quite intrusive since it requires 11 | changes in several other subsystems. 12 | 13 | It attach the patch in case someone is interested. 14 | 15 | regards, 16 | Nikos 17 | 18 | nmav@gennetsa.com 19 | 20 | 21 | -------------------------------------------------------------------------------- /contrib/mactable/macscript: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | STATUS_FILE="/tmp/dnsmasq-ip-mac.status" 4 | 5 | # Script for dnsmasq lease-change hook. 6 | # Maintains the above file with a IP address/MAC address pairs, 7 | # one lease per line. Works with IPv4 and IPv6 leases, file is 8 | # atomically updated, so no races for users of the data. 9 | 10 | action="$1" 11 | mac="$2" # IPv4 12 | ip="$3" 13 | 14 | # ensure it always exists. 15 | 16 | if [ ! -f "$STATUS_FILE" ]; then 17 | touch "$STATUS_FILE" 18 | fi 19 | 20 | if [ -n "$DNSMASQ_IAID" ]; then 21 | mac="$DNSMASQ_MAC" # IPv6 22 | fi 23 | 24 | # worry about an add or old action when the MAC address is not known: 25 | # leave any old one in place in that case. 26 | 27 | if [ "$action" = "add" -o "$action" = "old" -o "$action" = "del" ]; then 28 | if [ -n "$mac" -o "$action" = "del" ]; then 29 | sed "/^${ip//./\.} / d" "$STATUS_FILE" > "$STATUS_FILE".new 30 | 31 | if [ "$action" = "add" -o "$action" = "old" ]; then 32 | echo "$ip $mac" >> "$STATUS_FILE".new 33 | fi 34 | mv "$STATUS_FILE".new "$STATUS_FILE" # atomic update. 35 | fi 36 | fi 37 | -------------------------------------------------------------------------------- /contrib/openvpn/README: -------------------------------------------------------------------------------- 1 | The patch I have attached lets me get the behavior I wish out of 2 | dnsmasq. I also include my version of dhclient-enter-hooks as 3 | required for the switchover from pre-dnsmasq and dhclient. 4 | 5 | On 8/16/05, Joseph Tate wrote: 6 | > I'm trying to use dnsmasq on a laptop in order to facilitate openvpn 7 | > connections. As such, the only configuration option I'm concerned 8 | > about is a single server=3D/example.com/192.168.0.1 line. 9 | > 10 | > The way I currently have it set up is I modified dhclient to write its 11 | > resolv.conf data to /etc/resolv.conf.dhclient and configured 12 | > /etc/dnsmasq.conf to look there for its upstream dns servers. 13 | > /etc/resolv.conf is set to nameserver 127.0.0.1 14 | > 15 | > All of this works great. When I start the openvpn service, it the 16 | > routes, and queries to the domain in the server=3D line work just fine. 17 | > 18 | > The only problem is that the hostname for my system doesn't get set 19 | > correctly. With the resolv.conf data written to something other than 20 | > /etc/resolv.conf, the ifup scripts don't have a valid dns server to do 21 | > the ipcalc call to set the laptop's hostname. If I start dnsmasq 22 | > before the network comes up, something gets fubar'd. I'm not sure how 23 | > to describe it exactly, but network services are slow to load, and 24 | > restarting networking and dnsmasq doesn't solve the problem. Perhaps 25 | > dnsmasq is answering the dhcp request when the network starts? 26 | > Certainly not desired behavior. 27 | > 28 | > Anyway, my question: is there a way to have the best of both worlds? 29 | > DHCP requests to another server, and DNS lookups that work at all 30 | > times? 31 | > 32 | > My current best idea on how to solve this problem is modifying the 33 | > dnsmasq initscript to tweak /etc/dhclient-enter-hooks to change where 34 | > dhclient writes resolv.conf data, and fixing up /etc/resolv.conf on 35 | > the fly to set 127.0.0.1 to the nameserver (and somehow keep the 36 | > search domains intact), but I'm hoping that I'm just missing some key 37 | > piece of the puzzle and that this problem has been solved before. Any 38 | > insights? 39 | > 40 | > -- 41 | > Joseph Tate 42 | > Personal e-mail: jtate AT dragonstrider DOT com 43 | > Web: http://www.dragonstrider.com 44 | > 45 | -------------------------------------------------------------------------------- /contrib/openvpn/dhclient-enter-hooks: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function save_previous() { 4 | if [ -e $1 -a ! -e $1.predhclient ]; then 5 | mv $1 $1.predhclient 6 | fi 7 | } 8 | 9 | function write_resolv_conf() { 10 | RESOLVCONF=$1 11 | if [ -n "$new_domain_name" ] || [ -n "$new_domain_name_servers" ]; then 12 | save_previous $RESOLVCONF 13 | echo '; generated by /etc/dhclient-enter-hooks' > $RESOLVCONF 14 | if [ -n "$SEARCH" ]; then 15 | echo search $SEARCH >> $RESOLVCONF 16 | else 17 | if [ -n "$new_domain_name" ]; then 18 | echo search $new_domain_name >> $RESOLVCONF 19 | fi 20 | fi 21 | chmod 644 $RESOLVCONF 22 | for nameserver in $new_domain_name_servers; do 23 | echo nameserver $nameserver >>$RESOLVCONF 24 | done 25 | fi 26 | } 27 | 28 | make_resolv_conf() { 29 | write_resolv_conf /etc/resolv.conf 30 | } 31 | -------------------------------------------------------------------------------- /contrib/openvpn/dnsmasq.patch: -------------------------------------------------------------------------------- 1 | --- dnsmasq-2.22/rpm/dnsmasq.rh 2005-03-24 09:51:18.000000000 -0500 2 | +++ dnsmasq-2.22/rpm/dnsmasq.rh.new 2005-08-25 10:52:04.310568784 -0400 3 | @@ -2,7 +2,7 @@ 4 | # 5 | # Startup script for the DNS caching server 6 | # 7 | -# chkconfig: 2345 99 01 8 | +# chkconfig: 2345 07 89 9 | # description: This script starts your DNS caching server 10 | # processname: dnsmasq 11 | # pidfile: /var/run/dnsmasq.pid 12 | @@ -10,6 +10,25 @@ 13 | # Source function library. 14 | . /etc/rc.d/init.d/functions 15 | 16 | +function setup_dhclient_enter_hooks() { 17 | + if [ -f /etc/dhclient-enter-hooks ]; then 18 | + . /etc/dhclient-enter-hooks 19 | + cp /etc/resolv.conf /etc/resolv.conf.dnsmasq 20 | + cp /etc/dhclient-enter-hooks /etc/dhclient-enter-hooks.dnsmasq 21 | + sed -e 's/resolv\.conf$/resolv.conf.dnsmasq/' /etc/dhclient-enter-hooks.dnsmasq > /etc/dhclient-enter-hooks 22 | + sed -e 's/\(nameserver[ tab]\+\)[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+$/\1127.0.0.1/' /etc/resolv.conf.dnsmasq > /etc/resolv.conf 23 | + fi 24 | +} 25 | + 26 | +function teardown_dhclient_enter_hooks() { 27 | + if [ -f /etc/dhclient-enter-hooks -a -f /etc/dhclient-enter-hooks.dnsmasq ]; then 28 | + if [ -f /etc/resolv.conf.dnsmasq ]; then 29 | + mv /etc/resolv.conf.dnsmasq /etc/resolv.conf 30 | + fi 31 | + mv /etc/dhclient-enter-hooks.dnsmasq /etc/dhclient-enter-hooks 32 | + fi 33 | +} 34 | + 35 | # Source networking configuration. 36 | . /etc/sysconfig/network 37 | 38 | @@ -24,7 +43,7 @@ 39 | MAILHOSTNAME="" 40 | # change this line if you want dns to get its upstream servers from 41 | # somewhere other that /etc/resolv.conf 42 | -RESOLV_CONF="" 43 | +RESOLV_CONF="/etc/resolv.conf.dnsmasq" 44 | # change this if you want dnsmasq to cache any "hostname" or "client-hostname" from 45 | # a dhcpd's lease file 46 | @@ -54,6 +73,7 @@ 47 | case "$1" in 48 | start) 49 | echo -n "Starting dnsmasq: " 50 | + setup_dhclient_enter_hooks 51 | daemon $dnsmasq $OPTIONS 52 | RETVAL=$? 53 | echo 54 | @@ -62,6 +82,7 @@ 55 | stop) 56 | if test "x`pidof dnsmasq`" != x; then 57 | echo -n "Shutting down dnsmasq: " 58 | + teardown_dhclient_enter_hooks 59 | killproc dnsmasq 60 | fi 61 | RETVAL=$? 62 | -------------------------------------------------------------------------------- /contrib/port-forward/dnsmasq-portforward: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # /usr/sbin/dnsmasq-portforward 4 | # 5 | # A script which gets run when the dnsmasq DHCP lease database changes. 6 | # It logs to $LOGFILE, if it exists, and maintains port-forwards using 7 | # IP-tables so that they always point to the correct host. See 8 | # $PORTSFILE for details on configuring this. dnsmasq must be version 2.34 9 | # or later. 10 | # 11 | # To enable this script, add 12 | # dhcp-script=/usr/sbin/dnsmasq-portforward 13 | # to /etc/dnsmasq.conf 14 | # 15 | # To enable logging, touch $LOGFILE 16 | # 17 | 18 | PORTSFILE=/etc/portforward 19 | LOGFILE=/var/log/dhcp.log 20 | IPTABLES=/sbin/iptables 21 | 22 | action=${1:-0} 23 | hostname=${4} 24 | 25 | # log what's going on. 26 | if [ -f ${LOGFILE} ] ; then 27 | date +"%D %T $*" >>${LOGFILE} 28 | fi 29 | 30 | # If a lease gets stripped of a name, we see that as an "old" action 31 | # with DNSMASQ_OLD_HOSTNAME set, convert it into a "del" 32 | if [ ${DNSMASQ_OLD_HOSTNAME} ] && [ ${action} = old ] ; then 33 | action=del 34 | hostname=${DNSMASQ_OLD_HOSTNAME} 35 | fi 36 | 37 | # IPv6 leases are not our concern. no NAT there! 38 | if [ ${DNSMASQ_IAID} ] ; then 39 | exit 0 40 | fi 41 | 42 | # action init is not relevant, and will only be seen when leasefile-ro is set. 43 | if [ ${action} = init ] ; then 44 | exit 0 45 | fi 46 | 47 | # action tftp is not relevant. 48 | if [ ${action} = tftp ] ; then 49 | exit 0 50 | fi 51 | 52 | if [ ${hostname} ]; then 53 | ports=$(sed -n -e "/^${hostname}\ .*/ s/^.* //p" ${PORTSFILE}) 54 | 55 | for port in $ports; do 56 | verb=removed 57 | protocol=tcp 58 | if [ ${port:0:1} = u ] ; then 59 | protocol=udp 60 | port=${port/u/} 61 | fi 62 | src=${port/:*/} 63 | dst=${port/*:/} 64 | # delete first, to avoid multiple copies of rules. 65 | ${IPTABLES} -t nat -D PREROUTING -p $protocol --destination-port $src -j DNAT --to-destination ${3}:$dst 66 | if [ ${action} != del ] ; then 67 | ${IPTABLES} -t nat -A PREROUTING -p $protocol --destination-port $src -j DNAT --to-destination ${3}:$dst 68 | verb=added 69 | fi 70 | if [ -f ${LOGFILE} ] ; then 71 | echo " DNAT $protocol $src to ${3}:$dst ${verb}." >>${LOGFILE} 72 | fi 73 | done 74 | fi 75 | 76 | exit 0 77 | 78 | 79 | -------------------------------------------------------------------------------- /contrib/port-forward/portforward: -------------------------------------------------------------------------------- 1 | # This file is read by /usr/sbin/dnsmasq-portforward and used to set up port 2 | # forwarding to hostnames. If the dnsmasq-determined hostname matches the 3 | # first column of this file, then a DNAT port-forward will be set up 4 | # to the address which has just been allocated by DHCP . The second field 5 | # is port number(s). If there is only one, then the port-forward goes to 6 | # the same port on the DHCP-client, if there are two seperated with a 7 | # colon, then the second number is the port to which the connection 8 | # is forwarded on the DHCP-client. By default, forwarding is set up 9 | # for TCP, but it can done for UDP instead by prefixing the port to "u". 10 | # To forward both TCP and UDP, two lines are required. 11 | # 12 | # eg. 13 | # wwwserver 80 14 | # will set up a port forward from port 80 on this host to port 80 15 | # at the address allocated to wwwserver whenever wwwserver gets a DHCP lease. 16 | # 17 | # wwwserver 8080:80 18 | # will set up a port forward from port 8080 on this host to port 80 19 | # on the DHCP-client. 20 | # 21 | # dnsserver 53 22 | # dnsserver u53 23 | # will port forward port 53 UDP and TCP from this host to port 53 on dnsserver. 24 | # 25 | # Port forwards will recreated when dnsmasq restarts after a reboot, and 26 | # removed when DHCP leases expire. After editing this file, send 27 | # SIGHUP to dnsmasq to install new iptables entries in the kernel. 28 | 29 | -------------------------------------------------------------------------------- /contrib/slackware-dnsmasq/dnsmasq.SlackBuild: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | CWD=`pwd` 3 | PKG=/tmp/package-dnsmasq 4 | 5 | VERSION=2.24 6 | ARCH=${ARCH:-i486} 7 | BUILD=${BUILD:-1} 8 | 9 | if [ "$ARCH" = "i386" ]; then 10 | SLKCFLAGS="-O2 -march=i386 -mcpu=i686" 11 | elif [ "$ARCH" = "i486" ]; then 12 | SLKCFLAGS="-O2 -march=i486 -mcpu=i686" 13 | elif [ "$ARCH" = "s390" ]; then 14 | SLKCFLAGS="-O2" 15 | elif [ "$ARCH" = "x86_64" ]; then 16 | SLKCFLAGS="-O2" 17 | fi 18 | 19 | rm -rf $PKG 20 | mkdir -p $PKG 21 | cd /tmp 22 | rm -rf dnsmasq-$VERSION 23 | tar xzvf $CWD/dnsmasq-$VERSION.tar.gz 24 | cd dnsmasq-$VERSION 25 | zcat $CWD/dnsmasq.leasedir.diff.gz | patch -p1 --verbose --backup --suffix=.orig || exit 26 | chown -R root.root . 27 | make install-i18n PREFIX=/usr DESTDIR=$PKG MANDIR=/usr/man 28 | chmod 755 $PKG/usr/sbin/dnsmasq 29 | chown -R root.bin $PKG/usr/sbin 30 | gzip -9 $PKG/usr/man/man8/dnsmasq.8 31 | for f in $PKG/usr/share/man/*; do 32 | if [ -f $$f/man8/dnsmasq.8 ]; then 33 | gzip -9 $$f/man8/dnsmasq.8 ; 34 | fi 35 | done 36 | gzip -9 $PKG/usr/man/*/man8/dnsmasq.8 37 | mkdir -p $PKG/var/state/dnsmasq 38 | ( cd $PKG 39 | find . | xargs file | grep "executable" | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null 40 | find . | xargs file | grep "shared object" | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null 41 | ) 42 | mkdir $PKG/etc 43 | cat dnsmasq.conf.example > $PKG/etc/dnsmasq.conf.new 44 | mkdir $PKG/etc/rc.d 45 | zcat $CWD/rc.dnsmasq.gz > $PKG/etc/rc.d/rc.dnsmasq.new 46 | mkdir -p $PKG/usr/doc/dnsmasq-$VERSION 47 | cp -a \ 48 | CHANGELOG COPYING FAQ UPGRADING_to_2.0 doc.html setup.html \ 49 | $PKG/usr/doc/dnsmasq-$VERSION 50 | mkdir -p $PKG/install 51 | cat $CWD/slack-desc > $PKG/install/slack-desc 52 | zcat $CWD/doinst.sh.gz > $PKG/install/doinst.sh 53 | 54 | cd $PKG 55 | makepkg -l y -c n ../dnsmasq-$VERSION-$ARCH-$BUILD.tgz 56 | 57 | -------------------------------------------------------------------------------- /contrib/slackware-dnsmasq/dnsmasq.leasedir.diff.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infinet/dnsmasq/611fd4ac2d51ef3df22a32669466efc1109205c7/contrib/slackware-dnsmasq/dnsmasq.leasedir.diff.gz -------------------------------------------------------------------------------- /contrib/slackware-dnsmasq/doinst.sh.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infinet/dnsmasq/611fd4ac2d51ef3df22a32669466efc1109205c7/contrib/slackware-dnsmasq/doinst.sh.gz -------------------------------------------------------------------------------- /contrib/slackware-dnsmasq/rc.dnsmasq.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infinet/dnsmasq/611fd4ac2d51ef3df22a32669466efc1109205c7/contrib/slackware-dnsmasq/rc.dnsmasq.gz -------------------------------------------------------------------------------- /contrib/slackware-dnsmasq/slack-desc: -------------------------------------------------------------------------------- 1 | # HOW TO EDIT THIS FILE: 2 | # The "handy ruler" below makes it easier to edit a package description. Line 3 | # up the first '|' above the ':' following the base package name, and the '|' on 4 | # the right side marks the last column you can put a character in. You must make 5 | # exactly 11 lines for the formatting to be correct. It's also customary to 6 | # leave one space after the ':'. 7 | 8 | |-----handy-ruler------------------------------------------------------| 9 | dnsmasq: dnsmasq (small DNS and DHCP server) 10 | dnsmasq: 11 | dnsmasq: Dnsmasq is a lightweight, easy to configure DNS forwarder and DHCP 12 | dnsmasq: server. It is designed to provide DNS (and optionally DHCP) to a 13 | dnsmasq: small network, and can serve the names of local machines which are not 14 | dnsmasq: in the global DNS. 15 | dnsmasq: 16 | dnsmasq: Dnsmasq was written by Simon Kelley. 17 | dnsmasq: 18 | dnsmasq: 19 | dnsmasq: 20 | -------------------------------------------------------------------------------- /contrib/static-arp/static-arp: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Contributed by Darren Hoo 4 | 5 | # If you use dnsmasq as DHCP server on a router, you may have 6 | # met with attackers trying ARP Poison Routing (APR) on your 7 | # local area network. This script will setup a 'permanent' entry 8 | # in the router's ARP table upon each DHCP transaction so as to 9 | # make the attacker's efforts less successful. 10 | 11 | # Usage: 12 | # edit /etc/dnsmasq.conf and specify the path of this script 13 | # to dhcp-script, for example: 14 | # dhcp-script=/usr/sbin/static-arp 15 | 16 | # if $1 is add or old, update the static arp table entry. 17 | # if $1 is del, then delete the entry from the table 18 | # if $1 is init which is called by dnsmasq at startup, it's ignored 19 | 20 | ARP=/usr/sbin/arp 21 | 22 | # Arguments. 23 | # $1 is action (add, del, old) 24 | # $2 is MAC 25 | # $3 is address 26 | # $4 is hostname (optional, may be unset) 27 | 28 | if [ ${1} = del ] ; then 29 | ${ARP} -d $3 30 | fi 31 | 32 | if [ ${1} = old ] || [ ${1} = add ] ; then 33 | ${ARP} -s $3 $2 34 | fi 35 | 36 | -------------------------------------------------------------------------------- /contrib/systemd/README: -------------------------------------------------------------------------------- 1 | Hello, 2 | 3 | I created a systemd service file for dnsmasq. 4 | systemd is a sysvinit replacement (see [1] for more information). 5 | One of the goals of systemd is to encourage standardization between different 6 | distributions. This means, while I also submitted a ticket in Debian GNU/Linux, 7 | I would like to ask you to accept this service file as the upstream 8 | distributor, so that other distributions can use the same service file and 9 | don’t have to ship their own. 10 | 11 | Please include this file in your next release (just like in init script). 12 | 13 | 14 | [1] http://en.wikipedia.org/wiki/Systemd 15 | 16 | 17 | -------------------------------------------------------------------------------- /contrib/systemd/dbus_activation: -------------------------------------------------------------------------------- 1 | To: dnsmasq-discuss@lists.thekelleys.org.uk 2 | From: Alex Elsayed 3 | Date: Tue, 15 May 2012 01:53:54 -0700 4 | Subject: [Dnsmasq-discuss] [PATCH] Support dbus activation 5 | 6 | Introduce dbus service file and turn dbus on in the systemd 7 | unit. 8 | 9 | Note to packagers: 10 | To add support for dbus activation, you must install the dbus 11 | service file (dbus/uk.org.thekelleys.dnsmasq.service) into 12 | $DATADIR/dbus-1/system-services. 13 | 14 | --- 15 | contrib/systemd/dnsmasq.service | 2 +- 16 | dbus/uk.org.thekelleys.dnsmasq.service | 7 +++++++ 17 | 2 files changed, 8 insertions(+), 1 deletion(-) 18 | create mode 100644 dbus/uk.org.thekelleys.dnsmasq.service 19 | 20 | diff --git a/contrib/systemd/dnsmasq.service 21 | b/contrib/systemd/dnsmasq.service 22 | index a27fe6d..4a784d3 100644 23 | --- a/contrib/systemd/dnsmasq.service 24 | +++ b/contrib/systemd/dnsmasq.service 25 | @@ -5,7 +5,7 @@ Description=A lightweight DHCP and caching DNS server 26 | Type=dbus 27 | BusName=uk.org.thekelleys.dnsmasq 28 | ExecStartPre=/usr/sbin/dnsmasq --test 29 | -ExecStart=/usr/sbin/dnsmasq -k 30 | +ExecStart=/usr/sbin/dnsmasq -k -1 31 | ExecReload=/bin/kill -HUP $MAINPID 32 | 33 | [Install] 34 | diff --git a/dbus/uk.org.thekelleys.dnsmasq.service 35 | b/dbus/uk.org.thekelleys.dnsmasq.service 36 | new file mode 100644 37 | index 0000000..f5fe98d 38 | --- /dev/null 39 | +++ b/dbus/uk.org.thekelleys.dnsmasq.service 40 | @@ -0,0 +1,7 @@ 41 | +[D-BUS Service] 42 | +Name=uk.org.thekelleys.dnsmasq 43 | +Exec=/usr/sbin/dnsmasq -k -1 44 | +User=root 45 | +SystemdService=dnsmasq.service 46 | + 47 | + 48 | -- 49 | 1.7.10.2 50 | 51 | 52 | 53 | _______________________________________________ 54 | Dnsmasq-discuss mailing list 55 | Dnsmasq-discuss@lists.thekelleys.org.uk 56 | http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss 57 | 58 | -------------------------------------------------------------------------------- /contrib/systemd/dnsmasq.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=dnsmasq - A lightweight DHCP and caching DNS server 3 | 4 | [Service] 5 | Type=dbus 6 | BusName=uk.org.thekelleys.dnsmasq 7 | ExecStartPre=/usr/sbin/dnsmasq --test 8 | ExecStart=/usr/sbin/dnsmasq -k 9 | ExecReload=/bin/kill -HUP $MAINPID 10 | 11 | [Install] 12 | WantedBy=multi-user.target 13 | -------------------------------------------------------------------------------- /contrib/try-all-ns/README: -------------------------------------------------------------------------------- 1 | Date: Thu, 07 Dec 2006 00:41:43 -0500 2 | From: Bob Carroll 3 | Subject: dnsmasq suggestion 4 | To: simon@thekelleys.org.uk 5 | 6 | 7 | Hello, 8 | 9 | I recently needed a feature in dnsmasq for a very bizarre situation. I 10 | placed a list of name servers in a special resolve file and told dnsmasq 11 | to use that. But I wanted it to try requests in order and treat NXDOMAIN 12 | requests as a failed tcp connection. I wrote the feature into dnsmasq 13 | and it seems to work. I prepared a patch in the event that others might 14 | find it useful as well. 15 | 16 | Thanks and keep up the good work. 17 | 18 | --Bob 19 | 20 | -------------------------------------------------------------------------------- /contrib/try-all-ns/README-2.47: -------------------------------------------------------------------------------- 1 | A remake of patch Bob Carroll had posted to dnsmasq, 2 | now compatible with version 2.47. Hopefully he doesn't 3 | mind (sending a copy of this mail to him too). 4 | 5 | Maybe the patch in question is not acceptible 6 | as it doesn't add new switch, rather it binds itself to "strict-order". 7 | 8 | What it does is: if you have strict-order in the 9 | dnsmasq config file and query a domain that would result 10 | in NXDOMAIN, it iterates the whole given nameserver list 11 | until the last one says NXDOMAIN. 12 | -------------------------------------------------------------------------------- /contrib/try-all-ns/dnsmasq-2.35-try-all-ns.patch: -------------------------------------------------------------------------------- 1 | diff -Nau dnsmasq-2.35/src/dnsmasq.h dnsmasq/src/dnsmasq.h 2 | --- dnsmasq-2.35/src/dnsmasq.h 2006-10-18 16:24:50.000000000 -0400 3 | +++ dnsmasq/src/dnsmasq.h 2006-11-16 22:06:31.000000000 -0500 4 | @@ -112,6 +112,7 @@ 5 | #define OPT_NO_PING 2097152 6 | #define OPT_LEASE_RO 4194304 7 | #define OPT_RELOAD 8388608 8 | +#define OPT_TRY_ALL_NS 16777216 9 | 10 | struct all_addr { 11 | union { 12 | diff -Nau dnsmasq-2.35/src/forward.c dnsmasq/src/forward.c 13 | --- dnsmasq-2.35/src/forward.c 2006-10-18 16:24:50.000000000 -0400 14 | +++ dnsmasq/src/forward.c 2006-11-16 22:08:19.000000000 -0500 15 | @@ -445,6 +445,10 @@ 16 | { 17 | struct server *server = forward->sentto; 18 | 19 | + // If strict-order and try-all-ns are set, treat NXDOMAIN as a failed request 20 | + if( (daemon->options & OPT_ORDER) && (daemon->options && OPT_TRY_ALL_NS) 21 | + && header->rcode == NXDOMAIN ) header->rcode = SERVFAIL; 22 | + 23 | if ((header->rcode == SERVFAIL || header->rcode == REFUSED) && forward->forwardall == 0) 24 | /* for broken servers, attempt to send to another one. */ 25 | { 26 | diff -Nau dnsmasq-2.35/src/option.c dnsmasq/src/option.c 27 | --- dnsmasq-2.35/src/option.c 2006-10-18 16:24:50.000000000 -0400 28 | +++ dnsmasq/src/option.c 2006-11-16 22:10:36.000000000 -0500 29 | @@ -28,7 +28,7 @@ 30 | 31 | /* options which don't have a one-char version */ 32 | #define LOPT_RELOAD 256 33 | - 34 | +#define LOPT_TRY_ALL_NS 257 35 | 36 | #ifdef HAVE_GETOPT_LONG 37 | static const struct option opts[] = 38 | @@ -102,6 +102,7 @@ 39 | {"leasefile-ro", 0, 0, '9'}, 40 | {"dns-forward-max", 1, 0, '0'}, 41 | {"clear-on-reload", 0, 0, LOPT_RELOAD }, 42 | + {"try-all-ns", 0, 0, LOPT_TRY_ALL_NS }, 43 | { NULL, 0, 0, 0 } 44 | }; 45 | 46 | @@ -134,6 +135,7 @@ 47 | { '5', OPT_NO_PING }, 48 | { '9', OPT_LEASE_RO }, 49 | { LOPT_RELOAD, OPT_RELOAD }, 50 | + { LOPT_TRY_ALL_NS,OPT_TRY_ALL_NS }, 51 | { 'v', 0}, 52 | { 'w', 0}, 53 | { 0, 0 } 54 | @@ -208,6 +210,7 @@ 55 | { "-9, --leasefile-ro", gettext_noop("Read leases at startup, but never write the lease file."), NULL }, 56 | { "-0, --dns-forward-max=", gettext_noop("Maximum number of concurrent DNS queries. (defaults to %s)"), "!" }, 57 | { " --clear-on-reload", gettext_noop("Clear DNS cache when reloading %s."), RESOLVFILE }, 58 | + { " --try-all-ns", gettext_noop("Try all name servers in tandem on NXDOMAIN replies (use with strict-order)."), NULL }, 59 | { NULL, NULL, NULL } 60 | }; 61 | 62 | -------------------------------------------------------------------------------- /contrib/try-all-ns/dnsmasq-2.47_no_nxdomain_until_end.patch: -------------------------------------------------------------------------------- 1 | diff -ur dnsmasq-2.47/src/forward.c dnsmasq-2.47-patched/src/forward.c 2 | --- dnsmasq-2.47/src/forward.c 2009-02-01 17:59:48.000000000 +0200 3 | +++ dnsmasq-2.47-patched/src/forward.c 2009-03-18 19:10:22.000000000 +0200 4 | @@ -488,9 +488,12 @@ 5 | return; 6 | 7 | server = forward->sentto; 8 | + 9 | + if ( (header->rcode == NXDOMAIN) && ((daemon->options & OPT_ORDER) != 0) && (server->next != NULL) ) 10 | + header->rcode = SERVFAIL; 11 | 12 | if ((header->rcode == SERVFAIL || header->rcode == REFUSED) && 13 | - !(daemon->options & OPT_ORDER) && 14 | + ((daemon->options & OPT_ORDER) != 0) && 15 | forward->forwardall == 0) 16 | /* for broken servers, attempt to send to another one. */ 17 | { 18 | -------------------------------------------------------------------------------- /contrib/try-all-ns/dnsmasq-2.68-try-all-ns: -------------------------------------------------------------------------------- 1 | From: Jesse Glick 2 | To: dnsmasq-discuss@lists.thekelleys.org.uk 3 | Subject: Re: [Dnsmasq-discuss] Ability to delegate to one server but fall 4 | back to another after NXDOMAIN? 5 | 6 | 7 | On Wed, Jan 15, 2014 at 12:30 PM, Simon Kelley wrote: 8 | > > There's a (very old) patch in contrib/try-all-ns that would make a starting point 9 | This does not apply against trunk, so I tried to rework it. The 10 | following appears to do what I expect: 11 | 12 | diff --git a/src/forward.c b/src/forward.c 13 | index 8167229..76070b5 100644 14 | --- a/src/forward.c 15 | +++ b/src/forward.c 16 | @@ -610,7 +610,11 @@ void reply_query(int fd, int family, time_t now) 17 | 18 | if ((RCODE(header) == SERVFAIL || RCODE(header) == REFUSED) && 19 | !option_bool(OPT_ORDER) && 20 | - forward->forwardall == 0) 21 | + forward->forwardall == 0 || 22 | + /* try each in turn */ 23 | + RCODE(header) == NXDOMAIN && 24 | + option_bool(OPT_ORDER) && 25 | + server->next != NULL) 26 | /* for broken servers, attempt to send to another one. */ 27 | { 28 | unsigned char *pheader; 29 | 30 | -------------------------------------------------------------------------------- /contrib/webmin/README: -------------------------------------------------------------------------------- 1 | 2 | This is the README for the DNSmasq webmin module. 3 | 4 | Problems: 5 | 6 | 1) There's only basic error checking - if you enter some bad 7 | addresses or names, they will go straight into the config file 8 | although we do check for things like IP addresses being of 9 | the correct form (no letters, 4 groups of up to 3 digits 10 | separated by dots etc). One thing that ISN'T CHECKED FOR is 11 | that IP dotted quads are all numbers < 256. Another is that 12 | netmasks are logical (you could enter a netmask of 255.0.255.0 13 | for example). Essentially, if it'll pass the config file 14 | regex scanner (and the above examples will), it won't be 15 | flagged as "bad" even if it is a big no-no for dnsmasq itself. 16 | 17 | 2) Code is ugly and a kludge - I ain't a programmer! There are probably 18 | a lot of things that could be done to tidy up the code - eg, 19 | it probably wouldn't hurt to move some common stuff into the lib file. 20 | 21 | 3) I've used the %text hash and written an english lang file, but 22 | I am mono-lingual so no other language support as yet. 23 | 24 | 4) for reasons unknown to me, the icon does not appear properly 25 | on the servers page of webmin (at least it doesn't for me!) 26 | 27 | 5) icons have been shamelessly stolen from the ipfilter module, 28 | specifically the up and down arrows. 29 | 30 | 6) if you delete an item, the config file will contain 31 | an otherwise empty, but commented line. This means that if 32 | you add some new stuff, then delete it, the config file 33 | will have a number of lines at the end that are just comments. 34 | Therefore, the config file could possibly grow quite large. 35 | 36 | 7) NO INCLUDE FILES! 37 | if you use an include file, it'll be flagged as an error. 38 | OK if the include file line is commented out though. 39 | 40 | 8) deprecated lines not supported (eg user and group) - they 41 | may produce an error! (user and group don't, but you can't change 42 | them) 43 | 44 | IOW, it works, it's just not very elegant and not very robust. 45 | 46 | Hope you find it useful though - I do, as I prevents me having to ever 47 | wade through the config file and man pages again. 48 | 49 | If you modify it, or add a language file, and you have a spare moment, 50 | please e-mail me - I won't be upset at all if you fix my poor coding! 51 | (rather the opposite - I'd be pleased someone found it usefull) 52 | 53 | Cheers, 54 | Neil Fisher 55 | -------------------------------------------------------------------------------- /contrib/webmin/dnsmasq.wbm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infinet/dnsmasq/611fd4ac2d51ef3df22a32669466efc1109205c7/contrib/webmin/dnsmasq.wbm -------------------------------------------------------------------------------- /contrib/wrt/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS?= -O2 -Wall -W 2 | 3 | all: dhcp_release dhcp_lease_time 4 | 5 | clean: 6 | rm -f *~ *.o core dhcp_release dhcp_lease_time 7 | -------------------------------------------------------------------------------- /contrib/wrt/README: -------------------------------------------------------------------------------- 1 | This script can be used to implement persistent leases on openWRT, DD-WRT 2 | etc. Persistent leases are good: if the lease database is lost on a 3 | reboot, then it will eventually be restored as hosts renew their 4 | leases. Until a host renews (which may take hours/days) it will 5 | not exist in the DNS if dnsmasq's DDNS function is in use. 6 | 7 | *WRT systems remount all non-volatile fileystems read-only after boot, 8 | so the normal leasefile will not work. They do, however have NV 9 | storage, accessed with the nvram command: 10 | 11 | /usr/lib # nvram 12 | usage: nvram [get name] [set name=value] [unset name] [show] 13 | 14 | The principle is that leases are kept in NV variable with data 15 | corresponding to the line in a leasefile: 16 | 17 | dnsmasq_lease_192.168.1.56=3600 00:41:4a:05:80:74 192.168.1.56 * * 18 | 19 | By giving dnsmasq the leasefile-ro command, it no longer creates or writes a 20 | leasefile; responsibility for maintaining the lease database transfers 21 | to the lease change script. At startup, in leasefile-ro mode, 22 | dnsmasq will run 23 | 24 | " init" 25 | 26 | and read whatever that command spits out, expecting it to 27 | be in dnsmasq leasefile format. 28 | 29 | So the lease change script, given "init" as argv[1] will 30 | suck existing leases out of the NVRAM and emit them from 31 | stdout in the correct format. 32 | 33 | The second part of the problem is keeping the NVRAM up-to-date: this 34 | is done by the lease-change script which dnsmasq runs when a lease is 35 | updated. When it is called with argv[1] as "old", "add", or "del" 36 | it updates the relevant nvram entry. 37 | 38 | So, dnsmasq should be run as : 39 | 40 | dnsmasq --leasefile-ro --dhcp-script=/path/to/lease_update.sh 41 | 42 | or the same flags added to /etc/dnsmasq.conf 43 | 44 | 45 | 46 | Notes: 47 | 48 | This needs dnsmasq-2.33 or later to work. 49 | 50 | This technique will work with, or without, compilation with 51 | HAVE_BROKEN_RTC. Compiling with HAVE_BROKEN_RTC is 52 | _highly_recommended_ for this application since is avoids problems 53 | with the system clock being warped by NTP, and it vastly reduces the 54 | number of writes to the NVRAM. With HAVE_BROKEN_RTC, NVRAM is updated 55 | only when a lease is created or destroyed; without it, a write occurs 56 | every time a lease is renewed. 57 | 58 | It probably makes sense to restrict the number of active DHCP leases 59 | to an appropriate number using dhcp-lease-max. On a new DD_WRT system, 60 | there are about 10K bytes free in the NVRAM. Each lease record is 61 | about 100 bytes, so restricting the number of leases to 50 will limit 62 | use to half that. (The default limit in the distributed source is 150) 63 | 64 | Any UI script which reads the dnsmasq leasefile will have to be 65 | ammended, probably by changing it to read the output of 66 | `lease_update init` instead. 67 | 68 | 69 | Thanks: 70 | 71 | To Steve Horbachuk for checks on the script and debugging beyond the 72 | call of duty. 73 | 74 | 75 | Simon Kelley 76 | Fri Jul 28 11:51:13 BST 2006 77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /contrib/wrt/dhcp_lease_time.1: -------------------------------------------------------------------------------- 1 | .TH DHCP_LEASE_TIME 1 2 | .SH NAME 3 | dhcp_lease_time \- Query remaining time of a lease on a the local dnsmasq DHCP server. 4 | .SH SYNOPSIS 5 | .B dhcp_lease_time
6 | .SH "DESCRIPTION" 7 | Send a DHCPINFORM message to a dnsmasq server running on the local host 8 | and print (to stdout) the time remaining in any lease for the given 9 | address. The time is given as string printed to stdout. 10 | 11 | If an error occurs or no lease exists for the given address, 12 | nothing is sent to stdout a message is sent to stderr and a 13 | non-zero error code is returned. 14 | 15 | Requires dnsmasq 2.67 or later and may not work with other DHCP servers. 16 | 17 | The address argument is a dotted-quad IP addresses and mandatory. 18 | .SH LIMITATIONS 19 | Only works with IPv4 addresses and DHCP leases. 20 | .SH SEE ALSO 21 | .BR dnsmasq (8) 22 | .SH AUTHOR 23 | This manual page was written by Simon Kelley . 24 | 25 | 26 | -------------------------------------------------------------------------------- /contrib/wrt/dhcp_lease_time.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2007 Simon Kelley 2 | 3 | This program is free software; you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation; version 2 dated June, 1991. 6 | 7 | This program is distributed in the hope that it will be useful, 8 | but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | GNU General Public License for more details. 11 | */ 12 | 13 | /* dhcp_lease_time
*/ 14 | 15 | /* Send a DHCPINFORM message to a dnsmasq server running on the local host 16 | and print (to stdout) the time remaining in any lease for the given 17 | address. The time is given as string printed to stdout. 18 | 19 | If an error occurs or no lease exists for the given address, 20 | nothing is sent to stdout a message is sent to stderr and a 21 | non-zero error code is returned. 22 | 23 | This version requires dnsmasq 2.67 or later. 24 | */ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #define DHCP_CHADDR_MAX 16 43 | #define BOOTREQUEST 1 44 | #define DHCP_COOKIE 0x63825363 45 | #define OPTION_PAD 0 46 | #define OPTION_LEASE_TIME 51 47 | #define OPTION_OVERLOAD 52 48 | #define OPTION_MESSAGE_TYPE 53 49 | #define OPTION_REQUESTED_OPTIONS 55 50 | #define OPTION_END 255 51 | #define DHCPINFORM 8 52 | #define DHCP_SERVER_PORT 67 53 | 54 | #define option_len(opt) ((int)(((unsigned char *)(opt))[1])) 55 | #define option_ptr(opt) ((void *)&(((unsigned char *)(opt))[2])) 56 | 57 | 58 | typedef unsigned char u8; 59 | typedef unsigned short u16; 60 | typedef unsigned int u32; 61 | 62 | struct dhcp_packet { 63 | u8 op, htype, hlen, hops; 64 | u32 xid; 65 | u16 secs, flags; 66 | struct in_addr ciaddr, yiaddr, siaddr, giaddr; 67 | u8 chaddr[DHCP_CHADDR_MAX], sname[64], file[128]; 68 | u32 cookie; 69 | unsigned char options[308]; 70 | }; 71 | 72 | static unsigned char *option_find1(unsigned char *p, unsigned char *end, int opt, int minsize) 73 | { 74 | while (*p != OPTION_END) 75 | { 76 | if (p >= end) 77 | return NULL; /* malformed packet */ 78 | else if (*p == OPTION_PAD) 79 | p++; 80 | else 81 | { 82 | int opt_len; 83 | if (p >= end - 2) 84 | return NULL; /* malformed packet */ 85 | opt_len = option_len(p); 86 | if (p >= end - (2 + opt_len)) 87 | return NULL; /* malformed packet */ 88 | if (*p == opt && opt_len >= minsize) 89 | return p; 90 | p += opt_len + 2; 91 | } 92 | } 93 | 94 | return opt == OPTION_END ? p : NULL; 95 | } 96 | 97 | static unsigned char *option_find(struct dhcp_packet *mess, size_t size, int opt_type, int minsize) 98 | { 99 | unsigned char *ret, *overload; 100 | 101 | /* skip over DHCP cookie; */ 102 | if ((ret = option_find1(&mess->options[0], ((unsigned char *)mess) + size, opt_type, minsize))) 103 | return ret; 104 | 105 | /* look for overload option. */ 106 | if (!(overload = option_find1(&mess->options[0], ((unsigned char *)mess) + size, OPTION_OVERLOAD, 1))) 107 | return NULL; 108 | 109 | /* Can we look in filename area ? */ 110 | if ((overload[2] & 1) && 111 | (ret = option_find1(&mess->file[0], &mess->file[128], opt_type, minsize))) 112 | return ret; 113 | 114 | /* finally try sname area */ 115 | if ((overload[2] & 2) && 116 | (ret = option_find1(&mess->sname[0], &mess->sname[64], opt_type, minsize))) 117 | return ret; 118 | 119 | return NULL; 120 | } 121 | 122 | static unsigned int option_uint(unsigned char *opt, int size) 123 | { 124 | /* this worries about unaligned data and byte order */ 125 | unsigned int ret = 0; 126 | int i; 127 | unsigned char *p = option_ptr(opt); 128 | 129 | for (i = 0; i < size; i++) 130 | ret = (ret << 8) | *p++; 131 | 132 | return ret; 133 | } 134 | 135 | int main(int argc, char **argv) 136 | { 137 | struct in_addr lease; 138 | struct dhcp_packet packet; 139 | unsigned char *p = packet.options; 140 | struct sockaddr_in dest; 141 | int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); 142 | ssize_t rc; 143 | 144 | if (argc < 2) 145 | { 146 | fprintf(stderr, "usage: dhcp_lease_time
\n"); 147 | exit(1); 148 | } 149 | 150 | if (fd == -1) 151 | { 152 | perror("cannot create socket"); 153 | exit(1); 154 | } 155 | 156 | lease.s_addr = inet_addr(argv[1]); 157 | 158 | memset(&packet, 0, sizeof(packet)); 159 | 160 | packet.hlen = 0; 161 | packet.htype = 0; 162 | 163 | packet.op = BOOTREQUEST; 164 | packet.ciaddr = lease; 165 | packet.cookie = htonl(DHCP_COOKIE); 166 | 167 | *(p++) = OPTION_MESSAGE_TYPE; 168 | *(p++) = 1; 169 | *(p++) = DHCPINFORM; 170 | 171 | /* Explicity request the lease time, it won't be sent otherwise: 172 | this is a dnsmasq extension, not standard. */ 173 | *(p++) = OPTION_REQUESTED_OPTIONS; 174 | *(p++) = 1; 175 | *(p++) = OPTION_LEASE_TIME; 176 | 177 | *(p++) = OPTION_END; 178 | 179 | dest.sin_family = AF_INET; 180 | dest.sin_addr.s_addr = inet_addr("127.0.0.1"); 181 | dest.sin_port = ntohs(DHCP_SERVER_PORT); 182 | 183 | if (sendto(fd, &packet, sizeof(packet), 0, 184 | (struct sockaddr *)&dest, sizeof(dest)) == -1) 185 | { 186 | perror("sendto failed"); 187 | exit(1); 188 | } 189 | 190 | alarm(3); /* noddy timeout. */ 191 | 192 | rc = recv(fd, &packet, sizeof(packet), 0); 193 | 194 | if (rc < (ssize_t)(sizeof(packet) - sizeof(packet.options))) 195 | { 196 | perror("recv failed"); 197 | exit(1); 198 | } 199 | 200 | if ((p = option_find(&packet, (size_t)rc, OPTION_LEASE_TIME, 4))) 201 | { 202 | unsigned int t = option_uint(p, 4); 203 | if (t == 0xffffffff) 204 | printf("infinite"); 205 | else 206 | { 207 | unsigned int x; 208 | if ((x = t/86400)) 209 | printf("%dd", x); 210 | if ((x = (t/3600)%24)) 211 | printf("%dh", x); 212 | if ((x = (t/60)%60)) 213 | printf("%dm", x); 214 | if ((x = t%60)) 215 | printf("%ds", x); 216 | } 217 | return 0; 218 | } 219 | 220 | return 1; /* no lease */ 221 | } 222 | -------------------------------------------------------------------------------- /contrib/wrt/dhcp_release.1: -------------------------------------------------------------------------------- 1 | .TH DHCP_RELEASE 1 2 | .SH NAME 3 | dhcp_release \- Release a DHCP lease on a the local dnsmasq DHCP server. 4 | .SH SYNOPSIS 5 | .B dhcp_release
6 | .SH "DESCRIPTION" 7 | A utility which forces the DHCP server running on this machine to release a 8 | DHCP lease. 9 | .PP 10 | Send a DHCPRELEASE message via the specified interface to tell the 11 | local DHCP server to delete a particular lease. 12 | 13 | The interface argument is the interface in which a DHCP 14 | request _would_ be received if it was coming from the client, 15 | rather than being faked up here. 16 | 17 | The address argument is a dotted-quad IP addresses and mandatory. 18 | 19 | The MAC address is colon separated hex, and is mandatory. It may be 20 | prefixed by an address-type byte followed by -, eg 21 | 22 | 10-11:22:33:44:55:66 23 | 24 | but if the address-type byte is missing it is assumed to be 1, the type 25 | for ethernet. This encoding is the one used in dnsmasq lease files. 26 | 27 | The client-id is optional. If it is "*" then it treated as being missing. 28 | .SH NOTES 29 | MUST be run as root - will fail otherwise. 30 | .SH LIMITATIONS 31 | Only usable on IPv4 DHCP leases. 32 | .SH SEE ALSO 33 | .BR dnsmasq (8) 34 | .SH AUTHOR 35 | This manual page was written by Simon Kelley . 36 | 37 | 38 | -------------------------------------------------------------------------------- /contrib/wrt/dhcp_release.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006 Simon Kelley 2 | 3 | This program is free software; you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation; version 2 dated June, 1991. 6 | 7 | This program is distributed in the hope that it will be useful, 8 | but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | GNU General Public License for more details. 11 | */ 12 | 13 | /* dhcp_release
14 | MUST be run as root - will fail otherwise. */ 15 | 16 | /* Send a DHCPRELEASE message via the specified interface 17 | to tell the local DHCP server to delete a particular lease. 18 | 19 | The interface argument is the interface in which a DHCP 20 | request _would_ be received if it was coming from the client, 21 | rather than being faked up here. 22 | 23 | The address argument is a dotted-quad IP addresses and mandatory. 24 | 25 | The MAC address is colon separated hex, and is mandatory. It may be 26 | prefixed by an address-type byte followed by -, eg 27 | 28 | 10-11:22:33:44:55:66 29 | 30 | but if the address-type byte is missing it is assumed to be 1, the type 31 | for ethernet. This encoding is the one used in dnsmasq lease files. 32 | 33 | The client-id is optional. If it is "*" then it treated as being missing. 34 | */ 35 | 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | 52 | #define DHCP_CHADDR_MAX 16 53 | #define BOOTREQUEST 1 54 | #define DHCP_COOKIE 0x63825363 55 | #define OPTION_SERVER_IDENTIFIER 54 56 | #define OPTION_CLIENT_ID 61 57 | #define OPTION_MESSAGE_TYPE 53 58 | #define OPTION_END 255 59 | #define DHCPRELEASE 7 60 | #define DHCP_SERVER_PORT 67 61 | 62 | typedef unsigned char u8; 63 | typedef unsigned short u16; 64 | typedef unsigned int u32; 65 | 66 | struct dhcp_packet { 67 | u8 op, htype, hlen, hops; 68 | u32 xid; 69 | u16 secs, flags; 70 | struct in_addr ciaddr, yiaddr, siaddr, giaddr; 71 | u8 chaddr[DHCP_CHADDR_MAX], sname[64], file[128]; 72 | u32 cookie; 73 | unsigned char options[308]; 74 | }; 75 | 76 | static struct iovec iov; 77 | 78 | static int expand_buf(struct iovec *iov, size_t size) 79 | { 80 | void *new; 81 | 82 | if (size <= iov->iov_len) 83 | return 1; 84 | 85 | if (!(new = malloc(size))) 86 | { 87 | errno = ENOMEM; 88 | return 0; 89 | } 90 | 91 | if (iov->iov_base) 92 | { 93 | memcpy(new, iov->iov_base, iov->iov_len); 94 | free(iov->iov_base); 95 | } 96 | 97 | iov->iov_base = new; 98 | iov->iov_len = size; 99 | 100 | return 1; 101 | } 102 | 103 | static ssize_t netlink_recv(int fd) 104 | { 105 | struct msghdr msg; 106 | ssize_t rc; 107 | 108 | msg.msg_control = NULL; 109 | msg.msg_controllen = 0; 110 | msg.msg_name = NULL; 111 | msg.msg_namelen = 0; 112 | msg.msg_iov = &iov; 113 | msg.msg_iovlen = 1; 114 | 115 | while (1) 116 | { 117 | msg.msg_flags = 0; 118 | while ((rc = recvmsg(fd, &msg, MSG_PEEK)) == -1 && errno == EINTR); 119 | 120 | /* 2.2.x doesn't suport MSG_PEEK at all, returning EOPNOTSUPP, so we just grab a 121 | big buffer and pray in that case. */ 122 | if (rc == -1 && errno == EOPNOTSUPP) 123 | { 124 | if (!expand_buf(&iov, 2000)) 125 | return -1; 126 | break; 127 | } 128 | 129 | if (rc == -1 || !(msg.msg_flags & MSG_TRUNC)) 130 | break; 131 | 132 | if (!expand_buf(&iov, iov.iov_len + 100)) 133 | return -1; 134 | } 135 | 136 | /* finally, read it for real */ 137 | while ((rc = recvmsg(fd, &msg, 0)) == -1 && errno == EINTR); 138 | 139 | return rc; 140 | } 141 | 142 | static int parse_hex(char *in, unsigned char *out, int maxlen, int *mac_type) 143 | { 144 | int i = 0; 145 | char *r; 146 | 147 | if (mac_type) 148 | *mac_type = 0; 149 | 150 | while (maxlen == -1 || i < maxlen) 151 | { 152 | for (r = in; *r != 0 && *r != ':' && *r != '-'; r++); 153 | if (*r == 0) 154 | maxlen = i; 155 | 156 | if (r != in ) 157 | { 158 | if (*r == '-' && i == 0 && mac_type) 159 | { 160 | *r = 0; 161 | *mac_type = strtol(in, NULL, 16); 162 | mac_type = NULL; 163 | } 164 | else 165 | { 166 | *r = 0; 167 | out[i] = strtol(in, NULL, 16); 168 | i++; 169 | } 170 | } 171 | in = r+1; 172 | } 173 | return i; 174 | } 175 | 176 | static int is_same_net(struct in_addr a, struct in_addr b, struct in_addr mask) 177 | { 178 | return (a.s_addr & mask.s_addr) == (b.s_addr & mask.s_addr); 179 | } 180 | 181 | static struct in_addr find_interface(struct in_addr client, int fd, unsigned int index) 182 | { 183 | struct sockaddr_nl addr; 184 | struct nlmsghdr *h; 185 | ssize_t len; 186 | 187 | struct { 188 | struct nlmsghdr nlh; 189 | struct rtgenmsg g; 190 | } req; 191 | 192 | addr.nl_family = AF_NETLINK; 193 | addr.nl_pad = 0; 194 | addr.nl_groups = 0; 195 | addr.nl_pid = 0; /* address to kernel */ 196 | 197 | req.nlh.nlmsg_len = sizeof(req); 198 | req.nlh.nlmsg_type = RTM_GETADDR; 199 | req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST | NLM_F_ACK; 200 | req.nlh.nlmsg_pid = 0; 201 | req.nlh.nlmsg_seq = 1; 202 | req.g.rtgen_family = AF_INET; 203 | 204 | if (sendto(fd, (void *)&req, sizeof(req), 0, 205 | (struct sockaddr *)&addr, sizeof(addr)) == -1) 206 | { 207 | perror("sendto failed"); 208 | exit(1); 209 | } 210 | 211 | while (1) 212 | { 213 | if ((len = netlink_recv(fd)) == -1) 214 | { 215 | perror("netlink"); 216 | exit(1); 217 | } 218 | 219 | for (h = (struct nlmsghdr *)iov.iov_base; NLMSG_OK(h, (size_t)len); h = NLMSG_NEXT(h, len)) 220 | if (h->nlmsg_type == NLMSG_DONE) 221 | exit(0); 222 | else if (h->nlmsg_type == RTM_NEWADDR) 223 | { 224 | struct ifaddrmsg *ifa = NLMSG_DATA(h); 225 | struct rtattr *rta; 226 | unsigned int len1 = h->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa)); 227 | 228 | if (ifa->ifa_index == index && ifa->ifa_family == AF_INET) 229 | { 230 | struct in_addr netmask, addr; 231 | 232 | netmask.s_addr = htonl(0xffffffff << (32 - ifa->ifa_prefixlen)); 233 | addr.s_addr = 0; 234 | 235 | for (rta = IFA_RTA(ifa); RTA_OK(rta, len1); rta = RTA_NEXT(rta, len1)) 236 | if (rta->rta_type == IFA_LOCAL) 237 | addr = *((struct in_addr *)(rta+1)); 238 | 239 | if (addr.s_addr && is_same_net(addr, client, netmask)) 240 | return addr; 241 | } 242 | } 243 | } 244 | 245 | exit(0); 246 | } 247 | 248 | int main(int argc, char **argv) 249 | { 250 | struct in_addr server, lease; 251 | int mac_type; 252 | struct dhcp_packet packet; 253 | unsigned char *p = packet.options; 254 | struct sockaddr_in dest; 255 | struct ifreq ifr; 256 | int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); 257 | int nl = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); 258 | 259 | if (argc < 4 || argc > 5) 260 | { 261 | fprintf(stderr, "usage: dhcp_release []\n"); 262 | exit(1); 263 | } 264 | 265 | if (fd == -1 || nl == -1) 266 | { 267 | perror("cannot create socket"); 268 | exit(1); 269 | } 270 | 271 | /* This voodoo fakes up a packet coming from the correct interface, which really matters for 272 | a DHCP server */ 273 | strcpy(ifr.ifr_name, argv[1]); 274 | if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) == -1) 275 | { 276 | perror("cannot setup interface"); 277 | exit(1); 278 | } 279 | 280 | 281 | lease.s_addr = inet_addr(argv[2]); 282 | server = find_interface(lease, nl, if_nametoindex(argv[1])); 283 | 284 | memset(&packet, 0, sizeof(packet)); 285 | 286 | packet.hlen = parse_hex(argv[3], packet.chaddr, DHCP_CHADDR_MAX, &mac_type); 287 | if (mac_type == 0) 288 | packet.htype = ARPHRD_ETHER; 289 | else 290 | packet.htype = mac_type; 291 | 292 | packet.op = BOOTREQUEST; 293 | packet.ciaddr = lease; 294 | packet.cookie = htonl(DHCP_COOKIE); 295 | 296 | *(p++) = OPTION_MESSAGE_TYPE; 297 | *(p++) = 1; 298 | *(p++) = DHCPRELEASE; 299 | 300 | *(p++) = OPTION_SERVER_IDENTIFIER; 301 | *(p++) = sizeof(server); 302 | memcpy(p, &server, sizeof(server)); 303 | p += sizeof(server); 304 | 305 | if (argc == 5 && strcmp(argv[4], "*") != 0) 306 | { 307 | unsigned int clid_len = parse_hex(argv[4], p+2, 255, NULL); 308 | *(p++) = OPTION_CLIENT_ID; 309 | *(p++) = clid_len; 310 | p += clid_len; 311 | } 312 | 313 | *(p++) = OPTION_END; 314 | 315 | dest.sin_family = AF_INET; 316 | dest.sin_port = ntohs(DHCP_SERVER_PORT); 317 | dest.sin_addr = server; 318 | 319 | if (sendto(fd, &packet, sizeof(packet), 0, 320 | (struct sockaddr *)&dest, sizeof(dest)) == -1) 321 | { 322 | perror("sendto failed"); 323 | exit(1); 324 | } 325 | 326 | return 0; 327 | } 328 | -------------------------------------------------------------------------------- /contrib/wrt/lease_update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Copyright (c) 2006 Simon Kelley 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; version 2 dated June, 1991. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | 14 | 15 | # if $1 is add del or old, this is a dnsmasq-called lease-change 16 | # script, update the nvram database. if $1 is init, emit a 17 | # dnsmasq-format lease file to stdout representing the current state of the 18 | # database, this is called by dnsmasq at startup. 19 | 20 | NVRAM=/usr/sbin/nvram 21 | PREFIX=dnsmasq_lease_ 22 | 23 | # Arguments. 24 | # $1 is action (add, del, old) 25 | # $2 is MAC 26 | # $3 is address 27 | # $4 is hostname (optional, may be unset) 28 | 29 | # env. 30 | # DNSMASQ_LEASE_LENGTH or DNSMASQ_LEASE_EXPIRES (which depends on HAVE_BROKEN_RTC) 31 | # DNSMASQ_CLIENT_ID (optional, may be unset) 32 | 33 | # File. 34 | # length|expires MAC addr hostname|* CLID|* 35 | 36 | # Primary key is address. 37 | 38 | if [ ${1} = init ] ; then 39 | ${NVRAM} show | sed -n -e "/^${PREFIX}.*/ s/^.*=//p" 40 | else 41 | if [ ${1} = del ] ; then 42 | ${NVRAM} unset ${PREFIX}${3} 43 | fi 44 | 45 | if [ ${1} = old ] || [ ${1} = add ] ; then 46 | ${NVRAM} set ${PREFIX}${3}="${DNSMASQ_LEASE_LENGTH:-}${DNSMASQ_LEASE_EXPIRES:-} ${2} ${3} ${4:-*} ${DNSMASQ_CLIENT_ID:-*}" 47 | fi 48 | ${NVRAM} commit 49 | fi 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /dbus/DBus-interface: -------------------------------------------------------------------------------- 1 | DBus support must be enabled at compile-time and run-time. Ensure 2 | that src/config.h contains the line 3 | 4 | #define HAVE_DBUS. 5 | 6 | and that /etc/dnsmasq.conf contains the line 7 | 8 | enable-dbus 9 | 10 | Because dnsmasq can operate stand-alone from the DBus, and may need to provide 11 | service before the dbus daemon is available, it will continue to run 12 | if the DBus connection is not available at startup. The DBus will be polled 13 | every 250ms until a connection is established. Start of polling and final 14 | connection establishment are both logged. When dnsmasq establishes a 15 | connection to the dbus, it sends the signal "Up". Anything controlling 16 | the server settings in dnsmasq should re-invoke the SetServers method 17 | (q.v.) when it sees this signal. This allows dnsmasq to be restarted 18 | and avoids startup races with the provider of nameserver information. 19 | 20 | 21 | Dnsmasq provides one service on the DBus: uk.org.thekelleys.dnsmasq 22 | and a single object: /uk/org/thekelleys/dnsmasq 23 | The name of the service may be changed by giving an argument to --enable-dbus. 24 | 25 | 1. METHODS 26 | ---------- 27 | 28 | Methods are of the form 29 | 30 | uk.org.thekelleys. 31 | 32 | Available methods are: 33 | 34 | GetVersion 35 | ---------- 36 | Returns a string containing the version of dnsmasq running. 37 | 38 | ClearCache 39 | ---------- 40 | Returns nothing. Clears the domain name cache and re-reads 41 | /etc/hosts. The same as sending dnsmasq a HUP signal. 42 | 43 | SetFilterWin2KOption 44 | -------------------- 45 | Takes boolean, sets or resets the --filterwin2k option. 46 | 47 | SetBogusPrivOption 48 | ------------------ 49 | Takes boolean, sets or resets the --bogus-priv option. 50 | 51 | SetServers 52 | ---------- 53 | Returns nothing. Takes a set of arguments representing the new 54 | upstream DNS servers to be used by dnsmasq. IPv4 addresses are 55 | represented as a UINT32 (in network byte order) and IPv6 addresses 56 | are represented as sixteen BYTEs (since there is no UINT128 type). 57 | Each server address may be followed by one or more STRINGS, which are 58 | the domains for which the preceding server should be used. 59 | 60 | Examples. 61 | 62 | UINT32: 63 | UNIT32: 64 | 65 | is equivalent to 66 | 67 | --server= --server= 68 | 69 | 70 | UINT32 71 | UINT32 72 | STRING "somedomain.com" 73 | 74 | is equivalent to 75 | 76 | --server= --server=/somedomain.com/ 77 | 78 | UINT32 79 | UINT32 80 | STRING "somedomain.com" 81 | UINT32 82 | STRING "anotherdomain.com" 83 | STRING "thirddomain.com" 84 | 85 | is equivalent to 86 | 87 | --server= 88 | --server=/somedomain.com/ 89 | --server=/anotherdomain.com/thirddomain.com/ 90 | 91 | Am IPv4 address of 0.0.0.0 is interpreted as "no address, local only", 92 | so 93 | 94 | UINT32: <0.0.0.0> 95 | STRING "local.domain" 96 | 97 | is equivalent to 98 | 99 | --local=/local.domain/ 100 | 101 | 102 | Each call to SetServers completely replaces the set of servers 103 | specified by via the DBus, but it leaves any servers specified via the 104 | command line or /etc/dnsmasq.conf or /etc/resolv.conf alone. 105 | 106 | SetServersEx 107 | ------------ 108 | 109 | This function is more flexible and the SetServers function, in that it can 110 | handle address scoping, port numbers, and is easier for clients to use. 111 | 112 | Returns nothing. Takes a set of arguments representing the new 113 | upstream DNS servers to be used by dnsmasq. All addresses (both IPv4 and IPv6) 114 | are represented as STRINGS. Each server address may be followed by one or more 115 | STRINGS, which are the domains for which the preceding server should be used. 116 | 117 | This function takes an array of STRING arrays, where each inner array represents 118 | a set of DNS servers and domains for which those servers may be used. Each 119 | string represents a list of upstream DNS servers first, and domains second. 120 | Mixing of domains and servers within a the string array is not allowed. 121 | 122 | Examples. 123 | 124 | [ 125 | ["1.2.3.4", "foobar.com"], 126 | ["1003:1234:abcd::1%eth0", "eng.mycorp.com", "lab.mycorp.com"] 127 | ] 128 | 129 | is equivalent to 130 | 131 | --server=/foobar.com/1.2.3.4 \ 132 | --server=/eng.mycorp.com/lab.mycorp.com/1003:1234:abcd::1%eth0 133 | 134 | An IPv4 address of 0.0.0.0 is interpreted as "no address, local only", 135 | so 136 | 137 | [ ["0.0.0.0", "local.domain"] ] 138 | 139 | is equivalent to 140 | 141 | --local=/local.domain/ 142 | 143 | 144 | Each call to SetServersEx completely replaces the set of servers 145 | specified by via the DBus, but it leaves any servers specified via the 146 | command line or /etc/dnsmasq.conf or /etc/resolv.conf alone. 147 | 148 | 149 | SetDomainServers 150 | ---------------- 151 | 152 | Yes another variation for setting DNS servers, with the capability of 153 | SetServersEx, but without using arrays of arrays, which are not 154 | sendable with dbus-send. The arguments are an array of strings which 155 | are identical to the equivalent arguments --server, so the example 156 | for SetServersEx is represented as 157 | 158 | [ 159 | "/foobar.com/1.2.3.4" 160 | "/eng.mycorp.com/lab.mycorp.com/1003:1234:abcd::1%eth0" 161 | ] 162 | 163 | GetLoopServers 164 | -------------- 165 | 166 | (Only available if dnsmasq compiled with HAVE_LOOP) 167 | 168 | Return an array of strings, each string is the IP address of an upstream 169 | server which has been found to loop queries back to this dnsmasq instance, and 170 | it therefore not being used. 171 | 172 | 173 | 174 | 2. SIGNALS 175 | ---------- 176 | 177 | If dnsmasq's DHCP server is active, it will send signals over DBUS whenever 178 | the DHCP lease database changes. Think of these signals as transactions on 179 | a database with the IP address acting as the primary key. 180 | 181 | Signals are of the form: 182 | 183 | uk.org.thekelleys. 184 | 185 | and their parameters are: 186 | 187 | STRING "192.168.1.115" 188 | STRING "01:23:45:67:89:ab" 189 | STRING "hostname.or.fqdn" 190 | 191 | 192 | Available signals are: 193 | 194 | DhcpLeaseAdded 195 | --------------- 196 | 197 | This signal is emitted when a DHCP lease for a given IP address is created. 198 | 199 | DhcpLeaseDeleted 200 | ---------------- 201 | 202 | This signal is emitted when a DHCP lease for a given IP address is deleted. 203 | 204 | DhcpLeaseUpdated 205 | ---------------- 206 | 207 | This signal is emitted when a DHCP lease for a given IP address is updated. 208 | 209 | -------------------------------------------------------------------------------- /dbus/dnsmasq.conf: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /debian/conffiles: -------------------------------------------------------------------------------- 1 | /etc/init.d/dnsmasq 2 | /etc/default/dnsmasq 3 | /etc/dnsmasq.conf 4 | /etc/resolvconf/update.d/dnsmasq 5 | /etc/insserv.conf.d/dnsmasq 6 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: dnsmasq 2 | Section: net 3 | Priority: optional 4 | Build-depends: gettext, libnetfilter-conntrack-dev [linux-any], 5 | libidn11-dev, libdbus-1-dev (>=0.61), libgmp-dev, 6 | nettle-dev (>=2.4-3), libbsd-dev [!linux-any] 7 | Maintainer: Simon Kelley 8 | Standards-Version: 3.9.5 9 | 10 | Package: dnsmasq 11 | Architecture: all 12 | Depends: netbase, dnsmasq-base(>= ${binary:Version}), 13 | init-system-helpers (>= 1.18~) 14 | Suggests: resolvconf 15 | Conflicts: resolvconf (<<1.15) 16 | Description: Small caching DNS proxy and DHCP/TFTP server 17 | Dnsmasq is a lightweight, easy to configure, DNS forwarder and DHCP 18 | server. It is designed to provide DNS and optionally, DHCP, to a 19 | small network. It can serve the names of local machines which are 20 | not in the global DNS. The DHCP server integrates with the DNS 21 | server and allows machines with DHCP-allocated addresses 22 | to appear in the DNS with names configured either in each host or 23 | in a central configuration file. Dnsmasq supports static and dynamic 24 | DHCP leases and BOOTP/TFTP for network booting of diskless machines. 25 | 26 | Package: dnsmasq-base 27 | Architecture: any 28 | Depends: adduser, ${shlibs:Depends} 29 | Breaks: dnsmasq (<< 2.63-1~) 30 | Replaces: dnsmasq (<< 2.63-1~) 31 | Recommends: dns-root-data 32 | Description: Small caching DNS proxy and DHCP/TFTP server 33 | This package contains the dnsmasq executable and documentation, but 34 | not the infrastructure required to run it as a system daemon. For 35 | that, install the dnsmasq package. 36 | 37 | Package: dnsmasq-utils 38 | Architecture: linux-any 39 | Depends: ${shlibs:Depends} 40 | Conflicts: dnsmasq (<<2.40) 41 | Description: Utilities for manipulating DHCP leases 42 | Small utilities to query a DHCP server's lease database and 43 | remove leases from it. These programs are distributed with dnsmasq 44 | and may not work correctly with other DHCP servers. 45 | 46 | 47 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | dnsmasq is Copyright (c) 2000-2015 Simon Kelley 2 | 3 | It was downloaded from: http://www.thekelleys.org.uk/dnsmasq/ 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; version 2 dated June, 1991, or 8 | (at your option) version 3 dated 29 June, 2007. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | On Debian GNU/Linux systems, the text of the GNU general public license is 16 | available in the file /usr/share/common-licenses/GPL-2 or 17 | /usr/share/common-licenses/GPL-3 18 | 19 | The Debian package of dnsmasq was created by Simon Kelley with assistance 20 | from Lars Bahner. 21 | 22 | -------------------------------------------------------------------------------- /debian/dbus.conf: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /debian/default: -------------------------------------------------------------------------------- 1 | # This file has five functions: 2 | # 1) to completely disable starting dnsmasq, 3 | # 2) to set DOMAIN_SUFFIX by running `dnsdomainname` 4 | # 3) to select an alternative config file 5 | # by setting DNSMASQ_OPTS to --conf-file= 6 | # 4) to tell dnsmasq to read the files in /etc/dnsmasq.d for 7 | # more configuration variables. 8 | # 5) to stop the resolvconf package from controlling dnsmasq's 9 | # idea of which upstream nameservers to use. 10 | # For upgraders from very old versions, all the shell variables set 11 | # here in previous versions are still honored by the init script 12 | # so if you just keep your old version of this file nothing will break. 13 | 14 | #DOMAIN_SUFFIX=`dnsdomainname` 15 | #DNSMASQ_OPTS="--conf-file=/etc/dnsmasq.alt" 16 | 17 | # Whether or not to run the dnsmasq daemon; set to 0 to disable. 18 | ENABLED=1 19 | 20 | # By default search this drop directory for configuration options. 21 | # Libvirt leaves a file here to make the system dnsmasq play nice. 22 | # Comment out this line if you don't want this. The dpkg-* are file 23 | # endings which cause dnsmasq to skip that file. This avoids pulling 24 | # in backups made by dpkg. 25 | CONFIG_DIR=/etc/dnsmasq.d,.dpkg-dist,.dpkg-old,.dpkg-new 26 | 27 | # If the resolvconf package is installed, dnsmasq will use its output 28 | # rather than the contents of /etc/resolv.conf to find upstream 29 | # nameservers. Uncommenting this line inhibits this behaviour. 30 | # Note that including a "resolv-file=" line in 31 | # /etc/dnsmasq.conf is not enough to override resolvconf if it is 32 | # installed: the line below must be uncommented. 33 | #IGNORE_RESOLVCONF=yes 34 | -------------------------------------------------------------------------------- /debian/dnsmasq-base.conffiles: -------------------------------------------------------------------------------- 1 | /etc/dbus-1/system.d/dnsmasq.conf 2 | -------------------------------------------------------------------------------- /debian/dnsmasq-base.postinst: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | # Create the dnsmasq user in dnsmasq-base, so that Dbus doesn't complain. 5 | 6 | # create a user to run as (code stolen from dovecot-common) 7 | if [ "$1" = "configure" ]; then 8 | if [ -z "`id -u dnsmasq 2> /dev/null`" ]; then 9 | adduser --system --home /var/lib/misc --gecos "dnsmasq" \ 10 | --no-create-home --disabled-password \ 11 | --quiet dnsmasq || true 12 | fi 13 | 14 | # Make the directory where we keep the pid file - this 15 | # has to be owned by "dnsmasq" so that the file can be unlinked. 16 | # This is only actually used by the dnsmasq binary package, not 17 | # dnsmasq-base, but it's much easier to create it here so that 18 | # we don't have synchronisation issues with the creation of the 19 | # dnsmasq user. 20 | if [ ! -d /var/run/dnsmasq ]; then 21 | mkdir /var/run/dnsmasq 22 | chown dnsmasq:nogroup /var/run/dnsmasq 23 | fi 24 | fi 25 | -------------------------------------------------------------------------------- /debian/dnsmasq-base.postrm: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | if [ purge = "$1" ]; then 5 | if [ -x "$(command -v deluser)" ]; then 6 | deluser --quiet --system dnsmasq > /dev/null || true 7 | else 8 | echo >&2 "not removing dnsmasq system account because deluser command was not found" 9 | fi 10 | rm -rf /var/run/dnsmasq 11 | fi 12 | -------------------------------------------------------------------------------- /debian/insserv: -------------------------------------------------------------------------------- 1 | $named dnsmasq 2 | -------------------------------------------------------------------------------- /debian/postinst: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | # Code copied from dh_systemd_enable ---------------------- 5 | # This will only remove masks created by d-s-h on package removal. 6 | deb-systemd-helper unmask dnsmasq.service >/dev/null || true 7 | 8 | # was-enabled defaults to true, so new installations run enable. 9 | if deb-systemd-helper --quiet was-enabled dnsmasq.service; then 10 | # Enables the unit on first installation, creates new 11 | # symlinks on upgrades if the unit file has changed. 12 | deb-systemd-helper enable dnsmasq.service >/dev/null || true 13 | else 14 | # Update the statefile to add new symlinks (if any), which need to be 15 | # cleaned up on purge. Also remove old symlinks. 16 | deb-systemd-helper update-state dnsmasq.service >/dev/null || true 17 | fi 18 | # End code copied from dh_systemd_enable ------------------ 19 | 20 | if [ -x /etc/init.d/dnsmasq ]; then 21 | update-rc.d dnsmasq defaults 15 85 >/dev/null 22 | 23 | if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ]; then 24 | if [ -e /var/run/dnsmasq/dnsmasq.pid ]; then 25 | ACTION=restart 26 | else 27 | ACTION=start 28 | fi 29 | 30 | if [ -x /usr/sbin/invoke-rc.d ] ; then 31 | invoke-rc.d dnsmasq $ACTION || true 32 | else 33 | /etc/init.d/dnsmasq $ACTION || true 34 | fi 35 | fi 36 | fi 37 | 38 | 39 | -------------------------------------------------------------------------------- /debian/postrm: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | if [ purge = "$1" ]; then 5 | update-rc.d dnsmasq remove >/dev/null 6 | fi 7 | 8 | # Code copied from dh_systemd_enable ---------------------- 9 | if [ "$1" = "remove" ]; then 10 | if [ -x "/usr/bin/deb-systemd-helper" ]; then 11 | deb-systemd-helper mask dnsmasq.service >/dev/null 12 | fi 13 | fi 14 | 15 | if [ "$1" = "purge" ]; then 16 | if [ -x "/usr/bin/deb-systemd-helper" ]; then 17 | deb-systemd-helper purge dnsmasq.service >/dev/null 18 | deb-systemd-helper unmask dnsmasq.service >/dev/null 19 | fi 20 | fi 21 | # End code copied from dh_systemd_enable ------------------ 22 | 23 | -------------------------------------------------------------------------------- /debian/prerm: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | if [ "$1" = "remove" ]; then 5 | if [ -x /usr/sbin/invoke-rc.d ] ; then 6 | invoke-rc.d dnsmasq stop || true 7 | else 8 | /etc/init.d/dnsmasq stop || true 9 | fi 10 | fi 11 | 12 | exit 0 13 | 14 | 15 | -------------------------------------------------------------------------------- /debian/readme: -------------------------------------------------------------------------------- 1 | Notes on configuring dnsmasq as packaged for Debian. 2 | 3 | (1) To configure dnsmasq edit /etc/dnsmasq.conf. The file is well 4 | commented; see also the dnsmasq.8 man page for explanation of 5 | the options. The file /etc/default/dnsmasq also exists but it 6 | shouldn't need to be touched in most cases. To set up DHCP 7 | options you might need to refer to a copy of RFC 2132. This is 8 | available on Debian systems in the package doc-rfc-std as the file 9 | /usr/share/doc/RFC/draft-standard/rfc2132.txt.gz . 10 | 11 | (2) Installing the dnsmasq package also creates the directory 12 | /etc/dnsmasq.d which is searched by dnsmasq for configuration file 13 | fragments. This behaviour can be disabled by editing 14 | /etc/default/dnsmasq. 15 | 16 | (3) If the Debian resolvconf package is installed then, regardless 17 | of what interface configuration daemons are employed, the list of 18 | nameservers to which dnsmasq should forward queries can be found 19 | in /var/run/dnsmasq/resolv.conf; also, 127.0.0.1 is listed as the 20 | first nameserver address in /etc/resolv.conf. This works using the 21 | default configurations of resolvconf and dnsmasq. 22 | 23 | (4) In the absence of resolvconf, if you are using dhcpcd then 24 | dnsmasq should read the list of nameservers from the automatically 25 | generated file /etc/dhcpc/resolv.conf. You should list 127.0.0.1 26 | as the first nameserver address in /etc/resolv.conf. 27 | 28 | (5) In the absence of resolvconf, if you are using pppd then 29 | dnsmasq should read the list of nameservers from the automatically 30 | generated file /etc/ppp/resolv.conf. You should list 127.0.0.1 31 | as the first nameserver address in /etc/resolv.conf. 32 | 33 | (6) In the absence of resolvconf, dns-nameservers lines in 34 | /etc/network/interfaces are ignored. If you do do not use 35 | resolvconf, list 127.0.0.1 as the first nameserver address 36 | in /etc/resolv.conf and configure your nameservers using 37 | "server=" lines in /etc/dnsmasq.conf. 38 | 39 | (7) If you run multiple DNS servers on a single machine, each 40 | listening on a different interface, then it is necessary to use 41 | the bind-interfaces option by uncommenting "bind-interfaces" in 42 | /etc/dnsmasq.conf. This option stops dnsmasq from binding the 43 | wildcard address and allows servers listening on port 53 on 44 | interfaces not in use by dnsmasq to work. The Debian 45 | libvirt package will add a configuration file in /etc/dnsmasq.d 46 | which does this so that the "system" dnsmasq and "private" dnsmasq 47 | instances started by libvirt do not clash. 48 | 49 | (8) The following options are supported in DEB_BUILD_OPTIONS 50 | noopt : compile without optimisation. 51 | nostrip : don't remove symbols from binary. 52 | nodocs : omit documentation. 53 | notftp : omit TFTP support. 54 | nodhcp : omit DHCP support. 55 | nodhcp6 : omit DHCPv6 support. 56 | noscript : omit lease-change script support. 57 | use_lua : provide support for lease-change scripts written 58 | in Lua. 59 | noipv6 : omit IPv6 support. 60 | nodbus : omit DBus support. 61 | noconntrack : omit connection tracking support. 62 | noipset : omit IPset support. 63 | nortc : compile alternate mode suitable for systems without an RTC. 64 | noi18n : omit translations and internationalisation support. 65 | noidn : omit international domain name support, must be 66 | combined with noi18n to be effective. 67 | gitversion : set the version of the produced packages from the 68 | git-derived versioning information on the source, 69 | rather the the debian changelog. 70 | 71 | (9) Dnsmasq comes as three packages - dnsmasq-utils, dnsmasq-base and 72 | dnsmasq. Dnsmasq-base provides the dnsmasq executable and 73 | documentation (including this file). Dnsmasq, which depends on 74 | dnsmasq-base, provides the init script and configuration 75 | infrastructure. This file assumes that both are installed. It is 76 | possible to install only dnsmasq-base and use dnsmasq as a 77 | non-"system" daemon. Libvirt, for instance, does this. 78 | Dnsmasq-utils provides the utilities dhcp_release and 79 | dhcp_lease_time. 80 | -------------------------------------------------------------------------------- /debian/readme.dnsmasq.d: -------------------------------------------------------------------------------- 1 | # All files in this directory will be read by dnsmasq as 2 | # configuration files, except if their names end in 3 | # ".dpkg-dist",".dpkg-old" or ".dpkg-new" 4 | # 5 | # This can be changed by editing /etc/default/dnsmasq 6 | 7 | 8 | -------------------------------------------------------------------------------- /debian/resolvconf: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Script to update the resolver list for dnsmasq 4 | # 5 | # N.B. Resolvconf may run us even if dnsmasq is not (yet) running. 6 | # If dnsmasq is installed then we go ahead and update the resolver list 7 | # in case dnsmasq is started later. 8 | # 9 | # Assumption: On entry, PWD contains the resolv.conf-type files. 10 | # 11 | # This file is part of the dnsmasq package. 12 | # 13 | 14 | set -e 15 | 16 | RUN_DIR="/var/run/dnsmasq" 17 | RSLVRLIST_FILE="${RUN_DIR}/resolv.conf" 18 | TMP_FILE="${RSLVRLIST_FILE}_new.$$" 19 | MY_NAME_FOR_RESOLVCONF="dnsmasq" 20 | 21 | [ -x /usr/sbin/dnsmasq ] || exit 0 22 | [ -x /lib/resolvconf/list-records ] || exit 1 23 | 24 | PATH=/bin:/sbin 25 | 26 | report_err() { echo "$0: Error: $*" >&2 ; } 27 | 28 | # Stores arguments (minus duplicates) in RSLT, separated by spaces 29 | # Doesn't work properly if an argument itself contains whitespace 30 | uniquify() 31 | { 32 | RSLT="" 33 | while [ "$1" ] ; do 34 | for E in $RSLT ; do 35 | [ "$1" = "$E" ] && { shift ; continue 2 ; } 36 | done 37 | RSLT="${RSLT:+$RSLT }$1" 38 | shift 39 | done 40 | } 41 | 42 | if [ ! -d "$RUN_DIR" ] && ! mkdir --parents --mode=0755 "$RUN_DIR" ; then 43 | report_err "Failed trying to create directory $RUN_DIR" 44 | exit 1 45 | fi 46 | 47 | RSLVCNFFILES="" 48 | for F in $(/lib/resolvconf/list-records --after "lo.$MY_NAME_FOR_RESOLVCONF") ; do 49 | case "$F" in 50 | "lo.$MY_NAME_FOR_RESOLVCONF") 51 | # Omit own record 52 | ;; 53 | lo.*) 54 | # Include no more records after one for a local nameserver 55 | RSLVCNFFILES="${RSLVCNFFILES:+$RSLVCNFFILES }$F" 56 | break 57 | ;; 58 | *) 59 | RSLVCNFFILES="${RSLVCNFFILES:+$RSLVCNFFILES }$F" 60 | ;; 61 | esac 62 | done 63 | 64 | NMSRVRS="" 65 | if [ "$RSLVCNFFILES" ] ; then 66 | uniquify $(sed -n -e 's/^[[:space:]]*nameserver[[:space:]]\+//p' $RSLVCNFFILES) 67 | NMSRVRS="$RSLT" 68 | fi 69 | 70 | # Dnsmasq uses the mtime of $RSLVRLIST_FILE, with a resolution of one second, 71 | # to detect changes in the file. This means that if a resolvconf update occurs 72 | # within one second of the previous one then dnsmasq may fail to notice the 73 | # more recent change. To work around this problem we sleep one second here 74 | # if necessary in order to ensure that the new mtime is different. 75 | if [ -f "$RSLVRLIST_FILE" ] && [ "$(ls -go --time-style='+%s' "$RSLVRLIST_FILE" | { read p h s t n ; echo "$t" ; })" = "$(date +%s)" ] ; then 76 | sleep 1 77 | fi 78 | 79 | clean_up() { rm -f "$TMP_FILE" ; } 80 | trap clean_up EXIT 81 | : >| "$TMP_FILE" 82 | for N in $NMSRVRS ; do echo "nameserver $N" >> "$TMP_FILE" ; done 83 | mv -f "$TMP_FILE" "$RSLVRLIST_FILE" 84 | 85 | -------------------------------------------------------------------------------- /debian/resolvconf-package: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Resolvconf packaging event hook script for the dnsmasq package 3 | restart_dnsmasq() { 4 | if which invoke-rc.d >/dev/null 2>&1 ; then 5 | invoke-rc.d dnsmasq restart 6 | elif [ -x /etc/init.d/dnsmasq ] ; then 7 | /etc/init.d/dnsmasq restart 8 | fi 9 | } 10 | 11 | case "$1" in 12 | install) restart_dnsmasq ;; 13 | esac 14 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # debian/rules file - for dnsmasq. 3 | # Copyright 2001-2011 by Simon Kelley 4 | # Based on the sample in the debian hello package which carries the following: 5 | # Copyright 1994,1995 by Ian Jackson. 6 | # I hereby give you perpetual unlimited permission to copy, 7 | # modify and relicense this file, provided that you do not remove 8 | # my name from the file itself. (I assert my moral right of 9 | # paternity under the Copyright, Designs and Patents Act 1988.) 10 | # This file may have to be extensively modified 11 | 12 | package=dnsmasq-base 13 | 14 | dpkg_buildflags := DEB_BUILD_MAINT_OPTIONS="hardening=+all" dpkg-buildflags 15 | 16 | CFLAGS = $(shell $(dpkg_buildflags) --get CFLAGS) 17 | CFLAGS += $(shell $(dpkg_buildflags) --get CPPFLAGS) 18 | CFLAGS += -Wall -W 19 | 20 | LDFLAGS = $(shell $(dpkg_buildflags) --get LDFLAGS) 21 | 22 | DEB_COPTS = $(COPTS) 23 | 24 | TARGET = install-i18n 25 | 26 | DEB_HOST_ARCH_OS := $(shell dpkg-architecture -qDEB_HOST_ARCH_OS) 27 | 28 | # Force package version based on git tags. 29 | ifneq (,$(filter gitversion,$(DEB_BUILD_OPTIONS))) 30 | PACKAGE_VERSION = $(shell bld/get-version `pwd` | sed 's/test/~&/; s/[a-z]/~&/; s/-/./g; s/$$/-1/; s/^/-v/';) 31 | endif 32 | 33 | ifeq (,$(filter nodbus,$(DEB_BUILD_OPTIONS))) 34 | DEB_COPTS += -DHAVE_DBUS 35 | endif 36 | 37 | ifeq (,$(filter noconntrack,$(DEB_BUILD_OPTIONS))) 38 | ifeq ($(DEB_HOST_ARCH_OS),linux) 39 | DEB_COPTS += -DHAVE_CONNTRACK 40 | endif 41 | endif 42 | 43 | ifneq (,$(filter noipset,$(DEB_BUILD_OPTIONS))) 44 | DEB_COPTS += -DNO_IPSET 45 | endif 46 | 47 | ifneq (,$(filter nodhcp6,$(DEB_BUILD_OPTIONS))) 48 | DEB_COPTS += -DNO_DHCP6 49 | endif 50 | 51 | ifneq (,$(filter noipv6,$(DEB_BUILD_OPTIONS))) 52 | DEB_COPTS += -DNO_IPV6 53 | endif 54 | 55 | ifneq (,$(filter notftp,$(DEB_BUILD_OPTIONS))) 56 | DEB_COPTS += -DNO_TFTP 57 | endif 58 | 59 | ifneq (,$(filter nodhcp,$(DEB_BUILD_OPTIONS))) 60 | DEB_COPTS += -DNO_DHCP 61 | endif 62 | 63 | ifneq (,$(filter noscript,$(DEB_BUILD_OPTIONS))) 64 | DEB_COPTS += -DNO_SCRIPT 65 | endif 66 | 67 | ifneq (,$(filter nortc,$(DEB_BUILD_OPTIONS))) 68 | DEB_COPTS += -DHAVE_BROKEN_RTC 69 | endif 70 | 71 | ifneq (,$(filter noi18n,$(DEB_BUILD_OPTIONS))) 72 | TARGET = install 73 | ifeq (,$(filter noidn, $(DEB_BUILD_OPTIONS))) 74 | DEB_COPTS += -DHAVE_IDN 75 | endif 76 | endif 77 | 78 | ifneq (,$(filter uselua,$(DEB_BUILD_OPTIONS))) 79 | DEB_COPTS += -DHAVE_LUASCRIPT 80 | endif 81 | 82 | ifeq (,$(filter nodnssec,$(DEB_BUILD_OPTIONS))) 83 | DEB_COPTS += -DHAVE_DNSSEC 84 | endif 85 | 86 | ifneq ($(DEB_HOST_ARCH_OS),linux) 87 | # For strlcpy in FreeBSD 88 | LDFLAGS += -lbsd 89 | endif 90 | 91 | clean: 92 | $(checkdir) 93 | rm -rf debian/daemon debian/base debian/utils debian/*~ debian/files debian/substvars debian/utils-substvars 94 | make clean 95 | make -C contrib/wrt clean 96 | 97 | binary-indep: checkroot 98 | $(checkdir) 99 | rm -rf debian/daemon 100 | install -m 755 \ 101 | -d debian/daemon/DEBIAN \ 102 | -d debian/daemon/usr/share/doc \ 103 | -d debian/daemon/etc/init.d \ 104 | -d debian/daemon/etc/dnsmasq.d \ 105 | -d debian/daemon/etc/resolvconf/update.d \ 106 | -d debian/daemon/usr/lib/resolvconf/dpkg-event.d \ 107 | -d debian/daemon/etc/default \ 108 | -d debian/daemon/lib/systemd/system \ 109 | -d debian/daemon/etc/insserv.conf.d 110 | install -m 644 debian/conffiles debian/daemon/DEBIAN 111 | install -m 755 debian/postinst debian/postrm debian/prerm debian/daemon/DEBIAN 112 | install -m 755 debian/init debian/daemon/etc/init.d/dnsmasq 113 | install -m 755 debian/resolvconf debian/daemon/etc/resolvconf/update.d/dnsmasq 114 | install -m 755 debian/resolvconf-package debian/daemon/usr/lib/resolvconf/dpkg-event.d/dnsmasq 115 | install -m 644 debian/default debian/daemon/etc/default/dnsmasq 116 | install -m 644 dnsmasq.conf.example debian/daemon/etc/dnsmasq.conf 117 | install -m 644 debian/readme.dnsmasq.d debian/daemon/etc/dnsmasq.d/README 118 | install -m 644 debian/systemd.service debian/daemon/lib/systemd/system/dnsmasq.service 119 | install -m 644 debian/insserv debian/daemon/etc/insserv.conf.d/dnsmasq 120 | ln -s $(package) debian/daemon/usr/share/doc/dnsmasq 121 | cd debian/daemon && find . -type f ! -regex '.*DEBIAN/.*' -printf '%P\0' | xargs -r0 md5sum > DEBIAN/md5sums 122 | dpkg-gencontrol $(PACKAGE_VERSION) -T -pdnsmasq -Pdebian/daemon 123 | chown -R root.root debian/daemon 124 | chmod -R g-ws debian/daemon 125 | dpkg --build debian/daemon .. 126 | 127 | binary-arch: checkroot 128 | $(checkdir) 129 | rm -rf debian/base 130 | install -m 755 \ 131 | -d debian/base/DEBIAN \ 132 | -d debian/base/etc/dbus-1/system.d \ 133 | -d debian/base/usr/share/doc/$(package) \ 134 | -d debian/base/usr/share/doc/$(package)/examples \ 135 | -d debian/base/var/run \ 136 | -d debian/base/usr/share/$(package) \ 137 | -d debian/base/var/lib/misc 138 | make $(TARGET) PREFIX=/usr DESTDIR=`pwd`/debian/base CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" COPTS="$(DEB_COPTS)" CC=gcc 139 | ifeq (,$(findstring nodocs,$(DEB_BUILD_OPTIONS))) 140 | # Need to remove paypal links in Debian Package for policy reasons. 141 | sed -e /\Donations/Q -e /icon.png/d doc.html -e /favicon.ico/d >debian/base/usr/share/doc/$(package)/doc.html 142 | echo "" >>debian/base/usr/share/doc/$(package)/doc.html 143 | install -m 644 setup.html debian/base/usr/share/doc/$(package)/. 144 | install -m 644 dnsmasq.conf.example debian/base/usr/share/doc/$(package)/examples/. 145 | install -m 644 trust-anchors.conf debian/base/usr/share/$(package)/. 146 | install -m 644 FAQ debian/base/usr/share/doc/$(package)/. 147 | gzip -9 debian/base/usr/share/doc/$(package)/FAQ 148 | install -m 644 CHANGELOG debian/base/usr/share/doc/$(package)/changelog 149 | gzip -9 debian/base/usr/share/doc/$(package)/changelog 150 | install -m 644 CHANGELOG.archive debian/base/usr/share/doc/$(package)/changelog.archive 151 | gzip -9 debian/base/usr/share/doc/$(package)/changelog.archive 152 | install -m 644 dbus/DBus-interface debian/base/usr/share/doc/$(package)/. 153 | gzip -9 debian/base/usr/share/doc/$(package)/DBus-interface 154 | endif 155 | install -m 644 debian/dnsmasq-base.conffiles debian/base/DEBIAN/conffiles 156 | install -m 755 debian/dnsmasq-base.postinst debian/base/DEBIAN/postinst 157 | install -m 755 debian/dnsmasq-base.postrm debian/base/DEBIAN/postrm 158 | install -m 644 debian/changelog debian/base/usr/share/doc/$(package)/changelog.Debian 159 | gzip -9 debian/base/usr/share/doc/$(package)/changelog.Debian 160 | install -m 644 debian/readme debian/base/usr/share/doc/$(package)/README.Debian 161 | install -m 644 debian/copyright debian/base/usr/share/doc/$(package)/copyright 162 | install -m 644 debian/dbus.conf debian/base/etc/dbus-1/system.d/dnsmasq.conf 163 | gzip -9 debian/base/usr/share/man/man8/dnsmasq.8 164 | for f in debian/base/usr/share/man/*; do \ 165 | if [ -f $$f/man8/dnsmasq.8 ]; then \ 166 | gzip -9 $$f/man8/dnsmasq.8 ; \ 167 | fi \ 168 | done 169 | ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS))) 170 | strip -R .note -R .comment debian/base/usr/sbin/dnsmasq 171 | endif 172 | cd debian/base && find . -type f ! -regex '.*DEBIAN/.*' -printf '%P\0' | xargs -r0 md5sum > DEBIAN/md5sums 173 | dpkg-shlibdeps --warnings=1 debian/base/usr/sbin/dnsmasq 174 | dpkg-gencontrol $(PACKAGE_VERSION) -pdnsmasq-base -Pdebian/base 175 | chown -R root.root debian/base 176 | chmod -R g-ws debian/base 177 | dpkg --build debian/base .. 178 | 179 | ifeq ($(DEB_HOST_ARCH_OS),linux) 180 | rm -rf debian/utils 181 | install -m 755 -d debian/utils/DEBIAN \ 182 | -d debian/utils/usr/share/man/man1 \ 183 | -d debian/utils/usr/bin \ 184 | -d debian/utils/usr/share/doc/dnsmasq-utils 185 | make -C contrib/wrt PREFIX=/usr DESTDIR=`pwd`/debian/utils CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" COPTS="$(DEB_COPTS)" CC=gcc 186 | install -m 755 contrib/wrt/dhcp_release debian/utils/usr/bin/dhcp_release 187 | install -m 644 contrib/wrt/dhcp_release.1 debian/utils/usr/share/man/man1/dhcp_release.1 188 | gzip -9 debian/utils/usr/share/man/man1/dhcp_release.1 189 | install -m 755 contrib/wrt/dhcp_lease_time debian/utils/usr/bin/dhcp_lease_time 190 | install -m 644 contrib/wrt/dhcp_lease_time.1 debian/utils/usr/share/man/man1/dhcp_lease_time.1 191 | install -m 644 debian/copyright debian/utils/usr/share/doc/dnsmasq-utils/copyright 192 | install -m 644 debian/changelog debian/utils/usr/share/doc/dnsmasq-utils/changelog.Debian 193 | gzip -9 debian/utils/usr/share/doc/dnsmasq-utils/changelog.Debian 194 | gzip -9 debian/utils/usr/share/man/man1/dhcp_lease_time.1 195 | ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS))) 196 | strip -R .note -R .comment debian/utils/usr/bin/dhcp_release 197 | strip -R .note -R .comment debian/utils/usr/bin/dhcp_lease_time 198 | endif 199 | cd debian/utils && find . -type f ! -regex '.*DEBIAN/.*' -printf '%P\0' | xargs -r0 md5sum > DEBIAN/md5sums 200 | dpkg-shlibdeps -Tdebian/utils-substvars debian/utils/usr/bin/dhcp_release debian/utils/usr/bin/dhcp_lease_time 201 | dpkg-gencontrol $(PACKAGE_VERSION) -Tdebian/utils-substvars -pdnsmasq-utils -Pdebian/utils 202 | chown -R root.root debian/utils 203 | chmod -R g-ws debian/utils 204 | dpkg --build debian/utils .. 205 | endif 206 | 207 | define checkdir 208 | test -f Makefile -a -f debian/rules 209 | endef 210 | 211 | # Below here is fairly generic really 212 | 213 | binary: binary-arch binary-indep 214 | 215 | build: 216 | build-arch: 217 | build-indep: 218 | 219 | checkroot: 220 | test root = "`whoami`" 221 | 222 | .PHONY: binary binary-arch binary-indep clean checkroot 223 | 224 | 225 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 1.0 2 | -------------------------------------------------------------------------------- /debian/systemd.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=dnsmasq - A lightweight DHCP and caching DNS server 3 | 4 | [Service] 5 | Type=dbus 6 | BusName=uk.org.thekelleys.dnsmasq 7 | 8 | # Test the config file and refuse starting if it is not valid. 9 | ExecStartPre=/usr/sbin/dnsmasq --test 10 | 11 | # We run dnsmasq via the /etc/init.d/dnsmasq script which acts as a 12 | # wrapper picking up extra configuration files and then execs dnsmasq 13 | # itself, when called with the "systemd-exec" function. 14 | # 15 | # It also adds the command-line flags 16 | # --keep-in-foreground --enable-dbus 17 | # to enable DBus by default because we use DBus activation. 18 | # 19 | ExecStart=/etc/init.d/dnsmasq systemd-exec 20 | 21 | # The systemd-*-resolvconf functions configure (and deconfigure) 22 | # resolvconf to work with the dnsmasq DNS server. They're called liek 23 | # this to get correct error handling (ie don't start-resolvconf if the 24 | # dnsmasq daemon fails to start. 25 | ExecStartPost=/etc/init.d/dnsmasq systemd-start-resolvconf 26 | ExecStop=/etc/init.d/dnsmasq systemd-stop-resolvconf 27 | 28 | 29 | ExecReload=/bin/kill -HUP $MAINPID 30 | 31 | [Install] 32 | WantedBy=multi-user.target 33 | -------------------------------------------------------------------------------- /doc.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dnsmasq - network services for small networks. 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |

Dnsmasq

13 | Dnsmasq provides network infrastructure for small networks: DNS, DHCP, router advertisement and network boot. It is designed to be 14 | lightweight and have a small footprint, suitable for resource constrained routers and firewalls. It has also been widely used 15 | for tethering on smartphones and portable hotspots, and to support virtual networking in virtualisation frameworks. 16 | Supported platforms include Linux (with glibc and uclibc), Android, *BSD, and Mac OS X. Dnsmasq is included in most 17 | Linux distributions and the ports systems of FreeBSD, OpenBSD and NetBSD. Dnsmasq provides full IPv6 support. 18 | 19 |

20 | The DNS subsystem provides a local DNS server for the network, with forwarding of all query types to upstream recursive DNS servers and 21 | cacheing of common record types (A, AAAA, CNAME and PTR, also DNSKEY and DS when DNSSEC is enabled). 22 |

23 |
  • Local DNS names can be defined by reading /etc/hosts, by importing names from the DHCP subsystem, or by configuration of a wide range of useful record types.
  • 24 |
  • Upstream servers can be configured in a variety of convenient ways, including dynamic configuration as these change on moving upstream network. 25 |
  • Authoritative DNS mode allows local DNS names may be exported to zone in the global DNS. Dnsmasq acts as authoritative server for this zone, and also provides 26 | zone transfer to secondaries for the zone, if required.
  • 27 |
  • DNSSEC validation may be performed on DNS replies from upstream nameservers, providing security against spoofing and cache poisoning.
  • 28 |
  • Specified sub-domains can be directed to their own upstream DNS servers, making VPN configuration easy.
  • 29 |
  • Internationalised domain names are supported. 30 |
  • 31 |

    32 | The DHCP subsystem supports DHCPv4, DHCPv6, BOOTP and PXE. 33 |

    34 |
  • Both static and dynamic DHCP leases are supported, along with stateless mode in DHCPv6.
  • 35 |
  • The PXE system is a full PXE server, supporting netboot menus and multiple architecture support. It 36 | includes proxy-mode, where the PXE system co-operates with another DHCP server.
  • 37 |
  • There is a built in read-only TFTP server to support netboot.
  • 38 |
  • Machines which are configured by DHCP have their names automatically 39 | included in the DNS and the names can specified by each machine or 40 | centrally by associating a name with a MAC address or UID in the dnsmasq 41 | configuration file.
  • 42 |
    43 |

    44 | The Router Advertisement subsystem provides basic autoconfiguration for IPv6 hosts. It can be used stand-alone or in conjunction with DHCPv6. 45 |

    46 |
  • The M and O bits are configurable, to control hosts' use of DHCPv6.
  • 47 |
  • Router advertisements can include the RDNSS option.
  • 48 |
  • There is a mode which uses name information from DHCPv4 configuration to provide DNS entries 49 | for autoconfigured IPv6 addresses which would otherwise be anonymous.
  • 50 |
    51 |

    52 | 53 | For extra compactness, unused features may be omitted at compile time. 54 | 55 | 56 |

    Get code.

    57 | 58 | Download dnsmasq here. 59 | The tarball includes this documentation, source, and manpage. 60 | There is also a CHANGELOG and a FAQ. 61 | 62 | Dnsmasq has a git repository which contains the complete release 63 | history of version 2 and development history from 2.60. You can 64 | browse 65 | the repo, or get a copy using git protocol with the command 66 | 67 |
    git clone git://thekelleys.org.uk/dnsmasq.git 
    68 | 69 |

    License.

    70 | Dnsmasq is distributed under the GPL, version 2 or version 3 at your discretion. See the files COPYING and COPYING-v3 in the distribution 71 | for details. 72 | 73 |

    Contact.

    74 | There is a dnsmasq mailing list at 76 | http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss which should be the 77 | first location for queries, bugreports, suggestions etc. 78 | You can contact me at simon@thekelleys.org.uk. 80 | 81 |

    Donations.

    82 | Dnsmasq is mainly written and maintained by Simon Kelley. For most of its life, dnsmasq has been a spare-time project. 83 | These days I'm working on it as my main activity. 84 | I don't have an employer or anyone who pays me regularly to work on dnsmasq. If you'd like to make 85 | a contribution towards my expenses, please use the donation button below. 86 |
    87 | 88 | 89 | 90 | 91 |
    92 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /logo/README: -------------------------------------------------------------------------------- 1 | Dnsmasq logo, contributed by Justin Clift. 2 | 3 | The source format is Inkscape SVG vector format, which is scalable and 4 | easy to export to other formats. For convenience I've included a 56x31 5 | png export and a 16x16 ico suitable for use as a web favicon. 6 | 7 | Simon Kelley, 22/10/2010 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /logo/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infinet/dnsmasq/611fd4ac2d51ef3df22a32669466efc1109205c7/logo/favicon.ico -------------------------------------------------------------------------------- /logo/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infinet/dnsmasq/611fd4ac2d51ef3df22a32669466efc1109205c7/logo/icon.png -------------------------------------------------------------------------------- /logo/icon.svg: -------------------------------------------------------------------------------- 1 | 2 | image/svg+xml 35 | 47 | 110 | 123 | 128 | 133 | 136 | 143 | 147 | 151 | 152 | 157 | -------------------------------------------------------------------------------- /man/es/dnsmasq.8: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infinet/dnsmasq/611fd4ac2d51ef3df22a32669466efc1109205c7/man/es/dnsmasq.8 -------------------------------------------------------------------------------- /po/es.po: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infinet/dnsmasq/611fd4ac2d51ef3df22a32669466efc1109205c7/po/es.po -------------------------------------------------------------------------------- /po/fr.po: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infinet/dnsmasq/611fd4ac2d51ef3df22a32669466efc1109205c7/po/fr.po -------------------------------------------------------------------------------- /po/no.po: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infinet/dnsmasq/611fd4ac2d51ef3df22a32669466efc1109205c7/po/no.po -------------------------------------------------------------------------------- /src/blockdata.c: -------------------------------------------------------------------------------- 1 | /* dnsmasq is Copyright (c) 2000-2015 Simon Kelley 2 | 3 | This program is free software; you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation; version 2 dated June, 1991, or 6 | (at your option) version 3 dated 29 June, 2007. 7 | 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with this program. If not, see . 15 | */ 16 | 17 | #include "dnsmasq.h" 18 | 19 | #ifdef HAVE_DNSSEC 20 | 21 | static struct blockdata *keyblock_free; 22 | static unsigned int blockdata_count, blockdata_hwm, blockdata_alloced; 23 | 24 | static void blockdata_expand(int n) 25 | { 26 | struct blockdata *new = whine_malloc(n * sizeof(struct blockdata)); 27 | 28 | if (n > 0 && new) 29 | { 30 | int i; 31 | 32 | new[n-1].next = keyblock_free; 33 | keyblock_free = new; 34 | 35 | for (i = 0; i < n - 1; i++) 36 | new[i].next = &new[i+1]; 37 | 38 | blockdata_alloced += n; 39 | } 40 | } 41 | 42 | /* Preallocate some blocks, proportional to cachesize, to reduce heap fragmentation. */ 43 | void blockdata_init(void) 44 | { 45 | keyblock_free = NULL; 46 | blockdata_alloced = 0; 47 | blockdata_count = 0; 48 | blockdata_hwm = 0; 49 | 50 | /* Note that daemon->cachesize is enforced to have non-zero size if OPT_DNSSEC_VALID is set */ 51 | if (option_bool(OPT_DNSSEC_VALID)) 52 | blockdata_expand((daemon->cachesize * 100) / sizeof(struct blockdata)); 53 | } 54 | 55 | void blockdata_report(void) 56 | { 57 | if (option_bool(OPT_DNSSEC_VALID)) 58 | my_syslog(LOG_INFO, _("DNSSEC memory in use %u, max %u, allocated %u"), 59 | blockdata_count * sizeof(struct blockdata), 60 | blockdata_hwm * sizeof(struct blockdata), 61 | blockdata_alloced * sizeof(struct blockdata)); 62 | } 63 | 64 | struct blockdata *blockdata_alloc(char *data, size_t len) 65 | { 66 | struct blockdata *block, *ret = NULL; 67 | struct blockdata **prev = &ret; 68 | size_t blen; 69 | 70 | while (len > 0) 71 | { 72 | if (!keyblock_free) 73 | blockdata_expand(50); 74 | 75 | if (keyblock_free) 76 | { 77 | block = keyblock_free; 78 | keyblock_free = block->next; 79 | blockdata_count++; 80 | } 81 | else 82 | { 83 | /* failed to alloc, free partial chain */ 84 | blockdata_free(ret); 85 | return NULL; 86 | } 87 | 88 | if (blockdata_hwm < blockdata_count) 89 | blockdata_hwm = blockdata_count; 90 | 91 | blen = len > KEYBLOCK_LEN ? KEYBLOCK_LEN : len; 92 | memcpy(block->key, data, blen); 93 | data += blen; 94 | len -= blen; 95 | *prev = block; 96 | prev = &block->next; 97 | block->next = NULL; 98 | } 99 | 100 | return ret; 101 | } 102 | 103 | void blockdata_free(struct blockdata *blocks) 104 | { 105 | struct blockdata *tmp; 106 | 107 | if (blocks) 108 | { 109 | for (tmp = blocks; tmp->next; tmp = tmp->next) 110 | blockdata_count--; 111 | tmp->next = keyblock_free; 112 | keyblock_free = blocks; 113 | blockdata_count--; 114 | } 115 | } 116 | 117 | /* if data == NULL, return pointer to static block of sufficient size */ 118 | void *blockdata_retrieve(struct blockdata *block, size_t len, void *data) 119 | { 120 | size_t blen; 121 | struct blockdata *b; 122 | void *new, *d; 123 | 124 | static unsigned int buff_len = 0; 125 | static unsigned char *buff = NULL; 126 | 127 | if (!data) 128 | { 129 | if (len > buff_len) 130 | { 131 | if (!(new = whine_malloc(len))) 132 | return NULL; 133 | if (buff) 134 | free(buff); 135 | buff = new; 136 | } 137 | data = buff; 138 | } 139 | 140 | for (d = data, b = block; len > 0 && b; b = b->next) 141 | { 142 | blen = len > KEYBLOCK_LEN ? KEYBLOCK_LEN : len; 143 | memcpy(d, b->key, blen); 144 | d += blen; 145 | len -= blen; 146 | } 147 | 148 | return data; 149 | } 150 | 151 | #endif 152 | -------------------------------------------------------------------------------- /src/conntrack.c: -------------------------------------------------------------------------------- 1 | /* dnsmasq is Copyright (c) 2000-2015 Simon Kelley 2 | 3 | This program is free software; you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation; version 2 dated June, 1991, or 6 | (at your option) version 3 dated 29 June, 2007. 7 | 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with this program. If not, see . 15 | */ 16 | 17 | #include "dnsmasq.h" 18 | 19 | #ifdef HAVE_CONNTRACK 20 | 21 | #include 22 | 23 | static int gotit = 0; /* yuck */ 24 | 25 | static int callback(enum nf_conntrack_msg_type type, struct nf_conntrack *ct, void *data); 26 | 27 | int get_incoming_mark(union mysockaddr *peer_addr, struct all_addr *local_addr, int istcp, unsigned int *markp) 28 | { 29 | struct nf_conntrack *ct; 30 | struct nfct_handle *h; 31 | 32 | gotit = 0; 33 | 34 | if ((ct = nfct_new())) 35 | { 36 | nfct_set_attr_u8(ct, ATTR_L4PROTO, istcp ? IPPROTO_TCP : IPPROTO_UDP); 37 | nfct_set_attr_u16(ct, ATTR_PORT_DST, htons(daemon->port)); 38 | 39 | #ifdef HAVE_IPV6 40 | if (peer_addr->sa.sa_family == AF_INET6) 41 | { 42 | nfct_set_attr_u8(ct, ATTR_L3PROTO, AF_INET6); 43 | nfct_set_attr(ct, ATTR_IPV6_SRC, peer_addr->in6.sin6_addr.s6_addr); 44 | nfct_set_attr_u16(ct, ATTR_PORT_SRC, peer_addr->in6.sin6_port); 45 | nfct_set_attr(ct, ATTR_IPV6_DST, local_addr->addr.addr6.s6_addr); 46 | } 47 | else 48 | #endif 49 | { 50 | nfct_set_attr_u8(ct, ATTR_L3PROTO, AF_INET); 51 | nfct_set_attr_u32(ct, ATTR_IPV4_SRC, peer_addr->in.sin_addr.s_addr); 52 | nfct_set_attr_u16(ct, ATTR_PORT_SRC, peer_addr->in.sin_port); 53 | nfct_set_attr_u32(ct, ATTR_IPV4_DST, local_addr->addr.addr4.s_addr); 54 | } 55 | 56 | 57 | if ((h = nfct_open(CONNTRACK, 0))) 58 | { 59 | nfct_callback_register(h, NFCT_T_ALL, callback, (void *)markp); 60 | if (nfct_query(h, NFCT_Q_GET, ct) == -1) 61 | { 62 | static int warned = 0; 63 | if (!warned) 64 | { 65 | my_syslog(LOG_ERR, _("Conntrack connection mark retrieval failed: %s"), strerror(errno)); 66 | warned = 1; 67 | } 68 | } 69 | nfct_close(h); 70 | } 71 | nfct_destroy(ct); 72 | } 73 | 74 | return gotit; 75 | } 76 | 77 | static int callback(enum nf_conntrack_msg_type type, struct nf_conntrack *ct, void *data) 78 | { 79 | unsigned int *ret = (unsigned int *)data; 80 | *ret = nfct_get_attr_u32(ct, ATTR_MARK); 81 | (void)type; /* eliminate warning */ 82 | gotit = 1; 83 | 84 | return NFCT_CB_CONTINUE; 85 | } 86 | 87 | #endif 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /src/dhcp-protocol.h: -------------------------------------------------------------------------------- 1 | /* dnsmasq is Copyright (c) 2000-2015 Simon Kelley 2 | 3 | This program is free software; you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation; version 2 dated June, 1991, or 6 | (at your option) version 3 dated 29 June, 2007. 7 | 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with this program. If not, see . 15 | */ 16 | #define DHCP_SERVER_PORT 67 17 | #define DHCP_CLIENT_PORT 68 18 | #define DHCP_SERVER_ALTPORT 1067 19 | #define DHCP_CLIENT_ALTPORT 1068 20 | #define PXE_PORT 4011 21 | 22 | #define BOOTREQUEST 1 23 | #define BOOTREPLY 2 24 | #define DHCP_COOKIE 0x63825363 25 | 26 | /* The Linux in-kernel DHCP client silently ignores any packet 27 | smaller than this. Sigh........... */ 28 | #define MIN_PACKETSZ 300 29 | 30 | #define OPTION_PAD 0 31 | #define OPTION_NETMASK 1 32 | #define OPTION_ROUTER 3 33 | #define OPTION_DNSSERVER 6 34 | #define OPTION_HOSTNAME 12 35 | #define OPTION_DOMAINNAME 15 36 | #define OPTION_BROADCAST 28 37 | #define OPTION_VENDOR_CLASS_OPT 43 38 | #define OPTION_REQUESTED_IP 50 39 | #define OPTION_LEASE_TIME 51 40 | #define OPTION_OVERLOAD 52 41 | #define OPTION_MESSAGE_TYPE 53 42 | #define OPTION_SERVER_IDENTIFIER 54 43 | #define OPTION_REQUESTED_OPTIONS 55 44 | #define OPTION_MESSAGE 56 45 | #define OPTION_MAXMESSAGE 57 46 | #define OPTION_T1 58 47 | #define OPTION_T2 59 48 | #define OPTION_VENDOR_ID 60 49 | #define OPTION_CLIENT_ID 61 50 | #define OPTION_SNAME 66 51 | #define OPTION_FILENAME 67 52 | #define OPTION_USER_CLASS 77 53 | #define OPTION_CLIENT_FQDN 81 54 | #define OPTION_AGENT_ID 82 55 | #define OPTION_ARCH 93 56 | #define OPTION_PXE_UUID 97 57 | #define OPTION_SUBNET_SELECT 118 58 | #define OPTION_DOMAIN_SEARCH 119 59 | #define OPTION_SIP_SERVER 120 60 | #define OPTION_VENDOR_IDENT 124 61 | #define OPTION_VENDOR_IDENT_OPT 125 62 | #define OPTION_END 255 63 | 64 | #define SUBOPT_CIRCUIT_ID 1 65 | #define SUBOPT_REMOTE_ID 2 66 | #define SUBOPT_SUBNET_SELECT 5 /* RFC 3527 */ 67 | #define SUBOPT_SUBSCR_ID 6 /* RFC 3393 */ 68 | #define SUBOPT_SERVER_OR 11 /* RFC 5107 */ 69 | 70 | #define SUBOPT_PXE_BOOT_ITEM 71 /* PXE standard */ 71 | #define SUBOPT_PXE_DISCOVERY 6 72 | #define SUBOPT_PXE_SERVERS 8 73 | #define SUBOPT_PXE_MENU 9 74 | #define SUBOPT_PXE_MENU_PROMPT 10 75 | 76 | #define DHCPDISCOVER 1 77 | #define DHCPOFFER 2 78 | #define DHCPREQUEST 3 79 | #define DHCPDECLINE 4 80 | #define DHCPACK 5 81 | #define DHCPNAK 6 82 | #define DHCPRELEASE 7 83 | #define DHCPINFORM 8 84 | 85 | #define BRDBAND_FORUM_IANA 3561 /* Broadband forum IANA enterprise */ 86 | 87 | #define DHCP_CHADDR_MAX 16 88 | 89 | struct dhcp_packet { 90 | u8 op, htype, hlen, hops; 91 | u32 xid; 92 | u16 secs, flags; 93 | struct in_addr ciaddr, yiaddr, siaddr, giaddr; 94 | u8 chaddr[DHCP_CHADDR_MAX], sname[64], file[128]; 95 | u8 options[312]; 96 | }; 97 | -------------------------------------------------------------------------------- /src/dhcp6-protocol.h: -------------------------------------------------------------------------------- 1 | /* dnsmasq is Copyright (c) 2000-2015 Simon Kelley 2 | 3 | This program is free software; you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation; version 2 dated June, 1991, or 6 | (at your option) version 3 dated 29 June, 2007. 7 | 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with this program. If not, see . 15 | */ 16 | 17 | #define DHCPV6_SERVER_PORT 547 18 | #define DHCPV6_CLIENT_PORT 546 19 | 20 | #define ALL_SERVERS "FF05::1:3" 21 | #define ALL_RELAY_AGENTS_AND_SERVERS "FF02::1:2" 22 | 23 | #define DHCP6SOLICIT 1 24 | #define DHCP6ADVERTISE 2 25 | #define DHCP6REQUEST 3 26 | #define DHCP6CONFIRM 4 27 | #define DHCP6RENEW 5 28 | #define DHCP6REBIND 6 29 | #define DHCP6REPLY 7 30 | #define DHCP6RELEASE 8 31 | #define DHCP6DECLINE 9 32 | #define DHCP6RECONFIGURE 10 33 | #define DHCP6IREQ 11 34 | #define DHCP6RELAYFORW 12 35 | #define DHCP6RELAYREPL 13 36 | 37 | #define OPTION6_CLIENT_ID 1 38 | #define OPTION6_SERVER_ID 2 39 | #define OPTION6_IA_NA 3 40 | #define OPTION6_IA_TA 4 41 | #define OPTION6_IAADDR 5 42 | #define OPTION6_ORO 6 43 | #define OPTION6_PREFERENCE 7 44 | #define OPTION6_ELAPSED_TIME 8 45 | #define OPTION6_RELAY_MSG 9 46 | #define OPTION6_AUTH 11 47 | #define OPTION6_UNICAST 12 48 | #define OPTION6_STATUS_CODE 13 49 | #define OPTION6_RAPID_COMMIT 14 50 | #define OPTION6_USER_CLASS 15 51 | #define OPTION6_VENDOR_CLASS 16 52 | #define OPTION6_VENDOR_OPTS 17 53 | #define OPTION6_INTERFACE_ID 18 54 | #define OPTION6_RECONFIGURE_MSG 19 55 | #define OPTION6_RECONF_ACCEPT 20 56 | #define OPTION6_DNS_SERVER 23 57 | #define OPTION6_DOMAIN_SEARCH 24 58 | #define OPTION6_REFRESH_TIME 32 59 | #define OPTION6_REMOTE_ID 37 60 | #define OPTION6_SUBSCRIBER_ID 38 61 | #define OPTION6_FQDN 39 62 | #define OPTION6_CLIENT_MAC 79 63 | 64 | /* replace this with the real number when allocated. 65 | defining this also enables the relevant code. */ 66 | /* #define OPTION6_PREFIX_CLASS 99 */ 67 | 68 | 69 | #define DHCP6SUCCESS 0 70 | #define DHCP6UNSPEC 1 71 | #define DHCP6NOADDRS 2 72 | #define DHCP6NOBINDING 3 73 | #define DHCP6NOTONLINK 4 74 | #define DHCP6USEMULTI 5 75 | 76 | -------------------------------------------------------------------------------- /src/dns-protocol.h: -------------------------------------------------------------------------------- 1 | /* dnsmasq is Copyright (c) 2000-2015 Simon Kelley 2 | 3 | This program is free software; you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation; version 2 dated June, 1991, or 6 | (at your option) version 3 dated 29 June, 2007. 7 | 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with this program. If not, see . 15 | */ 16 | 17 | #define NAMESERVER_PORT 53 18 | #define TFTP_PORT 69 19 | 20 | #define IN6ADDRSZ 16 21 | #define INADDRSZ 4 22 | 23 | #define PACKETSZ 512 /* maximum packet size */ 24 | #define MAXDNAME 1025 /* maximum presentation domain name */ 25 | #define RRFIXEDSZ 10 /* #/bytes of fixed data in r record */ 26 | #define MAXLABEL 63 /* maximum length of domain label */ 27 | 28 | #define NOERROR 0 /* no error */ 29 | #define FORMERR 1 /* format error */ 30 | #define SERVFAIL 2 /* server failure */ 31 | #define NXDOMAIN 3 /* non existent domain */ 32 | #define NOTIMP 4 /* not implemented */ 33 | #define REFUSED 5 /* query refused */ 34 | 35 | #define QUERY 0 /* opcode */ 36 | 37 | #define C_IN 1 /* the arpa internet */ 38 | #define C_CHAOS 3 /* for chaos net (MIT) */ 39 | #define C_HESIOD 4 /* hesiod */ 40 | #define C_ANY 255 /* wildcard match */ 41 | 42 | #define T_A 1 43 | #define T_NS 2 44 | #define T_MD 3 45 | #define T_MF 4 46 | #define T_CNAME 5 47 | #define T_SOA 6 48 | #define T_MB 7 49 | #define T_MG 8 50 | #define T_MR 9 51 | #define T_PTR 12 52 | #define T_MINFO 14 53 | #define T_MX 15 54 | #define T_TXT 16 55 | #define T_RP 17 56 | #define T_AFSDB 18 57 | #define T_RT 21 58 | #define T_SIG 24 59 | #define T_PX 26 60 | #define T_AAAA 28 61 | #define T_NXT 30 62 | #define T_SRV 33 63 | #define T_NAPTR 35 64 | #define T_KX 36 65 | #define T_DNAME 39 66 | #define T_OPT 41 67 | #define T_DS 43 68 | #define T_RRSIG 46 69 | #define T_NSEC 47 70 | #define T_DNSKEY 48 71 | #define T_NSEC3 50 72 | #define T_TKEY 249 73 | #define T_TSIG 250 74 | #define T_AXFR 252 75 | #define T_MAILB 253 76 | #define T_ANY 255 77 | 78 | #define EDNS0_OPTION_MAC 65001 /* dyndns.org temporary assignment */ 79 | #define EDNS0_OPTION_CLIENT_SUBNET 8 /* IANA */ 80 | 81 | struct dns_header { 82 | u16 id; 83 | u8 hb3,hb4; 84 | u16 qdcount,ancount,nscount,arcount; 85 | }; 86 | 87 | #define HB3_QR 0x80 88 | #define HB3_OPCODE 0x78 89 | #define HB3_AA 0x04 90 | #define HB3_TC 0x02 91 | #define HB3_RD 0x01 92 | 93 | #define HB4_RA 0x80 94 | #define HB4_AD 0x20 95 | #define HB4_CD 0x10 96 | #define HB4_RCODE 0x0f 97 | 98 | #define OPCODE(x) (((x)->hb3 & HB3_OPCODE) >> 3) 99 | #define SET_OPCODE(x, code) (x)->hb3 = ((x)->hb3 & ~HB3_OPCODE) | code 100 | 101 | #define RCODE(x) ((x)->hb4 & HB4_RCODE) 102 | #define SET_RCODE(x, code) (x)->hb4 = ((x)->hb4 & ~HB4_RCODE) | code 103 | 104 | #define GETSHORT(s, cp) { \ 105 | unsigned char *t_cp = (unsigned char *)(cp); \ 106 | (s) = ((u16)t_cp[0] << 8) \ 107 | | ((u16)t_cp[1]) \ 108 | ; \ 109 | (cp) += 2; \ 110 | } 111 | 112 | #define GETLONG(l, cp) { \ 113 | unsigned char *t_cp = (unsigned char *)(cp); \ 114 | (l) = ((u32)t_cp[0] << 24) \ 115 | | ((u32)t_cp[1] << 16) \ 116 | | ((u32)t_cp[2] << 8) \ 117 | | ((u32)t_cp[3]) \ 118 | ; \ 119 | (cp) += 4; \ 120 | } 121 | 122 | #define PUTSHORT(s, cp) { \ 123 | u16 t_s = (u16)(s); \ 124 | unsigned char *t_cp = (unsigned char *)(cp); \ 125 | *t_cp++ = t_s >> 8; \ 126 | *t_cp = t_s; \ 127 | (cp) += 2; \ 128 | } 129 | 130 | #define PUTLONG(l, cp) { \ 131 | u32 t_l = (u32)(l); \ 132 | unsigned char *t_cp = (unsigned char *)(cp); \ 133 | *t_cp++ = t_l >> 24; \ 134 | *t_cp++ = t_l >> 16; \ 135 | *t_cp++ = t_l >> 8; \ 136 | *t_cp = t_l; \ 137 | (cp) += 4; \ 138 | } 139 | 140 | #define CHECK_LEN(header, pp, plen, len) \ 141 | ((size_t)((pp) - (unsigned char *)(header) + (len)) <= (plen)) 142 | 143 | #define ADD_RDLEN(header, pp, plen, len) \ 144 | (!CHECK_LEN(header, pp, plen, len) ? 0 : (((pp) += (len)), 1)) 145 | -------------------------------------------------------------------------------- /src/domain.c: -------------------------------------------------------------------------------- 1 | /* dnsmasq is Copyright (c) 2000-2015 Simon Kelley 2 | 3 | This program is free software; you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation; version 2 dated June, 1991, or 6 | (at your option) version 3 dated 29 June, 2007. 7 | 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with this program. If not, see . 15 | */ 16 | 17 | #include "dnsmasq.h" 18 | 19 | 20 | static struct cond_domain *search_domain(struct in_addr addr, struct cond_domain *c); 21 | #ifdef HAVE_IPV6 22 | static struct cond_domain *search_domain6(struct in6_addr *addr, struct cond_domain *c); 23 | #endif 24 | 25 | 26 | int is_name_synthetic(int flags, char *name, struct all_addr *addr) 27 | { 28 | char *p; 29 | struct cond_domain *c = NULL; 30 | int prot = AF_INET; 31 | 32 | #ifdef HAVE_IPV6 33 | if (flags & F_IPV6) 34 | prot = AF_INET6; 35 | #endif 36 | 37 | for (c = daemon->synth_domains; c; c = c->next) 38 | { 39 | int found = 0; 40 | char *tail, *pref; 41 | 42 | for (tail = name, pref = c->prefix; *tail != 0 && pref && *pref != 0; tail++, pref++) 43 | { 44 | unsigned int c1 = (unsigned char) *pref; 45 | unsigned int c2 = (unsigned char) *tail; 46 | 47 | if (c1 >= 'A' && c1 <= 'Z') 48 | c1 += 'a' - 'A'; 49 | if (c2 >= 'A' && c2 <= 'Z') 50 | c2 += 'a' - 'A'; 51 | 52 | if (c1 != c2) 53 | break; 54 | } 55 | 56 | if (pref && *pref != 0) 57 | continue; /* prefix match fail */ 58 | 59 | /* NB, must not alter name if we return zero */ 60 | for (p = tail; *p; p++) 61 | { 62 | char c = *p; 63 | 64 | if ((c >='0' && c <= '9') || c == '-') 65 | continue; 66 | 67 | #ifdef HAVE_IPV6 68 | if (prot == AF_INET6 && ((c >='A' && c <= 'F') || (c >='a' && c <= 'f'))) 69 | continue; 70 | #endif 71 | 72 | break; 73 | } 74 | 75 | if (*p != '.') 76 | continue; 77 | 78 | *p = 0; 79 | 80 | /* swap . or : for - */ 81 | for (p = tail; *p; p++) 82 | if (*p == '-') 83 | { 84 | if (prot == AF_INET) 85 | *p = '.'; 86 | #ifdef HAVE_IPV6 87 | else 88 | *p = ':'; 89 | #endif 90 | } 91 | 92 | if (hostname_isequal(c->domain, p+1) && inet_pton(prot, tail, addr)) 93 | { 94 | if (prot == AF_INET) 95 | { 96 | if (!c->is6 && 97 | ntohl(addr->addr.addr4.s_addr) >= ntohl(c->start.s_addr) && 98 | ntohl(addr->addr.addr4.s_addr) <= ntohl(c->end.s_addr)) 99 | found = 1; 100 | } 101 | #ifdef HAVE_IPV6 102 | else 103 | { 104 | u64 addrpart = addr6part(&addr->addr.addr6); 105 | 106 | if (c->is6 && 107 | is_same_net6(&addr->addr.addr6, &c->start6, 64) && 108 | addrpart >= addr6part(&c->start6) && 109 | addrpart <= addr6part(&c->end6)) 110 | found = 1; 111 | } 112 | #endif 113 | } 114 | 115 | /* restore name */ 116 | for (p = tail; *p; p++) 117 | if (*p == '.' || *p == ':') 118 | *p = '-'; 119 | 120 | *p = '.'; 121 | 122 | if (found) 123 | return 1; 124 | } 125 | 126 | return 0; 127 | } 128 | 129 | 130 | int is_rev_synth(int flag, struct all_addr *addr, char *name) 131 | { 132 | struct cond_domain *c; 133 | 134 | if (flag & F_IPV4 && (c = search_domain(addr->addr.addr4, daemon->synth_domains))) 135 | { 136 | char *p; 137 | 138 | *name = 0; 139 | if (c->prefix) 140 | strncpy(name, c->prefix, MAXDNAME - ADDRSTRLEN); 141 | 142 | inet_ntop(AF_INET, &addr->addr.addr4, name + strlen(name), ADDRSTRLEN); 143 | for (p = name; *p; p++) 144 | if (*p == '.') 145 | *p = '-'; 146 | 147 | strncat(name, ".", MAXDNAME); 148 | strncat(name, c->domain, MAXDNAME); 149 | 150 | return 1; 151 | } 152 | 153 | #ifdef HAVE_IPV6 154 | if (flag & F_IPV6 && (c = search_domain6(&addr->addr.addr6, daemon->synth_domains))) 155 | { 156 | char *p; 157 | 158 | *name = 0; 159 | if (c->prefix) 160 | strncpy(name, c->prefix, MAXDNAME - ADDRSTRLEN); 161 | 162 | inet_ntop(AF_INET6, &addr->addr.addr6, name + strlen(name), ADDRSTRLEN); 163 | 164 | /* IPv6 presentation address can start with ":", but valid domain names 165 | cannot start with "-" so prepend a zero in that case. */ 166 | if (!c->prefix && *name == ':') 167 | { 168 | *name = '0'; 169 | inet_ntop(AF_INET6, &addr->addr.addr6, name+1, ADDRSTRLEN); 170 | } 171 | 172 | for (p = name; *p; p++) 173 | if (*p == ':') 174 | *p = '-'; 175 | 176 | strncat(name, ".", MAXDNAME); 177 | strncat(name, c->domain, MAXDNAME); 178 | 179 | return 1; 180 | } 181 | #endif 182 | 183 | return 0; 184 | } 185 | 186 | 187 | static struct cond_domain *search_domain(struct in_addr addr, struct cond_domain *c) 188 | { 189 | for (; c; c = c->next) 190 | if (!c->is6 && 191 | ntohl(addr.s_addr) >= ntohl(c->start.s_addr) && 192 | ntohl(addr.s_addr) <= ntohl(c->end.s_addr)) 193 | return c; 194 | 195 | return NULL; 196 | } 197 | 198 | char *get_domain(struct in_addr addr) 199 | { 200 | struct cond_domain *c; 201 | 202 | if ((c = search_domain(addr, daemon->cond_domain))) 203 | return c->domain; 204 | 205 | return daemon->domain_suffix; 206 | } 207 | 208 | #ifdef HAVE_IPV6 209 | static struct cond_domain *search_domain6(struct in6_addr *addr, struct cond_domain *c) 210 | { 211 | u64 addrpart = addr6part(addr); 212 | 213 | for (; c; c = c->next) 214 | if (c->is6 && 215 | is_same_net6(addr, &c->start6, 64) && 216 | addrpart >= addr6part(&c->start6) && 217 | addrpart <= addr6part(&c->end6)) 218 | return c; 219 | 220 | return NULL; 221 | } 222 | 223 | char *get_domain6(struct in6_addr *addr) 224 | { 225 | struct cond_domain *c; 226 | 227 | if (addr && (c = search_domain6(addr, daemon->cond_domain))) 228 | return c->domain; 229 | 230 | return daemon->domain_suffix; 231 | } 232 | #endif 233 | -------------------------------------------------------------------------------- /src/inotify.c: -------------------------------------------------------------------------------- 1 | /* dnsmasq is Copyright (c) 2000-2015 Simon Kelley 2 | 3 | This program is free software; you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation; version 2 dated June, 1991, or 6 | (at your option) version 3 dated 29 June, 2007. 7 | 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with this program. If not, see . 15 | */ 16 | 17 | #include "dnsmasq.h" 18 | #ifdef HAVE_INOTIFY 19 | 20 | #include 21 | 22 | /* the strategy is to set a inotify on the directories containing 23 | resolv files, for any files in the directory which are close-write 24 | or moved into the directory. 25 | 26 | When either of those happen, we look to see if the file involved 27 | is actually a resolv-file, and if so, call poll-resolv with 28 | the "force" argument, to ensure it's read. 29 | 30 | This adds one new error condition: the directories containing 31 | all specified resolv-files must exist at start-up, even if the actual 32 | files don't. 33 | */ 34 | 35 | static char *inotify_buffer; 36 | #define INOTIFY_SZ (sizeof(struct inotify_event) + NAME_MAX + 1) 37 | 38 | void inotify_dnsmasq_init() 39 | { 40 | struct resolvc *res; 41 | 42 | inotify_buffer = safe_malloc(INOTIFY_SZ); 43 | daemon->inotifyfd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC); 44 | 45 | if (daemon->inotifyfd == -1) 46 | die(_("failed to create inotify: %s"), NULL, EC_MISC); 47 | 48 | for (res = daemon->resolv_files; res; res = res->next) 49 | { 50 | char *d = NULL, *path; 51 | 52 | if (!(path = realpath(res->name, NULL))) 53 | { 54 | /* realpath will fail if the file doesn't exist, but 55 | dnsmasq copes with missing files, so fall back 56 | and assume that symlinks are not in use in that case. */ 57 | if (errno == ENOENT) 58 | path = res->name; 59 | else 60 | die(_("cannot cannonicalise resolv-file %s: %s"), res->name, EC_MISC); 61 | } 62 | 63 | if ((d = strrchr(path, '/'))) 64 | { 65 | *d = 0; /* make path just directory */ 66 | res->wd = inotify_add_watch(daemon->inotifyfd, path, IN_CLOSE_WRITE | IN_MOVED_TO); 67 | 68 | res->file = d+1; /* pointer to filename */ 69 | *d = '/'; 70 | 71 | if (res->wd == -1 && errno == ENOENT) 72 | die(_("directory %s for resolv-file is missing, cannot poll"), res->name, EC_MISC); 73 | 74 | if (res->wd == -1) 75 | die(_("failed to create inotify for %s: %s"), res->name, EC_MISC); 76 | } 77 | } 78 | } 79 | 80 | 81 | /* initialisation for dynamic-dir. Set inotify watch for each directory, and read pre-existing files */ 82 | void set_dynamic_inotify(int flag, int total_size, struct crec **rhash, int revhashsz) 83 | { 84 | struct hostsfile *ah; 85 | 86 | for (ah = daemon->dynamic_dirs; ah; ah = ah->next) 87 | { 88 | DIR *dir_stream = NULL; 89 | struct dirent *ent; 90 | struct stat buf; 91 | 92 | if (!(ah->flags & flag)) 93 | continue; 94 | 95 | if (stat(ah->fname, &buf) == -1 || !(S_ISDIR(buf.st_mode))) 96 | { 97 | my_syslog(LOG_ERR, _("bad dynamic directory %s: %s"), 98 | ah->fname, strerror(errno)); 99 | continue; 100 | } 101 | 102 | if (!(ah->flags & AH_WD_DONE)) 103 | { 104 | ah->wd = inotify_add_watch(daemon->inotifyfd, ah->fname, IN_CLOSE_WRITE | IN_MOVED_TO); 105 | ah->flags |= AH_WD_DONE; 106 | } 107 | /* Read contents of dir _after_ calling add_watch, in the ho[e of avoiding 108 | a race which misses files being added as we start */ 109 | if (ah->wd == -1 || !(dir_stream = opendir(ah->fname))) 110 | { 111 | my_syslog(LOG_ERR, _("failed to create inotify for %s: %s"), 112 | ah->fname, strerror(errno)); 113 | continue; 114 | } 115 | 116 | while ((ent = readdir(dir_stream))) 117 | { 118 | size_t lendir = strlen(ah->fname); 119 | size_t lenfile = strlen(ent->d_name); 120 | char *path; 121 | 122 | /* ignore emacs backups and dotfiles */ 123 | if (lenfile == 0 || 124 | ent->d_name[lenfile - 1] == '~' || 125 | (ent->d_name[0] == '#' && ent->d_name[lenfile - 1] == '#') || 126 | ent->d_name[0] == '.') 127 | continue; 128 | 129 | if ((path = whine_malloc(lendir + lenfile + 2))) 130 | { 131 | strcpy(path, ah->fname); 132 | strcat(path, "/"); 133 | strcat(path, ent->d_name); 134 | 135 | /* ignore non-regular files */ 136 | if (stat(path, &buf) != -1 && S_ISREG(buf.st_mode)) 137 | { 138 | if (ah->flags & AH_HOSTS) 139 | total_size = read_hostsfile(path, ah->index, total_size, rhash, revhashsz); 140 | #ifdef HAVE_DHCP 141 | else if (ah->flags & (AH_DHCP_HST | AH_DHCP_OPT)) 142 | option_read_dynfile(path, ah->flags); 143 | #endif 144 | } 145 | 146 | free(path); 147 | } 148 | } 149 | } 150 | } 151 | 152 | int inotify_check(time_t now) 153 | { 154 | int hit = 0; 155 | struct hostsfile *ah; 156 | 157 | while (1) 158 | { 159 | int rc; 160 | char *p; 161 | struct resolvc *res; 162 | struct inotify_event *in; 163 | 164 | while ((rc = read(daemon->inotifyfd, inotify_buffer, INOTIFY_SZ)) == -1 && errno == EINTR); 165 | 166 | if (rc <= 0) 167 | break; 168 | 169 | for (p = inotify_buffer; rc - (p - inotify_buffer) >= (int)sizeof(struct inotify_event); p += sizeof(struct inotify_event) + in->len) 170 | { 171 | in = (struct inotify_event*)p; 172 | 173 | for (res = daemon->resolv_files; res; res = res->next) 174 | if (res->wd == in->wd && in->len != 0 && strcmp(res->file, in->name) == 0) 175 | hit = 1; 176 | 177 | /* ignore emacs backups and dotfiles */ 178 | if (in->len == 0 || 179 | in->name[in->len - 1] == '~' || 180 | (in->name[0] == '#' && in->name[in->len - 1] == '#') || 181 | in->name[0] == '.') 182 | continue; 183 | 184 | for (ah = daemon->dynamic_dirs; ah; ah = ah->next) 185 | if (ah->wd == in->wd) 186 | { 187 | size_t lendir = strlen(ah->fname); 188 | char *path; 189 | 190 | if ((path = whine_malloc(lendir + in->len + 2))) 191 | { 192 | strcpy(path, ah->fname); 193 | strcat(path, "/"); 194 | strcat(path, in->name); 195 | 196 | my_syslog(LOG_INFO, _("inotify, new or changed file %s"), path); 197 | 198 | if (ah->flags & AH_HOSTS) 199 | { 200 | read_hostsfile(path, ah->index, 0, NULL, 0); 201 | #ifdef HAVE_DHCP 202 | if (daemon->dhcp || daemon->doing_dhcp6) 203 | { 204 | /* Propogate the consequences of loading a new dhcp-host */ 205 | dhcp_update_configs(daemon->dhcp_conf); 206 | lease_update_from_configs(); 207 | lease_update_file(now); 208 | lease_update_dns(1); 209 | } 210 | #endif 211 | } 212 | #ifdef HAVE_DHCP 213 | else if (ah->flags & AH_DHCP_HST) 214 | { 215 | if (option_read_dynfile(path, AH_DHCP_HST)) 216 | { 217 | /* Propogate the consequences of loading a new dhcp-host */ 218 | dhcp_update_configs(daemon->dhcp_conf); 219 | lease_update_from_configs(); 220 | lease_update_file(now); 221 | lease_update_dns(1); 222 | } 223 | } 224 | else if (ah->flags & AH_DHCP_OPT) 225 | option_read_dynfile(path, AH_DHCP_OPT); 226 | #endif 227 | 228 | free(path); 229 | } 230 | } 231 | } 232 | } 233 | return hit; 234 | } 235 | 236 | #endif /* INOTIFY */ 237 | 238 | -------------------------------------------------------------------------------- /src/ip6addr.h: -------------------------------------------------------------------------------- 1 | /* dnsmasq is Copyright (c) 2000-2015 Simon Kelley 2 | 3 | This program is free software; you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation; version 2 dated June, 1991, or 6 | (at your option) version 3 dated 29 June, 2007. 7 | 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with this program. If not, see . 15 | */ 16 | 17 | 18 | 19 | #define IN6_IS_ADDR_ULA(a) \ 20 | ((((__const uint32_t *) (a))[0] & htonl (0xff000000)) \ 21 | == htonl (0xfd000000)) 22 | 23 | #define IN6_IS_ADDR_ULA_ZERO(a) \ 24 | (((__const uint32_t *) (a))[0] == htonl (0xfd000000) \ 25 | && ((__const uint32_t *) (a))[1] == 0 \ 26 | && ((__const uint32_t *) (a))[2] == 0 \ 27 | && ((__const uint32_t *) (a))[3] == 0) 28 | 29 | #define IN6_IS_ADDR_LINK_LOCAL_ZERO(a) \ 30 | (((__const uint32_t *) (a))[0] == htonl (0xfe800000) \ 31 | && ((__const uint32_t *) (a))[1] == 0 \ 32 | && ((__const uint32_t *) (a))[2] == 0 \ 33 | && ((__const uint32_t *) (a))[3] == 0) 34 | 35 | -------------------------------------------------------------------------------- /src/ipset.c: -------------------------------------------------------------------------------- 1 | /* ipset.c is Copyright (c) 2013 Jason A. Donenfeld . All Rights Reserved. 2 | 3 | This program is free software; you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation; version 2 dated June, 1991, or 6 | (at your option) version 3 dated 29 June, 2007. 7 | 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with this program. If not, see . 15 | */ 16 | 17 | #include "dnsmasq.h" 18 | 19 | #if defined(HAVE_IPSET) && defined(HAVE_LINUX_NETWORK) 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | /* We want to be able to compile against old header files 31 | Kernel version is handled at run-time. */ 32 | 33 | #define NFNL_SUBSYS_IPSET 6 34 | 35 | #define IPSET_ATTR_DATA 7 36 | #define IPSET_ATTR_IP 1 37 | #define IPSET_ATTR_IPADDR_IPV4 1 38 | #define IPSET_ATTR_IPADDR_IPV6 2 39 | #define IPSET_ATTR_PROTOCOL 1 40 | #define IPSET_ATTR_SETNAME 2 41 | #define IPSET_CMD_ADD 9 42 | #define IPSET_CMD_DEL 10 43 | #define IPSET_MAXNAMELEN 32 44 | #define IPSET_PROTOCOL 6 45 | 46 | #ifndef NFNETLINK_V0 47 | #define NFNETLINK_V0 0 48 | #endif 49 | 50 | #ifndef NLA_F_NESTED 51 | #define NLA_F_NESTED (1 << 15) 52 | #endif 53 | 54 | #ifndef NLA_F_NET_BYTEORDER 55 | #define NLA_F_NET_BYTEORDER (1 << 14) 56 | #endif 57 | 58 | struct my_nlattr { 59 | __u16 nla_len; 60 | __u16 nla_type; 61 | }; 62 | 63 | struct my_nfgenmsg { 64 | __u8 nfgen_family; /* AF_xxx */ 65 | __u8 version; /* nfnetlink version */ 66 | __be16 res_id; /* resource id */ 67 | }; 68 | 69 | 70 | /* data structure size in here is fixed */ 71 | #define BUFF_SZ 256 72 | 73 | #define NL_ALIGN(len) (((len)+3) & ~(3)) 74 | static const struct sockaddr_nl snl = { .nl_family = AF_NETLINK }; 75 | static int ipset_sock, old_kernel; 76 | static char *buffer; 77 | 78 | static inline void add_attr(struct nlmsghdr *nlh, uint16_t type, size_t len, const void *data) 79 | { 80 | struct my_nlattr *attr = (void *)nlh + NL_ALIGN(nlh->nlmsg_len); 81 | uint16_t payload_len = NL_ALIGN(sizeof(struct my_nlattr)) + len; 82 | attr->nla_type = type; 83 | attr->nla_len = payload_len; 84 | memcpy((void *)attr + NL_ALIGN(sizeof(struct my_nlattr)), data, len); 85 | nlh->nlmsg_len += NL_ALIGN(payload_len); 86 | } 87 | 88 | void ipset_init(void) 89 | { 90 | struct utsname utsname; 91 | int version; 92 | char *split; 93 | 94 | if (uname(&utsname) < 0) 95 | die(_("failed to find kernel version: %s"), NULL, EC_MISC); 96 | 97 | split = strtok(utsname.release, "."); 98 | version = (split ? atoi(split) : 0); 99 | split = strtok(NULL, "."); 100 | version = version * 256 + (split ? atoi(split) : 0); 101 | split = strtok(NULL, "."); 102 | version = version * 256 + (split ? atoi(split) : 0); 103 | old_kernel = (version < KERNEL_VERSION(2,6,32)); 104 | 105 | if (old_kernel && (ipset_sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) != -1) 106 | return; 107 | 108 | if (!old_kernel && 109 | (buffer = safe_malloc(BUFF_SZ)) && 110 | (ipset_sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_NETFILTER)) != -1 && 111 | (bind(ipset_sock, (struct sockaddr *)&snl, sizeof(snl)) != -1)) 112 | return; 113 | 114 | die (_("failed to create IPset control socket: %s"), NULL, EC_MISC); 115 | } 116 | 117 | static int new_add_to_ipset(const char *setname, const struct all_addr *ipaddr, int af, int remove) 118 | { 119 | struct nlmsghdr *nlh; 120 | struct my_nfgenmsg *nfg; 121 | struct my_nlattr *nested[2]; 122 | uint8_t proto; 123 | int addrsz = INADDRSZ; 124 | ssize_t rc; 125 | 126 | #ifdef HAVE_IPV6 127 | if (af == AF_INET6) 128 | addrsz = IN6ADDRSZ; 129 | #endif 130 | 131 | if (strlen(setname) >= IPSET_MAXNAMELEN) 132 | { 133 | errno = ENAMETOOLONG; 134 | return -1; 135 | } 136 | 137 | memset(buffer, 0, BUFF_SZ); 138 | 139 | nlh = (struct nlmsghdr *)buffer; 140 | nlh->nlmsg_len = NL_ALIGN(sizeof(struct nlmsghdr)); 141 | nlh->nlmsg_type = (remove ? IPSET_CMD_DEL : IPSET_CMD_ADD) | (NFNL_SUBSYS_IPSET << 8); 142 | nlh->nlmsg_flags = NLM_F_REQUEST; 143 | 144 | nfg = (struct my_nfgenmsg *)(buffer + nlh->nlmsg_len); 145 | nlh->nlmsg_len += NL_ALIGN(sizeof(struct my_nfgenmsg)); 146 | nfg->nfgen_family = af; 147 | nfg->version = NFNETLINK_V0; 148 | nfg->res_id = htons(0); 149 | 150 | proto = IPSET_PROTOCOL; 151 | add_attr(nlh, IPSET_ATTR_PROTOCOL, sizeof(proto), &proto); 152 | add_attr(nlh, IPSET_ATTR_SETNAME, strlen(setname) + 1, setname); 153 | nested[0] = (struct my_nlattr *)(buffer + NL_ALIGN(nlh->nlmsg_len)); 154 | nlh->nlmsg_len += NL_ALIGN(sizeof(struct my_nlattr)); 155 | nested[0]->nla_type = NLA_F_NESTED | IPSET_ATTR_DATA; 156 | nested[1] = (struct my_nlattr *)(buffer + NL_ALIGN(nlh->nlmsg_len)); 157 | nlh->nlmsg_len += NL_ALIGN(sizeof(struct my_nlattr)); 158 | nested[1]->nla_type = NLA_F_NESTED | IPSET_ATTR_IP; 159 | add_attr(nlh, 160 | (af == AF_INET ? IPSET_ATTR_IPADDR_IPV4 : IPSET_ATTR_IPADDR_IPV6) | NLA_F_NET_BYTEORDER, 161 | addrsz, &ipaddr->addr); 162 | nested[1]->nla_len = (void *)buffer + NL_ALIGN(nlh->nlmsg_len) - (void *)nested[1]; 163 | nested[0]->nla_len = (void *)buffer + NL_ALIGN(nlh->nlmsg_len) - (void *)nested[0]; 164 | 165 | while ((rc = sendto(ipset_sock, buffer, nlh->nlmsg_len, 0, 166 | (struct sockaddr *)&snl, sizeof(snl))) == -1 && retry_send()); 167 | return rc; 168 | } 169 | 170 | 171 | static int old_add_to_ipset(const char *setname, const struct all_addr *ipaddr, int remove) 172 | { 173 | socklen_t size; 174 | struct ip_set_req_adt_get { 175 | unsigned op; 176 | unsigned version; 177 | union { 178 | char name[IPSET_MAXNAMELEN]; 179 | uint16_t index; 180 | } set; 181 | char typename[IPSET_MAXNAMELEN]; 182 | } req_adt_get; 183 | struct ip_set_req_adt { 184 | unsigned op; 185 | uint16_t index; 186 | uint32_t ip; 187 | } req_adt; 188 | 189 | if (strlen(setname) >= sizeof(req_adt_get.set.name)) 190 | { 191 | errno = ENAMETOOLONG; 192 | return -1; 193 | } 194 | 195 | req_adt_get.op = 0x10; 196 | req_adt_get.version = 3; 197 | strcpy(req_adt_get.set.name, setname); 198 | size = sizeof(req_adt_get); 199 | if (getsockopt(ipset_sock, SOL_IP, 83, &req_adt_get, &size) < 0) 200 | return -1; 201 | req_adt.op = remove ? 0x102 : 0x101; 202 | req_adt.index = req_adt_get.set.index; 203 | req_adt.ip = ntohl(ipaddr->addr.addr4.s_addr); 204 | if (setsockopt(ipset_sock, SOL_IP, 83, &req_adt, sizeof(req_adt)) < 0) 205 | return -1; 206 | 207 | return 0; 208 | } 209 | 210 | 211 | 212 | int add_to_ipset(const char *setname, const struct all_addr *ipaddr, int flags, int remove) 213 | { 214 | int af = AF_INET; 215 | 216 | #ifdef HAVE_IPV6 217 | if (flags & F_IPV6) 218 | { 219 | af = AF_INET6; 220 | /* old method only supports IPv4 */ 221 | if (old_kernel) 222 | return -1; 223 | } 224 | #endif 225 | 226 | return old_kernel ? old_add_to_ipset(setname, ipaddr, remove) : new_add_to_ipset(setname, ipaddr, af, remove); 227 | } 228 | 229 | #endif 230 | -------------------------------------------------------------------------------- /src/loop.c: -------------------------------------------------------------------------------- 1 | /* dnsmasq is Copyright (c) 2000-2015 Simon Kelley 2 | 3 | This program is free software; you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation; version 2 dated June, 1991, or 6 | (at your option) version 3 dated 29 June, 2007. 7 | 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with this program. If not, see . 15 | */ 16 | 17 | #include "dnsmasq.h" 18 | 19 | #ifdef HAVE_LOOP 20 | static ssize_t loop_make_probe(u32 uid); 21 | 22 | void loop_send_probes() 23 | { 24 | struct server *serv; 25 | 26 | if (!option_bool(OPT_LOOP_DETECT)) 27 | return; 28 | 29 | /* Loop through all upstream servers not for particular domains, and send a query to that server which is 30 | identifiable, via the uid. If we see that query back again, then the server is looping, and we should not use it. */ 31 | for (serv = daemon->servers; serv; serv = serv->next) 32 | if (!(serv->flags & 33 | (SERV_LITERAL_ADDRESS | SERV_NO_ADDR | SERV_USE_RESOLV | SERV_NO_REBIND | SERV_HAS_DOMAIN | SERV_FOR_NODOTS | SERV_LOOP))) 34 | { 35 | ssize_t len = loop_make_probe(serv->uid); 36 | int fd; 37 | struct randfd *rfd = NULL; 38 | 39 | if (serv->sfd) 40 | fd = serv->sfd->fd; 41 | else 42 | { 43 | if (!(rfd = allocate_rfd(serv->addr.sa.sa_family))) 44 | continue; 45 | fd = rfd->fd; 46 | } 47 | 48 | while (sendto(fd, daemon->packet, len, 0, &serv->addr.sa, sa_len(&serv->addr)) == -1 && retry_send()); 49 | 50 | free_rfd(rfd); 51 | } 52 | } 53 | 54 | static ssize_t loop_make_probe(u32 uid) 55 | { 56 | struct dns_header *header = (struct dns_header *)daemon->packet; 57 | unsigned char *p = (unsigned char *)(header+1); 58 | 59 | /* packet buffer overwritten */ 60 | daemon->srv_save = NULL; 61 | 62 | header->id = rand16(); 63 | header->ancount = header->nscount = header->arcount = htons(0); 64 | header->qdcount = htons(1); 65 | header->hb3 = HB3_RD; 66 | header->hb4 = 0; 67 | SET_OPCODE(header, QUERY); 68 | 69 | *p++ = 8; 70 | sprintf((char *)p, "%.8x", uid); 71 | p += 8; 72 | *p++ = strlen(LOOP_TEST_DOMAIN); 73 | strcpy((char *)p, LOOP_TEST_DOMAIN); /* Add terminating zero */ 74 | p += strlen(LOOP_TEST_DOMAIN) + 1; 75 | 76 | PUTSHORT(LOOP_TEST_TYPE, p); 77 | PUTSHORT(C_IN, p); 78 | 79 | return p - (unsigned char *)header; 80 | } 81 | 82 | 83 | int detect_loop(char *query, int type) 84 | { 85 | int i; 86 | u32 uid; 87 | struct server *serv; 88 | 89 | if (!option_bool(OPT_LOOP_DETECT)) 90 | return 0; 91 | 92 | if (type != LOOP_TEST_TYPE || 93 | strlen(LOOP_TEST_DOMAIN) + 9 != strlen(query) || 94 | strstr(query, LOOP_TEST_DOMAIN) != query + 9) 95 | return 0; 96 | 97 | for (i = 0; i < 8; i++) 98 | if (!isxdigit(query[i])) 99 | return 0; 100 | 101 | uid = strtol(query, NULL, 16); 102 | 103 | for (serv = daemon->servers; serv; serv = serv->next) 104 | if (!(serv->flags & 105 | (SERV_LITERAL_ADDRESS | SERV_NO_ADDR | SERV_USE_RESOLV | SERV_NO_REBIND | SERV_HAS_DOMAIN | SERV_FOR_NODOTS | SERV_LOOP)) && 106 | uid == serv->uid) 107 | { 108 | serv->flags |= SERV_LOOP; 109 | check_servers(); /* log new state */ 110 | return 1; 111 | } 112 | 113 | return 0; 114 | } 115 | 116 | #endif 117 | -------------------------------------------------------------------------------- /src/outpacket.c: -------------------------------------------------------------------------------- 1 | /* dnsmasq is Copyright (c) 2000-2015 Simon Kelley 2 | 3 | This program is free software; you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation; version 2 dated June, 1991, or 6 | (at your option) version 3 dated 29 June, 2007. 7 | 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with this program. If not, see . 15 | */ 16 | 17 | 18 | #include "dnsmasq.h" 19 | 20 | #ifdef HAVE_DHCP6 21 | 22 | static size_t outpacket_counter; 23 | 24 | void end_opt6(int container) 25 | { 26 | void *p = daemon->outpacket.iov_base + container + 2; 27 | u16 len = outpacket_counter - container - 4 ; 28 | 29 | PUTSHORT(len, p); 30 | } 31 | 32 | int save_counter(int newval) 33 | { 34 | int ret = outpacket_counter; 35 | if (newval != -1) 36 | outpacket_counter = newval; 37 | 38 | return ret; 39 | } 40 | 41 | void *expand(size_t headroom) 42 | { 43 | void *ret; 44 | 45 | if (expand_buf(&daemon->outpacket, outpacket_counter + headroom)) 46 | { 47 | ret = daemon->outpacket.iov_base + outpacket_counter; 48 | outpacket_counter += headroom; 49 | return ret; 50 | } 51 | 52 | return NULL; 53 | } 54 | 55 | int new_opt6(int opt) 56 | { 57 | int ret = outpacket_counter; 58 | void *p; 59 | 60 | if ((p = expand(4))) 61 | { 62 | PUTSHORT(opt, p); 63 | PUTSHORT(0, p); 64 | } 65 | 66 | return ret; 67 | } 68 | 69 | void *put_opt6(void *data, size_t len) 70 | { 71 | void *p; 72 | 73 | if ((p = expand(len)) && data) 74 | memcpy(p, data, len); 75 | 76 | return p; 77 | } 78 | 79 | void put_opt6_long(unsigned int val) 80 | { 81 | void *p; 82 | 83 | if ((p = expand(4))) 84 | PUTLONG(val, p); 85 | } 86 | 87 | void put_opt6_short(unsigned int val) 88 | { 89 | void *p; 90 | 91 | if ((p = expand(2))) 92 | PUTSHORT(val, p); 93 | } 94 | 95 | void put_opt6_char(unsigned int val) 96 | { 97 | unsigned char *p; 98 | 99 | if ((p = expand(1))) 100 | *p = val; 101 | } 102 | 103 | void put_opt6_string(char *s) 104 | { 105 | put_opt6(s, strlen(s)); 106 | } 107 | 108 | #endif 109 | -------------------------------------------------------------------------------- /src/radv-protocol.h: -------------------------------------------------------------------------------- 1 | /* dnsmasq is Copyright (c) 2000-2015 Simon Kelley 2 | 3 | This program is free software; you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation; version 2 dated June, 1991, or 6 | (at your option) version 3 dated 29 June, 2007. 7 | 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with this program. If not, see . 15 | */ 16 | 17 | #define ALL_NODES "FF02::1" 18 | #define ALL_ROUTERS "FF02::2" 19 | 20 | struct ping_packet { 21 | u8 type, code; 22 | u16 checksum; 23 | u16 identifier; 24 | u16 sequence_no; 25 | }; 26 | 27 | struct ra_packet { 28 | u8 type, code; 29 | u16 checksum; 30 | u8 hop_limit, flags; 31 | u16 lifetime; 32 | u32 reachable_time; 33 | u32 retrans_time; 34 | }; 35 | 36 | struct neigh_packet { 37 | u8 type, code; 38 | u16 checksum; 39 | u16 reserved; 40 | struct in6_addr target; 41 | }; 42 | 43 | struct prefix_opt { 44 | u8 type, len, prefix_len, flags; 45 | u32 valid_lifetime, preferred_lifetime, reserved; 46 | struct in6_addr prefix; 47 | }; 48 | 49 | #define ICMP6_OPT_SOURCE_MAC 1 50 | #define ICMP6_OPT_PREFIX 3 51 | #define ICMP6_OPT_MTU 5 52 | #define ICMP6_OPT_ADV_INTERVAL 7 53 | #define ICMP6_OPT_RT_INFO 24 54 | #define ICMP6_OPT_RDNSS 25 55 | #define ICMP6_OPT_DNSSL 31 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /src/slaac.c: -------------------------------------------------------------------------------- 1 | /* dnsmasq is Copyright (c) 2000-2015 Simon Kelley 2 | 3 | This program is free software; you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation; version 2 dated June, 1991, or 6 | (at your option) version 3 dated 29 June, 2007. 7 | 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with this program. If not, see . 15 | */ 16 | 17 | #include "dnsmasq.h" 18 | 19 | #ifdef HAVE_DHCP6 20 | 21 | #include 22 | 23 | static int ping_id = 0; 24 | 25 | void slaac_add_addrs(struct dhcp_lease *lease, time_t now, int force) 26 | { 27 | struct slaac_address *slaac, *old, **up; 28 | struct dhcp_context *context; 29 | int dns_dirty = 0; 30 | 31 | if (!(lease->flags & LEASE_HAVE_HWADDR) || 32 | (lease->flags & (LEASE_TA | LEASE_NA)) || 33 | lease->last_interface == 0 || 34 | !lease->hostname) 35 | return ; 36 | 37 | old = lease->slaac_address; 38 | lease->slaac_address = NULL; 39 | 40 | for (context = daemon->dhcp6; context; context = context->next) 41 | if ((context->flags & CONTEXT_RA_NAME) && 42 | !(context->flags & CONTEXT_OLD) && 43 | lease->last_interface == context->if_index) 44 | { 45 | struct in6_addr addr = context->start6; 46 | if (lease->hwaddr_len == 6 && 47 | (lease->hwaddr_type == ARPHRD_ETHER || lease->hwaddr_type == ARPHRD_IEEE802)) 48 | { 49 | /* convert MAC address to EUI-64 */ 50 | memcpy(&addr.s6_addr[8], lease->hwaddr, 3); 51 | memcpy(&addr.s6_addr[13], &lease->hwaddr[3], 3); 52 | addr.s6_addr[11] = 0xff; 53 | addr.s6_addr[12] = 0xfe; 54 | } 55 | #if defined(ARPHRD_EUI64) 56 | else if (lease->hwaddr_len == 8 && 57 | lease->hwaddr_type == ARPHRD_EUI64) 58 | memcpy(&addr.s6_addr[8], lease->hwaddr, 8); 59 | #endif 60 | #if defined(ARPHRD_IEEE1394) && defined(ARPHRD_EUI64) 61 | else if (lease->clid_len == 9 && 62 | lease->clid[0] == ARPHRD_EUI64 && 63 | lease->hwaddr_type == ARPHRD_IEEE1394) 64 | /* firewire has EUI-64 identifier as clid */ 65 | memcpy(&addr.s6_addr[8], &lease->clid[1], 8); 66 | #endif 67 | else 68 | continue; 69 | 70 | addr.s6_addr[8] ^= 0x02; 71 | 72 | /* check if we already have this one */ 73 | for (up = &old, slaac = old; slaac; slaac = slaac->next) 74 | { 75 | if (IN6_ARE_ADDR_EQUAL(&addr, &slaac->addr)) 76 | { 77 | *up = slaac->next; 78 | /* recheck when DHCPv4 goes through init-reboot */ 79 | if (force) 80 | { 81 | slaac->ping_time = now; 82 | slaac->backoff = 1; 83 | dns_dirty = 1; 84 | } 85 | break; 86 | } 87 | up = &slaac->next; 88 | } 89 | 90 | /* No, make new one */ 91 | if (!slaac && (slaac = whine_malloc(sizeof(struct slaac_address)))) 92 | { 93 | slaac->ping_time = now; 94 | slaac->backoff = 1; 95 | slaac->addr = addr; 96 | /* Do RA's to prod it */ 97 | ra_start_unsolicted(now, context); 98 | } 99 | 100 | if (slaac) 101 | { 102 | slaac->next = lease->slaac_address; 103 | lease->slaac_address = slaac; 104 | } 105 | } 106 | 107 | if (old || dns_dirty) 108 | lease_update_dns(1); 109 | 110 | /* Free any no reused */ 111 | for (; old; old = slaac) 112 | { 113 | slaac = old->next; 114 | free(old); 115 | } 116 | } 117 | 118 | 119 | time_t periodic_slaac(time_t now, struct dhcp_lease *leases) 120 | { 121 | struct dhcp_context *context; 122 | struct dhcp_lease *lease; 123 | struct slaac_address *slaac; 124 | time_t next_event = 0; 125 | 126 | for (context = daemon->dhcp6; context; context = context->next) 127 | if ((context->flags & CONTEXT_RA_NAME) && !(context->flags & CONTEXT_OLD)) 128 | break; 129 | 130 | /* nothing configured */ 131 | if (!context) 132 | return 0; 133 | 134 | while (ping_id == 0) 135 | ping_id = rand16(); 136 | 137 | for (lease = leases; lease; lease = lease->next) 138 | for (slaac = lease->slaac_address; slaac; slaac = slaac->next) 139 | { 140 | /* confirmed or given up? */ 141 | if (slaac->backoff == 0 || slaac->ping_time == 0) 142 | continue; 143 | 144 | if (difftime(slaac->ping_time, now) <= 0.0) 145 | { 146 | struct ping_packet *ping; 147 | struct sockaddr_in6 addr; 148 | 149 | save_counter(0); 150 | ping = expand(sizeof(struct ping_packet)); 151 | ping->type = ICMP6_ECHO_REQUEST; 152 | ping->code = 0; 153 | ping->identifier = ping_id; 154 | ping->sequence_no = slaac->backoff; 155 | 156 | memset(&addr, 0, sizeof(addr)); 157 | #ifdef HAVE_SOCKADDR_SA_LEN 158 | addr.sin6_len = sizeof(struct sockaddr_in6); 159 | #endif 160 | addr.sin6_family = AF_INET6; 161 | addr.sin6_port = htons(IPPROTO_ICMPV6); 162 | addr.sin6_addr = slaac->addr; 163 | 164 | if (sendto(daemon->icmp6fd, daemon->outpacket.iov_base, save_counter(0), 0, 165 | (struct sockaddr *)&addr, sizeof(addr)) == -1 && 166 | errno == EHOSTUNREACH) 167 | slaac->ping_time = 0; /* Give up */ 168 | else 169 | { 170 | slaac->ping_time += (1 << (slaac->backoff - 1)) + (rand16()/21785); /* 0 - 3 */ 171 | if (slaac->backoff > 4) 172 | slaac->ping_time += rand16()/4000; /* 0 - 15 */ 173 | if (slaac->backoff < 12) 174 | slaac->backoff++; 175 | } 176 | } 177 | 178 | if (slaac->ping_time != 0 && 179 | (next_event == 0 || difftime(next_event, slaac->ping_time) >= 0.0)) 180 | next_event = slaac->ping_time; 181 | } 182 | 183 | return next_event; 184 | } 185 | 186 | 187 | void slaac_ping_reply(struct in6_addr *sender, unsigned char *packet, char *interface, struct dhcp_lease *leases) 188 | { 189 | struct dhcp_lease *lease; 190 | struct slaac_address *slaac; 191 | struct ping_packet *ping = (struct ping_packet *)packet; 192 | int gotone = 0; 193 | 194 | if (ping->identifier == ping_id) 195 | for (lease = leases; lease; lease = lease->next) 196 | for (slaac = lease->slaac_address; slaac; slaac = slaac->next) 197 | if (slaac->backoff != 0 && IN6_ARE_ADDR_EQUAL(sender, &slaac->addr)) 198 | { 199 | slaac->backoff = 0; 200 | gotone = 1; 201 | inet_ntop(AF_INET6, sender, daemon->addrbuff, ADDRSTRLEN); 202 | if (!option_bool(OPT_QUIET_DHCP6)) 203 | my_syslog(MS_DHCP | LOG_INFO, "SLAAC-CONFIRM(%s) %s %s", interface, daemon->addrbuff, lease->hostname); 204 | } 205 | 206 | lease_update_dns(gotone); 207 | } 208 | 209 | #endif 210 | -------------------------------------------------------------------------------- /src/tables.c: -------------------------------------------------------------------------------- 1 | /* tables.c is Copyright (c) 2014 Sven Falempin All Rights Reserved. 2 | 3 | Author's email: sfalempin@citypassenger.com 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; version 2 dated June, 1991, or 8 | (at your option) version 3 dated 29 June, 2007. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #include "dnsmasq.h" 20 | 21 | #if defined(HAVE_IPSET) && defined(HAVE_BSD_NETWORK) 22 | 23 | #ifndef __FreeBSD__ 24 | #include 25 | #endif 26 | 27 | #include 28 | #include 29 | 30 | #include 31 | #include 32 | #include 33 | 34 | #include 35 | #include 36 | #include 37 | 38 | #define UNUSED(x) (void)(x) 39 | 40 | static char *pf_device = "/dev/pf"; 41 | static int dev = -1; 42 | 43 | static char *pfr_strerror(int errnum) 44 | { 45 | switch (errnum) 46 | { 47 | case ESRCH: 48 | return "Table does not exist"; 49 | case ENOENT: 50 | return "Anchor or Ruleset does not exist"; 51 | default: 52 | return strerror(errnum); 53 | } 54 | } 55 | 56 | static int pfr_add_tables(struct pfr_table *tbl, int size, int *nadd, int flags) 57 | { 58 | struct pfioc_table io; 59 | 60 | if (size < 0 || (size && tbl == NULL)) 61 | { 62 | errno = EINVAL; 63 | return (-1); 64 | } 65 | bzero(&io, sizeof io); 66 | io.pfrio_flags = flags; 67 | io.pfrio_buffer = tbl; 68 | io.pfrio_esize = sizeof(*tbl); 69 | io.pfrio_size = size; 70 | if (ioctl(dev, DIOCRADDTABLES, &io)) 71 | return (-1); 72 | if (nadd != NULL) 73 | *nadd = io.pfrio_nadd; 74 | return (0); 75 | } 76 | 77 | static int fill_addr(const struct all_addr *ipaddr, int flags, struct pfr_addr* addr) { 78 | if ( !addr || !ipaddr) 79 | { 80 | my_syslog(LOG_ERR, _("error: fill_addr missused")); 81 | return -1; 82 | } 83 | bzero(addr, sizeof(*addr)); 84 | #ifdef HAVE_IPV6 85 | if (flags & F_IPV6) 86 | { 87 | addr->pfra_af = AF_INET6; 88 | addr->pfra_net = 0x80; 89 | memcpy(&(addr->pfra_ip6addr), &(ipaddr->addr), sizeof(struct in6_addr)); 90 | } 91 | else 92 | #endif 93 | { 94 | addr->pfra_af = AF_INET; 95 | addr->pfra_net = 0x20; 96 | addr->pfra_ip4addr.s_addr = ipaddr->addr.addr4.s_addr; 97 | } 98 | return 1; 99 | } 100 | 101 | /*****************************************************************************/ 102 | 103 | void ipset_init(void) 104 | { 105 | dev = open( pf_device, O_RDWR); 106 | if (dev == -1) 107 | { 108 | err(1, "%s", pf_device); 109 | die (_("failed to access pf devices: %s"), NULL, EC_MISC); 110 | } 111 | } 112 | 113 | int add_to_ipset(const char *setname, const struct all_addr *ipaddr, 114 | int flags, int remove) 115 | { 116 | struct pfr_addr addr; 117 | struct pfioc_table io; 118 | struct pfr_table table; 119 | int n = 0, rc = 0; 120 | 121 | if ( dev == -1 ) 122 | { 123 | my_syslog(LOG_ERR, _("warning: no opened pf devices %s"), pf_device); 124 | return -1; 125 | } 126 | 127 | bzero(&table, sizeof(struct pfr_table)); 128 | table.pfrt_flags |= PFR_TFLAG_PERSIST; 129 | if ( strlen(setname) >= PF_TABLE_NAME_SIZE ) 130 | { 131 | my_syslog(LOG_ERR, _("error: cannot use table name %s"), setname); 132 | errno = ENAMETOOLONG; 133 | return -1; 134 | } 135 | 136 | if ( strlcpy(table.pfrt_name, setname, 137 | sizeof(table.pfrt_name)) >= sizeof(table.pfrt_name)) 138 | { 139 | my_syslog(LOG_ERR, _("error: cannot strlcpy table name %s"), setname); 140 | return -1; 141 | } 142 | 143 | if ((rc = pfr_add_tables(&table, 1, &n, 0))) 144 | { 145 | my_syslog(LOG_WARNING, _("warning: pfr_add_tables: %s(%d)"), 146 | pfr_strerror(errno),rc); 147 | return -1; 148 | } 149 | table.pfrt_flags &= ~PFR_TFLAG_PERSIST; 150 | if (n) 151 | my_syslog(LOG_INFO, _("info: table created")); 152 | 153 | fill_addr(ipaddr,flags,&addr); 154 | bzero(&io, sizeof(io)); 155 | io.pfrio_flags = 0; 156 | io.pfrio_table = table; 157 | io.pfrio_buffer = &addr; 158 | io.pfrio_esize = sizeof(addr); 159 | io.pfrio_size = 1; 160 | if (ioctl(dev, ( remove ? DIOCRDELADDRS : DIOCRADDADDRS ), &io)) 161 | { 162 | my_syslog(LOG_WARNING, _("warning: DIOCR%sADDRS: %s"), ( remove ? "DEL" : "ADD" ), pfr_strerror(errno)); 163 | return -1; 164 | } 165 | 166 | my_syslog(LOG_INFO, _("%d addresses %s"), 167 | io.pfrio_nadd, ( remove ? "removed" : "added" )); 168 | 169 | return io.pfrio_nadd; 170 | } 171 | 172 | 173 | #endif 174 | -------------------------------------------------------------------------------- /trust-anchors.conf: -------------------------------------------------------------------------------- 1 | # The root DNSSEC trust anchor, valid as at 10/02/2017 2 | 3 | # Note that this is a DS record (ie a hash of the root Zone Signing Key) 4 | # If was downloaded from https://data.iana.org/root-anchors/root-anchors.xml 5 | 6 | trust-anchor=.,19036,8,2,49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5 7 | trust-anchor=.,20326,8,2,E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D 8 | 9 | 10 | 11 | --------------------------------------------------------------------------------