summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancois-Xavier Le Bail <devel.fx.lebail@orange.fr>2020-06-10 12:13:53 +0200
committerFrancois-Xavier Le Bail <devel.fx.lebail@orange.fr>2020-06-10 15:22:00 +0200
commit63216357de0aa557888329c614946626e37d7c6b (patch)
treec0375c5bd432b7ddba713ee70f180a27917457a0
parent403ae5774ba79909da85efebec754a2c82b24053 (diff)
downloadtcpdump-63216357de0aa557888329c614946626e37d7c6b.tar.gz
DNS: Do the 'over TCP' processing in the printer
Add the parameter 'over_tcp'. Move the shift by 2 bytes from the TCP printer to the DNS printer. Move adding a prepended space from the TCP printer to the DNS printer. Add a length check. Add some comments about 'over_tcp' and 'is_mdns' call values.
-rw-r--r--netdissect.h2
-rw-r--r--print-domain.c30
-rw-r--r--print-tcp.c20
-rw-r--r--print-udp.c9
4 files changed, 41 insertions, 20 deletions
diff --git a/netdissect.h b/netdissect.h
index 3123bc38..86605671 100644
--- a/netdissect.h
+++ b/netdissect.h
@@ -647,7 +647,7 @@ extern void nfsreply_print(netdissect_options *, const u_char *, u_int, const u_
extern void nfsreply_noaddr_print(netdissect_options *, const u_char *, u_int, const u_char *);
extern void nfsreq_noaddr_print(netdissect_options *, const u_char *, u_int, const u_char *);
extern const u_char *fqdn_print(netdissect_options *, const u_char *, const u_char *);
-extern void domain_print(netdissect_options *, const u_char *, u_int, int);
+extern void domain_print(netdissect_options *, const u_char *, u_int, int, int);
extern void nsh_print(netdissect_options *, const u_char *, u_int);
extern void ntp_print(netdissect_options *, const u_char *, u_int);
extern void oam_print(netdissect_options *, const u_char *, u_int, u_int);
diff --git a/print-domain.c b/print-domain.c
index 28c7f2b9..1486b5d1 100644
--- a/print-domain.c
+++ b/print-domain.c
@@ -842,7 +842,7 @@ ns_rprint(netdissect_options *ndo,
void
domain_print(netdissect_options *ndo,
- const u_char *bp, u_int length, int is_mdns)
+ const u_char *bp, u_int length, int over_tcp, int is_mdns)
{
const dns_header_t *np;
uint16_t flags, rcode, rdlen, type;
@@ -852,6 +852,34 @@ domain_print(netdissect_options *ndo,
uint16_t b2;
ndo->ndo_protocol = "domain";
+
+ if (over_tcp) {
+ /*
+ * The message is prefixed with a two byte length field
+ * which gives the message length, excluding the two byte
+ * length field. (RFC 1035 - 4.2.2. TCP usage)
+ */
+ if (length < 2) {
+ ND_PRINT(" [DNS over TCP: length %u < 2]", length);
+ nd_print_invalid(ndo);
+ return;
+ } else {
+ length -= 2; /* excluding the two byte length field */
+ if (GET_BE_U_2(bp) != length) {
+ ND_PRINT(" [prefix length(%u) != length(%u)]",
+ GET_BE_U_2(bp), length);
+ nd_print_invalid(ndo);
+ return;
+ } else {
+ bp += 2;
+ /* in over TCP case, we need to prepend a space
+ * (not needed in over UDP case)
+ */
+ ND_PRINT(" ");
+ }
+ }
+ }
+
np = (const dns_header_t *)bp;
if(length < sizeof(*np)) {
diff --git a/print-tcp.c b/print-tcp.c
index a08053b6..88870c65 100644
--- a/print-tcp.c
+++ b/print-tcp.c
@@ -703,8 +703,8 @@ tcp_print(netdissect_options *ndo,
resp_print(ndo, bp, length);
break;
case PT_DOMAIN:
- ND_PRINT(" ");
- domain_print(ndo, bp + 2, length - 2, 0);
+ /* over_tcp: TRUE, is_mdns: FALSE */
+ domain_print(ndo, bp, length, TRUE, FALSE);
break;
}
return;
@@ -746,19 +746,9 @@ tcp_print(netdissect_options *ndo,
} else if (IS_SRC_OR_DST_PORT(RTSP_PORT) || IS_SRC_OR_DST_PORT(RTSP_PORT_ALT)) {
ND_PRINT(": ");
rtsp_print(ndo, bp, length);
- } else if (length > 2 &&
- (IS_SRC_OR_DST_PORT(NAMESERVER_PORT))) {
- /* domain_print() assumes it does not have to prepend a space before its
- * own output to separate it from the output of the calling function. This
- * works well with udp_print(), but requires a small prop here.
- */
- ND_PRINT(" ");
-
- /*
- * TCP DNS query has 2byte length at the head.
- * XXX packet could be unaligned, it can go strange
- */
- domain_print(ndo, bp + 2, length - 2, 0);
+ } else if (IS_SRC_OR_DST_PORT(NAMESERVER_PORT)) {
+ /* over_tcp: TRUE, is_mdns: FALSE */
+ domain_print(ndo, bp, length, TRUE, FALSE);
} else if (IS_SRC_OR_DST_PORT(MSDP_PORT)) {
msdp_print(ndo, bp, length);
} else if (IS_SRC_OR_DST_PORT(RPKI_RTR_PORT)) {
diff --git a/print-udp.c b/print-udp.c
index ee93a874..75c4fb91 100644
--- a/print-udp.c
+++ b/print-udp.c
@@ -530,7 +530,8 @@ udp_print(netdissect_options *ndo, const u_char *bp, u_int length,
break;
case PT_DOMAIN:
udpipaddr_print(ndo, ip, sport, dport);
- domain_print(ndo, cp, length, 0);
+ /* over_tcp: FALSE, is_mdns: FALSE */
+ domain_print(ndo, cp, length, FALSE, FALSE);
break;
}
return;
@@ -610,9 +611,11 @@ udp_print(netdissect_options *ndo, const u_char *bp, u_int length,
if (!ndo->ndo_qflag) {
if (IS_SRC_OR_DST_PORT(NAMESERVER_PORT))
- domain_print(ndo, cp, length, 0);
+ /* over_tcp: FALSE, is_mdns: FALSE */
+ domain_print(ndo, cp, length, FALSE, FALSE);
else if (IS_SRC_OR_DST_PORT(MULTICASTDNS_PORT))
- domain_print(ndo, cp, length, 1);
+ /* over_tcp: FALSE, is_mdns: TRUE */
+ domain_print(ndo, cp, length, FALSE, TRUE);
else if (IS_SRC_OR_DST_PORT(TIMED_PORT))
timed_print(ndo, (const u_char *)cp);
else if (IS_SRC_OR_DST_PORT(TFTP_PORT))