Compartir a través de


Sockets sin formato TCP/IP

Un socket sin formato es un tipo de socket que permite el acceso al proveedor de transporte subyacente. Este tema se centra solo en sockets sin procesar y los protocolos IPv4 e IPv6. Esto se debe a que la mayoría de los demás protocolos con la excepción de ATM no admiten sockets sin procesar. Para usar sockets sin procesar, una aplicación debe tener información detallada sobre el protocolo subyacente que se usa.

Los proveedores de servicios winsock para el protocolo IP pueden admitir un tipo de socket de SOCK_RAW. El proveedor de Windows Sockets 2 para TCP/IP incluido en Windows admite este tipo de socket SOCK_RAW .

Hay dos tipos básicos de estos sockets sin procesar:

  • El primer tipo usa un tipo de protocolo conocido escrito en el encabezado IP reconocido por un proveedor de servicios winsock. Un ejemplo del primer tipo de socket es un socket para el protocolo ICMP (tipo de protocolo IP = 1) o el protocolo ICMPv6 (tipo de procotol IP = 58).
  • El segundo tipo permite especificar cualquier tipo de protocolo. Un ejemplo del segundo tipo sería un protocolo experimental que no es compatible directamente con el proveedor de servicios Winsock, como el Protocolo de transmisión de control de secuencias (SCTP).

Determinar si se admiten sockets sin formato

Si un proveedor de servicios winsock admite sockets SOCK_RAW para las familias de direcciones AF_INET o AF_INET6, el tipo de socket de SOCK_RAW debe incluirse en la estructura de WSAPROTOCOL_INFO devuelta por la función WSAEnumProtocols para uno o varios de los proveedores de transporte disponibles.

El miembro iAddressFamily de la estructura WSAPROTOCOL_INFO debe especificar AF_INET o AF_INET6 y el miembro iSocketType de la estructura WSAPROTOCOL_INFO debe especificar SOCK_RAW para uno de los proveedores de transporte.

El miembro iProtocol de la estructura WSAPROTOCOL_INFO se puede establecer en IPROTO_IP. El miembro iProtocol de la estructura de WSAPROTOCOL_INFO también puede establecerse en cero si el proveedor de servicios permite a una aplicación usar un tipo de socket SOCK_RAW para otros protocolos de red distintos del Protocolo de Internet para la familia de direcciones.

Los demás miembros de la estructura WSAPROTOCOL_INFO indican otras propiedades de la compatibilidad del protocolo para SOCK_RAW e indican cómo se debe tratar un socket de SOCK_RAW . Estos otros miembros del WSAPROTOCOL_INFO para SOCK_RAW normalmente especifican que el protocolo no tiene conexión, orientado a mensajes, admite difusión y multidifusión (el XP1_CONNECTIONLESS, XP1_MESSAGE_ORIENTED, XP1_SUPPORT_BROADCAST y XP1_SUPPORT_MULTIPOINT bits se establecen en el miembro dwServiceFlags1) y puede tener un tamaño máximo de mensaje de 65 467 bytes.

En Windows XP y versiones posteriores, se puede usar el comando NetSh.exe para determinar si se admiten sockets sin formato. El comando siguiente que se ejecuta desde una ventana de CMD mostrará datos del catálogo winsock en la consola:

netsh winsock show catalog

La salida incluirá una lista que contiene algunos de los datos de las estructuras de WSAPROTOCOL_INFO compatibles con el equipo local. Busque el término RAW/IP o RAW/IPv6 en el campo Descripción para buscar los protocolos que admiten sockets sin procesar.

Creación de un socket sin formato

Para crear un socket de tipo SOCK_RAW, llame a la función socket o WSASocket con el parámetro af (familia de direcciones) establecido en AF_INET o AF_INET6, el parámetro type establecido en SOCK_RAW y el parámetro de protocolo establecido en el número de protocolo necesario. El parámetro protocol se convierte en el valor del protocolo en el encabezado IP (SCTP es 132, por ejemplo).

Nota

Es posible que una aplicación no especifique cero (0) como parámetro de protocolo para las funciones socket, WSASocket y WSPSocket si el parámetro de tipo está establecido en SOCK_RAW.

 

Los sockets sin procesar ofrecen la capacidad de manipular el transporte subyacente, por lo que se pueden usar con fines malintencionados que suponen una amenaza de seguridad. Por lo tanto, solo los miembros del grupo Administradores pueden crear sockets de tipo SOCK_RAW en Windows 2000 y versiones posteriores.

Operaciones de envío y recepción

