UNIX: разработка сетевых приложений
Часть 234 из 399 Информация о книге
ПРИМЕЧАНИЕПользователи обычно задают имя интерфейса le0 или ether0, а IP-адрес и индекс интерфейса не используются. Например, tcpdump является одной из немногих программ, позволяющих пользователю задавать интерфейс, а ее параметр -i принимает имя интерфейса в качестве аргумента.
Функция
выводит узел из группы с IP-адресом, содержащимся в структуре адреса сокета, на которую указывает аргументmcast_leave.grpФункция
блокирует получение через конкретный сокет пакетов, относящихся к определенной группе и исходящих от определенного источника. IP-адреса группы и источника хранятся в структурах адреса сокета, на которые указывают аргументыmcast_block_sourceиgrpсоответственно. Длины структур задаются параметрамиsrcиsrclen. Для успешного завершения функции необходимо, чтобы до ее вызова уже была вызвана функцияgrplenдля того же сокета и той же группы.mcast_joinФункция
разблокирует получение трафика от источника из заданной группы. Аргументыmcast_unblock_source,src,srclenиgrpимеют тот же смысл, что и аргументы предыдущей функции, и должны совпадать с ними по значениям.grplenФункция
выполняет присоединение к группе источника. Адрес источника и адрес группы содержатся в структурах адреса сокета, на которые указывают аргументыmcast_join_source_groupиsrc. Длины структур задаются параметрамиgrpиsrclen. Интерфейс, присоединяемый к группе, может быть задан именем (ненулевой аргументgrplen) или индексом (ifname). Если интерфейс не задан явно, ядро выбирает его самостоятельно.ifindexФункция
выполняет отсоединение от группы источника. Адреса источника и группы содержатся в структурах адреса сокета, на которые указывают аргументыmcast_leave_source_groupиsrc. Длины структур задаются параметрамиgrpиsrclen. Подобноgrplen,mcast_leaveне требует указания интерфейса: она всегда отсоединяет от группы первый интерфейс, удовлетворяющий условиям.mcast_leave_source_groupФункция
устанавливает индекс интерфейса по умолчанию для исходящих дейтаграмм многоадресной передачи. Если аргументmcast_set_ifнепустой, он задает имя интерфейса. Иначе положительное значение аргументаifnameбудет задавать индекс интерфейса. В случае IPv6 имя сопоставляется индексу с использованием функцииifindex. В случае IPv4 сопоставление имени или индекса IP-адресу направленной передачи интерфейса происходит так же, как для функцииif_nametoindex.mcast_joinФункция
устанавливает параметр закольцовки либо в 0, либо в 1, а функцияmcast_set_loopTTL в случае IPv4 или предел количества транзитных узлов в случае IPv6. Функцииmcast_set_ttlвозвращают соответствующие значения.mcast_get_XXXПример: функция mcast_join
В листинге 21.1 [1] показана первая часть функции
. Эта часть демонстрирует простоту интерфейса программирования, не зависящего от протокола.mcast_joinЛистинг 21.1. Присоединение к группе: сокет IPv4
//lib/mcast_join.c1 #include "unp.h"2 #include <net/if.h>3 int4 mcast_join(int sockfd, const SA *grp, socklen_t grplen,5 const char *ifname, u_int ifindex)6 {7 #ifdef MCAST_JOIN_GROUP8 struct group_req req;9 if (ifindex > 0) {10 req.gr_interface = ifindex;11 } else if (ifname != NULL) {12 if ((req.gr_interface = if_nametoindex(ifname)) == 0) {13 errno = ENXIO; /* интерфейс не найден */14 return(-1);15 }16 } else17 req.gr_interface = 0;18 if (grplen > sizeof(req.gr_group)) {19 errno = EINVAL;20 return -1;21 }22 memcpy(&req.gr_group, grp, grplen);23 return (setsockopt(sockfd, family_to_level(grp->sa_family),24 MCAST_JOIN_GROUP, &req, sizeof(req)));25 #elseОбработка индексаЕсли при вызове был указан индекс интерфейса, функция использует его непосредственно. В противном случае (при указании имени интерфейса), имя преобразуется в индекс вызовом9-17. Если ни имя, ни индекс не заданы, интерфейс выбирается ядром.if_nametoindexКопирование адреса и вызов setsockoptАдрес сокета копируется непосредственно в поле группы. Вспомните, что поле это имеет тип18-22, а потому достаточно велико для хранения адреса любого типа, поддерживаемого системой. Для предотвращения переполнения буфера (при ошибках в программе) мы проверяем размерsockaddr_storageи возвращаемsockaddr, если он слишком велик.EINVALПрисоединение к группе выполняется вызовом23-24. Аргументsetsockoptопределяется на основании семейства группового адреса вызовом нашей собственной функцииlevel. Некоторые системы допускают несоответствие аргумента level семейству адреса сокета, например использованиеfamily_to_levelсIPPROTO_IP, даже если сокет относится к семействуMCAST_JOIN_GROUP, но это верно не для всех систем, поэтому мы и должны выполнить преобразование семейства к нужному значениюAF_INET6. Листинг этой тривиальной функции в книге мы не приводим, но исходный код этой функции вы можете скачать вместе со всеми остальными программами.level