[gPXE-devel] [PATCH] Check IPv4 destination address

Faur Andrei da3drus at gmail.com
Wed Apr 14 16:46:11 EDT 2010


Hello,

The following patch is an attempt to check the destination address
of incoming IPv4 packets and match it against the current NIC's address
or a series of allowed (unfiltered) addresses. Hopefully it will provide
a starting point for a more complete solution. The context :
http://support.etherboot.org/index.php?do=details&task_id=79&project=1&pagenum=2

---
 src/include/gpxe/ip.h |   11 +++++++++++
 src/net/ipv4.c        |   35 +++++++++++++++++++++++++++++++++++
 src/net/udp/tftp.c    |    6 ++++++
 3 files changed, 52 insertions(+), 0 deletions(-)

diff --git a/src/include/gpxe/ip.h b/src/include/gpxe/ip.h
index 4342a0c..e97dcf7 100644
--- a/src/include/gpxe/ip.h
+++ b/src/include/gpxe/ip.h
@@ -58,6 +58,15 @@ struct ipv4_pseudo_header {
 	uint16_t len;
 };

+/** An allowed IPv4 addresses list */
+struct ipv4_unfiltered_addr {
+	/** List of IPv4 addresses */
+	struct list_head list;
+
+	/** IPv4 address */
+	struct in_addr address;
+};
+
 /** An IPv4 address/routing table entry */
 struct ipv4_miniroute {
 	/** List of miniroutes */
@@ -94,4 +103,6 @@ extern struct list_head ipv4_miniroutes;

 extern struct net_protocol ipv4_protocol;

+extern struct list_head unfilt_addresses;
+
 #endif /* _GPXE_IP_H */
diff --git a/src/net/ipv4.c b/src/net/ipv4.c
index 7a8ddd3..317a2f5 100644
--- a/src/net/ipv4.c
+++ b/src/net/ipv4.c
@@ -34,6 +34,27 @@ struct list_head ipv4_miniroutes = LIST_HEAD_INIT (
ipv4_miniroutes );
 /** List of fragment reassembly buffers */
 static LIST_HEAD ( frag_buffers );

+/** List of unfiltered IP addresses **/
+struct list_head unfilt_addresses = LIST_HEAD_INIT ( unfilt_addresses );
+
+/**
+ * Check filtering list to see if incoming address matches one of them
+ *
+ * @v address		Incoming packet's destination address
+ * @ret addr		1 if address matches, 0 if not
+ */
+static int
+check_unfiltered_list ( struct in_addr address ) {
+	struct ipv4_unfiltered_addr *addr;
+
+	list_for_each_entry ( addr, &unfilt_addresses, list ) {
+		if ( addr->address.s_addr == address.s_addr )
+			return 1;
+	}
+
+	return 0;
+}
+
 /**
  * Add IPv4 minirouting table entry
  *
@@ -384,6 +405,8 @@ static int ipv4_tx ( struct io_buffer *iobuf,
 static int ipv4_rx ( struct io_buffer *iobuf, struct net_device
*netdev __unused,
 		     const void *ll_source __unused ) {
 	struct iphdr *iphdr = iobuf->data;
+	struct settings *settings;
+	struct in_addr address = { 0 };
 	size_t hdrlen;
 	size_t len;
 	union {
@@ -432,6 +455,18 @@ static int ipv4_rx ( struct io_buffer *iobuf,
struct net_device *netdev __unused
 		goto err;
 	}

+	/* Check if received packet is destined to us or unfiltered */
+	settings = netdev_settings ( netdev );
+	fetch_ipv4_setting ( settings, &ip_setting, &address );
+	//DBG ( "%x %x\n", iphdr->dest.s_addr, address.s_addr );
+	if ( ( address.s_addr != 0 ) &&
+	     ( iphdr->dest.s_addr != address.s_addr ) &&
+	     ( check_unfiltered_list ( iphdr->dest ) ) ) {
+		DBG ( "Destination address %s is not local address %s\n",
+		      inet_ntoa ( iphdr->dest ), inet_ntoa ( address ) );
+		goto err;
+	}
+
 	/* Print IPv4 header for debugging */
 	DBG ( "IPv4 RX %s<-", inet_ntoa ( iphdr->dest ) );
 	DBG ( "%s len %d proto %d id %04x csum %04x\n",
diff --git a/src/net/udp/tftp.c b/src/net/udp/tftp.c
index 3de2fb9..50bba12 100644
--- a/src/net/udp/tftp.c
+++ b/src/net/udp/tftp.c
@@ -38,6 +38,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #include <gpxe/dhcp.h>
 #include <gpxe/uri.h>
 #include <gpxe/tftp.h>
+#include <gpxe/ip.h>

 /** @file
  *
@@ -1105,6 +1106,7 @@ static int tftp_core_open ( struct
xfer_interface *xfer, struct uri *uri,
 			    struct sockaddr *multicast,
 			    unsigned int flags ) {
 	struct tftp_request *tftp;
+	struct ipv4_unfiltered_addr *addr;
 	int rc;

 	/* Sanity checks */
@@ -1136,6 +1138,10 @@ static int tftp_core_open ( struct
xfer_interface *xfer, struct uri *uri,
 	if ( multicast ) {
 		if ( ( rc = tftp_reopen_mc ( tftp, multicast ) ) != 0 )
 			goto err;
+		/* Add MTFTP address to unfiltered list */
+		addr = malloc ( sizeof ( *addr ) );
+		addr->address.s_addr = 0xefff0101;
+		list_add ( &addr->list, &unfilt_addresses );
 	}

 	/* Start timer to initiate RRQ */
-- 
1.6.3.3


More information about the gPXE-devel mailing list