Parcourir la source

added eth worker for traceroute

arag0re il y a 10 mois
Parent
commit
44e3019209

+ 1 - 1
eth_save_process.c

@@ -277,7 +277,7 @@ EthernetSaveConfig* ethernet_save_process_malloc() {
 
 void ethernet_save_process_print(EthernetSaveConfig* config, const char* str) {
     furi_assert(config);
-    FuriHalRtcDateTime datetime = {0};
+    DateTime datetime = {0};
     furi_hal_rtc_get_datetime(&datetime);
     storage_printf(
         config->log_file,

+ 2 - 0
eth_view_process.c

@@ -11,6 +11,8 @@
 
 #define TAG "EthView"
 
+
+
 EthViewProcess* ethernet_view_process_malloc(EthWorkerProcess type, EthernetSaveConfig* config) {
     EthViewProcess* evp = malloc(sizeof(EthViewProcess));
     evp->type = type;

+ 15 - 1
eth_view_process.h

@@ -195,4 +195,18 @@ typedef struct EthViewDrawStatic {
 typedef struct EthViewDrawPing {
     uint8_t current_digit;
     uint8_t* ip;
-} EthViewDrawPing;
+} EthViewDrawPing;
+
+typedef struct
+{
+    uint8_t hop_number;
+    uint8_t ip[4];
+    uint16_t rtt_ms; // Round-trip time in milliseconds
+} TracerouteHop;
+
+typedef struct
+{
+    TracerouteHop hops[30]; // Maximum hops, adjust as needed
+    uint8_t hop_count;      // Number of hops recorded
+} TracerouteResult;
+

+ 2 - 0
eth_worker.c

@@ -21,6 +21,7 @@ EthWorker* eth_worker_alloc() {
     worker->dhcp_process = ethernet_view_process_malloc(EthWorkerProcessDHCP, worker->config);
     worker->stat_process = ethernet_view_process_malloc(EthWorkerProcessStatic, worker->config);
     worker->ping_process = ethernet_view_process_malloc(EthWorkerProcessPing, worker->config);
+    worker->traceroute_process = ethernet_view_process_malloc(EthWorkerProcessTraceroute, worker->config);
     worker->reset_process = ethernet_view_process_malloc(EthWorkerProcessReset, worker->config);
     worker->active_process = worker->init_process;
 
@@ -48,6 +49,7 @@ void eth_worker_free(EthWorker* worker) {
     ethernet_view_process_free(worker->dhcp_process);
     ethernet_view_process_free(worker->stat_process);
     ethernet_view_process_free(worker->ping_process);
+    ethernet_view_process_free(worker->traceroute_process);
     ethernet_view_process_free(worker->reset_process);
     ethernet_save_process_free(worker->config);
 

+ 5 - 2
eth_worker.h

@@ -22,11 +22,13 @@ typedef enum {
     EthWorkerStateReset,
 } EthWorkerState;
 
-typedef enum {
+typedef enum
+{
     EthWorkerProcessInit,
     EthWorkerProcessDHCP,
     EthWorkerProcessStatic,
     EthWorkerProcessPing,
+    EthWorkerProcessTraceroute,
     EthWorkerProcessReset,
     EthWorkerProcessActive,
     EthWorkerProcessExit,
@@ -75,4 +77,5 @@ void eth_worker_init_process(EthWorker* eth_worker);
 
 #define PING_SOCKET 1
 uint8_t ping_auto_interface(uint8_t* adress);
-void dhcp_timer_callback(void* context);
+uint8_t traceroute_auto(uint8_t *adress); 
+void dhcp_timer_callback(void *context);

+ 1 - 0
eth_worker_i.h

@@ -13,6 +13,7 @@ struct EthWorker {
     EthViewProcess* dhcp_process;
     EthViewProcess* stat_process;
     EthViewProcess* ping_process;
+    EthViewProcess* traceroute_process;
     EthViewProcess* reset_process;
     EthViewProcess* active_process;
 

+ 8 - 0
eth_worker_traceroute.c

@@ -0,0 +1,8 @@
+#include "eth_worker.h"
+#include <furi_hal.h>
+#include <traceroute.h>
+
+uint8_t traceroute_auto(uint8_t *adress)
+{
+    return traceroute(PING_SOCKET, adress);
+}

+ 79 - 97
lib/ioLibrary_Driver/Internet/ICMP/traceroute.c

@@ -1,132 +1,114 @@
-#include "socket.h"
-#include "w5500.h"
+#include "traceroute.h"
 #include "ping.h"
+#include <string.h>
 
-#define MAX_HOPS 30
-#define PORT 33434
-#define BUF_LEN 32
+static uint16_t RandomID = 0x1234;
+static uint16_t RandomSeqNum = 0x4321;
 
-extern void ping_wait_ms(int ms);
+uint16_t port = PORT; // Store the port number in a variable
 
-uint8_t traceroute(uint8_t s, uint8_t* dest_addr) {
+uint8_t traceroute(uint8_t s, uint8_t *dest_addr)
+{
     uint8_t ttl = 1;
-    uint8_t hops = 0;
     int ret;
-    uint8_t curr_addr[4];
-    uint8_t curr_name[64];
-    
-    while (ttl <= MAX_HOPS) {
+
+    while (ttl <= MAX_HOPS)
+    {
         uint8_t sr = getSn_SR(s);
         eth_printf("SR: %02X", sr);
-        
-        switch (sr) {
-            case SOCK_CLOSED:
-                close(s);
-                IINCHIP_WRITE(Sn_PROTO(s), IPPROTO_ICMP); // set ICMP Protocol
-                if ((ret = socket(s, Sn_MR_IPRAW, 3000, 0)) != s) {
-                    eth_printf("socket %d fail %d", s, ret);
-                    return SOCKET_ERROR;
-                }
-                while (getSn_SR(s) != SOCK_IPRAW);
-                ping_wait_ms(1000); // Wait for a bit
-                break;
-
-            case SOCK_IPRAW:
-                send_traceroute_request(s, dest_addr, ttl);
-                while (1) {
-                    uint16_t len = getSn_RX_RSR(s);
-                    if (len > 0) {
-                        uint8_t recv_addr[4];
-                        receive_traceroute_reply(s, recv_addr, len);
-                        eth_printf("Hop %d: %d.%d.%d.%d\n", ttl, recv_addr[0], recv_addr[1], recv_addr[2], recv_addr[3]);
-                        if (memcmp(recv_addr, dest_addr, 4) == 0) {
-                            eth_printf("Destination reached: %d.%d.%d.%d\n", recv_addr[0], recv_addr[1], recv_addr[2], recv_addr[3]);
-                            return 0; // Destination reached
-                        }
-                        break;
+
+        switch (sr)
+        {
+        case SOCK_CLOSED:
+            close(s);
+            IINCHIP_WRITE(Sn_PROTO(s), IPPROTO_ICMP); // Set ICMP Protocol
+            if ((ret = socket(s, Sn_MR_IPRAW, 3000, 0)) != s)
+            {
+                eth_printf("Socket %d failed: %d", s, ret);
+                return SOCKET_ERROR;
+            }
+            while (getSn_SR(s) != SOCK_IPRAW)
+                ;
+            ping_wait_ms(500);
+            break;
+
+        case SOCK_IPRAW:
+            send_traceroute_request(s, dest_addr, ttl);
+
+            for (int i = 0; i < 40; i++)
+            { // Wait up to 2 seconds
+                uint16_t len = getSn_RX_RSR(s);
+                if (len > 0)
+                {
+                    uint8_t recv_addr[4];
+                    receive_traceroute_reply(s, recv_addr, len);
+
+                    eth_printf("Hop %d: %d.%d.%d.%d", ttl, recv_addr[0], recv_addr[1], recv_addr[2], recv_addr[3]);
+                    if (memcmp(recv_addr, dest_addr, 4) == 0)
+                    {
+                        eth_printf("Destination reached: %d.%d.%d.%d", recv_addr[0], recv_addr[1], recv_addr[2], recv_addr[3]);
+                        return 0; // Destination reached
                     }
-                    ping_wait_ms(50); // Wait a bit before retrying
+                    break;
                 }
-                break;
+                ping_wait_ms(50);
+            }
+            break;
 
-            default:
-                break;
+        default:
+            break;
         }
-        
+
         ttl++;
-        if (ttl > MAX_HOPS) {
-            eth_printf("Max hops reached.\n");
+        if (ttl > MAX_HOPS)
+        {
+            eth_printf("Max hops reached.");
             break;
         }
     }
     return FUNCTION_ERROR;
 }
 
-void send_traceroute_request(uint8_t s, uint8_t* dest_addr, uint8_t ttl) {
+void send_traceroute_request(uint8_t s, uint8_t *dest_addr, uint8_t ttl)
+{
     PINGMSGR PingRequest;
-    uint16_t i;
-    
+
     PingRequest.Type = PING_REQUEST;
     PingRequest.Code = CODE_ZERO;
     PingRequest.ID = htons(RandomID++);
     PingRequest.SeqNum = htons(RandomSeqNum++);
-    
-    for (i = 0; i < BUF_LEN; i++) {
+
+    for (int i = 0; i < BUF_LEN; i++)
+    {
         PingRequest.Data[i] = (i) % 8;
     }
-    
+
     PingRequest.CheckSum = 0;
-    PingRequest.CheckSum = htons(checksum((uint8_t*)&PingRequest, sizeof(PingRequest)));
-    
-    set_ttl(s, ttl); // Set TTL value for each packet sent
-    sendto(s, (uint8_t*)&PingRequest, sizeof(PingRequest), dest_addr, PORT);
-    eth_printf("Send traceroute request (TTL: %d) to %d.%d.%d.%d\n", ttl, dest_addr[0], dest_addr[1], dest_addr[2], dest_addr[3]);
+    PingRequest.CheckSum = htons(checksum((uint8_t *)&PingRequest, sizeof(PingRequest)));
+
+    set_ttl(s, ttl);                                                          // Set TTL
+    sendto(s, (uint8_t *)&PingRequest, sizeof(PingRequest), dest_addr, port); // Use the port variable
+
+    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]);
 }
 
-void receive_traceroute_reply(uint8_t s, uint8_t* addr, uint16_t len) {
-    uint16_t tmp_checksum;
+void receive_traceroute_reply(uint8_t s, uint8_t *addr, uint16_t len)
+{
     uint8_t data_buf[128];
-    
-    uint16_t rlen = recvfrom(s, data_buf, len, addr, &PORT);
-    if (data_buf[0] == PING_REPLY) {
-        PINGMSGR PingReply;
-        PingReply.Type = data_buf[0];
-        PingReply.Code = data_buf[1];
-        PingReply.CheckSum = (data_buf[3] << 8) + data_buf[2];
-        PingReply.ID = (data_buf[5] << 8) + data_buf[4];
-        PingReply.SeqNum = (data_buf[7] << 8) + data_buf[6];
-        
-        tmp_checksum = ~checksum(data_buf, rlen);
-        if (tmp_checksum != 0xffff) {
-            eth_printf("Checksum failed\n");
-        } else {
-            eth_printf("Received reply from %d.%d.%d.%d: ID=%x SeqNum=%x\n", addr[0], addr[1], addr[2], addr[3], PingReply.ID, PingReply.SeqNum);
-        }
+
+    uint16_t rlen = recvfrom(s, data_buf, len, addr, &port); // Pass the pointer to the port variable
+    (void)rlen;
+    if (data_buf[0] == PING_REPLY)
+    {
+        eth_printf("Reply from %d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
+    }
+    else if (data_buf[0] == 11)
+    { // ICMP Time Exceeded
+        eth_printf("Time Exceeded from %d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
     }
 }
 
-void set_ttl(uint8_t s, uint8_t ttl) {
+void set_ttl(uint8_t s, uint8_t ttl)
+{
     IINCHIP_WRITE(Sn_TTL(s), ttl);
 }
-
-uint16_t checksum(uint8_t* data_buf, uint16_t len) {
-    uint16_t sum, tsum, i, j;
-    uint32_t lsum;
-    
-    j = len >> 1;
-    lsum = 0;
-    tsum = 0;
-    for (i = 0; i < j; ++i) {
-        tsum = data_buf[i * 2];
-        tsum = tsum << 8;
-        tsum += data_buf[i * 2 + 1];
-        lsum += tsum;
-    }
-    if (len % 2) {
-        tsum = data_buf[i * 2];
-        lsum += (tsum << 8);
-    }
-    sum = (uint16_t)lsum;
-    sum = ~(sum + (lsum >> 16));
-    return sum;
-}

+ 7 - 18
lib/ioLibrary_Driver/Internet/ICMP/traceroute.h

@@ -1,32 +1,21 @@
 #ifndef TRACEROUTE_H
 #define TRACEROUTE_H
 
+#include "wizchip_conf.h"
 #include "ping.h"
 #include "socket.h"
 #include "w5500.h"
 
-// Maximum number of hops for the traceroute
 #define MAX_HOPS 30
-
-// The UDP port for sending traceroute packets (typically 33434 for traceroute)
-#define PORT 33434
-
-// Buffer length for the ping message
+#define PORT 33434 // Keep the macro definition;
 #define BUF_LEN 32
 
-// Function to perform a traceroute
-uint8_t traceroute(uint8_t s, uint8_t* dest_addr);
-
-// Function to send a traceroute request with a specific TTL value
-void send_traceroute_request(uint8_t s, uint8_t* dest_addr, uint8_t ttl);
+extern void ping_wait_ms(int ms);
 
-// Function to receive and process a traceroute reply
-void receive_traceroute_reply(uint8_t s, uint8_t* addr, uint16_t len);
-
-// Function to set the TTL value for outgoing packets
+uint8_t traceroute(uint8_t s, uint8_t *dest_addr);
+void send_traceroute_request(uint8_t s, uint8_t *dest_addr, uint8_t ttl);
+void receive_traceroute_reply(uint8_t s, uint8_t *addr, uint16_t len);
 void set_ttl(uint8_t s, uint8_t ttl);
-
-// Function to compute the checksum of a given data buffer
-uint16_t checksum(uint8_t* data_buf, uint16_t len);
+// uint16_t checksum(uint8_t *data_buf, uint16_t len);
 
 #endif // TRACEROUTE_H