浏览代码

Merge eth_troubleshooter from https://github.com/arag0re/fz-eth-troubleshooter

# Conflicts:
#	eth_troubleshooter/eth_view_process.h
#	eth_troubleshooter/eth_worker.h
Willy-JL 10 月之前
父节点
当前提交
cece98d9e9

+ 2 - 0
eth_troubleshooter/eth_view_process.c

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

+ 14 - 0
eth_troubleshooter/eth_view_process.h

@@ -57,3 +57,17 @@ typedef struct EthViewDrawPing {
     uint8_t current_digit;
     uint8_t* ip;
 } 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_troubleshooter/eth_worker.c

@@ -24,6 +24,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;
 
@@ -51,6 +52,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);
 

+ 6 - 3
eth_troubleshooter/eth_worker.h

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

+ 1 - 0
eth_troubleshooter/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;
 

+ 2 - 2
eth_troubleshooter/eth_worker_ping.c

@@ -6,6 +6,6 @@ void ping_wait_ms(int ms) {
     furi_delay_ms(ms);
 }
 
-uint8_t ping_auto_interface(uint8_t* address) {
-    return ping_auto(PING_SOCKET, address);
+uint8_t ping_auto_interface(uint8_t* adress) {
+    return ping_auto(PING_SOCKET, adress);
 }

+ 8 - 0
eth_troubleshooter/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);
+}

+ 114 - 0
eth_troubleshooter/lib/ioLibrary_Driver/Internet/ICMP/traceroute.c

@@ -0,0 +1,114 @@
+#include "traceroute.h"
+#include "ping.h"
+#include <string.h>
+
+static uint16_t RandomID = 0x1234;
+static uint16_t RandomSeqNum = 0x4321;
+
+uint16_t port = PORT; // Store the port number in a variable
+
+uint8_t traceroute(uint8_t s, uint8_t *dest_addr)
+{
+    uint8_t ttl = 1;
+    int ret;
+
+    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 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
+                    }
+                    break;
+                }
+                ping_wait_ms(50);
+            }
+            break;
+
+        default:
+            break;
+        }
+
+        ttl++;
+        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)
+{
+    PINGMSGR PingRequest;
+
+    PingRequest.Type = PING_REQUEST;
+    PingRequest.Code = CODE_ZERO;
+    PingRequest.ID = htons(RandomID++);
+    PingRequest.SeqNum = htons(RandomSeqNum++);
+
+    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
+    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)
+{
+    uint8_t data_buf[128];
+
+    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)
+{
+    IINCHIP_WRITE(Sn_TTL(s), ttl);
+}

+ 21 - 0
eth_troubleshooter/lib/ioLibrary_Driver/Internet/ICMP/traceroute.h

@@ -0,0 +1,21 @@
+#ifndef TRACEROUTE_H
+#define TRACEROUTE_H
+
+#include "wizchip_conf.h"
+#include "ping.h"
+#include "socket.h"
+#include "w5500.h"
+
+#define MAX_HOPS 30
+#define PORT 33434 // Keep the macro definition;
+#define BUF_LEN 32
+
+extern void ping_wait_ms(int ms);
+
+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);
+// uint16_t checksum(uint8_t *data_buf, uint16_t len);
+
+#endif // TRACEROUTE_H