From d11ae3a4c880696c40ce7f7c6bad83bcb25d15dd Mon Sep 17 00:00:00 2001 From: Ravi Dondaputi Date: Wed, 4 Jan 2023 18:39:28 +0530 Subject: [PATCH] net: shell: Add support to configure IP address Add support to configure IP address using net shell. Signed-off-by: Ravi Dondaputi --- subsys/net/ip/net_shell.c | 171 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) diff --git a/subsys/net/ip/net_shell.c b/subsys/net/ip/net_shell.c index eaa2d449e72..8ceba06c675 100644 --- a/subsys/net/ip/net_shell.c +++ b/subsys/net/ip/net_shell.c @@ -3536,6 +3536,163 @@ static int cmd_net_ipv6(const struct shell *sh, size_t argc, char *argv[]) return 0; } +#if defined(CONFIG_NET_NATIVE_IPV4) +static void ip_address_lifetime_cb(struct net_if *iface, void *user_data) +{ + struct net_shell_user_data *data = user_data; + const struct shell *sh = data->sh; + struct net_if_ipv4 *ipv4 = iface->config.ip.ipv4; + const char *extra; + int i; + + ARG_UNUSED(user_data); + + PR("\nIPv4 addresses for interface %d (%p) (%s)\n", + net_if_get_by_iface(iface), iface, iface2str(iface, &extra)); + PR("============================================%s\n", extra); + + if (!ipv4) { + PR("No IPv4 config found for this interface.\n"); + return; + } + + PR("Type \tState \tLifetime (sec)\tAddress\n"); + + for (i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) { + if (!ipv4->unicast[i].is_used || + ipv4->unicast[i].address.family != AF_INET) { + continue; + } + + PR("%s \t%s \t%12s/%12s\n", + addrtype2str(ipv4->unicast[i].addr_type), + addrstate2str(ipv4->unicast[i].addr_state), + net_sprint_ipv4_addr( + &ipv4->unicast[i].address.in_addr), + net_sprint_ipv4_addr( + &ipv4->netmask)); + } +} +#endif /* CONFIG_NET_NATIVE_IPV4 */ + +static int cmd_net_ipv4(const struct shell *sh, size_t argc, char *argv[]) +{ + PR("IPv4 support : %s\n", + IS_ENABLED(CONFIG_NET_IPV4) ? + "enabled" : "disabled"); + if (!IS_ENABLED(CONFIG_NET_IPV4)) { + return -ENOEXEC; + } + +#if defined(CONFIG_NET_NATIVE_IPV4) + struct net_shell_user_data user_data; + + PR("IPv4 fragmentation support : %s\n", + IS_ENABLED(CONFIG_NET_IPV4_FRAGMENT) ? "enabled" : + "disabled"); + PR("Max number of IPv4 network interfaces " + "in the system : %d\n", + CONFIG_NET_IF_MAX_IPV4_COUNT); + PR("Max number of unicast IPv4 addresses " + "per network interface : %d\n", + CONFIG_NET_IF_UNICAST_IPV4_ADDR_COUNT); + PR("Max number of multicast IPv4 addresses " + "per network interface : %d\n", + CONFIG_NET_IF_MCAST_IPV4_ADDR_COUNT); + + user_data.sh = sh; + user_data.user_data = NULL; + + /* Print information about address lifetime */ + net_if_foreach(ip_address_lifetime_cb, &user_data); +#endif + + return 0; +} + +static int cmd_net_ip_add(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_NATIVE_IPV4) + struct net_if *iface = NULL; + int idx; + struct in_addr addr; + + if (argc != 4) { + PR_ERROR("Correct usage: net ipv4 add
\n"); + return -EINVAL; + } + + idx = get_iface_idx(sh, argv[1]); + if (idx < 0) { + return -ENOEXEC; + } + + iface = net_if_get_by_index(idx); + if (!iface) { + PR_WARNING("No such interface in index %d\n", idx); + return -ENOEXEC; + } + + if (net_addr_pton(AF_INET, argv[2], &addr)) { + PR_ERROR("Invalid address: %s\n", argv[2]); + return -EINVAL; + } + + net_if_ipv4_addr_add(iface, &addr, NET_ADDR_MANUAL, 0); + + if (net_addr_pton(AF_INET, argv[3], &addr)) { + PR_ERROR("Invalid netmask: %s", argv[3]); + return -EINVAL; + } + + net_if_ipv4_set_netmask(iface, &addr); + +#else /* CONFIG_NET_NATIVE_IPV4 */ + PR_INFO("Set %s and %s to enable native %s support.\n", + "CONFIG_NET_NATIVE", "CONFIG_NET_IPV4", "IPv4"); +#endif /* CONFIG_NET_NATIVE_IPV4 */ + return 0; +} + +static int cmd_net_ip_del(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_NATIVE_IPV4) + struct net_if *iface = NULL; + int idx; + struct in_addr addr; + + if (argc != 3) { + PR_ERROR("Correct usage: net ipv4 del
"); + return -EINVAL; + } + + idx = get_iface_idx(sh, argv[1]); + if (idx < 0) { + return -ENOEXEC; + } + + iface = net_if_get_by_index(idx); + if (!iface) { + PR_WARNING("No such interface in index %d\n", idx); + return -ENOEXEC; + } + + if (net_addr_pton(AF_INET, argv[2], &addr)) { + PR_ERROR("Invalid address: %s\n", argv[2]); + return -EINVAL; + } + + if (!net_if_ipv4_addr_rm(iface, &addr)) { + PR_ERROR("Failed to delete %s\n", argv[2]); + return -ENOEXEC; + } +#else /* CONFIG_NET_NATIVE_IPV4 */ + PR_INFO("Set %s and %s to enable native %s support.\n", + "CONFIG_NET_NATIVE", "CONFIG_NET_IPV4", "IPv4"); +#endif /* CONFIG_NET_NATIVE_IPV4 */ + return 0; +} + static int cmd_net_iface(const struct shell *sh, size_t argc, char *argv[]) { struct net_if *iface = NULL; @@ -5984,6 +6141,16 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_iface, SHELL_SUBCMD_SET_END ); +SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_ip, + SHELL_CMD(add, NULL, + "'net ipv4 add
' adds the address to the interface.", + cmd_net_ip_add), + SHELL_CMD(del, NULL, + "'net ipv4 del
' deletes the address from the interface.", + cmd_net_ip_del), + SHELL_SUBCMD_SET_END +); + SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_ppp, SHELL_CMD(ping, IFACE_PPP_DYN_CMD, "'net ppp ping ' sends Echo-request to PPP interface.", @@ -6163,6 +6330,10 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_commands, "Print information about IPv6 specific information and " "configuration.", cmd_net_ipv6), + SHELL_CMD(ipv4, &net_cmd_ip, + "Print information about IPv4 specific information and " + "configuration.", + cmd_net_ipv4), SHELL_CMD(mem, NULL, "Print information about network memory usage.", cmd_net_mem), SHELL_CMD(nbr, &net_cmd_nbr, "Print neighbor information.",