Написание базового сценария traceroute на C - PullRequest
6 голосов
/ 03 февраля 2011

Мне нужно написать скрипт trceroute, но я не уверен, верны ли мои попытки.

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

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

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

Ответы [ 2 ]

2 голосов
/ 03 февраля 2011

Что касается настройки 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);
}
2 голосов
/ 03 февраля 2011

На какую платформу вы ориентируетесь?Вот пример BSD из источника OpenBSD :

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).

...