ReceivePacket
$BytesReceived = $nic->ReceivePacket();
Этот метод выполняет захват множества пакетов. Возвращает длину части буфера, содержащую достоверные данные. Число пакетов, полученных этим методом переменно. Это зависит от количества пакетов, фактически сохраненных в буфере драйвера, от размера этих пакетов и от размера буфера, связанного с $nic. Можно установить таймаут на запросы чтения с помощью метода SetReadTimeout(). В этом случае метод возвратит значение, даже если пакеты не были захвачены, если время ожидания, установленное этим методом истекло.
Формат, используемый драйвером, чтобы послать пакеты приложению следующий:
Пакет #1 - > --------- ----- bpf_hdr структура ------ | Bpf_hdr | --- > | tv_sec l = int | --------- | tv_usec l = int | | Данные | | bh_caplen I = unsigned int | --------- | bh_datalen I = unsigned int | | Выравнивание | | bh_hdrlen S = unsigned short| Пакет #2 - > --------- ------------------------------ | Bpf_hdr | --------- | Данные | --------- | Выравнивание | --------- ... И т.д
Каждый пакет имеет заголовок, находящийся в структуре bpf_hdr, которая определяет ее длину и вмещает ее временной штамп (timestamp). Поле выравнивание используется для выравнивания данных в буфере по границе слова.
Структура Bpf_hdr имеет следующие поля:
- tv_sec
дата захвата в стандарте времени UNIX,
- tv_usec
микросекунды захвата,
- bh_caplen
длина захваченной порции,
- bh_datalen
истинная длина пакета,
- Bh_hdrlen
длина заголовка формирующего (инкапсулирующего) пакет.
Например, можно получить значения первого заголовка буфера пользователя $buffer: ($tv_sec, $tv_usec, $caplen, $datalen, $hdrlen)=unpack ‘llIIS’, $buffer;
и затем извлечь первый пакет из этого буфера: my $packet = substr $buffer, 0, $datalen;