Socket non elaborati TCP/IP

Un socket non elaborato è un tipo di socket che consente l'accesso al provider di trasporto sottostante. Questo argomento è incentrato solo sui socket non elaborati e sui protocolli IPv4 e IPv6. Ciò è dovuto al fatto che la maggior parte degli altri protocolli ad eccezione di ATM non supporta i socket non elaborati. Per usare socket non elaborati, un'applicazione deve avere informazioni dettagliate sul protocollo sottostante in uso.

I provider di servizi Winsock per il protocollo IP possono supportare un tipo di socket di SOCK_RAW. Il provider Windows Sockets 2 per TCP/IP incluso in Windows supporta questo tipo di socket SOCK_RAW .

Esistono due tipi di base di questi socket non elaborati:

  • Il primo tipo usa un tipo di protocollo noto scritto nell'intestazione IP riconosciuto da un provider di servizi Winsock. Un esempio del primo tipo di socket è un socket per il protocollo ICMP (tipo di protocollo IP = 1) o il protocollo ICMPv6 (tipo IP procotol = 58).
  • Il secondo tipo consente di specificare qualsiasi tipo di protocollo. Un esempio del secondo tipo è un protocollo sperimentale che non è supportato direttamente dal provider di servizi Winsock, ad esempio Stream Control Transmission Protocol (SCTP).

Determinare se i socket non elaborati sono supportati

Se un provider di servizi Winsock supporta i socket SOCK_RAW per le famiglie di indirizzi AF_INET o AF_INET6, il tipo di socket di SOCK_RAW deve essere incluso nella struttura WSAPROTOCOL_INFO restituita dalla funzione WSAEnumProtocols per uno o più provider di trasporto disponibili.

Il membro iAddressFamily nella struttura WSAPROTOCOL_INFO deve specificare AF_INET o AF_INET6 e il membro iSocketType della struttura WSAPROTOCOL_INFO deve specificare SOCK_RAW per uno dei provider di trasporto.

Il membro iProtocol della struttura WSAPROTOCOL_INFO può essere impostato su IPROTO_IP. Il membro iProtocol della struttura WSAPROTOCOL_INFO può anche essere impostato su zero se il provider di servizi consente a un'applicazione di usare un tipo di socket SOCK_RAW per altri protocolli di rete diversi dal protocollo Internet per la famiglia di indirizzi.

Gli altri membri nella struttura WSAPROTOCOL_INFO indicano altre proprietà del supporto del protocollo per SOCK_RAW e indicano come deve essere trattato un socket di SOCK_RAW . Questi altri membri del WSAPROTOCOL_INFO per SOCK_RAW specificano in genere che il protocollo è senza connessione, orientato ai messaggi, supporta broadcast/multicast (i XP1_CONNECTIONLESS, XP1_MESSAGE_ORIENTED, XP1_SUPPORT_BROADCAST e i bit XP1_SUPPORT_MULTIPOINT sono impostati nel membro dwServiceFlags1) e possono avere una dimensione massima del messaggio di 65.467 byte.

In Windows XP e versioni successive è possibile usare il comando NetSh.exe per determinare se sono supportati socket non elaborati. Il comando seguente eseguito da una finestra CMD visualizzerà i dati del catalogo Winsock nella console:

netsh winsock show catalog

L'output includerà un elenco contenente alcuni dei dati delle strutture di WSAPROTOCOL_INFO supportate nel computer locale. Cercare il termine RAW/IP o RAW/IPv6 nel campo Descrizione per trovare i protocolli che supportano socket non elaborati.

Creazione di un socket non elaborato

Per creare un socket di tipo SOCK_RAW, chiamare la funzione socket o WSASocket con il parametro af (famiglia di indirizzi) impostato su AF_INET o AF_INET6, il parametro di tipo impostato su SOCK_RAW e il parametro del protocollo impostato sul numero di protocollo richiesto. Il parametro del protocollo diventa il valore del protocollo nell'intestazione IP (SCTP, ad esempio, è 132).

Nota

Un'applicazione potrebbe non specificare zero (0) come parametro di protocollo per il socket, WSASocket e WSPSocket se il parametro di tipo è impostato su SOCK_RAW.

 

I socket non elaborati offrono la possibilità di modificare il trasporto sottostante, in modo che possano essere usati per scopi dannosi che rappresentano una minaccia per la sicurezza. Pertanto, solo i membri del gruppo Administrators possono creare socket di tipo SOCK_RAW in Windows 2000 e versioni successive.

Operazioni di invio e ricezione

Dopo che un'applicazione crea un socket di tipo SOCK_RAW, questo socket può essere usato per inviare e ricevere dati. Tutti i pacchetti inviati o ricevuti su un socket di tipo SOCK_RAW vengono considerati come datagrammi in un socket non connesso.

