Необработанные сокеты TCP/IP

Необработанный сокет — это тип сокета, который обеспечивает доступ к базовому поставщику транспорта. В этом разделе рассматриваются только необработанные сокеты и протоколы IPv4 и IPv6. Это связано с тем, что большинство других протоколов, за исключением ATM, не поддерживают необработанные сокеты. Чтобы использовать необработанные сокеты, приложение должно иметь подробные сведения об используемом базовом протоколе.

Поставщики служб Winsock для протокола IP могут поддерживать типсокета SOCK_RAW. Поставщик Сокетов Windows 2 для TCP/IP, включенный в Windows, поддерживает этот тип сокета SOCK_RAW .

Существует два основных типа таких необработанных сокетов:

  • Первый тип использует известный тип протокола, записанный в ip-заголовок, который распознается поставщиком служб Winsock. Примером первого типа сокета является сокет для протокола ICMP (тип протокола IP = 1) или протокола ICMPv6 (ip procotol type = 58).
  • Второй тип позволяет указать любой тип протокола. Примером второго типа может служить экспериментальный протокол, который напрямую не поддерживается поставщиком услуг Winsock, например протоколом передачи управления потоком (SCTP).

Определение поддержки необработанных сокетов

Если поставщик службы Winsock поддерживает SOCK_RAW сокеты для семейств адресов AF_INET или AF_INET6, тип сокета SOCK_RAW должен быть включен в структуру WSAPROTOCOL_INFO , возвращаемую функцией WSAEnumProtocols для одного или нескольких доступных поставщиков транспорта.

Элемент iAddressFamily в структуре WSAPROTOCOL_INFO должен указывать AF_INET или AF_INET6, а элемент iSocketType структуры WSAPROTOCOL_INFO должен указывать SOCK_RAW для одного из поставщиков транспорта.

Элемент iProtocol структуры WSAPROTOCOL_INFO может иметь значение IPROTO_IP. Член iProtocolструктуры WSAPROTOCOL_INFO также может быть равен нулю, если поставщик услуг разрешает приложению использовать тип сокета SOCK_RAW для других сетевых протоколов, отличных от интернет-протокола для семейства адресов.

Другие члены структуры WSAPROTOCOL_INFO указывают другие свойства протокола, поддерживающего SOCK_RAW , и указывают, как следует обрабатывать сокет SOCK_RAW . Эти другие члены WSAPROTOCOL_INFO для SOCK_RAW обычно указывают, что протокол не подключен, ориентирован на сообщения, поддерживает широковещательную и многоадресную рассылку (XP1_CONNECTIONLESS, XP1_MESSAGE_ORIENTED, XP1_SUPPORT_BROADCAST и XP1_SUPPORT_MULTIPOINT биты заданы в элементе dwServiceFlags1) и может иметь максимальный размер сообщения 65 467 байт.

В Windows XP и более поздних версиях можно использовать команду NetSh.exe , чтобы определить, поддерживаются ли необработанные сокеты. Следующая команда, выполняемая в окне CMD, отобразит данные из каталога Winsock на консоли:

netsh winsock show catalog

Выходные данные будут содержать список, содержащий некоторые данные из WSAPROTOCOL_INFO структур, поддерживаемых на локальном компьютере. Найдите термин RAW/IP или RAW/IPv6 в поле Описание, чтобы найти протоколы, поддерживающие необработанные сокеты.

Создание необработанного сокета

Чтобы создать сокет типа SOCK_RAW, вызовите функцию сокета или WSASocket с параметром af (семейство адресов), для которых задано значение AF_INET или AF_INET6, для параметра типазадано значение SOCK_RAW, а для параметра протокола — требуемый номер протокола. Параметр протокола становится значением протокола в заголовке IP (например, SCTP — 132).

Примечание

Приложение не может указывать ноль (0) в качестве параметра протокола для функций сокета, WSASocket и WSPSocket , если для параметра type задано значение SOCK_RAW.

 

Необработанные сокеты позволяют управлять базовым транспортом, поэтому их можно использовать для вредоносных целей, представляющих угрозу безопасности. Таким образом, только члены группы "Администраторы" могут создавать сокеты типа SOCK_RAW в Windows 2000 и более поздних версиях.

Операции отправки и получения

