Отображать только раздел данных пакета

Я пытаюсь отобразить только раздел данных пакета 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,

  1. awk

    $ echo 'E..".J@.@.U~.........v.....!HELLO' | awk -F'!' '{print $NF}'
    HELLO
    

    awk разбивает входные строки на поля, разбивая символ, заданный как -F, В этом случае, !, $NF это специальная переменная, которая означает последнее поле. Итак, команда выше, принимает ! в качестве разделителя полей и печатает последнее поле, т. е. все, что идет после последнего !,

  2. grep

    echo 'E..".J@.@.U~.........v.....!HELLO' | grep -oP '!\K.+?$'
    

    -o флаг причины grep печатать только совпадающую часть строки и -P активирует Perl-совместимые регулярные выражения, которые дают нам \K, Регулярное выражение ищет ! и самая короткая возможная строка (.+?, ? заставляет его искать самый короткий) до конца строки ($). \K означает: отбросить то, что было найдено до \K, Результатом является то, что ! (что до \K) отбрасывается и только HELLO печатается.

  3. cut

    echo 'E..".J@.@.U~.........v.....!HELLO' | cut -d'!' -f2
    

    cut это утилита, которая, ну, режет линии В этом случае я устанавливаю разделитель поля на ! и печать 2-го поля, HELLO,

  4. 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:

UDPи 2 байта контрольной суммы:

введите описание изображения здесь

Другие вопросы по тегам