Обнаружение IP-пакетов внутри потока данных

Иногда в процессе отладки сетевых приложений возникает необходимость проанализировать содержимое пакетов по бинарным/hex логам обмена, и при этом под рукой может не оказаться специализированной программы для анализа.
Тем более, что, сформировать вручную бинарный файл (совместимый с форматом «снимков», поддерживаемых анализатором) содержащий «сырые» сетевые пакеты, зачастую, бывает гораздо сложнее, чем «вручную» эти пакеты «распарсить».
Либо, возникает ситуация, когда, просто нет возможности перехватить некоторые сетевые пакеты с помощью таких программ.
Например, мне так и не удалось «натравить» Microsoft Network Monitor на локально-установленный Apache.
Не помог даже специальный драйвер LoopBack-интерфейса, который я установил, в надежде что он поможет NetMon'у перехватывать локальные сетевые пакеты, типа PING 127.0.0.1 и ему подобные.
Тем не менее, вновь-созданный VPN-туннель, позволяющий отправлять в сеть «сырые» IP-пакеты, без проблем прослушивается NetMon'ом, (несмотря на то, что он так же как и Apache, поднят локально).

Приведенный ниже код позволяет в блоке «сырых» данных $raw_data отыскивать позиции начала возможных заголовков IP-пакетов версии 4.
<?php
$mask="/[E-O](?=.{8}[\x01\x06\x11])/s";
$res=preg_match_all($mask, $raw_data, $result, PREG_OFFSET_CAPTURE);
foreach ($result[0] as $rrr)
  echo $rrr[1],"\r\n";
Данный способ обнаружения довольно грубый, и дает очень много ложных срабатываний, поэтому, желательно так же более тщательно проверять результаты.
Проверка контрольной суммы заголовка полностью решает эту проблему.
function checksum($data, $bool=false) 
    { 
    if (strlen($data) & 1)
      $data .= "\x00"; 
    $bit = unpack("n*", $data); 
    $sum = array_sum($bit); 
    while ($sum >> 16) 
      $sum = ($sum >> 16) + ($sum & 0xffff); 
    if ($bool) return ($sum===0xffff);
    return pack("n", ~$sum);
    } 
Собственно вопрос:
Нужно так же обнаруживать заголовки пакетов IP версии 6.
Кто-нибудь подскажет как это попроще сделать?
9 февраля в 11:28
2
Сырые данные с какого уровня собираются? Пакет попадает полностью в $raw_data или частичо? DmZ,
Разумеется, полностью (если идет фрагментация, то фрагмент попадает целиком).
$raw_data может содержать данные из файлов захвата Network Monitor'а "*.cap", либо «растранспарированные» (untranspared) данные считанные напрямую из последовательного порта модема.
Внутри самого потока (в области обнаруживаемого пакета) нет никаких «посторонних» включений.
При этом, сам пакет может быть окружен с обоих сторон заголовками инкапсуляций канального (и, даже, транспортного) уровня. Сами RAW-данные не сжатые и незашифрованные.
1010101001000100110100111,

отсортировано по дате по оценке
ответы (1)

0
DmZ #
В общем случае не выйдет просто найти пакет IPv6.
Если есть заголовки Ethernet, то можно смотреть на «тип» и версию внутреннего протокола. (В любом случае это позволит практически 100% определять IPv4/IPv6 пакеты)
В случае с PPP — прийдется анализировать и установку соединения и конфигурацию (IPCP/IP6CP) — одним регеэкспом не отделаешься :(

Может проще посмотреть на нормальные тулзы типа Wireshark?
Одного лишь анализа заголовков канального уровня (Ethernet/PPP) явно недостаточно, поскольку пакеты разных протоколов могут инкапсулироваться внутри других протоколов. Например, в случае отсутствия нативной поддержки сетью протокола IPv6 пакеты IPv6 передаются через сеть IPv4 инкапсулируясь в UDP. так что, анализ типа в заголовке канального протокола покажет, что это пакет IPv4, и если не копать глубже, то вложенный пакет IPv6 окажется незамеченным (поскольку полностью «накрывается» IPv6-пакетом). Я вообще хочу сделать свой VPN-сервер, позволяющий отправлять сырые пакеты сетевого уровня IPv4/IPv6, а так же, любые другие пакеты канального уровня (Ethernet/ARP), и, даже, физического уровня (PnP) используя в качестве транспорта любой доступный протокол, возможно даже, уровня приложения HTTP/IRC. 1010101001000100110100111, 11 февраля в 08:43
Еще понимал вопрос с точки зрения сниффера, а с точки зрения VPN не понимаю совсем. Разве что вы пытаетесь разобрать пакеты на выходе VPN (так как на вход данные попадут в том формате, в котором захотите вы, имхо). Но для реализации VPN — не проще ли использовать дополнительный уровень инкапсуляции — сделать заголовок который вы уникально определите во входящем потоке и в котором будет содержаться необходимая информация об инкапсулированном протоколе. DmZ, 13 февраля в 13:06
На самом деле, все вертится вокруг предоставления приложению, написанному на языке высокого уровня (например PHP) и запущенному из-под непривилегированной учетной записи (например, Гость), возможности формировать и отправлять «сырые» IP-пакеты с помощью привычных файловых потоков, сделав для них «обертку» наподобие: «ip://192.168.1.2/» (по аналогии с «tcp://192.168.1.2:80/») или, даже, «gprs://internet.mts.ru/». Среда передачи в таком случае не играет особой роли. Фактически можно было бы для этого использовать протокол SLIP (основное назначение которого как раз-таки — разграничение отдельных IP-пакетов в потоке), и соответственно, обертку «slip://192.168.1.2/», но, как видно, задача разграничения решается гораздо проще, и не требует ввода специальных символов-разделителей, и соответственно экранирования этих спец-символов внутри самих пакетов. 1010101001000100110100111, 13 февраля в 13:53

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.