Skip to content

Commit

Permalink
Net_info module exposing ping function initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
vsky committed Jul 26, 2019
1 parent 6d9c5a4 commit c520bef
Show file tree
Hide file tree
Showing 6 changed files with 289 additions and 1 deletion.
2 changes: 2 additions & 0 deletions app/include/lwip/app/ping.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ struct ping_option{
ping_recv_function recv_function;
ping_sent_function sent_function;
void* reverse;
struct ping_msg *parent_msg;
};

struct ping_msg{
Expand All @@ -75,6 +76,7 @@ struct ping_resp{
uint32 bytes;
uint32 total_bytes;
uint32 total_time;
uint8 ttl;
sint8 ping_err;
};

Expand Down
2 changes: 2 additions & 0 deletions app/include/user_modules.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
//#define LUA_USE_MODULES_MDNS
#define LUA_USE_MODULES_MQTT
#define LUA_USE_MODULES_NET
#define LUA_USE_MODULES_NET_INFO
#define LUA_USE_MODULES_NODE
#define LUA_USE_MODULES_OW
//#define LUA_USE_MODULES_PCM
Expand Down Expand Up @@ -76,6 +77,7 @@
//#define LUA_USE_MODULES_WS2812
//#define LUA_USE_MODULES_WS2812_EFFECTS
//#define LUA_USE_MODULES_XPT2046
#define LUA_USE_MODULES_TEST

//debug modules
//#define LUA_USE_MODULES_SWTMR_DBG //SWTMR timer suspend Debug functions
Expand Down
9 changes: 8 additions & 1 deletion app/lwip/app/ping.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,14 @@ ping_recv(void *arg, struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *addr)
pingresp.resp_time = delay;
pingresp.seqno = ntohs(iecho->seqno);
pingresp.ping_err = 0;
pingmsg->ping_opt->recv_function(pingmsg->ping_opt,(void*) &pingresp);
pingresp.ttl = iphdr->_ttl;

// hand back pointer to message without breaking compatibility
pingmsg->ping_opt->parent_msg = pingmsg;

// pingmsg->ping_opt->recv_function(pingmsg,(void*) &pingresp);
pingmsg->ping_opt->recv_function(pingmsg->ping_opt, (void*) &pingresp);

}
}
seqno = iecho->seqno;
Expand Down
197 changes: 197 additions & 0 deletions app/modules/net_info.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
/*
* http://blog.mclemon.io/esp8266-contributing-to-the-nodemcu-ecosystem
* https://github.com/smcl/nodemcu-firmware/blob/cc04aaf92c1c076c30ef0b0eee43b3f924137440/app/modules/test.c
*
* extracted ping function
* adopted jan 2017 for commit to nodeMCU by Wolfgang Rosner
*/


#include "module.h"
#include "lauxlib.h"
#include "platform.h"

// #include <string.h>
// #include <strings.h>
// #include <stddef.h>
// #include <stdint.h>
#include "mem.h"

#include "lwip/ip_addr.h"
#include "espconn.h"
#include "lwip/dns.h"
#include "lwip/app/ping.h"
#include "lwip/raw.h"


#include "task/task.h"



// https://github.com/nodemcu/nodemcu-firmware/wiki/[DRAFT]-How-to-write-a-C-module#debug-and-error-messages

#define NET_INFO_DEBUG_ON

#define log_prefix " ### DEBUG: net_info ### : "

#if defined(DEVELOP_VERSION)
#define NET_INFO_DEBUG_ON
#endif
#if defined(NET_INFO_DEBUG_ON)
#define NET_INFO_DEBUG(format, ...) dbg_printf("%s"format"", log_prefix, ##__VA_ARGS__)
#else
#define NET_INFO_DEBUG(...)
#endif
#if defined(NODE_ERROR)
#define NET_INFO_ERR(format, ...) NODE_ERR("%s"format"\n", log_prefix, ##__VA_ARGS__)
#else
#define NET_INFO_ERR(...)
#endif


#define NET_INFO_PRIORITY_OUTPUT TASK_PRIORITY_MEDIUM
#define NET_INFO_PRIORITY_ERROR TASK_PRIORITY_MEDIUM

// these statics should go away for reentrancy and maybe other reasons!
static int ping_callback_ref;
static int ping_host_count;
static ip_addr_t ping_host_ip;
struct ping_option *ping_opt = NULL;

void ping_received(void *arg, void *data) {
// this would require change of the interface
// struct ping_msg *pingmsg = (struct ping_msg*)arg;
// struct ping_option *pingopt = pingmsg->ping_opt;
struct ping_option *pingopt = (struct ping_option*)arg;
struct ping_msg *pingmsg = pingopt->parent_msg ;

struct ping_resp *pingresp = (struct ping_resp*)data;

char ipaddrstr[16];
ip_addr_t source_ip;

source_ip.addr = pingopt->ip;
ipaddr_ntoa_r(&source_ip, ipaddrstr, sizeof(ipaddrstr));

if (ping_callback_ref != LUA_NOREF) {
lua_State *L = lua_getstate();
lua_rawgeti(L, LUA_REGISTRYINDEX, ping_callback_ref);
lua_pushinteger(L, pingresp->bytes);
lua_pushstring(L, ipaddrstr);
lua_pushinteger(L, pingresp->seqno);
lua_pushinteger(L, pingresp->ttl);
lua_pushinteger(L, pingresp->resp_time);
lua_call(L, 5, 0);
}
}

