/* print the bit string as a hex string */
ND_PRINT("\\[x");
for (bitp = cp + 1, b = bitlen; bitp < lim && b > 7; b -= 8, bitp++) {
- ND_TCHECK_1(bitp);
ND_PRINT("%02x", GET_U_1(bitp));
}
if (b > 4) {
- ND_TCHECK_1(bitp);
tc = GET_U_1(bitp);
bitp++;
ND_PRINT("%02x", tc & (0xff << (8 - b)));
} else if (b > 0) {
- ND_TCHECK_1(bitp);
tc = GET_U_1(bitp);
bitp++;
ND_PRINT("%1x", ((tc >> 4) & 0x0f) & (0x0f << (4 - b)));
}
ND_PRINT("/%u]", bitlen);
return lim;
-trunc:
- ND_PRINT(".../%u]", bitlen);
- return NULL;
}
static int
return (cp + data_len);
trunc:
- nd_print_invalid(ndo);
return (NULL);
}
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;
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)) {
if (cp + 1 > ndo->ndo_snapend)
goto print;
if (type == T_OPT) {
- rcode |= (*cp << 4);
+ rcode |= (GET_U_1(cp) << 4);
goto print;
}
cp += 4;