39 Inet_ntop(AF_INET6, &hip6->ip6_src, srcstr, sizeof(srcstr)),
40 Inet_ntop(AF_INET6, &hip6->ip6_dst, dststr, sizeof(dststr)),
41 hip6->ip6_nxt);
42 if (hip6->ip6_nxt == IPPROTO_UDP) {
43 udp = (struct udphdr*)(buf + 8 + hlen2);
44 sport = udp->uh_sport;
45 /* поиск доменного сокета клиента, отправка заголовков */
46 for (i = 0; i = 0 &&
48 client[i].family == AF_INET6 &&
49 client[i].lport == sport) {
50 bzero(&dest, sizeof(dest));
51 dest.sin6_family = AF_INET6;
52 #ifdef HAVE_SOCKADDR_SA_LEN
53 dest.sin6_len = sizeof(dest);
54 #endif
55 memcpy(&dest.sin6_addr, &hip6->ip6_dst,
56 sizeof(struct in6_addr));
57 dest.sin6_port = udp->uh_dport;
58 icmpd_err.icmpd_type = icmp6->icmp6_type;
59 icmpd_err.icmpd_code = icmp6->icmp6_code;
60 icmpd_err.icmpd_len = sizeof(struct sockaddr_in6);
61 memcpy(&icmpd_err.icmpd_dest, &dest, sizeof(dest));
62 /* преобразование типа и кода ICMPv6 к значению errno */
63 icmpd_err.icmpd_errno = EHOSTUNREACH; /* по умолчанию */
64 if (icmp6->icmp6_type == ICMP6_DST_UNREACH &&
65 icmp6->icmp6_code ICMP6_DST_UNREACH_NOPORT)
66 icmpd_err.icmpd_errno = ECONNREFUSED;
67 if (icmp6->icmp6_type == ICMP6_PACKET_TOO_BIG)
68 icmpd_err.icmpd_errno = EMSGSIZE;
69 Write(client[i].connfd, &icmpd_err, sizeof(icmpd_err));
70 }
71 }
72 }
73 }
74 return(--nready);
75 #endif
76 }
Символьные сокеты обеспечивают три возможности:
1. Чтение и запись пакетов ICMPv4, IGMPv4 и ICMPv6.
2. Чтение и запись IP-дейтаграммы с полем протокола, которое не обрабатывается ядром.
3. Формирование своих собственных заголовков IPv4, обычно используемых в диагностических целях (или, к сожалению, хакерами).
Два традиционных диагностических средства — программы ping
и traceroute
— используют символьные сокеты. Мы разработали наши собственные версии этих программ, поддерживающие обе версии протокола — и IPv4, и IPv6. Также нами разработан наш собственный демон icmpd
, который обеспечивает доступ к сообщениям об ошибках ICMP через сокет UDP. Данный пример также иллюстрирует передачу дескриптора через доменный сокет Unix между неродственными клиентом и сервером.
1. В этой главе говорилось, что почти все поля заголовка IPv6 и все дополнительные заголовки доступны приложению через параметры сокета или вспомогательные данные. Какая информация из дейтаграммы IPv6 не доступна приложению?
2. Что произойдет в листинге 28.30, если по какой-либо причине клиент перестанет производить считывание из своего доменного сокета Unix и демон icmpd
накопит множество сообщений для данного клиента? В чем заключается простейшее решение этой проблемы?
3. Если задать нашей программе ping
адрес широковещательной передачи, направленный в подсеть, она будет работать. То есть широковещательный эхо- запрос ICMP посылается как широковещательный запрос канального уровня, даже если мы не установим параметр сокета SO_BROADCAST
. Почему?
4. Что произойдет с программой ping
, если мы запустим ее на узле с несколькими интерфейсами, а в качестве аргумента имени узла возьмем групповой адрес 224.0.0.1?
Глава 29
Доступ к канальному уровню
В настоящее время большинство операционных систем позволяют приложению получать доступ к канальному уровню. Это подразумевает следующие возможности:
1. Отслеживание пакетов, принимаемых на канальном уровне, что, в свою очередь, позволяет запускать такие программы, как tcpdump
, на обычных компьютерных системах (а не только на специальных аппаратных устройствах для отслеживания пакетов). Если добавить к этому способность сетевого интерфейса работать в смешанном режиме ( promiscuous mode ), приложение сможет отслеживать все пакеты, проходящие по локальному кабелю, а не только предназначенные для того узла, на котором работает эта программа.
ПРИМЕЧАНИЕ
Эта возможность не так полезна в коммутируемых сетях, которые получили широкое распространение в последнее время. Дело в том, что коммутатор пропускает трафик на конкретный порт только в том случае, если этот трафик адресован конкретному устройству или устройствам, подключенным к этому порту, каким бы трафик ни был: направленным, широковещательным или многоадресным. Для того чтобы получать трафик, передаваемый через другие порты коммутатора, нужно сначала переключить свой порт коммутатора в режим контроля (monitor mode или port mirroring). Заметьте, что многие устройства, которые обычно не считают коммутаторами, на самом деле являются таковыми. Например, двухскоростной концентратор 10/100 обычно является двухпортовым коммутатором: один порт для сетей, работающих на 100 Мбит/с, другой — для сетей на 10 Мбит/с.
Читать дальше
Конец ознакомительного отрывка
Купить книгу