Skip to content

Commit 03b3b2b

Browse files
author
vsky
committed
Net_info module exposing ping function initial commit
1 parent 32ad759 commit 03b3b2b

File tree

6 files changed

+274
-1
lines changed

6 files changed

+274
-1
lines changed

app/include/lwip/app/ping.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ struct ping_option{
5454
ping_recv_function recv_function;
5555
ping_sent_function sent_function;
5656
void* reverse;
57+
struct ping_msg *parent_msg;
5758
};
5859

5960
struct ping_msg{

app/include/user_modules.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
//#define LUA_USE_MODULES_MDNS
3939
#define LUA_USE_MODULES_MQTT
4040
#define LUA_USE_MODULES_NET
41+
#define LUA_USE_MODULES_NET_INFO
4142
#define LUA_USE_MODULES_NODE
4243
#define LUA_USE_MODULES_OW
4344
//#define LUA_USE_MODULES_PCM
@@ -76,6 +77,7 @@
7677
//#define LUA_USE_MODULES_WS2812
7778
//#define LUA_USE_MODULES_WS2812_EFFECTS
7879
//#define LUA_USE_MODULES_XPT2046
80+
#define LUA_USE_MODULES_TEST
7981

8082
//debug modules
8183
//#define LUA_USE_MODULES_SWTMR_DBG //SWTMR timer suspend Debug functions

app/lwip/app/ping.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,13 @@ ping_recv(void *arg, struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *addr)
164164
pingresp.resp_time = delay;
165165
pingresp.seqno = ntohs(iecho->seqno);
166166
pingresp.ping_err = 0;
167-
pingmsg->ping_opt->recv_function(pingmsg->ping_opt,(void*) &pingresp);
167+
168+
// hand back pointer to message without breaking compatibility
169+
pingmsg->ping_opt->parent_msg = pingmsg;
170+
171+
// pingmsg->ping_opt->recv_function(pingmsg,(void*) &pingresp);
172+
pingmsg->ping_opt->recv_function(pingmsg->ping_opt, (void*) &pingresp);
173+
168174
}
169175
}
170176
seqno = iecho->seqno;

app/modules/net_info.c

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
// ***************************************************************************
2+
// net_info module for ESP8266 with nodeMCU
3+
//
4+
// adopted jan 2017 for commit to nodeMCU by Wolfgang Rosner
5+
// re-worked by Lukas Voborsky, @voborsky
6+
// ***************************************************************************
7+
8+
/**
9+
* test.ping()
10+
* Description:
11+
* Send ICMP ping request to address, optionally call callback when response received
12+
*
13+
* Syntax:
14+
* wifi.sta.getconfig(ssid, password) --Set STATION configuration, Auto-connect by default, Connects to any BSSID
15+
* test.ping(address) -- send 4 ping requests to target address
16+
* test.ping(address, n) -- send n ping requests to target address
17+
* test.ping(address, n, callback) -- send n ping requests to target address
18+
* Parameters:
19+
* address: string
20+
* n: number of requests to send
21+
* callback:
22+
* Returns:
23+
* Nothing.
24+
*
25+
* Example:
26+
* test.ping("192.168.0.1") -- send 4 pings to 192.168.0.1
27+
* test.ping("192.168.0.1", 10) -- send 10 pings to 192.168.0.1
28+
* test.ping("192.168.0.1", 10, got_ping) -- send 10 pings to 192.168.0.1, call got_ping() with the
29+
* -- ping results
30+
*/
31+
32+
#define NODE_DEBUG
33+
34+
#include "module.h"
35+
#include "lauxlib.h"
36+
#include "platform.h"
37+
#include "mem.h"
38+
#include "task/task.h"
39+
40+
#include "lwip/ip_addr.h"
41+
#include "espconn.h"
42+
#include "lwip/dns.h"
43+
#include "lwip/app/ping.h"
44+
#include "lwip/raw.h"
45+
46+
typedef struct {
47+
struct ping_option ping_opt; // ping_opt needs to be the first element of the structure
48+
sint32_t ping_callback_ref;
49+
sint32_t self_ref; /* Reference to this structure as userdata */
50+
uint8_t ping_host_count;
51+
ip_addr_t ping_host_ip;
52+
} net_info_ping_t;
53+
typedef net_info_ping_t* ping_t;
54+
55+
static ping_t nip_get( lua_State *L, int stack ) {
56+
ping_t nip = (ping_t)luaL_checkudata(L, stack, "net_info.ping");
57+
if (nip == NULL) {
58+
return (ping_t)luaL_error(L, "ping object expected");
59+
}
60+
return nip;
61+
}
62+
63+
void ping_received(void *arg, void *data) {
64+
NODE_DBG("[ping_received] \n");
65+
// struct ping_option *pingopt = (struct ping_option*)arg;
66+
ping_t nip = (ping_t)arg;
67+
struct ping_resp *pingresp = (struct ping_resp*)data;
68+
69+
char ipaddrstr[16];
70+
ip_addr_t source_ip;
71+
72+
source_ip.addr = nip->ping_opt.ip;
73+
ipaddr_ntoa_r(&source_ip, ipaddrstr, sizeof(ipaddrstr));
74+
75+
if (nip->ping_callback_ref != LUA_NOREF) {
76+
lua_State *L = lua_getstate();
77+
lua_rawgeti(L, LUA_REGISTRYINDEX, nip->ping_callback_ref);
78+
lua_pushinteger(L, pingresp->bytes);
79+
lua_pushstring(L, ipaddrstr);
80+
lua_pushinteger(L, pingresp->seqno);
81+
lua_pushinteger(L, pingresp->resp_time);
82+
lua_call(L, 4, 0);
83+
}
84+
}
85+
86+
static int net_info_ping(lua_State *L)
87+
{
88+
NODE_DBG("[net_info_ping]\n");
89+
ping_t nip = nip_get(L, 1);
90+
91+
if (nip->self_ref == LUA_NOREF) {
92+
lua_pushvalue(L, 1);
93+
nip->self_ref = luaL_ref(L, LUA_REGISTRYINDEX);
94+
}
95+
96+
const char *ping_target;
97+
unsigned count = 4;
98+
99+
// retrieve address arg (mandatory)
100+
if (lua_isstring(L, 2)) {
101+
ping_target = luaL_checkstring(L, 2);
102+
} else {
103+
return luaL_error(L, "no address specified");
104+
}
105+
106+
// retrieve count arg (optional)
107+
if (lua_isnumber(L, 3)) {
108+
count = luaL_checkinteger(L, 3);
109+
}
110+
111+
// retrieve callback arg (optional)
112+
if (nip->ping_callback_ref != LUA_NOREF) {
113+
luaL_unref(L, LUA_REGISTRYINDEX, nip->ping_callback_ref);
114+
}
115+
nip->ping_callback_ref = LUA_NOREF;
116+
117+
if (lua_type(L, 4) == LUA_TFUNCTION || lua_type(L, 4) == LUA_TLIGHTFUNCTION) {
118+
nip->ping_callback_ref = luaL_ref(L, LUA_REGISTRYINDEX);
119+
}
120+
121+
// attempt to parse ping target as IP
122+
uint32 ip = ipaddr_addr(ping_target);
123+
124+
if (ip != IPADDR_NONE) {
125+
nip->ping_opt.count = count;
126+
nip->ping_opt.ip = ip;
127+
nip->ping_opt.coarse_time = 0;
128+
nip->ping_opt.recv_function = &ping_received;
129+
130+
NODE_DBG("[net_info_ping] calling ping_start\n");
131+
ping_start(&(nip->ping_opt));
132+
} else {
133+
return luaL_error(L, "wrong IP address");
134+
}
135+
136+
return 0;
137+
}
138+
139+
static int net_info_create( lua_State *L ) {
140+
NODE_DBG("[net_info_create]\n");
141+
ping_t nip = (ping_t)lua_newuserdata(L, sizeof(net_info_ping_t));
142+
if (!nip) return luaL_error(L, "not enough memory");
143+
luaL_getmetatable(L, "net_info.ping");
144+
lua_setmetatable(L, -2);
145+
nip->ping_callback_ref = LUA_NOREF;
146+
nip->self_ref = LUA_NOREF;
147+
return 1;
148+
}
149+
150+
static int net_info_unregister(lua_State* L){
151+
NODE_DBG("[net_info_unregister]\n");
152+
ping_t nip = nip_get(L, 1);
153+
154+
if (nip->self_ref != LUA_REFNIL) {
155+
luaL_unref(L, LUA_REGISTRYINDEX, nip->self_ref);
156+
nip->self_ref = LUA_NOREF;
157+
}
158+
159+
if(nip->ping_callback_ref != LUA_NOREF) {
160+
luaL_unref(L, LUA_REGISTRYINDEX, nip->ping_callback_ref);
161+
}
162+
nip->ping_callback_ref = LUA_NOREF;
163+
return 0;
164+
}
165+
166+
// Module function map
167+
LROT_BEGIN(net_info_dyn)
168+
LROT_FUNCENTRY( ping, net_info_ping )
169+
LROT_FUNCENTRY( __gc, net_info_unregister )
170+
LROT_TABENTRY( __index, net_info_dyn )
171+
LROT_END( net_info_dyn, net_info_dyn, LROT_MASK_GC_INDEX )
172+
173+
174+
LROT_BEGIN(net_info)
175+
LROT_FUNCENTRY( create, net_info_create )
176+
LROT_END( net_ifo, NULL, 0 )
177+
178+
int luaopen_net_info( lua_State *L ){
179+
NODE_DBG("[luaopen_net_info]\n");
180+
luaL_rometatable(L, "net_info.ping", LROT_TABLEREF(net_info_dyn));
181+
return 0;
182+
}
183+
184+
NODEMCU_MODULE(NET_INFO, "net_info", net_info, luaopen_net_info);

