mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 02:08:24 +00:00
import of dnsmasq-2.1.tar.gz
This commit is contained in:
48
CHANGELOG
48
CHANGELOG
@@ -666,4 +666,50 @@ release 2.0
|
||||
domains and IPv6 queries. Thanks to Roy Marples for
|
||||
helping to track that one down.
|
||||
|
||||
|
||||
release 2.1
|
||||
Tweak include files to allow compilation on FreeBSD 5
|
||||
|
||||
Fix unaligned access warnings on BSD/Alpha.
|
||||
|
||||
Allow empty DHCP options, like so: dhpc-option=44
|
||||
|
||||
Allow single-byte DHCP options like so: dhcp-option=20,1
|
||||
|
||||
Allow comments on the same line as options in
|
||||
/etc/dnsmasq.conf
|
||||
|
||||
Don't complain when the same name and address is
|
||||
allocated to a host using DHCP and /etc/hosts.
|
||||
|
||||
Added to the example configuration the dnsmasq equivalent
|
||||
of the ISC dhcpd settings given in
|
||||
http://www.samba.org/samba/ftp/docs/textdocs/DHCP-Server-Configuration.txt
|
||||
|
||||
Fixed long-existing strangeness in Linux IPv6 interface
|
||||
discovery code. The flags field in /proc/net/if_inet6 is
|
||||
_not_ the interface flags.
|
||||
|
||||
Fail gracefully when getting an ENODEV error when trying
|
||||
to bind an IPv6 socket, rather than bailing out.
|
||||
|
||||
Allow the name->address mapping for static DHCP leases to
|
||||
be set by /etc/hosts. It's now possible to have
|
||||
dhcp-host=<mac addr>,wibble
|
||||
or even
|
||||
dhcp-host=wibble
|
||||
and in /etc/hosts have
|
||||
wibble 1.2.3.4
|
||||
and for the correct thing to happen. Note that some sort
|
||||
of dhcp-host line is still needed, it's not possible for
|
||||
random host to claim an address in /etc/hosts without
|
||||
some explicit configuration.
|
||||
|
||||
Make 0.0.0.0 in a dhcp-option to mean "the machine
|
||||
running dnsmasq".
|
||||
|
||||
Fix lease time spec when specified in dhcp-range and not
|
||||
in dhcp-host, previously this was always one hour.
|
||||
|
||||
Fix problem with setting domains as "local only".
|
||||
|
||||
Added support for max message size DHCP option.
|
||||
|
||||
28
FAQ
28
FAQ
@@ -154,6 +154,34 @@ A: [note: this was written in September 2003, things may well change.]
|
||||
registries pull the same stunt; there is a list of them all, and
|
||||
the addresses to block, at http://winware.org/bogus-domains.txt
|
||||
|
||||
Q: This new DHCP server is well and good, but it doesn't work for me.
|
||||
What's the problem?
|
||||
|
||||
A: There are a couple of configuration gotchas which have been
|
||||
encountered by people moving from the ISC dhcpd to the dnsmasq
|
||||
integrated DHCP daemon. Both are related to differences in
|
||||
in the way the two daemons bypass the IP stack to do "ground up"
|
||||
IP configuration and can lead to the dnsmasq daemon failing
|
||||
whilst the ISC one works.
|
||||
|
||||
The first thing to check is the broadcast address set for the
|
||||
ethernet interface. This is normally the adddress on the connected
|
||||
network with all ones in the host part. For instance if the
|
||||
address of the ethernet interface is 192.168.55.7 and the netmask
|
||||
is 255.255.255.0 then the broadcast address should be
|
||||
192.168.55.255. Having a broadcast address which is not on the
|
||||
network to which the interface is connected kills things stone
|
||||
dead.
|
||||
|
||||
The second potential problem relates to firewall rules: since the ISC
|
||||
daemon in some configurations bypasses the kernel firewall rules
|
||||
entirely, the ability to run the ISC daemon does not indicate
|
||||
that the current configuration is OK for the dnsmasq daemon.
|
||||
For the dnsmasq daemon to operate it's vital that UDP packets to
|
||||
and from ports 67 and 68 and broadcast packets with source
|
||||
address 0.0.0.0 and destination address 255.255.255.255 are not
|
||||
dropped by iptables/ipchains.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ to store its leases it is necessary to remove the configuration line in
|
||||
|
||||
To enable DHCP, simply add a line like this to /etc/dnsmasq.conf
|
||||
|
||||
dhcp-range=192.168.0.100,192,168.0.200,12h
|
||||
dhcp-range=192.168.0.100,192.168.0.200,12h
|
||||
|
||||
which tells dnsmasq to us the addresses 192.168.0.100 to 192.168.0.200
|
||||
for dynamic IP addresses, and to issue twelve hour leases.
|
||||
@@ -60,6 +60,8 @@ Windows use winipcfg.exe
|
||||
|
||||
|
||||
For more complex DHCP configuration, refer to the doc/setup.html, the
|
||||
dnsmasq manpage and the annotated example configuration file.
|
||||
dnsmasq manpage and the annotated example configuration file. Also
|
||||
note that for some ISC dhcpd to dnsmasq DHCP upgrades there may be
|
||||
firewall issues: see the FAQ for details of this.
|
||||
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
###############################################################################
|
||||
|
||||
Name: dnsmasq
|
||||
Version: 2.0
|
||||
Version: 2.1
|
||||
Release: 1
|
||||
Copyright: GPL
|
||||
Group: System Environment/Daemons
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
###############################################################################
|
||||
|
||||
Name: dnsmasq
|
||||
Version: 2.0
|
||||
Version: 2.1
|
||||
Release: 1
|
||||
Copyright: GPL
|
||||
Group: System Environment/Daemons
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
###############################################################################
|
||||
|
||||
Name: dnsmasq
|
||||
Version: 2.0
|
||||
Version: 2.1
|
||||
Release: 1
|
||||
Copyright: GPL
|
||||
Group: Productivity/Networking/DNS/Servers
|
||||
@@ -100,7 +100,7 @@ rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
%doc CHANGELOG COPYING FAQ doc.html setup.html UPGRADING_to_2.0
|
||||
%doc CHANGELOG COPYING FAQ doc.html setup.html UPGRADING_to_2.0 rpm/README.susefirewall
|
||||
%config /etc/init.d/dnsmasq
|
||||
%config /etc/dnsmasq.conf
|
||||
/usr/sbin/rcdnsmasq
|
||||
|
||||
10
dnsmasq.8
10
dnsmasq.8
@@ -251,7 +251,7 @@ an infinite DHCP lease.
|
||||
.B --dhcp-host=lap,192.168.0.199
|
||||
tells
|
||||
dnsmasq to always allocate the machine lap the IP address
|
||||
192.168.0.199. Addresses allocated like this are not contrained to be
|
||||
192.168.0.199. Addresses allocated like this are not constrained to be
|
||||
in the range given by the --dhcp-range option, but they must be on the
|
||||
network being served by the DHCP server. It is allowed to use client identifiers rather than
|
||||
hardware addresses to identify hosts by prefixing with 'id:'. Thus:
|
||||
@@ -259,8 +259,12 @@ hardware addresses to identify hosts by prefixing with 'id:'. Thus:
|
||||
refers to the host with client identifier 01:02:03:04. It is also
|
||||
allowed to specify the client ID as text, like this:
|
||||
.B --dhcp-host=id:clientidastext,.....
|
||||
If a name appears in /etc/hosts, the associated address can be
|
||||
allocated to a DHCP lease, but only if a
|
||||
.B --dhcp-host
|
||||
option specifying the name also exists.
|
||||
.TP
|
||||
.B \-O, --dhcp-option=<opt>,<value>[,<value>]
|
||||
.B \-O, --dhcp-option=<opt>,[<value>[,<value>]]
|
||||
Specfify different or extra options to DHCP clients. By default,
|
||||
dnsmasq sends some standard options to DHCP clients, the netmask and
|
||||
broadcast address are set to the same as the host running dnsmasq, and
|
||||
@@ -273,6 +277,8 @@ specfied in RFC2132. For example, to set the default route option to
|
||||
.B --dhcp-option=3,192.168.4.4
|
||||
and to set the time-server address to 192.168.0.4, do
|
||||
.B dhcp-option=42,192.168.0.4
|
||||
The special address 0.0.0.0 is taken to mean "the address of the
|
||||
machine running dnsmasq".
|
||||
Be careful: no checking is done that the correct type of data for the
|
||||
option number is sent, and there are option numbers for which it is not
|
||||
possible to generate the correct data type; it is quite possible to
|
||||
|
||||
@@ -31,6 +31,13 @@ filterwin2k
|
||||
# somewhere other that /etc/resolv.conf
|
||||
#resolv-file=
|
||||
|
||||
# By default, dnsmasq will send queries to any of the upstream
|
||||
# servers it knows about and tries to favour servers to are known
|
||||
# to be up. Uncommenting this forces dnsmasq to try each query
|
||||
# with each server strictly in the order they appear in
|
||||
# /etc/resolv.conf
|
||||
#strict-order
|
||||
|
||||
# If you don't want dnsmasq to read /etc/resolv.conf or any other
|
||||
# file, getting its servers for this file instead (see below), then
|
||||
# uncomment this
|
||||
@@ -88,9 +95,10 @@ filterwin2k
|
||||
#dhcp-range=192.168.0.50,192.168.0.150,12h
|
||||
|
||||
# Supply parameters for specified hosts using DHCP. There are lots
|
||||
# of valid alternatives, do we will give examples of each. Note that
|
||||
# of valid alternatives, so we will give examples of each. Note that
|
||||
# IP addresses DO NOT have to be in the range given above, they just
|
||||
# need to be on the same network.
|
||||
# need to be on the same network. The order of the parameters in these
|
||||
# do not matter, it's permissble to give name,adddress and MAC in any order
|
||||
|
||||
# Always allocate the host with ethernet address 11:22:33:44:55:66
|
||||
# The IP address 192.168.0.60
|
||||
@@ -116,15 +124,54 @@ filterwin2k
|
||||
# the IP address 192.168.0.60
|
||||
#dhcp-host=id:marjorie,192.168.0.60
|
||||
|
||||
# Enable the address given for "judge" in /etc/hosts
|
||||
# to be given to a machine presenting the name "judge" when
|
||||
# it asks for a DHCP lease.
|
||||
#dhcp-host=judge
|
||||
|
||||
# Send options to hosts which ask for a DHCP lease.
|
||||
# See RFC 2132 for details of available options.
|
||||
# Note that all the common settings, such as netmask and
|
||||
# broadcast address, DNS server and default route, are given
|
||||
# sane defaults by dnsmasq. You very likely will not need any
|
||||
# any dhcp-options. If you use Windows clients and Samba, there
|
||||
# are some options which are recommended, they are detailed at the
|
||||
# end of this section.
|
||||
# For reference, the common options are:
|
||||
# subnet mask - 1
|
||||
# default router - 3
|
||||
# DNS server - 6
|
||||
# broadcast address - 28
|
||||
|
||||
# Set the NTP time server addresses to 192.168.0.4 and 10.10.0.5
|
||||
#dhcp-option=42,192.168.0.4,10.10.0.5
|
||||
|
||||
# Set the NTP time server address to be the same machine as
|
||||
# is running dnsmasq
|
||||
#dhcp-option=42,0.0.0.0
|
||||
|
||||
# Set the NIS domain name to "welly"
|
||||
#dhcp-option=40,welly
|
||||
|
||||
# Set the default time-to-live to 50
|
||||
#dhcp-option=23,50
|
||||
|
||||
# Set the "all subnets are local" flag
|
||||
#dhcp-option=27,1
|
||||
|
||||
# The following DHCP options set up dnsmasq in the same way as is specified
|
||||
# for the ISC dhcpcd in
|
||||
# http://www.samba.org/samba/ftp/docs/textdocs/DHCP-Server-Configuration.txt
|
||||
# adapted for a typical dnsmasq installation where the host running
|
||||
# dnsmasq is also the host running samba.
|
||||
# you may want to uncomment them if you use Windows clients and Samba.
|
||||
#dhcp-option=19,0 # option ip-forwarding off
|
||||
#dhcp-option=44,0.0.0.0 # set netbios-over-TCP/IP nameserver(s) aka WINS server(s)
|
||||
#dhcp-option=45,0.0.0.0 # netbios datagram distribution server
|
||||
#dhcp-option=46,8 # netbios node type
|
||||
#dhcp-option=47 # empty netbios scope.
|
||||
|
||||
|
||||
# Set the boot filename and tftpd server name and address
|
||||
# for BOOTP. You will only need this is you want to
|
||||
# boot machines over the network.
|
||||
@@ -133,14 +180,10 @@ filterwin2k
|
||||
# The DHCP server needs somewhere on disk to keep its lease database.
|
||||
# This defaults to a sane location, but if you want to change it, use
|
||||
# the line below.
|
||||
#dhcp-leasefile=/var/lib/dnsmasq/leases
|
||||
|
||||
# Override the default route (which is normally automagically set
|
||||
# to be the machine running dnsmasq
|
||||
#dhcp-option=2,192,168.4.4
|
||||
#dhcp-leasefile=/var/lib/misc/dnsmasq.leases
|
||||
|
||||
# Set the cachesize here.
|
||||
#cache-size=600
|
||||
#cache-size=150
|
||||
|
||||
# If you want to disable negative caching, uncomment this.
|
||||
#no-negcache
|
||||
|
||||
27
rpm/README.susefirewall
Normal file
27
rpm/README.susefirewall
Normal file
@@ -0,0 +1,27 @@
|
||||
This is a patch against SuSEfirewall2-3.1-206 (SuSE 9.x and older)
|
||||
It fixes the depancy from the dns daemon name 'named'
|
||||
After appending the patch, the SuSEfirewall is again able to autodetect
|
||||
the dnsmasq named service.
|
||||
This is a very old bug in the SuSEfirewall script.
|
||||
The SuSE people think the name of the dns server will allways 'named'
|
||||
|
||||
|
||||
--- /sbin/SuSEfirewall2.orig 2004-01-23 13:30:09.000000000 +0100
|
||||
+++ /sbin/SuSEfirewall2 2004-01-23 13:31:56.000000000 +0100
|
||||
@@ -764,7 +764,7 @@
|
||||
echo 'FW_ALLOW_INCOMING_HIGHPORTS_UDP should be set to yes, if you are running a DNS server!'
|
||||
|
||||
test "$FW_SERVICE_AUTODETECT" = yes -o "$FW_SERVICE_AUTODETECT" = dmz -o "$FW_SERVICE_AUTODETECT" = ext && {
|
||||
- test "$FW_SERVICE_DNS" = no -a '!' "$START_NAMED" = no && check_srv named && {
|
||||
+ test "$FW_SERVICE_DNS" = no -a '!' "$START_NAMED" = no && check_srv dnsmasq && {
|
||||
echo -e 'Warning: detected activated named, enabling FW_SERVICE_DNS!
|
||||
You still have to allow tcp/udp port 53 on internal, dmz and/or external.'
|
||||
FW_SERVICE_DNS=$FW_SERVICE_AUTODETECT
|
||||
@@ -878,7 +878,7 @@
|
||||
test -e /etc/resolv.conf || echo "Warning: /etc/resolv.conf not found"
|
||||
# Get ports/IP bindings of NAMED/SQUID
|
||||
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 | \
|
||||
- $AWK -F: '/^named .* UDP / {print $2}'| $GREP -vw 53 | $SORT -un`
|
||||
+ $AWK -F: '/^dnsmasq .* UDP / {print $2}'| $GREP -vw 53 | $SORT -un`
|
||||
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 | \
|
||||
$AWK -F: '/^squid .* UDP/ {print $2}'| $SORT -un`
|
||||
@@ -639,7 +639,10 @@ void cache_add_dhcp_entry(char *host_name, struct in_addr *host_address, time_t
|
||||
if ((crec = cache_find_by_name(NULL, host_name, 0, F_IPV4)))
|
||||
{
|
||||
if (crec->flags & F_HOSTS)
|
||||
syslog(LOG_WARNING, "Ignoring DHCP lease for %s because it clashes with an /etc/hosts entry.", host_name);
|
||||
{
|
||||
if (crec->addr.addr.addr4.s_addr != host_address->s_addr)
|
||||
syslog(LOG_WARNING, "Not naming DHCP lease for %s because it clashes with an /etc/hosts entry.", host_name);
|
||||
}
|
||||
else if (!(crec->flags & F_DHCP))
|
||||
{
|
||||
if (crec->flags & F_NEG)
|
||||
@@ -650,7 +653,7 @@ void cache_add_dhcp_entry(char *host_name, struct in_addr *host_address, time_t
|
||||
goto newrec;
|
||||
}
|
||||
else
|
||||
syslog(LOG_WARNING, "Ignoring DHCP lease for %s because it clashes with a cached name.", cache_get_name(crec));
|
||||
syslog(LOG_WARNING, "Not naming DHCP lease for %s because it clashes with a cached name.", cache_get_name(crec));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -671,7 +674,7 @@ void cache_add_dhcp_entry(char *host_name, struct in_addr *host_address, time_t
|
||||
crec->flags |= F_IMMORTAL;
|
||||
else
|
||||
crec->ttd = ttd;
|
||||
memcpy(&crec->addr, host_address, INADDRSZ);
|
||||
crec->addr.addr.addr4 = *host_address;
|
||||
crec->name.namep = host_name;
|
||||
crec->prev = dhcp_inuse;
|
||||
dhcp_inuse = crec;
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
/* Author's email: simon@thekelleys.org.uk */
|
||||
|
||||
#define VERSION "2.0"
|
||||
#define VERSION "2.1"
|
||||
|
||||
#define FTABSIZ 150 /* max number of outstanding requests */
|
||||
#define TIMEOUT 40 /* drop queries after TIMEOUT seconds */
|
||||
|
||||
15
src/dhcp.c
15
src/dhcp.c
@@ -269,5 +269,18 @@ struct dhcp_config *find_config(struct dhcp_config *configs,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void set_configs_from_cache(struct dhcp_config *configs)
|
||||
/* Some people like to keep all static IP addresses in /etc/hosts.
|
||||
This goes through /etc/hosts and sets static addresses for any DHCP config
|
||||
records which don't have an address and whose name matches. */
|
||||
{
|
||||
struct dhcp_config *config;
|
||||
struct crec *crec;
|
||||
|
||||
for (config = configs; config; config = config->next)
|
||||
if (config->addr.s_addr == 0 && config->hostname &&
|
||||
(crec = cache_find_by_name(NULL, config->hostname, 0, F_IPV4)) &&
|
||||
(crec->flags & F_HOSTS))
|
||||
config->addr = crec->addr.addr.addr4;
|
||||
}
|
||||
|
||||
|
||||
@@ -158,6 +158,7 @@ int main (int argc, char **argv)
|
||||
if (!dhcp_tmp->iface)
|
||||
die("No suitable interface for DHCP service at address %s", inet_ntoa(dhcp_tmp->start));
|
||||
|
||||
set_configs_from_cache(dhcp_configs);
|
||||
leasefd = lease_init(lease_file, domain_suffix, dnamebuff, packet, time(NULL), dhcp_configs);
|
||||
lease_update_dns(1); /* must follow cache_init and lease_init */
|
||||
}
|
||||
@@ -270,6 +271,7 @@ int main (int argc, char **argv)
|
||||
if (sighup)
|
||||
{
|
||||
cache_reload(options, dnamebuff, domain_suffix, addn_hosts);
|
||||
set_configs_from_cache(dhcp_configs);
|
||||
lease_update_dns(1);
|
||||
if (resolv && (options & OPT_NO_POLL))
|
||||
servers = last_server =
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#define _XOPEN_SOURCE 600
|
||||
/* but then DNS headers don't compile without.... */
|
||||
#define _BSD_SOURCE
|
||||
/* and also, on FreeBSD 5.0 ..... */
|
||||
#define __BSD_VISIBLE 1
|
||||
|
||||
/* get these before config.h for IPv6 stuff... */
|
||||
#include <sys/types.h>
|
||||
@@ -26,7 +28,6 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -229,8 +230,7 @@ struct dhcp_config {
|
||||
};
|
||||
|
||||
struct dhcp_opt {
|
||||
unsigned char opt;
|
||||
unsigned char len;
|
||||
int opt, len, is_addr;
|
||||
unsigned char *val;
|
||||
struct dhcp_opt *next;
|
||||
};
|
||||
@@ -360,6 +360,7 @@ struct dhcp_config *find_config(struct dhcp_config *configs,
|
||||
unsigned char *clid, int clid_len,
|
||||
unsigned char *hwaddr, char *hostname);
|
||||
|
||||
void set_configs_from_cache(struct dhcp_config *configs);
|
||||
/* lease.c */
|
||||
void lease_update_dns(int force_dns);
|
||||
int lease_init(char *lease_file, char *domain, char *buff,
|
||||
|
||||
@@ -132,6 +132,7 @@ struct server *forward_query(int udpfd, union mysockaddr *udpaddr, HEADER *heade
|
||||
flags = 0; /* may be better match from previous literal */
|
||||
domain = serv->domain;
|
||||
matchlen = domainlen;
|
||||
type = SERV_HAS_DOMAIN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
143
src/network.c
143
src/network.c
@@ -76,12 +76,14 @@ static char *add_iface(struct irec **list, unsigned int flags,
|
||||
specific addresses even if BIND is running and has bound *:53 */
|
||||
opt = 1;
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
|
||||
bind(fd, &addr->sa, sa_len(addr)))
|
||||
bind(fd, &addr->sa, sa_len(addr)) == -1)
|
||||
{
|
||||
int errsave = errno;
|
||||
close(fd);
|
||||
errno = errsave;
|
||||
return "failed to bind socket: %s";
|
||||
/* IPv6 interfaces sometimes return ENODEV to bind() for unknown
|
||||
(to me) reasons. Don't treat that as fatal. */
|
||||
return errno == ENODEV ? NULL : "failed to bind socket: %s";
|
||||
}
|
||||
|
||||
/* If OK, add it to the head of the list */
|
||||
@@ -119,6 +121,7 @@ char *enumerate_interfaces(struct irec **interfacep,
|
||||
struct irec *iface, *prev;
|
||||
char *buf, *ptr, *err = NULL;
|
||||
struct ifconf ifc;
|
||||
struct ifreq *ifr = NULL;
|
||||
int fd = socket(PF_INET, SOCK_DGRAM, 0);
|
||||
int rawfd = -1;
|
||||
|
||||
@@ -158,12 +161,22 @@ char *enumerate_interfaces(struct irec **interfacep,
|
||||
|
||||
for (ptr = buf; ptr < buf + ifc.ifc_len; )
|
||||
{
|
||||
struct ifreq *ifr = (struct ifreq *) ptr;
|
||||
union mysockaddr addr;
|
||||
|
||||
#ifdef HAVE_SOCKADDR_SA_LEN
|
||||
ptr += ifr->ifr_addr.sa_len + IF_NAMESIZE;
|
||||
/* subsequent entries may not be aligned, so copy into
|
||||
an aligned buffer to avoid nasty complaints about
|
||||
unaligned accesses. */
|
||||
int ifr_len = ((struct ifreq *)ptr)->ifr_addr.sa_len + IF_NAMESIZE;
|
||||
if (!(ifr = realloc(ifr, ifr_len)))
|
||||
{
|
||||
err = "cannot allocate buffer";
|
||||
goto end;
|
||||
}
|
||||
|
||||
memcpy(ifr, ptr, ifr_len);
|
||||
ptr += ifr_len;
|
||||
#else
|
||||
ifr = (struct ifreq *)ptr;
|
||||
ptr += sizeof(struct ifreq);
|
||||
#endif
|
||||
|
||||
@@ -198,6 +211,54 @@ char *enumerate_interfaces(struct irec **interfacep,
|
||||
&addr, names, addrs, except)))
|
||||
goto end;
|
||||
|
||||
#if defined(HAVE_LINUX_IPV6_PROC) && defined(HAVE_IPV6)
|
||||
/* IPv6 addresses don't seem to work with SIOCGIFCONF. Barf */
|
||||
/* This code snarfed from net-tools 1.60 and certainly linux specific, though
|
||||
it shouldn't break on other Unices, and their SIOGIFCONF might work. */
|
||||
{
|
||||
FILE *f = fopen(IP6INTERFACES, "r");
|
||||
int found = 0;
|
||||
|
||||
if (f)
|
||||
{
|
||||
unsigned int plen, scope, flags, if_idx;
|
||||
char devname[20], addrstring[32];
|
||||
|
||||
while (fscanf(f, "%32s %02x %02x %02x %02x %20s\n",
|
||||
addrstring, &if_idx, &plen, &scope, &flags, devname) != EOF)
|
||||
{
|
||||
if (strcmp(devname, ifr->ifr_name) == 0)
|
||||
{
|
||||
int i;
|
||||
unsigned char *addr6p = (unsigned char *) &addr.in6.sin6_addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sa.sa_family = AF_INET6;
|
||||
for (i=0; i<16; i++)
|
||||
{
|
||||
unsigned int byte;
|
||||
sscanf(addrstring+i+i, "%02x", &byte);
|
||||
addr6p[i] = byte;
|
||||
}
|
||||
addr.in6.sin6_port = htons(port);
|
||||
addr.in6.sin6_flowinfo = htonl(0);
|
||||
addr.in6.sin6_scope_id = htonl(scope);
|
||||
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
if (found &&
|
||||
(err = add_iface(interfacep, ifr->ifr_flags, ifr->ifr_name,
|
||||
&addr, names, addrs, except)))
|
||||
goto end;
|
||||
}
|
||||
|
||||
#endif /* LINUX */
|
||||
|
||||
/* dhcp is non-null only on the first call: set up the relevant
|
||||
interface-related DHCP stuff here. DHCP is IPv4 only.
|
||||
Because errors here are ultimately fatal we can return directly and not bother
|
||||
@@ -289,32 +350,48 @@ char *enumerate_interfaces(struct irec **interfacep,
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_BPF
|
||||
/* now go through the interfaces again, looking for AF_LINK records
|
||||
to get hardware addresses from */
|
||||
for (ptr = buf; ptr < buf + ifc.ifc_len; )
|
||||
{
|
||||
struct ifreq *ifr = (struct ifreq *) ptr;
|
||||
struct dhcp_context *context;
|
||||
|
||||
#ifdef HAVE_SOCKADDR_SA_LEN
|
||||
ptr += ifr->ifr_addr.sa_len + IF_NAMESIZE;
|
||||
/* subsequent entries may not be aligned, so copy into
|
||||
an aligned buffer to avoid nasty complaints about
|
||||
unaligned accesses. */
|
||||
int ifr_len = ((struct ifreq *)ptr)->ifr_addr.sa_len + IF_NAMESIZE;
|
||||
if (!(ifr = realloc(ifr, ifr_len)))
|
||||
{
|
||||
err = "cannot allocate buffer";
|
||||
goto end;
|
||||
}
|
||||
|
||||
memcpy(ifr, ptr, ifr_len);
|
||||
ptr += ifr_len;
|
||||
#else
|
||||
ifr = (struct ifreq *)ptr;
|
||||
ptr += sizeof(struct ifreq);
|
||||
#endif
|
||||
|
||||
if (ifr->ifr_addr.sa_family == AF_LINK)
|
||||
for (context = dhcp; context; context = context->next)
|
||||
if (context->iface && strcmp(context->iface, ifr->ifr_name) == 0)
|
||||
memcpy(context->hwaddr, LLADDR((struct sockaddr_dl *)&ifr->ifr_addr), ETHER_ADDR_LEN);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
end:
|
||||
errsave = errno; /* since errno gets overwritten by close */
|
||||
if (buf)
|
||||
free(buf);
|
||||
#ifdef HAVE_SOCKADDR_SA_LEN
|
||||
if (ifr)
|
||||
free(ifr);
|
||||
#endif
|
||||
close(fd);
|
||||
if (err)
|
||||
{
|
||||
@@ -322,54 +399,6 @@ char *enumerate_interfaces(struct irec **interfacep,
|
||||
return err;
|
||||
}
|
||||
|
||||
#if defined(HAVE_LINUX_IPV6_PROC) && defined(HAVE_IPV6)
|
||||
/* IPv6 addresses don't seem to work with SIOCGIFCONF. Barf */
|
||||
/* This code snarfed from net-tools 1.60 and certainly linux specific, though
|
||||
it shouldn't break on other Unices, and their SIOGIFCONF might work. */
|
||||
{
|
||||
FILE *f = fopen(IP6INTERFACES, "r");
|
||||
|
||||
if (f)
|
||||
{
|
||||
union mysockaddr addr;
|
||||
unsigned int plen, scope, flags, if_idx;
|
||||
char devname[20], addrstring[32];
|
||||
|
||||
while (fscanf(f, "%32s %02x %02x %02x %02x %20s\n",
|
||||
addrstring, &if_idx, &plen, &scope, &flags, devname) != EOF)
|
||||
{
|
||||
int i;
|
||||
unsigned char *addr6p = (unsigned char *) &addr.in6.sin6_addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sa.sa_family = AF_INET6;
|
||||
for (i=0; i<16; i++)
|
||||
{
|
||||
unsigned int byte;
|
||||
sscanf(addrstring+i+i, "%02x", &byte);
|
||||
addr6p[i] = byte;
|
||||
}
|
||||
#ifdef HAVE_SOCKADDR_SA_LEN
|
||||
/* For completeness - should never be defined on Linux. */
|
||||
addr.in6.sin6_len = sizeof(struct sockaddr_in6);
|
||||
#endif
|
||||
addr.in6.sin6_port = htons(port);
|
||||
addr.in6.sin6_flowinfo = htonl(0);
|
||||
addr.in6.sin6_scope_id = htonl(scope);
|
||||
|
||||
if ((err = add_iface(interfacep, flags, devname, &addr, names, addrs, except)))
|
||||
{
|
||||
errsave = errno;
|
||||
fclose(f);
|
||||
errno = errsave;
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
#endif /* LINUX */
|
||||
|
||||
/* now remove interfaces which were not found on this scan */
|
||||
for(prev = NULL, iface = *interfacep; iface; )
|
||||
{
|
||||
|
||||
64
src/option.c
64
src/option.c
@@ -175,14 +175,18 @@ unsigned int read_opts (int argc, char **argv, char *buff, struct resolvc **reso
|
||||
else
|
||||
{
|
||||
char *p;
|
||||
/* dump comments */
|
||||
for (p = buff; *p; p++)
|
||||
if (*p == '#')
|
||||
*p = 0;
|
||||
/* fgets gets end of line char too. */
|
||||
while (strlen(buff) > 0 &&
|
||||
(buff[strlen(buff)-1] == '\n' ||
|
||||
buff[strlen(buff)-1] == ' ' ||
|
||||
buff[strlen(buff)-1] == '\t'))
|
||||
buff[strlen(buff)-1] = 0;
|
||||
if (*buff == '#' || *buff == 0)
|
||||
continue; /* comment */
|
||||
if (*buff == 0)
|
||||
continue;
|
||||
if ((p=strchr(buff, '=')))
|
||||
{
|
||||
optarg = p+1;
|
||||
@@ -639,7 +643,7 @@ unsigned int read_opts (int argc, char **argv, char *buff, struct resolvc **reso
|
||||
new->clid = NULL;
|
||||
new->hostname = NULL;
|
||||
new->addr.s_addr = 0;
|
||||
new->lease_time = DEFLEASE;
|
||||
new->lease_time = 0;
|
||||
|
||||
a[0] = optarg;
|
||||
for (k = 1; k < 4; k++)
|
||||
@@ -706,8 +710,8 @@ unsigned int read_opts (int argc, char **argv, char *buff, struct resolvc **reso
|
||||
{
|
||||
case 'h':
|
||||
case 'H':
|
||||
fac *= 60;
|
||||
/* fall through */
|
||||
fac *= 60;
|
||||
/* fall through */
|
||||
case 'm':
|
||||
case 'M':
|
||||
fac *= 60;
|
||||
@@ -717,7 +721,7 @@ unsigned int read_opts (int argc, char **argv, char *buff, struct resolvc **reso
|
||||
}
|
||||
|
||||
for (cp = a[j]; *cp; cp++)
|
||||
if (!isdigit(*cp))
|
||||
if (!isdigit(*cp) && *cp != ' ')
|
||||
break;
|
||||
|
||||
if (*cp)
|
||||
@@ -739,24 +743,33 @@ unsigned int read_opts (int argc, char **argv, char *buff, struct resolvc **reso
|
||||
{
|
||||
struct dhcp_opt *new = safe_malloc(sizeof(struct dhcp_opt));
|
||||
char *cp, *comma = strchr(optarg, ',');
|
||||
int addrs;
|
||||
int addrs, is_addr;
|
||||
|
||||
new->next = *dhcp_opts;
|
||||
new->len = 0;
|
||||
new->is_addr = 0;
|
||||
*dhcp_opts = new;
|
||||
|
||||
if (!comma || (*comma = 0) || (new->opt = atoi(optarg)) == 0)
|
||||
if ((new->opt = atoi(optarg)) == 0)
|
||||
{
|
||||
option = '?';
|
||||
break;
|
||||
}
|
||||
|
||||
if (!comma)
|
||||
break;
|
||||
|
||||
*comma = 0;
|
||||
|
||||
/* check for non-address list characters */
|
||||
for (addrs = 1, cp = comma+1; *cp; cp++)
|
||||
for (addrs = 1, is_addr = 0, cp = comma+1; *cp; cp++)
|
||||
if (*cp == ',')
|
||||
addrs++;
|
||||
else if (!(*cp == '.' || *cp == ' ' || (*cp >='0' && *cp <= '9')))
|
||||
break;
|
||||
|
||||
else if (*cp == '.')
|
||||
is_addr = 1;
|
||||
|
||||
if (*cp)
|
||||
{
|
||||
/* text arg */
|
||||
@@ -768,17 +781,28 @@ unsigned int read_opts (int argc, char **argv, char *buff, struct resolvc **reso
|
||||
{
|
||||
struct in_addr in;
|
||||
unsigned char *op;
|
||||
new->len = INADDRSZ * addrs;
|
||||
new->val = op = safe_malloc(new->len);
|
||||
while (addrs--)
|
||||
|
||||
if (addrs == 1 && !is_addr)
|
||||
{
|
||||
cp = comma;
|
||||
if (cp && (comma = strchr(cp+1, ',')))
|
||||
*comma = 0;
|
||||
if (cp && (in.s_addr = inet_addr(cp+1)) == (in_addr_t)-1)
|
||||
option = '?';
|
||||
memcpy(op, &in, INADDRSZ);
|
||||
op += INADDRSZ;
|
||||
new->len = 1;
|
||||
new->val = safe_malloc(1);
|
||||
*(new->val) = atoi(comma+1);
|
||||
}
|
||||
else
|
||||
{
|
||||
new->len = INADDRSZ * addrs;
|
||||
new->val = op = safe_malloc(new->len);
|
||||
new->is_addr = 1;
|
||||
while (addrs--)
|
||||
{
|
||||
cp = comma;
|
||||
if (cp && (comma = strchr(cp+1, ',')))
|
||||
*comma = 0;
|
||||
if (cp && (in.s_addr = inet_addr(cp+1)) == (in_addr_t)-1)
|
||||
option = '?';
|
||||
memcpy(op, &in, INADDRSZ);
|
||||
op += INADDRSZ;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -139,7 +139,7 @@ int dhcp_reply(struct dhcp_context *context, struct dhcp_packet *mess,
|
||||
|
||||
/* search again now we have a hostname */
|
||||
config = find_config(dhcp_configs, context, clid, clid_len, mess->chaddr, hostname);
|
||||
def_time = config ? config->lease_time : context->lease_time;
|
||||
def_time = config && config->lease_time ? config->lease_time : context->lease_time;
|
||||
|
||||
if ((opt = option_find(mess, sz, OPTION_LEASE_TIME)))
|
||||
{
|
||||
@@ -444,6 +444,9 @@ static unsigned char *do_req_options(struct dhcp_context *context,
|
||||
if (!req_options)
|
||||
return p;
|
||||
|
||||
if (in_list(req_options, OPTION_MAXMESSAGE))
|
||||
p = option_put(p, end, OPTION_MAXMESSAGE, 2, sizeof(struct udp_dhcp_packet));
|
||||
|
||||
if (in_list(req_options, OPTION_NETMASK) &&
|
||||
!option_find2(config_opts, OPTION_NETMASK))
|
||||
p = option_put(p, end, OPTION_NETMASK, INADDRSZ, ntohl(context->netmask.s_addr));
|
||||
@@ -484,12 +487,34 @@ static unsigned char *do_req_options(struct dhcp_context *context,
|
||||
for (i = 0; req_options[i] != OPTION_END; i++)
|
||||
{
|
||||
struct dhcp_opt *opt = option_find2(config_opts, req_options[i]);
|
||||
if (req_options[i] != OPTION_HOSTNAME && opt && (p + opt->len + 2 < end))
|
||||
if (req_options[i] != OPTION_HOSTNAME &&
|
||||
req_options[i] != OPTION_MAXMESSAGE &&
|
||||
opt && (p + opt->len + 2 < end))
|
||||
{
|
||||
*(p++) = opt->opt;
|
||||
*(p++) = opt->len;
|
||||
memcpy(p, opt->val, opt->len);
|
||||
p += opt->len;
|
||||
if (opt->len != 0)
|
||||
{
|
||||
if (opt->is_addr)
|
||||
{
|
||||
int j;
|
||||
struct in_addr *a = (struct in_addr *)opt->val;
|
||||
for (j = 0; j < opt->len; j+=INADDRSZ, a++)
|
||||
{
|
||||
/* zero means "self" */
|
||||
if (a->s_addr == 0)
|
||||
memcpy(p, &context->serv_addr, INADDRSZ);
|
||||
else
|
||||
memcpy(p, a, INADDRSZ);
|
||||
p += INADDRSZ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(p, opt->val, opt->len);
|
||||
p += opt->len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user