Le regole seguenti si applicano alle operazioni su SOCK_RAW socket:

  • La funzione sendto o WSASendTo viene in genere usata per inviare dati su un socket di tipo SOCK_RAW. L'indirizzo di destinazione può essere qualsiasi indirizzo valido nella famiglia di indirizzi del socket, incluso un indirizzo broadcast o multicast. Per inviare a un indirizzo broadcast, è necessario che un'applicazione abbia usato setsockopt con SO_BROADCAST abilitato. In caso contrario, sendto o WSASendTo avrà esito negativo con il codice di errore WSAEACCES. Per IP, un'applicazione può inviare a qualsiasi indirizzo multicast (senza diventare un membro del gruppo).

  • Quando si inviano dati IPv4, un'applicazione può scegliere se specificare l'intestazione IPv4 all'inizio del datagram in uscita per il pacchetto. Se l'opzione socket IP_HDRINCL è impostata su true per un socket IPv4 (famiglia di indirizzi di AF_INET), l'applicazione deve fornire l'intestazione IPv4 nei dati in uscita per le operazioni di invio. Se questa opzione socket è false (impostazione predefinita), l'intestazione IPv4 non deve essere inclusa nei dati in uscita per le operazioni di invio.

  • Quando si inviano dati IPv6, un'applicazione può scegliere se specificare l'intestazione IPv6 all'inizio del datagram in uscita per il pacchetto. Se l'opzione socket IPV6_HDRINCL è impostata su true per un socket IPv6 (famiglia di indirizzi di AF_INET6), l'applicazione deve fornire l'intestazione IPv6 nei dati in uscita per le operazioni di invio. L'impostazione predefinita per questa opzione è false. Se questa opzione socket è false (impostazione predefinita), l'intestazione IPv6 non deve essere inclusa nei dati in uscita per le operazioni di invio. Per IPv6, non è necessario includere l'intestazione IPv6. Se le informazioni sono disponibili usando le funzioni socket, l'intestazione IPv6 non deve essere inclusa per evitare problemi di compatibilità in futuro. Questi problemi sono descritti in RFC 3542 pubblicato da IETF. L'uso dell'opzione socket IPV6_HDRINCL non è consigliato e potrebbe essere deprecato in futuro.

  • La funzione recvfrom o WSARecvFrom viene in genere usata per ricevere dati su un socket di tipo SOCK_RAW. Entrambe queste funzioni hanno un'opzione per restituire l'indirizzo IP di origine da cui è stato inviato il pacchetto. I dati ricevuti sono un datagramma da un socket non connesso.

  • Per IPv4 (famiglia di indirizzi di AF_INET), un'applicazione riceve l'intestazione IP nella parte anteriore di ogni datagramma ricevuto indipendentemente dall'opzione socket IP_HDRINCL .

  • Per IPv6 (famiglia di indirizzi di AF_INET6), un'applicazione riceve tutti gli elementi dopo l'ultima intestazione IPv6 in ogni datagramma ricevuto indipendentemente dall'opzione socket IPV6_HDRINCL . L'applicazione non riceve intestazioni IPv6 usando un socket non elaborato.

  • I datagrammi ricevuti vengono copiati in tutti i socket SOCK_RAW che soddisfano le condizioni seguenti:

    • Il numero di protocollo specificato nel parametro del protocollo al momento della creazione del socket deve corrispondere al numero di protocollo nell'intestazione IP dell'oggetto datagram ricevuto.
    • Se per il socket è definito un indirizzo IP locale, deve corrispondere all'indirizzo di destinazione come specificato nell'intestazione IP del datagram ricevuto. Un'applicazione può specificare l'indirizzo IP locale chiamando la funzione di associazione . Se non viene specificato alcun indirizzo IP locale per il socket, i datagrammi vengono copiati nel socket indipendentemente dall'indirizzo IP di destinazione nell'intestazione IP del datagram ricevuto.
    • Se per il socket è definito un indirizzo esterno, deve corrispondere all'indirizzo di origine come specificato nell'intestazione IP del datagramma ricevuto. Un'applicazione può specificare l'indirizzo IP esterno chiamando la funzione connect o WSAConnect . Se non viene specificato alcun indirizzo IP esterno per il socket, i datagrammi vengono copiati nel socket indipendentemente dall'indirizzo IP di origine nell'intestazione IP del datagram ricevuto.

