2009-10-07 9 views
7

Jeśli mam duży pakiet HTTP, który został podzielony na kilka pakietów TCP, w jaki sposób mogę zrekonstruować je z powrotem do pojedynczego pakietu HTTP? Zasadniczo, gdzie w pakiecie mam sprawdzić, kiedy zaczyna się/kończy pakiet HTTP? Nie mogę zobaczyć żadnych flag/pól w nagłówku TCP, które oznaczają początek lub koniec pakietu HTTP.Rekonstrukcja pakietu HTTP

EDYCJA: W uzupełnieniu do odpowiedzi. Jeśli TCP zarządza strumieniem, skąd wiadomo, kiedy strumień się zaczyna i kończy? Czy to zależy od otwarcia i zamknięcia gniazda? Niektóre protokoły, na pewnym poziomie, muszą być w stanie wiedzieć, kiedy strumień HTTP/pakiet został uruchomiony i zakończony. Właśnie tego chciałbym wiedzieć.

Sytuacja, w której się znajduję polega na używaniu sniffera pakietów w C#, który czyta w pakietach TCP, i chciałbym móc odtworzyć żądania HTTP/odpowiedzi/etc. przeglądanie interfejsu, na przykład jak radzi sobie wireshark i różne inne sniffery. Alternatywnie, czy są jakieś biblioteki C#, które umożliwiają ci wejście w strumienie HTTP na wyższym poziomie, oszczędzając mi konieczność rekonstrukcji strumienia HTTP/pakietów?

Dzięki.

Odpowiedz

10

OK Dowiedziałem się, jak to zrobić (podejrzany, ale to się załatwia).

Łatwo jest usunąć nagłówki Ethernet, IP i TCP, pozostawiając "surowy" komunikat danych. Zaglądając do wiadomości, łatwo jest wykryć, czy jest to początek pakietu HTTP, szukając "HTTP/1.1 ..." na początku pakietu. Oznacza to, że pakiet jest początkiem strumienia HTTP/większego pakietu/cokolwiek. Możesz również wykonać proste przetwarzanie, aby odczytać pole "Długość treści", które jest całkowitą długością całego pakietu HTTP.

Można również użyć numerów portu Source/Destination IP &, aby utworzyć niepowtarzalny identyfikator dla łącza. Więc po otrzymaniu pakietu nagłówkowego, zanotuj te 4 rzeczy (SRCIP, SRCPORT, DESTIP, DESTPORT). Gdy następnym razem otrzymasz pakiet pasujący do tego portu/ip, możesz sprawdzić, czy jest to następna część pakietu HTTP. Możesz użyć numerów sekwencji, aby dokonać jakiejś weryfikacji i prawdopodobnie innych rzeczy, ale ogólnie pakiety są w porządku, więc jest OK.Myślę, że nowy port jest otwarty dla każdego strumienia HTTP, więc nie powinieneś otrzymywać losowych pakietów, które nie są częścią strumienia, ale może to być obszar podatny na błędy.

W każdym razie po otrzymaniu tego pakietu ponownie pozbądź się nagłówków i uzyskaj nieprzetworzoną wiadomość. Dodaj go do już znanej części wiadomości. Jeśli długość całkowitej wiadomości odebranej do tej pory jest równa długości odczytanej z pola "Content-Length", pakiet jest kompletny!

Ta metoda jest oczywiście podatna na ogromną liczbę błędów, ale nie jestem po wyjątkowo mocnym sposobie jej wykonywania. Pomyślałem, że odpowiem na własne pytanie na wypadek, gdyby ktoś inny natknął się na ten sam problem w przyszłości! Powodzenia w węszeniu: D

+2

Jeśli pole Content-Length nie jest określony, istnieją inne sposoby, aby wypracować długość też. na przykład http://www.httpwatch.com/httpgallery/chunked/ – mike

+2

Może być nieco spóźniony, ale nagłówek 'Content-Length' NIE określa całkowitej długości pakietu. Określa jedynie rozmiar treści, a więc ciało, które pojawia się po nagłówkach. Nagłówki i treść są oddzielone przez '\ r \ n \ r \ n'. –

7

Nie powinieneś używać żadnych informacji z poziomu TCP, aby określić granice żądań HTTP. TCP zapewnia niezawodną usługę strumienia bajtów; nie można zobaczyć żadnych pól lub flag w protokole TCP, które pomagają w tym, ponieważ ich tam nie ma.

Aby ustalić, gdzie granice znajdują się w żądaniu HTTP, należy postępować zgodnie z RFC 2616. Granice są dobrze zdefiniowane i można je określić, analizując otrzymywane dane.

2

Protokół TCP jest protokołem , a nie protokołem pakietowym. Warstwa aplikacji (np. Ty) otrzymuje strumień danych, a nie paczkę pakietów. Po prostu czytasz bajty ze strumienia, a otrzymasz cały ładunek http, podczas gdy TCP sprawdza błędy, wysyła ponownie, itp. Pod spodem.

4

W każdym pakiecie TCP początek danych ładunku jest zaraz po nagłówku TCP, a koniec danych ładunku jest końcem pakietu IP.

Koniec nagłówka TCP można łatwo znaleźć - Data Offset to 4-bitowe pole w nagłówku, które zawiera długość nagłówka w słowach 32-bitowych (więc pomnóż go przez 4, aby uzyskać długość w 8- bit bajtów).

Użyj numerów sekwencji TCP z pola Sequence, aby połączyć ciągi danych razem we właściwej kolejności. Zwróć uwagę, że w przypadku retransmisji mogą wystąpić duplikaty.

1

Musieliśmy pracować nad rozwiązaniem tego samego problemu. Udało nam się wydobyć niektóre z podstawowych funkcji w projekcie open source.

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

Prosimy to sprawdzić i dać mi znać, jeśli to ci pomóc.

+0

Jestem zainteresowany wykorzystaniem twojego kodu. Bez konieczności zbyt głębokiego zagłębiania się w źródło, czy Twój projekt obsługuje a) dekompresję skompresowanych danych w oparciu o nagłówek 'Content-Encoding', b) konwersję do wspólnego kodowania tekstu opartego na' charset' w 'Content-Type' nagłówek i c) zajmujące się fragmentarycznym kodowaniem, gdy nagłówek 'Transfer-Encoding' jest ustawiony na' chunked'? –

Powiązane problemy