Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 01a25fe

Browse files
committedJan 10, 2025·
add ping command
1 parent e9d112e commit 01a25fe

File tree

12 files changed

+370
-7
lines changed

12 files changed

+370
-7
lines changed
 

‎extras/net/lwipopts.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@
277277
* (requires the LWIP_RAW option)
278278
*/
279279
#ifndef MEMP_NUM_RAW_PCB
280-
#define MEMP_NUM_RAW_PCB 0
280+
#define MEMP_NUM_RAW_PCB 1
281281
#endif
282282

283283
/**
@@ -642,7 +642,7 @@
642642
* LWIP_RAW==1: Enable application layer to hook into the IP layer itself.
643643
*/
644644
#ifndef LWIP_RAW
645-
#define LWIP_RAW 0
645+
#define LWIP_RAW 1
646646
#endif
647647

648648
/*
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
Web ICMP Ping
3+
4+
This sketch pings a device based on the IP address or the hostname
5+
using the Ethernet module.
6+
7+
It's required an Ethernet network with DHCP
8+
9+
created 14 February 2024
10+
by paulvha
11+
modified 8 Jenuary 2025
12+
by fabik111
13+
14+
*/
15+
16+
#include <EthernetC33.h>
17+
18+
/* -------------------------------------------------------------------------- */
19+
void setup() {
20+
/* -------------------------------------------------------------------------- */
21+
//Initialize serial and wait for port to open:
22+
Serial.begin(9600);
23+
while (!Serial) {
24+
; // wait for serial port to connect. Needed for native USB port only
25+
}
26+
27+
while(Ethernet.begin() == 0){
28+
Serial.println("Failed to configure Ethernet using DHCP");
29+
delay(5000);
30+
}
31+
32+
Serial.println("Ethernet configuration OK!");
33+
Serial.print("Ip address: ");
34+
Serial.println(Ethernet.localIP());
35+
}
36+
37+
/* -------------------------------------------------------------------------- */
38+
void loop() {
39+
/* -------------------------------------------------------------------------- */
40+
41+
// Ping IP
42+
const IPAddress remote_ip(140,82,121,4);
43+
Serial.print("Trying to ping github.com on IP: ");
44+
Serial.println(remote_ip);
45+
46+
// using default ping count of 1
47+
int res = Ethernet.ping(remote_ip);
48+
49+
if (res > 0) {
50+
Serial.print("Ping response time: ");
51+
Serial.print(res);
52+
Serial.println(" ms");
53+
}
54+
else {
55+
Serial.println("Timeout on IP!");
56+
}
57+
58+
// Ping Host
59+
const char* remote_host = "www.google.com";
60+
Serial.print("Trying to ping host: ");
61+
Serial.println(remote_host);
62+
63+
int res1 = Ethernet.ping(remote_host);
64+
65+
if (res1 > 0) {
66+
Serial.print("Ping average response time: ");
67+
Serial.print(res1);
68+
Serial.println(" ms");
69+
}
70+
else {
71+
Serial.println("Timeout on host!");
72+
}
73+
74+
Serial.println();
75+
delay(5000);
76+
}

‎libraries/Ethernet/src/Ethernet.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,4 +221,27 @@ IPAddress CEthernet::dnsServerIP() {
221221
return CLwipIf::getInstance().getDns();
222222
}
223223

224+
/* -------------------------------------------------------------------------- */
225+
int CEthernet::ping(IPAddress ip, uint8_t ttl) {
226+
/* -------------------------------------------------------------------------- */
227+
return CLwipIf::getInstance().ping(ip, ttl);
228+
}
229+
230+
/* -------------------------------------------------------------------------- */
231+
int CEthernet::ping(const String &hostname, uint8_t ttl)
232+
/* -------------------------------------------------------------------------- */
233+
{
234+
return ping(hostname.c_str(), ttl);
235+
}
236+
237+
/* -------------------------------------------------------------------------- */
238+
int CEthernet::ping(const char* host, uint8_t ttl) {
239+
/* -------------------------------------------------------------------------- */
240+
IPAddress ip;
241+
if(CLwipIf::getInstance().getHostByName(host,ip)) {
242+
return CLwipIf::getInstance().ping(ip, ttl);
243+
}
244+
return -1;
245+
}
246+
224247
CEthernet Ethernet;

