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
_______________________________________________
gPXE-devel mailing list
[email protected]
http://etherboot.org/mailman/listinfo/gpxe-devel

Reply via email to