Came across an error when messing with the dns module. For some reason, it seems to trip on certain packets and throw a struct.error.
struct.error: unpack requires a bytes object of length 442
For the full context, here is the code I'm running, or trying to run. It works fine on other pcap files.
(sorry for the lack of comments, this was just a quick and dirty script)
import pcapy
from pypacker.pypacker import dns_name_decode
from pypacker.layer12 import ethernet
from pypacker.layer567 import dns
import os
from socket import inet_ntop, AF_INET, AF_INET6
# https://wiki.wireshark.org/SampleCaptures#General_.2F_Unsorted
#PCAPFILE = os.path.join(os.environ['HOME'], "pcap", "SkypeIRC.cap")
# https://wiki.wireshark.org/SampleCaptures#Server_Message_Block_.28SMB.29.2FCommon_Internet_File_System_.28CIFS.29
PCAPFILE = os.path.join(os.environ['HOME'], "pcap", "smbtorture.cap")
BPF = "port 53"
capture = pcapy.open_offline(PCAPFILE)
capture.setfilter(BPF)
while True:
try:
header, packet = capture.next()
except pcapy.PcapError:
break
pkt = ethernet.Ethernet(packet)
dnsP = pkt.highest_layer
if not isinstance(dnsP, dns.DNS):
continue
print("{0:016b}".format(dnsP.flags))
qr_flag = dnsP.flags >> 15
if qr_flag == dns.DNS_Q:
for query in dnsP.queries:
print(dnsP.id, "query", query.name_s)
else: #if qr_flag == dns.DNS_A:
if not dnsP.answers:
print(dnsP.id, "response", None)
continue
for answer in dnsP.answers:
if answer.type == dns.DNS_A:
print(dnsP.id, "response", "A", inet_ntop(AF_INET, answer.address))
elif answer.type == dns.DNS_AAAA:
print(dnsP.id, "response", "AAAA", inet_ntop(AF_INET6, answer.address))
elif answer.type == dns.DNS_CNAME:
# decoding name doesn't always work if it has \xc0 pointers
print(dnsP.id, "response", "CNAME", repr(dns_name_decode(answer.address)))
elif answer.type == dns.DNS_PTR:
print(dnsP.id, "response", "PTR", repr(dns_name_decode(answer.address)))
else:
print(dnsP.id, "response", "OTHER", repr(answer.address))
The full output, including the exception traceback:
> python3 ~/Python/quick_dns_test.py
0000000100000000
22185 query time.windows.com.
1000000110000000
22185 response None
0000000100000000
53928 query time.windows.com.localdomain.
1000000110000011
53928 response None
0000000100000000
427 query time.windows.com.
Traceback (most recent call last):
File "/home/user/Python/quick_dns_test.py", line 30, in <module>
print("{0:016b}".format(dnsP.flags))
File "/home/user/python3/lib/python3.4/site-packages/pypacker/pypacker.py", line 135, in getfield_simple
obj._unpack()
File "/home/user/python3/lib/python3.4/site-packages/pypacker/pypacker.py", line 776, in _unpack
header_unpacked = self._header_format.unpack(self._header_cached)
struct.error: unpack requires a bytes object of length 442
And for even more completion, here is the tcpdump output, suggesting to me that at least the packets aren't completely malformed:
> tcpdump -nnr ~/pcap/smbtorture.cap port 53
reading from file /home/user/pcap/smbtorture.cap, link-type EN10MB (Ethernet)
23:38:26.418664 IP 192.168.114.129.49157 > 192.168.114.1.53: 22185+ AAAA? time.windows.com. (34)
23:38:27.261990 IP 192.168.114.1.53 > 192.168.114.129.49157: 22185 0/1/0 (102)
23:38:27.268868 IP 192.168.114.129.49157 > 192.168.114.1.53: 53928+ AAAA? time.windows.com.localdomain. (46)
23:38:27.471756 IP 192.168.114.1.53 > 192.168.114.129.49157: 53928 NXDomain 0/1/0 (121)
23:38:27.563782 IP 192.168.114.129.49157 > 192.168.114.1.53: 427+ A? time.windows.com. (34)
23:38:27.743738 IP 192.168.114.1.53 > 192.168.114.129.49157: 427 1/5/5 A 207.46.130.100 (228)
23:38:28.844217 IP 192.168.114.129.49157 > 192.168.114.1.53: 55979+ A? teredo.ipv6.microsoft.com. (43)
23:38:28.844590 IP 192.168.114.1.53 > 192.168.114.129.49157: 55979 4/5/5 A 64.4.25.86, A 64.4.25.80, A 64.4.25.82, A 64.4.25.84 (285)
23:38:32.810654 IP 192.168.114.129.49157 > 192.168.114.1.53: 37291+ A? isatap.localdomain. (36)
23:38:32.948270 IP 192.168.114.1.53 > 192.168.114.129.49157: 37291 NXDomain 0/1/0 (111)
23:38:32.976324 IP 192.168.114.129.49157 > 192.168.114.1.53: 35498+ A? isatap.localdomain. (36)
23:38:32.976572 IP 192.168.114.1.53 > 192.168.114.129.49157: 35498 NXDomain 0/1/0 (111)
23:38:39.029400 IP 192.168.114.129.49157 > 192.168.114.1.53: 44972+ A? teredo.ipv6.microsoft.com. (43)
23:38:39.080072 IP 192.168.114.1.53 > 192.168.114.129.49157: 44972 4/5/5 A 64.4.25.84, A 64.4.25.86, A 64.4.25.80, A 64.4.25.82 (285)
23:38:39.083152 IP 192.168.114.129.49157 > 192.168.114.1.53: 11695+ A? isatap.localdomain. (36)
23:38:39.120008 IP 192.168.114.1.53 > 192.168.114.129.49157: 11695 NXDomain 0/1/0 (111)
23:38:39.122330 IP 192.168.114.129.49157 > 192.168.114.1.53: 21422+ A? isatap.localdomain. (36)
23:38:39.155815 IP 192.168.114.1.53 > 192.168.114.129.49157: 21422 NXDomain 0/1/0 (111)
23:38:39.703137 IP 192.168.114.129.49178 > 192.168.114.1.53: 63392+ A? time.windows.com. (34)
23:38:39.703434 IP 192.168.114.1.53 > 192.168.114.129.49178: 63392 1/5/5 A 207.46.130.100 (228)
23:38:39.711962 IP 192.168.114.129.49157 > 192.168.114.1.53: 19873+ A? isatap.localdomain. (36)
23:38:39.712165 IP 192.168.114.1.53 > 192.168.114.129.49157: 19873 NXDomain 0/1/0 (111)
Came across an error when messing with the dns module. For some reason, it seems to trip on certain packets and throw a struct.error.
struct.error: unpack requires a bytes object of length 442
I'm running it on the smbtorture.cap file here
For the full context, here is the code I'm running, or trying to run. It works fine on other pcap files. (sorry for the lack of comments, this was just a quick and dirty script)
The full output, including the exception traceback:
And for even more completion, here is the tcpdump output, suggesting to me that at least the packets aren't completely malformed: