UNFORMATIERTE TCP/IP-Sockets

Ein unformatiertes Socket ist ein Sockettyp, der den Zugriff auf den zugrunde liegenden Transportanbieter ermöglicht. In diesem Thema geht es nur um unformatierte Sockets und die Protokolle IPv4 und IPv6. Dies liegt daran, dass die meisten anderen Protokolle mit Ausnahme von ATM keine unformatierten Sockets unterstützen. Um rohe Sockets verwenden zu können, benötigt eine Anwendung ausführliche Informationen zum zugrunde liegenden Protokoll, das verwendet wird.

Winsock-Dienstanbieter für das IP-Protokoll unterstützen möglicherweise den Sockettyp SOCK _ RAW. Der Windows Sockets 2-Anbieter für TCP/IP in Windows unterstützt diesen SOCK _ RAW-Sockettyp.

Es gibt zwei grundlegende Typen solcher unformatierten Sockets:

  • Der erste Typ verwendet einen bekannten Protokolltyp, der in den IP-Header geschrieben ist und von einem Winsock-Dienstanbieter erkannt wird. Ein Beispiel für den ersten Sockettyp ist ein Socket für das ICMP-Protokoll (IP-Protokolltyp = 1) oder das ICMPv6-Protokoll (IP-Procotol-Typ = 58).
  • Der zweite Typ ermöglicht die Angabe eines beliebigen Protokolltyps. Ein Beispiel für den zweiten Typ wäre ein experimentelles Protokoll, das nicht direkt vom Winsock-Dienstanbieter wie dem Stream Control Transmission Protocol (SCTP) unterstützt wird.

Bestimmen, ob Rohdatensockets unterstützt werden

Wenn ein Winsock-Dienstanbieter SOCK _ RAW-Sockets für die AF _ INET- oder AF _ INET6-Adressfamilien unterstützt, sollte der Sockettyp VON SOCK _ RAW in der WSAPROTOCOL _ INFO-Struktur enthalten sein, die von der WSAEnumProtocols-Funktion für einen oder mehrere der verfügbaren Transportanbieter zurückgegeben wird.

Das iAddressFamily-Element in der WSAPROTOCOL _ INFO-Struktur sollte AF _ INET oder AF INET6 angeben, und der _ iSocketType-Member der WSAPROTOCOL _ INFO-Struktur sollte SOCK _ RAW für einen der Transportanbieter angeben.

Der iProtocol-Member der WSAPROTOCOL _ INFO-Struktur kann auf IPROTO _ IP festgelegt werden. Der iProtocol-Member der WSAPROTOCOL _ INFO-Struktur kann auch auf 0 (null) festgelegt werden, wenn der Dienstanbieter einer Anwendung erlaubt, einen SOCK _ RAW-Sockettyp für andere Netzwerkprotokolle als das Internetprotokoll für die Adressfamilie zu verwenden.

Die anderen Member in der WSAPROTOCOL _ INFO-Struktur geben andere Eigenschaften der Protokollunterstützung für SOCK _ RAW an und geben an, wie ein Socket von SOCK _ RAW behandelt werden soll. Diese anderen Member von WSAPROTOCOL _ INFO für SOCK _ RAW geben normalerweise an, dass das Protokoll verbindungslos und nachrichtenorientiert ist, Broadcast/Multicast unterstützt (die _ MULTIPOINT-Bits XP1 CONNECTIONLESS, XP1 _ MESSAGE _ ORIENTED, _ XP1 SUPPORT _ BROADCAST und XP1 SUPPORT sind _ im _ DwServiceFlags1-Member festgelegt und können eine maximale Nachrichtengröße von 65.467 Bytes haben.

Auf Windows XP und höher kann der befehlNetSh.exe verwendet werden, um zu bestimmen, ob Unformatierte Sockets unterstützt werden. Der folgende Befehl, der in einem CMD-Fenster ausgeführt wird, zeigt Daten aus dem Winsock-Katalog in der Konsole an:

netsh winsock show catalog

Die Ausgabe enthält eine Liste, die einige der Daten aus den WSAPROTOCOL _ INFO-Strukturen enthält, die auf dem lokalen Computer unterstützt werden. Suchen Sie im Feld Beschreibung nach dem Begriff RAW/IP oder RAW/IPv6, um die Protokolle zu finden, die Unformatierte Sockets unterstützen.

Erstellen eines Unformatierten Sockets

Um einen Socket vom Typ SOCK _ RAW zu erstellen, rufen Sie die Socket- oder WSASocket-Funktion auf, wobei der af-Parameter (Adressfamilie) auf AF _ INET oder AF _ INET6 festgelegt ist, der Typparameter auf SOCK _ RAW und der Protokollparameter auf die erforderliche Protokollnummer festgelegt ist. Der -Protokollparameter wird zum Protokollwert im IP-Header (SCTP ist z.B. 132).

Hinweis

Eine Anwendung darf null (0) nicht als Protokollparameter für die Socket-, WSASocket-und WSPSocket-Funktionen angeben, wenn der Typparameter auf SOCK _ RAW festgelegt ist.

Unformatierte Sockets bieten die Möglichkeit, den zugrunde liegenden Transport zu bearbeiten, sodass sie für böswillige Zwecke verwendet werden können, die eine Sicherheitsbedrohung darstellen. Daher können nur Mitglieder der Gruppe Administratoren Sockets vom Typ SOCK _ RAW auf Windows 2000 und höher erstellen.

Sende- und Empfangsvorgänge

Sobald eine Anwendung einen Socket vom Typ SOCK _ RAW erstellt, kann dieser Socket zum Senden und Empfangen von Daten verwendet werden. Alle Pakete, die an einen Socket vom Typ SOCK _ RAW gesendet oder empfangen werden, werden als Datagramme für einen nicht verbundenen Socket behandelt.

Die folgenden Regeln gelten für die Vorgänge über SOCK _ RAW-Sockets:

  • Die Sendto- oder WSASendTo-Funktion wird normalerweise verwendet, um Daten an einen Socket vom Typ SOCK _ RAW zu senden. Die Zieladresse kann eine beliebige gültige Adresse in der Adressfamilie des Sockets sein, einschließlich einer Broadcast- oder Multicastadresse. Zum Senden an eine Broadcastadresse muss eine Anwendung setsockopt mit aktivierter SO BROADCAST-Funktion verwendet _ haben. Andernfalls schlägt sendto oder WSASendTo mit dem Fehlercode WSAEACCESfehl. Bei IP-Adressen kann eine Anwendung an eine beliebige Multicastadresse senden (ohne Mitglied einer Gruppe zu werden).

  • Beim Senden von IPv4-Daten hat eine Anwendung die Wahl, ob der IPv4-Header am Anfang des ausgehenden Datagramms für das Paket angegeben werden soll. Wenn die _ IP-HDRINCL-Socketoption für einen IPv4-Socket (Adressfamilie von AF INET) auf TRUE festgelegt _ ist, muss die Anwendung den IPv4-Header in den ausgehenden Daten für Sendevorgänge bereitstellen. Wenn diese Socketoption false ist (Standardeinstellung), sollte der IPv4-Header nicht in die ausgehenden Daten für Sendevorgänge eingeschlossen werden.

  • Beim Senden von IPv6-Daten hat eine Anwendung die Wahl, ob der IPv6-Header am Anfang des ausgehenden Datagramms für das Paket angegeben werden soll. Wenn die IPV6 _ HDRINCL-Socketoption für einen IPv6-Socket (Adressfamilie von AF INET6) auf TRUE festgelegt _ ist, muss die Anwendung den IPv6-Header in den ausgehenden Daten für Sendevorgänge bereitstellen. Die Standardeinstellung für diese Option ist FALSE. Wenn diese Socketoption false ist (Standardeinstellung), sollte der IPv6-Header nicht in die ausgehenden Daten für Sendevorgänge eingeschlossen werden. Für IPv6 sollte der IPv6-Header nicht enthalten sein. Wenn Informationen mithilfe von Socketfunktionen verfügbar sind, sollte der IPv6-Header nicht enthalten sein, um Kompatibilitätsprobleme in Zukunft zu vermeiden. Diese Probleme werden in RFC 3542 erläutert, das von der IETF veröffentlicht wird. Die Verwendung der _ IPV6 HDRINCL-Socketoption wird nicht empfohlen und ist in Zukunft möglicherweise veraltet.

  • Die recvfrom- oder WSARecvFrom-Funktion wird normalerweise verwendet, um Daten auf einem Socket vom Typ SOCK _ RAW zu empfangen. Beide Funktionen haben eine Option, um die Quell-IP-Adresse zurückzugeben, von der das Paket gesendet wurde. Die empfangenen Daten sind ein Datagramm von einem nicht verbundenen Socket.

  • Für IPv4 (Adressfamilie von AF _ INET) empfängt eine Anwendung den IP-Header am Anfang jedes empfangenen Datagramms, unabhängig von der _ IP-HDRINCL-Socketoption.

  • Für IPv6 (Adressfamilie von AF _ INET6) empfängt eine Anwendung alles nach dem letzten IPv6-Header in jedem empfangenen Datagramm, unabhängig von der IPV6 _ HDRINCL-Socketoption. Die Anwendung empfängt keine IPv6-Header, die einen unformatierten Socket verwenden.

  • Empfangene Datagramme werden in alle SOCK _ RAW-Sockets kopiert, die die folgenden Bedingungen erfüllen:

    • Die Protokollnummer, die beim Erstellen des Sockets im Protokollparameter angegeben wurde, sollte mit der Protokollnummer im IP-Header des empfangenen Datagramms übereinstimmen.
    • Wenn eine lokale IP-Adresse für den Socket definiert ist, sollte sie der Zieladresse entsprechen, wie im IP-Header des empfangenen Datagramms angegeben. Eine Anwendung kann die lokale IP-Adresse angeben, indem sie die Bind-Funktion aufruft. Wenn keine lokale IP-Adresse für den Socket angegeben ist, werden die Datagramme unabhängig von der Ziel-IP-Adresse im IP-Header des empfangenen Datagramms in den Socket kopiert.
    • Wenn eine Fremdadresse für den Socket definiert ist, sollte sie der Quelladresse entsprechen, wie im IP-Header des empfangenen Datagramms angegeben. Eine Anwendung kann die Fremd-IP-Adresse angeben, indem sie die Connect- oder WSAConnect-Funktion aufruft. Wenn für den Socket keine Fremd-IP-Adresse angegeben ist, werden die Datagramme unabhängig von der Quell-IP-Adresse im IP-Header des empfangenen Datagramms in den Socket kopiert.

Es ist wichtig zu verstehen, dass einige Sockets vom Typ SOCK _ RAW viele unerwartete Datagramme erhalten können. Beispielsweise kann ein PING-Programm einen Socket vom Typ SOCK _ RAW erstellen, um ICMP-Echoanforderungen zu senden und Antworten zu empfangen. Während die Anwendung ICMP-Echoantworten erwartet, können auch alle anderen ICMP-Nachrichten (z. B. ICMP HOST _ UNREACHABLE) an diese Anwendung übermittelt werden. Wenn außerdem mehrere SOCK _ RAW-Sockets gleichzeitig auf einem Computer geöffnet sind, können dieselben Datagramme an alle offenen Sockets übermittelt werden. Eine Anwendung muss über einen Mechanismus verfügen, um die für Sie interessanten Datagramme zu erkennen und alle anderen zu ignorieren. Bei einem PING-Programm kann ein solcher Mechanismus die Überprüfung des empfangenen IP-Headers auf eindeutige Bezeichner im ICMP-Header (z. B. die Prozess-ID der Anwendung) umfassen.

Hinweis

Für die Verwendung eines Sockets vom Typ SOCK _ RAW sind Administratorrechte erforderlich. Benutzer, die Winsock-Anwendungen ausführen, die Unformatierte Sockets verwenden, müssen Mitglied der Gruppe "Administratoren" auf dem lokalen Computer sein. Andernfalls schlagen Unformatierte Socketaufrufe mit dem Fehlercode WSAEACCESfehl. Auf Windows Vista und höher wird der Zugriff für Unformatierte Sockets bei der Socketerstellung erzwungen. In früheren Versionen von Windows wird der Zugriff für Unformatierte Sockets während anderer Socketvorgänge erzwungen.

Häufige Verwendungsmöglichkeiten von Rohsockets

Eine häufige Verwendung von Unformatierungssockets ist die Problembehandlung von Anwendungen, die IP-Pakete und -Header im Detail untersuchen müssen. Beispielsweise kann ein unformatiertes Socket mit dem SIO RCVALL IOCTL verwendet werden, _ damit ein Socket alle IPv4- oder IPv6-Pakete empfangen kann, die über eine Netzwerkschnittstelle übergeben werden. Weitere Informationen finden Sie in der referenz SIO_RCVALL.

Einschränkungen für Rohdatensockets

In Windows 7, Windows Vista, Windows XP mit Service Pack 2 (SP2) und Windows XP mit Service Pack 3 (SP3) wurde die Möglichkeit zum Senden von Datenverkehr über Unformatierte Sockets auf verschiedene Weise eingeschränkt:

  • TCP-Daten können nicht über Unformatierte Sockets gesendet werden.
  • UDP-Datagramme mit einer ungültigen Quelladresse können nicht über Unformatierte Sockets gesendet werden. Die IP-Quelladresse für ein beliebiges ausgehendes UDP-Datagramm muss auf einer Netzwerkschnittstelle vorhanden sein, oder das Datagramm wird gelöscht. Diese Änderung wurde vorgenommen, um die Fähigkeit von schädlichem Code zum Erstellen verteilter Denial-of-Service-Angriffe einzuschränken und die Möglichkeit zum Senden von gefälschten Paketen (TCP/IP-Pakete mit einer gefälschten Quell-IP-Adresse) einzuschränken.
  • Ein Aufruf der Bind-Funktion mit einem unformatierten Socket für das IPPROTO-TCP-Protokoll _ ist nicht zulässig.

    Hinweis

    Die Bindungsfunktion mit einem unformatierten Socket ist für andere Protokolle zulässig _ (z.B. IPPROTO IP, IPPROTO _ UDP oder IPPROTO _ SCTP).

Diese oben genannten Einschränkungen gelten nicht für Windows Server 2008 R2, Windows Server 2008, Windows Server 2003 oder für Versionen des Betriebssystems vor Windows XP mit SP2.

Hinweis

Die Microsoft-Implementierung von TCP/IP auf Windows kann einen unformatierten UDP- oder TCP-Socket basierend auf den oben genannten Einschränkungen öffnen. Andere Winsock-Anbieter unterstützen möglicherweise nicht die Verwendung von unformatierten Sockets.

Es gibt weitere Einschränkungen für Anwendungen, die einen Socket vom Typ SOCK _ RAW verwenden. Beispielsweise empfangen alle Anwendungen, die auf ein bestimmtes Protokoll lauschen, alle Pakete, die für dieses Protokoll empfangen wurden. Dies ist möglicherweise nicht das Gewünschte für mehrere Anwendungen, die ein Protokoll verwenden. Dies ist auch nicht für Hochleistungsanwendungen geeignet. Um diese Probleme zu umgehen, ist es möglicherweise erforderlich, einen Windows Netzwerkprotokolltreiber (Gerätetreiber) für das spezifische Netzwerkprotokoll zu schreiben. Auf Windows Vista und höher, Winsock Kernel (WSK), kann eine neue transportunabhängige Kernelmodus-Netzwerkprogrammierschnittstelle verwendet werden, um einen Netzwerkprotokolltreiber zu schreiben. Auf Windows Server 2003 und früheren Versionen können ein Transport Driver Interface-Anbieter (TDI) und eine Winsock-Hilfs-DLL geschrieben werden, um das Netzwerkprotokoll zu unterstützen. Das Netzwerkprotokoll wird dann dem Winsock-Katalog als unterstütztes Protokoll hinzugefügt. Dadurch können mehrere Anwendungen Sockets für dieses spezifische Protokoll öffnen, und der Gerätetreiber kann nachverfolgen, welcher Socket bestimmte Pakete und Fehler empfängt. Informationen zum Schreiben eines Netzwerkprotokollanbieters finden Sie in den Abschnitten zu WSK und TDI im Windows Driver Kit (WDK).

Anwendungen müssen auch die Auswirkungen beachten, die Firewalleinstellungen auf das Senden und Empfangen von Paketen mithilfe von Unformatiertocket haben können.