‎libraries/Ethernet/src/EthernetC33.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,12 @@ class CEthernet {
6969
IPAddress gatewayIP();
7070
IPAddress dnsServerIP();
7171

72+
/*
73+
* PING
74+
*/
75+
int ping(IPAddress ip, uint8_t ttl = 128);
76+
int ping(const String &hostname, uint8_t ttl = 128);
77+
int ping(const char* host, uint8_t ttl = 128);
7278

7379
friend class EthernetClient;
7480
friend class EthernetServer;
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*
2+
Web ICMP Ping
3+
4+
This sketch pings a device based on the IP address or the hostname
5+
using the WiFi module.
6+
7+
This example is written for a network using WPA encryption. For
8+
WEP or WPA, change the WiFi.begin() call accordingly.
9+
10+
created 14 February 2024
11+
by paulvha
12+
modified 8 Jenuary 2025
13+
by fabik111
14+
15+
*/
16+
17+
#include <WiFiC3.h>
18+
#include "arduino_secrets.h"
19+
20+
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
21+
char ssid[] = SECRET_SSID; // your network SSID (name)
22+
char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP)
23+
24+
int status = WL_IDLE_STATUS;
25+
26+
/* -------------------------------------------------------------------------- */
27+
void setup() {
28+
/* -------------------------------------------------------------------------- */
29+
//Initialize serial and wait for port to open:
30+
Serial.begin(9600);
31+
while (!Serial) {
32+
; // wait for serial port to connect. Needed for native USB port only
33+
}
34+
35+
// check for the WiFi module:
36+
if (WiFi.status() == WL_NO_MODULE) {
37+
Serial.println("Communication with WiFi module failed.");
38+
// don't continue
39+
while (true);
40+
}
41+
42+
// attempt to connect to WiFi network:
43+
while (status != WL_CONNECTED) {
44+
Serial.print("Attempting to connect to SSID: ");
45+
Serial.println(ssid);
46+
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
47+
status = WiFi.begin(ssid, pass);
48+
49+
// wait 3 seconds for connection:
50+
delay(3000);
51+
}
52+
53+
printWifiStatus();
54+
}
55+
56+
/* -------------------------------------------------------------------------- */
57+
void loop() {
58+
/* -------------------------------------------------------------------------- */
59+
60+
// Ping IP
61+
const IPAddress remote_ip(140,82,121,4);
62+
Serial.print("Trying to ping github.com on IP: ");
63+
Serial.println(remote_ip);
64+
65+
// using default ping count of 1
66+
int res = WiFi.ping(remote_ip);
67+
68+
if (res > 0) {
69+
Serial.print("Ping response time: ");
70+
Serial.print(res);
71+
Serial.println(" ms");
72+
}
73+
else {
74+
Serial.println("Timeout on IP!");
75+
}
76+
77+
// Ping Host
78+
const char* remote_host = "www.google.com";
79+
Serial.print("Trying to ping host: ");
80+
Serial.println(remote_host);
81+
82+
int res1 = WiFi.ping(remote_host);
83+
84+
if (res1 > 0) {
85+
Serial.print("Ping average response time: ");
86+
Serial.print(res1);
87+
Serial.println(" ms");
88+
}
89+
else {
90+
Serial.println("Timeout on host!");
91+
}
92+
93+
Serial.println();
94+
delay(5000);
95+
}
96+
97+
/* -------------------------------------------------------------------------- */
98+
void printWifiStatus() {
99+
/* -------------------------------------------------------------------------- */
100+
// print the SSID of the network you're attached to:
101+
Serial.print("SSID: ");
102+
Serial.println(WiFi.SSID());
103+
104+
// print your board's IP address:
105+
IPAddress ip = WiFi.localIP();
106+
Serial.print("IP Address: ");
107+
Serial.println(ip);
108+
109+
// print the received signal strength:
110+
long rssi = WiFi.RSSI();
111+
Serial.print("signal strength (RSSI):");
112+
Serial.print(rssi);
113+
Serial.println(" dBm");
114+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#define SECRET_SSID ""
2+
#define SECRET_PASS ""

‎libraries/WiFi/src/WiFi.cpp

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,12 +318,33 @@ unsigned long CWifi::getTime() {
318318
return 0;
319319
}
320320

321-
322-
323321
void CWifi::setTimeout(unsigned long timeout) {
324322
(void)(timeout);
325323
}
326324

325+
/* -------------------------------------------------------------------------- */
326+
int CWifi::ping(IPAddress ip, uint8_t ttl) {
327+
/* -------------------------------------------------------------------------- */
328+
return CLwipIf::getInstance().ping(ip, ttl);
329+
}
330+
331+
/* -------------------------------------------------------------------------- */
332+
int CWifi::ping(const String &hostname, uint8_t ttl)
333+
/* -------------------------------------------------------------------------- */
334+
{
335+
return ping(hostname.c_str(), ttl);
336+
}
337+
338+
/* -------------------------------------------------------------------------- */
339+
int CWifi::ping(const char* host, uint8_t ttl) {
340+
/* -------------------------------------------------------------------------- */
341+
IPAddress ip;
342+
if(hostByName(host,ip)) {
343+
return CLwipIf::getInstance().ping(ip, ttl);
344+
}
345+
return -1;
346+
}
347+
327348

328349
CWifi WiFi;
329350

‎libraries/WiFi/src/WiFiC3.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,12 @@ class CWifi {
254254

255255

256256
void setTimeout(unsigned long timeout);
257-
257+
/*
258+
* PING
259+
*/
260+
int ping(IPAddress ip, uint8_t ttl = 128);
261+
int ping(const String &hostname, uint8_t ttl = 128);
262+
int ping(const char* host, uint8_t ttl = 128);
258263

259264
};
260265

‎libraries/lwIpWrapper/src/CNetIf.cpp

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
#include "CNetIf.h"
22
#include <functional>
3+
#include "lwip/include/lwip/raw.h"
4+
#include "lwip/include/lwip/icmp.h"
5+
#include "lwip/include/lwip/raw.h"
6+
#include "lwip/include/lwip/ip_addr.h"
7+
#include "lwip/include/lwip/inet_chksum.h"
38

49
IPAddress CNetIf::default_ip("192.168.0.10");
510
IPAddress CNetIf::default_nm("255.255.255.0");
@@ -14,6 +19,32 @@ bool CLwipIf::pending_eth_rx = false;
1419

1520
FspTimer CLwipIf::timer;
1621

22+
u8_t icmp_receive_callback(void* arg, struct raw_pcb* pcb, struct pbuf* p, const ip_addr_t* addr)
23+
{
24+
struct ping_data *d = (struct ping_data*)arg;
25+
struct __attribute__((__packed__)) {
26+
struct ip_hdr ipHeader;
27+
struct icmp_echo_hdr header;
28+
} response;
29+
30+
if(d->s == pcb) {
31+
if(p->len < sizeof(response)) {
32+
pbuf_free(p);
33+
return 1;
34+
}
35+
36+
pbuf_copy_partial(p, &response, sizeof(response), 0);
37+
38+
if(response.header.id == d->echo_req.id && response.header.seqno == d->echo_req.seqno) {
39+
d->endMillis = millis();
40+
}
41+
pbuf_free(p);
42+
return 1;
43+
}
44+
45+
return 0;
46+
}
47+
1748
ip_addr_t* u8_to_ip_addr(uint8_t* ipu8, ip_addr_t* ipaddr)
1849
{
1950
IP_ADDR4(ipaddr, ipu8[0], ipu8[1], ipu8[2], ipu8[3]);
@@ -120,6 +151,81 @@ void CLwipIf::lwip_task()
120151
}
121152
}
122153