Когда приложение создает сокет типа SOCK_RAW, этот сокет можно использовать для отправки и получения данных. Все пакеты, отправленные или полученные в сокете типа SOCK_RAW , обрабатываются как датаграммы в неподключаемом сокете.

К операциям с сокетами SOCK_RAW применяются следующие правила:

  • Функция sendto или WSASendTo обычно используется для отправки данных в сокет типа SOCK_RAW. Адрес назначения может быть любым допустимым адресом в семействе адресов сокета, включая адрес широковещательной или многоадресной рассылки. Для отправки на широковещательный адрес приложение должно использовать параметр setsockopt с включенным SO_BROADCAST. В противном случае sendto или WSASendTo завершится ошибкой с кодом WSAEACCES. Для IP-адреса приложение может отправлять сообщения на любой адрес многоадресной рассылки (не становясь участником группы).

  • При отправке данных IPv4 приложение может выбрать, следует ли указывать заголовок IPv4 в передней части исходящей датаграммы для пакета. Если параметр сокета IP_HDRINCL имеет значение true для сокета IPv4 (семейство адресов AF_INET), приложение должно предоставить заголовок IPv4 в исходящих данных для операций отправки. Если этот параметр сокета имеет значение false (значение по умолчанию), то заголовок IPv4 не должен включать исходящие данные для операций отправки.

  • При отправке данных IPv6 приложение может выбрать, следует ли указывать заголовок IPv6 в передней части исходящей датаграммы для пакета. Если параметр сокета IPV6_HDRINCL имеет значение true для сокета IPv6 (семейство адресов AF_INET6), приложение должно предоставить заголовок IPv6 в исходящих данных для операций отправки. Значение по умолчанию для этого параметра — false. Если этот параметр сокета имеет значение false (значение по умолчанию), то заголовок IPv6 не должен включаться в исходящие данные для операций отправки. Для IPv6 не нужно включать заголовок IPv6. Если сведения доступны с помощью функций сокетов, то заголовок IPv6 не следует включать, чтобы избежать проблем совместимости в будущем. Эти вопросы обсуждаются в документе RFC 3542, опубликованном IETF. Использовать параметр сокета IPV6_HDRINCL не рекомендуется и в будущем может быть нерекомендуем.

  • Функция recvfrom или WSARecvFrom обычно используется для получения данных в сокете типа SOCK_RAW. Обе эти функции могут возвращать исходный IP-адрес, с которого был отправлен пакет. Полученные данные — это датаграмма из несвязанного сокета.

  • Для IPv4 (семейство адресов AF_INET) приложение получает заголовок IP-адреса в передней части каждой полученной датаграммы независимо от параметра сокета IP_HDRINCL .

  • Для IPv6 (семейство адресов AF_INET6) приложение получает все после последнего заголовка IPv6 в каждой полученной датаграмме независимо от параметра сокета IPV6_HDRINCL . Приложение не получает заголовки IPv6 с помощью необработанного сокета.

  • Полученные датаграммы копируются во все SOCK_RAW сокеты, удовлетворяющие следующим условиям:

    • Номер протокола, указанный в параметре протокола при создании сокета, должен соответствовать номеру протокола в ip-заголовке полученной датаграммы.
    • Если для сокета определен локальный IP-адрес, он должен соответствовать адресу назначения, указанному в заголовке IP-адреса полученной датаграммы. Приложение может указать локальный IP-адрес, вызвав функцию bind . Если для сокета не указан локальный IP-адрес, датаграммы копируются в сокет независимо от ip-адреса назначения в заголовке IP-адреса полученной датаграммы.
    • Если для сокета определен внешний адрес, он должен соответствовать исходному адресу, указанному в заголовке IP-адреса полученной датаграммы. Приложение может указать внешний IP-адрес, вызвав функцию connect или WSAConnect . Если для сокета не указан внешний IP-адрес, датаграммы копируются в сокет независимо от исходного IP-адреса в заголовке IP-адреса полученной датаграммы.

