Я пытаюсь отобразить только раздел данных пакета udp, используя tcpdump. Другими словами, можно ли отфильтровать секцию заголовка пакета udp?
Команда ниже
sudo tcpdump -Aq -i lo udp port 1234
возвращает:
E..".J@.@.U~.........v.....!HELLO
Как можно Я отменяю часть E..".J@.@.U~.........v.....!
?
Вот несколько путей. В примерах ниже я использую echo
для печати определенной строки из ответа, но можно заменить echo 'blah blah' | command
с sudo tcpdump -Aq -i lo udp port 1234 | command
.
awk
$ echo 'E..".J@.@.U~.........v.....!HELLO' | awk -F'!' '{print $NF}'
HELLO
awk
разделяет входные строки на поля путем разделения на символе, данном как -F
. В этом случае, !
. $NF
специальная переменная, которая означает последнее поле. Так, команда выше, берет !
как разделитель полей и печать последнее поле, т.е. независимо от того, что прибывает после последнего !
.
grep
echo 'E..".J@.@.U~.........v.....!HELLO' | grep -oP '!\K.+?$'
-o
причины флага grep
распечатать только подобранную часть строки и -P
активирует Perl Совместимые Регулярные выражения, которые дают нам \K
. regex ищет a !
и самая короткая возможная строка (.+?
, ?
заставляет его искать самое короткое) в конец строки ($
). \K
средства: отбрасывание, что было подобрано перед \K
. Результат состоит в том что !
(который является перед \K
) отбрасывается и только HELLO
печатается.
cut
echo 'E..".J@.@.U~.........v.....!HELLO' | cut -d'!' -f2
cut
утилита, которая, ну, в общем, сокращает строки. В этом случае я устанавливаю разделитель полей на !
и печать 2-го поля, HELLO
.
perl
echo 'E..".J@.@.U~.........v.....!HELLO' | perl -pe 's/.+\!//'
-p
означает, "печатают каждую строку после применения сценария, данного с -e
к нему". Сам сценарий использует оператор замены (s/pattern/replacement/
) заменять все до последнего !
(здесь, с тех пор существует нет ?
, .+
будет соответствовать самой длинной строке) ни с чем, эффективно уезжая только HELLO
.
Попробуйте это,
$ echo 'E..".J@.@.U~.........v.....!HELLO' | grep -oP '!+.*' | sed 's/.\(.*\)/\1/g'
HELLO
На основе структуры udp пакета необходимо сократить tcpdump объем производства от определенного местоположения, вместо того, чтобы искать определенный символ, который мог также измениться:
sudo tcpdump -Aq -i lo udp port 1234 | cut -c29-
, Например, отправляя udp пакет с netcat:
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@.@..U....
0x0010: 7f00 0001 b07c 04d2 000f fe22 4845 4c4c .....|....."HELL
0x0020: 4f53 0a OS.
символ перед строкой "HELLOS" изменяется, потому что 2 байта, предшествующие разделу даты, связаны с контрольной суммой UDP, и затем изменяются согласно отправленному пакету.
whireshark снимок экрана:
IP:
пакет UDP:
и 2-байтовая контрольная сумма: