TCP/IP rohe Sockets
Ein unformatierter Socket ist ein Sockettyp, der den Zugriff auf den zugrunde liegenden Transportanbieter ermöglicht. Dieses Thema konzentriert sich nur auf rohe Sockets und die IPv4- und IPv6-Protokolle. Dies liegt daran, dass die meisten anderen Protokolle mit Ausnahme von ATM keine unformatierten Sockets unterstützen. Um rohe Sockets zu verwenden, muss eine Anwendung detaillierte Informationen zum verwendeten zugrunde liegenden Protokoll enthalten.
Winsock-Dienstanbieter für das IP-Protokoll unterstützen möglicherweise einen Socket-Typ von SOCK_RAW. Der in Windows enthaltene Windows Sockets 2-Anbieter für TCP/IP 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 wurde, der 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 type = 58).
- Mit dem zweiten Typ kann ein beliebiger Protokolltyp angegeben werden. Ein Beispiel für den zweiten Typ wäre ein experimentelles Protokoll, das nicht direkt vom Winsock-Dienstanbieter unterstützt wird, z. B. das Stream Control Transmission Protocol (SCTP).
Ermitteln, ob Unformatierte Sockets unterstützt werden
Wenn ein Winsock-Dienstanbieter SOCK_RAW Sockets für die AF_INET- oder AF_INET6 Adressfamilien unterstützt, sollte der Sockettyp der SOCK_RAW in der WSAPROTOCOL_INFO Struktur enthalten sein, die von WSAEnumProtocols Funktion für einen oder mehrere der verfügbaren Transportanbieter zurückgegeben wird.
Das iAddressFamily Mitglied in der WSAPROTOCOL_INFO-Struktur sollte AF_INET oder AF_INET6 angeben, und das iSocketType- Mitglied der WSAPROTOCOL_INFO-Struktur sollte SOCK_RAW für einen der Transportanbieter angeben.
Das iProtocol- Mitglied der WSAPROTOCOL_INFO-Struktur kann auf IPROTO_IPfestgelegt werden. Das iProtocol- Mitglied der WSAPROTOCOL_INFO-Struktur kann auch auf Null festgelegt werden, wenn der Dienstanbieter einer Anwendung die Verwendung eines SOCK_RAW Sockettyps für andere Netzwerkprotokolle außer dem Internetprotokoll für die Adressfamilie zulässt.
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 der WSAPROTOCOL_INFO für SOCK_RAW normalerweise angeben, dass das Protokoll verbindungslos, nachrichtenorientiert ist, Broadcast/Multicast unterstützt (die XP1_CONNECTIONLESS, XP1_MESSAGE_ORIENTED, XP1_SUPPORT_BROADCAST und XP1_SUPPORT_MULTIPOINT Bits werden im dwServiceFlags1-Element festgelegt) und kann eine maximale Nachrichtengröße von 65.467 Byte aufweisen.
Unter Windows XP und höher kann mit dem Befehl NetSh.exe ermittelt werden, ob rohe Sockets unterstützt werden. Der folgende Befehl aus einem CMD-Fenster zeigt Daten aus dem Winsock-Katalog auf der Konsole an:
netsh winsock katalog-
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_RAWzu erstellen, rufen Sie den Socket oder WSASocket--Funktion auf, wobei der af-Parameter (Adressfamilie) auf AF_INET oder AF_INET6 festgelegt ist, der Typ Parameter auf SOCK_RAWfestgelegt ist, und der Protokollparameter, der auf die erforderliche Protokollnummer festgelegt ist. Der protokoll Parameter wird zum Protokollwert im IP-Header (z. B. SCTP ist 132).
Anmerkung
Eine Anwendung darf null (0) nicht als Protokollparameter Parameter für den Socket-, WSASocket-und WSPSocket- Funktionen angeben, wenn der Typ Parameter auf SOCK_RAWfestgelegt 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 Sicherheitsrisiken darstellen. Daher können nur Mitglieder der Gruppe "Administratoren" Sockets vom Typ SOCK_RAW unter Windows 2000 und höher erstellen.
Sende- und Empfangsvorgänge
Sobald eine Anwendung einen Socket vom Typ SOCK_RAWerstellt, kann dieser Socket zum Senden und Empfangen von Daten verwendet werden. Alle Pakete, die in einem Socket vom Typ SOCK_RAW gesendet oder empfangen werden, werden als Datagramme in einem nicht verbundenen Socket behandelt.
Die folgenden Regeln gelten für die Vorgänge über SOCK_RAW Sockets:
Die funktion sendto oder WSASendTo wird normalerweise verwendet, um Daten in einem Socket vom Typ SOCK_RAWzu 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 Übertragungsadresse muss eine Anwendung setockopt- verwendet haben, wobei SO_BROADCAST aktiviert ist. Andernfalls schlägt sendto oder WSASendTo mit dem Fehlercode WSAEACCESfehl. Für IP kann eine Anwendung an eine beliebige Multicastadresse (ohne Gruppenmitglied zu werden) senden.
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 angeben. Wenn diese Socketoption "false" ist (Standardeinstellung), sollte der IPv4-Header nicht in die ausgehenden Daten für Sendevorgänge einbezogen 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 angeben. 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 einbezogen werden. Für IPv6 sollte der IPv6-Header nicht eingeschlossen werden. Wenn Informationen mithilfe von Socketfunktionen verfügbar sind, sollte der IPv6-Header nicht einbezogen werden, um Kompatibilitätsprobleme in Zukunft zu vermeiden. Diese Probleme werden in RFC 3542 von der IETF veröffentlicht. Die Verwendung der IPV6_HDRINCL Socketoption wird nicht empfohlen und ist in Zukunft möglicherweise veraltet.
Die funktion recvfrom oder WSARecvFrom wird normalerweise verwendet, um Daten in einem Socket vom Typ SOCK_RAWzu empfangen. Beide Funktionen haben die Möglichkeit, die QUELL-IP-Adresse zurückzugeben, von der das Paket gesendet wurde. Die empfangenen Daten sind ein Datagramm aus einem nicht verbundenen Socket.
Für IPv4 (Adressfamilie von AF_INET) empfängt eine Anwendung unabhängig von der IP_HDRINCL Socketoption den IP-Header am Anfang jedes empfangenen Datagramms.
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 mit einem unformatierten Socket.
Empfangene Datagramme werden in alle SOCK_RAW Sockets kopiert, die die folgenden Bedingungen erfüllen:
- Die im Protokoll Parameter angegebene Protokollnummer 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 Bindung Funktion aufruft. Wenn für den Socket keine lokale IP-Adresse 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 fremde IP-Adresse angeben, indem sie die connect oder WSAConnect--Funktion aufruft. Wenn keine fremde IP-Adresse für den Socket angegeben wird, 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 möglicherweise viele unerwartete Datagramme erhalten. 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 geöffneten Sockets übermittelt werden. Eine Anwendung muss über einen Mechanismus verfügen, um die datengramme von Interesse zu erkennen und alle anderen zu ignorieren. Bei einem PING-Programm kann ein solcher Mechanismus das Überprüfen des empfangenen IP-Headers auf eindeutige IDs im ICMP-Header (z. B. die Prozess-ID der Anwendung) umfassen.
Anmerkung
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 treten unformatierte Socketaufrufe mit einem Fehlercode von WSAEACCESauf. Unter Windows Vista und höher wird der Zugriff auf unformatierte Sockets bei der Socketerstellung erzwungen. In früheren Versionen von Windows wird der Zugriff auf unformatierte Sockets während anderer Socketvorgänge erzwungen.
Allgemeine Verwendung von Rohsockets
Eine häufige Verwendung von unformatierten Sockets ist die Problembehandlung von Anwendungen, die IP-Pakete und Header detailliert untersuchen müssen. Beispielsweise kann ein unformatierter Socket mit dem SIO_RCVALL IOCTL verwendet werden, um einen Socket zu ermöglichen, alle IPv4- oder IPv6-Pakete zu empfangen, die über eine Netzwerkschnittstelle übergeben werden. Weitere Informationen finden Sie in der SIO_RCVALL Referenz.
Einschränkungen für Unformatierte Sockets
Unter Windows 7, Windows Vista, Windows XP mit Service Pack 2 (SP2) und Windows XP mit Service Pack 3 (SP3) wurde die Möglichkeit, Datenverkehr über unformatierte Sockets zu senden, auf verschiedene Arten 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 alle ausgehenden UDP-Datagramme muss auf einer Netzwerkschnittstelle vorhanden sein, oder das Datagramm wird gelöscht. Diese Änderung wurde vorgenommen, um die Fähigkeit von bösartigem Code zu beschränken, verteilte Denial-of-Service-Angriffe zu erstellen und die Möglichkeit, gefälschte Pakete (TCP/IP-Pakete mit einer gefälschten Quell-IP-Adresse) zu senden.
Ein Aufruf der Bindung Funktion mit einem unformatierten Socket für das IPPROTO_TCP-Protokoll ist nicht zulässig.
Anmerkung
Die Bindung Funktion 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, die älter als Windows XP mit SP2 sind.
Anmerkung
Die Microsoft-Implementierung von TCP/IP unter Windows ist in der Lage, einen unformatierten UDP- oder TCP-Socket basierend auf den oben genannten Einschränkungen zu öffnen. Andere Winsock-Anbieter unterstützen möglicherweise nicht die Verwendung von rohen Sockets.
Es gibt weitere Einschränkungen für Anwendungen, die einen Socket vom Typ SOCK_RAWverwenden. Beispielsweise erhalten alle Anwendungen, die auf ein bestimmtes Protokoll lauschen, alle Pakete, die für dieses Protokoll empfangen werden. Dies kann für mehrere Anwendungen mit einem Protokoll nicht gewünscht werden. Dies eignet sich auch nicht für hochleistungsfähige Anwendungen. Um diese Probleme zu umgehen, muss möglicherweise ein Windows-Netzwerkprotokolltreiber (Gerätetreiber) für das spezifische Netzwerkprotokoll geschrieben werden. Unter Windows Vista und höher kann Winsock Kernel (WSK) eine neue transportunabhängige Kernelmodus-Netzwerkprogrammierschnittstelle zum Schreiben eines Netzwerkprotokolltreibers verwendet werden. Unter Windows Server 2003 und früheren Versionen kann ein TDI-Anbieter (Transport Driver Interface) 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. Auf diese Weise 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 kennen, die die Firewalleinstellungen möglicherweise auf das Senden und Empfangen von Paketen mit unformatierten Sockets haben.