Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
D
Dnsmasq
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nanahira
Dnsmasq
Commits
f6b7dc47
Commit
f6b7dc47
authored
Jan 23, 2005
by
Simon Kelley
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
import of dnsmasq-2.20.tar.gz
parent
bb01cb96
Changes
19
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
903 additions
and
435 deletions
+903
-435
CHANGELOG
CHANGELOG
+46
-3
dnsmasq-rh.spec
dnsmasq-rh.spec
+1
-1
dnsmasq-suse.spec
dnsmasq-suse.spec
+1
-1
dnsmasq.8
dnsmasq.8
+63
-14
dnsmasq.conf.example
dnsmasq.conf.example
+48
-11
rpm/dnsmasq-SuSE.patch
rpm/dnsmasq-SuSE.patch
+0
-11
src/cache.c
src/cache.c
+60
-18
src/config.h
src/config.h
+2
-3
src/dhcp.c
src/dhcp.c
+49
-3
src/dnsmasq.c
src/dnsmasq.c
+33
-38
src/dnsmasq.h
src/dnsmasq.h
+30
-9
src/forward.c
src/forward.c
+28
-9
src/isc.c
src/isc.c
+1
-1
src/lease.c
src/lease.c
+1
-1
src/network.c
src/network.c
+80
-33
src/option.c
src/option.c
+142
-20
src/rfc1035.c
src/rfc1035.c
+299
-215
src/rfc2131.c
src/rfc2131.c
+12
-39
src/util.c
src/util.c
+7
-5
No files found.
CHANGELOG
View file @
f6b7dc47
...
...
@@ -1267,7 +1267,7 @@ version 2.17
already a fatal error when bind-interfaces is set.)
Allow the --interface and --except-interface options to
take a comma-sep
e
rated list of interfaces.
take a comma-sep
a
rated list of interfaces.
Tweak --dhcp-userclass matching code to work with the
ISC dhclient which violates RFC3004 unless its
...
...
@@ -1324,7 +1324,50 @@ version 2.19
option, send the /etc/hosts name as the hostname in
the DHCP lease. Thanks to Will Murname for the suggestion.
version 2.20
Allow more than one instance of dnsmasq to run on a
machine, each providing DHCP service on a different
interface, provided that --bind-interfaces is set. This
configuration used to work, but regressed in version 2.14
Fix compilation on Mac OS X. Thanks to Kevin Bullock.
Protect against overlong names and overlong
labels in configuration and from DHCP.
Fix interesting corner case in CNAME handling. This occurs
when a CNAME has a target which "shadowed" by a name in
/etc/hosts or from DHCP. Resolving the CNAME would sneak
the upstream value of the CNAME's target into the cache,
alongside the local value. Now that doesn't happen, though
resolving the CNAME still gives the unshadowed value. This
is arguably wrong but rather difficult to fix. The main
thing is to avoid getting strange results for the target
due to the cache pollution when resolving the
CNAME. Thanks to Pierre Habouzit for exploring the corner
and submitting a very clear bug report.
Fix subtle bug in the DNS packet parsing code. It's almost
impossible to describe this succinctly, but the one known
manifestation is the inability to cache the A record for
www.apple.com. Thanks to Bob Alexander for spotting that.
Support SRV records. Thanks to Robert Kean for the patches
for this.
Fixed sign confusion in the vendor-id matching code which
could cause crashes sometimes. (Credit to Mark Wiater for
help finding this.)
Added the ability to match the netid tag in a
dhcp-range. Combined with the ability to have multiple
ranges in a single subnet, this provides a means to
segregate hosts on different address ranges based on
vendorclass or userclass. Thanks to Mark Wiater for
prompting this enhancement.
Added preference values for MX records.
Added the --localise-queries option.
dnsmasq-rh.spec
View file @
f6b7dc47
...
...
@@ -5,7 +5,7 @@
###############################################################################
Name: dnsmasq
Version: 2.
19
Version: 2.
20
Release: 1
Copyright: GPL
Group: System Environment/Daemons
...
...
dnsmasq-suse.spec
View file @
f6b7dc47
...
...
@@ -5,7 +5,7 @@
###############################################################################
Name: dnsmasq
Version: 2.
19
Version: 2.
20
Release: 1
Copyright: GPL
Group: Productivity/Networking/DNS/Servers
...
...
dnsmasq.8
View file @
f6b7dc47
...
...
@@ -143,11 +143,21 @@ requests that it shouldn't reply to. This has the advantage of
working even when interfaces come and go and change address. This
option forces dnsmasq to really bind only the interfaces it is
listening on. About the only time when this is useful is when
running another nameserver on the same machine or using IP
running another nameserver (or another instance of dnsmasq) on the
same machine or when using IP
alias. Specifying interfaces with IP alias automatically turns this
option on. Note that this only applies to the DNS part of dnsmasq, the
DHCP server always binds the wildcard address in order to receive
broadcast packets.
option on. Setting this option also enables multiple instances of
dnsmasq which provide DHCP service to run in the same machine.
.TP
.B \-y, --localise-queries
Return answers to DNS queries from /etc/hosts which depend on the interface over which the query was
recieved. If a name in /etc/hosts has more than one address associated with
it, and at least one of those addresses is on the same subnet as the
interface to which the query was sent, then return only the
address(es) on that subnet. This allows for a server to have multiple
addresses in /etc/hosts corresponding to each of its interfaces, and
hosts will get the correct address based on which network they are
attached to. Currently this facility is limited to IPv4.
.TP
.B \-b, --bogus-priv
Bogus private reverse lookups. All reverse lookups for private IP ranges (ie 192.168.x.x, etc)
...
...
@@ -214,7 +224,7 @@ and they are queried only using the specified server. This is
intended for private nameservers: if you have a nameserver on your
network which deals with names of the form
xxx.internal.thekelleys.org.uk at 192.168.1.1 then giving the flag
.B -S /internal.thekelleys.org.uk/192.168.1.1
.B -S /
.
internal.thekelleys.org.uk/192.168.1.1
will send all queries for
internal machines to that nameserver, everything else will go to the
servers in /etc/resolv.conf. An empty domain specification,
...
...
@@ -258,18 +268,20 @@ additional facility that /#/ matches any domain. Thus
answered from /etc/hosts or DHCP and not sent to an upstream
nameserver by a more specific --server directive.
.TP
.B \-m, --mx-host=<mx name>[
,<hostnam
e>]
.B \-m, --mx-host=<mx name>[
[,<hostname>],<preferenc
e>]
Return an MX record named <mx name> pointing to the given hostname (if
given), or
the host specified in the --mx-target switch
or, if that switch is not given, the host on which dnsmasq
is running. This is useful for directing mail from systems on a LAN
to a central server.
is running. The default is useful for directing mail from systems on a LAN
to a central server. The preference value is optional, and defaults to
1 if not given. More than one MX record may be given for a host.
.TP
.B \-t, --mx-target=<hostname>
Specify target for the MX record returned by dnsmasq. See --mx-host. Note that to turn on the MX function,
at least one of --mx-host and --mx-target must be set. If only one of --mx-host and --mx-target
is set, the other defaults to the hostname of the machine on which dnsmasq is running.
Specify the default target for the MX record returned by dnsmasq. See
--mx-host. If --mx-target is given, but not --mx-host, then dnsmasq
returns a MX record containing the MX target for MX queries on the
hostname of the machine on which dnsmasq is running.
.TP
.B \-e, --selfmx
Return an MX record pointing to itself for each local
...
...
@@ -281,6 +293,23 @@ machine on which dnsmasq is running) for each
local machine. Local machines are those in /etc/hosts or with DHCP
leases.
.TP
.B \-W, --srv-host=<_service>.<_prot>.[<domain>],[<target>[,<port>[,<priority>[,<weight>]]]]
Return a SRV DNS record. See RFC2782 for details. If not supplied, the
domain defaults to that given by
.B --domain.
The default for the target domain is empty, and the default for port
is one and the defaults for
weight and priority are zero. Be careful if transposing data from BIND
zone files: the port, weight and priority numbers are in a different
order. More than one SRV record for a given service/domain is allowed,
all that match are returned. Specifying at least one
.B --srv-host
option also turns on replies to SOA queries for the
domain given by the
.B --domain
option. The data in these is stereotyped, but is enough for resolvers
to deduce that the domain is a valid one for resolving SRV records.
.TP
.B \-c, --cache-size=<cachesize>
Set the size of dnsmasq's cache. The default is 150 names. Setting the cache size to zero disables caching.
.TP
...
...
@@ -307,7 +336,8 @@ always optional. On some broken systems, dnsmasq can listen on only
one interface when using DHCP, and the name of that interface must be
given using the
.B interface
option. This limitation currently affects OpenBSD. The optional
option. This limitation currently affects OpenBSD. It is always
allowed to have more than one dhcp-range in a single subnet. The optional
network-id is a alphanumeric label which marks this network so that
dhcp options may be specified on a per-network basis. The end address
may be replaced by the keyword
...
...
@@ -380,8 +410,8 @@ specfied in RFC2132. For example, to set the default route option to
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". Data types allowed are comma sep
e
rated
dotted-quad IP addresses, a decimal number, colon-sep
e
rated hex digits
machine running dnsmasq". Data types allowed are comma sep
a
rated
dotted-quad IP addresses, a decimal number, colon-sep
a
rated hex digits
and a text string. If the optional network-ids are given then
this option is only sent when all the network-ids are matched.
Be careful: no checking is done that the correct type of data for the
...
...
@@ -544,6 +574,17 @@ and run dnsmasq with the
.B \-r /etc/resolv.dnsmasq
option. This second technique allows for dynamic update of the server
addresses by PPP or DHCP.
.PP
Addresses in /etc/hosts will "shadow" different addresses for the same
names in the upstream DNS, so "mycompany.com 1.2.3.4" in /etc/hosts will ensure that
queries for "mycompany.com" always return 1.2.3.4 even if queries in
the upstream DNS would otherwise return a different address. There is
one exception to this: if the upstream DNS contains a CNAME which
points to a shadowed name, then looking up the CNAME through dnsmasq
will result in the unshadowed address associated with the target of
the CNAME. To work around this, add the CNAME to /etc/hosts so that
the CNAME is shadowed too.
.PP
The network-id system works as follows: For each DHCP request, dnsmasq
collects a set of valid network-id tags, one from the
...
...
@@ -560,6 +601,14 @@ set collected as described above. The prefix '#' on a tag means 'not'
so --dhcp=option=#purple,3,1.2.3.4 sends the option when the
network-id tag purple is not in the set of valid tags.
.PP
If the network-id in a
.B dhcp-range
is prefixed with 'net:' then its meaning changes from setting a
tag to matching it. Thus if there is more than dhcp-range on a subnet,
and one is tagged with a network-id which is set (for instance
from a vendorclass option) then hosts which set the netid tag will be
allocated addresses in the tagged range.
.PP
The DHCP server in dnsmasq will function as a BOOTP server also,
provided that the MAC address and IP address for clients are given,
either using
...
...
dnsmasq.conf.example
View file @
f6b7dc47
...
...
@@ -4,14 +4,6 @@
# as the long options legal on the command line. See
# "/usr/sbin/dnsmasq --help" or "man 8 dnsmasq" for details.
# Change these lines if you want dnsmasq to serve MX records.
# Only one of mx-host and mx-target need be set, the other defaults
# to the name of the host running dnsmasq.
#mx-host=
#mx-target=
#selfmx
#localmx
# The following two options make you a better netizen, since they
# tell dnsmasq to filter out queries which the public DNS cannot
# answer, and which load the servers (especially the root servers)
...
...
@@ -28,6 +20,8 @@ bogus-priv
# which can trigger dial-on-demand links needlessly.
# Note that (amongst other things) this blocks all SRV requests,
# so don't use it if you use eg Kerberos.
# This option only affects forwarding, SRV records originating for
# dnsmasq (via srv-host= lines) are not suppressed by it.
#filterwin2k
# Change this line if you want dns to get its upstream servers from
...
...
@@ -63,9 +57,8 @@ bogus-priv
# webserver.
#address=/doubleclick.net/127.0.0.1
# You no longer (as of version 1.7) need to set these to enable
# dnsmasq to read /etc/ppp/resolv.conf since dnsmasq now uses the
# "dip" group to achieve this.
# If you want dnsmasq to change uid and gid to something other
# than the default, edit the following lines.
#user=
#group=
...
...
@@ -292,6 +285,50 @@ bogus-priv
# and this maps 1.2.3.x to 5.6.7.x
#alias=1.2.3.0,5.6.7.0,255.255.255.0
# Change these lines if you want dnsmasq to serve MX records.
# Return an MX record named "maildomain.com" with target
# servermachine.com and preference 50
#mx-host=maildomain.com,servermachine.com,50
# Set the default target for MX records created using the localmx option.
#mx-target=servermachine.com
# Return an MX record pointing to the mx-target for all local
# machines.
#localmx
# Return an MX record pointing to itself for all local machines.
#selfmx
# Change the following lines if you want dnsmasq to serve SRV
# records. These are useful if you want to serve ldap requests for
# Active Directory and other windows-originated DNS requests.
# See RFC 2782.
# You may add multiple srv-host lines.
# The fields are <name>,<target>,<port>,<priority>,<weight>
# If the domain part if missing from the name (so that is just has the
# service and protocol sections) then the domain given by the domain=
# config option is used.
# A SRV record sending LDAP for the example.com domain to
# ldapserver.example.com port 289
#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389
# A SRV record sending LDAP for the example.com domain to
# ldapserver.example.com port 289 (using domain=)
#domain=example.com
#srv-host=_ldap._tcp,ldapserver.example.com,389
# Two SRV records for LDAP, each with different priorities
#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389,1
#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389,2
# A SRV record indicating that there is no LDAP server for the domain
# example.com
#srv-host=_ldap._tcp.example.com
# For debugging purposes, log each DNS query as it passes through
# dnsmasq.
#log-queries
...
...
rpm/dnsmasq-SuSE.patch
View file @
f6b7dc47
...
...
@@ -9,17 +9,6 @@
/etc/ppp/resolv.conf which is not normally world readable.
.TP
.B \-v, --version
--- dnsmasq.conf.example 2004-08-08 21:18:26.000000000 +0200
+++ dnsmasq.conf.example 2004-08-12 00:40:01.000000000 +0200
@@ -65,7 +65,7 @@
# You no longer (as of version 1.7) need to set these to enable
# dnsmasq to read /etc/ppp/resolv.conf since dnsmasq now uses the
-# "dip" group to achieve this.
+# "dialout" group to achieve this.
#user=
#group=
--- src/config.h 2004-08-11 11:39:18.000000000 +0200
+++ src/config.h 2004-08-12 00:40:01.000000000 +0200
@@ -44,7 +44,7 @@
...
...
src/cache.c
View file @
f6b7dc47
/* dnsmasq is Copyright (c) 2000 Simon Kelley
/* dnsmasq is Copyright (c) 2000
-2005
Simon Kelley
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
...
...
@@ -156,25 +156,35 @@ static int is_outdated_cname_pointer(struct crec *crecp)
return
1
;
}
static
void
cache_scan_free
(
char
*
name
,
struct
all_addr
*
addr
,
time_t
now
,
unsigned
short
flags
)
static
int
is_expired
(
time_t
now
,
struct
crec
*
crecp
)
{
if
(
crecp
->
flags
&
F_IMMORTAL
)
return
0
;
if
(
difftime
(
now
,
crecp
->
ttd
)
<
0
)
return
0
;
return
1
;
}
static
int
cache_scan_free
(
char
*
name
,
struct
all_addr
*
addr
,
time_t
now
,
unsigned
short
flags
)
{
/* Scan and remove old entries.
If (flags & F_FORWARD) then remove any forward entries for name and any expired
entries but only in the same hash bucket as name.
If (flags & F_REVERSE) then remove any reverse entries for addr and any expired
entries in the whole cache.
If (flags == 0) remove any expired entries in the whole cache. */
If (flags == 0) remove any expired entries in the whole cache.
In the flags & F_FORWARD case, the return code is valid, and returns zero if the
name exists in the cache as a HOSTS or DHCP entry (these are never deleted) */
#define F_CACHESTATUS (F_HOSTS | F_DHCP | F_FORWARD | F_REVERSE | F_IPV4 | F_IPV6 | F_CNAME)
struct
crec
*
crecp
,
**
up
;
flags
&=
(
F_FORWARD
|
F_REVERSE
|
F_IPV6
|
F_IPV4
|
F_CNAME
);
if
(
flags
&
F_FORWARD
)
{
for
(
up
=
hash_bucket
(
name
),
crecp
=
*
up
;
crecp
;
crecp
=
crecp
->
hash_next
)
if
((
!
(
crecp
->
flags
&
F_IMMORTAL
)
&&
difftime
(
now
,
crecp
->
ttd
)
>
0
)
||
is_outdated_cname_pointer
(
crecp
)
||
((
flags
==
(
crecp
->
flags
&
F_CACHESTATUS
))
&&
hostname_isequal
(
cache_get_name
(
crecp
),
name
)))
if
(
is_expired
(
now
,
crecp
)
||
is_outdated_cname_pointer
(
crecp
))
{
*
up
=
crecp
->
hash_next
;
if
(
!
(
crecp
->
flags
&
(
F_HOSTS
|
F_DHCP
)))
...
...
@@ -183,6 +193,16 @@ static void cache_scan_free(char *name, struct all_addr *addr, time_t now, unsig
cache_free
(
crecp
);
}
}
else
if
((
crecp
->
flags
&
F_FORWARD
)
&&
((
flags
&
crecp
->
flags
&
(
F_IPV4
|
F_IPV6
))
||
(
crecp
->
flags
&
F_CNAME
))
&&
hostname_isequal
(
cache_get_name
(
crecp
),
name
))
{
if
(
crecp
->
flags
&
(
F_HOSTS
|
F_DHCP
))
return
0
;
*
up
=
crecp
->
hash_next
;
cache_unlink
(
crecp
);
cache_free
(
crecp
);
}
else
up
=
&
crecp
->
hash_next
;
}
...
...
@@ -196,8 +216,7 @@ static void cache_scan_free(char *name, struct all_addr *addr, time_t now, unsig
#endif
for
(
i
=
0
;
i
<
hash_size
;
i
++
)
for
(
crecp
=
hash_table
[
i
],
up
=
&
hash_table
[
i
];
crecp
;
crecp
=
crecp
->
hash_next
)
if
((
!
(
crecp
->
flags
&
F_IMMORTAL
)
&&
difftime
(
now
,
crecp
->
ttd
)
>
0
)
||
((
flags
==
(
crecp
->
flags
&
F_CACHESTATUS
))
&&
memcmp
(
&
crecp
->
addr
.
addr
,
addr
,
addrlen
)
==
0
))
if
(
is_expired
(
now
,
crecp
))
{
*
up
=
crecp
->
hash_next
;
if
(
!
(
crecp
->
flags
&
(
F_HOSTS
|
F_DHCP
)))
...
...
@@ -206,9 +225,20 @@ static void cache_scan_free(char *name, struct all_addr *addr, time_t now, unsig
cache_free
(
crecp
);
}
}
else
if
(
!
(
crecp
->
flags
&
(
F_HOSTS
|
F_DHCP
))
&&
(
flags
&
crecp
->
flags
&
F_REVERSE
)
&&
(
flags
&
crecp
->
flags
&
(
F_IPV4
|
F_IPV6
))
&&
memcmp
(
&
crecp
->
addr
.
addr
,
addr
,
addrlen
)
==
0
)
{
*
up
=
crecp
->
hash_next
;
cache_unlink
(
crecp
);
cache_free
(
crecp
);
}
else
up
=
&
crecp
->
hash_next
;
}
return
1
;
}
/* Note: The normal calling sequence is
...
...
@@ -260,8 +290,13 @@ struct crec *cache_insert(char *name, struct all_addr *addr,
return
NULL
;
/* First remove any expired entries and entries for the name/address we
are currently inserting. */
cache_scan_free
(
name
,
addr
,
now
,
flags
);
are currently inserting. Fail is we attempt to delete a name from
/etc/hosts or DHCP. */
if
(
!
cache_scan_free
(
name
,
addr
,
now
,
flags
))
{
insert_error
=
1
;
return
NULL
;
}
/* Now get a cache entry from the end of the LRU list */
while
(
1
)
{
...
...
@@ -376,8 +411,7 @@ struct crec *cache_find_by_name(struct crec *crecp, char *name, time_t now, unsi
{
next
=
crecp
->
hash_next
;
if
(
!
is_outdated_cname_pointer
(
crecp
)
&&
((
crecp
->
flags
&
F_IMMORTAL
)
||
difftime
(
now
,
crecp
->
ttd
)
<
0
))
if
(
!
is_expired
(
now
,
crecp
)
&&
!
is_outdated_cname_pointer
(
crecp
))
{
if
((
crecp
->
flags
&
F_FORWARD
)
&&
(
crecp
->
flags
&
prot
)
&&
...
...
@@ -458,7 +492,7 @@ struct crec *cache_find_by_addr(struct crec *crecp, struct all_addr *addr,
for
(
i
=
0
;
i
<
hash_size
;
i
++
)
for
(
crecp
=
hash_table
[
i
],
up
=
&
hash_table
[
i
];
crecp
;
crecp
=
crecp
->
hash_next
)
if
(
(
crecp
->
flags
&
F_IMMORTAL
)
||
difftime
(
now
,
crecp
->
ttd
)
<
0
)
if
(
!
is_expired
(
now
,
crecp
)
)
{
if
((
crecp
->
flags
&
F_REVERSE
)
&&
(
crecp
->
flags
&
prot
)
&&
...
...
@@ -835,7 +869,15 @@ void log_query(unsigned short flags, char *name, struct all_addr *addr,
strcat
(
addrbuff
,
"-IPv6"
);
}
else
if
(
flags
&
F_CNAME
)
{
/* nasty abuse of IPV4 and IPV6 flags */
if
(
flags
&
F_IPV4
)
strcpy
(
addrbuff
,
"<MX>"
);
else
if
(
flags
&
F_IPV6
)
strcpy
(
addrbuff
,
"<SRV>"
);
else
strcpy
(
addrbuff
,
"<CNAME>"
);
}
else
#ifdef HAVE_IPV6
inet_ntop
(
flags
&
F_IPV4
?
AF_INET
:
AF_INET6
,
...
...
src/config.h
View file @
f6b7dc47
/* dnsmasq is Copyright (c) 2000-200
4
Simon Kelley
/* dnsmasq is Copyright (c) 2000-200
5
Simon Kelley
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
...
...
@@ -12,7 +12,7 @@
/* Author's email: simon@thekelleys.org.uk */
#define VERSION "2.
19
"
#define VERSION "2.
20
"
#define FTABSIZ 150
/* max number of outstanding requests */
#define MAX_PROCS 20
/* max no children for TCP requests */
...
...
@@ -278,7 +278,6 @@ typedef unsigned long in_addr_t;
#define HAVE_SOCKADDR_SA_LEN
#undef HAVE_PSELECT
#define HAVE_BPF
#define BIND_8_COMPAT
/* Define before sys/socket.h is included so we get socklen_t */
#define _BSD_SOCKLEN_T_
/* This is not defined in Mac OS X arpa/nameserv.h */
...
...
src/dhcp.c
View file @
f6b7dc47
...
...
@@ -34,6 +34,13 @@ void dhcp_init(struct daemon *daemon)
setsockopt
(
fd
,
SOL_SOCKET
,
SO_BROADCAST
,
&
oneopt
,
sizeof
(
oneopt
))
==
-
1
)
die
(
"failed to set options on DHCP socket: %s"
,
NULL
);
/* When bind-interfaces is set, there might be more than one dnmsasq
instance binding port 67. That's Ok if they serve different networks.
Need to set REUSEADDR to make this posible. */
if
((
daemon
->
options
&
OPT_NOWILD
)
&&
setsockopt
(
fd
,
SOL_SOCKET
,
SO_REUSEADDR
,
&
oneopt
,
sizeof
(
oneopt
))
==
-
1
)
die
(
"failed to set SO_REUSEADDR on DHCP socket: %s"
,
NULL
);
saddr
.
sin_family
=
AF_INET
;
saddr
.
sin_port
=
htons
(
DHCP_SERVER_PORT
);
saddr
.
sin_addr
.
s_addr
=
INADDR_ANY
;
...
...
@@ -429,17 +436,52 @@ struct dhcp_config *config_find_by_address(struct dhcp_config *configs, struct i
return
NULL
;
}
/* Is every member of check matched by a member of pool? */
int
match_netid
(
struct
dhcp_netid
*
check
,
struct
dhcp_netid
*
pool
)
{
struct
dhcp_netid
*
tmp1
;
if
(
!
check
)
return
0
;
for
(;
check
;
check
=
check
->
next
)
{
if
(
check
->
net
[
0
]
!=
'#'
)
{
for
(
tmp1
=
pool
;
tmp1
;
tmp1
=
tmp1
->
next
)
if
(
strcmp
(
check
->
net
,
tmp1
->
net
)
==
0
)
break
;
if
(
!
tmp1
)
return
0
;
}
else
for
(
tmp1
=
pool
;
tmp1
;
tmp1
=
tmp1
->
next
)
if
(
strcmp
((
check
->
net
)
+
1
,
tmp1
->
net
)
==
0
)
return
0
;
}
return
1
;
}
int
address_allocate
(
struct
dhcp_context
*
context
,
struct
daemon
*
daemon
,
struct
in_addr
*
addrp
,
unsigned
char
*
hwaddr
)
struct
in_addr
*
addrp
,
unsigned
char
*
hwaddr
,
struct
dhcp_netid
*
netids
)
{
/* Find a free address: exclude anything in use and anything allocated to
a particular hwaddr/clientid/hostname in our configuration */
a particular hwaddr/clientid/hostname in our configuration.
Try to return from contexts which mathc netis first. */
struct
in_addr
start
,
addr
;
unsigned
int
i
,
j
;
for
(;
context
;
context
=
context
->
current
)
if
(
!
context
->
static_only
)
if
(
context
->
static_only
)
continue
;
else
if
(
netids
&&
!
context
->
filter_netid
)
continue
;
else
if
(
!
netids
&&
context
->
filter_netid
)
continue
;
else
if
(
netids
&&
context
->
filter_netid
&&
!
match_netid
(
&
context
->
netid
,
netids
))
continue
;
else
{
/* pick a seed based on hwaddr then iterate until we find a free address. */
for
(
j
=
context
->
addr_epoch
,
i
=
0
;
i
<
ETHER_ADDR_LEN
;
i
++
)
...
...
@@ -471,6 +513,10 @@ int address_allocate(struct dhcp_context *context, struct daemon *daemon,
}
while
(
addr
.
s_addr
!=
start
.
s_addr
);
}
if
(
netids
)
return
address_allocate
(
context
,
daemon
,
addrp
,
hwaddr
,
NULL
);
return
0
;
}
...
...
src/dnsmasq.c
View file @
f6b7dc47
/* dnsmasq is Copyright (c) 2000-200
4
Simon Kelley
/* dnsmasq is Copyright (c) 2000-200
5
Simon Kelley
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
...
...
@@ -82,7 +82,8 @@ int main (int argc, char **argv)
die
(
"ISC dhcpd integration not available: set HAVE_ISC_READER in src/config.h"
,
NULL
);
#endif
interfaces
=
enumerate_interfaces
(
daemon
);
if
(
!
enumerate_interfaces
(
daemon
,
&
interfaces
,
NULL
,
NULL
))
die
(
"failed to find list of interfaces: %s"
,
NULL
);
if
(
!
(
daemon
->
options
&
OPT_NOWILD
)
&&
!
(
daemon
->
listeners
=
create_wildcard_listeners
(
daemon
->
port
)))
...
...
@@ -509,45 +510,25 @@ static void check_dns_listeners(struct daemon *daemon, fd_set *set, time_t now)
if
(
FD_ISSET
(
listener
->
tcpfd
,
set
))
{
int
confd
;
struct
in_addr
netmask
,
dst_addr_4
;
while
((
confd
=
accept
(
listener
->
tcpfd
,
NULL
,
NULL
))
==
-
1
&&
errno
==
EINTR
);
if
(
confd
!=
-
1
)
{
int
match
=
1
;
if
(
!
(
daemon
->
options
&
OPT_NOWILD
))
{
/* Check for allowed interfaces when binding the wildcard address */
/* Don't know how to get interface of a connection, so we have to
check by address. This will break when interfaces change address */
union
mysockaddr
tcp_addr
;
socklen_t
tcp_len
=
sizeof
(
union
mysockaddr
);
struct
iname
*
tmp
;
if
(
getsockname
(
confd
,
(
struct
sockaddr
*
)
&
tcp_addr
,
&
tcp_len
)
!=
-
1
)
{
#ifdef HAVE_IPV6
if
(
tcp_addr
.
sa
.
sa_family
==
AF_INET6
)
tcp_addr
.
in6
.
sin6_flowinfo
=
htonl
(
0
);
#endif
for
(
match
=
1
,
tmp
=
daemon
->
if_except
;
tmp
;
tmp
=
tmp
->
next
)
if
(
sockaddr_isequal
(
&
tmp
->
addr
,
&
tcp_addr
))
match
=
0
;
/* Check for allowed interfaces when binding the wildcard address:
we do this by looking for an interface with the same address as
the local address of the TCP connection, then looking to see if that's
an allowed interface. As a side effect, we get the netmask of the
interface too, for localisation. */
if
(
match
&&
(
daemon
->
if_names
||
daemon
->
if_addrs
))
{
match
=
0
;
for
(
tmp
=
daemon
->
if_names
;
tmp
;
tmp
=
tmp
->
next
)
if
(
sockaddr_isequal
(
&
tmp
->
addr
,
&
tcp_addr
))
match
=
1
;
for
(
tmp
=
daemon
->
if_addrs
;
tmp
;
tmp
=
tmp
->
next
)
if
(
sockaddr_isequal
(
&
tmp
->
addr
,
&
tcp_addr
))
match
=
1
;
}
}
}
if
(
!
match
||
(
num_kids
>=
MAX_PROCS
))
if
((
num_kids
>=
MAX_PROCS
)
||
(
!
(
daemon
->
options
&
OPT_NOWILD
)
&&
(
getsockname
(
confd
,
(
struct
sockaddr
*
)
&
tcp_addr
,
&
tcp_len
)
==
-
1
||
!
enumerate_interfaces
(
daemon
,
NULL
,
&
tcp_addr
,
&
netmask
))))
close
(
confd
);
#ifndef NO_FORK
else
if
(
!
(
daemon
->
options
&
OPT_DEBUG
)
&&
fork
())
...
...
@@ -584,7 +565,21 @@ static void check_dns_listeners(struct daemon *daemon, fd_set *set, time_t now)
if
((
flags
=
fcntl
(
confd
,
F_GETFL
,
0
))
!=
-
1
)
fcntl
(
confd
,
F_SETFL
,
flags
&
~
O_NONBLOCK
);
buff
=
tcp_request
(
daemon
,
confd
,
now
);
if
(
listener
->
family
==
AF_INET
)
{
if
(
daemon
->
options
&
OPT_NOWILD
)
{
netmask
=
listener
->
iface
->
netmask
;
dst_addr_4
=
listener
->
iface
->
addr
.
in
.
sin_addr
;
}
else
/* netmask already set by enumerate_interfaces */
dst_addr_4
=
tcp_addr
.
in
.
sin_addr
;
}
else
dst_addr_4
.
s_addr
=
0
;
buff
=
tcp_request
(
daemon
,
confd
,
now
,
dst_addr_4
,
netmask
);
if
(
!
(
daemon
->
options
&
OPT_DEBUG
))
exit
(
0
);
...
...
src/dnsmasq.h
View file @
f6b7dc47
/* dnsmasq is Copyright (c) 2000-200
3
Simon Kelley
/* dnsmasq is Copyright (c) 2000-200
5
Simon Kelley
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
...
...
@@ -12,11 +12,11 @@
/* Author's email: simon@thekelleys.org.uk */
#define COPYRIGHT "Copyright (C) 2000-200
4
Simon Kelley"
#define COPYRIGHT "Copyright (C) 2000-200
5
Simon Kelley"
#ifdef __linux__
/* for pselect.... */
#define _XOPEN_SOURCE 600
#
define _XOPEN_SOURCE 600
/* but then DNS headers don't compile without.... */
#define _BSD_SOURCE
#endif
...
...
@@ -27,6 +27,10 @@
/* get this before config.h too. */
#include <syslog.h>
#ifdef __APPLE__
/* need this before arpa/nameser.h */
# define BIND_8_COMPAT
#endif
#include <arpa/nameser.h>
/* and this. */
...
...
@@ -57,6 +61,7 @@
#include <errno.h>
#include <pwd.h>
#include <grp.h>
#include <stdarg.h>
#if defined(__OpenBSD__) || defined(__NetBSD__)
# include <netinet/if_ether.h>
#else
...
...
@@ -96,6 +101,7 @@
#define OPT_RESOLV_DOMAIN 32768
#define OPT_NO_FORK 65536
#define OPT_AUTHORITATIVE 131072
#define OPT_LOCALISE 262144
struct
all_addr
{
union
{
...
...
@@ -119,9 +125,16 @@ struct doctor {
struct
mx_record
{
char
*
mxname
,
*
mxtarget
;
int
preference
;
struct
mx_record
*
next
;
};
struct
srv_record
{
char
*
srvname
,
*
srvtarget
;
int
srvport
,
priority
,
weight
;
struct
srv_record
*
next
;
};
union
bigname
{
char
name
[
MAXDNAME
];
union
bigname
*
next
;
/* freelist */
...
...
@@ -211,11 +224,13 @@ struct server {
struct
irec
{
union
mysockaddr
addr
;
struct
in_addr
netmask
;
/* only valid for IPv4 */
struct
irec
*
next
;
};
struct
listener
{
int
fd
,
tcpfd
,
family
;
struct
irec
*
iface
;
/* only valid for non-wildcard */
struct
listener
*
next
;
};
...
...
@@ -319,7 +334,7 @@ struct dhcp_context {
unsigned
int
lease_time
,
addr_epoch
;
struct
in_addr
netmask
,
broadcast
,
router
;
struct
in_addr
start
,
end
;
/* range of available addresses */
int
static_only
;
int
static_only
,
filter_netid
;
struct
dhcp_netid
netid
;
struct
dhcp_context
*
next
,
*
current
;
};
...
...
@@ -360,6 +375,7 @@ struct daemon {
char
*
lease_file
;
char
*
username
,
*
groupname
;
char
*
domain_suffix
;
struct
srv_record
*
srvnames
;
char
*
runfile
;
struct
iname
*
if_names
,
*
if_addrs
,
*
if_except
;
struct
bogus_addr
*
bogus_addr
;
...
...
@@ -420,12 +436,13 @@ int setup_reply(HEADER *header, unsigned int qlen,
unsigned
long
local_ttl
);
void
extract_addresses
(
HEADER
*
header
,
unsigned
int
qlen
,
char
*
namebuff
,
time_t
now
,
struct
daemon
*
daemon
);
int
answer_request
(
HEADER
*
header
,
char
*
limit
,
unsigned
int
qlen
,
struct
daemon
*
daemon
,
time_t
now
);
int
answer_request
(
HEADER
*
header
,
char
*
limit
,
unsigned
int
qlen
,
struct
daemon
*
daemon
,
struct
in_addr
local_addr
,
struct
in_addr
local_netmask
,
time_t
now
);
int
check_for_bogus_wildcard
(
HEADER
*
header
,
unsigned
int
qlen
,
char
*
name
,
struct
bogus_addr
*
addr
,
time_t
now
);
unsigned
char
*
find_pseudoheader
(
HEADER
*
header
,
unsigned
int
plen
,
unsigned
int
*
len
,
unsigned
char
**
p
);
int
check_for_local_domain
(
char
*
name
,
time_t
now
,
struct
mx_record
*
mx
);
int
check_for_local_domain
(
char
*
name
,
time_t
now
,
struct
daemon
*
daemon
);
unsigned
int
questions_crc
(
HEADER
*
header
,
unsigned
int
plen
);
int
resize_packet
(
HEADER
*
header
,
unsigned
int
plen
,
unsigned
char
*
pheader
,
unsigned
int
hlen
);
...
...
@@ -453,13 +470,15 @@ struct daemon *read_opts (int argc, char **argv);
void
forward_init
(
int
first
);
void
reply_query
(
struct
serverfd
*
sfd
,
struct
daemon
*
daemon
,
time_t
now
);
void
receive_query
(
struct
listener
*
listen
,
struct
daemon
*
daemon
,
time_t
now
);
char
*
tcp_request
(
struct
daemon
*
daemon
,
int
confd
,
time_t
now
);
char
*
tcp_request
(
struct
daemon
*
daemon
,
int
confd
,
time_t
now
,
struct
in_addr
local_addr
,
struct
in_addr
netmask
);
/* network.c */
struct
serverfd
*
allocate_sfd
(
union
mysockaddr
*
addr
,
struct
serverfd
**
sfds
);
void
reload_servers
(
char
*
fname
,
struct
daemon
*
daemon
);
void
check_servers
(
struct
daemon
*
daemon
,
struct
irec
*
interfaces
);
struct
irec
*
enumerate_interfaces
(
struct
daemon
*
daemon
);
int
enumerate_interfaces
(
struct
daemon
*
daemon
,
struct
irec
**
chainp
,
union
mysockaddr
*
test_addrp
,
struct
in_addr
*
netmaskp
);
struct
listener
*
create_wildcard_listeners
(
int
port
);
struct
listener
*
create_bound_listeners
(
struct
irec
*
interfaces
,
int
port
);
...
...
@@ -469,8 +488,10 @@ void dhcp_packet(struct daemon *daemon, time_t now);
struct
dhcp_context
*
address_available
(
struct
dhcp_context
*
context
,
struct
in_addr
addr
);
struct
dhcp_context
*
narrow_context
(
struct
dhcp_context
*
context
,
struct
in_addr
taddr
);
int
match_netid
(
struct
dhcp_netid
*
check
,
struct
dhcp_netid
*
pool
);
int
address_allocate
(
struct
dhcp_context
*
context
,
struct
daemon
*
daemon
,
struct
in_addr
*
addrp
,
unsigned
char
*
hwaddr
);
struct
in_addr
*
addrp
,
unsigned
char
*
hwaddr
,
struct
dhcp_netid
*
netids
);
struct
dhcp_config
*
find_config
(
struct
dhcp_config
*
configs
,
struct
dhcp_context
*
context
,
unsigned
char
*
clid
,
int
clid_len
,
...
...
src/forward.c
View file @
f6b7dc47
/* dnsmasq is Copyright (c) 2000 - 200
3
Simon Kelley
/* dnsmasq is Copyright (c) 2000 - 200
5
Simon Kelley
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
...
...
@@ -197,7 +197,7 @@ static unsigned short search_servers(struct daemon *daemon, time_t now, struct a
else
if
(
qtype
&&
(
daemon
->
options
&
OPT_NODOTS_LOCAL
)
&&
!
strchr
(
qdomain
,
'.'
))
flags
=
F_NXDOMAIN
;
if
(
flags
==
F_NXDOMAIN
&&
check_for_local_domain
(
qdomain
,
now
,
daemon
->
mxnames
))
if
(
flags
==
F_NXDOMAIN
&&
check_for_local_domain
(
qdomain
,
now
,
daemon
))
flags
=
F_NOERR
;
if
(
flags
==
F_NXDOMAIN
||
flags
==
F_NOERR
)
...
...
@@ -390,7 +390,7 @@ static int process_reply(struct daemon *daemon, HEADER *header, time_t now,
{
if
(
header
->
rcode
==
NXDOMAIN
&&
extract_request
(
header
,
n
,
daemon
->
namebuff
,
NULL
)
&&
check_for_local_domain
(
daemon
->
namebuff
,
now
,
daemon
->
mxnames
))
check_for_local_domain
(
daemon
->
namebuff
,
now
,
daemon
))
{
/* if we forwarded a query for a locally known name (because it was for
an unknown type) and the answer is NXDOMAIN, convert that to NODATA,
...
...
@@ -474,6 +474,7 @@ void receive_query(struct listener *listen, struct daemon *daemon, time_t now)
unsigned
short
type
;
struct
iname
*
tmp
;
struct
all_addr
dst_addr
;
struct
in_addr
netmask
,
dst_addr_4
;
int
m
,
n
,
if_index
=
0
;
struct
iovec
iov
[
1
];
struct
msghdr
msg
;
...
...
@@ -491,6 +492,14 @@ void receive_query(struct listener *listen, struct daemon *daemon, time_t now)
#endif
}
control_u
;
if
(
listen
->
family
==
AF_INET
&&
(
daemon
->
options
&
OPT_NOWILD
))
{
dst_addr_4
=
listen
->
iface
->
addr
.
in
.
sin_addr
;
netmask
=
listen
->
iface
->
netmask
;
}
else
dst_addr_4
.
s_addr
=
0
;
iov
[
0
].
iov_base
=
daemon
->
packet
;
iov
[
0
].
iov_len
=
daemon
->
edns_pktsz
;
...
...
@@ -526,7 +535,7 @@ void receive_query(struct listener *listen, struct daemon *daemon, time_t now)
for
(
cmptr
=
CMSG_FIRSTHDR
(
&
msg
);
cmptr
;
cmptr
=
CMSG_NXTHDR
(
&
msg
,
cmptr
))
if
(
cmptr
->
cmsg_level
==
SOL_IP
&&
cmptr
->
cmsg_type
==
IP_PKTINFO
)
{
dst_addr
.
addr
.
addr4
=
((
struct
in_pktinfo
*
)
CMSG_DATA
(
cmptr
))
->
ipi_spec_dst
;
dst_addr
_4
=
dst_addr
.
addr
.
addr4
=
((
struct
in_pktinfo
*
)
CMSG_DATA
(
cmptr
))
->
ipi_spec_dst
;
if_index
=
((
struct
in_pktinfo
*
)
CMSG_DATA
(
cmptr
))
->
ipi_ifindex
;
}
#elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
...
...
@@ -534,7 +543,7 @@ void receive_query(struct listener *listen, struct daemon *daemon, time_t now)
{
for
(
cmptr
=
CMSG_FIRSTHDR
(
&
msg
);
cmptr
;
cmptr
=
CMSG_NXTHDR
(
&
msg
,
cmptr
))
if
(
cmptr
->
cmsg_level
==
IPPROTO_IP
&&
cmptr
->
cmsg_type
==
IP_RECVDSTADDR
)
dst_addr
.
addr
.
addr4
=
*
((
struct
in_addr
*
)
CMSG_DATA
(
cmptr
));
dst_addr
_4
=
dst_addr
.
addr
.
addr4
=
*
((
struct
in_addr
*
)
CMSG_DATA
(
cmptr
));
else
if
(
cmptr
->
cmsg_level
==
IPPROTO_IP
&&
cmptr
->
cmsg_type
==
IP_RECVIF
)
if_index
=
((
struct
sockaddr_dl
*
)
CMSG_DATA
(
cmptr
))
->
sdl_index
;
}
...
...
@@ -557,7 +566,7 @@ void receive_query(struct listener *listen, struct daemon *daemon, time_t now)
if
(
if_index
==
0
)
return
;
if
(
daemon
->
if_except
||
daemon
->
if_names
)
if
(
daemon
->
if_except
||
daemon
->
if_names
||
(
daemon
->
options
&
OPT_LOCALISE
)
)
{
#ifdef SIOCGIFNAME
ifr
.
ifr_ifindex
=
if_index
;
...
...
@@ -567,6 +576,13 @@ void receive_query(struct listener *listen, struct daemon *daemon, time_t now)
if
(
!
if_indextoname
(
if_index
,
ifr
.
ifr_name
))
return
;
#endif
if
(
listen
->
family
==
AF_INET
&&
(
daemon
->
options
&
OPT_LOCALISE
)
&&
ioctl
(
listen
->
fd
,
SIOCGIFNETMASK
,
&
ifr
)
==
-
1
)
return
;
netmask
=
((
struct
sockaddr_in
*
)
&
ifr
.
ifr_addr
)
->
sin_addr
;
}
for
(
tmp
=
daemon
->
if_except
;
tmp
;
tmp
=
tmp
->
next
)
...
...
@@ -610,7 +626,8 @@ void receive_query(struct listener *listen, struct daemon *daemon, time_t now)
#endif
}
m
=
answer_request
(
header
,
((
char
*
)
header
)
+
PACKETSZ
,
(
unsigned
int
)
n
,
daemon
,
now
);
m
=
answer_request
(
header
,
((
char
*
)
header
)
+
PACKETSZ
,
(
unsigned
int
)
n
,
daemon
,
dst_addr_4
,
netmask
,
now
);
if
(
m
>=
1
)
send_from
(
listen
->
fd
,
daemon
->
options
&
OPT_NOWILD
,
(
char
*
)
header
,
m
,
&
source_addr
,
&
dst_addr
,
if_index
);
else
...
...
@@ -647,7 +664,8 @@ static int read_write(int fd, char *packet, int size, int rw)
blocking as neccessary, and then return. Note, need to be a bit careful
about resources for debug mode, when the fork is suppressed: that's
done by the caller. */
char
*
tcp_request
(
struct
daemon
*
daemon
,
int
confd
,
time_t
now
)
char
*
tcp_request
(
struct
daemon
*
daemon
,
int
confd
,
time_t
now
,
struct
in_addr
local_addr
,
struct
in_addr
netmask
)
{
int
size
=
0
,
m
;
unsigned
short
qtype
,
gotname
;
...
...
@@ -689,7 +707,8 @@ char *tcp_request(struct daemon *daemon, int confd, time_t now)
}
/* m > 0 if answered from cache */
m
=
answer_request
(
header
,
((
char
*
)
header
)
+
65536
,
(
unsigned
int
)
size
,
daemon
,
now
);
m
=
answer_request
(
header
,
((
char
*
)
header
)
+
65536
,
(
unsigned
int
)
size
,
daemon
,
local_addr
,
netmask
,
now
);
if
(
m
==
0
)
{
...
...
src/isc.c
View file @
f6b7dc47
/* dnsmasq is Copyright (c) 2000 - 200
4
by Simon Kelley
/* dnsmasq is Copyright (c) 2000 - 200
5
by Simon Kelley
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
...
...
src/lease.c
View file @
f6b7dc47
/* dnsmasq is Copyright (c) 2000-200
3
Simon Kelley
/* dnsmasq is Copyright (c) 2000-200
5
Simon Kelley
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
...
...
src/network.c
View file @
f6b7dc47
/* dnsmasq is Copyright (c) 2000 - 200
3
Simon Kelley
/* dnsmasq is Copyright (c) 2000 - 200
5
Simon Kelley
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
...
...
@@ -14,10 +14,9 @@
#include "dnsmasq.h"
static
struct
irec
*
add_iface
(
struct
daemon
*
daemon
,
struct
irec
*
list
,
static
int
iface_allowed
(
struct
daemon
*
daemon
,
struct
irec
*
iface
,
char
*
name
,
int
is_loopback
,
union
mysockaddr
*
addr
)
{
struct
irec
*
iface
;
struct
iname
*
tmp
;
/* If we are restricting the set of interfaces to use, make
...
...
@@ -45,11 +44,7 @@ static struct irec *add_iface(struct daemon *daemon, struct irec *list,
if
(
daemon
->
if_except
)
for
(
tmp
=
daemon
->
if_except
;
tmp
;
tmp
=
tmp
->
next
)
if
(
tmp
->
name
&&
strcmp
(
tmp
->
name
,
name
)
==
0
)
{
/* record address of named interfaces, for TCP access control */
tmp
->
addr
=
*
addr
;
return
list
;
}
return
0
;
/* we may need to check the whitelist */
if
(
daemon
->
if_names
||
daemon
->
if_addrs
)
...
...
@@ -58,36 +53,39 @@ static struct irec *add_iface(struct daemon *daemon, struct irec *list,
for
(
tmp
=
daemon
->
if_names
;
tmp
;
tmp
=
tmp
->
next
)
if
(
tmp
->
name
&&
(
strcmp
(
tmp
->
name
,
name
)
==
0
))
{
tmp
->
addr
=
*
addr
;
found
=
tmp
->
used
=
1
;
}
for
(
tmp
=
daemon
->
if_addrs
;
tmp
;
tmp
=
tmp
->
next
)
if
(
sockaddr_isequal
(
&
tmp
->
addr
,
addr
))
found
=
tmp
->
used
=
1
;
if
(
!
found
)
return
list
;
return
0
;
}
/* check whether the interface IP has been added already
it is possible to have multiple interfaces with the same address */
for
(
iface
=
list
;
iface
;
iface
=
iface
->
next
)
for
(;
iface
;
iface
=
iface
->
next
)
if
(
sockaddr_isequal
(
&
iface
->
addr
,
addr
))
break
;
if
(
iface
)
return
list
;
return
0
;
/* If OK, add it to the head of the list */
iface
=
safe_malloc
(
sizeof
(
struct
irec
));
iface
->
addr
=
*
addr
;
iface
->
next
=
list
;
return
iface
;
return
1
;
}
/* This does two different jobs: if chainp is non-NULL, it puts
a list of all the interfaces allowed by config into *chainp.
If chainp is NULL, it returns 1 if addr is an address of an interface
allowed by config and if that address is IPv4, it fills in the
netmask of the interface.
If chainp is non-NULL, a zero return indicates a fatal error.
struct
irec
*
enumerate_interfaces
(
struct
daemon
*
daemon
)
If chainp is NULL, errors result in a match failure and zero return.
*/
int
enumerate_interfaces
(
struct
daemon
*
daemon
,
struct
irec
**
chainp
,
union
mysockaddr
*
test_addrp
,
struct
in_addr
*
netmaskp
)
{
#if defined(HAVE_LINUX_IPV6_PROC) && defined(HAVE_IPV6)
FILE
*
f
;
...
...
@@ -100,9 +98,16 @@ struct irec *enumerate_interfaces(struct daemon *daemon)
int
lastlen
=
0
;
int
len
=
20
*
sizeof
(
struct
ifreq
);
int
fd
=
socket
(
PF_INET
,
SOCK_DGRAM
,
0
);
struct
in_addr
netmask
;
int
ret
=
0
;
if
(
fd
==
-
1
)
die
(
"cannot create socket to enumerate interfaces: %s"
,
NULL
);
return
0
;
#ifdef HAVE_IPV6
if
(
test_addrp
&&
test_addrp
->
sa
.
sa_family
==
AF_INET6
)
test_addrp
->
in6
.
sin6_flowinfo
=
htonl
(
0
);
#endif
while
(
1
)
{
...
...
@@ -113,7 +118,7 @@ struct irec *enumerate_interfaces(struct daemon *daemon)
if
(
ioctl
(
fd
,
SIOCGIFCONF
,
&
ifc
)
<
0
)
{
if
(
errno
!=
EINVAL
||
lastlen
!=
0
)
die
(
"ioctl error while enumerating interfaces: %s"
,
NULL
)
;
goto
exit
;
}
else
{
...
...
@@ -133,7 +138,7 @@ struct irec *enumerate_interfaces(struct daemon *daemon)
unaligned accesses. */
int
ifr_len
=
((
struct
ifreq
*
)
ptr
)
->
ifr_addr
.
sa_len
+
IF_NAMESIZE
;
if
(
!
(
ifr
=
realloc
(
ifr
,
ifr_len
)))
die
(
"cannot allocate buffer"
,
NULL
)
;
goto
exit
;
memcpy
(
ifr
,
ptr
,
ifr_len
);
ptr
+=
ifr_len
;
...
...
@@ -147,6 +152,9 @@ struct irec *enumerate_interfaces(struct daemon *daemon)
{
addr
.
in
=
*
((
struct
sockaddr_in
*
)
&
ifr
->
ifr_addr
);
addr
.
in
.
sin_port
=
htons
(
daemon
->
port
);
if
(
ioctl
(
fd
,
SIOCGIFNETMASK
,
ifr
)
==
-
1
)
goto
exit
;
netmask
=
((
struct
sockaddr_in
*
)
&
ifr
->
ifr_addr
)
->
sin_addr
;
}
#ifdef HAVE_IPV6
else
if
(
ifr
->
ifr_addr
.
sa_family
==
AF_INET6
)
...
...
@@ -164,9 +172,25 @@ struct irec *enumerate_interfaces(struct daemon *daemon)
continue
;
/* unknown address family */
if
(
ioctl
(
fd
,
SIOCGIFFLAGS
,
ifr
)
<
0
)
die
(
"ioctl error getting interface flags: %m"
,
NULL
)
;
goto
exit
;
iface
=
add_iface
(
daemon
,
iface
,
ifr
->
ifr_name
,
ifr
->
ifr_flags
&
IFF_LOOPBACK
,
&
addr
);
if
(
iface_allowed
(
daemon
,
iface
,
ifr
->
ifr_name
,
ifr
->
ifr_flags
&
IFF_LOOPBACK
,
&
addr
))
{
if
(
chainp
)
{
struct
irec
*
new
=
safe_malloc
(
sizeof
(
struct
irec
));
new
->
addr
=
addr
;
new
->
netmask
=
netmask
;
new
->
next
=
iface
;
iface
=
new
;
}
else
if
(
sockaddr_isequal
(
&
addr
,
test_addrp
))
{
*
netmaskp
=
netmask
;
ret
=
1
;
goto
exit
;
}
}
}
#if defined(HAVE_LINUX_IPV6_PROC) && defined(HAVE_IPV6)
...
...
@@ -198,13 +222,35 @@ struct irec *enumerate_interfaces(struct daemon *daemon)
strncpy
(
sifr
.
ifr_name
,
devname
,
IF_NAMESIZE
);
if
(
ioctl
(
fd
,
SIOCGIFFLAGS
,
&
sifr
)
<
0
)
die
(
"ioctl error getting interface flags: %m"
,
NULL
);
iface
=
add_iface
(
daemon
,
iface
,
sifr
.
ifr_name
,
sifr
.
ifr_flags
&
IFF_LOOPBACK
,
&
addr
);
goto
exit
;
if
(
iface_allowed
(
daemon
,
iface
,
sifr
.
ifr_name
,
sifr
.
ifr_flags
&
IFF_LOOPBACK
,
&
addr
))
{
if
(
chainp
)
{
struct
irec
*
new
=
safe_malloc
(
sizeof
(
struct
irec
));
new
->
addr
=
addr
;
new
->
next
=
iface
;
iface
=
new
;
}
else
if
(
sockaddr_isequal
(
&
addr
,
test_addrp
))
{
ret
=
1
;
goto
exit
;
}
}
}
fclose
(
f
);
}
#endif
/* LINUX */
if
(
chainp
)
{
*
chainp
=
iface
;
ret
=
1
;
}
exit:
if
(
buf
)
free
(
buf
);
#ifdef HAVE_SOCKADDR_SA_LEN
...
...
@@ -213,7 +259,7 @@ struct irec *enumerate_interfaces(struct daemon *daemon)
#endif
close
(
fd
);
return
iface
;
return
ret
;
}
#ifdef HAVE_IPV6
...
...
@@ -354,6 +400,7 @@ struct listener *create_bound_listeners(struct irec *interfaces, int port)
{
struct
listener
*
new
=
safe_malloc
(
sizeof
(
struct
listener
));
new
->
family
=
iface
->
addr
.
sa
.
sa_family
;
new
->
iface
=
iface
;
new
->
next
=
listeners
;
if
((
new
->
tcpfd
=
socket
(
iface
->
addr
.
sa
.
sa_family
,
SOCK_STREAM
,
0
))
==
-
1
||
(
new
->
fd
=
socket
(
iface
->
addr
.
sa
.
sa_family
,
SOCK_DGRAM
,
0
))
==
-
1
||
...
...
src/option.c
View file @
f6b7dc47
/* dnsmasq is Copyright (c) 2000 - 200
4
Simon Kelley
/* dnsmasq is Copyright (c) 2000 - 200
5
Simon Kelley
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
...
...
@@ -21,7 +21,7 @@ struct myoption {
int
val
;
};
#define OPTSTRING "
ZDNLERKzowefnbvhdkqr:m:p:c:l:s:i:t:u:g:a:x:S:C:A:T:H:Q:I:B:F:G:O:M:X:V:U:j:P:J
:"
#define OPTSTRING "
yZDNLERKzowefnbvhdkqr:m:p:c:l:s:i:t:u:g:a:x:S:C:A:T:H:Q:I:B:F:G:O:M:X:V:U:j:P:J:W
:"
static
struct
myoption
opts
[]
=
{
{
"version"
,
0
,
0
,
'v'
},
...
...
@@ -76,6 +76,8 @@ static struct myoption opts[] = {
{
"edns-packet-max"
,
1
,
0
,
'P'
},
{
"keep-in-foreground"
,
0
,
0
,
'k'
},
{
"dhcp-authoritative"
,
0
,
0
,
'K'
},
{
"srv-host"
,
1
,
0
,
'W'
},
{
"localise-queries"
,
0
,
0
,
'y'
},
{
0
,
0
,
0
,
0
}
};
...
...
@@ -102,6 +104,7 @@ static struct optflags optmap[] = {
{
'D'
,
OPT_NODOTS_LOCAL
},
{
'z'
,
OPT_NOWILD
},
{
'Z'
,
OPT_ETHERS
},
{
'y'
,
OPT_LOCALISE
},
{
'v'
,
0
},
{
'w'
,
0
},
{
0
,
0
}
...
...
@@ -137,7 +140,7 @@ static char *usage =
"-K, --dhcp-authoritative Assume we are the only DHCP server on the local network.
\n
"
"-l, --dhcp-leasefile=path Specify where to store DHCP leases (defaults to "
LEASEFILE
").
\n
"
"-L, --localmx Return MX records for local hosts.
\n
"
"-m, --mx-host=host_name
Specify the MX name to reply to
.
\n
"
"-m, --mx-host=host_name
,target,pref Specify an MX record
.
\n
"
"-M, --dhcp-boot=<bootp opts> Specify BOOTP options to DHCP server.
\n
"
"-n, --no-poll Do NOT poll "
RESOLVFILE
" file, reload only on SIGHUP.
\n
"
"-N, --no-negcache Do NOT cache failed search results.
\n
"
...
...
@@ -152,15 +155,17 @@ static char *usage =
"-S, --server=/domain/ipaddr Specify address(es) of upstream servers with optional domains.
\n
"
" --local=/domain/ Never forward queries to specified domains.
\n
"
"-s, --domain=domain Specify the domain to be assigned in DHCP leases.
\n
"
"-t, --mx-target=host_name Specify
the host in an MX reply
.
\n
"
"-t, --mx-target=host_name Specify
default target in an MX record
.
\n
"
"-T, --local-ttl=time Specify time-to-live in seconds for replies from /etc/hosts.
\n
"
"-u, --user=username Change to this user after startup. (defaults to "
CHUSER
").
\n
"
"-U, --dhcp-vendorclass=<id>,<class> Map DHCP vendor class to option set.
\n
"
"-v, --version Display dnsmasq version and copyright information.
\n
"
"-V, --alias=addr,addr,mask Translate IPv4 addresses from upstream servers.
\n
"
"-W, --srv-host=name,port,pri,weight Specify a SRV record.
\n
"
"-w, --help Display this message.
\n
"
"-x, --pid-file=path Specify path of PID file. (defaults to "
RUNFILE
").
\n
"
"-X, --dhcp-lease-max=number Specify maximum number of DHCP leases (defaults to %d).
\n
"
"-y, --localise-queries Answer DNS queries based on the interface a query was sent to."
"-z, --bind-interfaces Bind only to interfaces in use.
\n
"
"-Z, --read-ethers Read DHCP static host information from "
ETHERSFILE
".
\n
"
"
\n
"
;
...
...
@@ -372,21 +377,38 @@ struct daemon *read_opts (int argc, char **argv)
case
'm'
:
{
int
pref
=
1
;
struct
mx_record
*
new
;
if
((
comma
=
strchr
(
optarg
,
','
)))
{
char
*
prefstr
;
*
(
comma
++
)
=
0
;
if
((
prefstr
=
strchr
(
comma
,
','
)))
{
*
(
prefstr
++
)
=
0
;
if
(
!
atoi_check
(
prefstr
,
&
pref
))
{
option
=
'?'
;
problem
=
"bad MX preference"
;
break
;
}
}
}
if
(
!
canonicalise
(
optarg
)
||
(
comma
&&
!
canonicalise
(
comma
)))
{
option
=
'?'
;
problem
=
"bad MX name"
;
break
;
}
else
{
struct
mx_record
*
new
=
safe_malloc
(
sizeof
(
struct
mx_record
));
new
=
safe_malloc
(
sizeof
(
struct
mx_record
));
new
->
next
=
daemon
->
mxnames
;
daemon
->
mxnames
=
new
;
new
->
mxname
=
safe_string_alloc
(
optarg
);
new
->
mxtarget
=
safe_string_alloc
(
comma
);
/* may be NULL */
}
new
->
preference
=
pref
;
break
;
}
...
...
@@ -747,7 +769,7 @@ struct daemon *read_opts (int argc, char **argv)
new
->
broadcast
.
s_addr
=
0
;
new
->
router
.
s_addr
=
0
;
new
->
netid
.
net
=
NULL
;
new
->
static_only
=
0
;
new
->
static_only
=
new
->
filter_netid
=
0
;
problem
=
"bad dhcp-range"
;
...
...
@@ -758,6 +780,13 @@ struct daemon *read_opts (int argc, char **argv)
if
(
*
cp
!=
','
&&
(
comma
=
strchr
(
optarg
,
','
)))
{
*
comma
=
0
;
if
(
strstr
(
optarg
,
"net:"
)
==
optarg
)
{
new
->
netid
.
net
=
safe_string_alloc
(
optarg
+
4
);
new
->
netid
.
next
=
NULL
;
new
->
filter_netid
=
1
;
}
else
new
->
netid
.
net
=
safe_string_alloc
(
optarg
);
a
[
0
]
=
comma
+
1
;
}
...
...
@@ -1363,6 +1392,84 @@ struct daemon *read_opts (int argc, char **argv)
break
;
}
case
'W'
:
{
int
port
=
1
,
priority
=
0
,
weight
=
0
;
char
*
name
,
*
target
=
NULL
;
struct
srv_record
*
new
;
if
((
comma
=
strchr
(
optarg
,
','
)))
*
(
comma
++
)
=
0
;
if
(
!
canonicalise
(
optarg
))
{
option
=
'?'
;
problem
=
"bad SRV record"
;
break
;
}
name
=
safe_string_alloc
(
optarg
);
if
(
comma
)
{
optarg
=
comma
;
if
((
comma
=
strchr
(
optarg
,
','
)))
*
(
comma
++
)
=
0
;
if
(
!
canonicalise
(
optarg
))
{
option
=
'?'
;
problem
=
"bad SRV target"
;
break
;
}
target
=
safe_string_alloc
(
optarg
);
if
(
comma
)
{
optarg
=
comma
;
if
((
comma
=
strchr
(
optarg
,
','
)))
*
(
comma
++
)
=
0
;
if
(
!
atoi_check
(
optarg
,
&
port
))
{
option
=
'?'
;
problem
=
"invalid port number"
;
break
;
}
if
(
comma
)
{
optarg
=
comma
;
if
((
comma
=
strchr
(
optarg
,
','
)))
*
(
comma
++
)
=
0
;
if
(
!
atoi_check
(
optarg
,
&
priority
))
{
option
=
'?'
;
problem
=
"invalid priority"
;
break
;
}
if
(
comma
)
{
optarg
=
comma
;
if
((
comma
=
strchr
(
optarg
,
','
)))
*
(
comma
++
)
=
0
;
if
(
!
atoi_check
(
optarg
,
&
weight
))
{
option
=
'?'
;
problem
=
"invalid weight"
;
break
;
}
}
}
}
}
new
=
safe_malloc
(
sizeof
(
struct
srv_record
));
new
->
next
=
daemon
->
srvnames
;
daemon
->
srvnames
=
new
;
new
->
srvname
=
name
;
new
->
srvtarget
=
target
;
new
->
srvport
=
port
;
new
->
priority
=
priority
;
new
->
weight
=
weight
;
break
;
}
}
}
...
...
@@ -1411,8 +1518,7 @@ struct daemon *read_opts (int argc, char **argv)
#endif
/* IPv6 */
}
/* only one of these need be specified: the other defaults to the
host-name */
/* only one of these need be specified: the other defaults to the host-name */
if
((
daemon
->
options
&
OPT_LOCALMX
)
||
daemon
->
mxnames
||
daemon
->
mxtarget
)
{
if
(
gethostname
(
buff
,
MAXDNAME
)
==
-
1
)
...
...
@@ -1424,12 +1530,28 @@ struct daemon *read_opts (int argc, char **argv)
daemon
->
mxnames
->
next
=
NULL
;
daemon
->
mxnames
->
mxtarget
=
NULL
;
daemon
->
mxnames
->
mxname
=
safe_string_alloc
(
buff
);
}
}
if
(
!
daemon
->
mxtarget
)
daemon
->
mxtarget
=
safe_string_alloc
(
buff
);
}
if
(
daemon
->
domain_suffix
)
{
/* add domain for any srv record without one. */
struct
srv_record
*
srv
;
for
(
srv
=
daemon
->
srvnames
;
srv
;
srv
=
srv
->
next
)
if
(
strchr
(
srv
->
srvname
,
'.'
)
&&
strchr
(
srv
->
srvname
,
'.'
)
==
strrchr
(
srv
->
srvname
,
'.'
))
{
strcpy
(
buff
,
srv
->
srvname
);
strcat
(
buff
,
"."
);
strcat
(
buff
,
daemon
->
domain_suffix
);
free
(
srv
->
srvname
);
srv
->
srvname
=
safe_string_alloc
(
buff
);
}
}
if
(
daemon
->
options
&
OPT_NO_RESOLV
)
daemon
->
resolv_files
=
0
;
else
if
(
daemon
->
resolv_files
&&
(
daemon
->
resolv_files
)
->
next
&&
(
daemon
->
options
&
OPT_NO_POLL
))
...
...
src/rfc1035.c
View file @
f6b7dc47
This diff is collapsed.
Click to expand it.
src/rfc2131.c
View file @
f6b7dc47
/* dnsmasq is Copyright (c) 2000-200
3
Simon Kelley
/* dnsmasq is Copyright (c) 2000-200
5
Simon Kelley
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
...
...
@@ -59,13 +59,12 @@ static unsigned char *option_end(unsigned char *p, unsigned char *end, struct dh
static
unsigned
char
*
option_put_string
(
unsigned
char
*
p
,
unsigned
char
*
end
,
int
opt
,
char
*
string
);
static
void
bootp_option_put
(
struct
dhcp_packet
*
mess
,
struct
dhcp_boot
*
boot_opts
,
struct
dhcp_netid
*
netids
);
static
unsigned
int
option_len
(
unsigned
char
*
opt
);
static
int
option_len
(
unsigned
char
*
opt
);
static
void
*
option_ptr
(
unsigned
char
*
opt
);
static
struct
in_addr
option_addr
(
unsigned
char
*
opt
);
static
unsigned
int
option_uint
(
unsigned
char
*
opt
,
int
size
);
static
void
log_packet
(
char
*
type
,
struct
in_addr
*
addr
,
unsigned
char
*
hwaddr
,
char
*
interface
,
char
*
string
);
static
int
match_netid
(
struct
dhcp_netid
*
check
,
struct
dhcp_netid
*
pool
);
static
unsigned
char
*
option_find
(
struct
dhcp_packet
*
mess
,
int
size
,
int
opt_type
,
unsigned
int
minsize
);
static
unsigned
char
*
option_find
(
struct
dhcp_packet
*
mess
,
int
size
,
int
opt_type
,
int
minsize
);
static
unsigned
char
*
do_req_options
(
struct
dhcp_context
*
context
,
unsigned
char
*
p
,
unsigned
char
*
end
,
unsigned
char
*
req_options
,
...
...
@@ -211,7 +210,7 @@ int dhcp_reply(struct daemon *daemon, struct in_addr iface_addr, char *iface_nam
if
(
have_config
(
config
,
CONFIG_NAME
))
hostname
=
config
->
hostname
;
if
(
context
->
netid
.
net
)
if
(
context
->
netid
.
net
&&
!
context
->
filter_netid
)
{
context
->
netid
.
next
=
netid
;
netid
=
&
context
->
netid
;
...
...
@@ -255,7 +254,7 @@ int dhcp_reply(struct daemon *daemon, struct in_addr iface_addr, char *iface_nam
hostname
=
config
->
hostname
;
else
if
((
opt
=
option_find
(
mess
,
sz
,
OPTION_HOSTNAME
,
1
)))
{
unsigned
int
len
=
option_len
(
opt
);
int
len
=
option_len
(
opt
);
hostname
=
daemon
->
dhcp_buff
;
memcpy
(
hostname
,
option_ptr
(
opt
),
len
);
/* May not be zero terminated */
...
...
@@ -291,7 +290,7 @@ int dhcp_reply(struct daemon *daemon, struct in_addr iface_addr, char *iface_nam
if
((
opt
=
option_find
(
mess
,
sz
,
OPTION_USER_CLASS
,
1
)))
{
unsigned
char
*
ucp
=
option_ptr
(
opt
);
unsigned
int
tmp
,
j
;
int
tmp
,
j
;
for
(
j
=
0
;
j
<
option_len
(
opt
);
j
+=
ucp
[
j
]
+
1
);
if
(
j
==
option_len
(
opt
))
for
(
j
=
0
;
j
<
option_len
(
opt
);
j
=
tmp
)
...
...
@@ -304,7 +303,7 @@ int dhcp_reply(struct daemon *daemon, struct in_addr iface_addr, char *iface_nam
for
(
vendor
=
daemon
->
dhcp_vendors
;
vendor
;
vendor
=
vendor
->
next
)
if
((
opt
=
option_find
(
mess
,
sz
,
vendor
->
is_vendor
?
OPTION_VENDOR_ID
:
OPTION_USER_CLASS
,
1
)))
{
unsigned
int
i
;
int
i
;
for
(
i
=
0
;
i
<=
(
option_len
(
opt
)
-
vendor
->
len
);
i
++
)
if
(
memcmp
(
vendor
->
data
,
option_ptr
(
opt
)
+
i
,
vendor
->
len
)
==
0
)
{
...
...
@@ -407,7 +406,7 @@ int dhcp_reply(struct daemon *daemon, struct in_addr iface_addr, char *iface_nam
else
if
(
opt
&&
address_available
(
context
,
addr
)
&&
!
lease_find_by_addr
(
addr
)
&&
!
config_find_by_address
(
daemon
->
dhcp_conf
,
addr
))
mess
->
yiaddr
=
addr
;
else
if
(
!
address_allocate
(
context
,
daemon
,
&
mess
->
yiaddr
,
mess
->
chaddr
))
else
if
(
!
address_allocate
(
context
,
daemon
,
&
mess
->
yiaddr
,
mess
->
chaddr
,
netid
))
message
=
"no address available"
;
log_packet
(
"DISCOVER"
,
opt
?
&
addr
:
NULL
,
mess
->
chaddr
,
iface_name
,
message
);
...
...
@@ -415,7 +414,7 @@ int dhcp_reply(struct daemon *daemon, struct in_addr iface_addr, char *iface_nam
return
0
;
context
=
narrow_context
(
context
,
mess
->
yiaddr
);
if
(
context
->
netid
.
net
)
if
(
context
->
netid
.
net
&&
!
context
->
filter_netid
)
{
context
->
netid
.
next
=
netid
;
netid
=
&
context
->
netid
;
...
...
@@ -542,7 +541,7 @@ int dhcp_reply(struct daemon *daemon, struct in_addr iface_addr, char *iface_nam
log_packet
(
"ACK"
,
&
mess
->
yiaddr
,
mess
->
chaddr
,
iface_name
,
hostname
);
context
=
narrow_context
(
context
,
mess
->
yiaddr
);
if
(
context
->
netid
.
net
)
if
(
context
->
netid
.
net
&&
!
context
->
filter_netid
)
{
context
->
netid
.
next
=
netid
;
netid
=
&
context
->
netid
;
...
...
@@ -628,7 +627,7 @@ static void log_packet(char *type, struct in_addr *addr, unsigned char *hwaddr,
string
?
string
:
""
);
}
static
unsigned
int
option_len
(
unsigned
char
*
opt
)
static
int
option_len
(
unsigned
char
*
opt
)
{
return
opt
[
1
];
}
...
...
@@ -769,7 +768,7 @@ static unsigned char *option_find1(unsigned char *p, unsigned char *end, int opt
return
NULL
;
}
static
unsigned
char
*
option_find
(
struct
dhcp_packet
*
mess
,
int
size
,
int
opt_type
,
unsigned
int
minsize
)
static
unsigned
char
*
option_find
(
struct
dhcp_packet
*
mess
,
int
size
,
int
opt_type
,
int
minsize
)
{
int
overload
=
0
;
unsigned
char
*
ret
;
...
...
@@ -805,32 +804,6 @@ static int in_list(unsigned char *list, int opt)
return
0
;
}
/* Is every member of check matched by a member of pool? */
static
int
match_netid
(
struct
dhcp_netid
*
check
,
struct
dhcp_netid
*
pool
)
{
struct
dhcp_netid
*
tmp1
;
if
(
!
check
)
return
0
;
for
(;
check
;
check
=
check
->
next
)
{
if
(
check
->
net
[
0
]
!=
'#'
)
{
for
(
tmp1
=
pool
;
tmp1
;
tmp1
=
tmp1
->
next
)
if
(
strcmp
(
check
->
net
,
tmp1
->
net
)
==
0
)
break
;
if
(
!
tmp1
)
return
0
;
}
else
for
(
tmp1
=
pool
;
tmp1
;
tmp1
=
tmp1
->
next
)
if
(
strcmp
((
check
->
net
)
+
1
,
tmp1
->
net
)
==
0
)
return
0
;
}
return
1
;
}
static
struct
dhcp_opt
*
option_find2
(
struct
dhcp_netid
*
netid
,
struct
dhcp_opt
*
opts
,
int
opt
)
{
struct
dhcp_opt
*
tmp
;
...
...
src/util.c
View file @
f6b7dc47
...
...
@@ -113,11 +113,11 @@ int legal_char(char c)
int
canonicalise
(
char
*
s
)
{
/* check for legal chars and remove trailing .
also fail empty string
.
*/
int
l
=
strlen
(
s
);
also fail empty string
and label > 63 chars
*/
int
dotgap
=
0
,
l
=
strlen
(
s
);
char
c
;
if
(
l
==
0
)
return
0
;
if
(
l
==
0
||
l
>
MAXDNAME
)
return
0
;
if
(
s
[
l
-
1
]
==
'.'
)
{
...
...
@@ -126,7 +126,9 @@ int canonicalise(char *s)
}
while
((
c
=
*
s
++
))
if
(
c
!=
'.'
&&
!
legal_char
(
c
))
if
(
c
==
'.'
)
dotgap
=
0
;
else
if
(
!
legal_char
(
c
)
||
(
++
dotgap
>
MAXLABEL
))
return
0
;
return
1
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment