Message ID | 6a7582ab314aca691738c0a0ec68d45b9bf335eb.1729070678.git.jerome.forissier@linaro.org |
---|---|
State | Accepted |
Commit | aedcfec9ed788588b9a7ed368fcbc4d6e6588461 |
Headers | show |
Series | Introduce the lwIP network stack | expand |
On Wed, 16 Oct 2024 at 13:05, Jerome Forissier <jerome.forissier@linaro.org> wrote: > > Add CMD_DNS when NET_LWIP is enabled to provide the dns command using > lwIP. > > Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org> > --- > cmd/Kconfig | 11 ++-- > cmd/net-lwip.c | 8 +++ > include/net-lwip.h | 1 + > net/lwip/Makefile | 1 + > net/lwip/dns.c | 127 +++++++++++++++++++++++++++++++++++++++++++++ > 5 files changed, 143 insertions(+), 5 deletions(-) > create mode 100644 net/lwip/dns.c > > diff --git a/cmd/Kconfig b/cmd/Kconfig > index b7d1dd028a1..2791ad5393c 100644 > --- a/cmd/Kconfig > +++ b/cmd/Kconfig > @@ -2027,11 +2027,6 @@ config CMD_SNTP > help > Synchronize RTC via network > > -config CMD_DNS > - bool "dns" > - help > - Lookup the IP of a hostname > - > config CMD_LINK_LOCAL > bool "linklocal" > select LIB_RAND > @@ -2079,6 +2074,12 @@ config CMD_DHCP > help > Boot image via network using DHCP/TFTP protocol > > +config CMD_DNS > + bool "dns" > + select PROT_DNS_LWIP if NET_LWIP > + help > + Lookup the IP of a hostname > + > config CMD_MII > bool "mii" > imply CMD_MDIO > diff --git a/cmd/net-lwip.c b/cmd/net-lwip.c > index feed719beef..c021da6a674 100644 > --- a/cmd/net-lwip.c > +++ b/cmd/net-lwip.c > @@ -27,3 +27,11 @@ U_BOOT_CMD( > "[loadAddress] [[hostIPaddr:]bootfilename]" > ); > #endif > + > +#if defined(CONFIG_CMD_DNS) > +U_BOOT_CMD( > + dns, 3, 1, do_dns, > + "lookup the IP of a hostname", > + "hostname [envvar]" > +); > +#endif > diff --git a/include/net-lwip.h b/include/net-lwip.h > index 9aa371e962c..ff9d03b23e8 100644 > --- a/include/net-lwip.h > +++ b/include/net-lwip.h > @@ -17,6 +17,7 @@ struct netif *net_lwip_get_netif(void); > int net_lwip_rx(struct udevice *udev, struct netif *netif); > > int do_dhcp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); > +int do_dns(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); > int do_ping(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); > > #endif /* __NET_LWIP_H__ */ > diff --git a/net/lwip/Makefile b/net/lwip/Makefile > index b5af37a9b18..645d8a8c457 100644 > --- a/net/lwip/Makefile > +++ b/net/lwip/Makefile > @@ -2,5 +2,6 @@ ccflags-y += -I$(srctree)/lib/lwip/lwip/src/include -I$(srctree)/lib/lwip/u-boot > > obj-$(CONFIG_$(SPL_)DM_ETH) += net-lwip.o > obj-$(CONFIG_CMD_DHCP) += dhcp.o > +obj-$(CONFIG_CMD_DNS) += dns.o > obj-$(CONFIG_CMD_PING) += ping.o > obj-$(CONFIG_CMD_TFTPBOOT) += tftp.o > diff --git a/net/lwip/dns.c b/net/lwip/dns.c > new file mode 100644 > index 00000000000..4b937feaee1 > --- /dev/null > +++ b/net/lwip/dns.c > @@ -0,0 +1,127 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* Copyright (C) 2024 Linaro Ltd. */ > + > +#include <command.h> > +#include <console.h> > +#include <lwip/dns.h> > +#include <lwip/timeouts.h> > +#include <net.h> > +#include <time.h> > + > +#define DNS_RESEND_MS 1000 > +#define DNS_TIMEOUT_MS 10000 > + > +struct dns_cb_arg { > + ip_addr_t host_ipaddr; > + const char *var; > + bool done; > +}; > + > +static void do_dns_tmr(void *arg) > +{ > + dns_tmr(); > +} > + > +static void dns_cb(const char *name, const ip_addr_t *ipaddr, void *arg) > +{ > + struct dns_cb_arg *dns_cb_arg = arg; > + char *ipstr = ip4addr_ntoa(ipaddr); > + > + dns_cb_arg->done = true; > + > + if (!ipaddr) { > + printf("DNS: host not found\n"); > + dns_cb_arg->host_ipaddr.addr = 0; > + return; > + } > + > + if (dns_cb_arg->var) > + env_set(dns_cb_arg->var, ipstr); > + > + printf("%s\n", ipstr); > +} > + > +static int dns_loop(struct udevice *udev, const char *name, const char *var) > +{ > + struct dns_cb_arg dns_cb_arg = { }; > + bool has_server = false; > + struct netif *netif; > + ip_addr_t ipaddr; > + ip_addr_t ns; > + ulong start; > + char *nsenv; > + int ret; > + > + dns_cb_arg.var = var; > + > + netif = net_lwip_new_netif(udev); > + if (!netif) > + return -1; > + > + dns_init(); > + > + nsenv = env_get("dnsip"); > + if (nsenv && ipaddr_aton(nsenv, &ns)) { > + dns_setserver(0, &ns); > + has_server = true; > + } > + > + nsenv = env_get("dnsip2"); > + if (nsenv && ipaddr_aton(nsenv, &ns)) { > + dns_setserver(1, &ns); > + has_server = true; > + } > + > + if (!has_server) { > + log_err("No valid name server (dnsip/dnsip2)\n"); > + net_lwip_remove_netif(netif); > + return CMD_RET_FAILURE; > + } > + > + dns_cb_arg.done = false; > + > + ret = dns_gethostbyname(name, &ipaddr, dns_cb, &dns_cb_arg); > + > + if (ret == ERR_OK) { > + dns_cb(name, &ipaddr, &dns_cb_arg); > + } else if (ret == ERR_INPROGRESS) { > + start = get_timer(0); > + sys_timeout(DNS_RESEND_MS, do_dns_tmr, NULL); > + do { > + net_lwip_rx(udev, netif); > + if (dns_cb_arg.done) > + break; > + sys_check_timeouts(); > + if (ctrlc()) { > + printf("\nAbort\n"); > + break; > + } > + } while (get_timer(start) < DNS_TIMEOUT_MS); > + sys_untimeout(do_dns_tmr, NULL); > + } > + > + net_lwip_remove_netif(netif); > + > + if (dns_cb_arg.done && dns_cb_arg.host_ipaddr.addr != 0) > + return CMD_RET_SUCCESS; > + > + return CMD_RET_FAILURE; > +} > + > +int do_dns(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) > +{ > + char *name; > + char *var = NULL; > + > + if (argc == 1 || argc > 3) > + return CMD_RET_USAGE; > + > + name = argv[1]; > + > + if (argc == 3) > + var = argv[2]; > + > + eth_set_current(); > + > + return dns_loop(eth_get_dev(), name, var); > +} > -- > 2.40.1 > Acked-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
diff --git a/cmd/Kconfig b/cmd/Kconfig index b7d1dd028a1..2791ad5393c 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -2027,11 +2027,6 @@ config CMD_SNTP help Synchronize RTC via network -config CMD_DNS - bool "dns" - help - Lookup the IP of a hostname - config CMD_LINK_LOCAL bool "linklocal" select LIB_RAND @@ -2079,6 +2074,12 @@ config CMD_DHCP help Boot image via network using DHCP/TFTP protocol +config CMD_DNS + bool "dns" + select PROT_DNS_LWIP if NET_LWIP + help + Lookup the IP of a hostname + config CMD_MII bool "mii" imply CMD_MDIO diff --git a/cmd/net-lwip.c b/cmd/net-lwip.c index feed719beef..c021da6a674 100644 --- a/cmd/net-lwip.c +++ b/cmd/net-lwip.c @@ -27,3 +27,11 @@ U_BOOT_CMD( "[loadAddress] [[hostIPaddr:]bootfilename]" ); #endif + +#if defined(CONFIG_CMD_DNS) +U_BOOT_CMD( + dns, 3, 1, do_dns, + "lookup the IP of a hostname", + "hostname [envvar]" +); +#endif diff --git a/include/net-lwip.h b/include/net-lwip.h index 9aa371e962c..ff9d03b23e8 100644 --- a/include/net-lwip.h +++ b/include/net-lwip.h @@ -17,6 +17,7 @@ struct netif *net_lwip_get_netif(void); int net_lwip_rx(struct udevice *udev, struct netif *netif); int do_dhcp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); +int do_dns(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); int do_ping(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); #endif /* __NET_LWIP_H__ */ diff --git a/net/lwip/Makefile b/net/lwip/Makefile index b5af37a9b18..645d8a8c457 100644 --- a/net/lwip/Makefile +++ b/net/lwip/Makefile @@ -2,5 +2,6 @@ ccflags-y += -I$(srctree)/lib/lwip/lwip/src/include -I$(srctree)/lib/lwip/u-boot obj-$(CONFIG_$(SPL_)DM_ETH) += net-lwip.o obj-$(CONFIG_CMD_DHCP) += dhcp.o +obj-$(CONFIG_CMD_DNS) += dns.o obj-$(CONFIG_CMD_PING) += ping.o obj-$(CONFIG_CMD_TFTPBOOT) += tftp.o diff --git a/net/lwip/dns.c b/net/lwip/dns.c new file mode 100644 index 00000000000..4b937feaee1 --- /dev/null +++ b/net/lwip/dns.c @@ -0,0 +1,127 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* Copyright (C) 2024 Linaro Ltd. */ + +#include <command.h> +#include <console.h> +#include <lwip/dns.h> +#include <lwip/timeouts.h> +#include <net.h> +#include <time.h> + +#define DNS_RESEND_MS 1000 +#define DNS_TIMEOUT_MS 10000 + +struct dns_cb_arg { + ip_addr_t host_ipaddr; + const char *var; + bool done; +}; + +static void do_dns_tmr(void *arg) +{ + dns_tmr(); +} + +static void dns_cb(const char *name, const ip_addr_t *ipaddr, void *arg) +{ + struct dns_cb_arg *dns_cb_arg = arg; + char *ipstr = ip4addr_ntoa(ipaddr); + + dns_cb_arg->done = true; + + if (!ipaddr) { + printf("DNS: host not found\n"); + dns_cb_arg->host_ipaddr.addr = 0; + return; + } + + if (dns_cb_arg->var) + env_set(dns_cb_arg->var, ipstr); + + printf("%s\n", ipstr); +} + +static int dns_loop(struct udevice *udev, const char *name, const char *var) +{ + struct dns_cb_arg dns_cb_arg = { }; + bool has_server = false; + struct netif *netif; + ip_addr_t ipaddr; + ip_addr_t ns; + ulong start; + char *nsenv; + int ret; + + dns_cb_arg.var = var; + + netif = net_lwip_new_netif(udev); + if (!netif) + return -1; + + dns_init(); + + nsenv = env_get("dnsip"); + if (nsenv && ipaddr_aton(nsenv, &ns)) { + dns_setserver(0, &ns); + has_server = true; + } + + nsenv = env_get("dnsip2"); + if (nsenv && ipaddr_aton(nsenv, &ns)) { + dns_setserver(1, &ns); + has_server = true; + } + + if (!has_server) { + log_err("No valid name server (dnsip/dnsip2)\n"); + net_lwip_remove_netif(netif); + return CMD_RET_FAILURE; + } + + dns_cb_arg.done = false; + + ret = dns_gethostbyname(name, &ipaddr, dns_cb, &dns_cb_arg); + + if (ret == ERR_OK) { + dns_cb(name, &ipaddr, &dns_cb_arg); + } else if (ret == ERR_INPROGRESS) { + start = get_timer(0); + sys_timeout(DNS_RESEND_MS, do_dns_tmr, NULL); + do { + net_lwip_rx(udev, netif); + if (dns_cb_arg.done) + break; + sys_check_timeouts(); + if (ctrlc()) { + printf("\nAbort\n"); + break; + } + } while (get_timer(start) < DNS_TIMEOUT_MS); + sys_untimeout(do_dns_tmr, NULL); + } + + net_lwip_remove_netif(netif); + + if (dns_cb_arg.done && dns_cb_arg.host_ipaddr.addr != 0) + return CMD_RET_SUCCESS; + + return CMD_RET_FAILURE; +} + +int do_dns(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + char *name; + char *var = NULL; + + if (argc == 1 || argc > 3) + return CMD_RET_USAGE; + + name = argv[1]; + + if (argc == 3) + var = argv[2]; + + eth_set_current(); + + return dns_loop(eth_get_dev(), name, var); +}
Add CMD_DNS when NET_LWIP is enabled to provide the dns command using lwIP. Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org> --- cmd/Kconfig | 11 ++-- cmd/net-lwip.c | 8 +++ include/net-lwip.h | 1 + net/lwip/Makefile | 1 + net/lwip/dns.c | 127 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 143 insertions(+), 5 deletions(-) create mode 100644 net/lwip/dns.c