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
36717eee
Commit
36717eee
authored
Sep 20, 2004
by
Simon Kelley
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
import of dnsmasq-2.15.tar.gz
parent
3be34541
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
314 additions
and
147 deletions
+314
-147
CHANGELOG
CHANGELOG
+24
-0
dnsmasq-rh.spec
dnsmasq-rh.spec
+1
-1
dnsmasq-suse.spec
dnsmasq-suse.spec
+1
-1
src/config.h
src/config.h
+1
-1
src/dhcp.c
src/dhcp.c
+59
-52
src/dnsmasq.h
src/dnsmasq.h
+7
-3
src/forward.c
src/forward.c
+84
-40
src/option.c
src/option.c
+43
-14
src/rfc1035.c
src/rfc1035.c
+67
-15
src/rfc2131.c
src/rfc2131.c
+27
-20
No files found.
CHANGELOG
View file @
36717eee
...
...
@@ -1190,3 +1190,27 @@ version 2.14
Added "keep-in-foreground" option. Thanks to Sean
MacLennan for the patch.
version 2.15
Fixed NXDOMAIN/NODATA confusion for locally known
names. We now return a NODATA reponse for names which are
locally known. Now a query for (eg AAAA or MX) for a name
with an IPv4 address in /etc/hosts which fails upstream
will generate a NODATA response. Note that the query
is still tried upstream, but a NXDOMAIN reply gets
converted to NODATA. Thanks to Eric de Thouars, Eric
Spakman and Mike Mestnik for bug reports/testing.
Allow multiple dhcp-ranges within the same network. The
original intention was that there would be a dhcp-range
option for each network served, but there's no real reason
not to allow discontinuous ranges within a network so this
release adds support for that.
Check for dhcp-ranges which are inconsistent with their
netmask, and generate errors or warnings.
Improve error messages when there are problems with
configuration.
dnsmasq-rh.spec
View file @
36717eee
...
...
@@ -5,7 +5,7 @@
###############################################################################
Name: dnsmasq
Version: 2.1
4
Version: 2.1
5
Release: 1
Copyright: GPL
Group: System Environment/Daemons
...
...
dnsmasq-suse.spec
View file @
36717eee
...
...
@@ -5,7 +5,7 @@
###############################################################################
Name: dnsmasq
Version: 2.1
4
Version: 2.1
5
Release: 1
Copyright: GPL
Group: Productivity/Networking/DNS/Servers
...
...
src/config.h
View file @
36717eee
...
...
@@ -12,7 +12,7 @@
/* Author's email: simon@thekelleys.org.uk */
#define VERSION "2.1
4
"
#define VERSION "2.1
5
"
#define FTABSIZ 150
/* max number of outstanding requests */
#define MAX_PROCS 20
/* max no children for TCP requests */
...
...
src/dhcp.c
View file @
36717eee
...
...
@@ -209,9 +209,19 @@ void dhcp_packet(struct daemon *daemon, time_t now)
iface_netmask
=
((
struct
sockaddr_in
*
)
&
ifr
.
ifr_addr
)
->
sin_addr
;
if
(
iface_netmask
.
s_addr
&&
is_same_net
(
iface_addr
,
context
->
start
,
iface_netmask
)
&&
is_same_net
(
iface_addr
,
context
->
end
,
iface_netmask
))
(
is_same_net
(
iface_addr
,
context
->
start
,
iface_netmask
)
||
is_same_net
(
iface_addr
,
context
->
end
,
iface_netmask
)))
{
context
->
netmask
=
iface_netmask
;
if
(
!
(
is_same_net
(
iface_addr
,
context
->
start
,
iface_netmask
)
&&
is_same_net
(
iface_addr
,
context
->
end
,
iface_netmask
)))
{
strcpy
(
daemon
->
dhcp_buff
,
inet_ntoa
(
context
->
start
));
strcpy
(
daemon
->
dhcp_buff2
,
inet_ntoa
(
context
->
end
));
syslog
(
LOG_WARNING
,
"DHCP range %s -- %s is not consistent with netmask %s"
,
daemon
->
dhcp_buff
,
daemon
->
dhcp_buff2
,
inet_ntoa
(
iface_netmask
));
}
}
}
/* Determine "default" default routes. These are to this server or the relay agent.
...
...
@@ -226,7 +236,8 @@ void dhcp_packet(struct daemon *daemon, time_t now)
{
if
(
!
iface_broadcast
.
s_addr
&&
ioctl
(
daemon
->
dhcpfd
,
SIOCGIFBRDADDR
,
&
ifr
)
!=
-
1
)
iface_broadcast
=
((
struct
sockaddr_in
*
)
&
ifr
.
ifr_addr
)
->
sin_addr
;
if
(
iface_broadcast
.
s_addr
)
if
(
iface_broadcast
.
s_addr
&&
is_same_net
(
iface_broadcast
,
context
->
start
,
context
->
netmask
))
context
->
broadcast
=
iface_broadcast
;
else
context
->
broadcast
.
s_addr
=
context
->
start
.
s_addr
|
~
context
->
netmask
.
s_addr
;
...
...
@@ -361,26 +372,23 @@ void dhcp_packet(struct daemon *daemon, time_t now)
int
address_available
(
struct
dhcp_context
*
context
,
struct
in_addr
taddr
)
{
/* Check is an address is OK for this network,
ie
within allowable range and not in an existing lease
*/
/* Check is an address is OK for this network,
check all
possible ranges.
*/
unsigned
int
addr
,
start
,
end
;
unsigned
int
start
,
end
,
addr
=
ntohl
(
taddr
.
s_addr
)
;
/* static leases only. */
if
(
context
->
static_only
)
return
0
;
addr
=
ntohl
(
taddr
.
s_addr
);
for
(;
context
;
context
=
context
->
current
)
{
start
=
ntohl
(
context
->
start
.
s_addr
);
end
=
ntohl
(
context
->
end
.
s_addr
);
if
(
addr
<
start
)
return
0
;
if
(
!
context
->
static_only
&&
addr
>=
start
&&
addr
<=
end
)
return
1
;
}
if
(
addr
>
end
)
return
0
;
return
1
;
}
struct
dhcp_config
*
config_find_by_address
(
struct
dhcp_config
*
configs
,
struct
in_addr
addr
)
...
...
@@ -403,10 +411,9 @@ int address_allocate(struct dhcp_context *context, struct daemon *daemon,
struct
in_addr
start
,
addr
;
unsigned
int
i
,
j
;
/* check if no dynamic leases. */
if
(
context
->
static_only
)
return
0
;
for
(;
context
;
context
=
context
->
current
)
if
(
!
context
->
static_only
)
{
/* 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
++
)
j
+=
hwaddr
[
i
]
+
(
hwaddr
[
i
]
<<
8
)
+
(
hwaddr
[
i
]
<<
16
);
...
...
@@ -436,7 +443,7 @@ int address_allocate(struct dhcp_context *context, struct daemon *daemon,
addr
=
context
->
start
;
}
while
(
addr
.
s_addr
!=
start
.
s_addr
);
}
return
0
;
}
...
...
src/dnsmasq.h
View file @
36717eee
...
...
@@ -294,7 +294,7 @@ struct dhcp_context {
struct
in_addr
start
,
end
;
/* range of available addresses */
int
static_only
;
struct
dhcp_netid
netid
;
struct
dhcp_context
*
next
;
struct
dhcp_context
*
next
,
*
current
;
};
typedef
unsigned
char
u8
;
...
...
@@ -393,11 +393,15 @@ 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
doctor
*
doctors
);
void
extract_neg_addrs
(
HEADER
*
header
,
unsigned
int
qlen
,
char
*
namebuff
,
time_t
now
);
void
extract_neg_addrs
(
HEADER
*
header
,
unsigned
int
qlen
,
char
*
namebuff
,
time_t
now
,
unsigned
short
flags
);
int
answer_request
(
HEADER
*
header
,
char
*
limit
,
unsigned
int
qlen
,
struct
daemon
*
daemon
,
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
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
resize_packet
(
HEADER
*
header
,
unsigned
int
plen
,
unsigned
char
*
pheader
,
unsigned
int
hlen
);
/* util.c */
unsigned
short
rand16
(
void
);
...
...
src/forward.c
View file @
36717eee
...
...
@@ -114,7 +114,7 @@ static void send_from(int fd, int nowild, char *packet, int len,
}
}
unsigned
short
search_servers
(
struct
daemon
*
daemon
,
struct
all_addr
**
addrpp
,
static
unsigned
short
search_servers
(
struct
daemon
*
daemon
,
time_t
now
,
struct
all_addr
**
addrpp
,
unsigned
short
qtype
,
char
*
qdomain
,
int
*
type
,
char
**
domain
)
{
...
...
@@ -133,10 +133,11 @@ unsigned short search_servers(struct daemon *daemon, struct all_addr **addrpp,
{
unsigned
short
sflag
=
serv
->
addr
.
sa
.
sa_family
==
AF_INET
?
F_IPV4
:
F_IPV6
;
*
type
=
SERV_FOR_NODOTS
;
flags
=
0
;
if
(
serv
->
flags
&
SERV_NO_ADDR
)
flags
=
F_NXDOMAIN
;
else
if
((
serv
->
flags
&
SERV_LITERAL_ADDRESS
)
&&
(
sflag
&
qtype
))
else
if
(
serv
->
flags
&
SERV_LITERAL_ADDRESS
)
{
if
(
sflag
&
qtype
)
{
flags
=
sflag
;
if
(
serv
->
addr
.
sa
.
sa_family
==
AF_INET
)
...
...
@@ -146,6 +147,9 @@ unsigned short search_servers(struct daemon *daemon, struct all_addr **addrpp,
*
addrpp
=
(
struct
all_addr
*
)
&
serv
->
addr
.
in6
.
sin6_addr
;
#endif
}
else
if
(
!
flags
)
flags
=
F_NOERR
;
}
}
else
if
(
serv
->
flags
&
SERV_HAS_DOMAIN
)
{
...
...
@@ -158,10 +162,11 @@ unsigned short search_servers(struct daemon *daemon, struct all_addr **addrpp,
*
type
=
SERV_HAS_DOMAIN
;
*
domain
=
serv
->
domain
;
matchlen
=
domainlen
;
flags
=
0
;
if
(
serv
->
flags
&
SERV_NO_ADDR
)
flags
=
F_NXDOMAIN
;
else
if
((
serv
->
flags
&
SERV_LITERAL_ADDRESS
)
&&
((
sflag
|
F_QUERY
)
&
qtype
))
else
if
(
serv
->
flags
&
SERV_LITERAL_ADDRESS
)
{
if
((
sflag
|
F_QUERY
)
&
qtype
)
{
flags
=
qtype
;
if
(
serv
->
addr
.
sa
.
sa_family
==
AF_INET
)
...
...
@@ -171,10 +176,13 @@ unsigned short search_servers(struct daemon *daemon, struct all_addr **addrpp,
*
addrpp
=
(
struct
all_addr
*
)
&
serv
->
addr
.
in6
.
sin6_addr
;
#endif
}
else
if
(
!
flags
)
flags
=
F_NOERR
;
}
}
}
if
(
flags
&
~
F_NXDOMAIN
)
/* flags set here means a literal found */
if
(
flags
&
~
(
F_NOERR
|
F_NXDOMAIN
)
)
/* flags set here means a literal found */
{
if
(
flags
&
F_QUERY
)
log_query
(
F_CONFIG
|
F_FORWARD
|
F_NEG
,
qdomain
,
NULL
,
0
);
...
...
@@ -182,9 +190,12 @@ unsigned short search_servers(struct daemon *daemon, struct all_addr **addrpp,
log_query
(
F_CONFIG
|
F_FORWARD
|
flags
,
qdomain
,
*
addrpp
,
0
);
}
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
))
flags
=
F_NOERR
;
if
(
flags
&
(
F_NOERR
|
F_NXDOMAIN
)
)
if
(
flags
==
F_NXDOMAIN
||
flags
==
F_NOERR
)
log_query
(
F_CONFIG
|
F_FORWARD
|
F_NEG
|
qtype
|
(
flags
&
F_NXDOMAIN
),
qdomain
,
NULL
,
0
);
return
flags
;
...
...
@@ -223,7 +234,7 @@ static void forward_query(struct daemon *daemon, int udpfd, union mysockaddr *ud
else
{
if
(
gotname
)
flags
=
search_servers
(
daemon
,
&
addrp
,
gotname
,
daemon
->
namebuff
,
&
type
,
&
domain
);
flags
=
search_servers
(
daemon
,
now
,
&
addrp
,
gotname
,
daemon
->
namebuff
,
&
type
,
&
domain
);
if
(
!
flags
&&
!
(
forward
=
get_new_frec
(
now
)))
/* table full - server failure. */
...
...
@@ -316,20 +327,21 @@ static void forward_query(struct daemon *daemon, int udpfd, union mysockaddr *ud
}
static
int
process_reply
(
struct
daemon
*
daemon
,
HEADER
*
header
,
time_t
now
,
union
mysockaddr
*
serveraddr
,
int
n
)
union
mysockaddr
*
serveraddr
,
unsigned
int
n
)
{
unsigned
char
*
pheader
;
unsigned
char
*
pheader
,
*
sizep
;
unsigned
int
plen
;
/* If upstream is advertising a larger UDP packet size
than we allow, trim it so that we don't get overlarge
requests for the client. */
if
((
pheader
=
find_pseudoheader
(
header
,
n
)))
if
((
pheader
=
find_pseudoheader
(
header
,
n
,
&
plen
,
&
sizep
)))
{
unsigned
short
udpsz
;
unsigned
char
*
psave
=
pheader
;
unsigned
char
*
psave
=
sizep
;
GETSHORT
(
udpsz
,
pheader
);
GETSHORT
(
udpsz
,
sizep
);
if
(
udpsz
>
daemon
->
edns_pktsz
)
PUTSHORT
(
daemon
->
edns_pktsz
,
psave
);
}
...
...
@@ -350,20 +362,52 @@ static int process_reply(struct daemon *daemon, HEADER *header, time_t now,
return
0
;
}
if
((
header
->
rcode
==
NOERROR
||
header
->
rcode
==
NXDOMAIN
)
&&
header
->
opcode
==
QUERY
)
if
(
header
->
opcode
!=
QUERY
||
(
header
->
rcode
!=
NOERROR
&&
header
->
rcode
!=
NXDOMAIN
))
return
n
;
if
(
header
->
rcode
==
NOERROR
&&
ntohs
(
header
->
ancount
)
!=
0
)
{
if
(
!
(
daemon
->
bogus_addr
&&
header
->
rcode
==
NOERROR
&&
check_for_bogus_wildcard
(
header
,
(
unsigned
int
)
n
,
daemon
->
namebuff
,
daemon
->
bogus_addr
,
now
)))
check_for_bogus_wildcard
(
header
,
n
,
daemon
->
namebuff
,
daemon
->
bogus_addr
,
now
)))
extract_addresses
(
header
,
n
,
daemon
->
namebuff
,
now
,
daemon
->
doctors
);
}
else
{
if
(
header
->
rcode
==
NOERROR
&&
ntohs
(
header
->
ancount
)
!=
0
)
extract_addresses
(
header
,
(
unsigned
int
)
n
,
daemon
->
namebuff
,
now
,
daemon
->
doctors
);
else
if
(
!
(
daemon
->
options
&
OPT_NO_NEG
))
extract_neg_addrs
(
header
,
(
unsigned
int
)
n
,
daemon
->
namebuff
,
now
);
unsigned
short
flags
=
F_NEG
;
int
munged
=
0
;
if
(
header
->
rcode
==
NXDOMAIN
)
{
/* 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,
since we know that the domain exists, even if upstream doesn't */
if
(
extract_request
(
header
,
n
,
daemon
->
namebuff
,
NULL
)
&&
check_for_local_domain
(
daemon
->
namebuff
,
now
,
daemon
->
mxnames
))
{
munged
=
1
;
header
->
rcode
=
NOERROR
;
}
else
flags
|=
F_NXDOMAIN
;
}
return
1
;
if
(
!
(
daemon
->
options
&
OPT_NO_NEG
))
extract_neg_addrs
(
header
,
n
,
daemon
->
namebuff
,
now
,
flags
);
/* do this after extract_neg_addrs. Ensure NODATA reply and remove
nameserver info. */
if
(
munged
)
{
header
->
ancount
=
htons
(
0
);
header
->
nscount
=
htons
(
0
);
header
->
arcount
=
htons
(
0
);
}
}
/* the bogus-nxdomain stuff, doctor and NXDOMAIN->NODATA munging can all elide
sections of the packet. Find the new length here and put back pseudoheader
if it was removed. */
return
resize_packet
(
header
,
n
,
pheader
,
plen
);
}
/* sets new last_server */
...
...
@@ -401,7 +445,7 @@ void reply_query(struct serverfd *sfd, struct daemon *daemon, time_t now)
}
}
if
(
process_reply
(
daemon
,
header
,
now
,
&
serveraddr
,
n
))
if
(
(
n
=
process_reply
(
daemon
,
header
,
now
,
&
serveraddr
,
(
unsigned
int
)
n
)
))
{
header
->
id
=
htons
(
forward
->
orig_id
);
send_from
(
forward
->
fd
,
daemon
->
options
&
OPT_NOWILD
,
daemon
->
packet
,
n
,
...
...
@@ -654,7 +698,7 @@ char *tcp_request(struct daemon *daemon, int confd, time_t now)
char
*
domain
=
NULL
;
if
(
gotname
)
flags
=
search_servers
(
daemon
,
&
addrp
,
gotname
,
daemon
->
namebuff
,
&
type
,
&
domain
);
flags
=
search_servers
(
daemon
,
now
,
&
addrp
,
gotname
,
daemon
->
namebuff
,
&
type
,
&
domain
);
if
(
type
!=
0
||
(
daemon
->
options
&
OPT_ORDER
)
||
!
daemon
->
last_server
)
last_server
=
daemon
->
servers
;
...
...
@@ -729,7 +773,7 @@ char *tcp_request(struct daemon *daemon, int confd, time_t now)
/* There's no point in updating the cache, since this process will exit and
lose the information after one query. We make this call for the alias and
bogus-nxdomain side-effects. */
process_reply
(
daemon
,
header
,
now
,
&
last_server
->
addr
,
m
);
m
=
process_reply
(
daemon
,
header
,
now
,
&
last_server
->
addr
,
(
unsigned
int
)
m
);
break
;
}
...
...
src/option.c
View file @
36717eee
...
...
@@ -161,7 +161,7 @@ static char *usage =
struct
daemon
*
read_opts
(
int
argc
,
char
**
argv
)
{
struct
daemon
*
daemon
=
safe_malloc
(
sizeof
(
struct
daemon
));
char
*
buff
=
safe_malloc
(
MAXDNAME
);
char
*
problem
=
NULL
,
*
buff
=
safe_malloc
(
MAXDNAME
);
int
option
=
0
,
i
;
FILE
*
file_save
=
NULL
,
*
f
=
NULL
;
char
*
file_name_save
=
NULL
,
*
conffile
=
CONFFILE
;
...
...
@@ -187,6 +187,8 @@ struct daemon *read_opts (int argc, char **argv)
while
(
1
)
{
problem
=
NULL
;
if
(
!
f
)
#ifdef HAVE_GETOPT_LONG
option
=
getopt_long
(
argc
,
argv
,
OPTSTRING
,
(
struct
option
*
)
opts
,
NULL
);
...
...
@@ -366,7 +368,10 @@ struct daemon *read_opts (int argc, char **argv)
if
(
comma
)
*
(
comma
++
)
=
0
;
if
(
!
canonicalise
(
optarg
)
||
(
comma
&&
!
canonicalise
(
comma
)))
{
option
=
'?'
;
problem
=
"bad MX name"
;
}
else
{
struct
mx_record
*
new
=
safe_malloc
(
sizeof
(
struct
mx_record
));
...
...
@@ -380,7 +385,10 @@ struct daemon *read_opts (int argc, char **argv)
case
't'
:
if
(
!
canonicalise
(
optarg
))
{
option
=
'?'
;
problem
=
"bad MX target"
;
}
else
daemon
->
mxtarget
=
safe_string_alloc
(
optarg
);
break
;
...
...
@@ -391,7 +399,10 @@ struct daemon *read_opts (int argc, char **argv)
case
'H'
:
if
(
daemon
->
addn_hosts
)
{
option
=
'?'
;
problem
=
"only one addn hosts file allowed"
;
}
else
daemon
->
addn_hosts
=
safe_string_alloc
(
optarg
);
break
;
...
...
@@ -563,7 +574,10 @@ struct daemon *read_opts (int argc, char **argv)
{
*
portno
=
0
;
if
(
!
atoi_check
(
portno
+
1
,
&
source_port
))
{
option
=
'?'
;
problem
=
"bad port"
;
}
}
}
...
...
@@ -571,7 +585,10 @@ struct daemon *read_opts (int argc, char **argv)
{
*
portno
=
0
;
if
(
!
atoi_check
(
portno
+
1
,
&
serv_port
))
{
option
=
'?'
;
problem
=
"bad port"
;
}
}
#ifdef HAVE_IPV6
...
...
@@ -717,6 +734,8 @@ struct daemon *read_opts (int argc, char **argv)
new
->
netid
.
net
=
NULL
;
new
->
static_only
=
0
;
problem
=
"bad dhcp-range"
;
for
(
cp
=
optarg
;
*
cp
;
cp
++
)
if
(
!
(
*
cp
==
' '
||
*
cp
==
'.'
||
(
*
cp
>=
'0'
&&
*
cp
<=
'9'
)))
break
;
...
...
@@ -755,6 +774,17 @@ struct daemon *read_opts (int argc, char **argv)
new
->
end
=
tmp
;
}
if
(
option
!=
'?'
&&
k
>=
3
&&
strchr
(
a
[
2
],
'.'
)
&&
((
new
->
netmask
.
s_addr
=
inet_addr
(
a
[
2
]))
!=
(
in_addr_t
)
-
1
))
{
leasepos
=
3
;
if
(
!
is_same_net
(
new
->
start
,
new
->
end
,
new
->
netmask
))
{
problem
=
"inconsistent DHCP range"
;
option
=
'?'
;
}
}
if
(
option
==
'?'
)
{
free
(
new
);
...
...
@@ -763,10 +793,6 @@ struct daemon *read_opts (int argc, char **argv)
else
daemon
->
dhcp
=
new
;
if
(
k
>=
3
&&
strchr
(
a
[
2
],
'.'
)
&&
((
new
->
netmask
.
s_addr
=
inet_addr
(
a
[
2
]))
!=
(
in_addr_t
)
-
1
))
leasepos
=
3
;
if
(
k
>=
4
&&
strchr
(
a
[
3
],
'.'
)
&&
((
new
->
broadcast
.
s_addr
=
inet_addr
(
a
[
3
]))
!=
(
in_addr_t
)
-
1
))
leasepos
=
4
;
...
...
@@ -955,6 +981,7 @@ struct daemon *read_opts (int argc, char **argv)
if
(
option
==
'?'
)
{
problem
=
"bad dhcp-host"
;
if
(
new
->
flags
&
CONFIG_NAME
)
free
(
new
->
hostname
);
if
(
new
->
flags
&
CONFIG_CLID
)
...
...
@@ -1003,6 +1030,7 @@ struct daemon *read_opts (int argc, char **argv)
if
((
new
->
opt
=
atoi
(
optarg
))
==
0
)
{
option
=
'?'
;
problem
=
"bad dhcp-opt"
;
if
(
new
->
netid
)
free
(
new
->
netid
);
free
(
new
);
...
...
@@ -1203,11 +1231,12 @@ struct daemon *read_opts (int argc, char **argv)
{
if
(
f
)
{
sprintf
(
buff
,
"error at line %d of %s "
,
lineno
,
conffile
);
sprintf
(
buff
,
"%s at line %d of %s "
,
problem
?
problem
:
"error"
,
lineno
,
conffile
);
complain
(
buff
,
NULL
);
}
else
die
(
"bad command line options:
try --help."
,
NULL
);
die
(
"bad command line options:
%s."
,
problem
?
problem
:
"try --help"
);
}
}
...
...
src/rfc1035.c
View file @
36717eee
...
...
@@ -306,9 +306,44 @@ static unsigned char *skip_questions(HEADER *header, unsigned int plen)
return
ansp
;
}
unsigned
char
*
find_pseudoheader
(
HEADER
*
header
,
unsigned
int
p
len
)
int
resize_packet
(
HEADER
*
header
,
unsigned
int
plen
,
unsigned
char
*
pheader
,
unsigned
int
h
len
)
{
/* See if packet has an RFC2671 pseudoheader, and if so return a pointer to it. */
int
i
;
unsigned
char
*
ansp
=
skip_questions
(
header
,
plen
);
unsigned
short
rdlen
;
if
(
!
ansp
)
return
0
;
for
(
i
=
0
;
i
<
(
ntohs
(
header
->
ancount
)
+
ntohs
(
header
->
nscount
)
+
ntohs
(
header
->
arcount
));
i
++
)
{
if
(
!
(
ansp
=
skip_name
(
ansp
,
header
,
plen
)))
return
0
;
ansp
+=
8
;
/* type, class, TTL */
GETSHORT
(
rdlen
,
ansp
);
if
((
unsigned
int
)(
ansp
+
rdlen
-
(
unsigned
char
*
)
header
)
>
plen
)
return
0
;
ansp
+=
rdlen
;
}
/* restore pseudoheader */
if
(
pheader
&&
ntohs
(
header
->
arcount
)
==
0
)
{
/* must use memmove, may overlap */
memmove
(
ansp
,
pheader
,
hlen
);
header
->
arcount
=
htons
(
1
);
ansp
+=
hlen
;
}
return
ansp
-
(
unsigned
char
*
)
header
;
}
unsigned
char
*
find_pseudoheader
(
HEADER
*
header
,
unsigned
int
plen
,
unsigned
int
*
len
,
unsigned
char
**
p
)
{
/* See if packet has an RFC2671 pseudoheader, and if so return a pointer to it.
also return length of pseudoheader in *len and pointer to the UDP size in *p */
int
i
,
arcount
=
ntohs
(
header
->
arcount
);
unsigned
char
*
ansp
;
...
...
@@ -330,7 +365,7 @@ unsigned char *find_pseudoheader(HEADER *header, unsigned int plen)
for
(
i
=
0
;
i
<
arcount
;
i
++
)
{
unsigned
char
*
save
;
unsigned
char
*
save
,
*
start
=
ansp
;
if
(
!
(
ansp
=
skip_name
(
ansp
,
header
,
plen
)))
return
NULL
;
...
...
@@ -340,9 +375,15 @@ unsigned char *find_pseudoheader(HEADER *header, unsigned int plen)
GETSHORT
(
rdlen
,
ansp
);
if
((
unsigned
int
)(
ansp
+
rdlen
-
(
unsigned
char
*
)
header
)
>
plen
)
return
NULL
;
if
(
type
==
T_OPT
)
return
save
;
ansp
+=
rdlen
;
if
(
type
==
T_OPT
)
{
if
(
len
)
*
len
=
ansp
-
start
;
if
(
p
)
*
p
=
save
;
return
start
;
}
}
return
NULL
;
...
...
@@ -397,16 +438,12 @@ static unsigned char *add_text_record(unsigned int nameoffset, unsigned char *p,
/* On receiving an NXDOMAIN or NODATA reply, determine which names are known
not to exist for negative caching. name if a working buffer passed in. */
void
extract_neg_addrs
(
HEADER
*
header
,
unsigned
int
qlen
,
char
*
name
,
time_t
now
)
void
extract_neg_addrs
(
HEADER
*
header
,
unsigned
int
qlen
,
char
*
name
,
time_t
now
,
unsigned
short
flags
)
{
unsigned
char
*
p
;
int
i
,
found_soa
=
0
;
int
qtype
,
qclass
,
rdlen
;
unsigned
long
ttl
,
minttl
=
0
;
unsigned
short
flags
=
F_NEG
;
if
(
header
->
rcode
==
NXDOMAIN
)
flags
|=
F_NXDOMAIN
;
/* there may be more than one question with some questions
answered. We don't generate negative entries from those. */
...
...
@@ -736,6 +773,21 @@ int setup_reply(HEADER *header, unsigned int qlen,
return
p
-
(
unsigned
char
*
)
header
;
}
/* check if name matches local names ie from /etc/hosts or DHCP or local mx names. */
int
check_for_local_domain
(
char
*
name
,
time_t
now
,
struct
mx_record
*
mx
)
{
struct
crec
*
crecp
;
if
((
crecp
=
cache_find_by_name
(
NULL
,
name
,
now
,
F_IPV4
|
F_IPV6
))
&&
(
crecp
->
flags
&
(
F_HOSTS
|
F_DHCP
)))
return
1
;
for
(;
mx
;
mx
=
mx
->
next
)
if
(
hostname_isequal
(
name
,
mx
->
mxname
))
return
1
;
return
0
;
}
/* Is the packet a reply with the answer address equal to addr?
If so mung is into an NXDOMAIN reply and also put that information
...
...
@@ -811,7 +863,7 @@ int answer_request(HEADER *header, char *limit, unsigned int qlen, struct daemon
forward rather than answering from the cache, which doesn't include
security information. */
if
(
(
pheader
=
find_pseudoheader
(
header
,
qlen
)
))
if
(
find_pseudoheader
(
header
,
qlen
,
NULL
,
&
pheader
))
{
unsigned
short
udpsz
,
ext_rcode
,
flags
;
unsigned
char
*
psave
=
pheader
;
...
...
src/rfc2131.c
View file @
36717eee
...
...
@@ -80,7 +80,7 @@ static int have_config(struct dhcp_config *config, unsigned int mask)
int
dhcp_reply
(
struct
daemon
*
daemon
,
struct
in_addr
iface_addr
,
char
*
iface_name
,
unsigned
int
sz
,
time_t
now
)
{
struct
dhcp_context
*
context
;
struct
dhcp_context
*
context
,
*
context_tmp
;
unsigned
char
*
opt
,
*
clid
;
struct
dhcp_lease
*
lease
,
*
ltmp
;
struct
dhcp_vendor
*
vendor
;
...
...
@@ -149,11 +149,24 @@ int dhcp_reply(struct daemon *daemon, struct in_addr iface_addr, char *iface_nam
(
mess
->
giaddr
.
s_addr
?
mess
->
giaddr
:
(
mess
->
ciaddr
.
s_addr
?
mess
->
ciaddr
:
iface_addr
));
for
(
context
=
daemon
->
dhcp
;
context
;
context
=
context
->
next
)
if
(
context
->
netmask
.
s_addr
&&
is_same_net
(
addr
,
context
->
start
,
context
->
netmask
)
&&
is_same_net
(
addr
,
context
->
end
,
context
->
netmask
))
break
;
/* More than one context may match, we build a chain of them all on ->current
Note that if netmasks, netid or lease times don't match, odd things may happen. */
for
(
context
=
NULL
,
context_tmp
=
daemon
->
dhcp
;
context_tmp
;
context_tmp
=
context_tmp
->
next
)
if
(
context_tmp
->
netmask
.
s_addr
&&
is_same_net
(
addr
,
context_tmp
->
start
,
context_tmp
->
netmask
)
&&
is_same_net
(
addr
,
context_tmp
->
end
,
context_tmp
->
netmask
))
{
context_tmp
->
current
=
context
;
context
=
context_tmp
;
/* start to build netid chain */
if
(
context_tmp
->
netid
.
net
)
{
context_tmp
->
netid
.
next
=
netid
;
netid
=
&
context_tmp
->
netid
;
}
}
if
(
!
context
)
{
...
...
@@ -165,13 +178,6 @@ int dhcp_reply(struct daemon *daemon, struct in_addr iface_addr, char *iface_nam
mess
->
op
=
BOOTREPLY
;
/* start to build netid chain */
if
(
context
->
netid
.
net
)
{
context
->
netid
.
next
=
netid
;
netid
=
&
context
->
netid
;
}
if
(
mess_type
==
0
)
{
/* BOOTP request */
...
...
@@ -268,8 +274,6 @@ int dhcp_reply(struct daemon *daemon, struct in_addr iface_addr, char *iface_nam
}
}
def_time
=
have_config
(
config
,
CONFIG_TIME
)
?
config
->
lease_time
:
context
->
lease_time
;
if
(
have_config
(
config
,
CONFIG_NETID
))
{
config
->
netid
.
next
=
netid
;
...
...
@@ -326,6 +330,8 @@ int dhcp_reply(struct daemon *daemon, struct in_addr iface_addr, char *iface_nam
/* do we have a lease in store? */
lease
=
lease_find_by_client
(
clid
,
clid_len
);
def_time
=
have_config
(
config
,
CONFIG_TIME
)
?
config
->
lease_time
:
context
->
lease_time
;
if
((
opt
=
option_find
(
mess
,
sz
,
OPTION_LEASE_TIME
)))
{
unsigned
int
req_time
=
option_uint
(
opt
,
4
);
...
...
@@ -392,6 +398,7 @@ int dhcp_reply(struct daemon *daemon, struct in_addr iface_addr, char *iface_nam
}
else
/* make sure this host gets a different address next time. */
for
(;
context
;
context
=
context
->
current
)
context
->
addr_epoch
++
;
return
0
;
...
...
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