Skip to content

Commit

Permalink
Merge pull request #19849 from krzysztof-cabaj/LWIP-ifconfig-IPv4-con…
Browse files Browse the repository at this point in the history
…figuration

sys/shell/lwip: add IPv4 configuration to lwip ifconfig command
  • Loading branch information
benpicco authored Apr 10, 2024
2 parents 8791e67 + 71d47cd commit e3c02f5
Showing 1 changed file with 198 additions and 10 deletions.
208 changes: 198 additions & 10 deletions sys/shell/cmds/lwip_netif.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2021 Google LLC
* 2024 Krzysztof Cabaj <kcabaj@gmail.com>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
Expand All @@ -12,8 +13,10 @@
*
* @file
* @brief Shell command for printing lwIP network interface status
* and configuration of IPv4 address
*
* @author Erik Ekman <eekman@google.com>
* Krzysztof Cabaj <kcabaj@gmail.com>
*
* @}
*/
Expand All @@ -26,6 +29,11 @@
#include "net/netopt.h"
#include "shell.h"

#include "arch/sys_arch.h"
#include <arpa/inet.h>

#include "net/netif.h"

#ifdef MODULE_LWIP_IPV6
static void _netif_list_ipv6(struct netif *netif, int addr_index, uint8_t state)
{
Expand All @@ -34,17 +42,20 @@ static void _netif_list_ipv6(struct netif *netif, int addr_index, uint8_t state)
printf(" scope: ");
if (ip6_addr_isglobal(netif_ip6_addr(netif, addr_index))) {
printf("global");
} else if (ip6_addr_islinklocal(netif_ip6_addr(netif, addr_index))) {
}
else if (ip6_addr_islinklocal(netif_ip6_addr(netif, addr_index))) {
printf("link");
} else if (ip6_addr_issitelocal(netif_ip6_addr(netif, addr_index))) {
}
else if (ip6_addr_issitelocal(netif_ip6_addr(netif, addr_index))) {
printf("site");
} else {
}
else {
printf("unknown");
}
printf(" state:");
if (ip6_addr_istentative(state)) {
printf(" tentative (%u probes send)",
(unsigned)(state & IP6_ADDR_TENTATIVE_COUNT_MASK));
(unsigned)(state & IP6_ADDR_TENTATIVE_COUNT_MASK));
}
if (ip6_addr_isvalid(state)) {
printf(" valid");
Expand All @@ -65,20 +76,21 @@ static void _netif_list(struct netif *netif)
char name[CONFIG_NETIF_NAMELENMAX];
struct netdev *dev = netif->state;
lwip_netif_t *compat = container_of(netif, lwip_netif_t, lwip_netif);

netif_get_name(&compat->common_netif, name);
printf("Iface %s HWaddr: ", name);
for (i = 0; i < netif->hwaddr_len; i++) {
printf("%02x", netif->hwaddr[i]);
if ((i+1) < netif->hwaddr_len) {
if ((i + 1) < netif->hwaddr_len) {
printf(":");
}
}
printf(" Link: %s State: %s\n",
netif_is_link_up(netif) ? "up" : "down",
netif_is_up(netif) ? "up" : "down");
netif_is_link_up(netif) ? "up" : "down",
netif_is_up(netif) ? "up" : "down");
printf(" Link type: %s\n",
(dev->driver->get(dev, NETOPT_IS_WIRED, &i, sizeof(i)) > 0) ?
"wired" : "wireless");
(dev->driver->get(dev, NETOPT_IS_WIRED, &i, sizeof(i)) > 0) ?
"wired" : "wireless");
#ifdef MODULE_LWIP_IPV4
printf(" inet addr: ");
ip_addr_debug_print(LWIP_DBG_ON, netif_ip_addr4(netif));
Expand All @@ -105,6 +117,133 @@ static void _netif_list(struct netif *netif)
#endif
}

#ifdef MODULE_LWIP_IPV4
static void _usage_add4(char *cmd)
{
printf("usage: %s add <interface> <IPv4>/<prefix>\n", cmd);
printf("usage: %s add <interface> <IPv4>/<prefix> gw <IPv4>\n", cmd);
}

static void _lwip_prefix_to_subnet(int prefix, ip4_addr_t *subnet)
{
uint32_t value = 0;
uint32_t tmp = 0x80000000;

for (int i = 0; i < prefix; i++) {
value += tmp;
tmp = tmp >> 1;
}
subnet->addr = htonl(value);
}

