bash получать пакеты udp tcpdump

На одном сервере я получаю пакеты udp на 192.168.0.51 от приложения, работающего на 192.168.0.21, и должен ответить определенным пакетом подтверждения.

Решение, которое я написал, работает следующим образом:

#!/bin/bash
send_ack() {
<calculate $ack - code removed>
echo -n "$ack" | nc -u -w1 192.168.0.21 8076
}
while [ 1 ]
do
    for string in $(/usr/sbin/tcpdump -Avnni eth0 -c 1 dst 192.168.0.51 and udp port 8076)
    do
        send_ack &
    done
done

Проблема в том, что у меня, похоже, какое-то рабочее состояние, когда пакеты приходят слишком быстро, я думаю, они прибывают до перезапуска tcpdump. Я пробовал -l для однострочного буфера вместо -c 1 безуспешно.

У кого-нибудь есть идеи, как решить эту проблему?

Спасибо, ждем :)


person user1747036    schedule 16.05.2013    source источник


Ответы (1)


Проблема в вашей программе заключается в том, что пакеты будут проскальзывать между вызовами tcpdump, поскольку вы просто запускаете его для захвата одного пакета, используя -c 1, а затем каждый раз выходите снова.

Решением будет непрерывный запуск tcpdump в режиме линейной буферизации (-l) с передачей его вывода в процесс, читающий это.

#!/bin/bash
# tcpdump line buffered and piped to infinite loop
/usr/sbin/tcpdump -Avnni eth0 -l dst 192.168.0.51 and udp port 8076 | \
  while true; do
    # read output line by line
    read result
    # only act on non-blank output
    if [ "$result" != "" ]; then
      echo "Read a packet: $result"
      # perform whatever action
      send_ack &
    fi
  done

В дополнение к этому вы также можете поэкспериментировать с параметром -B для tcpdump, который позволяет вам установить размер буфера, и с различными параметрами для read.

person Riot    schedule 18.06.2013