Если у вас современный дистрибутив Linux, вы можете посмотреть на источник для traceroute (или tracepath, который появился до того, как traceroute не установил setuid) и tcptraceroute. Ни для одного из них не требуются сокеты RAW - проверено в Fedora 9, они не настроены и работают с параметрами по умолчанию для обычного пользователя.
Использование кода, который делает tcptraceroute, может быть esp. полезно, так как пакеты ICMP по адресу не обязательно заканчиваются тем же местом, что и TCP-соединение с портом 80, например.
Выполнение трассировки трассировки (как обычного пользователя) показывает, что она выполняет что-то вроде:
int opt_on = 1;
int opt_off = 0;
fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)
setsockopt(fd, SOL_IP, IP_MTU_DISCOVER, &opt_off, sizeof int)
setsockopt(fd, SOL_SOCKET, SO_TIMESTAMP, &opt_on, sizeof int)
setsockopt(fd, SOL_IP, IP_RECVTTL, &opt_on, sizeof int)
... и затем чтение данных из результатов CMSG.