From f85c2780ad035a5e0b2e38cbd30293aaba2649e1 Mon Sep 17 00:00:00 2001 From: Nathaniel Wesley Filardo Date: Mon, 9 Dec 2019 13:33:30 +0100 Subject: [PATCH] New `net.if.info` call to show LwIP information (#2862) * Remove app/include/netif/wlan_lwip_if.h This file appears to be unused in our tree. * New `net.if.info` call to show LwIP information This is a generalization of `wifi.sta`'s and `wifi.ap`'s `getip` and `getmac` calls. I don't propose to deprecate those, but perhaps we should, in the documentation, point users at this function instead. The direct motivation is to permit continued use of DHCP-provided NTP servers in a future where https://github.com/nodemcu/nodemcu-firmware/pull/2819 has landed, now that https://github.com/nodemcu/nodemcu-firmware/pull/2709 is in the tree. But rather than exposing just that information, a more general interface seems useful. --- app/include/netif/wlan_lwip_if.h | 25 ------------- app/modules/net.c | 61 ++++++++++++++++++++++++++++++++ docs/modules/net.md | 37 +++++++++++++++++++ 3 files changed, 98 insertions(+), 25 deletions(-) delete mode 100644 app/include/netif/wlan_lwip_if.h diff --git a/app/include/netif/wlan_lwip_if.h b/app/include/netif/wlan_lwip_if.h deleted file mode 100644 index 13eff5e454..0000000000 --- a/app/include/netif/wlan_lwip_if.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2010-2011 Espressif System - * -*/ - -#ifndef _WLAN_LWIP_IF_H_ -#define _WLAN_LWIP_IF_H_ - -#define LWIP_IF0_PRIO 28 -#define LWIP_IF1_PRIO 29 - -enum { - SIG_LWIP_RX = 0, -}; - -struct netif * eagle_lwip_if_alloc(struct ieee80211_conn *conn, const uint8 *macaddr, struct ip_info *info); -struct netif * eagle_lwip_getif(uint8 index); - -#ifndef IOT_SIP_MODE -sint8 ieee80211_output_pbuf(struct netif *ifp, struct pbuf* pb); -#else -sint8 ieee80211_output_pbuf(struct ieee80211_conn *conn, esf_buf *eb); -#endif - -#endif /* _WLAN_LWIP_IF_H_ */ diff --git a/app/modules/net.c b/app/modules/net.c index 51efae715b..d8678ec9c8 100644 --- a/app/modules/net.c +++ b/app/modules/net.c @@ -18,6 +18,7 @@ #include "lwip/igmp.h" #include "lwip/tcp.h" #include "lwip/udp.h" +#include "lwip/dhcp.h" #if defined(CLIENT_SSL_ENABLE) && defined(LUA_USE_MODULES_NET) && defined(LUA_USE_MODULES_TLS) #define TLS_MODULE_PRESENT @@ -980,6 +981,62 @@ static int net_getdnsserver( lua_State* L ) { return 1; } +#pragma mark - netif info + +/* + * XXX This is internal to Espressif's SDK, but it's called from several places + * in the NodeMCU tree. It would be nicer if there were a LwIP export for this + * rather than this not-so-secret symbol. + */ +extern struct netif *eagle_lwip_getif(uint8); + +static void +push_ipaddr(lua_State *L, ip_addr_t *addr) { + char temp[20]; + ssize_t ipl = ets_snprintf(temp, sizeof temp, IPSTR, IP2STR(&addr->addr)); + lua_assert (ipl >= 0 && ipl < 20); + lua_pushlstring( L, temp, ipl ); +} + +static void +field_from_ipaddr(lua_State *L, const char * field_name, ip_addr_t* addr) { + if ( ip_addr_isany(addr) ) { + lua_pushnil(L); + } else { + push_ipaddr(L, addr); + } + lua_setfield(L, -2, field_name); +} + +static int net_if_info( lua_State* L ) { + int ifidx = luaL_optint(L, 1, 0); + + struct netif * nif = eagle_lwip_getif(ifidx); + if (nif == NULL) { + return luaL_error( L, "unknown network interface index %d", ifidx); + } + + lua_createtable(L, 0, + 4 + (nif->dhcp == NULL ? 0 : 1)); + + lua_pushlstring(L, nif->hwaddr, nif->hwaddr_len); + lua_setfield(L, -2, "hwaddr"); + + field_from_ipaddr(L, "ip" , &nif->ip_addr); + field_from_ipaddr(L, "netmask", &nif->netmask); + field_from_ipaddr(L, "gateway", &nif->gw); + + if (nif->dhcp != NULL) { + lua_createtable(L, 0, 3); + field_from_ipaddr(L, "server_ip" , &nif->dhcp->server_ip_addr ); + field_from_ipaddr(L, "client_ip" , &nif->dhcp->offered_ip_addr ); + field_from_ipaddr(L, "ntp_server", &nif->dhcp->offered_ntp_addr); + } + lua_setfield(L, -2, "dhcp"); + + return 1; +} + #pragma mark - Tables #ifdef TLS_MODULE_PRESENT @@ -1031,6 +1088,9 @@ LROT_BEGIN(net_dns) LROT_FUNCENTRY( resolve, net_dns_static ) LROT_END( net_dns, net_dns, 0 ) +LROT_BEGIN(net_if) + LROT_FUNCENTRY( info, net_if_info ) +LROT_END(net_if, net_if, 0) LROT_BEGIN(net) LROT_FUNCENTRY( createServer, net_createServer ) @@ -1039,6 +1099,7 @@ LROT_BEGIN(net) LROT_FUNCENTRY( multicastJoin, net_multicastJoin ) LROT_FUNCENTRY( multicastLeave, net_multicastLeave ) LROT_TABENTRY( dns, net_dns ) + LROT_TABENTRY( if, net_if ) #ifdef TLS_MODULE_PRESENT LROT_TABENTRY( cert, tls_cert ) #endif diff --git a/docs/modules/net.md b/docs/modules/net.md index dd1c0ee495..7f6b70e4ff 100644 --- a/docs/modules/net.md +++ b/docs/modules/net.md @@ -618,6 +618,43 @@ Sets the IP of the DNS server used to resolve hostnames. Default: resolver1.open #### See also [`net.dns:getdnsserver()`](#netdnsgetdnsserver) +# net.if Module + +## net.if.info() + +Return information about a network interface, specified by index. + +#### Syntax +`net.if.info(if_index)` + +#### Parameters +- `if_index` the interface index; on ESP8266, `0` is the wifi client (STA) and `1` + is the wifi AP. + +#### Returns +`nil` if the given `if_index` does not correspond to an interface. Otherwise, +a table containing ... + +* `ip`, `netmask`, and `gateway` configured for this interface, as dotted quad strings + or `nil` if none is set. + +* if DHCP was used to configure the interface, then `dhcp` will be a table containing... + + * `server_ip` -- the DHCP server itself, as a dotted quad + + * `client_ip` -- the IP address suggested for the client; likely, this equals `ip` + above, unless the configuration has been overridden. + + * `ntp_server` -- the NTP server suggested by the DHCP server. + +DNS servers are not tracked per-interface in LwIP and, as such, are not +reported here; use [`net.dns:getdnsserver()`](#netdnsgetdnsserver). + +#### Example + +`print(net.if.info(0).dhcp.ntp_server)` will show the NTP server suggested by +the DHCP server. + # net.cert Module This part gone to the [TLS](tls.md) module, link kept for backward compatibility.