2011-02-03 5 views
6

Мне нужно написать скрипт trceroute, но я не уверен, что мои попытки верны.Написание базового сценария traceroute в C

Прямо сейчас я делаю это так (пожалуйста, поправьте меня, если я делаю неправильно или неуклюжим):

  1. Получил-структуру для IP- и udpheader
  2. Функции Контрольной
  3. Открытие 2 сокетов: один для отправки UDP-пакетов в режиме SOCK_RAW (для управления ttl) и один для приема ICMP-ответов от маршрутизаторов.
  4. Используя SendTo() для отправки UDP пакета
  5. Не имея ни малейшего понятия, как получить и обработать ответ ICMP

есть ли более удобные способы изменить TTL, чем при использовании SOCK_RAW, где я должен определить все заголовок для себя? Какие параметры следует использовать для socket() при открытии носки ICMP? Как получить ответ ICMP?

ответ

2

На какой платформе вы нацеливаетесь? Вот BSD аромат от OpenBSD source:

if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) 
    err(5, "icmp socket"); 
if ((sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) 
    err(5, "raw socket"); 

В Linux, я считаю, что вам нужно использовать IP_RECVERR и recvmsg(2) с MSG_ERRQUEUE см ip(7).

+0

Спасибо за ваш ответ. Это привело меня в бегство вперед. –

2

Что касается установки TTL, вы можете использовать setsockopt(). Вот выдержка из источника iputils для ping на Linux:

if (setsockopt(icmp_sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, 1) == -1) { 
    perror ("ping: can't set multicast time-to-live"); 
    exit(2); 
} 

if (setsockopt(icmp_sock, IPPROTO_IP, IP_TTL, &ittl, sizeof(ittl)) == -1) { 
    perror ("ping: can't set unicast time-to-live"); 
    exit(2); 
} 
+0

Спасибо, это похоже на то, что это намного проще. –