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
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 |
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.