]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
l2_packet: Add support for DHCP packet filter in l2_packet_linux
authorKyeyoon Park <kyeyoonp@qca.qualcomm.com>
Mon, 8 Sep 2014 21:27:11 +0000 (14:27 -0700)
committerJouni Malinen <j@w1.fi>
Mon, 27 Oct 2014 23:08:29 +0000 (01:08 +0200)
Signed-off-by: Kyeyoon Park <kyeyoonp@qca.qualcomm.com>
src/l2_packet/l2_packet.h
src/l2_packet/l2_packet_freebsd.c
src/l2_packet/l2_packet_linux.c
src/l2_packet/l2_packet_ndis.c
src/l2_packet/l2_packet_none.c
src/l2_packet/l2_packet_pcap.c
src/l2_packet/l2_packet_privsep.c

index dd825b56894df230ee878e3bdfa64759a0e1d6b5..f391f3682aa00af314747346cb01941ec636eb8d 100644 (file)
@@ -39,6 +39,10 @@ struct l2_ethhdr {
 #pragma pack(pop)
 #endif /* _MSC_VER */
 
+enum l2_packet_filter_type {
+       L2_PACKET_FILTER_DHCP,
+};
+
 /**
  * l2_packet_init - Initialize l2_packet interface
  * @ifname: Interface name
@@ -121,4 +125,16 @@ int l2_packet_get_ip_addr(struct l2_packet_data *l2, char *buf, size_t len);
  */
 void l2_packet_notify_auth_start(struct l2_packet_data *l2);
 
+/**
+ * l2_packet_set_packet_filter - Set socket filter for l2_packet
+ * @l2: Pointer to internal l2_packet data from l2_packet_init()
+ * @type: enum l2_packet_filter_type, type of filter
+ * Returns: 0 on success, -1 on failure
+ *
+ * This function is used to set the socket filter for l2_packet socket.
+ *
+ */
+int l2_packet_set_packet_filter(struct l2_packet_data *l2,
+                               enum l2_packet_filter_type type);
+
 #endif /* L2_PACKET_H */
index 2e9a04c8943c496c48943c9b154e9b8cd7a0d715..d87c32b2cc40d4e64a2d35227fb0d4d285c62b17 100644 (file)
@@ -308,3 +308,10 @@ int l2_packet_get_ip_addr(struct l2_packet_data *l2, char *buf, size_t len)
 void l2_packet_notify_auth_start(struct l2_packet_data *l2)
 {
 }
+
+
+int l2_packet_set_packet_filter(struct l2_packet_data *l2,
+                               enum l2_packet_filter_type type)
+{
+       return -1;
+}
index 1419830db7ac5163e8214757763980115568e807..fcbf7e040fe92f936c9e566f6908fbcb19b3d90c 100644 (file)
@@ -10,6 +10,7 @@
 #include <sys/ioctl.h>
 #include <netpacket/packet.h>
 #include <net/if.h>
+#include <linux/filter.h>
 
 #include "common.h"
 #include "eloop.h"
@@ -28,6 +29,32 @@ struct l2_packet_data {
                     * buffers */
 };
 
+/* Generated by 'sudo tcpdump -s 3000 -dd greater 278 and ip and udp and
+ * src port bootps and dst port bootpc'
+ */
+static struct sock_filter dhcp_sock_filter_insns[] = {
+       { 0x80, 0, 0, 0x00000000 },
+       { 0x35, 0, 12, 0x00000116 },
+       { 0x28, 0, 0, 0x0000000c },
+       { 0x15, 0, 10, 0x00000800 },
+       { 0x30, 0, 0, 0x00000017 },
+       { 0x15, 0, 8, 0x00000011 },
+       { 0x28, 0, 0, 0x00000014 },
+       { 0x45, 6, 0, 0x00001fff },
+       { 0xb1, 0, 0, 0x0000000e },
+       { 0x48, 0, 0, 0x0000000e },
+       { 0x15, 0, 3, 0x00000043 },
+       { 0x48, 0, 0, 0x00000010 },
+       { 0x15, 0, 1, 0x00000044 },
+       { 0x6, 0, 0, 0x00000bb8 },
+       { 0x6, 0, 0, 0x00000000 },
+};
+
+static const struct sock_fprog dhcp_sock_filter = {
+       .len = ARRAY_SIZE(dhcp_sock_filter_insns),
+       .filter = dhcp_sock_filter_insns,
+};
+
 
 int l2_packet_get_own_addr(struct l2_packet_data *l2, u8 *addr)
 {
@@ -202,3 +229,28 @@ int l2_packet_get_ip_addr(struct l2_packet_data *l2, char *buf, size_t len)
 void l2_packet_notify_auth_start(struct l2_packet_data *l2)
 {
 }
+
+
+int l2_packet_set_packet_filter(struct l2_packet_data *l2,
+                               enum l2_packet_filter_type type)
+{
+       const struct sock_fprog *sock_filter;
+
+       switch (type) {
+       case L2_PACKET_FILTER_DHCP:
+               sock_filter = &dhcp_sock_filter;
+               break;
+       default:
+               return -1;
+       }
+
+       if (setsockopt(l2->fd, SOL_SOCKET, SO_ATTACH_FILTER,
+                      sock_filter, sizeof(struct sock_fprog))) {
+               wpa_printf(MSG_ERROR,
+                          "l2_packet_linux: setsockopt(SO_ATTACH_FILTER) failed: %s",
+                          strerror(errno));
+               return -1;
+       }
+
+       return 0;
+}
index 23b8ddcc9e3613f6632c59ccd12b95c150904719..39a62a0abe7fb9e9239b15125cf42364f1715ffd 100644 (file)
@@ -514,3 +514,10 @@ int l2_packet_get_ip_addr(struct l2_packet_data *l2, char *buf, size_t len)
 void l2_packet_notify_auth_start(struct l2_packet_data *l2)
 {
 }
+
+
+int l2_packet_set_packet_filter(struct l2_packet_data *l2,
+                               enum l2_packet_filter_type type)
+{
+       return -1;
+}
index 6896c4e4e5cad53d08946195616426f3f2b6f6ec..0501925c6c0763e4b0a59786545d1eff6ab3460a 100644 (file)
@@ -116,3 +116,10 @@ void l2_packet_notify_auth_start(struct l2_packet_data *l2)
 {
        /* This function can be left empty */
 }
+
+
+int l2_packet_set_packet_filter(struct l2_packet_data *l2,
+                               enum l2_packet_filter_type type)
+{
+       return -1;
+}
index 45aef56bcdbd89870331bf6ce0d0c99f85295055..f06417254380f7652fb15331d6362ff23074455b 100644 (file)
@@ -378,3 +378,10 @@ void l2_packet_notify_auth_start(struct l2_packet_data *l2)
                               l2, l2->pcap);
 #endif /* CONFIG_WINPCAP */
 }
+
+
+int l2_packet_set_packet_filter(struct l2_packet_data *l2,
+                               enum l2_packet_filter_type type)
+{
+       return -1;
+}
index 6b117ca2b9076709d3840d06924b363908ce6612..8b952476225f1c36d667fcfee1dcca97957a0858 100644 (file)
@@ -259,3 +259,10 @@ void l2_packet_notify_auth_start(struct l2_packet_data *l2)
 {
        wpa_priv_cmd(l2, PRIVSEP_CMD_L2_NOTIFY_AUTH_START, NULL, 0);
 }
+
+
+int l2_packet_set_packet_filter(struct l2_packet_data *l2,
+                               enum l2_packet_filter_type type)
+{
+       return -1;
+}