static int _lwip_netif_add4(int argc, char **argv)
{
struct netif *iface;
char *ip_ptr, *prefix_ptr = NULL;
ip4_addr_t ip, subnet, gw;
int prefix;

if (argc != 4 && argc != 6) {
printf("error: invalid number of parameters\n");
_usage_add4(argv[0]);
return 1;
}

sys_lock_tcpip_core();
iface = netif_find(argv[2]);

if (iface == NULL) {
printf("error: invalid interface name (names are case sensitive)\n");
sys_unlock_tcpip_core();
return 1;
}

ip_ptr = argv[3];
while ((*ip_ptr) != 0) {
if ((*ip_ptr) == '/') {
*ip_ptr = 0;
prefix_ptr = ip_ptr + 1;
}

ip_ptr++;
}
ip_ptr = argv[3];

if (prefix_ptr == NULL) {
printf("error: invalid IPv4 prefix notation\n");
_usage_add4(argv[0]);
sys_unlock_tcpip_core();
return 1;
}

if (inet_pton(AF_INET, ip_ptr, &ip.addr) != 1) {
printf("error:invalid IPv4 address\n");
sys_unlock_tcpip_core();
return 1;
}

prefix = atoi(prefix_ptr);

if (prefix < 0 || prefix > 32) {
printf("error:invalid prefix, should be in range <0, 32>\n");
sys_unlock_tcpip_core();
return 1;
}

_lwip_prefix_to_subnet(prefix, &subnet);

if (argc == 4) {
netif_set_addr(iface, &ip, &subnet, NULL);
}
else {
if (strcmp("gw", argv[4]) != 0) {
printf("error: invalid subcommand \"%s\"\n", argv[4]);
_usage_add4(argv[0]);
sys_unlock_tcpip_core();
return 1;
}

if (inet_pton(AF_INET, argv[5], &gw.addr) != 1) {
printf("error: invalid gateway address\n");
sys_unlock_tcpip_core();
return 1;
}
netif_set_addr(iface, &ip, &subnet, &gw);
}

sys_unlock_tcpip_core();
return 0;
}
#endif

#ifdef MODULE_LWIP_IPV6
static void _usage_add6(char *cmd)
{
printf("usage: %s add for LWIP IPv6 currently not implemented\n", cmd);
}

static int _lwip_netif_add6(int argc, char **argv)
{
(void)argc;
(void)argv;
printf("error: LWIP IPv6 configuration currently not implemented\n");

return 0;
}
#endif

static void _lwip_netif_help(char *cmd)
{
printf("usage: %s\n", cmd);
printf("usage: %s help\n", cmd);
#ifdef MODULE_LWIP_IPV4
_usage_add4(cmd);
#endif
#ifdef MODULE_LWIP_IPV6
_usage_add6(cmd);
#endif
}

static int _lwip_netif_config(int argc, char **argv)
{
if (argc < 2) {
Expand All @@ -124,7 +263,56 @@ static int _lwip_netif_config(int argc, char **argv)
}
return 0;
}
printf("%s takes no arguments.\n", argv[0]);
else {
if (strcmp("help", argv[1]) == 0) {
_lwip_netif_help(argv[0]);
}
#if defined(MODULE_LWIP_IPV4) || defined(MODULE_LWIP_IPV6)
else if (strcmp("add", argv[1]) == 0) {
if (argc != 4 && argc != 6) {
printf("error: invalid number of parameters\n");
#ifdef MODULE_LWIP_IPV4
_usage_add4(argv[0]);
#endif
#ifdef MODULE_LWIP_IPV6
_usage_add6(argv[0]);
#endif
return 0;
}

char *prefix_ptr = strchr(argv[3], '/');

if (prefix_ptr == NULL) {
printf("error: provide IP address with prefix\n");
return 0;
}

*prefix_ptr = 0;

#ifdef MODULE_LWIP_IPV4
ipv4_addr_t ip4;

if (ipv4_addr_from_buf(&ip4, argv[3], strlen(argv[3])) != NULL) {
*prefix_ptr = '/';
_lwip_netif_add4(argc, argv);
return 1;
}
#endif
#ifdef MODULE_LWIP_IPV6
ipv6_addr_t ip6;
if (ipv6_addr_from_buf(&ip6, argv[3], strlen(argv[3])) != NULL) {
*prefix_ptr = '/';
_lwip_netif_add6(argc, argv);
return 1;
}
#endif
printf("error: use proper IPv4 or IPv6 address\n");
}
#endif
else {
printf("error: invalid subcommand - use help\n");
}
}
return 1;
}

Expand Down

0 comments on commit e3c02f5

Please sign in to comment.