Una vez que una aplicación crea un socket de tipo SOCK_RAW, este socket se puede usar para enviar y recibir datos. Todos los paquetes enviados o recibidos en un socket de tipo SOCK_RAW se tratan como datagramas en un socket no conectado.

Las reglas siguientes se aplican a las operaciones en SOCK_RAW sockets:

  • Normalmente, la función sendto o WSASendTo se usa para enviar datos en un socket de tipo SOCK_RAW. La dirección de destino puede ser cualquier dirección válida de la familia de direcciones del socket, incluida una dirección de difusión o multidifusión. Para enviar a una dirección de difusión, una aplicación debe haber usado setsockopt con SO_BROADCAST habilitado. De lo contrario, se producirá un error en sendto o WSASendTo con el código de error WSAEACCES. En el caso de ip, una aplicación puede enviar a cualquier dirección de multidifusión (sin convertirse en miembro del grupo).

  • Al enviar datos IPv4, una aplicación tiene la opción de especificar el encabezado IPv4 en la parte delantera del datagrama saliente para el paquete. Si la opción de socket IP_HDRINCL se establece en true para un socket IPv4 (familia de direcciones de AF_INET), la aplicación debe proporcionar el encabezado IPv4 en los datos salientes para las operaciones de envío. Si esta opción de socket es false (la configuración predeterminada), el encabezado IPv4 no debe estar incluido en los datos salientes para las operaciones de envío.

  • Al enviar datos IPv6, una aplicación tiene la opción de especificar el encabezado IPv6 delante del datagrama saliente para el paquete. Si la opción de socket IPV6_HDRINCL se establece en true para un socket IPv6 (familia de direcciones de AF_INET6), la aplicación debe proporcionar el encabezado IPv6 en los datos salientes para las operaciones de envío. La configuración predeterminada para esta opción es false. Si esta opción de socket es false (la configuración predeterminada), el encabezado IPv6 no debe incluirse en los datos salientes para las operaciones de envío. Para IPv6, no debe haber necesidad de incluir el encabezado IPv6. Si la información está disponible mediante funciones de socket, el encabezado IPv6 no debe incluirse para evitar problemas de compatibilidad en el futuro. Estos problemas se tratan en RFC 3542 publicado por el IETF. No se recomienda usar la opción de socket IPV6_HDRINCL y puede quedar en desuso en el futuro.

  • Normalmente, la función recvfrom o WSARecvFrom se usa para recibir datos en un socket de tipo SOCK_RAW. Ambas funciones tienen una opción para devolver la dirección IP de origen desde la que se envió el paquete. Los datos recibidos son un datagrama de un socket no conectado.

  • Para IPv4 (familia de direcciones de AF_INET), una aplicación recibe el encabezado IP delante de cada datagrama recibido independientemente de la opción de socket IP_HDRINCL .

  • Para IPv6 (familia de direcciones de AF_INET6), una aplicación recibe todo después del último encabezado IPv6 de cada datagrama recibido independientemente de la opción de socket IPV6_HDRINCL . La aplicación no recibe ningún encabezado IPv6 mediante un socket sin formato.

  • Los datagramas recibidos se copian en todos los sockets SOCK_RAW que cumplen las condiciones siguientes:

    • El número de protocolo especificado en el parámetro de protocolo cuando se creó el socket debe coincidir con el número de protocolo en el encabezado IP del datagrama recibido.
    • Si se define una dirección IP local para el socket, debe corresponder a la dirección de destino tal como se especifica en el encabezado IP del datagrama recibido. Una aplicación puede especificar la dirección IP local llamando a la función de enlace . Si no se especifica ninguna dirección IP local para el socket, los datagramas se copian en el socket independientemente de la dirección IP de destino en el encabezado IP del datagrama recibido.
    • Si se define una dirección externa para el socket, debe corresponder a la dirección de origen tal como se especifica en el encabezado IP del datagrama recibido. Una aplicación puede especificar la dirección IP externa llamando a la función connect o WSAConnect . Si no se especifica ninguna dirección IP externa para el socket, los datagramas se copian en el socket independientemente de la dirección IP de origen en el encabezado IP del datagrama recibido.

