50 lines
1.6 KiB
Python
Executable File
50 lines
1.6 KiB
Python
Executable File
#!/usr/bin/python
|
|
import argparse
|
|
import sys
|
|
|
|
import dns.exception
|
|
import dns.message
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(
|
|
description="Read sequence of DNS wire formats prefixed with 2-byte "
|
|
"length field - like from TCP socket - and print the messages. This "
|
|
"format is used e.g. by dnsperf -B option and dnsgen."
|
|
)
|
|
parser.add_argument("infile")
|
|
args = parser.parse_args()
|
|
ok_msgs = 0
|
|
bad_msgs = 0
|
|
|
|
with open(args.infile, "rb") as infile:
|
|
while True:
|
|
offset = infile.tell()
|
|
len_wire = infile.read(2)
|
|
if len(len_wire) == 0: # end of file - expected
|
|
break
|
|
if len(len_wire) == 1:
|
|
raise ValueError("incomplete length preamble, offset", offset)
|
|
len_msg = int.from_bytes(len_wire, byteorder="big", signed=False)
|
|
print(f"; msg offset 0x{offset + 2:x}, length {len_msg} bytes")
|
|
msg_wire = infile.read(len_msg)
|
|
if len(msg_wire) != len_msg:
|
|
raise ValueError(
|
|
f"incomplete message: expected {len_msg} != got {len(msg_wire)}, "
|
|
f"length field offset 0x{offset:x}",
|
|
)
|
|
try:
|
|
msg = dns.message.from_wire(msg_wire)
|
|
ok_msgs += 1
|
|
print(msg)
|
|
except dns.exception.DNSException as ex:
|
|
print(f"; invalid message, skipping: {ex}")
|
|
bad_msgs += 1
|
|
print(f"; read {ok_msgs} valid and {bad_msgs} invalid messages")
|
|
if bad_msgs:
|
|
sys.exit(1)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|