Podczas analizy ramki, przejrzałem this page.
teraz na Perl ...
my $l3protlen = ord substr $raw_bytes, 14, 1;
Ekstrakt 15. bajcie (znaku) ze $raw_bytes
i konwersji do jego wartości porządkowej (np postaci „A” powinno być przekształcony w całkowitej 65 (0x41), zakładając, że zestaw znaków to ASCII). W ten sposób Perl może przetwarzać dane binarne tak, jakby były ciągiem znaków (np. Przekazywać je do substr
), ale potem pozwala wycofać wartości binarne i obsłużyć je jako liczby. (Ale pamiętaj o TMTOWTDI.)
W ramce IPv4 pierwsze 14 bajtów to nagłówek MAC (6 bajtów każdy dla docelowego i źródłowego adresu MAC, a następnie 2-bajtowy Ethertype, który prawdopodobnie był 0x8000 - mogłeś to sprawdzić). Po tym, 15 bajt jest początkiem ładunku danych Ethernet: pierwszy bajt zawiera wersję (4 górne bajty) i długość nagłówka w DWORD (4 bajty niższe).
Teraz wygląda na to, że w następnym wierszu tego przykładowego kodu jest błąd, ale normalnie może działać fluke!
my $l3prot = $l3protlen & 0xf0 >> 2; # the protocol part
W Perl >>
ma wyższy priorytet niż &
, więc będzie to równoznaczne z
my $l3prot = $l3protlen & (0xf0 >> 2);
lub jeśli wolisz
my $l3prot = $l3protlen & 0x3c;
Więc ten wydobywa bity 2 - 5 Z $l3prot
wartość: wartość maski 0x3c wynosi 0011 1100 w binarnym. Na przykład wartość 0x86 (w binarnym, 1000 0110) będzie wynosić 0x04 (binarny 0000 0100). W rzeczywistości "normalna" wartość IPv4 to 0x45, tj. Protokół typu 4, długość nagłówka 5 dwordów. Maskuj to za pomocą 0x3c, a otrzymasz ... 4! Ale tylko przez Fuksa: przetestowałeś 2 pierwsze bity długości, a nie typ protokołu!
Linia ta powinna być na pewno
my $l3prot = ($l3protlen & 0xf0) >> 4;
(wsporniki note dla pierwszeństwa i przesunięcie 4 bity, a nie 2). (Uważam, że ten sam błąd w CPAN documentation więc myślę, że to prawdopodobnie dość szeroko rozpowszechniony.)
return unless $l3prot == 4; # return unless IPv4
Dla IPv4 oczekujemy wartość ta będzie 4 - jeśli tak nie jest, wyskoczyć z funkcji od razu. (Tak zły kod powyżej daje wynik, który pozwala to być interpretowane jako pakiet IPv4, ale tylko dzięki szczęściu.)
my $l4prot = ord substr $packet, 23, 1;
Teraz wyodrębnić 24 bajtów i konwertować do wartości porządkowej w ten sam sposób.Jest to bajt Protokół z nagłówka IP:
return unless $l4prot == '7';
Oczekujemy, że jest to 7 - jeśli nie jest wyskoczyć z funkcji od razu. (Zgodnie z IANA, 7 to "drzewa bazowe" ... ale domyślam się, że znasz protokoły, którymi jesteś zainteresowany!)
Bardzo dobrze wyjaśniony. Tak, szukałem specjalnie dla udp, więc 7. – nohup
@nohup - Dzięki! ale UDP ma 17, a nie 7 ... Czy próbowałeś tego z moją sugerowaną poprawką do linii '' & 0xf0'? – AAT
Doskonałe i dobrze wyjaśnione. Dobra robota dostrzegając te błędy –