Что такое сырые сокеты
Сокет — это один конец двустороннего канала связи между двумя программами, работающими в сети. Соединяя вместе два сокета, можно передавать данные между разными процессами (локальными или удаленными). Реализация сокетов обеспечивает инкапсуляцию протоколов сетевого и транспортного уровней.
Первоначально сокеты были разработаны для UNIX в Калифорнийском университете в Беркли. В UNIX обеспечивающий связь метод ввода-вывода следует алгоритму open/read/write/close. Прежде чем ресурс использовать, его нужно открыть, задав соответствующие разрешения и другие параметры. Как только ресурс открыт, из него можно считывать или в него записывать данные. После использования ресурса пользователь должен вызывать метод Close(), чтобы подать сигнал операционной системе о завершении его работы с этим ресурсом.
Когда в операционную систему UNIX были добавлены средства межпроцессного взаимодействия (Inter-Process.
Linux (в отличии, к примеру, от FreeBSD) позволяет использовать сырые сокеты не только для отправки, но и для получения данных. В этом месте существуют интересные грабли, на которые я наступил. Теперь спешу показать их тем, кто еще на знает, чтобы каждый, используя свой любимый язык программирования, будь то C++ или Python, мог опробовать их в деле.
Суть граблей изображена на рисунке, чтобы те, кто уже в курсе, не тратили свое время.
Я буду писать примеры на С, но вы можете перенести их и на другие языки, предоставляющие возможность низкоуровневой работы со стеком TCP\IP в Linux.
Некоторые понятия
Напомню, что для инициализации сырого сокета мы передаем параметр, обозначающий тип протокола. Например UDP:
socket(AF_INET, SOCK_RAW, IPPROTO_UDP)
Этот протокол я буду называть уровнем на котором работает сырой сокет. В примере мы создали сырой сокет на уровне UDP.
Уровень сырого сокета не ограничивает вас в формировании пакета на.
Книги: [Классика] [Базы данных] [Internet/WWW] [Сети] [Программирование] [UNIX] [Windows] [Безопасность] [Графика] [Software Engineering] [ERP-системы] [Hardware]
Самоучитель игры на WINSOCK
Сокеты (sockets) представляют собой высокоуровневый унифицированный интерфейс взаимодействия с телекоммуникационными протоколами. В технической литературе встречаются различные переводы этого слова - их называют и гнездами, и соединителями, и патронами, и патрубками, и т .д. По причине отсутствия устоявшегося русскоязычного термина, в настоящей статье сокеты будет именоваться сокетами и никак иначе.
Программирование сокетов несложно само по себе, но довольно поверхностно описано в доступной литературе, а Windows Sockets SDK содержит многоженство ошибок как в технической документации, так и в прилагаемых к ней демонстрационных примерах. К тому же имеются значительные отличия реализаций сокетов в UNIX и в Windows, что.
Нужна консультация? Заполните форму и наш експерт Вам подскажетСокет - это совокупность IP адреса и порта (IP:Port). Это понятно, а что такое сырой сокет? И бывают ли ещё какие-то сокеты?
Примечание:
latander, я неправильно наверное ярлыки выставил, изучаю сети (сейчас UDP), так вот на четвертом уровне в качестве адресации используют порты, это определенный номер приложения на узле.
Затем, как вы знаете, надо инициализировать windows sockets api.
Делается это WSAStartup'ом, коему впаривается версия именно 2.2 - в
противном случае вас ожидает вселенский сакс.
Теперь можно сделать raw-сокет. Вот он.
SOCKET raw_socket = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
if (raw_socket == INVALID_SOCKET)
<
printf("ERROR:socket(SOCK_RAW) error %i\n", WSAGetLastError());
exit(0);
>
Далее все зависит от цели - снифак мы пишем, спуфер, или даже все
вместе.
СПУФЕР
------
Для тех кто не знает, спуфер (spoofer) - это такая хрень, которая
позволяет вместо своего IP-шника подставить чужой. А в общем случае
послать весь IP-пакет целиком. И это правильно.
Вторым автором книги стал Михаил Балабаев, предложив свою помощь в работе над книгой. И я благодарен Михаилу за те замечания и исправления, которые он вносил (и продолжает вносить :)) в текст книги. Надеюсь, что и к финишу мы придём вместе.
Следует отметить, что представленный ниже текст главы был написан практически с нуля и затрагивает самые основы Synapse — работу с сокетами, о которой я очень кратко упоминал в блоге.
Вполне возможно, что после публикации в блоге.
сырые сокеты на Висле, XP, W2K… крис касперски ака мыщъх, no-email сырые сокеты (raw sockets) широко используются как в хакерских, так и в легальных коммерческих программах: exploit'ах, спуферах, сниферах, сканерах, брандмауэрах, NAT'ах, etc. никсы поддерживают сырые сокеты изначально, 9x – лишь формально. с выходом W2K некрософт подарила нам полноценную поддержку сырых сокетов, но, начиная с XP SP2, сурово урезала их функциональность, в результате чего многие системные программы перестали работать и, чтобы вернуть функциональность взад программистам пришлось опуститься на уровень ядра или заюзать библиотеку WinCap. а простым пользователям что делать? как "оживить" старые программы, не имея исходных текстов на руках? без паники! мыщъх сейчас все расскажет, только покурит слегонца. введение Сокеты представляют собой индустриальный стандарт унифицированного интерфейса, ориентированный на межпроцессорное взаимодействие, и поддерживаемый практически всеми операционными системами. Причем.Сырость не радость
Реализация сырых сокетов в WinNT
Сырые сокеты (raw sockets) широко используются как в хакерских, так и в легальных коммерческих программах: эксплойтах, спуферах, сниферах, сканерах, брандмауэрах, NAT'ах, etc. Никсы поддерживают сырые сокеты изначально, 9x – лишь формально. С выходом W2K Microsoft подарила нам полноценную поддержку сырых сокетов, но начиная с XP SP2 сурово урезала их функциональность, в результате чего многие системные программы перестали работать. Чтобы вернуть былую функциональность, программистам пришлось опуститься на уровень ядра или заюзать библиотеку WinCap. А что делать простым пользователям? Как оживить старые программы, не имея исходных текстов на руках? Без паники! Сейчас я все расскажу.
Сокеты представляют собой индустриальный стандарт унифицированного интерфейса, ориентированный на межпроцессорное взаимодействие и поддерживаемый практически всеми.
здравствуйте!
как в qnx создать сокет, который будет принимать все пакеты, пришедшие на сетевую катрочку?
соответственно нужно отправлять в этот сокет пакеты которые я формирую.
насколько я знаю в qnx 6.5.0 создаются только tcp\ip сокеты
=( все знают и молчат, ну подскажите новичку!
Посмотри в сторону pcap.
а без pcap это возможно? я мельком просматривал исходники, где то видел константу PROMISCOUS, может как то так возможно?
а как работать с pcap в qnx? может ссылки есть какие?
A: This is one of the most frequently asked question by someone who is experimenting with raw sockets and TCP/IP. It is known that the 'IP_HDRINCL' socket option allows you to include the IP header along with the data. Since TCP encapsulates the IP header, we can also build a TCP packet and send it over a network. But the problem is, a TCP connection can never be established this way. The scenario is as follows:
A TCP connection is always made by a three-way handshake. So, initially you send a 'SYN' packet to the remote machine. If it is actively listening on the port, you get a 'SYN/ACK' packet. So far so good. But before you can respond, your machine sends an 'ACK/RST' packet and connection attempt is ended. For the connection to be complete, instead of the 'RST' packet, your machine should be sending an 'ACK' to the remote machine.
The difference lies where the connection is exactly.
В каждом конкретном случае необходимо проверять, поддерживает ли ОС сырые сокеты. Приблизительно поддержка отражена в таблице:
ОС поддержка сырых сокетов 95, 98, 98SE не поддерживает сырых сокетов (ограниченно поддерживает сырые сокеты для ICMP-протокола); NT 4.0 сырые сокеты ограничены 10 входящими соединениями за 10 минут (может быть исправлено в реестре); W2K полностью поддерживает сырые сокеты; XP без SP полностью поддерживает сырые сокеты после остановки брандмауэра ("net stop sharedaccess"); XP SP1 без заплатки MS05-019 поддерживает сырые сокеты так же, как и XP без SP; XP SP1 с заплаткой MS05-019 блокирует исходящие сырые TCP-сокеты, если брандмауэр запущен XP SP2 без MS05-019 полностью поддерживает входящие сырые сокеты и частично исходящие; XP SP2 с MS05-019 полностью поддерживает входящие сырые сокеты и некоторые исходящие; Vista не поддерживает сырые сокеты (ограниченно поддерживает сырые сокеты для ICMP-протокола); Win 7 ограниченно поддерживает сырые.
— это один конец двустороннего канала связи между двумя программами, работающими в сети. Соединяя вместе два сокета, можно передавать данные между разными процессами (локальными или удаленными). Реализация сокетов обеспечивает инкапсуляцию протоколов сетевого и транспортного уровней.
Первоначально сокеты были разработаны для UNIX в Калифорнийском университете в Беркли. В UNIX обеспечивающий связь метод ввода-вывода следует алгоритму open/read/write/close. Прежде чем ресурс использовать, его нужно открыть, задав соответствующие разрешения и другие параметры. Как только ресурс открыт, из него можно считывать или в него записывать данные. После использования ресурса пользователь должен вызывать метод Close(), чтобы подать сигнал операционной системе о завершении его работы с этим ресурсом.
Интерфейс IPC для взаимодействия между разными процессами построен поверх методов ввода-вывода. Они облегчают для сокетов отправку и получение данных. Каждый целевой объект задается адресом сокета, следовательно, этот адрес можно указать в клиенте, чтобы установить соединение с целью.
Типы сокетов
Существуют два основных типа сокетов — потоковые сокеты и дейтаграммные.
Потоковые сокеты (stream socket)
Потоковый сокет — это сокет с установленным соединением, состоящий из потока байтов, который может быть двунаправленным, т, е. через эту конечную точку приложение может и передавать, и получать данные.
Потоки базируются на явных соединениях: сокет А запрашивает соединение с сокетом В, а сокет В либо соглашается с запросом на установление соединения, либо отвергает его.
Если данные должны гарантированно доставляться другой стороне или размер их велик, потоковые сокеты предпочтительнее дейтаграммных. Следовательно, если надежность связи между двумя приложениями имеет первостепенное значение, выбирайте потоковые сокеты.
Дейтаграммные сокеты (datagram socket)
Потоковые сокеты по сравнению с дейтаграммными действительно дают более надежный метод, но для некоторых приложений накладные расходы, связанные с установкой явного соединения, неприемлемы (например, сервер времени суток, обеспечивающий синхронизацию времени для своих клиентов). В конце концов на установление надежного соединения с сервером требуется время, которое просто вносит задержки в обслуживание, и задача серверного приложения не выполняется. Для сокращения накладных расходов нужно использовать дейтаграммные сокеты.
Кроме двух рассмотренных типов существует также обобщенная форма сокетов, которую называют необрабатываемыми или сырыми.
Сырые сокеты (raw socket)
Главная цель использования сырых сокетов состоит в обходе механизма, с помощью которого компьютер обрабатывает TCP/IP. Это достигается обеспечением специальной реализации стека TCP/IP, замещающей механизм, предоставленный стеком TCP/IP в ядре — пакет непосредственно передается приложению и, следовательно, обрабатывается гораздо эффективнее, чем при проходе через главный стек протоколов клиента.
По определению, — это сокет, который принимает пакеты, обходит уровни TCP и UDP в стеке TCP/IP и отправляет их непосредственно приложению.
При использовании таких сокетов пакет не проходит через фильтр TCP/IP, т.е. никак не обрабатывается, и предстает в своей сырой форме. В таком случае обязанность правильно обработать все данные и выполнить такие действия, как удаление заголовков и разбор полей, ложится на получающее приложение — все равно, что включить в приложение небольшой стек TCP/IP.
Однако нечасто может потребоваться программа, работающая с сырыми сокетами. Если вы не пишете системное программное обеспечение или программу, аналогичную анализатору пакетов, вникать в такие детали не придется. Сырые сокеты главным образом используются при разработке специализированных низкоуровневых протокольных приложений. Например, такие разнообразные утилиты TCP/IP, как trace route, ping или arp, используют сырые сокеты.
Работа с сырыми сокетами требует солидного знания базовых протоколов TCP/UDP/IP.
Порты
Порт определен, чтобы разрешить задачу одновременного взаимодействия с несколькими приложениями. По существу с его помощью расширяется понятие IP-адреса. Компьютер, на котором в одно время выполняется несколько приложений, получая пакет из сети, может идентифицировать целевой процесс, пользуясь уникальным номером порта, определенным при установлении соединения.
Сокет состоит из IP-адреса машины и номера порта, используемого приложением TCP. Поскольку IP-адрес уникален в Интернете, а номера портов уникальны на отдельной машине, номера сокетов также уникальны во всем Интернете. Эта характеристика позволяет процессу общаться через сеть с другим процессом исключительно на основании номера сокета.
За определенными службами номера портов зарезервированы — это широко известные номера портов, например порт 21, использующийся в FTP. Ваше приложение может пользоваться любым номером порта, который не был зарезервирован и пока не занят. Агентство Internet Assigned Numbers Authority (IANA) ведет перечень широко известных номеров портов.
Обычно приложение клиент-сервер, использующее сокеты, состоит из двух разных приложений - клиента, инициирующего соединение с целью (сервером), и сервера, ожидающего соединения от клиента.
Например, на стороне клиента, приложение должно знать адрес цели и номер порта. Отправляя запрос на соединение, клиент пытается установить соединение с сервером:
Если события развиваются удачно, при условии что сервер запущен прежде, чем клиент попытался с ним соединиться, сервер соглашается на соединение. Дав согласие, серверное приложение создает новый сокет для взаимодействия именно с установившим соединение клиентом:
Класс Socket
Класс Socket играет важную роль в сетевом программировании, обеспечивая функционирование как клиента, так и сервера. Главным образом, вызовы методов этого класса выполняют необходимые проверки, связанные с безопасностью, в том числе проверяют разрешения системы безопасности, после чего они переправляются к аналогам этих методов в Windows Sockets API.
Прежде чем обращаться к примеру использования класса Socket, рассмотрим некоторые важные свойства и методы этого класса:
Необработанный сокет — это тип сокета, который обеспечивает доступ к базовому поставщику транспорта. В этом разделе рассматриваются только необработанные сокеты и протоколы IPv4 и IPv6. Это связано с тем, что большинство других протоколов с исключением ATM не поддерживает необработанные сокеты. Чтобы использовать необработанные сокеты, приложение должно иметь подробную информацию об используемом базовом протоколе.
Поставщики служб Winsock для IP-протокола могут поддерживать тип сокета Сокк _ RAW. поставщик Windows sockets 2 для TCP/IP, включенный в Windows, поддерживает этот тип сокк _ необработанного сокета.
Существует два основных типа таких необработанных сокетов:
- Первый тип использует известный тип протокола, записанный в IP-заголовке, который распознается поставщиком службы Winsock. Примером первого типа сокета является сокет для протокола ICMP (тип протокола IP = 1) или протокол ICMPv6 (IP протокола Type = 58).
- Второй тип позволяет указать любой тип протокола. Примером второго типа будет экспериментальный протокол, который не поддерживается напрямую поставщиком службы Winsock, например протоколом передачи управления потоком (SCTP).
Определение поддержки необработанных сокетов
Если поставщик услуг Winsock поддерживает Сокк _ необработанные сокеты для _ семейств адресов AF inet или AF _ INET6, тип сокета Сокк _ RAW должен включаться в структуру всапротокол _ info , возвращаемую функцией всаенумпротоколс для одного или нескольких доступных поставщиков транспорта.
Элемент иаддрессфамили в структуре _ сведений о всапротокол должен указывать AF _ inet или AF _ INET6, а элемент исоккеттипе структуры всапротокол должен указать _ Сокк _ RAW для одного из поставщиков транспорта.
Элемент ипротокол структуры _ info Всапротокол может иметь значение ипрото _ IP. Элемент ипротокол структуры _ info всапротокол также может иметь нулевое значение, если поставщик услуг позволяет приложению использовать тип _ необработанного сокета Сокк для других сетевых протоколов, отличных от протокола Интернета для семейства адресов.
в Windows XP и более поздних версиях можно использовать команду NetSh.exe , чтобы определить, поддерживаются ли необработанные сокеты. Следующая команда из окна CMD выводит данные из каталога Winsock в консоли:
Netsh Winsock показывать каталог
Выходные данные будут содержать список, содержащий некоторые данные из структур всапротокол _ info , поддерживаемых на локальном компьютере. Найдите термин RAW/IP или RAW/IPv6 в поле Описание, чтобы найти протоколы, поддерживающие необработанные сокеты.
Создание необработанного сокета
Чтобы создать сокет типа Сокк _ RAW, вызовите функцию Socket или всасоккет с параметром AF (семейство адресов), для которого задано значение AF _ inet или AF _ INET6, параметру Type задано значение Сокк _ RAW, а параметру протокола задано значение требуемого номера протокола. Параметр протокола становится значением протокола в IP-заголовке (например, SCTP — 132).
Приложение не может указывать нуль (0) в качестве параметра протокола для функций Socket, всасоккети вспсоккет , если для параметра Type задано значение Сокк _ RAW.
Необработанные сокеты предоставляют возможность управлять базовым транспортом, поэтому их можно использовать для вредоносных целей, представляющих угрозу безопасности. таким образом, только члены группы "администраторы" могут создавать сокеты типа сокк _ RAW на Windows 2000 и более поздних версиях.
Операции отправки и получения
Когда приложение создает сокет типа Сокк _ RAW, этот сокет можно использовать для отправки и получения данных. Все пакеты, отправленные или полученные на сокете типа Сокк _ RAW , обрабатываются как датаграммы на неподключенном сокете.
К операциям по Сокк _ необработанным сокетам применяются следующие правила.
При отправке данных 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.
Для IPv6 (семейство адресов AF _ INET6) приложение получает все после последнего заголовка IPv6 в каждой полученной датаграмме независимо от параметра сокета IPv6 _ хдринкл . Приложение не получает заголовки IPv6, используя необработанный сокет.
Полученные датаграммы копируются во все _ необработанные сокеты Сокк, которые отвечают следующим условиям:
- Номер протокола, указанный в параметре протокола при создании сокета, должен соответствовать номеру протокола в IP-заголовке полученной датаграммы.
- Если для сокета определен локальный IP-адрес, он должен соответствовать адресу назначения, указанному в заголовке IP полученной датаграммы. Приложение может указать локальный IP-адрес, вызвав функцию BIND . Если для сокета не указан локальный IP-адрес, датаграммы копируются в сокет независимо от IP-адреса назначения в IP-заголовке полученной датаграммы.
- Если для сокета определен внешний адрес, он должен соответствовать адресу источника, указанному в заголовке IP полученной датаграммы. Приложение может указать внешний IP-адрес, вызвав функцию Connect или всаконнект . Если для сокета не указан внешний IP-адрес, датаграммы копируются в сокет независимо от IP-адреса источника в IP-заголовке полученной датаграммы.
Для использования сокета типа Сокк _ RAW требуются права администратора. Пользователи, запускающие приложения Winsock, использующие необработанные сокеты, должны быть членами группы "Администраторы" на локальном компьютере, в противном случае вызовы необработанных сокетов завершатся ошибкой с кодом всаеакцес. в Windows Vista и более поздних версиях доступ к необработанным сокетам применяется при создании сокета. в более ранних версиях Windows доступ к необработанным сокетам применяется во время других операций сокета.
Распространенные способы использования необработанных сокетов
Одним из распространенных способов использования необработанных сокетов являются приложения для устранения неполадок, требующие подробного анализа пакетов и заголовков IP. Например, необработанный сокет можно использовать с SIO _ РКВАЛЛ ioctl, чтобы обеспечить получение сокетом всех пакетов IPv4 или IPv6, передаваемых через сетевой интерфейс. Дополнительные сведения см. в справочнике по SIO _ рквалл .
Ограничения для необработанных сокетов
в Windows 7, Windows Vista, Windows XP с пакетом обновления 2 (sp2) и Windows XP с пакетом обновления 3 (sp3) возможность отправки трафика через необработанные сокеты ограничена несколькими способами:
- Данные TCP не могут быть отправлены через необработанные сокеты.
- UDP-датаграммы с недопустимым исходным адресом не могут быть отправлены через необработанные сокеты. IP-адрес источника для любой исходящей датаграммы UDP должен существовать в сетевом интерфейсе, или датаграмма удалена. Это изменение было сделано, чтобы ограничить способность вредоносного кода создавать распределенные атаки типа "отказ в обслуживании" и ограничивает возможность отправки ложных пакетов (пакетов TCP/IP с подложным исходным IP-адресом).
- Вызов функции BIND с необработанным сокетом для _ протокола TCP иппрото не разрешен.
Функция 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).
Приложениям также необходимо учитывать влияние параметров брандмауэра на отправку и получение пакетов с помощью необработанных сокетов.
Представляем вашему вниманию гайд по работе с сырыми сокетами (SOCK_RAW). Не пугайтесь, здесь автоперевод. Если есть желание (и знание английского языка), в конце статьи ссылка на первоисточник.
Статья за 2008 год. И вместе с тем, в качестве примера тут C++. А это, как известно, классика .
0x1. Вступление
Мы по этой причине собираюсь углубиться во внутреннее устройство сетевого стека. Предполагается, что читатель уже имеет некоторый опыт работы с сокетами и готов взглянуть на некоторый код ядра, поскольку реализация сырых сокетов фактически зависит от ОС. Мы будет охватывать реализации как FreeBSD 7.0, так и Linux 2.6. Большинство вещей покрыто для FreeBSD может также применяться к OpenBSD, NetBSD и даже MAC OS X.
0x2. Создание
Перво-наперво. Создание. Как создается сырой сокет? Какие основные в хитросплетениях? Необработанный сокет создается путем вызова системного вызова socket (2) и определив тип сокета как SOCK_RAW следующим образом:
Прежде чем переходить к конкретным комбинациям для каждой ОС, давайте сначала рассмотрим посмотрите на фактическое значение значения * протокола *. Чтобы все протоколы работали одновременно был использован конкретный общий подход к проектированию. Согласно ему, похожие протоколы сгруппированы в домены. Домен обычно определяется тем, что называется семейством протоколов или семейством адресов (последнее является самым последним практика) и ряд констант используются для различения между ними. В самые распространенные из них:
FreeBSD определяет указанные выше значения (почти такие же) в /usr/src/sys/sys/socket.h Как вы уже догадались, мы займемся Семья AF_INET. Семейство Интернета разбивает свои протоколы на протокол типы, каждый из которых может состоять более чем из одного протокол.
Linux определяет типы протоколов семейства Интернет в /usr/src/linux-2.6.*/include/linux/net.h
Это одно из самых важных полей, поскольку именно оно будет использоваться уровень IP на стороне получателя, чтобы понять, какой уровень находится над ним (для пример TCP или UDP) дейтаграмма должна быть доставлена.
Linux определяет эти протоколы в /usr/src/linux-2.6.*/include/linux/in.h
Во 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 для ясности.
Необработанная запись с подстановочными знаками (та, у которой .pr_protocol не присвоено значение и, следовательно, имеющий значение 0) определяется как последний член массива inetsw [] в /usr/src/sys/netinet/in_proto.h:
Вернемся к поиску, который выглядит так:
pffindtype:
- найти соответствующий домен через значение * family *
- вернуть первую запись соответствующего protosw таблица, которая соответствует *type* значению
обе функции возвращают запись inetsw [] (то есть указатель protosw * на соответствующее смещение массива) /usr/src/sys/kernel/uipc_domain.c:
Изучая приведенный выше код, мы замечаем еще одно важное значение SOCK_RAW. По сути, последние несколько строк pffindproto () используют SOCK_RAW как резервный протокол по умолчанию. Это означает, что если пользовательское приложение вызывает socket (2) вот так: сокет
где протокол со значением 30 не указан в ядре, то вместо в случае неудачи используется wildcard_RAW. Это потому, что это единственный protosw struct в массиве inetsw [], содержащем .pr_protocol равным 0 и pr_type равным SOCK_RAW.
То же самое и с таким вызовом:
Тип SOCK_RAW и IPPROTO_TCP не совпадают, поскольку SOCK_RAW имеет только записи для ICMP, IGMP и сырого IP. Однако это идеальный правильный вызов, поскольку ядро вернет подстановочный знак SOCK_RAW.
Это касается FreeBSD. Что касается Linux, возможно, у вас уже есть видно из фрагмента кода сверху (in.h), значение * 0 * на самом деле определяется как другой тип протокола для TCP. Эта практика имеет сильный эффект в переносе приложений между * BSD и Linux. Например, для * BSD это верный:
Случай 8 демонстрирует, как Linux использует SOCK_RAW в качестве резервного протокола, как и мы видели выше с FreeBSD.
Это не единственные различия между двумя системами. Мы обсудим больше из них дальше.
Читайте также: