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
c2bcd1e1
Commit
c2bcd1e1
authored
Dec 15, 2015
by
Simon Kelley
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Generalise RR-filtering code, for use with EDNS0.
parent
d64c81ff
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
349 additions
and
309 deletions
+349
-309
Makefile
Makefile
+2
-1
bld/Android.mk
bld/Android.mk
+1
-1
src/dnsmasq.h
src/dnsmasq.h
+5
-0
src/dnssec.c
src/dnssec.c
+1
-306
src/forward.c
src/forward.c
+1
-1
src/rrfilter.c
src/rrfilter.c
+339
-0
No files found.
Makefile
View file @
c2bcd1e1
...
...
@@ -73,7 +73,8 @@ objs = cache.o rfc1035.o util.o option.o forward.o network.o \
dnsmasq.o dhcp.o lease.o rfc2131.o netlink.o dbus.o bpf.o
\
helper.o tftp.o log.o conntrack.o dhcp6.o rfc3315.o
\
dhcp-common.o outpacket.o radv.o slaac.o auth.o ipset.o
\
domain.o dnssec.o blockdata.o tables.o loop.o inotify.o poll.o
domain.o dnssec.o blockdata.o tables.o loop.o inotify.o
\
poll.o rrfilter.o
hdrs
=
dnsmasq.h config.h dhcp-protocol.h dhcp6-protocol.h
\
dns-protocol.h radv-protocol.h ip6addr.h
...
...
bld/Android.mk
View file @
c2bcd1e1
...
...
@@ -10,7 +10,7 @@ LOCAL_SRC_FILES := bpf.c cache.c dbus.c dhcp.c dnsmasq.c \
dhcp6.c rfc3315.c dhcp-common.c outpacket.c
\
radv.c slaac.c auth.c ipset.c domain.c
\
dnssec.c dnssec-openssl.c blockdata.c tables.c
\
loop.c inotify.c poll.c
loop.c inotify.c poll.c
rrfilter.c
LOCAL_MODULE
:=
dnsmasq
...
...
src/dnsmasq.h
View file @
c2bcd1e1
...
...
@@ -1513,3 +1513,8 @@ int poll_check(int fd, short event);
void
poll_listen
(
int
fd
,
short
event
);
int
do_poll
(
int
timeout
);
/* rrfilter.c */
size_t
rrfilter
(
struct
dns_header
*
header
,
size_t
plen
,
int
mode
);
u16
*
rrfilter_desc
(
int
type
);
int
expand_workspace
(
unsigned
char
***
wkspc
,
int
*
szp
,
int
new
);
src/dnssec.c
View file @
c2bcd1e1
...
...
@@ -507,50 +507,6 @@ static int check_date_range(unsigned long date_start, unsigned long date_end)
&&
serial_compare_32
(
curtime
,
date_end
)
==
SERIAL_LT
;
}
static
u16
*
get_desc
(
int
type
)
{
/* List of RRtypes which include domains in the data.
0 -> domain
integer -> no of plain bytes
-1 -> end
zero is not a valid RRtype, so the final entry is returned for
anything which needs no mangling.
*/
static
u16
rr_desc
[]
=
{
T_NS
,
0
,
-
1
,
T_MD
,
0
,
-
1
,
T_MF
,
0
,
-
1
,
T_CNAME
,
0
,
-
1
,
T_SOA
,
0
,
0
,
-
1
,
T_MB
,
0
,
-
1
,
T_MG
,
0
,
-
1
,
T_MR
,
0
,
-
1
,
T_PTR
,
0
,
-
1
,
T_MINFO
,
0
,
0
,
-
1
,
T_MX
,
2
,
0
,
-
1
,
T_RP
,
0
,
0
,
-
1
,
T_AFSDB
,
2
,
0
,
-
1
,
T_RT
,
2
,
0
,
-
1
,
T_SIG
,
18
,
0
,
-
1
,
T_PX
,
2
,
0
,
0
,
-
1
,
T_NXT
,
0
,
-
1
,
T_KX
,
2
,
0
,
-
1
,
T_SRV
,
6
,
0
,
-
1
,
T_DNAME
,
0
,
-
1
,
0
,
-
1
/* wildcard/catchall */
};
u16
*
p
=
rr_desc
;
while
(
*
p
!=
type
&&
*
p
!=
0
)
while
(
*
p
++
!=
(
u16
)
-
1
);
return
p
+
1
;
}
/* Return bytes of canonicalised rdata, when the return value is zero, the remaining
data, pointed to by *p, should be used raw. */
static
int
get_rdata
(
struct
dns_header
*
header
,
size_t
plen
,
unsigned
char
*
end
,
char
*
buff
,
int
bufflen
,
...
...
@@ -594,34 +550,6 @@ static int get_rdata(struct dns_header *header, size_t plen, unsigned char *end,
}
}
static
int
expand_workspace
(
unsigned
char
***
wkspc
,
int
*
szp
,
int
new
)
{
unsigned
char
**
p
;
int
old
=
*
szp
;
if
(
old
>=
new
+
1
)
return
1
;
if
(
new
>=
100
)
return
0
;
new
+=
5
;
if
(
!
(
p
=
whine_malloc
(
new
*
sizeof
(
unsigned
char
**
))))
return
0
;
if
(
old
!=
0
&&
*
wkspc
)
{
memcpy
(
p
,
*
wkspc
,
old
*
sizeof
(
unsigned
char
**
));
free
(
*
wkspc
);
}
*
wkspc
=
p
;
*
szp
=
new
;
return
1
;
}
/* Bubble sort the RRset into the canonical order.
Note that the byte-streams from two RRs may get unsynced: consider
RRs which have two domain-names at the start and then other data.
...
...
@@ -849,7 +777,7 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
int
rdlen
,
j
,
name_labels
;
struct
crec
*
crecp
=
NULL
;
int
algo
,
labels
,
orig_ttl
,
key_tag
;
u16
*
rr_desc
=
get
_desc
(
type
);
u16
*
rr_desc
=
rrfilter
_desc
(
type
);
if
(
wildcard_out
)
*
wildcard_out
=
NULL
;
...
...
@@ -2266,239 +2194,6 @@ size_t dnssec_generate_query(struct dns_header *header, char *end, char *name, i
return
ret
;
}
/* Go through a domain name, find "pointers" and fix them up based on how many bytes
we've chopped out of the packet, or check they don't point into an elided part. */
static
int
check_name
(
unsigned
char
**
namep
,
struct
dns_header
*
header
,
size_t
plen
,
int
fixup
,
unsigned
char
**
rrs
,
int
rr_count
)
{
unsigned
char
*
ansp
=
*
namep
;
while
(
1
)
{
unsigned
int
label_type
;
if
(
!
CHECK_LEN
(
header
,
ansp
,
plen
,
1
))
return
0
;
label_type
=
(
*
ansp
)
&
0xc0
;
if
(
label_type
==
0xc0
)
{
/* pointer for compression. */
unsigned
int
offset
;
int
i
;
unsigned
char
*
p
;
if
(
!
CHECK_LEN
(
header
,
ansp
,
plen
,
2
))
return
0
;
offset
=
((
*
ansp
++
)
&
0x3f
)
<<
8
;
offset
|=
*
ansp
++
;
p
=
offset
+
(
unsigned
char
*
)
header
;
for
(
i
=
0
;
i
<
rr_count
;
i
++
)
if
(
p
<
rrs
[
i
])
break
;
else
if
(
i
&
1
)
offset
-=
rrs
[
i
]
-
rrs
[
i
-
1
];
/* does the pointer end up in an elided RR? */
if
(
i
&
1
)
return
0
;
/* No, scale the pointer */
if
(
fixup
)
{
ansp
-=
2
;
*
ansp
++
=
(
offset
>>
8
)
|
0xc0
;
*
ansp
++
=
offset
&
0xff
;
}
break
;
}
else
if
(
label_type
==
0x80
)
return
0
;
/* reserved */
else
if
(
label_type
==
0x40
)
{
/* Extended label type */
unsigned
int
count
;
if
(
!
CHECK_LEN
(
header
,
ansp
,
plen
,
2
))
return
0
;
if
(((
*
ansp
++
)
&
0x3f
)
!=
1
)
return
0
;
/* we only understand bitstrings */
count
=
*
(
ansp
++
);
/* Bits in bitstring */
if
(
count
==
0
)
/* count == 0 means 256 bits */
ansp
+=
32
;
else
ansp
+=
((
count
-
1
)
>>
3
)
+
1
;
}
else
{
/* label type == 0 Bottom six bits is length */
unsigned
int
len
=
(
*
ansp
++
)
&
0x3f
;
if
(
!
ADD_RDLEN
(
header
,
ansp
,
plen
,
len
))
return
0
;
if
(
len
==
0
)
break
;
/* zero length label marks the end. */
}
}
*
namep
=
ansp
;
return
1
;
}
/* Go through RRs and check or fixup the domain names contained within */
static
int
check_rrs
(
unsigned
char
*
p
,
struct
dns_header
*
header
,
size_t
plen
,
int
fixup
,
unsigned
char
**
rrs
,
int
rr_count
)
{
int
i
,
type
,
class
,
rdlen
;
unsigned
char
*
pp
;
for
(
i
=
0
;
i
<
ntohs
(
header
->
ancount
)
+
ntohs
(
header
->
nscount
)
+
ntohs
(
header
->
arcount
);
i
++
)
{
pp
=
p
;
if
(
!
(
p
=
skip_name
(
p
,
header
,
plen
,
10
)))
return
0
;
GETSHORT
(
type
,
p
);
GETSHORT
(
class
,
p
);
p
+=
4
;
/* TTL */
GETSHORT
(
rdlen
,
p
);
if
(
type
!=
T_NSEC
&&
type
!=
T_NSEC3
&&
type
!=
T_RRSIG
)
{
/* fixup name of RR */
if
(
!
check_name
(
&
pp
,
header
,
plen
,
fixup
,
rrs
,
rr_count
))
return
0
;
if
(
class
==
C_IN
)
{
u16
*
d
;
for
(
pp
=
p
,
d
=
get_desc
(
type
);
*
d
!=
(
u16
)
-
1
;
d
++
)
{
if
(
*
d
!=
0
)
pp
+=
*
d
;
else
if
(
!
check_name
(
&
pp
,
header
,
plen
,
fixup
,
rrs
,
rr_count
))
return
0
;
}
}
}
if
(
!
ADD_RDLEN
(
header
,
p
,
plen
,
rdlen
))
return
0
;
}
return
1
;
}
size_t
filter_rrsigs
(
struct
dns_header
*
header
,
size_t
plen
)
{
static
unsigned
char
**
rrs
;
static
int
rr_sz
=
0
;
unsigned
char
*
p
=
(
unsigned
char
*
)(
header
+
1
);
int
i
,
rdlen
,
qtype
,
qclass
,
rr_found
,
chop_an
,
chop_ns
,
chop_ar
;
if
(
ntohs
(
header
->
qdcount
)
!=
1
||
!
(
p
=
skip_name
(
p
,
header
,
plen
,
4
)))
return
plen
;
GETSHORT
(
qtype
,
p
);
GETSHORT
(
qclass
,
p
);
/* First pass, find pointers to start and end of all the records we wish to elide:
records added for DNSSEC, unless explicity queried for */
for
(
rr_found
=
0
,
chop_ns
=
0
,
chop_an
=
0
,
chop_ar
=
0
,
i
=
0
;
i
<
ntohs
(
header
->
ancount
)
+
ntohs
(
header
->
nscount
)
+
ntohs
(
header
->
arcount
);
i
++
)
{
unsigned
char
*
pstart
=
p
;
int
type
,
class
;
if
(
!
(
p
=
skip_name
(
p
,
header
,
plen
,
10
)))
return
plen
;
GETSHORT
(
type
,
p
);
GETSHORT
(
class
,
p
);
p
+=
4
;
/* TTL */
GETSHORT
(
rdlen
,
p
);
if
((
type
==
T_NSEC
||
type
==
T_NSEC3
||
type
==
T_RRSIG
)
&&
(
type
!=
qtype
||
class
!=
qclass
))
{
if
(
!
expand_workspace
(
&
rrs
,
&
rr_sz
,
rr_found
+
1
))
return
plen
;
rrs
[
rr_found
++
]
=
pstart
;
if
(
!
ADD_RDLEN
(
header
,
p
,
plen
,
rdlen
))
return
plen
;
rrs
[
rr_found
++
]
=
p
;
if
(
i
<
ntohs
(
header
->
ancount
))
chop_an
++
;
else
if
(
i
<
(
ntohs
(
header
->
nscount
)
+
ntohs
(
header
->
ancount
)))
chop_ns
++
;
else
chop_ar
++
;
}
else
if
(
!
ADD_RDLEN
(
header
,
p
,
plen
,
rdlen
))
return
plen
;
}
/* Nothing to do. */
if
(
rr_found
==
0
)
return
plen
;
/* Second pass, look for pointers in names in the records we're keeping and make sure they don't
point to records we're going to elide. This is theoretically possible, but unlikely. If
it happens, we give up and leave the answer unchanged. */
p
=
(
unsigned
char
*
)(
header
+
1
);
/* question first */
if
(
!
check_name
(
&
p
,
header
,
plen
,
0
,
rrs
,
rr_found
))
return
plen
;
p
+=
4
;
/* qclass, qtype */
/* Now answers and NS */
if
(
!
check_rrs
(
p
,
header
,
plen
,
0
,
rrs
,
rr_found
))
return
plen
;
/* Third pass, elide records */
for
(
p
=
rrs
[
0
],
i
=
1
;
i
<
rr_found
;
i
+=
2
)
{
unsigned
char
*
start
=
rrs
[
i
];
unsigned
char
*
end
=
(
i
!=
rr_found
-
1
)
?
rrs
[
i
+
1
]
:
((
unsigned
char
*
)(
header
+
1
))
+
plen
;
memmove
(
p
,
start
,
end
-
start
);
p
+=
end
-
start
;
}
plen
=
p
-
(
unsigned
char
*
)
header
;
header
->
ancount
=
htons
(
ntohs
(
header
->
ancount
)
-
chop_an
);
header
->
nscount
=
htons
(
ntohs
(
header
->
nscount
)
-
chop_ns
);
header
->
arcount
=
htons
(
ntohs
(
header
->
arcount
)
-
chop_ar
);
/* Fourth pass, fix up pointers in the remaining records */
p
=
(
unsigned
char
*
)(
header
+
1
);
check_name
(
&
p
,
header
,
plen
,
1
,
rrs
,
rr_found
);
p
+=
4
;
/* qclass, qtype */
check_rrs
(
p
,
header
,
plen
,
1
,
rrs
,
rr_found
);
return
plen
;
}
unsigned
char
*
hash_questions
(
struct
dns_header
*
header
,
size_t
plen
,
char
*
name
)
{
int
q
;
...
...
src/forward.c
View file @
c2bcd1e1
...
...
@@ -662,7 +662,7 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
/* If the requestor didn't set the DO bit, don't return DNSSEC info. */
if
(
!
do_bit
)
n
=
filter_rrsigs
(
header
,
n
);
n
=
rrfilter
(
header
,
n
,
1
);
#endif
/* do this after extract_addresses. Ensure NODATA reply and remove
...
...
src/rrfilter.c
0 → 100644
View file @
c2bcd1e1
/* dnsmasq is Copyright (c) 2000-2015 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
the Free Software Foundation; version 2 dated June, 1991, or
(at your option) version 3 dated 29 June, 2007.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* Code to safely remove RRs from an DNS answer */
#include "dnsmasq.h"
/* Go through a domain name, find "pointers" and fix them up based on how many bytes
we've chopped out of the packet, or check they don't point into an elided part. */
static
int
check_name
(
unsigned
char
**
namep
,
struct
dns_header
*
header
,
size_t
plen
,
int
fixup
,
unsigned
char
**
rrs
,
int
rr_count
)
{
unsigned
char
*
ansp
=
*
namep
;
while
(
1
)
{
unsigned
int
label_type
;
if
(
!
CHECK_LEN
(
header
,
ansp
,
plen
,
1
))
return
0
;
label_type
=
(
*
ansp
)
&
0xc0
;
if
(
label_type
==
0xc0
)
{
/* pointer for compression. */
unsigned
int
offset
;
int
i
;
unsigned
char
*
p
;
if
(
!
CHECK_LEN
(
header
,
ansp
,
plen
,
2
))
return
0
;
offset
=
((
*
ansp
++
)
&
0x3f
)
<<
8
;
offset
|=
*
ansp
++
;
p
=
offset
+
(
unsigned
char
*
)
header
;
for
(
i
=
0
;
i
<
rr_count
;
i
++
)
if
(
p
<
rrs
[
i
])
break
;
else
if
(
i
&
1
)
offset
-=
rrs
[
i
]
-
rrs
[
i
-
1
];
/* does the pointer end up in an elided RR? */
if
(
i
&
1
)
return
0
;
/* No, scale the pointer */
if
(
fixup
)
{
ansp
-=
2
;
*
ansp
++
=
(
offset
>>
8
)
|
0xc0
;
*
ansp
++
=
offset
&
0xff
;
}
break
;
}
else
if
(
label_type
==
0x80
)
return
0
;
/* reserved */
else
if
(
label_type
==
0x40
)
{
/* Extended label type */
unsigned
int
count
;
if
(
!
CHECK_LEN
(
header
,
ansp
,
plen
,
2
))
return
0
;
if
(((
*
ansp
++
)
&
0x3f
)
!=
1
)
return
0
;
/* we only understand bitstrings */
count
=
*
(
ansp
++
);
/* Bits in bitstring */
if
(
count
==
0
)
/* count == 0 means 256 bits */
ansp
+=
32
;
else
ansp
+=
((
count
-
1
)
>>
3
)
+
1
;
}
else
{
/* label type == 0 Bottom six bits is length */
unsigned
int
len
=
(
*
ansp
++
)
&
0x3f
;
if
(
!
ADD_RDLEN
(
header
,
ansp
,
plen
,
len
))
return
0
;
if
(
len
==
0
)
break
;
/* zero length label marks the end. */
}
}
*
namep
=
ansp
;
return
1
;
}
/* Go through RRs and check or fixup the domain names contained within */
static
int
check_rrs
(
unsigned
char
*
p
,
struct
dns_header
*
header
,
size_t
plen
,
int
fixup
,
unsigned
char
**
rrs
,
int
rr_count
)
{
int
i
,
j
,
type
,
class
,
rdlen
;
unsigned
char
*
pp
;
for
(
i
=
0
;
i
<
ntohs
(
header
->
ancount
)
+
ntohs
(
header
->
nscount
)
+
ntohs
(
header
->
arcount
);
i
++
)
{
pp
=
p
;
if
(
!
(
p
=
skip_name
(
p
,
header
,
plen
,
10
)))
return
0
;
GETSHORT
(
type
,
p
);
GETSHORT
(
class
,
p
);
p
+=
4
;
/* TTL */
GETSHORT
(
rdlen
,
p
);
/* If this RR is to be elided, don't fix up its contents */
for
(
j
=
0
;
j
<
rr_count
;
j
+=
2
)
if
(
rrs
[
j
]
==
pp
)
break
;
if
(
j
>=
rr_count
)
{
/* fixup name of RR */
if
(
!
check_name
(
&
pp
,
header
,
plen
,
fixup
,
rrs
,
rr_count
))
return
0
;
if
(
class
==
C_IN
)
{
u16
*
d
;
for
(
pp
=
p
,
d
=
rrfilter_desc
(
type
);
*
d
!=
(
u16
)
-
1
;
d
++
)
{
if
(
*
d
!=
0
)
pp
+=
*
d
;
else
if
(
!
check_name
(
&
pp
,
header
,
plen
,
fixup
,
rrs
,
rr_count
))
return
0
;
}
}
}
if
(
!
ADD_RDLEN
(
header
,
p
,
plen
,
rdlen
))
return
0
;
}
return
1
;
}
/* mode is 0 to remove EDNS0, 1 to filter DNSSEC RRs */
size_t
rrfilter
(
struct
dns_header
*
header
,
size_t
plen
,
int
mode
)
{
static
unsigned
char
**
rrs
;
static
int
rr_sz
=
0
;
unsigned
char
*
p
=
(
unsigned
char
*
)(
header
+
1
);
int
i
,
rdlen
,
qtype
,
qclass
,
rr_found
,
chop_an
,
chop_ns
,
chop_ar
;
if
(
ntohs
(
header
->
qdcount
)
!=
1
||
!
(
p
=
skip_name
(
p
,
header
,
plen
,
4
)))
return
plen
;
GETSHORT
(
qtype
,
p
);
GETSHORT
(
qclass
,
p
);
/* First pass, find pointers to start and end of all the records we wish to elide:
records added for DNSSEC, unless explicity queried for */
for
(
rr_found
=
0
,
chop_ns
=
0
,
chop_an
=
0
,
chop_ar
=
0
,
i
=
0
;
i
<
ntohs
(
header
->
ancount
)
+
ntohs
(
header
->
nscount
)
+
ntohs
(
header
->
arcount
);
i
++
)
{
unsigned
char
*
pstart
=
p
;
int
type
,
class
;
if
(
!
(
p
=
skip_name
(
p
,
header
,
plen
,
10
)))
return
plen
;
GETSHORT
(
type
,
p
);
GETSHORT
(
class
,
p
);
p
+=
4
;
/* TTL */
GETSHORT
(
rdlen
,
p
);
if
(
!
ADD_RDLEN
(
header
,
p
,
plen
,
rdlen
))
return
plen
;
/* Don't remove the answer. */
if
(
i
<
ntohs
(
header
->
ancount
)
&&
type
==
qtype
&&
class
==
qclass
)
continue
;
if
(
mode
==
0
)
/* EDNS */
{
/* EDNS mode, remove T_OPT from additional section only */
if
(
i
<
(
ntohs
(
header
->
nscount
)
+
ntohs
(
header
->
ancount
))
||
type
!=
T_OPT
)
continue
;
}
else
if
(
type
!=
T_NSEC
&&
type
!=
T_NSEC3
&&
type
!=
T_RRSIG
)
/* DNSSEC mode, remove SIGs and NSECs from all three sections. */
continue
;
if
(
!
expand_workspace
(
&
rrs
,
&
rr_sz
,
rr_found
+
1
))
return
plen
;
rrs
[
rr_found
++
]
=
pstart
;
rrs
[
rr_found
++
]
=
p
;
if
(
i
<
ntohs
(
header
->
ancount
))
chop_an
++
;
else
if
(
i
<
(
ntohs
(
header
->
nscount
)
+
ntohs
(
header
->
ancount
)))
chop_ns
++
;
else
chop_ar
++
;
}
/* Nothing to do. */
if
(
rr_found
==
0
)
return
plen
;
/* Second pass, look for pointers in names in the records we're keeping and make sure they don't
point to records we're going to elide. This is theoretically possible, but unlikely. If
it happens, we give up and leave the answer unchanged. */
p
=
(
unsigned
char
*
)(
header
+
1
);
/* question first */
if
(
!
check_name
(
&
p
,
header
,
plen
,
0
,
rrs
,
rr_found
))
return
plen
;
p
+=
4
;
/* qclass, qtype */
/* Now answers and NS */
if
(
!
check_rrs
(
p
,
header
,
plen
,
0
,
rrs
,
rr_found
))
return
plen
;
/* Third pass, elide records */
for
(
p
=
rrs
[
0
],
i
=
1
;
i
<
rr_found
;
i
+=
2
)
{
unsigned
char
*
start
=
rrs
[
i
];
unsigned
char
*
end
=
(
i
!=
rr_found
-
1
)
?
rrs
[
i
+
1
]
:
((
unsigned
char
*
)(
header
+
1
))
+
plen
;
memmove
(
p
,
start
,
end
-
start
);
p
+=
end
-
start
;
}
plen
=
p
-
(
unsigned
char
*
)
header
;
header
->
ancount
=
htons
(
ntohs
(
header
->
ancount
)
-
chop_an
);
header
->
nscount
=
htons
(
ntohs
(
header
->
nscount
)
-
chop_ns
);
header
->
arcount
=
htons
(
ntohs
(
header
->
arcount
)
-
chop_ar
);
/* Fourth pass, fix up pointers in the remaining records */
p
=
(
unsigned
char
*
)(
header
+
1
);
check_name
(
&
p
,
header
,
plen
,
1
,
rrs
,
rr_found
);
p
+=
4
;
/* qclass, qtype */
check_rrs
(
p
,
header
,
plen
,
1
,
rrs
,
rr_found
);
return
plen
;
}
/* This is used in the DNSSEC code too, hence it's exported */
u16
*
rrfilter_desc
(
int
type
)
{
/* List of RRtypes which include domains in the data.
0 -> domain
integer -> no of plain bytes
-1 -> end
zero is not a valid RRtype, so the final entry is returned for
anything which needs no mangling.
*/
static
u16
rr_desc
[]
=
{
T_NS
,
0
,
-
1
,
T_MD
,
0
,
-
1
,
T_MF
,
0
,
-
1
,
T_CNAME
,
0
,
-
1
,
T_SOA
,
0
,
0
,
-
1
,
T_MB
,
0
,
-
1
,
T_MG
,
0
,
-
1
,
T_MR
,
0
,
-
1
,
T_PTR
,
0
,
-
1
,
T_MINFO
,
0
,
0
,
-
1
,
T_MX
,
2
,
0
,
-
1
,
T_RP
,
0
,
0
,
-
1
,
T_AFSDB
,
2
,
0
,
-
1
,
T_RT
,
2
,
0
,
-
1
,
T_SIG
,
18
,
0
,
-
1
,
T_PX
,
2
,
0
,
0
,
-
1
,
T_NXT
,
0
,
-
1
,
T_KX
,
2
,
0
,
-
1
,
T_SRV
,
6
,
0
,
-
1
,
T_DNAME
,
0
,
-
1
,
0
,
-
1
/* wildcard/catchall */
};
u16
*
p
=
rr_desc
;
while
(
*
p
!=
type
&&
*
p
!=
0
)
while
(
*
p
++
!=
(
u16
)
-
1
);
return
p
+
1
;
}
int
expand_workspace
(
unsigned
char
***
wkspc
,
int
*
szp
,
int
new
)
{
unsigned
char
**
p
;
int
old
=
*
szp
;
if
(
old
>=
new
+
1
)
return
1
;
if
(
new
>=
100
)
return
0
;
new
+=
5
;
if
(
!
(
p
=
whine_malloc
(
new
*
sizeof
(
unsigned
char
**
))))
return
0
;
if
(
old
!=
0
&&
*
wkspc
)
{
memcpy
(
p
,
*
wkspc
,
old
*
sizeof
(
unsigned
char
**
));
free
(
*
wkspc
);
}
*
wkspc
=
p
;
*
szp
=
new
;
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