Отображать только раздел данных пакета
Я пытаюсь отобразить только раздел данных пакета udp, используя tcpdump. Другими словами, есть ли способ отфильтровать заголовочный раздел пакета udp?
Команда ниже
sudo tcpdump -Aq -i lo udp port 1234
возвращает:
E..".J@.@.U~.........v.....!HELLO
Как я могу отказаться от E..".J@.@.U~.........v.....!
часть?
3 ответа
Вот несколько способов. В приведенных ниже примерах я использую 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
, Регулярное выражение ищет!
и самая короткая возможная строка (.+?
,?
заставляет его искать самый короткий) до конца строки ($
).\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 (в hex и 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 байта контрольной суммы: