]> The Tcpdump Group git mirrors - tcpdump/commitdiff
DNS: Do the 'over TCP' processing in the printer
authorFrancois-Xavier Le Bail <[email protected]>
Wed, 10 Jun 2020 10:13:53 +0000 (12:13 +0200)
committerFrancois-Xavier Le Bail <[email protected]>
Wed, 10 Jun 2020 13:22:00 +0000 (15:22 +0200)
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.

netdissect.h
print-domain.c
print-tcp.c
print-udp.c

index 3123bc389ee1946233adde97db9b919d54872fbb..866056711b3b0f33dc4df9c511e6591da467ac68 100644 (file)
@@ -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);
index 28c7f2b9a549647012e4a1b751af6c3bc12e97f1..1486b5d121333abe8c26cde7856e4312d1e0f513 100644 (file)
@@ -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)) {
index a08053b6db67be0e7bc770db4120e776d8ef015b..88870c6518be5bf0005de7d8eb7a43511f66ddf5 100644 (file)
@@ -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)) {
index ee93a8741135c8a8a8a3c955ed779696c0a240d0..75c4fb911c78b47d22434cdbce0679e00769f1a7 100644 (file)
@@ -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))