[PATCH] net: lwip: support syslog

James Hilliard <[email protected]>
Newsgroups org.u-boot-project.lists.u-boot
Message-ID <[email protected]>
LOG_SYSLOG depends on NET, but the raw Ethernet and UDP header
builders it uses are only available with the legacy network stack. This
makes LOG_SYSLOG fail to build with NET_LWIP.

Provide lwIP implementations using the selected Ethernet device and its
indexed IP address from the environment. Move the shared declarations to
net-common.h and extend the syslog test to check the source MAC address
and IPv4 header checksum.

Signed-off-by: James Hilliard <[email protected]>
---
 include/net-common.h   |  7 ++++++
 include/net-legacy.h   |  4 ----
 net/lwip/net-lwip.c    | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++
 test/log/syslog_test.c |  2 ++
 test/log/syslog_test.h |  4 ++--
 5 files changed, 69 insertions(+), 6 deletions(-)

diff --git a/include/net-common.h b/include/net-common.h
index 0c260873c2c..3084a2b2a57 100644
--- a/include/net-common.h
+++ b/include/net-common.h
@@ -362,6 +362,13 @@ struct ethernet_hdr {
 /* Ethernet header size */
 #define ETHER_HDR_SIZE	(sizeof(struct ethernet_hdr))
 
+/* Set Ethernet header; returns the size of the header */
+int net_set_ether(uchar *xet, const uchar *dest_ethaddr, uint prot);
+
+/* Set IPv4 and UDP headers */
+void net_set_udp_header(uchar *pkt, struct in_addr dest, int dport,
+			int sport, int len);
+
 /**
  * net_random_ethaddr - Generate software assigned random Ethernet address
  * @addr: Pointer to a six-byte array containing the Ethernet address
diff --git a/include/net-legacy.h b/include/net-legacy.h
index d3b122c9062..d7f55d34a30 100644
--- a/include/net-legacy.h
+++ b/include/net-legacy.h
@@ -344,15 +344,11 @@ int net_loop(enum proto_t);
 /* Get size of the ethernet header when we send */
 int net_eth_hdr_size(void);
 
-/* Set ethernet header; returns the size of the header */
-int net_set_ether(uchar *xet, const uchar *dest_ethaddr, uint prot);
 int net_update_ether(struct ethernet_hdr *et, uchar *addr, uint prot);
 
 /* Set IP header */
 void net_set_ip_header(uchar *pkt, struct in_addr dest, struct in_addr source,
 		       u16 pkt_len, u8 proto);
-void net_set_udp_header(uchar *pkt, struct in_addr dest, int dport,
-			int sport, int len);
 
 /* Callbacks */
 rxhand_f *net_get_udp_handler(void);	/* Get UDP RX packet handler */
diff --git a/net/lwip/net-lwip.c b/net/lwip/net-lwip.c
index 8f8f9d69020..4dd8f0d2ce7 100644
--- a/net/lwip/net-lwip.c
+++ b/net/lwip/net-lwip.c
@@ -159,6 +159,64 @@ static int get_udev_ipv4_info(struct udevice *dev, ip4_addr_t *ip,
 	return 0;
 }
 
+int net_set_ether(uchar *xet, const uchar *dest_ethaddr, uint prot)
+{
+	struct ethernet_hdr *et = (struct ethernet_hdr *)xet;
+	const uchar *src = eth_get_ethaddr();
+
+	memcpy(et->et_dest, dest_ethaddr, ARP_HLEN);
+	if (src)
+		memcpy(et->et_src, src, ARP_HLEN);
+	else
+		memset(et->et_src, 0, ARP_HLEN);
+	et->et_protlen = htons(prot);
+
+	return ETHER_HDR_SIZE;
+}
+
+static void net_lwip_set_ip_header(uchar *pkt, struct in_addr dest,
+				   struct in_addr source, u16 pkt_len,
+				   u8 proto)
+{
+	static u16 ip_id;
+	struct ip_udp_hdr *ip = (struct ip_udp_hdr *)pkt;
+
+	ip->ip_hl_v = 0x45;
+	ip->ip_tos = 0;
+	ip->ip_len = htons(pkt_len);
+	ip->ip_p = proto;
+	ip->ip_id = htons(ip_id++);
+	ip->ip_off = htons(IP_FLAGS_DFRAG);
+	ip->ip_ttl = 255;
+	ip->ip_sum = 0;
+	memcpy(&ip->ip_src, &source, sizeof(source));
+	memcpy(&ip->ip_dst, &dest, sizeof(dest));
+	ip->ip_sum = compute_ip_checksum(ip, IP_HDR_SIZE);
+}
+
+void net_set_udp_header(uchar *pkt, struct in_addr dest, int dport, int sport,
+			int len)
+{
+	struct ip_udp_hdr *ip = (struct ip_udp_hdr *)pkt;
+	struct in_addr source = {};
+	ip4_addr_t addr, mask, gateway;
+	struct udevice *dev = eth_get_dev();
+	u16 pkt_len = IP_UDP_HDR_SIZE + len;
+
+	if (len & 1)
+		pkt[IP_UDP_HDR_SIZE + len] = 0;
+
+	if (dev && !get_udev_ipv4_info(dev, &addr, &mask, &gateway))
+		source.s_addr = addr.addr;
+
+	net_lwip_set_ip_header(pkt, dest, source, pkt_len, IPPROTO_UDP);
+
+	ip->udp_src = htons(sport);
+	ip->udp_dst = htons(dport);
+	ip->udp_len = htons(UDP_HDR_SIZE + len);
+	ip->udp_xsum = 0;
+}
+
 /*
  * Initialize DNS via env
  */
diff --git a/test/log/syslog_test.c b/test/log/syslog_test.c
index b6c0631aaf6..f848506fb1c 100644
--- a/test/log/syslog_test.c
+++ b/test/log/syslog_test.c
@@ -34,11 +34,13 @@ int sb_log_tx_handler(struct udevice *dev, void *packet, unsigned int len)
 
 	/* Check Ethernet header */
 	ut_asserteq_mem(&eth_hdr->et_dest, net_bcast_ethaddr, ARP_HLEN);
+	ut_asserteq_mem(&eth_hdr->et_src, eth_get_ethaddr(), ARP_HLEN);
 	ut_asserteq(ntohs(eth_hdr->et_protlen), PROT_IP);
 
 	/* Check IP header */
 	buf += sizeof(struct ethernet_hdr);
 	ip_udp_hdr = (struct ip_udp_hdr *)buf;
+	ut_assert(ip_checksum_ok(ip_udp_hdr, IP_HDR_SIZE));
 	ut_asserteq(ip_udp_hdr->ip_p, IPPROTO_UDP);
 	ut_asserteq(ip_udp_hdr->ip_dst.s_addr, 0xffffffff);
 	ut_asserteq(ntohs(ip_udp_hdr->udp_dst), 514);
diff --git a/test/log/syslog_test.h b/test/log/syslog_test.h
index 39cce4ed498..89c86541f5e 100644
--- a/test/log/syslog_test.h
+++ b/test/log/syslog_test.h
@@ -31,8 +31,8 @@ struct sb_log_env {
  *
  * The following checks are executed:
  *
- * * the Ethernet packet indicates a IP broadcast message
- * * the IP header is for a local UDP broadcast message to port 514
+ * * the Ethernet packet uses the selected interface and broadcast destination
+ * * the IP header checksum is valid and describes a UDP broadcast to port 514
  * * the UDP payload matches the expected string
  *
  * After testing the pointer to the expected string is set to NULL to signal

---
base-commit: 964ad5b5c91b7be56e443e899d7f873e6aa8c9fc
change-id: 20260825-lwip-syslog-v1-a5625eba2ea3

Best regards,
--  
James Hilliard <[email protected]>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.