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

Стивенс Уильям Ричард

Шрифт:

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
.

Обработка альтернативных имен

64-72
Нам нужно обнаружить все альтернативные имена (псевдонимы), которые могут существовать для интерфейса, то есть присвоенные этому интерфейсу дополнительные адреса. Обратите внимание в наших примерах, следующих за листингом 17.3, что в Solaris псевдоним содержит двоеточие, в то время как в 4.4BSD имя интерфейса в псевдониме не изменяется. Чтобы обработать оба случая, мы сохраняем последнее имя интерфейса в
lastname
и сравниваем его только до двоеточия, если оно присутствует. Если двоеточия нет, мы игнорируем этот интерфейс в том случае, когда имя эквивалентно последнему обработанному интерфейсу.

  • Читать дальше
  • 1
  • ...
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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