154+
int CLwipIf::ping(IPAddress ip, uint8_t ttl)
155+
{
156+
uint32_t result = -1;
157+
uint32_t timeout = 5000;
158+
uint32_t sendTime = 0;
159+
uint32_t startWait = 0;
160+
struct pbuf *p;
161+
struct raw_pcb* s;
162+
struct ping_data *d = new ping_data;
163+
if (!d){
164+
goto exit;
165+
}
166+
167+
//Create a raw socket
168+
s = raw_new(IP_PROTO_ICMP);
169+
if(!s) {
170+
goto exit;
171+
}
172+
173+
struct __attribute__((__packed__)) {
174+
struct icmp_echo_hdr header;
175+
uint8_t data[32];
176+
} request;
177+
178+
ICMPH_TYPE_SET(&request.header, ICMP_ECHO);
179+
ICMPH_CODE_SET(&request.header, 0);
180+
request.header.chksum = 0;
181+
request.header.id = 0xAFAF;
182+
request.header.seqno = random(0xffff);
183+
184+
d->echo_req = request.header;
185+
186+
for (size_t i = 0; i < sizeof(request.data); i++) {
187+
request.data[i] = i;
188+
}
189+
190+
request.header.chksum = inet_chksum(&request, sizeof(request));
191+
192+
ip_addr_t addr;
193+
addr.addr = ip;
194+
195+
d->endMillis = 0;
196+
197+
raw_recv(s, icmp_receive_callback, d);
198+
199+
// Build the packet
200+
p = pbuf_alloc(PBUF_IP, sizeof(request), PBUF_RAM);
201+
if (!p) {
202+
goto exit;
203+
}
204+
205+
//Load payload into buffer
206+
pbuf_take(p, &request, sizeof(request));
207+
208+
// Send the echo request
209+
sendTime = millis();
210+
raw_sendto(s, p, &addr);
211+
212+
// Wait for response
213+
startWait = millis();
214+
do {
215+
lwip_task();
216+
} while (d->endMillis == 0 && (millis() - startWait) < timeout);
217+
218+
if (d->endMillis != 0) {
219+
result = d->endMillis - sendTime;
220+
}
221+
222+
exit:
223+
pbuf_free(p);
224+
delete d;
225+
raw_remove(s);
226+
return result;
227+
}
228+
123229
/* -------------------------------------------------------------------------- */
124230
/* GET INSTANCE SINGLETONE FUNCTION */
125231
/* -------------------------------------------------------------------------- */