Es importante comprender que algunos sockets de tipo SOCK_RAW pueden recibir muchos datagramas inesperados. Por ejemplo, un programa PING puede crear un socket de tipo SOCK_RAW para enviar solicitudes de eco ICMP y recibir respuestas. Aunque la aplicación espera respuestas de eco ICMP, también se pueden entregar a esta aplicación todos los demás mensajes ICMP (como ICMP HOST_UNREACHABLE). Además, si varios sockets de SOCK_RAW están abiertos en un equipo al mismo tiempo, se pueden entregar los mismos datagramas a todos los sockets abiertos. Una aplicación debe tener un mecanismo para reconocer los datagramas de interés y omitir todos los demás. Para un programa PING, este mecanismo puede incluir inspeccionar el encabezado IP recibido para los identificadores únicos en el encabezado ICMP (el identificador de proceso de la aplicación, por ejemplo).

Nota

Para usar un socket de tipo SOCK_RAW requiere privilegios administrativos. Los usuarios que ejecutan aplicaciones winsock que usan sockets sin procesar deben ser miembros del grupo Administradores en el equipo local; de lo contrario, se producirá un error en las llamadas de socket sin procesar con un código de error de WSAEACCES. En Windows Vista y versiones posteriores, el acceso a sockets sin procesar se aplica en la creación de sockets. En versiones anteriores de Windows, se aplica el acceso a sockets sin procesar durante otras operaciones de socket.

 

Usos comunes de sockets sin formato

Un uso común de sockets sin formato son las aplicaciones de solución de problemas que necesitan examinar los paquetes IP y los encabezados con detalle. Por ejemplo, se puede usar un socket sin formato con el SIO_RCVALL IOCTL para permitir que un socket reciba todos los paquetes IPv4 o IPv6 que pasan a través de una interfaz de red. Para obtener más información, consulte la referencia de SIO_RCVALL .

Limitaciones en sockets sin formato

En Windows 7, Windows Vista, Windows XP con Service Pack 2 (SP2) y Windows XP con Service Pack 3 (SP3), la capacidad de enviar tráfico a través de sockets sin procesar se ha restringido de varias maneras:

  • Los datos TCP no se pueden enviar a través de sockets sin procesar.

  • Los datagramas UDP con una dirección de origen no válida no se pueden enviar a través de sockets sin procesar. La dirección de origen IP de cualquier datagrama UDP saliente debe existir en una interfaz de red o se quita el datagrama. Este cambio se realizó para limitar la capacidad de código malintencionado para crear ataques de denegación de servicio distribuidos y limita la capacidad de enviar paquetes suplantados (paquetes TCP/IP con una dirección IP de origen falsificada).

  • No se permite una llamada a la función de enlace con un socket sin formato para el protocolo IPPROTO_TCP.

    Nota

    La función bind con un socket sin formato se permite para otros protocolos (IPPROTO_IP, IPPROTO_UDP o IPPROTO_SCTP, por ejemplo).

     

Estas restricciones anteriores no se aplican a Windows Server 2008 R2, Windows Server 2008 , Windows Server 2003 o a versiones del sistema operativo anteriores a Windows XP con SP2.

Nota

La implementación de Microsoft de TCP/IP en Windows es capaz de abrir un socket UDP o TCP sin procesar en función de las restricciones anteriores. Es posible que otros proveedores de Winsock no admitan el uso de sockets sin procesar.

 

Hay más limitaciones para las aplicaciones que usan un socket de tipo SOCK_RAW. Por ejemplo, todas las aplicaciones que escuchan un protocolo específico recibirán todos los paquetes recibidos para este protocolo. Esto puede no ser lo que se desea para varias aplicaciones mediante un protocolo. Esto tampoco es adecuado para aplicaciones de alto rendimiento. Para solucionar estos problemas, es posible que sea necesario escribir un controlador de protocolo de red (controlador de dispositivo) de Windows para el protocolo de red específico. En Windows Vista y versiones posteriores, se puede usar el kernel winsock (WSK), una nueva interfaz de programación de red del modo kernel independiente del transporte para escribir un controlador de protocolo de red. En Windows Server 2003 y versiones anteriores, se puede escribir un proveedor de interfaz de controlador de transporte (TDI) y un archivo DLL auxiliar winsock para admitir el protocolo de red. A continuación, el protocolo de red se agregaría al catálogo winsock como protocolo admitido. Esto permite que varias aplicaciones abran sockets para este protocolo específico y el controlador de dispositivo puede realizar un seguimiento de qué socket recibe paquetes y errores específicos. Para obtener información sobre cómo escribir un proveedor de protocolos de red, consulta las secciones de WSK y TDI en el Kit de controladores de Windows (WDK).

Las aplicaciones también deben tener en cuenta el impacto que la configuración del firewall puede tener al enviar y recibir paquetes mediante sockets sin procesar.