Ich versuche, das DF (nicht fragmentieren Flag) zum Senden von Paketen mit UDP zu setzen.
Betrachten wir das Buch von Richard Steven Volume 1 Unix Network Programming; Die Sockets-Netzwerk-API kann nicht gefunden werden, wie dies eingerichtet wird.
Ich vermute, dass ich es mit setsockopt () machen würde, aber ich finde es nicht in der Tabelle auf Seite 193.
Bitte schlagen Sie vor, wie das gemacht wird.
Sie tun es mit dem Aufruf setsockopt()
, indem Sie die IP_DONTFRAG
Option ::
Hier ist eine Seite, die das genauer erklärt.
Für Linux scheint es, dass Sie die Option IP_MTU_DISCOVER
mit dem Wert IP_PMTUDISC_DO
(oder IP_PMTUDISC_DONT
, um es auszuschalten) verwenden müssen:
Ich habe das nicht getestet, habe nur in die Header-Dateien und ein bisschen eine Websuche gesucht, also müssen Sie es testen.
Gibt es eine andere Möglichkeit, das DF Flag zu setzen:
Ich finde nirgendwo in meinem Programm, wo das "force DF Flag" gesetzt ist, aber
tcpdump
deutet darauf hin, dass es ist. Gibt es eine andere Möglichkeit, dies zu erreichen?
Von dieser ausgezeichneten Seite hier :
IP_MTU_DISCOVER:
Setzt oder definiert die Path MTU Discovery-Einstellung für einen Socket. Wenn diese Option aktiviert ist, führt Linux die Pfad-MTU-Erkennung gemäß RFC 1191 für diesen Socket durch. Das Flag nicht fragmentieren wird für alle ausgehenden Datagramme gesetzt. Der systemweite Standardwert wird von den Socketsip_no_pmtu_disc
sysctl
fürSOCK_STREAM
und bei allen anderen Sockets deaktiviert. Für nichtSOCK_STREAM
-Sockets ist der Benutzer dafür verantwortlich, die Daten in MTU-großen Blöcken zu paketieren und die Übertragungen gegebenenfalls durchzuführen. Der Kernel wird Pakete zurückweisen, die größer als die MTU des bekannten Pfads sind, wenn dieses Flag gesetzt ist (mitEMSGSIZE
).
Das sieht so aus, als könnten Sie den systemweiten Standard mit sysctl
:
gibt "error: "ip_no_pmtu_disc" is an unknown key"
auf meinem System zurück, aber möglicherweise wird es auf deins gesetzt. Abgesehen davon ist mir nichts anderes bekannt (außer setsockopt()
wie zuvor erwähnt), das die Einstellung beeinflussen kann.
Wenn Sie in Userland mit der Absicht arbeiten, den Netzwerkstack des Kernels zu umgehen und somit Ihre eigenen Pakete und Header zu erstellen und sie einem benutzerdefinierten Kernelmodul zu übergeben, gibt es eine bessere Option als setsockopt()
.
Sie können das DF-Flag genauso einstellen wie jedes andere Feld von struct iphdr
, das in linux/ip.h
definiert ist. Die 3-Bit-IP-Flags sind tatsächlich Teil von frag_off
(Fragment Offset) Mitglied der Struktur.
Wenn Sie darüber nachdenken, ist es sinnvoll, diese beiden Dinge zu gruppieren, da die Flags fragmentiert sind. Laut dem RFC-791 , der Abschnitt, der die IP-Header-Struktur beschreibt, dass Fragment Offset ist 13-Bit lang und Es gibt drei 1-Bit-Flags. Der Member
frag_off
hat den Typ __be16
, der 13 + 3 Bits enthalten kann.
Lange Rede, kurzer Sinn, hier ist eine Lösung:
%Vor% Wir setzen hier das DF-Bit genau ein, indem wir die für IP_DF
bestimmte Maske verwenden.
IP_DF
ist in net/ip.h
(natürlich Kernel-Header) definiert, während struct iphdr
in linux/ip.h
definiert ist.
Ich stimme der Antwort von paxdiablo zu.
%Vor%
ip_no_pmtu_disc
in der Kernelquelle: if (ipv4_config.no_pmttu_disc) inet- & gt; pmtudisc = IP_PMTUDISC_DONT; sonst inet- & gt; pmtudisc = IP_PMTUDISC_WANT;