UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
29.3. DLPI: интерфейс поставщика канального уровня
SVR4 обеспечивает доступ к канальному уровню через DLPI (Data Link Provider Interface — интерфейс поставщика канального уровня). DLPI — это не зависящий от протокола интерфейс, разработанный в AT&T и служащий средством связи с сервисами, обеспечиваемыми канальным уровнем [124]. Доступ к DLPI осуществляется посредством отправки и получения сообщений через потоки STREAMS.
Для подсоединения к канальному уровню приложение просто открывает устройство (например,
le0
DL_ATTACH_REQ
pfmod
bufmod
Рис. 29.2. Захват пакета с использованием DLPI, pfmod и bufmod
Концептуально DLPI аналогичен BPF.
pfmod
bufmod
Одно интересное различие, тем не менее, заключается в том, что для BPF и фильтров
pfmod
pfmod
Еще одно отличие состоит в том, что BPF всегда выполняет фильтрацию перед копированием пакета, чтобы не копировать те пакеты, которые будут сброшены фильтром. В некоторых реализациях DLPI пакеты сначала копируются в модуль
pfmod
29.4. Linux: SOCK_PACKET и PF_PACKET
Существует два метода получения пакетов канального уровня в Linux. Первоначальный метод получил более широкое распространение, но является менее гибким. Он состоит в создании сокета типа
SOCK_PACKET
PF_PACKET
PF_PACKET
socket
SOCK_DGRAM
SOCK_RAW
SOCK_PACKET
fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); /* в новых системах */
или
fd = socket(AF_INET, SOCK_PACKET, htons(ETH_P_ALL)); /* в старых системах */
В результате этого будут возвращены кадры для всех протоколов, получаемые канальным уровнем. Если нам нужны кадры IPv4, то вызов будет таким:
fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP)); /* в новых системах */
fd = socket(AF_INET, SOCK_PACKET, htons(ETH_P_IP)); /* в старых системах */
Другие константы, которые могут использоваться в качестве последнего аргумента, — это, например,
ETH_P_ARP
ETH_P_IPV6
Указывая протокол
ETH_P_ххх
PACKET_ADD_MEMBERSHIP
packet_mreq
PACKET_MR_PROMISC
ioctl
SIOCGIFFLAGS
IFF_PROMISC
SIOCSIFFLAGS
Сравнивая это средство Linux с BPF и DLPI, мы можем отметить некоторые различия.
1. В Linux не обеспечивается буферизация. Фильтрация на уровне ядра доступна только в новых системах (при помощи параметра
SO_ATTACH_FILTER
2. В Linux не предусмотрена фильтрация на уровне устройства. Сокеты
PF_PACKET
bind
socket
ETH_P_IP
recvfrom
sa_data
eth0
29.5. Libcap: библиотека для захвата пакетов
Библиотека захвата пакетов
libcap