On Wed, 16 Oct 2024 at 13:05, Jerome Forissier <jerome.foriss...@linaro.org> wrote: > > Add CMD_DNS when NET_LWIP is enabled to provide the dns command using > lwIP. > > Signed-off-by: Jerome Forissier <jerome.foriss...@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.apalodi...@linaro.org>