Mir-knigi.online
Книги онлайн читать бесплатно!
  • Главная
  • Жанры
  • ТОП книг
  • ТОП авторов
  • Контакты

UNIX: разработка сетевых приложений

Часть 195 из 399 Информация о книге

19-20
 Если функция
ioctl
возвращает ошибку
EINVAL
и функция еще не возвращалась успешно (то есть
lastlen
все еще равно нулю), значит, мы еще не выделили буфер достаточного размера, поэтому мы продолжаем выполнять цикл.

22-23
 Если функция
ioctl
завершается успешно и возвращаемая длина равна
lastlen
, значит, длина не изменилась (наш буфер имеет достаточный размер), и мы с помощью функции
break
выходим из цикла, так как у нас имеется вся информация.

26-27
 В каждом проходе цикла мы увеличиваем размер буфера для хранения еще 10 структур
ifreq
.

Инициализация указателей связного списка

29-31
 Поскольку мы будем возвращать указатель на начало связного списка структур
ifi_info
, мы используем две переменные
ifihead
и
ifipnext
для хранения указателей на список по мере его создания.

Следующая часть нашей функции

get_ifi_info
, содержащая начало основного цикла, показана в листинге 17.5.

Листинг 17.5. Конфигурация интерфейса процесса

//lib/get_ifi_info.c

34 for (ptr = buf; ptr < buf + ifc.ifc_len; ) {

35  ifr = (struct ifreq*)ptr;

36 #ifdef HAVE_SOCKADDR_SA_LEN

37  len = max(sizeof(struct sockaddr), ifr->ifr_addr.sa_len);

38 #else

39  switch (ifr->ifr_addr.sa_family) {

40 #ifdef IPV6

41  case AF_INET6:

42   len = sizeof(struct sockaddr_in6);

43   break;

44 #endif

45  case AF_INET:

46  default:

47   len = sizeof(struct sockaddr);

48   break;

49  }

50 #endif /* HAVE_SOCKADDR_SA_LEN */

51  ptr += sizeof(ifr->ifr_name) + len; /* для следующей строки */

52 #ifdef HAVE_SOCKADDR_DL_STRUCT

53  /* предполагается, что AF_LINK идет перед AF_INET и AF_INET6 */

54  if (ifr->ifr_addr.sa_family == AF_LINK) {

55   struct sockaddr_dl *sdl = (struct sockaddr_dl*)&ifr->ifr_addr;

56   sdlname = ifr->ifr_name;

57   idx = sdl->sdl_index;

58   haddr = sdl->sdl_data + sdl->sdl_nlen;

59   hlen = sdl->sdl_alen;

60  }

61 #endif

62  if (ifr->ifr_addr.sa_family != family)

63   continue; /* игнорируется, если семейство адреса не то */

64  myflags = 0;

65  if ((cptr = strchr(ifr->ifr_name, ':')) != NULL)

66   *cptr = 0; /* замена двоеточия нулем */

67  if (strncmp(lastname, ifr->ifr_name, IFNAMSIZ) == 0) {

68   if (doaliases == 0)

69    continue; /* этот интерфейс уже обработан */

70   myflags = IFI_ALIAS;

71  }

72  memcpy(lastname, ifr->ifr_name, IFNAMSIZ);

73  ifrcopy = *ifr;

74  Ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy);

75  flags = ifrcopy.ifr_flags;

76  if ((flags & IFF_UP) == 0)

77   continue; /* игнорируется, если интерфейс не используется */

Переход к следующей структуре адреса сокета

35-51
 При последовательном просмотре всех структур i
freq ifr
указывает на текущую структуру, а мы увеличиваем
ptr
на единицу, чтобы он указывал на следующую. Необходимо предусмотреть особенность более новых систем, предоставляющих поле длины для структур адреса сокета, и вместе с тем учесть, что более старые системы этого поля не предоставляют. Хотя в листинге 17.1 структура адреса сокета, содержащаяся в структуре
ifreq
, объявляется как общая структура адреса сокета, в новых системах она может относиться к произвольному типу. Действительно, в 4.4BSD структура адреса сокета канального уровня также возвращается для каждого интерфейса [128, с. 118]. Следовательно, если поддерживается элемент длины, то мы должны использовать его значение для переустановки нашего указателя на следующую структуру адреса сокета. В противном случае мы определяем длину, исходя из семейства адресов, используя размер общей структуры адреса сокета (16 байт) в качестве значения по умолчанию.

ПРИМЕЧАНИЕ

В системах, поддерживающих IPv6, не оговаривается, возвращается ли адрес IPv6 вызовом SIOCGIFCONF. Для более новых систем мы вводим оператор case, в котором предусмотрена возможность возвращения адресов IPv6. Проблема состоит в том, что объединение в структуре ifreq определяет возвращаемые адреса как общие 16-байтовые структуры sockaddr, подходящие для 16-байтовых структур sockaddr_in IPv4, но для 24-байтовых структур sockaddr_in6 IPv6 они слишком малы. В случае возвращения адресов IPv6 возможно некорректное поведение существующего кода, созданного в предположении, что в каждой структуре ifreq содержится структура sockaddr фиксированного размера. В системах, где структура sockaddr имеет поле sa_len, никаких проблем не возникает, потому что такие системы легко могут указывать размер структур sockaddr.

52-60
 Если система возвращает структуры
sockaddr
семейства
AF_LINK
в
SIOCGIFCONF
, мы копируем индекс интерфейса и данные об аппаратном адресе из таких структур.

62-63
 Мы игнорируем все адреса из семейств, отличных от указанного вызывающим процессом в аргументе функции
get_ini_info
.


Перейти к странице:
Предыдущая страница
Следующая страница
Жанры
  • Военное дело
  • Деловая литература
  • Детективы и триллеры
  • Детские
  • Детские книги
  • Документальная литература
  • Дом и дача
  • Дом и Семья
  • Жанр не определен
  • Зарубежная литература
  • Знания и навыки
  • История
  • Компьютеры и Интернет
  • Легкое чтение
  • Любовные романы
  • Научно-образовательная
  • Образование
  • Поэзия и драматургия
  • Приключения
  • Проза
  • Прочее
  • Психология и мотивация
  • Публицистика и периодические издания
  • Религия и духовность
  • Родителям
  • Серьезное чтение
  • Спорт, здоровье и красота
  • Справочная литература
  • Старинная литература
  • Техника
  • Фантастика и фентези
  • Фольклор
  • Хобби и досуг
  • Юмор
Mir-knigi.online

Бесплатная онлайн библиотека для чтения книг без регистрации с телефона или компьютера. У нас собраны последние новинки, мировые бестселлеры книжного мира.

Контакты
  • [email protected]
Информация
  • Карта сайта
© mir-knigi.online, 2026. | Вход