diff options
Diffstat (limited to 'net/lwip')
-rw-r--r-- | net/lwip/Makefile | 2 | ||||
-rw-r--r-- | net/lwip/dhcp.c | 2 | ||||
-rw-r--r-- | net/lwip/dns.c | 128 | ||||
-rw-r--r-- | net/lwip/eth_internal.h | 35 | ||||
-rw-r--r-- | net/lwip/net-lwip.c | 82 | ||||
-rw-r--r-- | net/lwip/ping.c | 180 | ||||
-rw-r--r-- | net/lwip/tftp.c | 9 | ||||
-rw-r--r-- | net/lwip/wget.c | 208 |
8 files changed, 97 insertions, 549 deletions
diff --git a/net/lwip/Makefile b/net/lwip/Makefile index 5df222589b8..97299d9b542 100644 --- a/net/lwip/Makefile +++ b/net/lwip/Makefile @@ -2,8 +2,6 @@ ccflags-y += -I$(srctree)/lib/lwip/lwip/src/include -I$(srctree)/lib/lwip/u-boot obj-$(CONFIG_$(PHASE_)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 obj-$(CONFIG_WGET) += wget.o diff --git a/net/lwip/dhcp.c b/net/lwip/dhcp.c index 92bd7067a7f..4c9cb0ecaa0 100644 --- a/net/lwip/dhcp.c +++ b/net/lwip/dhcp.c @@ -3,6 +3,7 @@ #include <command.h> #include <console.h> +#include <env.h> #include <log.h> #include <dm/device.h> #include <linux/delay.h> @@ -57,7 +58,6 @@ static int dhcp_loop(struct udevice *udev) /* Wait for DHCP to complete */ do { net_lwip_rx(udev, netif); - sys_check_timeouts(); bound = dhcp_supplied_address(netif); if (bound) break; diff --git a/net/lwip/dns.c b/net/lwip/dns.c deleted file mode 100644 index 19172ac959a..00000000000 --- a/net/lwip/dns.c +++ /dev/null @@ -1,128 +0,0 @@ -// 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 CMD_RET_FAILURE; - - 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]; - - if (net_lwip_eth_start() < 0) - return CMD_RET_FAILURE; - - return dns_loop(eth_get_dev(), name, var); -} diff --git a/net/lwip/eth_internal.h b/net/lwip/eth_internal.h deleted file mode 100644 index 87561d5b214..00000000000 --- a/net/lwip/eth_internal.h +++ /dev/null @@ -1,35 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * (C) Copyright 2001-2015 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * Joe Hershberger, National Instruments - */ - -#ifndef __ETH_INTERNAL_H -#define __ETH_INTERNAL_H - -/* Do init that is common to driver model and legacy networking */ -void eth_common_init(void); - -/** - * eth_env_set_enetaddr_by_index() - set the MAC address environment variable - * - * This sets up an environment variable with the given MAC address (@enetaddr). - * The environment variable to be set is defined by <@base_name><@index>addr. - * If @index is 0 it is omitted. For common Ethernet this means ethaddr, - * eth1addr, etc. - * - * @base_name: Base name for variable, typically "eth" - * @index: Index of interface being updated (>=0) - * @enetaddr: Pointer to MAC address to put into the variable - * Return: 0 if OK, other value on error - */ -int eth_env_set_enetaddr_by_index(const char *base_name, int index, - uchar *enetaddr); - -int eth_mac_skip(int index); -void eth_current_changed(void); -void eth_set_dev(struct udevice *dev); -void eth_set_current_to_next(void); - -#endif diff --git a/net/lwip/net-lwip.c b/net/lwip/net-lwip.c index f05c4cd3f64..3918d57d7e5 100644 --- a/net/lwip/net-lwip.c +++ b/net/lwip/net-lwip.c @@ -3,18 +3,23 @@ /* Copyright (C) 2024 Linaro Ltd. */ #include <command.h> +#include <env.h> #include <dm/device.h> #include <dm/uclass.h> #include <hexdump.h> +#include <linux/kernel.h> #include <lwip/ip4_addr.h> +#include <lwip/dns.h> #include <lwip/err.h> #include <lwip/netif.h> #include <lwip/pbuf.h> #include <lwip/etharp.h> #include <lwip/init.h> #include <lwip/prot/etharp.h> +#include <lwip/timeouts.h> #include <net.h> #include <timer.h> +#include <u-boot/schedule.h> /* xx:xx:xx:xx:xx:xx\0 */ #define MAC_ADDR_STRLEN 18 @@ -138,6 +143,40 @@ static int get_udev_ipv4_info(struct udevice *dev, ip4_addr_t *ip, } /* + * Initialize DNS via env + */ +int net_lwip_dns_init(void) +{ +#if CONFIG_IS_ENABLED(CMD_DNS) + bool has_server = false; + ip_addr_t ns; + char *nsenv; + + 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"); + return -EINVAL; + } + + return 0; +#else + log_err("DNS disabled\n"); + return -EINVAL; +#endif +} + +/* * Initialize the network stack if needed and start the current device if valid */ int net_lwip_eth_start(void) @@ -284,6 +323,11 @@ int net_lwip_rx(struct udevice *udev, struct netif *netif) int len; int i; + /* lwIP timers */ + sys_check_timeouts(); + /* Other tasks and actions */ + schedule(); + if (!eth_is_active(udev)) return -EINVAL; @@ -315,6 +359,44 @@ int net_lwip_rx(struct udevice *udev, struct netif *netif) return len; } +/** + * net_lwip_dns_resolve() - find IP address from name or IP + * + * @name_or_ip: host name or IP address + * @ip: output IP address + * + * Return value: 0 on success, -1 on failure. + */ +int net_lwip_dns_resolve(char *name_or_ip, ip_addr_t *ip) +{ +#if defined(CONFIG_CMD_DNS) + char *var = "_dnsres"; + char *argv[] = { "dns", name_or_ip, var, NULL }; + int argc = ARRAY_SIZE(argv) - 1; +#endif + + if (ipaddr_aton(name_or_ip, ip)) + return 0; + +#if defined(CONFIG_CMD_DNS) + if (do_dns(NULL, 0, argc, argv) != CMD_RET_SUCCESS) + return -1; + + name_or_ip = env_get(var); + if (!name_or_ip) + return -1; + + if (!ipaddr_aton(name_or_ip, ip)) + return -1; + + env_set(var, NULL); + + return 0; +#else + return -1; +#endif +} + void net_process_received_packet(uchar *in_packet, int len) { #if defined(CONFIG_API) || defined(CONFIG_EFI_LOADER) diff --git a/net/lwip/ping.c b/net/lwip/ping.c deleted file mode 100644 index d8042ceecf9..00000000000 --- a/net/lwip/ping.c +++ /dev/null @@ -1,180 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* Copyright (C) 2024 Linaro Ltd. */ - -#include <command.h> -#include <console.h> -#include <dm/device.h> -#include <linux/delay.h> -#include <linux/errno.h> -#include <lwip/icmp.h> -#include <lwip/inet_chksum.h> -#include <lwip/raw.h> -#include <lwip/timeouts.h> -#include <net.h> -#include <time.h> - -#define PING_DELAY_MS 1000 -#define PING_COUNT 5 -/* Ping identifier - must fit on a u16_t */ -#define PING_ID 0xAFAF - -struct ping_ctx { - ip_addr_t target; - struct raw_pcb *pcb; - struct icmp_echo_hdr *iecho; - uint16_t seq_num; - bool alive; -}; - -static u8_t ping_recv(void *arg, struct raw_pcb *pcb, struct pbuf *p, - const ip_addr_t *addr) -{ - struct ping_ctx *ctx = arg; - struct icmp_echo_hdr *iecho = ctx->iecho; - - if (addr->addr != ctx->target.addr) - return 0; - - if ((p->tot_len >= (IP_HLEN + sizeof(struct icmp_echo_hdr))) && - pbuf_remove_header(p, IP_HLEN) == 0) { - iecho = (struct icmp_echo_hdr *)p->payload; - - if (iecho->id == PING_ID && - iecho->seqno == lwip_htons(ctx->seq_num)) { - ctx->alive = true; - printf("host %s is alive\n", ipaddr_ntoa(addr)); - pbuf_free(p); - return 1; /* eat the packet */ - } - /* not eaten, restore original packet */ - pbuf_add_header(p, IP_HLEN); - } - - return 0; /* don't eat the packet */ -} - -static int ping_raw_init(struct ping_ctx *ctx) -{ - ctx->pcb = raw_new(IP_PROTO_ICMP); - if (!ctx->pcb) - return -ENOMEM; - - raw_recv(ctx->pcb, ping_recv, ctx); - raw_bind(ctx->pcb, IP_ADDR_ANY); - - return 0; -} - -static void ping_raw_stop(struct ping_ctx *ctx) -{ - if (ctx->pcb) - raw_remove(ctx->pcb); -} - -static void ping_prepare_echo(struct ping_ctx *ctx) -{ - struct icmp_echo_hdr *iecho = ctx->iecho; - - ICMPH_TYPE_SET(iecho, ICMP_ECHO); - ICMPH_CODE_SET(iecho, 0); - iecho->chksum = 0; - iecho->id = PING_ID; - iecho->seqno = lwip_htons(ctx->seq_num); - - iecho->chksum = inet_chksum(iecho, sizeof(*iecho)); -} - -static void ping_send_icmp(struct ping_ctx *ctx) -{ - struct pbuf *p; - size_t ping_size = sizeof(struct icmp_echo_hdr); - - p = pbuf_alloc(PBUF_IP, (u16_t)ping_size, PBUF_RAM); - if (!p) - return; - - if (p->len == p->tot_len && !p->next) { - ctx->iecho = (struct icmp_echo_hdr *)p->payload; - ping_prepare_echo(ctx); - raw_sendto(ctx->pcb, p, &ctx->target); - } - - pbuf_free(p); -} - -static void ping_send(void *arg) -{ - struct ping_ctx *ctx = arg; - - ctx->seq_num++; - if (ctx->seq_num <= PING_COUNT) { - ping_send_icmp(ctx); - sys_timeout(PING_DELAY_MS, ping_send, ctx); - } -} - -static int ping_loop(struct udevice *udev, const ip_addr_t *addr) -{ - struct ping_ctx ctx = {}; - struct netif *netif; - int ret; - - netif = net_lwip_new_netif(udev); - if (!netif) - return -ENODEV; - - printf("Using %s device\n", udev->name); - - ret = ping_raw_init(&ctx); - if (ret < 0) { - net_lwip_remove_netif(netif); - return ret; - } - - ctx.target = *addr; - - ping_send(&ctx); - - do { - sys_check_timeouts(); - net_lwip_rx(udev, netif); - if (ctx.alive) - break; - if (ctrlc()) { - printf("\nAbort\n"); - break; - } - } while (ctx.seq_num <= PING_COUNT); - - sys_untimeout(ping_send, &ctx); - ping_raw_stop(&ctx); - - net_lwip_remove_netif(netif); - - if (ctx.alive) - return 0; - - printf("ping failed; host %s is not alive\n", ipaddr_ntoa(addr)); - return -1; -} - -int do_ping(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) -{ - ip_addr_t addr; - - if (argc < 2) - return CMD_RET_USAGE; - - if (!ipaddr_aton(argv[1], &addr)) - return CMD_RET_USAGE; - -restart: - if (net_lwip_eth_start() < 0 || ping_loop(eth_get_dev(), &addr) < 0) { - if (net_start_again() == 0) - goto restart; - else - return CMD_RET_FAILURE; - } - - return CMD_RET_SUCCESS; -} diff --git a/net/lwip/tftp.c b/net/lwip/tftp.c index fae701bad2e..94bacf63075 100644 --- a/net/lwip/tftp.c +++ b/net/lwip/tftp.c @@ -6,6 +6,7 @@ #include <display_options.h> #include <dm/device.h> #include <efi_loader.h> +#include <env.h> #include <image.h> #include <linux/delay.h> #include <linux/kconfig.h> @@ -156,8 +157,10 @@ static void no_response(void *arg) static int tftp_loop(struct udevice *udev, ulong addr, char *fname, ip_addr_t srvip, uint16_t srvport) { + int blksize = CONFIG_TFTP_BLOCKSIZE; struct netif *netif; struct tftp_ctx ctx; + const char *ep; err_t err; if (!fname || addr == 0) @@ -186,7 +189,10 @@ static int tftp_loop(struct udevice *udev, ulong addr, char *fname, if (!(err == ERR_OK || err == ERR_USE)) log_err("tftp_init_client err: %d\n", err); - tftp_client_set_blksize(CONFIG_TFTP_BLOCKSIZE); + ep = env_get("tftpblocksize"); + if (ep) + blksize = simple_strtol(ep, NULL, 10); + tftp_client_set_blksize(blksize); ctx.start_time = get_timer(0); err = tftp_get(&ctx, &srvip, srvport, fname, TFTP_MODE_OCTET); @@ -200,7 +206,6 @@ static int tftp_loop(struct udevice *udev, ulong addr, char *fname, sys_timeout(NO_RSP_TIMEOUT_MS, no_response, &ctx); while (!ctx.done) { net_lwip_rx(udev, netif); - sys_check_timeouts(); if (ctrlc()) { printf("\nAbort\n"); ctx.done = ABORTED; diff --git a/net/lwip/wget.c b/net/lwip/wget.c index ea1113e18b1..55bd2b72e26 100644 --- a/net/lwip/wget.c +++ b/net/lwip/wget.c @@ -5,7 +5,7 @@ #include <console.h> #include <display_options.h> #include <efi_loader.h> -#include <image.h> +#include <env.h> #include <linux/kconfig.h> #include <lwip/apps/http_client.h> #include "lwip/altcp_tls.h" @@ -137,72 +137,6 @@ static int parse_url(char *url, char *host, u16 *port, char **path, return 0; } -/* - * Legacy syntax support - * Convert [<server_name_or_ip>:]filename into a URL if needed - */ -static int parse_legacy_arg(char *arg, char *nurl, size_t rem) -{ - char *p = nurl; - size_t n; - char *col = strchr(arg, ':'); - char *env; - char *server; - char *path; - - if (strstr(arg, "http") == arg) { - n = snprintf(nurl, rem, "%s", arg); - if (n < 0 || n > rem) - return -1; - return 0; - } - - n = snprintf(p, rem, "%s", "http://"); - if (n < 0 || n > rem) - return -1; - p += n; - rem -= n; - - if (col) { - n = col - arg; - server = arg; - path = col + 1; - } else { - env = env_get("httpserverip"); - if (!env) - env = env_get("serverip"); - if (!env) { - log_err("error: httpserver/serverip has to be set\n"); - return -1; - } - n = strlen(env); - server = env; - path = arg; - } - - if (rem < n) - return -1; - strncpy(p, server, n); - p += n; - rem -= n; - if (rem < 1) - return -1; - *p = '/'; - p++; - rem--; - n = strlen(path); - if (rem < n) - return -1; - strncpy(p, path, n); - p += n; - rem -= n; - if (rem < 1) - return -1; - *p = '\0'; - - return 0; -} - /** * store_block() - copy received data * @@ -337,94 +271,10 @@ static err_t httpc_headers_done_cb(httpc_state_t *connection, void *arg, struct return ERR_OK; } -#if CONFIG_IS_ENABLED(WGET_HTTPS) -enum auth_mode { - AUTH_NONE, - AUTH_OPTIONAL, - AUTH_REQUIRED, -}; - -static char *cacert; -static size_t cacert_size; -static enum auth_mode cacert_auth_mode = AUTH_OPTIONAL; -#endif #if CONFIG_IS_ENABLED(WGET_CACERT) -static int set_auth(enum auth_mode auth) -{ - cacert_auth_mode = auth; - - return CMD_RET_SUCCESS; -} #endif -#if CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT) -extern const char builtin_cacert[]; -extern const size_t builtin_cacert_size; -static bool cacert_initialized; -#endif - -#if CONFIG_IS_ENABLED(WGET_CACERT) || CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT) -static int _set_cacert(const void *addr, size_t sz) -{ - mbedtls_x509_crt crt; - void *p; - int ret; - - if (cacert) - free(cacert); - - if (!addr) { - cacert = NULL; - cacert_size = 0; - return CMD_RET_SUCCESS; - } - - p = malloc(sz); - if (!p) - return CMD_RET_FAILURE; - cacert = p; - cacert_size = sz; - - memcpy(cacert, (void *)addr, sz); - - mbedtls_x509_crt_init(&crt); - ret = mbedtls_x509_crt_parse(&crt, cacert, cacert_size); - if (ret) { - if (!wget_info->silent) - printf("Could not parse certificates (%d)\n", ret); - free(cacert); - cacert = NULL; - cacert_size = 0; - return CMD_RET_FAILURE; - } - -#if CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT) - cacert_initialized = true; -#endif - return CMD_RET_SUCCESS; -} - -#if CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT) -static int set_cacert_builtin(void) -{ - return _set_cacert(builtin_cacert, builtin_cacert_size); -} -#endif - -#if CONFIG_IS_ENABLED(WGET_CACERT) -static int set_cacert(char * const saddr, char * const ssz) -{ - ulong addr, sz; - - addr = hextoul(saddr, NULL); - sz = hextoul(ssz, NULL); - - return _set_cacert((void *)addr, sz); -} -#endif -#endif /* CONFIG_WGET_CACERT || CONFIG_WGET_BUILTIN_CACERT */ - int wget_do_request(ulong dst_addr, char *uri) { #if CONFIG_IS_ENABLED(WGET_HTTPS) @@ -460,12 +310,17 @@ int wget_do_request(ulong dst_addr, char *uri) if (!netif) return -1; + /* if URL with hostname init dns */ + if (!ipaddr_aton(ctx.server_name, NULL) && net_lwip_dns_init()) + return CMD_RET_FAILURE; + memset(&conn, 0, sizeof(conn)); #if CONFIG_IS_ENABLED(WGET_HTTPS) if (is_https) { char *ca; size_t ca_sz; +#if CONFIG_IS_ENABLED(WGET_CACERT) || CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT) #if CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT) if (!cacert_initialized) set_cacert_builtin(); @@ -492,7 +347,7 @@ int wget_do_request(ulong dst_addr, char *uri) * with no verification if not. */ } - +#endif if (!ca && !wget_info->silent) { printf("WARNING: no CA certificates, "); printf("HTTPS connections not authenticated\n"); @@ -525,7 +380,6 @@ int wget_do_request(ulong dst_addr, char *uri) while (!ctx.done) { net_lwip_rx(udev, netif); - sys_check_timeouts(); if (ctrlc()) break; } @@ -541,54 +395,6 @@ int wget_do_request(ulong dst_addr, char *uri) return -1; } -int do_wget(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) -{ - char *end; - char *url; - ulong dst_addr; - char nurl[1024]; - -#if CONFIG_IS_ENABLED(WGET_CACERT) - if (argc == 4 && !strncmp(argv[1], "cacert", strlen("cacert"))) - return set_cacert(argv[2], argv[3]); - if (argc == 3 && !strncmp(argv[1], "cacert", strlen("cacert"))) { -#if CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT) - if (!strncmp(argv[2], "builtin", strlen("builtin"))) - return set_cacert_builtin(); -#endif - if (!strncmp(argv[2], "none", strlen("none"))) - return set_auth(AUTH_NONE); - if (!strncmp(argv[2], "optional", strlen("optional"))) - return set_auth(AUTH_OPTIONAL); - if (!strncmp(argv[2], "required", strlen("required"))) - return set_auth(AUTH_REQUIRED); - return CMD_RET_USAGE; - } -#endif - - if (argc < 2 || argc > 3) - return CMD_RET_USAGE; - - dst_addr = hextoul(argv[1], &end); - if (end == (argv[1] + strlen(argv[1]))) { - if (argc < 3) - return CMD_RET_USAGE; - url = argv[2]; - } else { - dst_addr = image_load_addr; - url = argv[1]; - } - - if (parse_legacy_arg(url, nurl, sizeof(nurl))) - return CMD_RET_FAILURE; - - wget_info = &default_wget_info; - if (wget_do_request(dst_addr, nurl)) - return CMD_RET_FAILURE; - - return CMD_RET_SUCCESS; -} - /** * wget_validate_uri() - validate the uri for wget * |