traceroute.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. #include "traceroute.h"
  2. #include "ping.h"
  3. #include <string.h>
  4. static uint16_t RandomID = 0x1234;
  5. static uint16_t RandomSeqNum = 0x4321;
  6. uint16_t port = PORT; // Store the port number in a variable
  7. uint8_t traceroute(uint8_t s, uint8_t *dest_addr)
  8. {
  9. uint8_t ttl = 1;
  10. int ret;
  11. while (ttl <= MAX_HOPS)
  12. {
  13. uint8_t sr = getSn_SR(s);
  14. eth_printf("SR: %02X", sr);
  15. switch (sr)
  16. {
  17. case SOCK_CLOSED:
  18. close(s);
  19. IINCHIP_WRITE(Sn_PROTO(s), IPPROTO_ICMP); // Set ICMP Protocol
  20. if ((ret = socket(s, Sn_MR_IPRAW, 3000, 0)) != s)
  21. {
  22. eth_printf("Socket %d failed: %d", s, ret);
  23. return SOCKET_ERROR;
  24. }
  25. while (getSn_SR(s) != SOCK_IPRAW)
  26. ;
  27. ping_wait_ms(500);
  28. break;
  29. case SOCK_IPRAW:
  30. send_traceroute_request(s, dest_addr, ttl);
  31. for (int i = 0; i < 40; i++)
  32. { // Wait up to 2 seconds
  33. uint16_t len = getSn_RX_RSR(s);
  34. if (len > 0)
  35. {
  36. uint8_t recv_addr[4];
  37. receive_traceroute_reply(s, recv_addr, len);
  38. eth_printf("Hop %d: %d.%d.%d.%d", ttl, recv_addr[0], recv_addr[1], recv_addr[2], recv_addr[3]);
  39. if (memcmp(recv_addr, dest_addr, 4) == 0)
  40. {
  41. eth_printf("Destination reached: %d.%d.%d.%d", recv_addr[0], recv_addr[1], recv_addr[2], recv_addr[3]);
  42. return 0; // Destination reached
  43. }
  44. break;
  45. }
  46. ping_wait_ms(50);
  47. }
  48. break;
  49. default:
  50. break;
  51. }
  52. ttl++;
  53. if (ttl > MAX_HOPS)
  54. {
  55. eth_printf("Max hops reached.");
  56. break;
  57. }
  58. }
  59. return FUNCTION_ERROR;
  60. }
  61. void send_traceroute_request(uint8_t s, uint8_t *dest_addr, uint8_t ttl)
  62. {
  63. PINGMSGR PingRequest;
  64. PingRequest.Type = PING_REQUEST;
  65. PingRequest.Code = CODE_ZERO;
  66. PingRequest.ID = htons(RandomID++);
  67. PingRequest.SeqNum = htons(RandomSeqNum++);
  68. for (int i = 0; i < BUF_LEN; i++)
  69. {
  70. PingRequest.Data[i] = (i) % 8;
  71. }
  72. PingRequest.CheckSum = 0;
  73. PingRequest.CheckSum = htons(checksum((uint8_t *)&PingRequest, sizeof(PingRequest)));
  74. set_ttl(s, ttl); // Set TTL
  75. sendto(s, (uint8_t *)&PingRequest, sizeof(PingRequest), dest_addr, port); // Use the port variable
  76. eth_printf("Sent traceroute request (TTL: %d) to %d.%d.%d.%d", ttl, dest_addr[0], dest_addr[1], dest_addr[2], dest_addr[3]);
  77. }
  78. void receive_traceroute_reply(uint8_t s, uint8_t *addr, uint16_t len)
  79. {
  80. uint8_t data_buf[128];
  81. uint16_t rlen = recvfrom(s, data_buf, len, addr, &port); // Pass the pointer to the port variable
  82. (void)rlen;
  83. if (data_buf[0] == PING_REPLY)
  84. {
  85. eth_printf("Reply from %d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
  86. }
  87. else if (data_buf[0] == 11)
  88. { // ICMP Time Exceeded
  89. eth_printf("Time Exceeded from %d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
  90. }
  91. }
  92. void set_ttl(uint8_t s, uint8_t ttl)
  93. {
  94. IINCHIP_WRITE(Sn_TTL(s), ttl);
  95. }