我在使用 tcpdump 时遇到了麻烦。我只想捕获包含权威响应的 DNS 数据包,其中单个 RR 为 0.0.0.0。例如,我只想捕获如下数据包:
root@OpenWrt:~# tcpdump -XKvvv 'udp src port 53'
tcpdump: listening on br-lan, link-type EN10MB (Ethernet), capture size 262144 bytes
22:40:19.929483 IP (tos 0x0, ttl 64, id 60020, offset 0, flags [DF], proto UDP (17), length 74)
OpenWrt.lan.53 > 192.168.0.231.12244: 730* q: A? test.2o7.net. 1/0/0 test.2o7.net. [0s] A 0.0.0.0 (46)
0x0000: 4500 004a ea74 4000 4011 cdf5 c0a8 0001 E..J.t@.@.......
0x0010: c0a8 00e7 0035 2fd4 0036 8280 02da 8580 .....5/..6......
0x0020: 0001 0001 0000 0000 0474 6573 7403 326f .........test.2o
0x0030: 3703 6e65 7400 0001 0001 c00c 0001 0001 7.net...........
0x0040: 0000 0000 0004 0000 0000 ..........
^C
1 packet captured
1 packet received by filter
0 packets dropped by kernel
UDP 标头始终为 8 个字节,因此 UDP 数据的开头应在过滤器语法中的 udp[7] 处。DNS 数据包以 2 个字节的 ID 开头,然后是 2 个字节的标志字,因此标志字应从偏移量 9 开始,AA 位是标志的位 5。但是当我使用过滤器测试它时,udp port 53 and (udp[9:2]&0xfbff) != 0
它不会仅打印权威答案。这是发生的事情:
root@OpenWrt:~# tcpdump -XKvvv 'udp src port 53 and (udp[9:2]&0xfbff) != 0'
tcpdump: listening on br-lan, link-type EN10MB (Ethernet), capture size 262144 bytes
22:42:42.233028 IP (tos 0x0, ttl 64, id 16920, offset 0, flags [DF], proto UDP (17), length 76)
OpenWrt.lan.53 > 192.168.0.231.50259: 55688 q: A? duckduckgo.com. 1/0/0 duckduckgo.com. [1m26s] A 52.250.42.157 (48)
0x0000: 4500 004c 4218 4000 4011 7650 c0a8 0001 E..LB.@[email protected]....
0x0010: c0a8 00e7 0035 c453 0038 8282 d988 8180 .....5.S.8......
0x0020: 0001 0001 0000 0000 0a64 7563 6b64 7563 .........duckduc
0x0030: 6b67 6f03 636f 6d00 0001 0001 c00c 0001 kgo.com.........
0x0040: 0001 0000 0056 0004 34fa 2a9d .....V..4.*.
^C
1 packet captured
1 packet received by filter
0 packets dropped by kernel
但这不是 AA。有什么问题吗?
答案1
我udp src port 53 and (udp[10:2]&0x840f) = 0x8400 and udp[14:2] = 1
现在正在使用,它有效。它仅列出 QR 设置为 1(响应)、AA 设置为 1(权威)、rCode 设置为 0(无错误)和权限 RR 设置为 1(一个权限 RR)的 DNS 响应。我还想根据 RR 本身进行过滤,但它的偏移量是可变的,我认为 pcap 过滤器语法不够强大,无法做到这一点(但我可能是错的)。所以这对我来说足够了。