UNIX: разработка сетевых приложений, стр. 235
В листинге 21.2 представлена вторая часть функции
mcast_joinЛистинг 21.2. Присоединение к группе: обработка сокета IPv4
26 switch (grp->sa_family) {27 case AF_INET: {28 struct ip_mreq mreq;29 struct ifreq ifreq;30 memcpy(&mreq.imr_multiaddr,31 &((const struct sockaddr_in*)grp)->sin_addr,32 sizeof(struct in_addr));33 if (ifindex > 0) {34 if (if_indextoname(ifindex, ifreq.ifr_name) == NULL) {35 errno = ENXIO; /* i/f index not found */36 return(-1);37 }38 goto doioctl;39 } else if (ifname != NULL) {40 strncpy(ifreq.ifr_name, ifname, IFNAMSIZ);41 doioctl:42 if (ioctl(sockfd, SIOCGIFADDR, &ifreq) < 0)43 return(-1);44 memcpy(&mreq.imr_interface,45 &((struct sockaddr_in*)&ifreq.ifr_addr)->sin_addr,46 sizeof(struct in_addr));47 } else48 mreq.imr_interface.s_addr = htonl(INADDR_ANY);49 return(setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP,50 &mreq, sizeof(mreq)));51 }Обработка индекса
33-38ip_mreqif_indextonameip_mreqioctlОбработка имени
39-46ip_mreqSIOCGIFADDRioctlimr_interfaceip_mreqЗначения по умолчанию
47-4849-50setsockoptТретья, и последняя, часть функции, обрабатывающая сокеты IPv6, приведена в листинге 21.3.
Листинг 21.3. Присоединение к группе: обработка сокета IPv6
52 #ifdef IPV653 case AF_INET6: {54 struct ipv6_mreq mreq6;55 memcpy(&mreq6.ipv6mr_multiaddr,56 &((const struct sockaddr_in6*) grp)->sin6_addr,57 sizeof(struct in6_addr));58 if (ifindex > 0) {59 mreq6.ipv6mr_interface = ifindex;60 } else if (ifname != NULL) {61 if ((mreq6.ipv6mr_interface = if_nametoindex(ifname)) == 0) {62 errno = ENXIO; /* интерфейс не найден */63 return(-1);64 }65 } else66 mreq6.ipv6mr_interface = 0;67 return(setsockopt(sockfd, IPPROTO_IPV6, IPV6_JOIN_GROUP,68 &mreq6, sizeof(mreq6)));69 }70 #endif71 default:72 errno = EAFNOSUPPORT;73 return(-1);74 }75 #endif76 }Копирование адреса
55-57ipv6_mreqОбработка индекса или имени интерфейса или выбор интерфейса по умолчанию
58-66ipv6mr_interfaceif_nametoindexsetsockopt67-68Пример: функция mcast_set_loop
В листинге 21.4 показана наша функция
mcast_set_loopПоскольку аргументом является дескриптор сокета, а не структура адреса сокета, мы вызываем нашу функцию
sockfd_to_familyМы не показываем исходный код для всех остальных функций
mcast_<i>XXX</i>Листинг 21.4. Установка параметра закольцовки для многоадресной передачи
//lib/mcast_set_loop.c 1 #include "unp.h" 2 int 3 mcast_set_loop(int sockfd, int onoff)