I was trying to parse some dns requests/responses, edit some fields, and then write out the new packets when I noticed that for some inputs the newly written packets were messed up. I took out all my changes to the packet and still saw the same issue
Then when dpkt is packing it into bytes it calls pack_rdata which will execute this
def pack_rdata(self, off, label_ptrs):
# XXX - yeah, this sux
if self.rdata:
return self.rdata
But this will not update label_ptrs so when the next RR object references youtube-ui.l.google.com it will pack the url again and create a ptr offset to the newly packed url and store that in label_ptrs.
I see that when I comment out return self.rdata it instead executes pack_name and correctly stores the label_ptrs and the newly written pcap looks the same as the source
A workaround is to just set rr.rdata = None for all the packets and pack_rdata figures it out.
I was trying to parse some dns requests/responses, edit some fields, and then write out the new packets when I noticed that for some inputs the newly written packets were messed up. I took out all my changes to the packet and still saw the same issue
tcpdump -vv -n -r rewrite.pcap .... bad udp cksum 0x6d58 -> 0xbb39!] 11938 q: A? www.youtube.com. 7/13/6 www.youtube.com. CNAME youtube-ui.l.google.com., youtube-ui.l.google.com. A 172.217.6.46, youtube-ui.l.google.com. A 172.217.6.78, youtube-ui.l.google.com. A 172.217.164.110, youtube-ui.l.google.com. A 216.58.195.78, youtube-ui.l.google.com. A 172.217.0.46, youtube-ui.l.google.com. A 172.217.5.110 ns: . NS f.root-servers.net., . NS m.^@^DM-,M-Y^En^@^@^B^@^A^@^@M-&M-^M^@^T^Af^Lroot-servers^Cnet^@^@^@^B^@^A^@^@.M-^M^@^D^AmM-@M-0^@^@^B^@^A^ ....
I think the issue occurs when the first RR has type DNS_CNAME and has the url in bytes in the rdata field
RR(name='www.youtube.com', type=5, ttl=43919, rlen=22, rdata=b'\nyoutube-ui\x01l\x06google\xc0\x18', cname='youtube-ui.l.google.com')
Then when dpkt is packing it into bytes it calls pack_rdata which will execute this
But this will not update label_ptrs so when the next RR object references youtube-ui.l.google.com it will pack the url again and create a ptr offset to the newly packed url and store that in label_ptrs.
b'... \xc0\x0c\x00\x05\x00\x01\x00\x00\xab\x8f\x00\x16\nyoutube-ui\x01l\x06google\xc0\x18\nyoutube-ui\x01l\x06google\xc0\x18\ ...'
I see that when I comment out
return self.rdata
it instead executespack_name
and correctly stores the label_ptrs and the newly written pcap looks the same as the sourceA workaround is to just set
rr.rdata = None
for all the packets andpack_rdata
figures it out.