static void ping_by_hostname(const char *name, ip_addr_t *ipaddr, void *arg) {
if (!ping_opt) {
ping_opt = (struct ping_option *)os_zalloc(sizeof(struct ping_option));
} else {
os_memset (ping_opt, 0, sizeof(struct ping_option));
}

if (ipaddr == NULL) {
lua_State *L = lua_getstate();
luaL_error(L, "SEVERE problem resolving hostname - network and DNS accessible?\n");
return;
}
if (ipaddr->addr == IPADDR_NONE) {
lua_State *L = lua_getstate();
luaL_error(L, "problem resolving hostname - maybe nonexistent host?\n");
return;
}

ping_opt->count = ping_host_count;
ping_opt->ip = ipaddr->addr;
ping_opt->coarse_time = 0;
ping_opt->recv_function = &ping_received;

ping_start(ping_opt);
}


/**
* test.ping()
* Description:
* Send ICMP ping request to address, optionally call callback when response received
*
* Syntax:
* wifi.sta.getconfig(ssid, password) --Set STATION configuration, Auto-connect by default, Connects to any BSSID
* test.ping(address) -- send 4 ping requests to target address
* test.ping(address, n) -- send n ping requests to target address
* test.ping(address, n, callback) -- send n ping requests to target address
* Parameters:
* address: string
* n: number of requests to send
* callback:
* Returns:
* Nothing.
*
* Example:
* test.ping("192.168.0.1") -- send 4 pings to 192.168.0.1
* test.ping("192.168.0.1", 10) -- send 10 pings to 192.168.0.1
* test.ping("192.168.0.1", 10, got_ping) -- send 10 pings to 192.168.0.1, call got_ping() with the
* -- ping results
*/

static int net_info_ping(lua_State *L)
{
const char *ping_target;
unsigned count = 4;

// retrieve address arg (mandatory)
if (lua_isstring(L, 1)) {
ping_target = luaL_checkstring(L, 1);
} else {
return luaL_error(L, "no address specified");
}

// retrieve count arg (optional)
if (lua_isnumber(L, 2)) {
count = luaL_checkinteger(L, 2);
}

// retrieve callback arg (optional)
if (ping_callback_ref != LUA_NOREF)
luaL_unref(L, LUA_REGISTRYINDEX, ping_callback_ref);
ping_callback_ref = LUA_NOREF;

if (lua_type(L, 3) == LUA_TFUNCTION || lua_type(L, 3) == LUA_TLIGHTFUNCTION)
ping_callback_ref = luaL_ref(L, LUA_REGISTRYINDEX);

// attempt to parse ping target as IP
uint32 ip = ipaddr_addr(ping_target);

if (ip != IPADDR_NONE) {
if (!ping_opt) {
ping_opt = (struct ping_option *)os_zalloc(sizeof(struct ping_option));
} else {
os_memset (ping_opt, 0, sizeof(struct ping_option));
}


ping_opt->count = count;
ping_opt->ip = ip;
ping_opt->coarse_time = 0;
ping_opt->recv_function = &ping_received;

ping_start(ping_opt);
} else {
ping_host_count = count;

struct espconn *ping_dns_lookup;
espconn_create(ping_dns_lookup);
espconn_gethostbyname(ping_dns_lookup, ping_target, &ping_host_ip, ping_by_hostname);
}

return 0;
}

// Module function map
LROT_BEGIN(net_info)
LROT_FUNCENTRY( ping, net_info_ping )
LROT_END( net_ifo, NULL, 0 )

NODEMCU_MODULE(NET_INFO, "net_info", net_info, NULL);
79 changes: 79 additions & 0 deletions docs/en/modules/net_info.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# net_info Module
| Since | Origin / Contributor | Maintainer | Source |
| :----- | :-------------------- | :---------- | :------ |
| 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)


This module is a stub to collect common network diagnostic and analysis tools.

##net_info.ping()
send ICMP ECHO_REQUEST to network hosts

**Synopsis:**:
```
net_info.ping(host [, count [, callback]])
```

**Usage example:**
```
=net_info.ping("www.google.de",2)
> 32 bytes from 172.217.20.195, icmp_seq=25 ttl=53 time=37ms
32 bytes from 172.217.20.195, icmp_seq=26 ttl=53 time=38ms
ping 2, timeout 0, total payload 64 bytes, 1946 ms
```


**Description:** (from *linux man 8 ping*)

> `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.

**Usage variants**

ping host **by IP-Adress:**
```
net_info.ping("1.2.3.4")
```
Enter IP-Adress in commonly known dotted quad-decimal notation, enclosed in string quotes.

!!! Note
There is only limited error checking on the validity of IP adresses in lwIP. Check twice!


Use **DNS resolver** to get IP adress for ping:
```
net_info.ping("hostname")
```

!!! Note
This only works with Network access and DNS resolution properly configured.


Custom **ping count**:
```
net_info.ping(host, count)
```
* `host` can be given by IP or hostname as above.
* `count` number of repetitive pings - default is 4 if omitted.


Ping **callback function**:
```
net_info.ping(host, count, callback)
```
Instead of printing ping results on the console, the given callback function ist called each time a ECHO_RESPONSE is received.

The callback receives the following arguments:
```
function ping_recv(bytes, ipaddr, seqno, ttl, ping)
```
* length of message
* ip-address of pinged host
* icmp_seq number
* time-to-live-value
* ping time in ms

!!! Caution
The callback functionality is still untested. Use at even more your own risk!

For further reference to callback functionality, see smcl origin link provided on top of this page.
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ pages:
- 'mdns': 'modules/mdns.md'
- 'mqtt': 'modules/mqtt.md'
- 'net': 'modules/net.md'
- 'net_info': 'en/modules/net_info.md'
- 'node': 'modules/node.md'
- 'ow (1-Wire)': 'modules/ow.md'
- 'pcm' : 'modules/pcm.md'
Expand Down

0 comments on commit c520bef

Please sign in to comment.