Важно понимать, что некоторые сокеты типа SOCK_RAW могут получать много непредвиденных датаграмм. Например, программа PING может создать сокет типа SOCK_RAW для отправки эхо-запросов ICMP и получения ответов. В то время как приложение ожидает эхо-ответов ICMP, все остальные сообщения ICMP (например, ICMP HOST_UNREACHABLE) также могут быть доставлены в это приложение. Кроме того, если на компьютере одновременно открыто несколько сокетов SOCK_RAW , во все открытые сокеты могут быть доставлены одни и те же датаграммы. Приложение должно иметь механизм для распознавания интересующих датаграмм и пропускать все остальные. Для программы PING такой механизм может включать проверку полученного ip-заголовка на наличие уникальных идентификаторов в заголовке ICMP (например, идентификатора процесса приложения).

Примечание

Для использования сокета типа SOCK_RAW требуются права администратора. Пользователи, выполняющие приложения Winsock, использующие необработанные сокеты, должны быть членами группы Администраторы на локальном компьютере, в противном случае необработанные вызовы сокетов завершатся ошибкой с кодом WSAEACCES. В Windows Vista и более поздних версиях доступ к необработанным сокетам применяется при создании сокетов. В более ранних версиях Windows доступ к необработанным сокетам применяется во время других операций сокетов.

 

Частое использование необработанных сокетов

Одним из распространенных вариантов использования необработанных сокетов являются устранение неполадок приложений, которым необходимо подробно изучить IP-пакеты и заголовки. Например, необработанный сокет можно использовать с SIO_RCVALL IOCTL, чтобы позволить сокету получать все пакеты IPv4 или IPv6, проходящие через сетевой интерфейс. Дополнительные сведения см. в справочнике по SIO_RCVALL .

Ограничения на необработанные сокеты

В Windows 7, Windows Vista, Windows XP с пакетом обновления 2 (SP2) и Windows XP с пакетом обновления 3 (SP3) возможность отправки трафика через необработанные сокеты была ограничена несколькими способами:

  • Данные TCP нельзя отправлять через необработанные сокеты.

  • UDP-датаграммы с недопустимым исходным адресом нельзя отправлять через необработанные сокеты. Исходный IP-адрес любой исходящей UDP-датаграммы должен существовать в сетевом интерфейсе, иначе датаграмма удаляется. Это изменение было внесено, чтобы ограничить возможность вредоносного кода создавать распределенные атаки типа "отказ в обслуживании" и ограничить возможность отправки поддельных пакетов (пакетов TCP/IP с подделанным исходным IP-адресом).

  • Вызов функции bind с необработанным сокетом для протокола IPPROTO_TCP не допускается.

    Примечание

    Функция bind с необработанным сокетом разрешена для других протоколов (например, IPPROTO_IP, IPPROTO_UDP или IPPROTO_SCTP).

     

Указанные выше ограничения не применяются к Windows Server 2008 R2, Windows Server 2008, Windows Server 2003 или версиям операционной системы, предшествующим Windows XP с пакетом обновления 2 (SP2).

Примечание

Реализация ПРОТОКОЛА TCP/IP майкрософт в Windows может открывать необработанные UDP-сокеты или TCP на основе указанных выше ограничений. Другие поставщики Winsock могут не поддерживать использование необработанных сокетов.

 

Существуют дополнительные ограничения для приложений, использующих сокет типа SOCK_RAW. Например, все приложения, прослушивающие определенный протокол, будут получать все пакеты, полученные для этого протокола. Это может быть не то, что нужно для нескольких приложений, использующих протокол. Это также не подходит для высокопроизводительных приложений. Чтобы обойти эти проблемы, может потребоваться написать драйвер сетевого протокола Windows (драйвер устройства) для конкретного сетевого протокола. В Windows Vista и более поздних версиях winsock Kernel (WSK) для записи драйвера сетевого протокола можно использовать новый независимый от транспорта режим ядра Сетевой интерфейс программирования. В Windows Server 2003 и более ранних версиях для поддержки сетевого протокола можно записать поставщик TDI и вспомоганную библиотеку DLL Winsock. Затем сетевой протокол будет добавлен в каталог Winsock в качестве поддерживаемого протокола. Это позволяет нескольким приложениям открывать сокеты для этого конкретного протокола, а драйвер устройства может отслеживать, какой сокет получает определенные пакеты и ошибки. Сведения о создании поставщика сетевых протоколов см. в разделах, посвященных WSK и TDI в пакете драйверов Windows (WDK).

Приложения также должны знать о влиянии параметров брандмауэра на отправку и получение пакетов с помощью необработанных сокетов.