2011-02-03 36 views
6

Tôi phải viết kịch bản lệnh trceroute nhưng tôi không chắc liệu các nỗ lực của tôi có đúng không.Viết kịch bản lệnh traceroute cơ bản trong C

Ngay bây giờ tôi đang làm nó như thế (xin vui lòng chính xác cho tôi nếu tôi đang làm sai hoặc vụng về):

  1. Got một struct cho IP và udpheader
  2. Một chức năng checksum
  3. Mở 2 ổ cắm: Một để gửi gói UDP ở chế độ SOCK_RAW (để thao tác ttl) và một để nhận các câu trả lời ICMP từ các bộ định tuyến.
  4. Sử dụng sendto() để gửi UDP gói
  5. Không có đầu mối làm thế nào để nhận và xử lý một câu trả lời ICMP

Có cách nào thoải mái hơn để thay đổi TTL vì sử dụng SOCK_RAW nơi tôi phải xác định tất cả tiêu đề công cụ của bản thân mình? Tôi nên sử dụng thông số nào cho socket() khi mở khóa ICMP? Làm thế nào để nhận được câu trả lời ICMP?

Trả lời

2

Bạn đang nhắm mục tiêu nền tảng nào? Dưới đây là một hương vị BSD từ 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"); 

Trên Linux, tôi tin rằng, bạn cần phải sử dụng IP_RECVERRrecvmsg(2) với MSG_ERRQUEUE, xem ip(7).

+0

Cảm ơn câu trả lời của bạn. Nó mang lại cho tôi một litte về phía trước. –

2

Khi đặt TTL liên quan, bạn có thể sử dụng setsockopt(). Dưới đây là trích xuất từ ​​nguồn iputils 'cho ping trên 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

Cảm ơn, điều đó dường như làm cho nó dễ dàng hơn rất nhiều. –

Các vấn đề liên quan