This patch provices an EFI application to check the correct function
of the Simple Network Protocol implementation.
It sends a DHCP request and analyzes the DHCP offer.
Different error conditions including a 10s timeout are checked.
A successful execution will look like this:
=> bootefi nettest
Scanning disk ide.blk#0...
Found 1 disks
WARNING: Invalid device tree, expect boot to fail
Network test
DHCP Discover
DHCP reply received from 192.168.76.2 (52:55:c0:a8:4c:02)
as broadcast message.
OK. The test was completed successfully.
Signed-off-by: Heinrich Schuchardt
---
v2
move efi_st_memcmp to efi_selftest_util.c
The function can be reused for other tests.
Use constants for return values.
---
include/efi_selftest.h | 11 +
lib/efi_selftest/Makefile| 8 +-
lib/efi_selftest/efi_selftest_snp.c | 424 +++
lib/efi_selftest/efi_selftest_util.c | 25 +++
4 files changed, 467 insertions(+), 1 deletion(-)
create mode 100644 lib/efi_selftest/efi_selftest_snp.c
create mode 100644 lib/efi_selftest/efi_selftest_util.c
diff --git a/include/efi_selftest.h b/include/efi_selftest.h
index 2f0992f06e..7ec42a0406 100644
--- a/include/efi_selftest.h
+++ b/include/efi_selftest.h
@@ -60,6 +60,17 @@ void efi_st_exit_boot_services(void);
void efi_st_printf(const char *fmt, ...)
__attribute__ ((format (__printf__, 1, 2)));
+/*
+ * Compare memory.
+ * We cannot use lib/string.c due to different CFLAGS values.
+ *
+ * @buf1: first buffer
+ * @buf2: second buffer
+ * @length:number of bytes to compare
+ * @return:0 if both buffers contain the same bytes
+ */
+int efi_st_memcmp(const void *buf1, const void *buf2, size_t length);
+
/*
* Reads an Unicode character from the input device.
*
diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile
index 30f1960933..e446046e02 100644
--- a/lib/efi_selftest/Makefile
+++ b/lib/efi_selftest/Makefile
@@ -15,12 +15,18 @@ CFLAGS_efi_selftest_events.o := $(CFLAGS_EFI)
CFLAGS_REMOVE_efi_selftest_events.o := $(CFLAGS_NON_EFI)
CFLAGS_efi_selftest_exitbootservices.o := $(CFLAGS_EFI)
CFLAGS_REMOVE_efi_selftest_exitbootservices.o := $(CFLAGS_NON_EFI)
+CFLAGS_efi_selftest_snp.o := $(CFLAGS_EFI)
+CFLAGS_REMOVE_efi_selftest_snp.o := $(CFLAGS_NON_EFI)
CFLAGS_efi_selftest_tpl.o := $(CFLAGS_EFI)
CFLAGS_REMOVE_efi_selftest_tpl.o := $(CFLAGS_NON_EFI)
+CFLAGS_efi_selftest_util.o := $(CFLAGS_EFI)
+CFLAGS_REMOVE_efi_selftest_util.o := $(CFLAGS_NON_EFI)
obj-$(CONFIG_CMD_BOOTEFI_SELFTEST) += \
efi_selftest.o \
efi_selftest_console.o \
efi_selftest_events.o \
efi_selftest_exitbootservices.o \
-efi_selftest_tpl.o
+efi_selftest_snp.o \
+efi_selftest_tpl.o \
+efi_selftest_util.o
diff --git a/lib/efi_selftest/efi_selftest_snp.c
b/lib/efi_selftest/efi_selftest_snp.c
new file mode 100644
index 00..638be0147d
--- /dev/null
+++ b/lib/efi_selftest/efi_selftest_snp.c
@@ -0,0 +1,424 @@
+/*
+ * efi_selftest_snp
+ *
+ * Copyright (c) 2017 Heinrich Schuchardt
+ *
+ * SPDX-License-Identifier:GPL-2.0+
+ *
+ * This unit test covers the Simple Network Protocol as well as
+ * the CopyMem and SetMem boottime services.
+ *
+ * A DHCP discover message is sent. The test is successful if a
+ * DHCP reply is received.
+ *
+ * TODO: Once ConnectController and DisconnectController are implemented
+ * we should connect our code as controller.
+ */
+
+#include
+
+/*
+ * MAC address for broadcasts
+ */
+static const u8 BROADCAST_MAC[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+struct dhcp_hdr {
+ u8 op;
+#define BOOTREQUEST 1
+#define BOOTREPLY 2
+ u8 htype;
+# define HWT_ETHER 1
+ u8 hlen;
+# define HWL_ETHER 6
+ u8 hops;
+ u32 xid;
+ u16 secs;
+ u16 flags;
+#define DHCP_FLAGS_UNICAST 0x
+#define DHCP_FLAGS_BROADCAST 0x0080
+ u32 ciaddr;
+ u32 yiaddr;
+ u32 siaddr;
+ u32 giaddr;
+ u8 chaddr[16];
+ u8 sname[64];
+ u8 file[128];
+};
+
+/*
+ * Message type option.
+ */
+#define DHCP_MESSAGE_TYPE 0x35
+#define DHCPDISCOVER 1
+#define DHCPOFFER 2
+#define DHCPREQUEST3
+#define DHCPDECLINE4
+#define DHCPACK5
+#define DHCPNAK6
+#define DHCPRELEASE7
+
+struct dhcp {
+ struct ethernet_hdr eth_hdr;
+ struct ip_udp_hdr ip_udp;
+ struct dhcp_hdr dhcp_hdr;
+ u8 opt[128];
+} __packed;
+
+static struct efi_boot_services *boottime;
+static struct efi_simple_network *net;
+static struct efi_event *timer;
+static const efi_guid_t efi_net_guid = EFI_SIMPLE_NETWORK_GUID;
+/* IP packet ID */
+static unsigned int net_ip_id;
+
+/*
+ * Compute the checksum of the IP header. We cover even values of length only.
+ * We cannot use net/checksum.c due to different CFLAGS values.
+ *
+ * @buf: IP header
+ * @len: length of header in bytes
+ * @return:check