Forum: PC-Programmierung Probleme mit selbstgebautem rudimentären IP-Stack mit Pcap


von Hardi S. (hardi13)


Angehängte Dateien:

Lesenswert?

Ich möchte ein eigenständiges rudimentäres Netzwerkdevice mit der 
Pcap-Library in C entwickeln. Der erste Schritt funktioniert bereits: 
Auf Arp-Broadcasts aus dem Netzwerk antwortet das C-Programm mit einer 
fiktiven MAC-Adresse. Mit arp -a wird meine fiktive MAC-Adresse dann 
korrekt angezeigt. Der identische Quelltext läuft sowohl unter Windows 7 
(mingw) als auch unter Debian 8.

Beim nächsten Schritt, einer Ping-Antwort, habe ich allerdings schon 
Probleme. Mein Programm empfängt die icmp Ping-Anforderung und sendet 
auch eine entsprechende Antwort. Doch sowohl unter Windows, als auch 
unter Linux bekommt der Ping Befehl diese Antwort nicht mit. Ein 
gleichzeitig laufendes Wireshark sieht hingegen die Antwort und markiert 
auch keinerlei Fehler. Auch hier zeigen Windows und Linux gleiches 
(Fehl-)Verhalten.

Grundsätzlich scheint das Senden und Empfangen laut Wireshark ja zu 
funktionieren. Ich habe schon bitweise die Ping-Antworten von anderen 
Rechnern nachgebildet, komme aber keinen Schritt weiter. Wie ist der 
richtige Startwert des Id-Feldes im IP-Header? Zur Zeit spiegele ich den 
empfangenen Wert.

Habe ich etwas Grundsätzliches übersehen? Fällt jemandem etwas auf?

Das Programm habe ich aus den Beispielen aus WinPcap weiterentwickelt. 
Statt der Auswahl des Devices suche ich nach den Strings eth0 oder 
Network.
Da ich in den Dumpfiles mit vorerst unwichtigen Paketen überhäuft wurde, 
habe ich einen Filter im packet_handler() vorweggeschaltet. Aber auch 
ohne diesen Filter bleibt das Verhalten gleich.

: Bearbeitet durch User
von DPA (Gast)


Lesenswert?

Hast du in wireshark die Überprüfung der Checksumme eingeschaltet?

Ich hab das jetzt nicht getestet, aber ich glaube nicht, dass die 
richtige Checksumme rauskommt, wenn man diese Berechnet, bevor man alle 
Daten eingesetzt hat. Versuch mal dashier:
1
    ip_header->ip_sum = in_cksum((u_int16_t *) ip_header, sizeof(struct struct_ip));                // Header checksum
2
    ip_header->ip_src = global.emul_ip;              // Source address
3
    ip_header->ip_dst = global.caller_ip;            // Destination address
Anders anzuordnen:
1
    ip_header->ip_sum = 0;                           // Make sure checksum field value doesn't change later checksum calculation.
2
    ip_header->ip_src = global.emul_ip;              // Source address
3
    ip_header->ip_dst = global.caller_ip;            // Destination address
4
    ip_header->ip_sum = in_cksum((u_int16_t *) ip_header, sizeof(struct struct_ip));                // Header checksum

Und eventuell bei der ICMP checksumme vorher das feld auch noch auf 0 
setzen:
1
    icmp_header->icmp_sum = 0; // Make sure checksum field value doesn't change later checksum calculation.
2
    icmp_header->icmp_sum = in_cksum((u_int16_t *) icmp_header, sizeof(struct struct_icmp)+global.datalen); 
3
// ip-Parameter

von Hardi S. (hardi13)


Lesenswert?

Da ich schon bitweise die Ping-Antworten von anderen Rechnern in meinem 
Programm nachgebildet und die identischen Prüfsummen erhalten habe, 
hatte ich bisher einen Fehler an dieser Stelle ausgeschlossen.

Du hast aber recht! Offensichtlich ist durch herumprobieren an dem 
Programm die Summenbildung später an die falsche Stelle gerutscht.

Danke! Das war es!
Wenn man die Lösung hat, ist es immer einfach...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.