È importante comprendere che alcuni socket di tipo SOCK_RAW possono ricevere molti datagrammi imprevisti. Ad esempio, un programma PING può creare un socket di tipo SOCK_RAW per inviare richieste echo ICMP e ricevere risposte. Anche se l'applicazione prevede risposte echo ICMP, anche tutti gli altri messaggi ICMP (ad esempio ICMP HOST_UNREACHABLE) possono essere recapitati a questa applicazione. Inoltre, se più socket SOCK_RAW sono aperti in un computer contemporaneamente, gli stessi datagrammi possono essere recapitati a tutti i socket aperti. Un'applicazione deve avere un meccanismo per riconoscere i datagrammi di interesse e ignorare tutti gli altri. Per un programma PING, tale meccanismo potrebbe includere l'ispezione dell'intestazione IP ricevuta per gli identificatori univoci nell'intestazione ICMP (ad esempio, l'ID del processo dell'applicazione).

Nota

Per usare un socket di tipo SOCK_RAW richiede privilegi amministrativi. Gli utenti che eseguono applicazioni Winsock che usano socket non elaborati devono essere membri del gruppo Administrators nel computer locale. In caso contrario, le chiamate socket non elaborate avranno esito negativo con un codice di errore WSAEACCES. In Windows Vista e versioni successive, l'accesso ai socket non elaborati viene applicato al momento della creazione del socket. Nelle versioni precedenti di Windows, l'accesso ai socket non elaborati viene applicato durante altre operazioni socket.

 

Usi comuni dei socket non elaborati

Un uso comune dei socket non elaborati è la risoluzione dei problemi delle applicazioni che devono esaminare in dettaglio pacchetti e intestazioni IP. Ad esempio, un socket non elaborato può essere usato con il SIO_RCVALL IOCTL per consentire a un socket di ricevere tutti i pacchetti IPv4 o IPv6 che passano attraverso un'interfaccia di rete. Per altre informazioni, vedere le informazioni di riferimento sul SIO_RCVALL .

Limitazioni dei socket non elaborati

In Windows 7, Windows Vista, Windows XP con Service Pack 2 (SP2) e Windows XP con Service Pack 3 (SP3), la possibilità di inviare traffico su socket non elaborati è stata limitata in diversi modi:

  • I dati TCP non possono essere inviati tramite socket non elaborati.

  • I datagrammi UDP con un indirizzo di origine non valido non possono essere inviati tramite socket non elaborati. L'indirizzo di origine IP per qualsiasi datagramma UDP in uscita deve esistere in un'interfaccia di rete oppure il datagramma viene eliminato. Questa modifica è stata apportata per limitare la capacità di codice dannoso di creare attacchi Denial of Service distribuiti e limitare la possibilità di inviare pacchetti di spoofing (pacchetti TCP/IP con un indirizzo IP di origine contraffatto).

  • Non è consentita una chiamata alla funzione di associazione con un socket non elaborato per il protocollo IPPROTO_TCP.

    Nota

    La funzione di associazione con un socket non elaborato è consentita per altri protocolli (ad esempio, IPPROTO_IP, IPPROTO_UDP o IPPROTO_SCTP).

     

Queste restrizioni precedenti non si applicano a Windows Server 2008 R2, Windows Server 2008 , Windows Server 2003 o alle versioni del sistema operativo precedenti a Windows XP con SP2.

Nota

L'implementazione Microsoft di TCP/IP in Windows è in grado di aprire un socket UDP o TCP non elaborato in base alle restrizioni precedenti. Altri provider Winsock potrebbero non supportare l'uso di socket non elaborati.

 

Esistono ulteriori limitazioni per le applicazioni che usano un socket di tipo SOCK_RAW. Ad esempio, tutte le applicazioni in ascolto di un protocollo specifico riceveranno tutti i pacchetti ricevuti per questo protocollo. Questo potrebbe non essere quello desiderato per più applicazioni che usano un protocollo. Questo non è adatto anche per applicazioni ad alte prestazioni. Per risolvere questi problemi, potrebbe essere necessario scrivere un driver di protocollo di rete Windows (driver di dispositivo) per il protocollo di rete specifico. In Windows Vista e versioni successive, Winsock Kernel (WSK), è possibile usare una nuova interfaccia di programmazione della programmazione di rete indipendente dal trasporto per scrivere un driver di protocollo di rete. In Windows Server 2003 e versioni precedenti, è possibile scrivere una DLL helper Winsock per supportare il protocollo di rete. Il protocollo di rete verrà quindi aggiunto al catalogo Winsock come protocollo supportato. Ciò consente a più applicazioni di aprire socket per questo protocollo specifico e il driver del dispositivo può tenere traccia di quali socket ricevono pacchetti e errori specifici. Per informazioni sulla scrittura di un provider di protocolli di rete, vedere le sezioni su WSK e TDI nel Kit driver windows (WDK).

Le applicazioni devono essere consapevoli anche dell'impatto che le impostazioni del firewall potrebbero avere sull'invio e la ricezione di pacchetti usando socket non elaborati.