我尝试使用 tcpdump 仅显示 udp 数据包的数据部分。换句话说,有没有办法过滤 udp 数据包的报头部分?
以下命令
sudo tcpdump -Aq -i lo udp port 1234
返回:
E..".J@[email protected]~.........v.....!HELLO
我怎样才能丢弃该部分?E..".J@[email protected]~.........v.....!
答案1
这里有几个方法。在下面的例子中,我使用echo
打印答案中的特定字符串,但你可以将 替换echo 'blah blah' | command
为sudo tcpdump -Aq -i lo udp port 1234 | command
。
awk
$ echo 'E..".J@[email protected]~.........v.....!HELLO' | awk -F'!' '{print $NF}' HELLO
awk
根据给定的字符将输入行拆分为字段-F
。在这种情况下,!
.$NF
是一个特殊变量,表示最后一个字段。因此,上面的命令将其作为字段分隔符并打印最后一个字段,即最后一个.!
之后的内容。!
grep
echo 'E..".J@[email protected]~.........v.....!HELLO' | grep -oP '!\K.+?$'
标志
-o
导致grep
仅打印行的匹配部分,并-P
激活 Perl 兼容正则表达式,从而为我们提供\K
。正则表达式正在寻找!
和最短的可能字符串(.+?
, 使其?
寻找最短的)直到行尾($
)。\K
意思是:丢弃 之前匹配的内容\K
。结果是!
( 之前的\K
)被丢弃,只HELLO
打印 。cut
echo 'E..".J@[email protected]~.........v.....!HELLO' | cut -d'!' -f2
cut
是一个可以截断行的实用程序。在本例中,我将字段分隔符设置为!
并打印第二个字段,即HELLO
。perl
echo 'E..".J@[email protected]~.........v.....!HELLO' | perl -pe 's/.+\!//'
意思
-p
是“将 和 所给的脚本应用到每一行后打印出来-e
”。脚本本身使用替换运算符 (s/pattern/replacement/
) 将所有内容替换为空,直到最后一行!
(这里,由于没有?
,.+
会匹配最长的字符串),实际上只留下HELLO
。
答案2
尝试这个,
$ echo 'E..".J@[email protected]~.........v.....!HELLO' | grep -oP '!+.*' | sed 's/.\(.*\)/\1/g'
HELLO
答案3
根据 udp 数据包的结构,您应该从特定位置剪切 tcpdump 输出,而不是寻找某个字符,这也会改变:
sudo tcpdump -Aq -i lo udp port 1234 | cut -c29-
例如用netcat发送udp数据包:
echo "HELLO" | netcat -4u -w1 localhost 1234
这是我的 tcpdump 输出(十六进制和 ascii):
sudo tcpdump -X -i lo udp port 1234
12:35:10.672236 IP localhost.36898 > localhost.1234: UDP, length 6
0x0000: 4500 0022 ab0e 4000 4011 91ba 7f00 0001 E.."..@.@.......
0x0010: 7f00 0001 9022 04d2 000e fe21 4845 4c4c .....".....!HELL
0x0020: 4f0a O.
但是,发送另一个字符串,例如:
echo "HELLOS" | netcat -4u -w1 localhost 1234
这是输出:
12:50:01.987211 IP localhost.45180 > localhost.1234: UDP, length 7
0x0000: 4500 0023 3873 4000 4011 0455 7f00 0001 E..#8s@[email protected]....
0x0010: 7f00 0001 b07c 04d2 000f fe22 4845 4c4c .....|....."HELL
0x0020: 4f53 0a OS.
字符串“HELLOS”之前的字符被改变了,因为日期部分前面的2个字节与udp校验和有关,然后根据发送的数据包而变化。
whireshark 截图:
IP地址:
UDP数据包:
以及2字节校验和: