diff options
author | Francois-Xavier Le Bail <devel.fx.lebail@orange.fr> | 2020-06-10 12:13:53 +0200 |
---|---|---|
committer | Francois-Xavier Le Bail <devel.fx.lebail@orange.fr> | 2020-06-10 15:22:00 +0200 |
commit | 63216357de0aa557888329c614946626e37d7c6b (patch) | |
tree | c0375c5bd432b7ddba713ee70f180a27917457a0 | |
parent | 403ae5774ba79909da85efebec754a2c82b24053 (diff) | |
download | tcpdump-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.h | 2 | ||||
-rw-r--r-- | print-domain.c | 30 | ||||
-rw-r--r-- | print-tcp.c | 20 | ||||
-rw-r--r-- | print-udp.c | 9 |
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)) |