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

Листинг 28.15. Функция traceloop: основной цикл обработки

//traceroute/traceloop.c

 1 #include "trace.h"

 2 void

 3 traceloop(void)

 4 {

 5  int seq, code, done;

 6  double rtt;

 7  struct rec *rec;

 8  struct timeval tvrecv;

 9  recvfd = Socket(pr->sasend->sa_family, SOCK_RAW, pr->icmpproto);

10  setuid(getuid()); /* права привилегированного пользователя больше

                         не нужны */

11 #ifdef IPV6

12  if (pr->sasend->sa_family == AF_INET6 && verbose == 0) {

13   struct icmp6_filter myfilt;

14   ICMP6_FILTER_SETBLOCKALL(&myfilt);

15   ICMP6_FILTER_SETPASS(ICMP6_TIME_EXCEEDED, &myfilt);

16   ICMP6_FILTER_SETPASS(ICMP6_DST_UNREACH, &myfilt);

17   setsockopt(recvfd, IPPROTO_IPV6, ICMP6_FILTER,

18    &myfilt, sizeof(myfilt));

19  }

20 #endif

21  sendfd = Socket(pr->sasend->sa_family, SOCK_DGRAM, 0);

22  pr->sabind->sa_family = pr->sasend->sa_family;

23  sport = (getpid() & 0xffff) | 0x8000; /* UDP-порт отправителя # */

24  sock_set_port(pr->sabind, pr->salen, htons(sport));

25  Bind(sendfd, pr->sabind, pr->salen);

26  sig_alrm(SIGALRM);

27  seq = 0;

28  done = 0;

29  for (ttl = 1; ttl <= max_ttl && done == 0; ttl++) {

30   Setsockopt(sendfd, pr->ttllevel, pr->ttloptname, &ttl, sizeof(int));

31   bzero(pr->salast, pr->salen);

32   printf("%2d ", ttl);

33   fflush(stdout);

34   for (probe = 0; probe < nprobes; probe++) {

35    rec = (struct rec*)sendbuf;

36    rec->rec_seq = ++seq;

37    rec->rec_ttl = ttl;

38    Gettimeofday(&rec->rec_tv, NULL);

39    sock_set_port(pr->sasend, pr->salen, htons(dport + seq));

40    Sendto(sendfd, sendbuf, datalen, 0, pr->sasend, pr->salen);

41    if ((code = (*pr->recv)(seq, &tvrecv)) == -3)

42     printf(" *"); /* тайм-аут, ответа нет */

43    else {

44     char str[NI_MAXHOST];

45     if (sock_cmp_addr(pr->sarecv, pr->salast, pr->salen) != 0) {

46      if (getnameinfo(pr->sarecv, pr->salen, str, sizeof(str),

47       NULL, 0, 0) == 0)

48       printf(" %s (%s)", str,

49        Sock_ntop_host(pr->sarecv, pr->salen));

50      else

51       printf(" %s", Sock_ntop_host(pr->sarecv, pr->salen));

52      memcpy(pr->salast, pr->sarecv, pr->salen);

53     }

54     tv_sub(&tvrecv, &rec->rec_tv);

55     rtt = tvrecv.tv_sec * 1000.0 + tvrecv.tv_usec / 1000.0;

56     printf(" %.3f ms", rtt);

57     if (code == -1) /* порт получателя недоступен */

58      done++;

59     else if (code >= 0)

60      printf(" (ICMP %s)", (*pr->icmpcode)(code));

61    }

62    fflush(stdout);

63   }

64   printf("\n");

65  }

66 }

Создание двух сокетов
Перейти на страницу:

Все книги серии Мастер-класс

Секреты резьбы по дереву
Секреты резьбы по дереву

Изделия из древесины и материалов, имитирующих ее текстуру, привычным образом окружают нас в повседневной жизни, поэтому мы относимся к ней как к чему-то обыденному. Но как только ее коснется умелая рука мастера резьбы по дереву, рождается произведение искусства и раскрываются такие качества древесины, как богатая фактура, разнообразие цветов, особая теплота. Эта книга поможет читателю открыть для себя удивительный мир творчества и познать секреты резьбы по дереву. Автор надеется, что начинающие резчики найдут в ней интересный и полезный материал, который позволит им стать мастерами. В приложении представлены рисунки орнаментов и различных узоров, которые на первых порах можно копировать, а по мере приобретения навыка на их основе разрабатывать свои образцы.

Галина Алексеевна Серикова

Сделай сам / Хобби и ремесла / Руководства / Дом и досуг / Словари и Энциклопедии

Похожие книги