Что это raw sockets
Особенности получения пакетов через raw socket в Linux
Linux (в отличии, к примеру, от FreeBSD) позволяет использовать сырые сокеты не только для отправки, но и для получения данных. В этом месте существуют интересные грабли, на которые я наступил. Теперь спешу показать их тем, кто еще на знает, чтобы каждый, используя свой любимый язык программирования, будь то C++ или Python, мог опробовать их в деле.
Суть граблей изображена на рисунке, чтобы те, кто уже в курсе, не тратили свое время.
Я буду писать примеры на С, но вы можете перенести их и на другие языки, предоставляющие возможность низкоуровневой работы со стеком TCP\IP в Linux.
Некоторые понятия
Напомню, что для инициализации сырого сокета мы передаем параметр, обозначающий тип протокола. Например UDP:
socket(AF_INET, SOCK_RAW, IPPROTO_UDP)
Этот протокол я буду называть уровнем на котором работает сырой сокет. В примере мы создали сырой сокет на уровне UDP.
Уровень сырого сокета не ограничивает вас в формировании пакета на отправку, вы можете самостоятельно сформировать как UDP, так и IP заголовок. А вот при получении данных начинается самое интересное…
Грабли
Допустим мы создали 2 сырых сокета на уровне UDP и воспользовались одним из них для отправки UDP пакета на UDP эхо сервер. Эхо вернет нам UDP payload обратно. Так вот, Стек TCP\IP скопирует полученный пакет на все сырые сокеты того уровня, который указан в поле Protocol IP заголовка пришедшего пакета. Еще раз повторюсь — на ВСЕ, даже те, которые открыты в других приложениях (по этой причине приложение, оперирующее сырыми сокетами может быть запущено только с правами суперпользователя). Так как UDP эхо сервер отвечает UDP пакетом, то все сырые сокеты UDP уровня его получат.
Отметим еще одну важную особенность. Не зависимо от уровня сырого сокета, ему доставляется полный пакет, включающий IP заголовки.
Таким образом, каждый сырой сокет в Linux является сниффером на том уровне, на котором он был создан. Следует помнить об этом при разработке приложений.
Пример
Не стал нагружать заметку кодом. Для тех, кому интересно попробовать, я
выложил свой пример на github. Там cmake проект, который собирает простенький UDP эхо-сервер и приложение, создающее 2 сырых сокета уровня UDP, один из которых посылает данные, но оба отправляются в epoll в ожидании ответа. Для чистоты эксперимента эхо-сервер и пример желательно пустить на разных машинах (не забудьте поправить код в соответствии вашим IP-шникам). Для интереса можно запустить несколько экземпляров примера.
Для внешкольного чтения есть хорошая статья.
Как работать с сырыми сокетами (SOCK_RAW) | Часть 1
Представляем вашему вниманию гайд по работе с сырыми сокетами (SOCK_RAW). Не пугайтесь, здесь автоперевод. Если есть желание (и знание английского языка), в конце статьи ссылка на первоисточник.
0x1. Вступление
Цель этой статьи — объяснить часто неправильно понимаемую природу сырых сокетов. Движущей силой написания этого текста стало любопытство автора. чтобы изучить все тонкости этого мощного типа сокетов, также известного как SOCK_RAW. То, что здесь будет обсуждаться, * не * будет еще одним руководством о том, как изготовить собственные пакеты вручную. Эта тема много раз обсуждалась чрезмерно и в сети можно найти довольно много упоминаний о нем (микшер и т. д.). Какие Здесь будет обсуждаться то, что необработанные сокеты делают за кулисами.
Мы по этой причине собираюсь углубиться во внутреннее устройство сетевого стека. Предполагается, что читатель уже имеет некоторый опыт работы с сокетами и готов взглянуть на некоторый код ядра, поскольку реализация сырых сокетов фактически зависит от ОС. Мы будет охватывать реализации как FreeBSD 7.0, так и Linux 2.6. Большинство вещей покрыто для FreeBSD может также применяться к OpenBSD, NetBSD и даже MAC OS X.
0x2. Создание
Перво-наперво. Создание. Как создается сырой сокет? Какие основные в хитросплетениях? Необработанный сокет создается путем вызова системного вызова socket (2) и определив тип сокета как SOCK_RAW следующим образом:
где XXX — это * протокол int *, который, как мы обсудим далее, является главный источник путаницы и проблем, вникающий в сам факт того, что здесь могут применяться разные комбинации. Допустимые значения: IPPROTO_RAW, IPPROTO_ICMP, IPPOROTO_IGMP, IPPROTO_TCP, 0 (осторожно — см. Ниже), IPPROTO_UDP и т. Д. При другой комбинации возникает другое поведение. И это поведение критично для того, как ядро взаимодействует с приложение, создающее необработанный сокет.
Прежде чем переходить к конкретным комбинациям для каждой ОС, давайте сначала рассмотрим посмотрите на фактическое значение значения * протокола *. Чтобы все протоколы работали одновременно был использован конкретный общий подход к проектированию. Согласно ему, похожие протоколы сгруппированы в домены. Домен обычно определяется тем, что называется семейством протоколов или семейством адресов (последнее является самым последним практика) и ряд констант используются для различения между ними. В самые распространенные из них:
FreeBSD определяет указанные выше значения (почти такие же) в /usr/src/sys/sys/socket.h Как вы уже догадались, мы займемся Семья AF_INET. Семейство Интернета разбивает свои протоколы на протокол типы, каждый из которых может состоять более чем из одного протокол.
Linux определяет типы протоколов семейства Интернет в /usr/src/linux-2.6.*/include/linux/net.h
Если вы в прошлом занимались программированием сокетов, то вы, вероятно, признать некоторые из вышеперечисленных. Один из них должен быть вторым аргументом вызов socket (AF_INET, …, …). Третий аргумент — это значение IPPROTO_XXX, которое определяет фактический протокол над IP. Это важно понимать значение. Это значение / число — то, что IP-уровень будет записывать в Поле protocol_type в его заголовке для определения протокола верхнего уровня. Это Поле «Протокол», как вы видите в IP-заголовке ниже (RFC 791).
Это одно из самых важных полей, поскольку именно оно будет использоваться уровень IP на стороне получателя, чтобы понять, какой уровень находится над ним (для пример TCP или UDP) дейтаграмма должна быть доставлена.
Linux определяет эти протоколы в /usr/src/linux-2.6.*/include/linux/in.h
С таким количеством различных комбинаций лучше всего обсуждать вещи последовательно, чтобы начнем с часто используемого значения протокола * 0 *. Вы когда-нибудь задумывались, как Системный вызов socket (2) волшебным образом находит, какой протокол использовать, даже если он был называется как socket (…, …, 0)? Например, когда приложение вызывает его так:
как ядро узнает, с каким протоколом связать сокет? Дело в том, что ядро не делает никаких предположений — ядро не играет в кости с пользовательским пространством (цитируя сумасшедшего физика и великого ума http://www.quotedb.com/quotes/878 в несколько ином контексте) — в большинстве случаи, которые есть (см. шифрование и энтропию для противоположной парадигмы)
Во FreeBSD все, что он делает, это ассоциирует первый протокол, найденный в связанный список доменов через функцию pffindproto (dom, type).
Давайте будем более конкретными и посмотрим код POC:
Сокет создается с помощью функции ядра socreate (), которая определяется как это: (исходный код из FreeBSD 7.0 /usr/src/sys/kern/uipc_socket.c)
Секрет кроется в двух функциях pffindproto () и pffindtype (). Если proto == 0, тогда вызывается pffindtype, который менее строг, чем pffindproto (). Как видно из кода, pffindtype () не проверяет значение протокола в all и просто возвращает * первую * структуру protosw, которую он находит, выводя ее из только pr_type (тип протокола: SOCK_STREAM, SOCK_DGRAM, SOCK_RAW и т. д.) и семья / домен (AF_INET, AF_LOCAL и т. д.).
Каждая структура protosw (переключение протокола) представляет собой ассоциацию типа SOCK_XXX и Протокол IPPROTO_XXX. Все структуры protosw находятся внутри таблицы inetsw [] на который указывает запись inetdomain в связанном списке глобальных доменов. Графическое представление может немного прояснить ситуацию: домены:
Примечание. Место IP (raw) в 4-м индексе (inetsw [3]) упоминается для исторические причины и более новые реализации стека FreeBSD отличаются в этом отношении. В частности, если в ядре определена поддержка SCTP, тогда IP (необработанный), ICMP и остальные перемещаются на 3 позиции вверх по массиву inetsw [] фактически становится inetsw [6], inetsw [7] и т. д. Конечно, здесь нет никаких значительная разница в исходных кодах ядра, поскольку inetsw [] никогда не используется индекс, но по имени. На протяжении всего текста мы будем использовать соглашение, относящееся к записи по умолчанию (inetsw [3]) как default_RAW и запись RAW с подстановочными знаками (последний член inetsw [] и в старые времена inetsw [6]) как wildcard_RAW для ясности.
Вернемся к поиску, который выглядит так:
pffindtype:
обе функции возвращают запись inetsw [] (то есть указатель protosw * на соответствующее смещение массива) /usr/src/sys/kernel/uipc_domain.c:
Изучая приведенный выше код, мы замечаем еще одно важное значение SOCK_RAW. По сути, последние несколько строк pffindproto () используют SOCK_RAW как резервный протокол по умолчанию. Это означает, что если пользовательское приложение вызывает socket (2) вот так: сокет
То же самое и с таким вызовом:
Тип SOCK_RAW и IPPROTO_TCP не совпадают, поскольку SOCK_RAW имеет только записи для ICMP, IGMP и сырого IP. Однако это идеальный правильный вызов, поскольку ядро вернет подстановочный знак SOCK_RAW.
Это касается FreeBSD. Что касается Linux, возможно, у вас уже есть видно из фрагмента кода сверху (in.h), значение * 0 * на самом деле определяется как другой тип протокола для TCP. Эта практика имеет сильный эффект в переносе приложений между * BSD и Linux. Например, для * BSD это верный:
Обратите внимание, что при вводе значения 0 будет возвращена запись default_RAW, а не запись с подстановочным знаком, так как pffindtype () вернет первую структуру protosw с тип SOCK_RAW внутри таблицы inetsw [] и первый — default_RAW Вход.
В Linux вы получите ошибку EPROTONOSUPPORT. См. Код ядра ниже, чтобы понять, почему это происходит.
Случай 8 демонстрирует, как Linux использует SOCK_RAW в качестве резервного протокола, как и мы видели выше с FreeBSD.
Это не единственные различия между двумя системами. Мы обсудим больше из них дальше.
Raw сокеты WinSocket C++
Raw сокеты WinSocket C++. В данной статье – примере мне хотелось бы показать работу с простыми(raw) сокетами. Данные сокеты позволяют получить доступ к базовому протоколу передачи данных, это дает нам большие возможности создания таких сетевых утилит как Ping, Traceroute, а также для организации IP Spoofing, DDoS, ICMP-flood, и многого еще =) Рассматривать будем только протокол IP, так как большинство других протоколов вообще не поддерживают простые сокеты, разве только ATM.
Поддержка данного типа сокетов начинается только в Windows Sockets 2-ой версии. Первое, что необходимо сделать для использования данного типа сокета – это его создание. Для этого запускаем Visual C++, далее создаем новый проект(«CTRL+N» или File->New), тип проекта «Win32 Console Application», и пишем следующий код:
Как видно из приведенного кода, для создания простого сокета достаточно указать вторым аргументом функции socket, протокол SOCK_RAW, но самое интересное представляет третий аргумент, в приведенной выше коде мы использовали IPPROTO_ICMP, но так же можно использовать IPPROTO_IGMP, IPPROTO_IP, IPPROTO_UDP, IPPROTO_RAW, IPPROTO_TCP, все эти параметры позволяют нам манипулировать заголовками представленных протоколов. При самостоятельном заполнение IP заголовка, необходимо добавить в код следующие строки:
Это позволит функции отправки(send, sendto) отправить заголовок IP перед посылаемыми данными, а функция приема вернет этот заголовок вместе с данными. На рисунке представленном ниже показан заголовок IP.
Теперь нам надо определить структуру, которая будет представлять IP заголовок:
Для начальных опытов мы попробуем создать простой UDP сокет, так как он проще, его величина всего 8 байт, содержит 4 поля, более наглядно показано на рисунке ниже.
Определение структуры UDP заголовка.
Как Вы знаете протокол UDP ненадежный и не гарантирует доставку данных, значит вычисление контрольной суммы не обязательно, хотя и можно это сделать. Для этого используется псевдозаголовок представленный на рисунке: 
Контрольная сумма UDP рассчитывается точно так же, как контрольная сумма IP заголовка, сумма 16-битных слов с переполнением. Если UDP датаграмма состоит из нечетного количества байт то необходимо в конце датаграммы добавить нулевые байты заполнения(который не передаются). Для расчета контрольной суммы в коде программы мы будем использовать следующею функцию, которая одинаковая для всех протоколов TCP/IP:
Настоящее sock_raw’вище
Raw сокеты предоставляют программисту более широкие возможности по сравнению с остальной частью сокетного API. Все знают об этих «широких» возможностях, но более или менее систематизированное их описание встречается в Интернете нечасто. Попробуем, восполнить данный пробел и разобраться с предназначением raw cокетов и вариантами их применения в сетевом ПО.
Итак, raw сокеты — особый вид сокетов, доступный при использовании системного вызова типа:
Не удержусь и сделаю небольшое отступление по поводу возможных аргументов в вызове socket и их концептуального значения. Все мы знаем, что сокетный API задумывался как генерализированный интерфейс программирования, т.е. интерфейс, посредством которого можно будет работать с самыми различными механизмами сетевого, а то и просто внутрихостового взаимодействия. Первый аргумент вызова выбирает т.н. коммуникационный домен. Создатели сокетного API отвели под межсетевое взаимодействие на базе TCP/IP (IPv4) коммуникационный домен AF_INET, который мы и указываем в нашем вызове. Второй аргумент задает тип сокета — сокеты типизируются в соответствии с семантикой передачи данных, которую они обеспечивают (SOCK_STREAM — потоковая передача, SOCK_DGRAM — дейтаграммная передача). В нашем случае используется тип сокета SOCK_RAW — наверное это единственное отступление от правил, когда второй аргумент означает не столько семантику передачи, сколько доступ к специальному низкоуровневому функционалу. Наконец, третий аргумент задает протокол. Список констант, большинство из которых можно использовать в качестве третьего аргумента в нашем вызове, можно посмотреть в файле /usr/src/linux-*/include/linux/in.h, где * — версия ядра. Наиболее часто используются константы IPPROTO_TCP, IPPROTO_UDP, IPPROTO_ICMP, IPPOROTO_IGMP, IPPROTO_RAW.
Когда начинаешь работать с raw сокетами, сразу замечаешь, по крайней мере, две их особенности — то как осуществляется инкапсуляция данных и наличие доступа к IP-заголовкам. Посылаемые с помощью raw сокета данные инкапсулируются непосредственно в поле полезной нагрузки IP-дейтаграммы, минуя транспортный уровень. Что касается заголовков, то тут удобно выделить две ситуации – отправка и прием дейтаграммы. Пользовательское приложение, использующее raw сокеты, всегда получает IP-дейтаграмму целиком, включая её заголовок. При этом все необходимые проверки валидности полей заголовка дейтаграммы все равно осуществляются ядром, и приложение никогда не получит через raw сокет дейтаграмму, в которой указана, к примеру, невалидная версия протокола IP (т.е. версия отличная от IPv4).
При отправке данных через raw сокет у программиста есть выбор – переложить задачу создания IP заголовков на ядро или создавать заголовки самому. Второе возможно при использовании сокетной опции IP_HDRINCL (плюс в Linux есть ситуация, когда данная опция будет включена автоматически, если в качестве третьего аргумента в вызове socket() использовать константу IPPROTO_RAW). Однако, даже в случае использования опции IP_HDRINCL ядро все равно будет “ассистировать” программисту. Так, поля заголовка дейтаграммы Total Length и Header Checksum всегда автоматически заполняются ядром, а поля Source Address и Identification будут заполнены ядром, если программист оставит их значения равными нулю. Возможность создать свой заголовок дейтаграммы используется в основном для отправки пакетов с «проспуфленным» source IP-адресом.
Raw сокеты могут использоваться как несколько ограниченный в своих возможностях механизм packet capture. Ограничен он по ряду причин. Во-первых, через raw сокет можно получать только копию входящего пакета, но не генерируемого данной машиной и не транзитируемого (маршрутизируемого). Во-вторых, через raw сокет можно получать только IP-дейтаграммы с заданным Protocol ID (Protocol ID соответствует третьему аргументу в системном вызове socket(), использовавшимся при создании сокета), а не весь IP-трафик. Наконец, отличительной особенностью raw сокетов во FreeBSD (но не Linux) является то, что мы сможем получить IP-дейтаграмму, только если ядро не знает как ее обрабатывать (исключение — пакеты протоколов ICMP и IGMP, о которых скажем ниже). Здесь имеется ввиду, что в ядре не реализован код, предназначенный для обработки IP-дейтаграммы с указанным в ней Protocol ID. Также, интересен следующий факт — если создано более одного raw сокета с аналогичными параметрами, каждый сокет будет получать по собственной копии входящего пакета.
Raw сокеты незаменимы при написании сетевых сканеров. К примеру, мы можем использовать вызов типа:
Далее нам остается только сконструировать TCP-сегмент и передать его на отправку raw сокету. Не забываем так же и о возможности подделки source IP-адреса, которая в данном контексте придется очень кстати. Аналогичным образом, можно писать программы для фаззинга сетевого стека ядра. К примеру, конструируемые пакеты транспортного уровня могут содержать заведомо невалидные значения в нужных нам полях.
При использовании протокола TCP через raw сокет стоит понимать следующую вещь. Мы не можем полностью воссоздать работу протокола TCP, да у нас это и не получится, исходя из возможностей, предоставляемых raw сокетами. Максимум, что мы сможем сделать — это принимать входящий трафик этого типа (в Linux) и отправлять отдельно взятые исходящие TCP-сегменты, якобы являющиеся частью установленного или устанавливаемого TCP-соединения.
Наконец, стоит упомянуть еще один аспект использования raw сокетов. Существуют протоколы, работа которых контролируется, главным образом, самим ядром, например ICMP и IGMP. В ряде случаев, доступ к этим протоколам из пользовательского приложения может быть весьма полезен:
Именно так написаны такие утилиты как ping, классический tracert (ICMP), а также утилиты, позволяющие манипулировать подпиской по IGMP.
Таким образом, собрав воедино все факты, можно попытаться сделать вывод о предназначении raw сокетов. Данный механизм пригодится нам, если нужно реализовать:
Сложно себе представить, что функционал, предоставляемый raw сокетами, был изначально призван поощрить написание софта для проведения сетевых атак. Скорее обоснованием необходимости данного механизма послужили достаточно мирные цели. Однако возможности raw сокетов, в конечном счете, нашли применение и в хакерском софте.
Ссылки на полезные ресурсы по теме
Необработанные сокеты TCP/IP
Необработанный сокет — это тип сокета, который обеспечивает доступ к базовому поставщику транспорта. В этом разделе рассматриваются только необработанные сокеты и протоколы IPv4 и IPv6. Это связано с тем, что большинство других протоколов с исключением ATM не поддерживает необработанные сокеты. Чтобы использовать необработанные сокеты, приложение должно иметь подробную информацию об используемом базовом протоколе.
Поставщики служб Winsock для IP-протокола могут поддерживать тип сокета Сокк _ RAW. поставщик Windows sockets 2 для TCP/IP, включенный в Windows, поддерживает этот тип сокк _ необработанного сокета.
Существует два основных типа таких необработанных сокетов:
Определение поддержки необработанных сокетов
Элемент иаддрессфамили в структуре _ сведений о всапротокол должен указывать AF _ inet или AF _ INET6, а элемент исоккеттипе структуры всапротокол должен указать _ Сокк _ RAW для одного из поставщиков транспорта.
Элемент ипротокол структуры _ info Всапротокол может иметь значение ипрото _ IP. Элемент ипротокол структуры _ info всапротокол также может иметь нулевое значение, если поставщик услуг позволяет приложению использовать тип _ необработанного сокета Сокк для других сетевых протоколов, отличных от протокола Интернета для семейства адресов.
Netsh Winsock показывать каталог
Создание необработанного сокета
Чтобы создать сокет типа Сокк _ RAW, вызовите функцию Socket или всасоккет с параметром AF (семейство адресов), для которого задано значение AF _ inet или AF _ INET6, параметру Type задано значение Сокк _ RAW, а параметру протокола задано значение требуемого номера протокола. Параметр протокола становится значением протокола в IP-заголовке (например, SCTP — 132).
Необработанные сокеты предоставляют возможность управлять базовым транспортом, поэтому их можно использовать для вредоносных целей, представляющих угрозу безопасности. таким образом, только члены группы «администраторы» могут создавать сокеты типа сокк _ RAW на Windows 2000 и более поздних версиях.
Операции отправки и получения
К операциям по Сокк _ необработанным сокетам применяются следующие правила.
Функция SendTo или всасендто обычно используется для отправки данных на сокет типа Сокк _ RAW. Адресом назначения может быть любой допустимый адрес в семействе адресов сокета, включая широковещательный или многоадресный адрес. Чтобы отправить широковещательный адрес, приложение должно использовать сетсоккопт с таким образом, чтобы _ вещание было включено. В противном случае SendTo или всасендто завершится ошибкой с кодом ошибки всаеакцес. Для IP-адреса приложение может отправить на любой адрес многоадресной рассылки (без участия в группе).
При отправке данных IPv4 приложение имеет возможность указать, следует ли указывать заголовок IPv4 в начале исходящей датаграммы для пакета. Если для параметра IP- _ хдринкл Socket задано значение true для сокета IPv4 (семейство адресов AF _ iNet), приложение должно предоставить заголовок IPv4 в исходящих данных для операций отправки. Если этот параметр сокета имеет значение false (значение по умолчанию), то заголовок IPv4 не должен включаться в исходящие данные для операций отправки.
При отправке данных IPv6 приложение имеет возможность указать, следует ли указывать заголовок IPv6 в начале исходящей датаграммы для пакета. Если параметр сокета _ хдринкл IPv6 имеет значение true для сокета IPv6 (семейство адресов AF _ INET6), приложение должно предоставить заголовок IPv6 в исходящих данных для операций отправки. Значение по умолчанию для этого параметра — false. Если этот параметр сокета имеет значение false (значение по умолчанию), то заголовок IPv6 не должен включаться в исходящие данные для операций отправки. Для IPv6 не нужно включать заголовок IPv6. Если сведения доступны с помощью функций сокета, то заголовок IPv6 не следует включать, чтобы избежать проблем совместимости в будущем. Эти проблемы обсуждаются в RFC 3542, опубликованных IETF. Использование параметра сокета _ хдринкл IPv6 не рекомендуется и может быть устаревшим в будущем.
Функция реквфром или всареквфром обычно используется для получения данных на сокете типа Сокк _ RAW. Обе эти функции имеют возможность вернуть исходный IP-адрес, с которого был отправлен пакет. Полученные данные — это датаграмма неподключенного сокета.
Для IPv4 (семейство адресов AF _ iNet) приложение получает заголовок IP-адреса в начале каждой полученной датаграммы независимо от параметра IP- _ хдринкл Socket.
Полученные датаграммы копируются во все _ необработанные сокеты Сокк, которые отвечают следующим условиям:
Важно понимать, что некоторые сокеты типа Сокк _ RAW могут принимать много непредусмотренных датаграмм. Например, программа PING может создать сокет типа Сокк _ RAW для отправки эхо-запросов ICMP и получения ответов. Хотя приложение ожидает ответа ICMP, все остальные ICMP-сообщения (такие как узел ICMP, _ НЕдоступные) также могут доставляться в это приложение. Кроме того, если несколько _ необработанных сокетов Сокк открыты на компьютере одновременно, одни и те же датаграммы могут быть доставлены всем открытым сокетам. Приложение должно иметь механизм для распознавания интересующих датаграмм и пропускать все остальные. Для программы PING такой механизм может включать проверку IP-заголовка Received для уникальных идентификаторов в заголовке ICMP (например, идентификатор процесса приложения).
Для использования сокета типа Сокк _ RAW требуются права администратора. Пользователи, запускающие приложения Winsock, использующие необработанные сокеты, должны быть членами группы «Администраторы» на локальном компьютере, в противном случае вызовы необработанных сокетов завершатся ошибкой с кодом всаеакцес. в Windows Vista и более поздних версиях доступ к необработанным сокетам применяется при создании сокета. в более ранних версиях Windows доступ к необработанным сокетам применяется во время других операций сокета.
Распространенные способы использования необработанных сокетов
Ограничения для необработанных сокетов
в Windows 7, Windows Vista, Windows XP с пакетом обновления 2 (sp2) и Windows XP с пакетом обновления 3 (sp3) возможность отправки трафика через необработанные сокеты ограничена несколькими способами:
Функция BIND с необработанным сокетом разрешена для других протоколов ( _ например, ИППРОТО IP, ИППРОТО _ UDP или иппрото _ SCTP).
указанные выше ограничения не относятся к Windows server 2008 R2, Windows Server 2008, Windows Server 2003 или к версиям операционной системы, предшествующим Windows XP с пакетом обновления 2 (SP2).
реализация TCP/IP в корпорации майкрософт на Windows может открыть необработанный сокет UDP или TCP на основе указанных выше ограничений. Другие поставщики Winsock могут не поддерживать использование необработанных сокетов.
Существуют дополнительные ограничения для приложений, использующих сокет типа Сокк _ RAW. Например, все приложения, прослушивающие конкретный протокол, получат все пакеты, полученные для этого протокола. Это может быть нежелательным для нескольких приложений, использующих протокол. Это также не подходит для высокопроизводительных приложений. чтобы избежать этих проблем, может потребоваться написать Windows драйвер сетевого протокола (драйвер устройства) для конкретного сетевого протокола. в Windows Vista и более поздних версиях Winsock Kernel (WSK) — новый интерфейс сетевого программирования, не зависящий от транспорта, может использоваться для записи драйвера сетевого протокола. в Windows Server 2003 и более ранних версиях для поддержки сетевого протокола можно написать поставщик TDI (TDI) и библиотеку DLL модуля поддержки Winsock. Затем сетевой протокол будет добавлен в каталог Winsock как поддерживаемый протокол. Это позволяет нескольким приложениям открывать сокеты для этого конкретного протокола, и драйвер устройства может контролировать, какой сокет получает определенные пакеты и ошибки. сведения о создании поставщика сетевых протоколов см. в разделах WSK и TDI в комплекте Windows Driver Kit (WDK).
Приложениям также необходимо учитывать влияние параметров брандмауэра на отправку и получение пакетов с помощью необработанных сокетов.


