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

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

Шрифт:

8 mib[1] = AF_ROUTE;

9 mib[2] = 0;

10 mib[3] = family; /* только адреса этого семейства */

11 mib[4] = NET_RT_IFLIST;

12 mib[5] = flags; /* индекс интерфейса или 0.*/

13 if (sysctl(mib, 6, NULL, lenp, NULL, 0) < 0)

14 return (NULL);

15 if ((buf = malloc(*lenp)) == NULL)

16 return (NULL);

17 if (sysctl(mib, 6, buf, lenp, NULL, 0) < 0) {

18 free(buf);

19 return (NULL);

20 }

21 return (buf);

22 }

7-14
Инициализируется массив
mib
, как показано в табл. 18.3, для возвращения списка интерфейсов и всех сконфигурированных адресов заданного семейства. Затем функция
sysctl
вызывается дважды. В первом вызове функции третий аргумент нулевой, в результате чего в переменной, на которую указывает
lenp
, возвращается размер буфера, требуемый для хранения всей информации об интерфейсе.

15-21
Затем в памяти выделяется место для буфера, и функция
sysctl
вызывается снова, на этот раз с ненулевым третьим аргументом. При этом переменная, на которую указывает
lenp
, содержит при завершении функции число, равное количеству информации, хранимой в буфере, и эта переменная размещается в памяти вызывающим процессом. Указатель на буфер также возвращается вызывающему процессу.

ПРИМЕЧАНИЕ

Поскольку размер таблицы маршрутизации или число интерфейсов может изменяться между двумя вызовами функции sysctl, значение, возвращаемое при первом вызове, содержит поправочный множитель 10% [128, с. 639-640].

В листинге 18.9 показана первая половина функции

get_ifi_info
.

Листинг 18.9. Функция get_ifi_info, первая половина

//route/get_ifi_info.c

3 struct ifi_info *

4 get_ifi_info(int family, int doaliases)

5 {

6 int flags;

7 char *buf, *next, *lim;

8 size_t len;

9 struct if_msghdr *ifm;

10 struct ifa_msghdr *ifam;

11 struct sockaddr *sa, *rti_info[RTAX_MAX];

12 struct sockaddr_dl *sdl;

13 struct ifi_info *ifi, *ifisave, *ifihead, **ifipnext;

14 buf = Net_rt_iflist(family, 0, &len);

15 ifihead = NULL;

16 ifipnext = &ifihead;

17 lim = buf + len;

18 for (next = buf; next < lim; next += ifm->ifm_msglen) {

19 ifm = (struct if_msghdr*)next;

20 if (ifm->ifm_type = RTM_IFINFO) {

21 if (((flags = ifm->ifm_flags) & IFF_UP) == 0)

22 continue; /* игнорируем, если интерфейс не активен */

23 sa = (struct sockaddr*)(ifm + 1);

24 get_rtaddrs(ifm->ifm_addrs, sa, rti_info);

25 if ((sa = rti_info[RTAX_IFP]) != NULL) {

26 ifi = Calloc(1, sizeof(struct ifi_info));

27 *ifipnext = ifi; /* предыдущий указатель указывал на эту

структуру */

28 ifipnext = &ifi->ifi_next; /* указатель на следующую структуру */

29 ifi->ifi_flags = flags;

30 if (sa->sa_family == AF_LINK) {

31 sdl = (struct sockaddr_dl*)sa;

32 ifi->ifi_index = sdl->sdl_index;

33 if (sdl->sdl_nlen > 0)

  • Читать дальше
  • 1
  • ...
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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