2016-04-10 14 views
0

Ich arbeite an der Entwicklung eines benutzerdefinierten Paket-Sniffer für Windows 7 64-Bit-Host-System (NIC-Karte Realtek PCIe GBE Family Controller) und benutze WinPcap 4.3.1 Bibliothek mit C-Programmierung und Cygwin-Entwicklungsplattform. Ich kann ausgehende und eingehende TCP- und UDP-Pakete über mein Programm lesen. Allerdings bin ich in einem Problem stecken nicht in der Lage, korrekte Zeitstempel in Mikrosekunde von der Struktur Struktur pcap_pkthdr bekommen. Es folgt der Code-Schnipsel aus dem Programm, in dem das Problem besteht:Cygwin und WinPcap 4.1.3 Zeitstempel - Mikrosekundenausgabe - Header-> ts.tv_usec nicht korrekt - C Programm

... 

int getPacket; 
struct pcap_pkthdr *header; 
const u_char *pkt_data; 

/* Sniff the packets */ 
while((getPacket= pcap_next_ex(handle, &header, &pkt_data)) >= 0) 
{  

printf("\n 1) Epoch is: %ld",header->ts.tv_sec&0x00000000ffffffff);  

printf("\n 2) Microsecond is: %ld",header->ts.tv_usec); 

... 

Im Anschluss an die Konsolausgabe, die ich für diese 2 printf() Aussagen in einem Lauf bekam:

1) Epoche ist: 1460262399
2) Mikrosekunde ist: 1576252997999

Zeit in Sekunden (Header-> ts.tv_sec & 0x00000000ffffffff) korrekt ist, wie es zu 2016.04.09 :: 23 übersetzt: 26: 39 (yy-mm- dd :: hh-mm-ss Format)

jedoch Mikrosekunden- (Header-> ts.tv_usec) nicht korrekt ist als der Hexadezimalwert von Mikrosekunde 0x16F0000016F ist, die immer diese Art zeigt Muster von sich wiederholenden (mit verschiedenen Werten) bei der niedrigen und hohen Oktettpositionen. Ich habe Speicherabzüge analysiert und dieselben Werte gefunden, die mich glauben lassen, dass der header-> ts.tv_usec nicht korrekt durch den NPF-Treiber gefüllt wird.

Ich habe viel gesucht und konnte dieses Problem nirgendwo gefunden finden. Außerdem habe ich den Code auf separaten AMD- und Intel-Rechnern getestet und das Problem scheint zu bestehen.

Alle Vorschläge zur Lösung dieses Problems werden sehr geschätzt.

+0

Alle Bits von 'tv_sec' sind signifikant, daher sollte man sie nicht mit' 0x00000000ffffffff' verknüpfen. Was passiert, wenn Sie nur 'printf (" \ n 1) Epoch ist:% ld ", header-> ts.tv_sec);'? –

+0

Danke Guy.In der Tat habe ich ANDing mit '0x00000000ffffffff' gezeigt, um die Tatsache hervorzuheben, dass nur 32 niedrigerwertige Bits von tv_sec gültig sind. In meinem Code schreibe ich es mit (int). 'printf (" \ n 1) Epoch ist:% ld ", header-> ts.tv_sec) ergibt die volle 64-Bit-Zahl, z. '1341397056348719 (0x4C3FE570BE22F)'. Sie können sehen, dass nur die letzten 8 Oktetts sinnvoll sind. Ich habe es durch Tests und Versuche gefunden. – Han

+0

"Markieren Sie die Tatsache, dass nur 32 niedrigerwertige Bits von tv_sec gültig sind" Wenn das eine Tatsache ist, ist das ein * Bug * in WinPcap! Wir möchten, dass WinPcap 2038 und später, zumindest auf 64-Bit-Plattformen, weiter läuft und dass alle 64 Bits von tv_sec gültig sein müssen, und wir möchten, dass es mit UN \ * X libpcap kompatibel ist. auf dem alle 64 Bits signifikant sind. Möglicherweise gibt es * einen anderen Fehler in 64-Bit-WinPcap, der die Probleme verursacht, die Sie sehen. –

Antwort

1

Eigentlich sind in WinPcap nur 32 Bits in tv_sec.

WinPcap verwendet Microsoft's definition of struct timeval - es ist nicht Cygwin benötigt, so kann es nicht Cygwin Definition verwenden - und in dieser Definition tv_sec und tv_usec sind beide long und in MSVC, long ist 32-Bit-sogar auf 64 -bit Plattformen. (Sie benötigen einen anderen Datentyp für ein 64-Bit-Integer.)

Von Ihrem Test, Cygwin struct timeval hat einen 64-Bit-tv_sec und einen 64-Bit tv_usec auf 64-Bit-Plattformen. Deshalb:

  1. Cygwin nicht mit WinPcap arbeiten auf 64-Bit-Plattformen;
  2. ein 64-Bit-Cygwin-Programm mit WinPcap wird denken, dass die Sekunden und Mikrosekunden Felder eines pcap-Zeitstempels sind ein 64-Bit tv_sec Feld, so dass nur die unteren 32 Bits gültig sind, und denke, dass einige zufällige Orte in Speicher ist das tv_usec Feld, so dass Sie das Verhalten sehen, das Sie melden.
+0

Danke für die Details. Sie sind sehr hilfreich, um den Umfang des Problems zu reduzieren. Ich habe versucht, die machine.h Datei von Cygwin zu ändern, wo die Strukturen TIME_T und __suconds_t von LANG zu unsigned int geändert werden. Es hat jedoch den Effekt, dass die Funktion printf() in der Konsolenausgabe angehalten wird (nur printf() mit Zeitstrukturen). Programm läuft ohne Coredump und endet ohne Fehler. Ist es das gleiche Problem, bei dem Sie erwähnt haben, dass das Programm an zufällige Speicherorte springt und damit beendet wird, ohne einen Fehler zu melden? – Han

+0

"Sie haben erwähnt, dass das Programm an zufällige Speicherorte springt." Nein, tat ich nicht. Ich sagte, "ein 64-Bit Cygwin-Programm mit WinPcap ... wird denken, dass einige zufällige Orte im Speicher das' tv_usec' Feld sind, dh dass es einige "zufällige Orte im Speicher" als * Daten * bezeichnen wird, nicht als * Code*. Die Orte sind nicht "zufällig" im Sinne von zufälligen Speicheradressen - ihre Adressen sind direkt nach dem, was "header" zeigt - aber was dem entspricht * ist * zufällig, ohne Gewähr dafür, was da ist. –

+0

"Ich habe versucht, die machine.h-Datei von Cygwin zu ändern, wobei die Strukturen TIME_T und __suconds_t von LONG in unsigned int geändert werden." Ich kann nicht garantieren, welche anderen Effekte, wahrscheinlich unerwünschte Auswirkungen, auf jeden Code haben werden, den Sie kompilieren, der direkt oder direkt diesen Header enthält; das könnte alle möglichen anderen Dinge in Ihrem Code brechen. –