in nshlib/nsh_netcmds.c [546:1060]
int cmd_ifconfig(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv)
{
#ifdef CONFIG_NET_IPv4
struct in_addr addr;
in_addr_t gip = INADDR_ANY;
in_addr_t mip;
#endif
#ifdef CONFIG_NET_IPv6
struct in6_addr addr6;
struct in6_addr gip6 = IN6ADDR_ANY_INIT;
FAR char *preflen = NULL;
# ifdef CONFIG_NETDEV_MULTIPLE_IPv6
bool remove = false;
# endif
#endif
int i;
FAR char *ifname = NULL;
FAR char *hostip = NULL;
FAR char *gwip = NULL;
FAR char *mask = NULL;
FAR char *tmp = NULL;
#ifdef HAVE_HWADDR
FAR char *hw = NULL;
#endif
#ifdef CONFIG_NETDB_DNSCLIENT
FAR char *dns = NULL;
#endif
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
bool inet6 = false;
#endif
bool missingarg = true;
bool badarg = false;
#ifdef HAVE_HWADDR
mac_addr_t macaddr;
#endif
int ret;
int mtu = 0;
/* With one or no arguments, ifconfig simply shows the status of the
* network device:
*
* ifconfig
* ifconfig [interface]
*/
if (argc <= 2)
{
if (argc == 2)
{
return ifconfig_callback(vtbl, argv[1]);
}
ret = nsh_foreach_netdev(ifconfig_callback, vtbl, "ifconfig");
if (ret < 0)
{
return ERROR;
}
net_statistics(vtbl);
return OK;
}
/* If both the network interface name and an IP address are supplied as
* arguments, then ifconfig will set the address of the Ethernet device:
*
* ifconfig ifname [ip_address] [named options]
*/
if (argc > 2)
{
for (i = 1; i < argc; i++)
{
if (i == 1)
{
ifname = argv[i];
missingarg = false;
}
else
{
tmp = argv[i];
if (!strcmp(tmp, "dr") || !strcmp(tmp, "gw") ||
!strcmp(tmp, "gateway"))
{
if (argc - 1 >= i + 1)
{
gwip = argv[i + 1];
i++;
}
else
{
badarg = true;
}
}
else if (!strcmp(tmp, "netmask"))
{
if (argc - 1 >= i + 1)
{
mask = argv[i + 1];
i++;
}
else
{
badarg = true;
}
}
else if (!strcmp(tmp, "inet"))
{
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
inet6 = false;
#elif !defined(CONFIG_NET_IPv4)
badarg = true;
#endif
}
else if (!strcmp(tmp, "inet6"))
{
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
inet6 = true;
#elif !defined(CONFIG_NET_IPv6)
badarg = true;
#endif
}
#ifdef CONFIG_NET_IPv6
else if (!strcmp(tmp, "prefixlen"))
{
if (argc - 1 >= i + 1)
{
preflen = argv[i + 1];
i++;
}
else
{
badarg = true;
}
}
#endif
#ifdef HAVE_HWADDR
/* REVISIT: How will we handle Ethernet and SLIP together? */
else if (!strcmp(tmp, "hw"))
{
if (argc - 1 >= i + 1)
{
hw = argv[i + 1];
i++;
badarg = nsh_addrconv(hw, &macaddr);
}
else
{
badarg = true;
}
}
#endif
#ifdef CONFIG_NETDB_DNSCLIENT
else if (!strcmp(tmp, "dns"))
{
if (argc - 1 >= i + 1)
{
dns = argv[i + 1];
i++;
}
else
{
badarg = true;
}
}
#endif
else if (!strcmp(tmp, "add"))
{
#if defined(CONFIG_NET_IPv6) && defined(CONFIG_NETDEV_MULTIPLE_IPv6)
remove = false;
continue;
}
else if (!strcmp(tmp, "del"))
{
remove = true;
#endif
continue;
}
else if (!strcmp(tmp, "mtu"))
{
if (argc - 1 >= i + 1)
{
mtu = atoi(argv[i + 1]);
i++;
if (mtu < 1280)
{
mtu = 1280;
}
}
else
{
badarg = true;
}
}
else if (hostip == NULL && i <= 4)
{
/* Let first non-option be host ip, to support inet/inet6
* options before address.
*/
hostip = tmp;
}
else
{
badarg = true;
}
}
}
}
if (missingarg)
{
nsh_error(vtbl, g_fmtargrequired, argv[0]);
return ERROR;
}
if (badarg)
{
nsh_error(vtbl, g_fmtarginvalid, argv[0]);
return ERROR;
}
#ifdef HAVE_HWADDR
/* Set Hardware Ethernet MAC address */
if (hw != NULL)
{
ninfo("HW MAC: %s\n", hw);
nsh_sethwaddr(ifname, &macaddr);
}
#endif
if (mtu != 0)
{
netlib_set_mtu(ifname, mtu);
return OK;
}
/* Set IP address */
#ifdef CONFIG_NET_IPv6
#ifdef CONFIG_NET_IPv4
if (inet6)
#endif
{
if (hostip != NULL)
{
/* REVISIT: Should DHCPC check be used here too? */
if ((tmp = strchr(hostip, '/')) != NULL)
{
*tmp = 0;
if (preflen == NULL)
{
preflen = tmp + 1;
}
}
ninfo("Host IP: %s\n", hostip);
ret = inet_pton(AF_INET6, hostip, &addr6);
if (ret <= 0)
{
nsh_error(vtbl, g_fmtarginvalid, argv[0]);
return ERROR;
}
}
#ifndef CONFIG_NETDEV_MULTIPLE_IPv6
netlib_set_ipv6addr(ifname, &addr6);
#endif
}
#endif /* CONFIG_NET_IPv6 */
#ifdef CONFIG_NET_IPv4
#ifdef CONFIG_NET_IPv6
else
#endif
{
if (hostip != NULL)
{
#if defined(CONFIG_NETUTILS_DHCPC)
if (strcmp(hostip, "dhcp") == 0)
{
/* Set DHCP addr */
ninfo("DHCPC Mode\n");
addr.s_addr = 0;
gip = 0;
}
else
#endif
{
/* Set host IP address */
ninfo("Host IP: %s\n", hostip);
addr.s_addr = inet_addr(hostip);
gip = addr.s_addr;
}
}
else
{
addr.s_addr = 0;
}
netlib_set_ipv4addr(ifname, &addr);
}
#endif /* CONFIG_NET_IPv4 */
/* Set network mask */
#ifdef CONFIG_NET_IPv6
#ifdef CONFIG_NET_IPv4
if (inet6)
#endif
{
struct in6_addr mask6;
#ifdef CONFIG_NETDEV_MULTIPLE_IPv6
uint8_t plen;
#endif
if (mask != NULL)
{
ninfo("Netmask: %s\n", mask);
ret = inet_pton(AF_INET6, mask, &mask6);
if (ret <= 0)
{
nsh_error(vtbl, g_fmtarginvalid, argv[0]);
return ERROR;
}
}
else if (preflen != NULL)
{
ninfo("Prefixlen: %s\n", preflen);
netlib_prefix2ipv6netmask(atoi(preflen), &mask6);
}
else
{
ninfo("Netmask: Default\n");
inet_pton(AF_INET6, "ffff:ffff:ffff:ffff::", &mask6);
}
#ifdef CONFIG_NETDEV_MULTIPLE_IPv6
plen = netlib_ipv6netmask2prefix(mask6.in6_u.u6_addr16);
if (remove)
{
ret = netlib_del_ipv6addr(ifname, &addr6, plen);
}
else
{
ret = netlib_add_ipv6addr(ifname, &addr6, plen);
}
if (ret < 0)
{
perror("Failed to manage IPv6 address");
/* REVISIT: Should we return ERROR or just let it go? */
return ERROR;
}
#else
netlib_set_ipv6netmask(ifname, &mask6);
#endif /* CONFIG_NETDEV_MULTIPLE_IPv6 */
}
#endif /* CONFIG_NET_IPv6 */
#ifdef CONFIG_NET_IPv4
#ifdef CONFIG_NET_IPv6
else
#endif
{
if (mask != NULL)
{
ninfo("Netmask: %s\n", mask);
addr.s_addr = inet_addr(mask);
}
else
{
ninfo("Netmask: Default\n");
addr.s_addr = inet_addr("255.255.255.0");
}
mip = addr.s_addr;
netlib_set_ipv4netmask(ifname, &addr);
}
#endif /* CONFIG_NET_IPv4 */
/* Set gateway */
#ifdef CONFIG_NET_IPv6
#ifdef CONFIG_NET_IPv4
if (inet6)
#endif
{
/* Only set the gateway address if it was explicitly provided. */
if (gwip != NULL)
{
ninfo("Gateway: %s\n", gwip);
ret = inet_pton(AF_INET6, gwip, &addr6);
if (ret <= 0)
{
nsh_error(vtbl, g_fmtarginvalid, argv[0]);
return ERROR;
}
netlib_set_dripv6addr(ifname, &addr6);
gip6 = addr6;
}
}
#endif /* CONFIG_NET_IPv6 */
#ifdef CONFIG_NET_IPv4
#ifdef CONFIG_NET_IPv6
else
#endif
{
if (gwip != NULL)
{
ninfo("Gateway: %s\n", gwip);
gip = addr.s_addr = inet_addr(gwip);
}
else
{
if (gip != INADDR_ANY)
{
ninfo("Gateway: default\n");
gip = ntohl(gip);
gip &= ntohl(mip);
gip |= 0x00000001;
gip = htonl(gip);
}
addr.s_addr = gip;
}
netlib_set_dripv4addr(ifname, &addr);
}
#endif /* CONFIG_NET_IPv4 */
UNUSED(ifname); /* Not used in all configurations */
#ifdef CONFIG_NETDB_DNSCLIENT
#ifdef CONFIG_NET_IPv6
#ifdef CONFIG_NET_IPv4
if (inet6)
#endif
{
if (dns != NULL)
{
ninfo("DNS: %s\n", dns);
ret = inet_pton(AF_INET6, dns, &addr6);
if (ret <= 0)
{
nsh_error(vtbl, g_fmtarginvalid, argv[0]);
return ERROR;
}
}
else
{
ninfo("DNS: Default\n");
addr6 = gip6;
}
netlib_set_ipv6dnsaddr(&addr6);
}
#endif /* CONFIG_NET_IPv6 */
#ifdef CONFIG_NET_IPv4
#ifdef CONFIG_NET_IPv6
else
#endif
{
if (dns != NULL)
{
ninfo("DNS: %s\n", dns);
addr.s_addr = inet_addr(dns);
}
else
{
ninfo("DNS: Default\n");
addr.s_addr = gip;
}
netlib_set_ipv4dnsaddr(&addr);
}
#endif /* CONFIG_NET_IPv4 */
#endif /* CONFIG_NETDB_DNSCLIENT */
#if defined(CONFIG_NETUTILS_DHCPC)
if (!gip)
{
netlib_obtain_ipv4addr(ifname);
}
#endif
#if !defined(CONFIG_NET_IPv4) && !defined(CONFIG_NET_IPv6)
UNUSED(hostip);
UNUSED(mask);
UNUSED(gwip);
#endif
#ifdef CONFIG_NET_IPv4
UNUSED(gip);
#endif
#ifdef CONFIG_NET_IPv6
UNUSED(gip6);
#endif
return OK;
}