Реконструкция HTTP-пакета - PullRequest
       22

Реконструкция HTTP-пакета

7 голосов
/ 07 октября 2009

Если у меня большой HTTP-пакет, который был разбит на несколько TCP-пакетов, как я могу восстановить их обратно в один HTTP-пакет? В основном, где в пакете я смотрю, чтобы узнать, когда начинается / заканчивается пакет HTTP? Кажется, я не вижу никаких флагов / полей в заголовке TCP, которые обозначают начало или конец HTTP-пакета.

РЕДАКТИРОВАТЬ: В ответ на ответы. Если TCP управляет потоком, как он узнает, когда поток начинается и заканчивается? Это определяется открытием и закрытием гнезда? Некоторый протокол, на некотором уровне, должен знать, когда поток / пакет HTTP начался и закончился. Это то, что я хотел бы знать.

Ситуация, в которой я нахожусь, заключается в том, что я использую анализатор пакетов в C #, который считывает TCP-пакеты, и я хотел бы иметь возможность восстановить HTTP-запросы / ответы / и т. Д. прохождение через интерфейс, например, как это делают Wireshark и другие снифферы. В качестве альтернативы есть ли библиотеки C #, которые позволяют подключаться к потокам HTTP на более высоком уровне, избавляя меня от необходимости восстанавливать поток / пакеты HTTP самостоятельно?

Спасибо.

Ответы [ 6 ]

10 голосов
/ 08 октября 2009

ОК, я разобрался, как это сделать (хитро, но он выполняет свою работу).

Легко убрать заголовки Ethernet, IP и TCP, оставив вас с «необработанным» сообщением данных. Заглянув внутрь сообщения, легко определить, является ли это началом пакета HTTP, по запросу «HTTP / 1.1 ...» в начале пакета. Это указывает на то, что пакет является началом потока HTTP / большего пакета / чего угодно. Вы также можете выполнить простой анализ, чтобы прочитать поле «Content-Length», которое является общей длиной всего пакета HTTP.

Вы также можете использовать IP-адреса источника / назначения и номера портов, чтобы сформировать уникальный идентификатор для ссылки. Поэтому после получения пакета заголовка обратите внимание на эти 4 вещи (SRCIP, SRCPORT, DESTIP, DESTPORT). В следующий раз, когда вы получите пакет, соответствующий этой комбинации порта / ip, вы можете проверить, является ли это следующей частью HTTP-пакета. Вы можете использовать порядковые номера для некоторой проверки и, возможно, других вещей, но обычно пакеты в порядке, так что все в порядке. Я думаю, что новый порт открывается для каждого потока HTTP, поэтому вы не должны получать случайные пакеты, которые не являются частью потока, но это может быть область, подверженная ошибкам.

В любом случае, как только вы получили этот пакет, еще раз уберите заголовки и получите необработанное сообщение. Добавьте его в уже известную часть сообщения. Если общая длина полученного сообщения равна длине, считанной из поля «Content-Length», пакет завершен!

Этот метод, очевидно, подвержен огромному количеству ошибок, но мне не нужен чрезвычайно надежный способ сделать это. Я думал, что отвечу на свой вопрос, если кто-то еще столкнется с этой проблемой в будущем! Удачи тебе с нюханием: D

7 голосов
/ 07 октября 2009

Вы не должны использовать какую-либо информацию с уровня TCP для определения границ HTTP-запроса. TCP обеспечивает надежную службу потока байтов; вы не можете видеть какие-либо поля или флаги в TCP, которые помогают с этим, потому что их там нет.

Чтобы определить, где находятся границы в HTTP-запросе, вы должны следовать RFC 2616. Границы четко определены, и вы можете определить их, анализируя полученные данные.

4 голосов
/ 07 октября 2009

В каждом пакете TCP начало данных полезной нагрузки следует сразу после заголовка TCP, а конец данных полезной нагрузки - это конец IP-пакета.

Конец заголовка TCP легко найти - Data Offset - это 4-битное поле в заголовке, которое содержит длину заголовка в 32-битных словах (поэтому умножьте его на 4, чтобы получить длину в 8 байт).

Используйте порядковые номера TCP из поля Sequence, чтобы связать полезные данные в правильном порядке. Обратите внимание, что в случае повторных передач могут быть дубликаты.

2 голосов
/ 23 июня 2010

Вы можете использовать код проекта с открытым исходным кодом с именем Xplico: http://www.xplico.org

2 голосов
/ 07 октября 2009

TCP - это протокол stream , а не пакетный протокол. Прикладной уровень (т. Е. Вы) получает поток данных, а не набор пакетов. Вы просто продолжаете читать байты из потока и получаете всю полезную нагрузку http, в то время как TCP выполняет проверку ошибок, повторную отправку и т. Д. Внизу.

1 голос
/ 12 ноября 2009

Нам пришлось работать над решением той же проблемы. Мы смогли извлечь некоторые основные функции из проекта с открытым исходным кодом.

http://code.google.com/p/pcap-reconst/

Пожалуйста, проверьте это и дайте мне знать, если это поможет вам.

...