Вход/Регистрация
Разработка приложений в среде Linux. Второе издание
вернуться

Троан Эрик В.

Шрифт:

Программы, работающие на машинах IPv6 и требующие обращения к машинам IPv4, могут использовать отображенные IPv4-адреса. Они дополняют IPv4-адрес 80-ю нулевыми старшими разрядами и 16-битным значением

0xffff
, которое записывается как
::ffff:
, а за ним следует десятичный IPv4-адрес с точками. Подобная адресация позволяет большинству программ в системе, поддерживающей только версию IPv6, явно общаться с узлами IPv4.

IPv6-адреса хранятся в переменных типа

struct sockaddr_in6
.

#include <sys/socket.h>

#include <netinet/in.h>

struct sockaddr_in6 {

 short int sin6_family; /* AF_INET6 */

 unsigned short int sin6_port; /* номер порта */

 unsigned int sin6_flowinfo; /* информация о потоке обмена IPv6 */

 struct in6_addr sin6_addr; /* IP-адрес */

 unsigned int sin6_scope_id; /* набор граничных интерфейсов */

}

Данная структура подобна

struct sockaddr_in
; здесь первый член сохраняет семейство адресов (в этом примере
AF_INET6
), а следующий — 16-битный номер порта в сетевом порядке байтов.

Четвертый член содержит двоичное представление IPv6-адреса, выполняя те же самые функции, что и последний член структуры

struct sockaddr_in
. Оставшиеся два элемента
sin6_flowinfo
и
sin6_scope_id
используются в более сложных задачах и для большинства приложений должны быть равны нулю.

Стандарты ограничивают

struct sockaddr_in
в точности тремя членами, тогда как
struct sockaddr_in6
позволительно иметь дополнительные элементы. По этой причине программы, которые вручную заполняют
struct sockaddr_in6
, должны обнулить все данные структуры с помощью функции
memset
.

17.5.4. Манипулирование IP-адресами

В приложениях нередко требуется преобразовывать IP-адреса из удобочитаемых для человека представлений (либо десятичное с разделителями-точками, либо с разделителями-двоеточиями) в двоичное представление

struct in_addr
и наоборот. Функция
inet_ntop
принимает двоичный IP-адрес и возвращает указатель на строку, содержащую десятичную форму с точками или двоеточиями.

#include <arpa/inet.h>

const char * inet_ntop(int family, const void * address, char * dest,

 int size);

Здесь

family
— это адресное семейство того адреса, который передается во втором параметре; поддерживаются только
AF_INET
и
AF_INET6
. Следующий параметр указывает на
struct in_addr
или
struct in6_addr6
в зависимости от первого параметра. Значение
dest
представляет массив символов, состоящий из
size
элементов, в котором хранится адрес, удобочитаемый для человека. Если форматирование адреса прошло успешно, то функция
inet_ntop
возвращает
dest
, в противном случае возвращается
NULL
. Существуют только две причины, по которым
inet_ntop
может не выполнить свою работу: если буфер назначения недостаточно велик для хранения форматированного адреса (переменной errno присваивается значение
ENOSPC
) или если параметр
family
задан неверно (errno содержит
EAFNOSUPPORT
).

INET_ADDRSTRLEN
является константой, определяющей наибольший размер
dest
, необходимый для хранения любого IPv4-адреса. Соответственно,
INET6_ADDRSTRLEN
определяет максимальный размер массива для IPv6-адреса.

Программа-пример

netlookup.с
демонстрирует использование
inet_ntop
; полная программа представлена далее в этой главе.

120: if (addr->ai_family == PF_INET) {

121: struct sockaddr_in * inetaddr = (void*)addr->ai_addr;

122: char nameBuf[INET_ADDRSTRLEN];

123:

124: if (serviceName)

125: printf("\tport %d", ntohs(inetaddr->sin_port));

126:

127: if (hostName)

128: printf("\thost %s",

129: inet_ntop(AF_INET, &inetaddr->sin_addr,

130: nameBuf, sizeof(nameBuf)));

131: } else if (addr->ai_family == PF_INET6) {

132: struct sockaddr_in6 *inetaddr =

133: (void *) addr->ai_addr;

134: char nameBuf[INET6_ADDRSTRLEN];

135:

136: if (serviceName)

137: printf("\tport %d", ntohs(inetaddr->sin6_port));

138:

139: if (hostName)

140: printf("\thost %s",

141: inet_ntop(AF_INET6, &inetaddr->sin6_addr,

  • Читать дальше
  • 1
  • ...
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: