Литмир - Электронная Библиотека
Содержание  
A
A
ПРИМЕЧАНИЕ

Пользователи обычно задают имя интерфейса le0 или ether0, а IP-адрес и индекс интерфейса не используются. Например, tcpdump является одной из немногих программ, позволяющих пользователю задавать интерфейс, а ее параметр -i принимает имя интерфейса в качестве аргумента.

Функция

mcast_leave
выводит узел из группы с IP-адресом, содержащимся в структуре адреса сокета, на которую указывает аргумент
grp
.

Функция

mcast_block_source
блокирует получение через конкретный сокет пакетов, относящихся к определенной группе и исходящих от определенного источника. IP-адреса группы и источника хранятся в структурах адреса сокета, на которые указывают аргументы
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
непустой, он задает имя интерфейса. Иначе положительное значение аргумента
ifindex
будет задавать индекс интерфейса. В случае IPv6 имя сопоставляется индексу с использованием функции
if_nametoindex
. В случае IPv4 сопоставление имени или индекса IP-адресу направленной передачи интерфейса происходит так же, как для функции
mcast_join
.

Функция

mcast_set_loop
устанавливает параметр закольцовки либо в 0, либо в 1, а функция
mcast_set_ttl
TTL в случае IPv4 или предел количества транзитных узлов в случае IPv6. Функции
mcast_get_XXX
возвращают соответствующие значения.

Пример: функция mcast_join

В листинге 21.1[1] показана первая часть функции

mcast_join
. Эта часть демонстрирует простоту интерфейса программирования, не зависящего от протокола.

Листинг 21.1. Присоединение к группе: сокет IPv4

//lib/mcast_join.c

 1 #include "unp.h"

 2 #include <net/if.h>

 3 int

 4 mcast_join(int sockfd, const SA *grp, socklen_t grplen,

 5 const char *ifname, u_int ifindex)

 6 {

 7 #ifdef MCAST_JOIN_GROUP

 8  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  } else

17  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
определяется на основании семейства группового адреса вызовом нашей собственной функции
family_to_level
. Некоторые системы допускают несоответствие аргумента level семейству адреса сокета, например использование
IPPROTO_IP
с
MCAST_JOIN_GROUP
, даже если сокет относится к семейству
AF_INET6
, но это верно не для всех систем, поэтому мы и должны выполнить преобразование семейства к нужному значению
level
. Листинг этой тривиальной функции в книге мы не приводим, но исходный код этой функции вы можете скачать вместе со всеми остальными программами.

вернуться

1

Все исходные коды программ, опубликованные в этой книге, вы можете найти по адресу http://www.piter.com.

234
{"b":"225366","o":1}