docs/en/modules/net_info.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# net_info Module
2+
| Since | Origin / Contributor | Maintainer | Source |
3+
| :----- | :-------------------- | :---------- | :------ |
4+
| 2017-01-21 | [smcl](http://blog.mclemon.io/esp8266-contributing-to-the-nodemcu-ecosystem) | [wolfgangr](https://github.com/wolfgangr/nodemcu-firmware) | [net_info.c](../../../app/modules/net_info.c)
5+
6+
7+
This module is a stub to collect common network diagnostic and analysis tools.
8+
9+
##net_info.ping()
10+
send ICMP ECHO_REQUEST to network hosts
11+
12+
**Synopsis:**:
13+
```
14+
net_info.ping(host [, count [, callback]])
15+
```
16+
17+
**Usage example:**
18+
```
19+
=net_info.ping("www.google.de",2)
20+
> 32 bytes from 172.217.20.195, icmp_seq=25 ttl=53 time=37ms
21+
32 bytes from 172.217.20.195, icmp_seq=26 ttl=53 time=38ms
22+
ping 2, timeout 0, total payload 64 bytes, 1946 ms
23+
```
24+
25+
26+
**Description:** (from *linux man 8 ping*)
27+
28+
> `ping` uses the ICMP protocol's mandatory ECHO_REQUEST datagram to elicit an ICMP ECHO_RESPONSE from a host or gateway. ECHO_REQUEST datagrams (''pings'') have an IP and ICMP header, followed by a struct timeval and then an arbitrary number of ''pad'' bytes used to fill out the packet.
29+
30+
31+
**Usage variants**
32+
33+
ping host **by IP-Adress:**
34+
```
35+
net_info.ping("1.2.3.4")
36+
```
37+
Enter IP-Adress in commonly known dotted quad-decimal notation, enclosed in string quotes.
38+
39+
!!! Note
40+
There is only limited error checking on the validity of IP adresses in lwIP. Check twice!
41+
42+
43+
Use **DNS resolver** to get IP adress for ping:
44+
```
45+
net_info.ping("hostname")
46+
```
47+
48+
!!! Note
49+
This only works with Network access and DNS resolution properly configured.
50+
51+
52+
Custom **ping count**:
53+
```
54+
net_info.ping(host, count)
55+
```
56+
* `host` can be given by IP or hostname as above.
57+
* `count` number of repetitive pings - default is 4 if omitted.
58+
59+
60+
Ping **callback function**:
61+
```
62+
net_info.ping(host, count, callback)
63+
```
64+
Instead of printing ping results on the console, the given callback function ist called each time a ECHO_RESPONSE is received.
65+
66+
The callback receives the following arguments:
67+
```
68+
function ping_recv(bytes, ipaddr, seqno, ttl, ping)
69+
```
70+
* length of message
71+
* ip-address of pinged host
72+
* icmp_seq number
73+
* time-to-live-value
74+
* ping time in ms
75+
76+
!!! Caution
77+
The callback functionality is still untested. Use at even more your own risk!
78+
79+
For further reference to callback functionality, see smcl origin link provided on top of this page.

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ pages:
8383
- 'mdns': 'modules/mdns.md'
8484
- 'mqtt': 'modules/mqtt.md'
8585
- 'net': 'modules/net.md'
86+
- 'net_info': 'en/modules/net_info.md'
8687
- 'node': 'modules/node.md'
8788
- 'ow (1-Wire)': 'modules/ow.md'
8889
- 'pcm' : 'modules/pcm.md'

0 commit comments

Comments
 (0)