mirror of
http://thekelleys.org.uk/git/dnsmasq.git
synced 2026-11-07 16:01:41 +00:00
Compare commits
11
Commits
v2.63test2
...
v2.63test3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
611ebc5f1e | ||
|
|
be0f45cdbc | ||
|
|
9b40cbf587 | ||
|
|
c4a7f90ebb | ||
|
|
9609baee41 | ||
|
|
395eb71931 | ||
|
|
8bc4cecee6 | ||
|
|
6b617c0d15 | ||
|
|
55d290a3bf | ||
|
|
e17b4b3871 | ||
|
|
236e072cab |
No files matched your search
@@ -11,6 +11,24 @@ version 2.63
|
|||||||
--bind-interfaces which copes with dynamically created
|
--bind-interfaces which copes with dynamically created
|
||||||
interfaces.
|
interfaces.
|
||||||
|
|
||||||
|
A couple of fixes to the build system for Android. Thanks
|
||||||
|
to Metin Kaya for the patches.
|
||||||
|
|
||||||
|
Remove the interface:<interface> argument in --dhcp-range, and
|
||||||
|
the interface argument to --enable-tftp. These were a
|
||||||
|
still-born attempt to allow automatic isolated
|
||||||
|
configuration by libvirt, but have never (to my knowledge)
|
||||||
|
been used, had very strange semantics, and have been
|
||||||
|
superceded by other mechanisms.
|
||||||
|
|
||||||
|
Fixed bug logging filenames when duplicate dhcp-host
|
||||||
|
addresses are found. Thanks to John Hanks for the patch.
|
||||||
|
|
||||||
|
Fix regression in 2.61 which broke caching of CNAME
|
||||||
|
chains. Thanks to Atul Gupta for the bug report.
|
||||||
|
|
||||||
|
Allow the target of a --cname flag to be anothe --cname.
|
||||||
|
|
||||||
|
|
||||||
version 2.62
|
version 2.62
|
||||||
Update German translation. Thanks to Conrad Kostecki.
|
Update German translation. Thanks to Conrad Kostecki.
|
||||||
|
|||||||
@@ -17,4 +17,6 @@ LOCAL_C_INCLUDES := external/dnsmasq/src
|
|||||||
LOCAL_CFLAGS := -O2 -g -W -Wall -D__ANDROID__ -DNO_IPV6 -DNO_TFTP -DNO_SCRIPT
|
LOCAL_CFLAGS := -O2 -g -W -Wall -D__ANDROID__ -DNO_IPV6 -DNO_TFTP -DNO_SCRIPT
|
||||||
LOCAL_SYSTEM_SHARED_LIBRARIES := libc libcutils
|
LOCAL_SYSTEM_SHARED_LIBRARIES := libc libcutils
|
||||||
|
|
||||||
|
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog
|
||||||
|
|
||||||
include $(BUILD_EXECUTABLE)
|
include $(BUILD_EXECUTABLE)
|
||||||
@@ -522,7 +522,7 @@
|
|||||||
# If you want to disable negative caching, uncomment this.
|
# If you want to disable negative caching, uncomment this.
|
||||||
#no-negcache
|
#no-negcache
|
||||||
|
|
||||||
# Normally responses which come form /etc/hosts and the DHCP lease
|
# Normally responses which come from /etc/hosts and the DHCP lease
|
||||||
# file have Time-To-Live set as zero, which conventionally means
|
# file have Time-To-Live set as zero, which conventionally means
|
||||||
# do not cache further. If you are happy to trade lower load on the
|
# do not cache further. If you are happy to trade lower load on the
|
||||||
# server for potentially stale date, you can set a time-to-live (in
|
# server for potentially stale date, you can set a time-to-live (in
|
||||||
|
|||||||
+7
-54
@@ -461,7 +461,9 @@ Return an NAPTR DNS record, as specified in RFC3403.
|
|||||||
Return a CNAME record which indicates that <cname> is really
|
Return a CNAME record which indicates that <cname> is really
|
||||||
<target>. There are significant limitations on the target; it must be a
|
<target>. There are significant limitations on the target; it must be a
|
||||||
DNS name which is known to dnsmasq from /etc/hosts (or additional
|
DNS name which is known to dnsmasq from /etc/hosts (or additional
|
||||||
hosts files) or from DHCP. If the target does not satisfy this
|
hosts files), from DHCP or from another
|
||||||
|
.B --cname.
|
||||||
|
If the target does not satisfy this
|
||||||
criteria, the whole cname is ignored. The cname must be unique, but it
|
criteria, the whole cname is ignored. The cname must be unique, but it
|
||||||
is permissable to have more than one cname pointing to the same target.
|
is permissable to have more than one cname pointing to the same target.
|
||||||
.TP
|
.TP
|
||||||
@@ -529,9 +531,9 @@ compiled in and the kernel must have conntrack support
|
|||||||
included and configured. This option cannot be combined with
|
included and configured. This option cannot be combined with
|
||||||
--query-port.
|
--query-port.
|
||||||
.TP
|
.TP
|
||||||
.B \-F, --dhcp-range=[interface:<interface>,][tag:<tag>[,tag:<tag>],][set:<tag],]<start-addr>[,<end-addr>][,<mode>][,<netmask>[,<broadcast>]][,<lease time>]
|
.B \-F, --dhcp-range=[tag:<tag>[,tag:<tag>],][set:<tag],]<start-addr>[,<end-addr>][,<mode>][,<netmask>[,<broadcast>]][,<lease time>]
|
||||||
.TP
|
.TP
|
||||||
.B \-F, --dhcp-range=[interface:<interface>,][tag:<tag>[,tag:<tag>],][set:<tag],]<start-IPv6addr>[,<end-IPv6addr>][,<mode>][,<prefix-len>][,<lease time>]
|
.B \-F, --dhcp-range=[tag:<tag>[,tag:<tag>],][set:<tag],]<start-IPv6addr>[,<end-IPv6addr>][,<mode>][,<prefix-len>][,<lease time>]
|
||||||
|
|
||||||
Enable the DHCP server. Addresses will be given out from the range
|
Enable the DHCP server. Addresses will be given out from the range
|
||||||
<start-addr> to <end-addr> and from statically defined addresses given
|
<start-addr> to <end-addr> and from statically defined addresses given
|
||||||
@@ -624,8 +626,6 @@ can be combined with
|
|||||||
and
|
and
|
||||||
.B slaac.
|
.B slaac.
|
||||||
|
|
||||||
The interface:<interface name> section is not normally used. See the
|
|
||||||
NOTES section for details of this.
|
|
||||||
.TP
|
.TP
|
||||||
.B \-G, --dhcp-host=[<hwaddr>][,id:<client_id>|*][,set:<tag>][,<ipaddr>][,<hostname>][,<lease_time>][,ignore]
|
.B \-G, --dhcp-host=[<hwaddr>][,id:<client_id>|*][,set:<tag>][,<ipaddr>][,<hostname>][,<lease_time>][,ignore]
|
||||||
Specify per host parameters for the DHCP server. This allows a machine
|
Specify per host parameters for the DHCP server. This allows a machine
|
||||||
@@ -1369,12 +1369,11 @@ the relevant link-local address of the machine running dnsmasq is sent
|
|||||||
as recursive DNS server. If provided, the DHCPv6 options dns-server and
|
as recursive DNS server. If provided, the DHCPv6 options dns-server and
|
||||||
domain-search are used for RDNSS and DNSSL.
|
domain-search are used for RDNSS and DNSSL.
|
||||||
.TP
|
.TP
|
||||||
.B --enable-tftp[=<interface>]
|
.B --enable-tftp
|
||||||
Enable the TFTP server function. This is deliberately limited to that
|
Enable the TFTP server function. This is deliberately limited to that
|
||||||
needed to net-boot a client. Only reading is allowed; the tsize and
|
needed to net-boot a client. Only reading is allowed; the tsize and
|
||||||
blksize extensions are supported (tsize is only supported in octet
|
blksize extensions are supported (tsize is only supported in octet
|
||||||
mode). See NOTES section for use of the interface argument.
|
mode).
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B --tftp-root=<directory>[,<interface>]
|
.B --tftp-root=<directory>[,<interface>]
|
||||||
Look for files to transfer using TFTP relative to the given
|
Look for files to transfer using TFTP relative to the given
|
||||||
@@ -1638,52 +1637,6 @@ parameter in a BOOTP request is used as a tag,
|
|||||||
as is the tag "bootp", allowing some control over the options returned to
|
as is the tag "bootp", allowing some control over the options returned to
|
||||||
different classes of hosts.
|
different classes of hosts.
|
||||||
|
|
||||||
.B dhcp-range
|
|
||||||
may have an interface name supplied as
|
|
||||||
"interface:<interface-name>". The semantics if this are as follows:
|
|
||||||
For DHCP, if any other dhcp-range exists _without_ an interface name,
|
|
||||||
then the interface name is ignored and and dnsmasq behaves as if the
|
|
||||||
interface parts did not exist, otherwise DHCP is only provided to
|
|
||||||
interfaces mentioned in dhcp-range
|
|
||||||
declarations. For DNS, if there are no
|
|
||||||
.B --interface
|
|
||||||
or
|
|
||||||
.B --listen-address
|
|
||||||
flags, behaviour is unchanged by the interface part. If either of
|
|
||||||
these flags are present, the interfaces mentioned in
|
|
||||||
dhcp-ranges are added to the set which get DNS service.
|
|
||||||
|
|
||||||
Similarly,
|
|
||||||
.B enable-tftp
|
|
||||||
may take an interface name, which enables TFTP only for a particular
|
|
||||||
interface, ignoring
|
|
||||||
.B --interface
|
|
||||||
or
|
|
||||||
.B --listen-address
|
|
||||||
flags. In addition
|
|
||||||
.B --tftp-secure
|
|
||||||
and
|
|
||||||
.B --tftp-unique-root
|
|
||||||
and
|
|
||||||
.B --tftp-no-blocksize
|
|
||||||
are ignored for requests from such interfaces. (A
|
|
||||||
.B --tftp-root
|
|
||||||
directive giving a root path and an interface should be
|
|
||||||
provided too.)
|
|
||||||
|
|
||||||
These rules may seem odd at first sight, but they
|
|
||||||
allow a single line of the form "dhcp-range=interface:virt0,192.168.0.4,192.168.0.200"
|
|
||||||
to be added to dnsmasq configuration which then supplies
|
|
||||||
DHCP and DNS services to that interface, without affecting
|
|
||||||
what services are supplied to other interfaces and irrespective of
|
|
||||||
the existance or lack of "interface=<interface>"
|
|
||||||
lines elsewhere in the dnsmasq configuration.
|
|
||||||
"enable-tftp=virt0" and "tftp-root=<root>,virt0" do the same job for TFTP.
|
|
||||||
The idea is
|
|
||||||
that such a line can be added automatically by libvirt
|
|
||||||
or equivalent systems, without disturbing any manual
|
|
||||||
configuration.
|
|
||||||
|
|
||||||
.SH EXIT CODES
|
.SH EXIT CODES
|
||||||
.PP
|
.PP
|
||||||
0 - Dnsmasq successfully forked into the background, or terminated
|
0 - Dnsmasq successfully forked into the background, or terminated
|
||||||
|
|||||||
+50
-36
@@ -243,7 +243,7 @@ static int is_outdated_cname_pointer(struct crec *crecp)
|
|||||||
/* NB. record may be reused as DS or DNSKEY, where uid is
|
/* NB. record may be reused as DS or DNSKEY, where uid is
|
||||||
overloaded for something completely different */
|
overloaded for something completely different */
|
||||||
if (crecp->addr.cname.cache &&
|
if (crecp->addr.cname.cache &&
|
||||||
(crecp->addr.cname.cache->flags & (F_IPV4 | F_IPV6)) &&
|
(crecp->addr.cname.cache->flags & (F_IPV4 | F_IPV6 | F_CNAME)) &&
|
||||||
crecp->addr.cname.uid == crecp->addr.cname.cache->uid)
|
crecp->addr.cname.uid == crecp->addr.cname.cache->uid)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -645,13 +645,29 @@ struct crec *cache_find_by_addr(struct crec *crecp, struct all_addr *addr,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void add_hosts_cname(struct crec *target)
|
||||||
|
{
|
||||||
|
struct crec *crec;
|
||||||
|
struct cname *a;
|
||||||
|
|
||||||
|
for (a = daemon->cnames; a; a = a->next)
|
||||||
|
if (hostname_isequal(cache_get_name(target), a->target) &&
|
||||||
|
(crec = whine_malloc(sizeof(struct crec))))
|
||||||
|
{
|
||||||
|
crec->flags = F_FORWARD | F_IMMORTAL | F_NAMEP | F_HOSTS | F_CNAME;
|
||||||
|
crec->name.namep = a->alias;
|
||||||
|
crec->addr.cname.cache = target;
|
||||||
|
crec->addr.cname.uid = target->uid;
|
||||||
|
cache_hash(crec);
|
||||||
|
add_hosts_cname(crec); /* handle chains */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void add_hosts_entry(struct crec *cache, struct all_addr *addr, int addrlen,
|
static void add_hosts_entry(struct crec *cache, struct all_addr *addr, int addrlen,
|
||||||
int index, struct crec **rhash, int hashsz)
|
int index, struct crec **rhash, int hashsz)
|
||||||
{
|
{
|
||||||
struct crec *lookup = cache_find_by_name(NULL, cache_get_name(cache), 0, cache->flags & (F_IPV4 | F_IPV6));
|
struct crec *lookup = cache_find_by_name(NULL, cache_get_name(cache), 0, cache->flags & (F_IPV4 | F_IPV6));
|
||||||
int i, nameexists = 0;
|
int i, nameexists = 0;
|
||||||
struct cname *a;
|
|
||||||
unsigned int j;
|
unsigned int j;
|
||||||
|
|
||||||
/* Remove duplicates in hosts files. */
|
/* Remove duplicates in hosts files. */
|
||||||
@@ -702,16 +718,7 @@ static void add_hosts_entry(struct crec *cache, struct all_addr *addr, int addrl
|
|||||||
|
|
||||||
/* don't need to do alias stuff for second and subsequent addresses. */
|
/* don't need to do alias stuff for second and subsequent addresses. */
|
||||||
if (!nameexists)
|
if (!nameexists)
|
||||||
for (a = daemon->cnames; a; a = a->next)
|
add_hosts_cname(cache);
|
||||||
if (hostname_isequal(cache_get_name(cache), a->target) &&
|
|
||||||
(lookup = whine_malloc(sizeof(struct crec))))
|
|
||||||
{
|
|
||||||
lookup->flags = F_FORWARD | F_IMMORTAL | F_NAMEP | F_HOSTS | F_CNAME;
|
|
||||||
lookup->name.namep = a->alias;
|
|
||||||
lookup->addr.cname.cache = cache;
|
|
||||||
lookup->addr.cname.uid = index;
|
|
||||||
cache_hash(lookup);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int eatspace(FILE *f)
|
static int eatspace(FILE *f)
|
||||||
@@ -1003,13 +1010,41 @@ void cache_unhash_dhcp(void)
|
|||||||
up = &cache->hash_next;
|
up = &cache->hash_next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void add_dhcp_cname(struct crec *target, time_t ttd)
|
||||||
|
{
|
||||||
|
struct crec *aliasc;
|
||||||
|
struct cname *a;
|
||||||
|
|
||||||
|
for (a = daemon->cnames; a; a = a->next)
|
||||||
|
if (hostname_isequal(cache_get_name(target), a->target))
|
||||||
|
{
|
||||||
|
if ((aliasc = dhcp_spare))
|
||||||
|
dhcp_spare = dhcp_spare->next;
|
||||||
|
else /* need new one */
|
||||||
|
aliasc = whine_malloc(sizeof(struct crec));
|
||||||
|
|
||||||
|
if (aliasc)
|
||||||
|
{
|
||||||
|
aliasc->flags = F_FORWARD | F_NAMEP | F_DHCP | F_CNAME;
|
||||||
|
if (ttd == 0)
|
||||||
|
aliasc->flags |= F_IMMORTAL;
|
||||||
|
else
|
||||||
|
aliasc->ttd = ttd;
|
||||||
|
aliasc->name.namep = a->alias;
|
||||||
|
aliasc->addr.cname.cache = target;
|
||||||
|
aliasc->addr.cname.uid = target->uid;
|
||||||
|
cache_hash(aliasc);
|
||||||
|
add_dhcp_cname(aliasc, ttd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void cache_add_dhcp_entry(char *host_name, int prot,
|
void cache_add_dhcp_entry(char *host_name, int prot,
|
||||||
struct all_addr *host_address, time_t ttd)
|
struct all_addr *host_address, time_t ttd)
|
||||||
{
|
{
|
||||||
struct crec *crec = NULL, *aliasc;
|
struct crec *crec = NULL;
|
||||||
unsigned short flags = F_IPV4;
|
unsigned short flags = F_IPV4;
|
||||||
int in_hosts = 0;
|
int in_hosts = 0;
|
||||||
struct cname *a;
|
|
||||||
size_t addrlen = sizeof(struct in_addr);
|
size_t addrlen = sizeof(struct in_addr);
|
||||||
|
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
@@ -1030,7 +1065,6 @@ void cache_add_dhcp_entry(char *host_name, int prot,
|
|||||||
|
|
||||||
inet_ntop(prot, host_address, daemon->addrbuff, ADDRSTRLEN);
|
inet_ntop(prot, host_address, daemon->addrbuff, ADDRSTRLEN);
|
||||||
if (crec->flags & F_CNAME)
|
if (crec->flags & F_CNAME)
|
||||||
|
|
||||||
my_syslog(MS_DHCP | LOG_WARNING,
|
my_syslog(MS_DHCP | LOG_WARNING,
|
||||||
_("%s is a CNAME, not giving it to the DHCP lease of %s"),
|
_("%s is a CNAME, not giving it to the DHCP lease of %s"),
|
||||||
host_name, daemon->addrbuff);
|
host_name, daemon->addrbuff);
|
||||||
@@ -1083,27 +1117,7 @@ void cache_add_dhcp_entry(char *host_name, int prot,
|
|||||||
crec->uid = uid++;
|
crec->uid = uid++;
|
||||||
cache_hash(crec);
|
cache_hash(crec);
|
||||||
|
|
||||||
for (a = daemon->cnames; a; a = a->next)
|
add_dhcp_cname(crec, ttd);
|
||||||
if (hostname_isequal(host_name, a->target))
|
|
||||||
{
|
|
||||||
if ((aliasc = dhcp_spare))
|
|
||||||
dhcp_spare = dhcp_spare->next;
|
|
||||||
else /* need new one */
|
|
||||||
aliasc = whine_malloc(sizeof(struct crec));
|
|
||||||
|
|
||||||
if (aliasc)
|
|
||||||
{
|
|
||||||
aliasc->flags = F_FORWARD | F_NAMEP | F_DHCP | F_CNAME;
|
|
||||||
if (ttd == 0)
|
|
||||||
aliasc->flags |= F_IMMORTAL;
|
|
||||||
else
|
|
||||||
aliasc->ttd = ttd;
|
|
||||||
aliasc->name.namep = a->alias;
|
|
||||||
aliasc->addr.cname.cache = crec;
|
|
||||||
aliasc->addr.cname.uid = crec->uid;
|
|
||||||
cache_hash(aliasc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+7
-2
@@ -33,7 +33,6 @@
|
|||||||
#define SMALLDNAME 40 /* most domain names are smaller than this */
|
#define SMALLDNAME 40 /* most domain names are smaller than this */
|
||||||
#define HOSTSFILE "/etc/hosts"
|
#define HOSTSFILE "/etc/hosts"
|
||||||
#define ETHERSFILE "/etc/ethers"
|
#define ETHERSFILE "/etc/ethers"
|
||||||
#define RUNFILE "/var/run/dnsmasq.pid"
|
|
||||||
#define DEFLEASE 3600 /* default lease time, 1 hour */
|
#define DEFLEASE 3600 /* default lease time, 1 hour */
|
||||||
#define CHUSER "nobody"
|
#define CHUSER "nobody"
|
||||||
#define CHGRP "dip"
|
#define CHGRP "dip"
|
||||||
@@ -158,7 +157,13 @@ RESOLVFILE
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef RUNFILE
|
||||||
|
# if defined(__ANDROID__)
|
||||||
|
# define RUNFILE "/data/dnsmasq.pid"
|
||||||
|
# else
|
||||||
|
# define RUNFILE "/var/run/dnsmasq.pid"
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/* platform dependent options: these are determined automatically below
|
/* platform dependent options: these are determined automatically below
|
||||||
|
|
||||||
|
|||||||
@@ -246,40 +246,6 @@ int match_bytes(struct dhcp_opt *o, unsigned char *p, int len)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void check_dhcp_hosts(int fatal)
|
|
||||||
{
|
|
||||||
/* If the same IP appears in more than one host config, then DISCOVER
|
|
||||||
for one of the hosts will get the address, but REQUEST will be NAKed,
|
|
||||||
since the address is reserved by the other one -> protocol loop.
|
|
||||||
Also check that FQDNs match the domain we are using. */
|
|
||||||
|
|
||||||
struct dhcp_config *configs, *cp;
|
|
||||||
|
|
||||||
for (configs = daemon->dhcp_conf; configs; configs = configs->next)
|
|
||||||
{
|
|
||||||
char *domain;
|
|
||||||
|
|
||||||
if ((configs->flags & DHOPT_BANK) || fatal)
|
|
||||||
{
|
|
||||||
for (cp = configs->next; cp; cp = cp->next)
|
|
||||||
if ((configs->flags & cp->flags & CONFIG_ADDR) && configs->addr.s_addr == cp->addr.s_addr)
|
|
||||||
{
|
|
||||||
if (fatal)
|
|
||||||
die(_("duplicate IP address %s in dhcp-config directive."),
|
|
||||||
inet_ntoa(cp->addr), EC_BADCONF);
|
|
||||||
else
|
|
||||||
my_syslog(MS_DHCP | LOG_ERR, _("duplicate IP address %s in %s."),
|
|
||||||
inet_ntoa(cp->addr), daemon->dhcp_hosts_file);
|
|
||||||
configs->flags &= ~CONFIG_ADDR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* split off domain part */
|
|
||||||
if ((configs->flags & CONFIG_NAME) && (domain = strip_hostname(configs->hostname)))
|
|
||||||
configs->domain = domain;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void dhcp_update_configs(struct dhcp_config *configs)
|
void dhcp_update_configs(struct dhcp_config *configs)
|
||||||
{
|
{
|
||||||
/* Some people like to keep all static IP addresses in /etc/hosts.
|
/* Some people like to keep all static IP addresses in /etc/hosts.
|
||||||
@@ -372,7 +338,6 @@ static int join_multicast_worker(struct in6_addr *local, int prefix,
|
|||||||
char ifrn_name[IFNAMSIZ];
|
char ifrn_name[IFNAMSIZ];
|
||||||
struct ipv6_mreq mreq;
|
struct ipv6_mreq mreq;
|
||||||
int fd, i, max = *((int *)vparam);
|
int fd, i, max = *((int *)vparam);
|
||||||
struct dhcp_context *context;
|
|
||||||
struct iname *tmp;
|
struct iname *tmp;
|
||||||
|
|
||||||
(void)prefix;
|
(void)prefix;
|
||||||
@@ -406,15 +371,6 @@ static int join_multicast_worker(struct in6_addr *local, int prefix,
|
|||||||
if (tmp->name && (strcmp(tmp->name, ifrn_name) == 0))
|
if (tmp->name && (strcmp(tmp->name, ifrn_name) == 0))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* weird libvirt-inspired access control */
|
|
||||||
for (context = daemon->ra_contexts ? daemon->ra_contexts : daemon->dhcp6;
|
|
||||||
context; context = context->next)
|
|
||||||
if (!context->interface || strcmp(context->interface, ifrn_name) == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (!context)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
mreq.ipv6mr_interface = if_index;
|
mreq.ipv6mr_interface = if_index;
|
||||||
|
|
||||||
inet_pton(AF_INET6, ALL_RELAY_AGENTS_AND_SERVERS, &mreq.ipv6mr_multiaddr);
|
inet_pton(AF_INET6, ALL_RELAY_AGENTS_AND_SERVERS, &mreq.ipv6mr_multiaddr);
|
||||||
|
|||||||
-10
@@ -117,8 +117,6 @@ void dhcp_init(void)
|
|||||||
/* Make BPF raw send socket */
|
/* Make BPF raw send socket */
|
||||||
init_bpf();
|
init_bpf();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
check_dhcp_hosts(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void dhcp_packet(time_t now, int pxe_fd)
|
void dhcp_packet(time_t now, int pxe_fd)
|
||||||
@@ -257,14 +255,6 @@ void dhcp_packet(time_t now, int pxe_fd)
|
|||||||
if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
|
if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* weird libvirt-inspired access control */
|
|
||||||
for (context = daemon->dhcp; context; context = context->next)
|
|
||||||
if (!context->interface || strcmp(context->interface, ifr.ifr_name) == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (!context)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* unlinked contexts are marked by context->current == context */
|
/* unlinked contexts are marked by context->current == context */
|
||||||
for (context = daemon->dhcp; context; context = context->next)
|
for (context = daemon->dhcp; context; context = context->next)
|
||||||
context->current = context;
|
context->current = context;
|
||||||
|
|||||||
@@ -111,14 +111,6 @@ void dhcp6_packet(time_t now)
|
|||||||
if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
|
if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* weird libvirt-inspired access control */
|
|
||||||
for (context = daemon->dhcp6; context; context = context->next)
|
|
||||||
if (!context->interface || strcmp(context->interface, ifr.ifr_name) == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (!context)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* unlinked contexts are marked by context->current == context */
|
/* unlinked contexts are marked by context->current == context */
|
||||||
for (context = daemon->dhcp6; context; context = context->next)
|
for (context = daemon->dhcp6; context; context = context->next)
|
||||||
{
|
{
|
||||||
|
|||||||
+4
-5
@@ -120,12 +120,12 @@ int main (int argc, char **argv)
|
|||||||
{
|
{
|
||||||
bind_fallback = 1;
|
bind_fallback = 1;
|
||||||
set_option_bool(OPT_NOWILD);
|
set_option_bool(OPT_NOWILD);
|
||||||
reset_option_bool(OPT_CLVERBIND);
|
reset_option_bool(OPT_CLEVERBIND);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_TFTP
|
#ifndef HAVE_TFTP
|
||||||
if (daemon->tftp_unlimited || daemon->tftp_interfaces)
|
if (option_bool(OPT_TFTP))
|
||||||
die(_("TFTP server not available: set HAVE_TFTP in src/config.h"), NULL, EC_BADCONF);
|
die(_("TFTP server not available: set HAVE_TFTP in src/config.h"), NULL, EC_BADCONF);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -512,7 +512,7 @@ int main (int argc, char **argv)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_TFTP
|
#ifdef HAVE_TFTP
|
||||||
if (daemon->tftp_unlimited || daemon->tftp_interfaces)
|
if (option_bool(OPT_TFTP))
|
||||||
{
|
{
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
struct tftp_prefix *p;
|
struct tftp_prefix *p;
|
||||||
@@ -668,7 +668,7 @@ int main (int argc, char **argv)
|
|||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_TFTP
|
#ifdef HAVE_TFTP
|
||||||
if (daemon->tftp_unlimited || daemon->tftp_interfaces)
|
if (option_bool(OPT_TFTP))
|
||||||
{
|
{
|
||||||
#ifdef FD_SETSIZE
|
#ifdef FD_SETSIZE
|
||||||
if (FD_SETSIZE < (unsigned)max_fd)
|
if (FD_SETSIZE < (unsigned)max_fd)
|
||||||
@@ -1243,7 +1243,6 @@ void clear_cache_and_reload(time_t now)
|
|||||||
dhcp_read_ethers();
|
dhcp_read_ethers();
|
||||||
reread_dhcp();
|
reread_dhcp();
|
||||||
dhcp_update_configs(daemon->dhcp_conf);
|
dhcp_update_configs(daemon->dhcp_conf);
|
||||||
check_dhcp_hosts(0);
|
|
||||||
lease_update_from_configs();
|
lease_update_from_configs();
|
||||||
lease_update_file(now);
|
lease_update_file(now);
|
||||||
lease_update_dns(1);
|
lease_update_dns(1);
|
||||||
|
|||||||
+2
-10
@@ -220,7 +220,8 @@ struct event_desc {
|
|||||||
#define OPT_RA 37
|
#define OPT_RA 37
|
||||||
#define OPT_TFTP_LC 38
|
#define OPT_TFTP_LC 38
|
||||||
#define OPT_CLEVERBIND 39
|
#define OPT_CLEVERBIND 39
|
||||||
#define OPT_LAST 40
|
#define OPT_TFTP 40
|
||||||
|
#define OPT_LAST 41
|
||||||
|
|
||||||
/* extra flags for my_syslog, we use a couple of facilities since they are known
|
/* extra flags for my_syslog, we use a couple of facilities since they are known
|
||||||
not to occupy the same bits as priorities, no matter how syslog.h is set up. */
|
not to occupy the same bits as priorities, no matter how syslog.h is set up. */
|
||||||
@@ -664,7 +665,6 @@ struct dhcp_context {
|
|||||||
time_t ra_time;
|
time_t ra_time;
|
||||||
#endif
|
#endif
|
||||||
int flags;
|
int flags;
|
||||||
char *interface;
|
|
||||||
struct dhcp_netid netid, *filter;
|
struct dhcp_netid netid, *filter;
|
||||||
struct dhcp_context *next, *current;
|
struct dhcp_context *next, *current;
|
||||||
};
|
};
|
||||||
@@ -712,11 +712,6 @@ struct addr_list {
|
|||||||
struct addr_list *next;
|
struct addr_list *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct interface_list {
|
|
||||||
char *interface;
|
|
||||||
struct interface_list *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct tftp_prefix {
|
struct tftp_prefix {
|
||||||
char *interface;
|
char *interface;
|
||||||
char *prefix;
|
char *prefix;
|
||||||
@@ -780,8 +775,6 @@ extern struct daemon {
|
|||||||
unsigned short edns_pktsz;
|
unsigned short edns_pktsz;
|
||||||
char *tftp_prefix;
|
char *tftp_prefix;
|
||||||
struct tftp_prefix *if_prefix; /* per-interface TFTP prefixes */
|
struct tftp_prefix *if_prefix; /* per-interface TFTP prefixes */
|
||||||
struct interface_list *tftp_interfaces; /* interfaces for limited TFTP service */
|
|
||||||
int tftp_unlimited;
|
|
||||||
unsigned int duid_enterprise, duid_config_len;
|
unsigned int duid_enterprise, duid_config_len;
|
||||||
unsigned char *duid_config;
|
unsigned char *duid_config;
|
||||||
|
|
||||||
@@ -1130,7 +1123,6 @@ char *strip_hostname(char *hostname);
|
|||||||
void log_tags(struct dhcp_netid *netid, u32 xid);
|
void log_tags(struct dhcp_netid *netid, u32 xid);
|
||||||
int match_bytes(struct dhcp_opt *o, unsigned char *p, int len);
|
int match_bytes(struct dhcp_opt *o, unsigned char *p, int len);
|
||||||
void dhcp_update_configs(struct dhcp_config *configs);
|
void dhcp_update_configs(struct dhcp_config *configs);
|
||||||
void check_dhcp_hosts(int fatal);
|
|
||||||
void display_opts(void);
|
void display_opts(void);
|
||||||
u16 lookup_dhcp_opt(int prot, char *name);
|
u16 lookup_dhcp_opt(int prot, char *name);
|
||||||
u16 lookup_dhcp_len(int prot, u16 val);
|
u16 lookup_dhcp_len(int prot, u16 val);
|
||||||
|
|||||||
+39
-45
@@ -39,7 +39,6 @@ static struct iovec iov;
|
|||||||
static u32 netlink_pid;
|
static u32 netlink_pid;
|
||||||
|
|
||||||
static int nl_async(struct nlmsghdr *h);
|
static int nl_async(struct nlmsghdr *h);
|
||||||
static void nl_routechange(struct nlmsghdr *h);
|
|
||||||
|
|
||||||
void netlink_init(void)
|
void netlink_init(void)
|
||||||
{
|
{
|
||||||
@@ -342,59 +341,54 @@ static int nl_async(struct nlmsghdr *h)
|
|||||||
}
|
}
|
||||||
else if (h->nlmsg_pid == 0 && h->nlmsg_type == RTM_NEWROUTE)
|
else if (h->nlmsg_pid == 0 && h->nlmsg_type == RTM_NEWROUTE)
|
||||||
{
|
{
|
||||||
nl_routechange(h);
|
/* We arrange to receive netlink multicast messages whenever the network route is added.
|
||||||
|
If this happens and we still have a DNS packet in the buffer, we re-send it.
|
||||||
|
This helps on DoD links, where frequently the packet which triggers dialling is
|
||||||
|
a DNS query, which then gets lost. By re-sending, we can avoid the lookup
|
||||||
|
failing. */
|
||||||
|
struct rtmsg *rtm = NLMSG_DATA(h);
|
||||||
|
|
||||||
|
if (rtm->rtm_type == RTN_UNICAST && rtm->rtm_scope == RT_SCOPE_LINK)
|
||||||
|
{
|
||||||
|
/* Force re-reading resolv file right now, for luck. */
|
||||||
|
daemon->last_resolv = 0;
|
||||||
|
|
||||||
|
if (daemon->srv_save)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
if (daemon->srv_save->sfd)
|
||||||
|
fd = daemon->srv_save->sfd->fd;
|
||||||
|
else if (daemon->rfd_save && daemon->rfd_save->refcount != 0)
|
||||||
|
fd = daemon->rfd_save->fd;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
while(sendto(fd, daemon->packet, daemon->packet_len, 0,
|
||||||
|
&daemon->srv_save->addr.sa, sa_len(&daemon->srv_save->addr)) == -1 && retry_send());
|
||||||
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (h->nlmsg_type == RTM_NEWADDR)
|
|
||||||
{
|
|
||||||
#ifdef HAVE_DHCP6
|
#ifdef HAVE_DHCP6
|
||||||
/* force RAs to sync new network and pick up new interfaces. */
|
else if (h->nlmsg_type == RTM_NEWADDR)
|
||||||
if (daemon->ra_contexts)
|
{
|
||||||
{
|
/* force RAs to sync new network and pick up new interfaces. */
|
||||||
schedule_subnet_map();
|
if (daemon->ra_contexts)
|
||||||
ra_start_unsolicted(dnsmasq_time(), NULL);
|
{
|
||||||
/* cause lease_update_file to run after we return, in case we were called from
|
schedule_subnet_map();
|
||||||
iface_enumerate and can't re-enter it now */
|
ra_start_unsolicted(dnsmasq_time(), NULL);
|
||||||
send_alarm(0, 0);
|
/* cause lease_update_file to run after we return, in case we were called from
|
||||||
}
|
iface_enumerate and can't re-enter it now */
|
||||||
return 1; /* clever bind mode - rescan */
|
send_alarm(0, 0);
|
||||||
}
|
}
|
||||||
|
return 1; /* clever bind mode - rescan */
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We arrange to receive netlink multicast messages whenever the network route is added.
|
|
||||||
If this happens and we still have a DNS packet in the buffer, we re-send it.
|
|
||||||
This helps on DoD links, where frequently the packet which triggers dialling is
|
|
||||||
a DNS query, which then gets lost. By re-sending, we can avoid the lookup
|
|
||||||
failing. */
|
|
||||||
static void nl_routechange(struct nlmsghdr *h)
|
|
||||||
{
|
|
||||||
struct rtmsg *rtm = NLMSG_DATA(h);
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
if (rtm->rtm_type != RTN_UNICAST || rtm->rtm_scope != RT_SCOPE_LINK)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Force re-reading resolv file right now, for luck. */
|
|
||||||
daemon->last_resolv = 0;
|
|
||||||
|
|
||||||
if (daemon->srv_save)
|
|
||||||
{
|
|
||||||
if (daemon->srv_save->sfd)
|
|
||||||
fd = daemon->srv_save->sfd->fd;
|
|
||||||
else if (daemon->rfd_save && daemon->rfd_save->refcount != 0)
|
|
||||||
fd = daemon->rfd_save->fd;
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
|
|
||||||
while(sendto(fd, daemon->packet, daemon->packet_len, 0,
|
|
||||||
&daemon->srv_save->addr.sa, sa_len(&daemon->srv_save->addr)) == -1 && retry_send());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
+20
-43
@@ -117,18 +117,8 @@ int iface_check(int family, struct all_addr *addr, char *name)
|
|||||||
|
|
||||||
if (daemon->if_names || daemon->if_addrs)
|
if (daemon->if_names || daemon->if_addrs)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_DHCP
|
|
||||||
struct dhcp_context *range;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
#ifdef HAVE_DHCP
|
|
||||||
for (range = daemon->dhcp; range; range = range->next)
|
|
||||||
if (range->interface && strcmp(range->interface, name) == 0)
|
|
||||||
ret = 1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (tmp = daemon->if_names; tmp; tmp = tmp->next)
|
for (tmp = daemon->if_names; tmp; tmp = tmp->next)
|
||||||
if (tmp->name && (strcmp(tmp->name, name) == 0))
|
if (tmp->name && (strcmp(tmp->name, name) == 0))
|
||||||
ret = tmp->used = 1;
|
ret = tmp->used = 1;
|
||||||
@@ -161,12 +151,11 @@ static int iface_allowed(struct irec **irecp, int if_index,
|
|||||||
struct irec *iface;
|
struct irec *iface;
|
||||||
int fd, mtu = 0, loopback;
|
int fd, mtu = 0, loopback;
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
int tftp_ok = daemon->tftp_unlimited;
|
int tftp_ok = !!option_bool(OPT_TFTP);
|
||||||
int dhcp_ok = 1;
|
int dhcp_ok = 1;
|
||||||
#ifdef HAVE_DHCP
|
#ifdef HAVE_DHCP
|
||||||
struct iname *tmp;
|
struct iname *tmp;
|
||||||
#endif
|
#endif
|
||||||
struct interface_list *ir = NULL;
|
|
||||||
|
|
||||||
/* check whether the interface IP has been added already
|
/* check whether the interface IP has been added already
|
||||||
we call this routine multiple times. */
|
we call this routine multiple times. */
|
||||||
@@ -220,37 +209,25 @@ static int iface_allowed(struct irec **irecp, int if_index,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_TFTP
|
if (addr->sa.sa_family == AF_INET &&
|
||||||
/* implement wierd TFTP service rules */
|
!iface_check(AF_INET, (struct all_addr *)&addr->in.sin_addr, ifr.ifr_name))
|
||||||
for (ir = daemon->tftp_interfaces; ir; ir = ir->next)
|
return 1;
|
||||||
if (strcmp(ir->interface, ifr.ifr_name) == 0)
|
|
||||||
|
#ifdef HAVE_DHCP
|
||||||
|
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
|
||||||
|
if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
|
||||||
{
|
{
|
||||||
tftp_ok = 1;
|
tftp_ok = 0;
|
||||||
break;
|
dhcp_ok = 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!ir)
|
|
||||||
{
|
|
||||||
if (addr->sa.sa_family == AF_INET &&
|
|
||||||
!iface_check(AF_INET, (struct all_addr *)&addr->in.sin_addr, ifr.ifr_name))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
#ifdef HAVE_DHCP
|
|
||||||
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
|
|
||||||
if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
|
|
||||||
{
|
|
||||||
tftp_ok = 0;
|
|
||||||
dhcp_ok = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
if (addr->sa.sa_family == AF_INET6 &&
|
if (addr->sa.sa_family == AF_INET6 &&
|
||||||
!iface_check(AF_INET6, (struct all_addr *)&addr->in6.sin6_addr, ifr.ifr_name))
|
!iface_check(AF_INET6, (struct all_addr *)&addr->in6.sin6_addr, ifr.ifr_name))
|
||||||
return 1;
|
return 1;
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
/* add to list */
|
/* add to list */
|
||||||
if ((iface = whine_malloc(sizeof(struct irec))))
|
if ((iface = whine_malloc(sizeof(struct irec))))
|
||||||
@@ -485,8 +462,7 @@ static struct listener *create_listeners(union mysockaddr *addr, int do_tftp, in
|
|||||||
void create_wildcard_listeners(void)
|
void create_wildcard_listeners(void)
|
||||||
{
|
{
|
||||||
union mysockaddr addr;
|
union mysockaddr addr;
|
||||||
struct listener *l;
|
struct listener *l, *l6;
|
||||||
int tftp_enabled = daemon->tftp_unlimited || daemon->tftp_interfaces;
|
|
||||||
|
|
||||||
memset(&addr, 0, sizeof(addr));
|
memset(&addr, 0, sizeof(addr));
|
||||||
#ifdef HAVE_SOCKADDR_SA_LEN
|
#ifdef HAVE_SOCKADDR_SA_LEN
|
||||||
@@ -496,7 +472,7 @@ void create_wildcard_listeners(void)
|
|||||||
addr.in.sin_addr.s_addr = INADDR_ANY;
|
addr.in.sin_addr.s_addr = INADDR_ANY;
|
||||||
addr.in.sin_port = htons(daemon->port);
|
addr.in.sin_port = htons(daemon->port);
|
||||||
|
|
||||||
l = create_listeners(&addr, tftp_enabled, 1);
|
l = create_listeners(&addr, !!option_bool(OPT_TFTP), 1);
|
||||||
|
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
memset(&addr, 0, sizeof(addr));
|
memset(&addr, 0, sizeof(addr));
|
||||||
@@ -507,10 +483,11 @@ void create_wildcard_listeners(void)
|
|||||||
addr.in6.sin6_addr = in6addr_any;
|
addr.in6.sin6_addr = in6addr_any;
|
||||||
addr.in6.sin6_port = htons(daemon->port);
|
addr.in6.sin6_port = htons(daemon->port);
|
||||||
|
|
||||||
|
l6 = create_listeners(&addr, !!option_bool(OPT_TFTP), 1);
|
||||||
if (l)
|
if (l)
|
||||||
l->next = create_listeners(&addr, tftp_enabled, 1);
|
l->next = l6;
|
||||||
else
|
else
|
||||||
l = create_listeners(&addr, tftp_enabled, 1);
|
l = l6;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
daemon->listeners = l;
|
daemon->listeners = l;
|
||||||
@@ -544,7 +521,7 @@ void create_bound_listeners(int dienow)
|
|||||||
|
|
||||||
for (if_tmp = daemon->if_addrs; if_tmp; if_tmp = if_tmp->next)
|
for (if_tmp = daemon->if_addrs; if_tmp; if_tmp = if_tmp->next)
|
||||||
if (!if_tmp->used &&
|
if (!if_tmp->used &&
|
||||||
(new = create_listeners(&if_tmp->addr, daemon->tftp_unlimited, dienow)))
|
(new = create_listeners(&if_tmp->addr, !!option_bool(OPT_TFTP), dienow)))
|
||||||
{
|
{
|
||||||
new->iface = NULL;
|
new->iface = NULL;
|
||||||
new->next = daemon->listeners;
|
new->next = daemon->listeners;
|
||||||
|
|||||||
+295
-332
File diff suppressed because it is too large.
Load diff
+1
-8
@@ -119,7 +119,6 @@ void icmp6_packet(void)
|
|||||||
struct sockaddr_in6 from;
|
struct sockaddr_in6 from;
|
||||||
unsigned char *packet;
|
unsigned char *packet;
|
||||||
struct iname *tmp;
|
struct iname *tmp;
|
||||||
struct dhcp_context *context;
|
|
||||||
|
|
||||||
/* Note: use outpacket for input buffer */
|
/* Note: use outpacket for input buffer */
|
||||||
msg.msg_control = control_u.control6;
|
msg.msg_control = control_u.control6;
|
||||||
@@ -157,13 +156,7 @@ void icmp6_packet(void)
|
|||||||
if (tmp->name && (strcmp(tmp->name, interface) == 0))
|
if (tmp->name && (strcmp(tmp->name, interface) == 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* weird libvirt-inspired access control */
|
if (packet[1] != 0)
|
||||||
for (context = daemon->ra_contexts ? daemon->ra_contexts : daemon->dhcp6;
|
|
||||||
context; context = context->next)
|
|
||||||
if (!context->interface || strcmp(context->interface, interface) == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (!context || packet[1] != 0)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (packet[0] == ICMP6_ECHO_REPLY)
|
if (packet[0] == ICMP6_ECHO_REPLY)
|
||||||
|
|||||||
+11
-30
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
#ifdef HAVE_TFTP
|
#ifdef HAVE_TFTP
|
||||||
|
|
||||||
static struct tftp_file *check_tftp_fileperm(ssize_t *len, char *prefix, int special);
|
static struct tftp_file *check_tftp_fileperm(ssize_t *len, char *prefix);
|
||||||
static void free_transfer(struct tftp_transfer *transfer);
|
static void free_transfer(struct tftp_transfer *transfer);
|
||||||
static ssize_t tftp_err(int err, char *packet, char *mess, char *file);
|
static ssize_t tftp_err(int err, char *packet, char *mess, char *file);
|
||||||
static ssize_t tftp_err_oops(char *packet, char *file);
|
static ssize_t tftp_err_oops(char *packet, char *file);
|
||||||
@@ -48,7 +48,7 @@ void tftp_request(struct listener *listen, time_t now)
|
|||||||
struct msghdr msg;
|
struct msghdr msg;
|
||||||
struct iovec iov;
|
struct iovec iov;
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
int is_err = 1, if_index = 0, mtu = 0, special = 0;
|
int is_err = 1, if_index = 0, mtu = 0;
|
||||||
#ifdef HAVE_DHCP
|
#ifdef HAVE_DHCP
|
||||||
struct iname *tmp;
|
struct iname *tmp;
|
||||||
#endif
|
#endif
|
||||||
@@ -61,7 +61,6 @@ void tftp_request(struct listener *listen, time_t now)
|
|||||||
char *name = NULL;
|
char *name = NULL;
|
||||||
char *prefix = daemon->tftp_prefix;
|
char *prefix = daemon->tftp_prefix;
|
||||||
struct tftp_prefix *pref;
|
struct tftp_prefix *pref;
|
||||||
struct interface_list *ir;
|
|
||||||
|
|
||||||
union {
|
union {
|
||||||
struct cmsghdr align; /* this ensures alignment */
|
struct cmsghdr align; /* this ensures alignment */
|
||||||
@@ -115,7 +114,6 @@ void tftp_request(struct listener *listen, time_t now)
|
|||||||
{
|
{
|
||||||
struct cmsghdr *cmptr;
|
struct cmsghdr *cmptr;
|
||||||
int check;
|
int check;
|
||||||
struct interface_list *ir;
|
|
||||||
|
|
||||||
if (msg.msg_controllen < sizeof(struct cmsghdr))
|
if (msg.msg_controllen < sizeof(struct cmsghdr))
|
||||||
return;
|
return;
|
||||||
@@ -200,23 +198,12 @@ void tftp_request(struct listener *listen, time_t now)
|
|||||||
#endif
|
#endif
|
||||||
check = iface_check(AF_INET, (struct all_addr *)&addr.in.sin_addr, name);
|
check = iface_check(AF_INET, (struct all_addr *)&addr.in.sin_addr, name);
|
||||||
|
|
||||||
/* wierd TFTP service override */
|
|
||||||
for (ir = daemon->tftp_interfaces; ir; ir = ir->next)
|
|
||||||
if (strcmp(ir->interface, name) == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (!ir)
|
|
||||||
{
|
|
||||||
if (!daemon->tftp_unlimited || !check)
|
|
||||||
return;
|
|
||||||
|
|
||||||
#ifdef HAVE_DHCP
|
#ifdef HAVE_DHCP
|
||||||
/* allowed interfaces are the same as for DHCP */
|
/* allowed interfaces are the same as for DHCP */
|
||||||
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
|
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
|
||||||
if (tmp->name && (strcmp(tmp->name, name) == 0))
|
if (tmp->name && (strcmp(tmp->name, name) == 0))
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
strncpy(ifr.ifr_name, name, IF_NAMESIZE);
|
strncpy(ifr.ifr_name, name, IF_NAMESIZE);
|
||||||
if (ioctl(listen->tftpfd, SIOCGIFMTU, &ifr) != -1)
|
if (ioctl(listen->tftpfd, SIOCGIFMTU, &ifr) != -1)
|
||||||
@@ -229,11 +216,6 @@ void tftp_request(struct listener *listen, time_t now)
|
|||||||
for (pref = daemon->if_prefix; pref; pref = pref->next)
|
for (pref = daemon->if_prefix; pref; pref = pref->next)
|
||||||
if (strcmp(pref->interface, name) == 0)
|
if (strcmp(pref->interface, name) == 0)
|
||||||
prefix = pref->prefix;
|
prefix = pref->prefix;
|
||||||
|
|
||||||
/* wierd TFTP interfaces disable special options. */
|
|
||||||
for (ir = daemon->tftp_interfaces; ir; ir = ir->next)
|
|
||||||
if (strcmp(ir->interface, name) == 0)
|
|
||||||
special = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (listen->family == AF_INET)
|
if (listen->family == AF_INET)
|
||||||
@@ -325,8 +307,7 @@ void tftp_request(struct listener *listen, time_t now)
|
|||||||
{
|
{
|
||||||
if (strcasecmp(opt, "blksize") == 0)
|
if (strcasecmp(opt, "blksize") == 0)
|
||||||
{
|
{
|
||||||
if ((opt = next(&p, end)) &&
|
if ((opt = next(&p, end)) && !option_bool(OPT_TFTP_NOBLOCK))
|
||||||
(special || !option_bool(OPT_TFTP_NOBLOCK)))
|
|
||||||
{
|
{
|
||||||
transfer->blocksize = atoi(opt);
|
transfer->blocksize = atoi(opt);
|
||||||
if (transfer->blocksize < 1)
|
if (transfer->blocksize < 1)
|
||||||
@@ -363,7 +344,7 @@ void tftp_request(struct listener *listen, time_t now)
|
|||||||
if (prefix[strlen(prefix)-1] != '/')
|
if (prefix[strlen(prefix)-1] != '/')
|
||||||
strncat(daemon->namebuff, "/", (MAXDNAME-1) - strlen(daemon->namebuff));
|
strncat(daemon->namebuff, "/", (MAXDNAME-1) - strlen(daemon->namebuff));
|
||||||
|
|
||||||
if (!special && option_bool(OPT_TFTP_APREF))
|
if (option_bool(OPT_TFTP_APREF))
|
||||||
{
|
{
|
||||||
size_t oldlen = strlen(daemon->namebuff);
|
size_t oldlen = strlen(daemon->namebuff);
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
@@ -390,7 +371,7 @@ void tftp_request(struct listener *listen, time_t now)
|
|||||||
strncat(daemon->namebuff, filename, (MAXDNAME-1) - strlen(daemon->namebuff));
|
strncat(daemon->namebuff, filename, (MAXDNAME-1) - strlen(daemon->namebuff));
|
||||||
|
|
||||||
/* check permissions and open file */
|
/* check permissions and open file */
|
||||||
if ((transfer->file = check_tftp_fileperm(&len, prefix, special)))
|
if ((transfer->file = check_tftp_fileperm(&len, prefix)))
|
||||||
{
|
{
|
||||||
if ((len = get_block(packet, transfer)) == -1)
|
if ((len = get_block(packet, transfer)) == -1)
|
||||||
len = tftp_err_oops(packet, daemon->namebuff);
|
len = tftp_err_oops(packet, daemon->namebuff);
|
||||||
@@ -411,7 +392,7 @@ void tftp_request(struct listener *listen, time_t now)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct tftp_file *check_tftp_fileperm(ssize_t *len, char *prefix, int special)
|
static struct tftp_file *check_tftp_fileperm(ssize_t *len, char *prefix)
|
||||||
{
|
{
|
||||||
char *packet = daemon->packet, *namebuff = daemon->namebuff;
|
char *packet = daemon->packet, *namebuff = daemon->namebuff;
|
||||||
struct tftp_file *file;
|
struct tftp_file *file;
|
||||||
@@ -448,7 +429,7 @@ static struct tftp_file *check_tftp_fileperm(ssize_t *len, char *prefix, int spe
|
|||||||
goto perm;
|
goto perm;
|
||||||
}
|
}
|
||||||
/* in secure mode, must be owned by user running dnsmasq */
|
/* in secure mode, must be owned by user running dnsmasq */
|
||||||
else if (!special && option_bool(OPT_TFTP_SECURE) && uid != statbuf.st_uid)
|
else if (option_bool(OPT_TFTP_SECURE) && uid != statbuf.st_uid)
|
||||||
goto perm;
|
goto perm;
|
||||||
|
|
||||||
/* If we're doing many tranfers from the same file, only
|
/* If we're doing many tranfers from the same file, only
|
||||||
|
|||||||
Reference in new issue
Block a user