diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/lwip/Kconfig | 9 | ||||
-rw-r--r-- | net/lwip/dhcp.c | 20 | ||||
-rw-r--r-- | net/lwip/eth_internal.h | 2 | ||||
-rw-r--r-- | net/lwip/net-lwip.c | 35 | ||||
-rw-r--r-- | net/lwip/ping.c | 8 | ||||
-rw-r--r-- | net/lwip/tftp.c | 8 | ||||
-rw-r--r-- | net/lwip/wget.c | 102 |
7 files changed, 135 insertions, 49 deletions
diff --git a/net/lwip/Kconfig b/net/lwip/Kconfig index 8a67de4cf33..40345ced9c9 100644 --- a/net/lwip/Kconfig +++ b/net/lwip/Kconfig @@ -6,9 +6,16 @@ if NET_LWIP config LWIP_DEBUG bool "Enable debug traces in the lwIP library" + help + Prints messages to the console regarding network packets that go in + and out of the lwIP library. config LWIP_ASSERT bool "Enable assertions in the lwIP library" + help + Compiles additional error checking code into the lwIP library. These + checks are related to conditions that should not happen in typical + use, but may be helpful to debug new features. config PROT_DHCP_LWIP bool @@ -37,7 +44,7 @@ config PROT_UDP_LWIP config LWIP_TCP_WND int "Value of TCP_WND" - default 8000 if ARCH_QEMU + default 32768 if ARCH_QEMU default 3000000 help Default value for TCP_WND in the lwIP configuration diff --git a/net/lwip/dhcp.c b/net/lwip/dhcp.c index 23b56226921..9b882cf5b87 100644 --- a/net/lwip/dhcp.c +++ b/net/lwip/dhcp.c @@ -27,9 +27,9 @@ static void call_lwip_dhcp_fine_tmr(void *ctx) static int dhcp_loop(struct udevice *udev) { - char *ipstr = "ipaddr\0\0"; - char *maskstr = "netmask\0\0"; - char *gwstr = "gatewayip\0\0"; + char ipstr[] = "ipaddr\0\0"; + char maskstr[] = "netmask\0\0"; + char gwstr[] = "gatewayip\0\0"; unsigned long start; struct netif *netif; struct dhcp *dhcp; @@ -111,9 +111,21 @@ static int dhcp_loop(struct udevice *udev) int do_dhcp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { + int ret; + eth_set_current(); - return dhcp_loop(eth_get_dev()); + ret = dhcp_loop(eth_get_dev()); + if (ret) + return ret; + + if (argc > 1) { + struct cmd_tbl cmdtp = {}; + + return do_tftpb(&cmdtp, 0, argc, argv); + } + + return CMD_RET_SUCCESS; } int dhcp_run(ulong addr, const char *fname, bool autoload) diff --git a/net/lwip/eth_internal.h b/net/lwip/eth_internal.h index 0b829a8d388..87561d5b214 100644 --- a/net/lwip/eth_internal.h +++ b/net/lwip/eth_internal.h @@ -25,7 +25,7 @@ void eth_common_init(void); * Return: 0 if OK, other value on error */ int eth_env_set_enetaddr_by_index(const char *base_name, int index, - uchar *enetaddr); + uchar *enetaddr); int eth_mac_skip(int index); void eth_current_changed(void); diff --git a/net/lwip/net-lwip.c b/net/lwip/net-lwip.c index 5c2bb2e0361..b863047f598 100644 --- a/net/lwip/net-lwip.c +++ b/net/lwip/net-lwip.c @@ -91,9 +91,9 @@ struct netif *net_lwip_get_netif(void) static int get_udev_ipv4_info(struct udevice *dev, ip4_addr_t *ip, ip4_addr_t *mask, ip4_addr_t *gw) { - char *ipstr = "ipaddr\0\0"; - char *maskstr = "netmask\0\0"; - char *gwstr = "gatewayip\0\0"; + char ipstr[] = "ipaddr\0\0"; + char maskstr[] = "netmask\0\0"; + char gwstr[] = "gatewayip\0\0"; int idx = dev_seq(dev); char *env; @@ -203,7 +203,6 @@ struct netif *net_lwip_new_netif(struct udevice *udev) struct netif *net_lwip_new_netif_noip(struct udevice *udev) { - return new_netif(udev, false); } @@ -224,24 +223,24 @@ int net_init(void) static struct pbuf *alloc_pbuf_and_copy(uchar *data, int len) { - struct pbuf *p, *q; + struct pbuf *p, *q; - /* We allocate a pbuf chain of pbufs from the pool. */ - p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); - if (!p) { - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.drop); - return NULL; - } + /* We allocate a pbuf chain of pbufs from the pool. */ + p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); + if (!p) { + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.drop); + return NULL; + } - for (q = p; q != NULL; q = q->next) { - memcpy(q->payload, data, q->len); - data += q->len; - } + for (q = p; q != NULL; q = q->next) { + memcpy(q->payload, data, q->len); + data += q->len; + } - LINK_STATS_INC(link.recv); + LINK_STATS_INC(link.recv); - return p; + return p; } int net_lwip_rx(struct udevice *udev, struct netif *netif) diff --git a/net/lwip/ping.c b/net/lwip/ping.c index 8dafa25959f..aa617530749 100644 --- a/net/lwip/ping.c +++ b/net/lwip/ping.c @@ -39,8 +39,8 @@ static u8_t ping_recv(void *arg, struct raw_pcb *pcb, struct pbuf *p, 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))) { + 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); @@ -93,7 +93,7 @@ static void ping_send_icmp(struct ping_ctx *ctx) if (!p) return; - if ((p->len == p->tot_len) && !p->next) { + 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); @@ -113,7 +113,7 @@ static void ping_send(void *arg) } } -static int ping_loop(struct udevice *udev, const ip_addr_t* addr) +static int ping_loop(struct udevice *udev, const ip_addr_t *addr) { struct ping_ctx ctx = {}; struct netif *netif; diff --git a/net/lwip/tftp.c b/net/lwip/tftp.c index f4d0a6aa19a..fc4aff5f2ba 100644 --- a/net/lwip/tftp.c +++ b/net/lwip/tftp.c @@ -71,7 +71,7 @@ static int tftp_write(void *handle, struct pbuf *p) struct tftp_ctx *ctx = handle; struct pbuf *q; - for (q = p; q != NULL; q = q->next) { + for (q = p; q; q = q->next) { memcpy((void *)ctx->daddr, q->payload, q->len); ctx->daddr += q->len; ctx->size += q->len; @@ -130,7 +130,7 @@ static int tftp_loop(struct udevice *udev, ulong addr, char *fname, printf("Using %s device\n", udev->name); printf("TFTP from server %s; our IP address is %s\n", - ip4addr_ntoa(&srvip), env_get("ipaddr")); + ip4addr_ntoa(&srvip), env_get("ipaddr")); printf("Filename '%s'.\n", fname); printf("Load address: 0x%lx\n", ctx.daddr); printf("Loading: "); @@ -187,7 +187,7 @@ int do_tftpb(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) char *server_port = NULL; char *end; ip_addr_t srvip; - uint16_t port = TFTP_PORT; + u16 port = TFTP_PORT; ulong laddr; ulong addr; int i; @@ -228,7 +228,7 @@ int do_tftpb(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) if (arg) { /* Parse [ip:[port:]]fname */ i = 0; - while ((*(words + i) = strsep(&arg,":"))) + while ((*(words + i) = strsep(&arg, ":"))) i++; switch (i) { diff --git a/net/lwip/wget.c b/net/lwip/wget.c index 53c3b169e01..46858cb5dd3 100644 --- a/net/lwip/wget.c +++ b/net/lwip/wget.c @@ -7,19 +7,23 @@ #include <efi_loader.h> #include <image.h> #include <lwip/apps/http_client.h> +#include "lwip/altcp_tls.h" #include <lwip/timeouts.h> +#include <rng.h> #include <mapmem.h> #include <net.h> #include <time.h> +#include <dm/uclass.h> -#define SERVER_NAME_SIZE 200 +#define SERVER_NAME_SIZE 254 #define HTTP_PORT_DEFAULT 80 +#define HTTPS_PORT_DEFAULT 443 #define PROGRESS_PRINT_STEP_BYTES (100 * 1024) enum done_state { - NOT_DONE = 0, - SUCCESS = 1, - FAILURE = 2 + NOT_DONE = 0, + SUCCESS = 1, + FAILURE = 2 }; struct wget_ctx { @@ -46,18 +50,54 @@ static void wget_lwip_set_file_size(u32_t rx_content_len) wget_info->file_size = (ulong)rx_content_len; } -static int parse_url(char *url, char *host, u16 *port, char **path) +bool wget_validate_uri(char *uri); + +int mbedtls_hardware_poll(void *data, unsigned char *output, size_t len, + size_t *olen) +{ + struct udevice *dev; + int ret; + + *olen = 0; + + ret = uclass_get_device(UCLASS_RNG, 0, &dev); + if (ret) { + log_err("Failed to get an rng: %d\n", ret); + return ret; + } + ret = dm_rng_read(dev, output, len); + if (ret) + return ret; + + *olen = len; + + return 0; +} + +static int parse_url(char *url, char *host, u16 *port, char **path, + bool *is_https) { char *p, *pp; long lport; + size_t prefix_len = 0; + if (!wget_validate_uri(url)) { + log_err("Invalid URL. Use http(s)://\n"); + return -EINVAL; + } + + *is_https = false; + *port = HTTP_PORT_DEFAULT; + prefix_len = strlen("http://"); p = strstr(url, "http://"); if (!p) { - log_err("only http:// is supported\n"); - return -EINVAL; + p = strstr(url, "https://"); + prefix_len = strlen("https://"); + *port = HTTPS_PORT_DEFAULT; + *is_https = true; } - p += strlen("http://"); + p += prefix_len; /* Parse hostname */ pp = strchr(p, ':'); @@ -81,9 +121,8 @@ static int parse_url(char *url, char *host, u16 *port, char **path) if (lport > 65535) return -EINVAL; *port = (u16)lport; - } else { - *port = HTTP_PORT_DEFAULT; } + if (*pp != '/') return -EINVAL; *path = pp; @@ -136,7 +175,7 @@ static int parse_legacy_arg(char *arg, char *nurl, size_t rem) if (rem < n) return -1; - strncpy(p, server, n); + strlcpy(p, server, n); p += n; rem -= n; if (rem < 1) @@ -147,7 +186,7 @@ static int parse_legacy_arg(char *arg, char *nurl, size_t rem) n = strlen(path); if (rem < n) return -1; - strncpy(p, path, n); + strlcpy(p, path, n); p += n; rem -= n; if (rem < 1) @@ -244,11 +283,17 @@ static err_t httpc_headers_done_cb(httpc_state_t *connection, void *arg, struct static int wget_loop(struct udevice *udev, ulong dst_addr, char *uri) { + char server_name[SERVER_NAME_SIZE]; +#if defined CONFIG_WGET_HTTPS + altcp_allocator_t tls_allocator; +#endif httpc_connection_t conn; httpc_state_t *state; struct netif *netif; struct wget_ctx ctx; char *path; + u16 port; + bool is_https; ctx.daddr = dst_addr; ctx.saved_daddr = dst_addr; @@ -257,7 +302,7 @@ static int wget_loop(struct udevice *udev, ulong dst_addr, char *uri) ctx.prevsize = 0; ctx.start_time = 0; - if (parse_url(uri, ctx.server_name, &ctx.port, &path)) + if (parse_url(uri, server_name, &port, &path, &is_https)) return CMD_RET_USAGE; netif = net_lwip_new_netif(udev); @@ -265,6 +310,22 @@ static int wget_loop(struct udevice *udev, ulong dst_addr, char *uri) return -1; memset(&conn, 0, sizeof(conn)); +#if defined CONFIG_WGET_HTTPS + if (is_https) { + tls_allocator.alloc = &altcp_tls_alloc; + tls_allocator.arg = + altcp_tls_create_config_client(NULL, 0, server_name); + + if (!tls_allocator.arg) { + log_err("error: Cannot create a TLS connection\n"); + net_lwip_remove_netif(netif); + return -1; + } + + conn.altcp_allocator = &tls_allocator; + } +#endif + conn.result_fn = httpc_result_cb; conn.headers_done_fn = httpc_headers_done_cb; ctx.path = path; @@ -310,7 +371,7 @@ int do_wget(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) return CMD_RET_USAGE; dst_addr = hextoul(argv[1], &end); - if (end == (argv[1] + strlen(argv[1]))) { + if (end == (argv[1] + strlen(argv[1]))) { if (argc < 3) return CMD_RET_USAGE; url = argv[2]; @@ -320,7 +381,7 @@ int do_wget(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) } if (parse_legacy_arg(url, nurl, sizeof(nurl))) - return CMD_RET_FAILURE; + return CMD_RET_FAILURE; wget_info = &default_wget_info; if (wget_with_dns(dst_addr, nurl)) @@ -354,6 +415,7 @@ bool wget_validate_uri(char *uri) char c; bool ret = true; char *str_copy, *s, *authority; + size_t prefix_len = 0; for (c = 0x1; c < 0x21; c++) { if (strchr(uri, c)) { @@ -361,15 +423,21 @@ bool wget_validate_uri(char *uri) return false; } } + if (strchr(uri, 0x7f)) { log_err("invalid character is used\n"); return false; } - if (strncmp(uri, "http://", 7)) { - log_err("only http:// is supported\n"); + if (!strncmp(uri, "http://", strlen("http://"))) { + prefix_len = strlen("http://"); + } else if (!strncmp(uri, "https://", strlen("https://"))) { + prefix_len = strlen("https://"); + } else { + log_err("only http(s):// is supported\n"); return false; } + str_copy = strdup(uri); if (!str_copy) return false; |