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/ip_addr.h"
6+ #include " lwip/include/lwip/inet_chksum.h"
37
48IPAddress CNetIf::default_ip (" 192.168.0.10" );
59IPAddress CNetIf::default_nm (" 255.255.255.0" );
@@ -14,6 +18,32 @@ bool CLwipIf::pending_eth_rx = false;
1418
1519FspTimer CLwipIf::timer;
1620
21+ u8_t icmp_receive_callback (void * arg, struct raw_pcb * pcb, struct pbuf * p, const ip_addr_t * addr)
22+ {
23+ struct ping_data *d = (struct ping_data *)arg;
24+ struct __attribute__ ((__packed__)) {
25+ struct ip_hdr ipHeader;
26+ struct icmp_echo_hdr header;
27+ } response;
28+
29+ if (d->s == pcb) {
30+ if (p->len < sizeof (response)) {
31+ pbuf_free (p);
32+ return 1 ;
33+ }
34+
35+ pbuf_copy_partial (p, &response, sizeof (response), 0 );
36+
37+ if (response.header .id == d->echo_req .id && response.header .seqno == d->echo_req .seqno ) {
38+ d->endMillis = millis ();
39+ }
40+ pbuf_free (p);
41+ return 1 ;
42+ }
43+
44+ return 0 ;
45+ }
46+
1747ip_addr_t * u8_to_ip_addr (uint8_t * ipu8, ip_addr_t * ipaddr)
1848{
1949 IP_ADDR4 (ipaddr, ipu8[0 ], ipu8[1 ], ipu8[2 ], ipu8[3 ]);
@@ -120,6 +150,81 @@ void CLwipIf::lwip_task()
120150 }
121151}
122152
153+ int CLwipIf::ping (IPAddress ip, uint8_t ttl)
154+ {
155+ uint32_t result = -1 ;
156+ uint32_t timeout = 5000 ;
157+ uint32_t sendTime = 0 ;
158+ uint32_t startWait = 0 ;
159+ struct pbuf *p;
160+ struct raw_pcb * s;
161+ struct ping_data *d = new ping_data;
162+ if (!d){
163+ goto exit;
164+ }
165+
166+ // Create a raw socket
167+ s = raw_new (IP_PROTO_ICMP);
168+ if (!s) {
169+ goto exit;
170+ }
171+
172+ struct __attribute__ ((__packed__)) {
173+ struct icmp_echo_hdr header;
174+ uint8_t data[32 ];
175+ } request;
176+
177+ ICMPH_TYPE_SET (&request.header , ICMP_ECHO);
178+ ICMPH_CODE_SET (&request.header , 0 );
179+ request.header .chksum = 0 ;
180+ request.header .id = 0xAFAF ;
181+ request.header .seqno = random (0xffff );
182+
183+ d->echo_req = request.header ;
184+
185+ for (size_t i = 0 ; i < sizeof (request.data ); i++) {
186+ request.data [i] = i;
187+ }
188+
189+ request.header .chksum = inet_chksum (&request, sizeof (request));
190+
191+ ip_addr_t addr;
192+ addr.addr = ip;
193+
194+ d->endMillis = 0 ;
195+
196+ raw_recv (s, icmp_receive_callback, d);
197+
198+ // Build the packet
199+ p = pbuf_alloc (PBUF_IP, sizeof (request), PBUF_RAM);
200+ if (!p) {
201+ goto exit;
202+ }
203+
204+ // Load payload into buffer
205+ pbuf_take (p, &request, sizeof (request));
206+
207+ // Send the echo request
208+ sendTime = millis ();
209+ raw_sendto (s, p, &addr);
210+
211+ // Wait for response
212+ startWait = millis ();
213+ do {
214+ lwip_task ();
215+ } while (d->endMillis == 0 && (millis () - startWait) < timeout);
216+
217+ if (d->endMillis != 0 ) {
218+ result = d->endMillis - sendTime;
219+ }
220+
221+ exit:
222+ pbuf_free (p);
223+ delete d;
224+ raw_remove (s);
225+ return result;
226+ }
227+
123228/* -------------------------------------------------------------------------- */
124229/* GET INSTANCE SINGLETONE FUNCTION */
125230/* -------------------------------------------------------------------------- */
0 commit comments