Frage

Ich versuche, die DF zu setzen (keinen Flag nicht fragmentieren) zum Senden von Paketen UDP verwendet wird.

Mit Blick auf das Buch Volume Richard Steven 1 Unix Network Programming; Die Sockets Networking API, ich bin nicht in der Lage zu finden, wie diese einzustellen.

Ich vermute, dass ich es mit setsockopt tun würde (), aber es kann nicht auf Seite 193 in der Tabelle finden.

Bitte legen nahe, wie dies geschehen ist.

War es hilfreich?

Lösung

Sie tun es mit dem setsockopt() Aufruf, durch die IP_DONTFRAG Option ::

int val = 1;
setsockopt(sd, IPPROTO_IP, IP_DONTFRAG, &val, sizeof(val));

Hier eine Seite erklärt dies in weitere Details.

Für Linux, es scheint, dass Sie die IP_MTU_DISCOVER Option zu verwenden, haben mit dem Wert IP_PMTUDISC_DO (oder IP_PMTUDISC_DONT es auszuschalten):

int val = IP_PMTUDISC_DO;
setsockopt(sd, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val));

ich nicht getestet haben, nur in den Header-Dateien gesucht und ein bisschen eine Web-Suche, so dass Sie es testen müssen.

Zur Frage, ob eine andere Art und Weise gibt es die DF-Flag gesetzt werden:

  

Ich finde nirgends in meinem Programm, wo der „Kraft DF-Flag“ gesetzt ist, noch tcpdump schlägt vor, es ist. Gibt es eine andere Möglichkeit, dies könnte eingestellt werden?

Von dieser hervorragenden Seite hier :

  

IP_MTU_DISCOVER: Sets oder empfängt die Path MTU Discovery für einen Sockel setzen. Wenn diese Funktion aktiviert, wird Linux Path MTU Discovery durchführen, wie in RFC 1191 auf dieser Buchse definiert. Das Fragment nicht Flag wird auf alle ausgehenden Datengramme eingestellt. Die systemweite Standard wird durch die ip_no_pmtu_disc sysctl für SOCK_STREAM Buchsen gesteuert und auf alle anderen deaktiviert. Für nicht SOCK_STREAM Steckdosen ist es in der Verantwortung des Anwenders, die Daten in MTU Chunks paketieren und die Retransmits bei Bedarf zu tun. Der Kernel-Pakete zurückweisen, die MTU größer als der bekannte Weg sind, wenn dieses Flag gesetzt ist (mit EMSGSIZE).

Das sieht für mich wie Sie die systemweite Standard mit sysctl festlegen:

sysctl ip_no_pmtu_disc

kehrt "error: "ip_no_pmtu_disc" is an unknown key" auf meinem System, aber es kann auf Ihnen eingestellt werden. Other than that, ich bin nicht bewusst etwas anderes (außer setsockopt() wie bereits erwähnt), die die Einstellung beeinflussen können.

Andere Tipps

Wenn Sie mit der Absicht, in Userland arbeiten, um die Kernel-Netzwerk-Stack zu umgehen und damit den Aufbau Ihrer eigenen Pakete und Header und übergeben sie an einen benutzerdefinierten Kernel-Modul gibt es eine bessere Option als setsockopt().

Sie können tatsächlich die DF-Flag gesetzt wie jedes andere Gebiet der struct iphdr in linux/ip.h definiert. Die 3-Bit-IP-Flags sind in der Tat Teil der frag_off  (Fragment Offset) Mitglied der Struktur.

Wenn man darüber nachdenkt, macht es Sinn, zu gruppieren diese beiden Dinge wie die Fahnen sind Fragmentierung im Zusammenhang. Nach dem RFC-791 , der Abschnitt der IP-Header-Struktur beschreibt, besagt, dass Fragment Offset ist 13-Bit lang und es gibt drei 1-Bit-Flags. Das frag_off Mitglied ist vom Typ __be16, die 13 + 3 Bits aufnehmen können.

Lange Rede kurzer Sinn, hier eine Lösung:

struct iphdr ip;
ip.frag_off |= ntohs(IP_DF);

Wir sind hier genau die DF-Bit Einstellung IP_DF Maske mit dem designed-for-dass-insbesondere universell einsetzbar.

IP_DF wird in net/ip.h (kernel-Headern, natürlich) definiert, während struct iphdr in linux/ip.h definiert ist.

Ich stimme der paxdiablo Antwort.

  • setsockopt (sockfd, IPPROTO_IP, IP_MTU_DISCOVER & val, sizeof (val))

wo val ist eines der folgenden:

#define IP_PMTUDISC_DONT   0    /* Never send DF frames.  */
#define IP_PMTUDISC_WANT   1    /* Use per route hints.  */
#define IP_PMTUDISC_DO     2    /* Always DF.  */
#define IP_PMTUDISC_PROBE  3    /* Ignore dst pmtu.  */
  • ip_no_pmtu_disc in Kernel-Quelle:
if (ipv4_config.no_pmtu_disc)
    inet->pmtudisc = IP_PMTUDISC_DONT;
else
    inet->pmtudisc = IP_PMTUDISC_WANT;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top