‎libraries/lwIpWrapper/src/CNetIf.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,12 @@ ip_addr_t* u8_to_ip_addr(uint8_t* ipu8, ip_addr_t* ipaddr);
124124

125125
uint32_t ip_addr_to_u32(ip_addr_t* ipaddr);
126126

127+
struct ping_data{
128+
uint32_t endMillis;
129+
icmp_echo_hdr echo_req;
130+
struct raw_pcb* s;
131+
};
132+
127133
/* Base class implements DHCP, derived class will switch it on or off */
128134
/* -------------------------------------------------------------------------- */
129135
class CNetIf {
@@ -429,6 +435,10 @@ class CLwipIf {
429435
int setWifiMode(WifiMode_t mode);
430436

431437
void lwip_task();
438+
/*
439+
* PING
440+
*/
441+
int ping(IPAddress ip, uint8_t ttl = 128);
432442
};
433443

434444
#endif
-3.38 KB
Binary file not shown.

‎libraries/lwIpWrapper/src/lwipopts.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@
273273
* (requires the LWIP_RAW option)
274274
*/
275275
#ifndef MEMP_NUM_RAW_PCB
276-
#define MEMP_NUM_RAW_PCB 0
276+
#define MEMP_NUM_RAW_PCB 1
277277
#endif
278278

279279
/**
@@ -633,7 +633,7 @@
633633
* LWIP_RAW==1: Enable application layer to hook into the IP layer itself.
634634
*/
635635
#ifndef LWIP_RAW
636-
#define LWIP_RAW 0
636+
#define LWIP_RAW 1
637637
#endif
638638

639639
/*

0 commit comments

Comments
 (0)
Please sign in to comment.