Чтение пакетов с Linux::TunTap

Я собрал perl-скрипт, который считывает пакеты в пользовательское пространство через Linux::TunTap, и кажется, что все работает нормально:

#!/usr/bin/perl
use warnings;
use strict;
use Linux::TunTap;

$tun = new Linux::TunTap(NAME => 'localtun')
or die "Couldn't connect to IF\n";

while (my $packet = $tun->get_raw()) {
        print Dumper($packet);
}

Теперь возникает вопрос: как превратить строку, представляющую необработанный IP-пакет, считанный с устройства tuntap, в правильную структуру данных для обработки? В частности, я после источника, назначения и порядкового номера.

Очевидно, что исходный IP-пакет не очень удобен для чтения в исходном формате. Вот вывод после отправки пинга через интерфейс tuntap:

{{{�}/��8V�| !"#$%&'()*+,-./0123456ET��@@4

Как мне перейти отсюда, чтобы иметь возможность обрабатывать эти данные программно?

1 ответ

Решение

Основываясь на комментарии, сделанном Steffen Ullrich, я взглянул на NetPacket:: IP, который помог мне decode() метод. После того, как он был вставлен в мой код, он работал практически из коробки, единственное предостережение в том, что первые четыре байта должны исходить из необработанных данных (см. Ленивое регулярное выражение ниже), так как эти байты формируют дополнительный заголовок, добавленный TunTap слой.

Мой код теперь выглядит так, и работает как задумано:

#!/usr/bin/perl
use warnings;
use strict;
use Linux::TunTap;
use NetPacket::IP;

$tun = new Linux::TunTap(NAME => 'localtun')
or die "Couldn't connect to IF\n";

while (my $rawdata = $tun->get_raw()) {
        $rawdata =~ s/^....//;  # Using regex to strip 4 bytes, because I'm lazy 
        my $packet = NetPacket::IP->decode($rawdata);
        print "$packet->{id} $packet->{src_ip} -> $packet->{dest_ip} $packet->{proto} $packet->{len}\n";
}

Приведенный выше код печатает последовательность, IP-адрес источника, IP-адрес назначения, номер протокола и длину пакета.

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