summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/Kconfig70
-rw-r--r--net/Makefile6
-rw-r--r--net/bootp.c8
-rw-r--r--net/cdp.c8
-rw-r--r--net/dhcpv6.c32
-rw-r--r--net/lwip/Kconfig2
-rw-r--r--net/lwip/dhcp.c15
-rw-r--r--net/lwip/dns.c7
-rw-r--r--net/lwip/net-lwip.c16
-rw-r--r--net/lwip/nfs.c4
-rw-r--r--net/lwip/tftp.c4
-rw-r--r--net/lwip/wget.c125
-rw-r--r--net/net.c9
-rw-r--r--net/nfs-common.c4
-rw-r--r--net/sntp.c3
15 files changed, 228 insertions, 85 deletions
diff --git a/net/Kconfig b/net/Kconfig
index e45ceb25106..386376ce884 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -2,8 +2,45 @@
# Network configuration
#
+config NO_NET
+ bool "Disable networking"
+ help
+ Transitional variable. Equivalent to setting NET=n.
+
+menuconfig NET
+ bool "Networking"
+ depends on !NO_NET
+ default y
+
if NET
+choice
+ prompt "Networking stack"
+ default NET_LEGACY
+
+config NET_LEGACY
+ bool "Legacy U-Boot networking stack"
+ select NETDEVICES
+ help
+ Include networking support with U-Boot's internal implementation of
+ the TCP/IP protocol stack.
+
+config NET_LWIP
+ bool "Use lwIP for networking stack"
+ select NETDEVICES
+ help
+ Include networking support based on the lwIP (lightweight IP)
+ TCP/IP stack (https://nongnu.org/lwip). This is a replacement for
+ the default U-Boot network stack and applications located in net/
+ and enabled via CONFIG_NET_LEGACY as well as other pieces of code that
+ depend on CONFIG_NET_LEGACY (such as cmd/net.c enabled via CONFIG_CMD_NET).
+ Therefore the two symbols CONFIG_NET_LEGACY and CONFIG_NET_LWIP are mutually
+ exclusive.
+
+endchoice
+
+if NET_LEGACY
+
config ARP_TIMEOUT
int "Milliseconds before trying ARP again"
default 5000
@@ -77,15 +114,15 @@ config SERVERIP_FROM_PROXYDHCP
bool "Get serverip value from Proxy DHCP response"
help
Allows bootfile config to be fetched from Proxy DHCP server
- while IP is obtained from main DHCP server.
+ while IP is obtained from main DHCP server.
config SERVERIP_FROM_PROXYDHCP_DELAY_MS
int "# of additional milliseconds to wait for ProxyDHCP response"
default 100
help
Amount of additional time to wait for ProxyDHCP response after
- receiving response from main DHCP server. Has no effect if
- SERVERIP_FROM_PROXYDHCP is false.
+ receiving response from main DHCP server. Has no effect if
+ SERVERIP_FROM_PROXYDHCP is false.
config KEEP_SERVERADDR
bool "Write the server's MAC address to 'serveraddr'"
@@ -195,12 +232,10 @@ config IPV6
ip6addr, serverip6. If a u-boot command is capable to parse an IPv6
address and find it, it will force using IPv6 in the network stack.
-endif # if NET
+endif # if NET_LEGACY
source "net/lwip/Kconfig"
-if NET || NET_LWIP
-
config BOOTDEV_ETH
bool "Enable bootdev for ethernet"
depends on BOOTSTD
@@ -228,7 +263,7 @@ config DNS
config WGET
bool "Enable wget"
- select PROT_TCP if NET
+ select PROT_TCP if NET_LEGACY
select PROT_TCP_LWIP if NET_LWIP
help
Selecting this will enable wget, an interface to send HTTP requests
@@ -244,13 +279,16 @@ config TFTP_BLOCKSIZE
almost-MTU block sizes.
You can also activate CONFIG_IP_DEFRAG to set a larger block.
-endif # if NET || NET_LWIP
-
config SYS_RX_ETH_BUFFER
- int "Number of receive packet buffers"
- default 4
- help
- Defines the number of Ethernet receive buffers. On some Ethernet
- controllers it is recommended to set this value to 8 or even higher,
- since all buffers can be full shortly after enabling the interface on
- high Ethernet traffic.
+ int "Number of receive packet buffers"
+ default 8 if FSL_ENETC
+ default 4
+ help
+ Defines the number of Ethernet receive buffers. On some Ethernet
+ controllers (e.g. FSL_ENETC) it is recommended to set this value to 8
+ or even higher, since all buffers can be full shortly after enabling
+ the interface on high Ethernet traffic.
+
+ FSL_ENETC requires this value to be a multiple of 8.
+
+endif # if NET
diff --git a/net/Makefile b/net/Makefile
index 3a32bc8b0e7..ceac6de6377 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -5,9 +5,9 @@
#ccflags-y += -DDEBUG
-ifeq ($(CONFIG_NET),y)
+ifeq ($(CONFIG_NET_LEGACY),y)
-obj-$(CONFIG_NET) += arp.o
+obj-$(CONFIG_NET_LEGACY) += arp.o
obj-$(CONFIG_CMD_BOOTP) += bootp.o
obj-$(CONFIG_CMD_CDP) += cdp.o
obj-$(CONFIG_DNS) += dns.o
@@ -37,7 +37,7 @@ CFLAGS_eth_common.o += -Wno-format-extra-args
endif
-ifeq ($(filter y,$(CONFIG_NET) $(CONFIG_NET_LWIP)),y)
+ifeq ($(CONFIG_NET),y)
obj-$(CONFIG_DM_DSA) += dsa-uclass.o
obj-$(CONFIG_$(PHASE_)DM_ETH) += eth-uclass.o
obj-$(CONFIG_$(PHASE_)BOOTDEV_ETH) += eth_bootdev.o
diff --git a/net/bootp.c b/net/bootp.c
index 8976936b184..f0dc329d6e4 100644
--- a/net/bootp.c
+++ b/net/bootp.c
@@ -997,13 +997,13 @@ static void dhcp_packet_process_options(struct bootp_hdr *bp)
}
}
-static int dhcp_message_type(unsigned char *popt)
+static int dhcp_message_type(unsigned char *popt, unsigned char *end)
{
if (net_read_u32((u32 *)popt) != htonl(BOOTP_VENDOR_MAGIC))
return -1;
popt += 4;
- while (*popt != 0xff) {
+ while (popt < end && *popt != 0xff) {
if (*popt == 53) /* DHCP Message Type */
return *(popt + 2);
if (*popt == 0) {
@@ -1120,7 +1120,7 @@ static void dhcp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
strlen(CONFIG_SYS_BOOTFILE_PREFIX)) == 0) {
#endif /* CONFIG_SYS_BOOTFILE_PREFIX */
if (CONFIG_IS_ENABLED(UNIT_TEST) &&
- dhcp_message_type((u8 *)bp->bp_vend) == -1) {
+ dhcp_message_type((u8 *)bp->bp_vend, (u8 *)pkt + len) == -1) {
debug("got BOOTP response; transitioning to BOUND\n");
goto dhcp_got_bootp;
}
@@ -1149,7 +1149,7 @@ static void dhcp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
case REQUESTING:
debug("DHCP State: REQUESTING\n");
- if (dhcp_message_type((u8 *)bp->bp_vend) == DHCP_ACK) {
+ if (dhcp_message_type((u8 *)bp->bp_vend, (u8 *)pkt + len) == DHCP_ACK) {
dhcp_got_bootp:
dhcp_packet_process_options(bp);
/* Store net params from reply */
diff --git a/net/cdp.c b/net/cdp.c
index 6e404981d4a..300b3d5c409 100644
--- a/net/cdp.c
+++ b/net/cdp.c
@@ -276,7 +276,13 @@ void cdp_receive(const uchar *pkt, unsigned len)
ss = (const ushort *)pkt;
type = ntohs(ss[0]);
tlen = ntohs(ss[1]);
- if (tlen > len)
+ /*
+ * tlen includes the 4-byte TLV header, so it must be at
+ * least 4. Without this check a crafted tlen < 4 makes the
+ * "tlen -= 4" below underflow (tlen is a ushort), and a tlen
+ * of 0 also fails to advance pkt/len, hanging the loop.
+ */
+ if (tlen < 4 || tlen > len)
goto pkt_short;
pkt += tlen;
diff --git a/net/dhcpv6.c b/net/dhcpv6.c
index 5bf935cb6a3..640f089a2e1 100644
--- a/net/dhcpv6.c
+++ b/net/dhcpv6.c
@@ -339,6 +339,11 @@ static void dhcp6_parse_options(uchar *rx_pkt, unsigned int len)
break;
case DHCP6_OPTION_IA_TA:
case DHCP6_OPTION_IA_NA:
+ if (option_len < sizeof(u32)) {
+ debug("Invalid IA_NA/IA_TA option length\n");
+ break;
+ }
+
/* check the IA_ID */
if (*((u32 *)option_ptr) != htonl(sm_params.ia_id)) {
debug("IA_ID mismatch 0x%08x 0x%08x\n",
@@ -347,6 +352,10 @@ static void dhcp6_parse_options(uchar *rx_pkt, unsigned int len)
}
if (ntohs(option_hdr->option_id) == DHCP6_OPTION_IA_NA) {
+ if (option_len < 3 * sizeof(u32)) {
+ debug("Invalid IA_NA option length\n");
+ break;
+ }
/* skip past IA_ID/T1/T2 */
option_ptr += 3 * sizeof(u32);
} else if (ntohs(option_hdr->option_id) == DHCP6_OPTION_IA_TA) {
@@ -358,12 +367,20 @@ static void dhcp6_parse_options(uchar *rx_pkt, unsigned int len)
break;
case DHCP6_OPTION_STATUS_CODE:
debug("DHCP6_OPTION_STATUS_CODE FOUND\n");
+ if (option_len < sizeof(u16)) {
+ debug("Invalid status code option length\n");
+ break;
+ }
sm_params.rx_status.status_code = ntohs(*((u16 *)option_ptr));
debug("DHCP6 top-level status code %d\n", sm_params.rx_status.status_code);
debug("DHCP6 status message: %.*s\n", len, option_ptr + 2);
break;
case DHCP6_OPTION_SOL_MAX_RT:
debug("DHCP6_OPTION_SOL_MAX_RT FOUND\n");
+ if (option_len != sizeof(u32)) {
+ debug("Invalid SOL_MAX_RT option length\n");
+ break;
+ }
sol_max_rt_sec = ntohl(*((u32 *)option_ptr));
/* A DHCP client MUST ignore any SOL_MAX_RT option values that are less
@@ -377,6 +394,11 @@ static void dhcp6_parse_options(uchar *rx_pkt, unsigned int len)
break;
case DHCP6_OPTION_OPT_BOOTFILE_URL:
debug("DHCP6_OPTION_OPT_BOOTFILE_URL FOUND\n");
+ if (option_len >= sizeof(net_boot_file_name)) {
+ debug("Option length for BOOTFILE_URL is greater or equal than %zu. Skipping\n",
+ sizeof(net_boot_file_name));
+ break;
+ }
copy_filename(net_boot_file_name, option_ptr, option_len + 1);
debug("net_boot_file_name: %s\n", net_boot_file_name);
@@ -389,6 +411,12 @@ static void dhcp6_parse_options(uchar *rx_pkt, unsigned int len)
case DHCP6_OPTION_OPT_BOOTFILE_PARAM:
if (IS_ENABLED(CONFIG_DHCP6_PXE_DHCP_OPTION)) {
debug("DHCP6_OPTION_OPT_BOOTFILE_PARAM FOUND\n");
+
+ if (option_len < sizeof(u16)) {
+ debug("Invalid BOOTFILE_PARAM option length\n");
+ break;
+ }
+
/* if CONFIG_DHCP6_PXE_DHCP_OPTION is set the PXE config file path
* is contained in the first OPT_BOOTFILE_PARAM argument
*/
@@ -414,6 +442,10 @@ static void dhcp6_parse_options(uchar *rx_pkt, unsigned int len)
break;
case DHCP6_OPTION_PREFERENCE:
debug("DHCP6_OPTION_PREFERENCE FOUND\n");
+ if (option_len != 1) {
+ debug("Invalid preference option length\n");
+ break;
+ }
sm_params.rx_status.preference = *option_ptr;
break;
default:
diff --git a/net/lwip/Kconfig b/net/lwip/Kconfig
index 0cfd3eb2684..3beaf48ff2a 100644
--- a/net/lwip/Kconfig
+++ b/net/lwip/Kconfig
@@ -18,7 +18,7 @@ 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.
+ and out of the lwIP library.
config LWIP_DEBUG_RXTX
bool "Dump packets sent and received by lwIP"
diff --git a/net/lwip/dhcp.c b/net/lwip/dhcp.c
index acdf601d7eb..18dc36ae7ca 100644
--- a/net/lwip/dhcp.c
+++ b/net/lwip/dhcp.c
@@ -138,18 +138,25 @@ int do_dhcp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
dev = eth_get_dev();
if (!dev) {
log_err("No network device\n");
- return CMD_RET_FAILURE;
+ ret = CMD_RET_FAILURE;
+ goto out;
}
ret = dhcp_loop(dev);
if (ret)
- return ret;
+ goto out;
if (argc > 1) {
struct cmd_tbl cmdtp = {};
- return do_tftpb(&cmdtp, 0, argc, argv);
+ ret = do_tftpb(&cmdtp, 0, argc, argv);
+ goto out;
}
- return CMD_RET_SUCCESS;
+ ret = CMD_RET_SUCCESS;
+
+out:
+ net_lwip_eth_stop();
+
+ return ret;
}
diff --git a/net/lwip/dns.c b/net/lwip/dns.c
index 8b7b3b7f970..b620b0611d6 100644
--- a/net/lwip/dns.c
+++ b/net/lwip/dns.c
@@ -91,6 +91,7 @@ int do_dns(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
char *name;
char *var = NULL;
+ int ret;
if (argc == 1 || argc > 3)
return CMD_RET_USAGE;
@@ -103,5 +104,9 @@ int do_dns(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
if (net_lwip_eth_start() < 0)
return CMD_RET_FAILURE;
- return dns_loop(eth_get_dev(), name, var);
+ ret = dns_loop(eth_get_dev(), name, var);
+
+ net_lwip_eth_stop();
+
+ return ret;
}
diff --git a/net/lwip/net-lwip.c b/net/lwip/net-lwip.c
index 0c83c004cab..cfe5a6a640d 100644
--- a/net/lwip/net-lwip.c
+++ b/net/lwip/net-lwip.c
@@ -31,6 +31,7 @@ void (*push_packet)(void *, int len) = 0;
int net_try_count;
static int net_restarted;
int net_restart_wrap;
+static int net_lwip_eth_started;
static uchar net_pkt_buf[(PKTBUFSRX) * PKTSIZE_ALIGN + PKTALIGN]
__aligned(PKTALIGN);
const u8 net_bcast_ethaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
@@ -180,11 +181,15 @@ int net_lwip_eth_start(void)
{
int ret;
+ if (net_lwip_eth_started++ > 0)
+ return 0;
+
net_init();
eth_halt();
eth_set_current();
ret = eth_init();
if (ret < 0) {
+ net_lwip_eth_started--;
eth_halt();
return ret;
}
@@ -192,6 +197,17 @@ int net_lwip_eth_start(void)
return 0;
}
+void net_lwip_eth_stop(void)
+{
+ if (!net_lwip_eth_started)
+ return;
+
+ if (--net_lwip_eth_started)
+ return;
+
+ eth_halt();
+}
+
static struct netif *new_netif(struct udevice *udev, bool with_ip)
{
unsigned char enetaddr[ARP_HLEN];
diff --git a/net/lwip/nfs.c b/net/lwip/nfs.c
index 9e6b801e465..4cc36373fdd 100644
--- a/net/lwip/nfs.c
+++ b/net/lwip/nfs.c
@@ -187,6 +187,7 @@ static int nfs_loop(struct udevice *udev, ulong addr, char *fname,
int do_nfs(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
int ret = CMD_RET_SUCCESS;
+ bool started = false;
char *arg = NULL;
char *words[2] = { };
char *fname = NULL;
@@ -281,10 +282,13 @@ int do_nfs(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
ret = CMD_RET_FAILURE;
goto out;
}
+ started = true;
if (nfs_loop(eth_get_dev(), laddr, fname, srvip) < 0)
ret = CMD_RET_FAILURE;
out:
+ if (started)
+ net_lwip_eth_stop();
if (arg != net_boot_file_name)
free(arg);
return ret;
diff --git a/net/lwip/tftp.c b/net/lwip/tftp.c
index 7f3b28b8507..571c38172f9 100644
--- a/net/lwip/tftp.c
+++ b/net/lwip/tftp.c
@@ -261,6 +261,7 @@ static int tftp_loop(struct udevice *udev, ulong addr, char *fname,
int do_tftpb(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
int ret = CMD_RET_SUCCESS;
+ bool started = false;
char *arg = NULL;
char *words[3] = { };
char *fname = NULL;
@@ -365,12 +366,15 @@ int do_tftpb(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
ret = CMD_RET_FAILURE;
goto out;
}
+ started = true;
if (tftp_loop(eth_get_dev(), laddr, fname, srvip, port) < 0)
ret = CMD_RET_FAILURE;
else
image_load_addr = laddr;
out:
+ if (started)
+ net_lwip_eth_stop();
if (arg != net_boot_file_name)
free(arg);
return ret;
diff --git a/net/lwip/wget.c b/net/lwip/wget.c
index 008f3b395e7..247ece18e2b 100644
--- a/net/lwip/wget.c
+++ b/net/lwip/wget.c
@@ -20,7 +20,6 @@
#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,
@@ -178,6 +177,9 @@ static int store_block(struct wget_ctx *ctx, void *src, u16_t len)
ctx->daddr += len;
ctx->size += len;
+ if (wget_info->silent)
+ return 0;
+
pos = clamp(ctx->size, 0UL, ctx->content_len);
while (ctx->hash_count < pos * 50 / ctx->content_len) {
@@ -240,20 +242,18 @@ static void httpc_result_cb(void *arg, httpc_result_t httpc_result,
}
/* Print hash marks for the last packet received */
- while (ctx->hash_count < 49) {
- putc('#');
- ctx->hash_count++;
+ if (!wget_info->silent) {
+ while (ctx->hash_count < 49) {
+ putc('#');
+ ctx->hash_count++;
+ }
}
- puts(" ");
- print_size(ctx->content_len, "");
elapsed = get_timer(ctx->start_time);
if (!elapsed)
elapsed = 1;
if (!wget_info->silent) {
- if (rx_content_len > PROGRESS_PRINT_STEP_BYTES)
- printf("\n");
- printf("%u bytes transferred in %lu ms (", rx_content_len,
+ printf("\n%u bytes transferred in %lu ms (", rx_content_len,
elapsed);
print_size(rx_content_len / elapsed * 1000, "/s)\n");
printf("Bytes transferred = %lu (%lx hex)\n", ctx->size,
@@ -292,46 +292,22 @@ static err_t httpc_headers_done_cb(httpc_state_t *connection, void *arg, struct
#if CONFIG_IS_ENABLED(WGET_CACERT)
#endif
-int wget_do_request(ulong dst_addr, char *uri)
+static int wget_handle_request(struct wget_ctx *ctx, bool is_https,
+ struct udevice *udev, struct netif *netif)
{
#if CONFIG_IS_ENABLED(WGET_HTTPS)
altcp_allocator_t tls_allocator;
#endif
httpc_connection_t conn;
httpc_state_t *state;
- struct udevice *udev;
- struct netif *netif;
- struct wget_ctx ctx;
- char *path;
- bool is_https;
-
- ctx.daddr = dst_addr;
- ctx.saved_daddr = dst_addr;
- ctx.done = NOT_DONE;
- ctx.size = 0;
- ctx.prevsize = 0;
- ctx.start_time = 0;
- ctx.content_len = 0;
- ctx.hash_count = 0;
-
- if (parse_url(uri, ctx.server_name, &ctx.port, &path, &is_https))
- return CMD_RET_USAGE;
-
- if (net_lwip_eth_start() < 0)
- return CMD_RET_FAILURE;
-
- if (!wget_info)
- wget_info = &default_wget_info;
-
- udev = eth_get_dev();
-
- netif = net_lwip_new_netif(udev);
- if (!netif)
- return -1;
+ int ret;
/* if URL with hostname init dns */
- if (!ipaddr_aton(ctx.server_name, NULL) && net_lwip_dns_init())
- return CMD_RET_FAILURE;
+ if (!ipaddr_aton(ctx->server_name, NULL)) {
+ ret = net_lwip_dns_init();
+ if (ret)
+ return ret;
+ }
memset(&conn, 0, sizeof(conn));
#if CONFIG_IS_ENABLED(WGET_HTTPS)
@@ -353,7 +329,7 @@ int wget_do_request(ulong dst_addr, char *uri)
printf("Error: cacert authentication "
"mode is 'required' but no CA "
"certificates given\n");
- return CMD_RET_FAILURE;
+ return -EINVAL;
}
} else if (cacert_auth_mode == AUTH_NONE) {
ca = NULL;
@@ -374,12 +350,11 @@ int wget_do_request(ulong dst_addr, char *uri)
tls_allocator.alloc = &altcp_tls_alloc;
tls_allocator.arg =
altcp_tls_create_config_client(ca, ca_sz,
- ctx.server_name);
+ ctx->server_name);
if (!tls_allocator.arg) {
log_err("error: Cannot create a TLS connection\n");
- net_lwip_remove_netif(netif);
- return -1;
+ return -ENODEV;
}
conn.altcp_allocator = &tls_allocator;
@@ -388,30 +363,70 @@ int wget_do_request(ulong dst_addr, char *uri)
conn.result_fn = httpc_result_cb;
conn.headers_done_fn = httpc_headers_done_cb;
- ctx.path = path;
- if (httpc_get_file_dns(ctx.server_name, ctx.port, path, &conn, httpc_recv_cb,
- &ctx, &state)) {
- net_lwip_remove_netif(netif);
- return CMD_RET_FAILURE;
+ if (httpc_get_file_dns(ctx->server_name, ctx->port, ctx->path, &conn,
+ httpc_recv_cb, ctx, &state)) {
+ return -ENODEV;
}
errno = 0;
- while (!ctx.done) {
+ while (!ctx->done) {
net_lwip_rx(udev, netif);
if (ctrlc())
break;
}
- net_lwip_remove_netif(netif);
-
- if (ctx.done == SUCCESS)
+ if (ctx->done == SUCCESS)
return 0;
if (errno == EPERM && !wget_info->silent)
printf("Certificate verification failed\n");
- return -1;
+ return -errno ?: -EIO;
+}
+
+int wget_do_request(ulong dst_addr, char *uri)
+{
+ struct udevice *udev;
+ struct wget_ctx ctx;
+ struct netif *netif;
+ bool is_https;
+ int ret;
+
+ ctx.daddr = dst_addr;
+ ctx.saved_daddr = dst_addr;
+ ctx.done = NOT_DONE;
+ ctx.size = 0;
+ ctx.prevsize = 0;
+ ctx.start_time = 0;
+ ctx.content_len = 0;
+ ctx.hash_count = 0;
+
+ ret = parse_url(uri, ctx.server_name, &ctx.port, &ctx.path, &is_https);
+ if (ret)
+ return ret;
+
+ ret = net_lwip_eth_start();
+ if (ret)
+ return ret;
+
+ if (!wget_info)
+ wget_info = &default_wget_info;
+
+ udev = eth_get_dev();
+
+ netif = net_lwip_new_netif(udev);
+ if (!netif) {
+ net_lwip_eth_stop();
+ return -ENODEV;
+ }
+
+ ret = wget_handle_request(&ctx, is_https, udev, netif);
+
+ net_lwip_remove_netif(netif);
+ net_lwip_eth_stop();
+
+ return ret;
}
/**
diff --git a/net/net.c b/net/net.c
index ae3b977781f..61c5a6ef6c4 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1103,6 +1103,15 @@ static struct ip_udp_hdr *__net_defragment(struct ip_udp_hdr *ip, int *lenp)
*lenp = total_len + IP_HDR_SIZE;
localip->ip_len = htons(*lenp);
+
+ /*
+ * Mark the reassembly state empty so that any further
+ * fragment goes through the normal re-init path and
+ * rebuilds a clean hole list
+ */
+ total_len = 0;
+ first_hole = 0;
+
return localip;
}
diff --git a/net/nfs-common.c b/net/nfs-common.c
index 4fbde67a760..72d8fd823e3 100644
--- a/net/nfs-common.c
+++ b/net/nfs-common.c
@@ -674,11 +674,15 @@ static int nfs_readlink_reply(uchar *pkt, unsigned int len)
strcat(nfs_path, "/");
pathlen = strlen(nfs_path);
+ if (pathlen + rlen >= sizeof(nfs_path_buff))
+ return -NFS_RPC_DROP;
memcpy(nfs_path + pathlen,
(uchar *)&rpc_pkt.u.reply.data[2 + nfsv3_data_offset],
rlen);
nfs_path[pathlen + rlen] = 0;
} else {
+ if (rlen >= sizeof(nfs_path_buff))
+ return -NFS_RPC_DROP;
memcpy(nfs_path,
(uchar *)&rpc_pkt.u.reply.data[2 + nfsv3_data_offset],
rlen);
diff --git a/net/sntp.c b/net/sntp.c
index 77cee0046bd..4b3dc675bab 100644
--- a/net/sntp.c
+++ b/net/sntp.c
@@ -64,6 +64,9 @@ static void sntp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
if (dest != sntp_our_port)
return;
+ if (len < SNTP_PACKET_LEN)
+ return;
+
/*
* As the RTC's used in U-Boot support second resolution only
* we simply ignore the sub-second field.