aboutsummaryrefslogtreecommitdiffstats
path: root/src/l2_packet
diff options
context:
space:
mode:
authorKyeyoon Park <kyeyoonp@qca.qualcomm.com>2014-09-08 21:27:11 (GMT)
committerJouni Malinen <j@w1.fi>2014-10-27 23:08:29 (GMT)
commit7d20dd66f3c7eab7c9107816161342e9f6dc22ba (patch)
tree7077fabbaf0d54a98d1004ee8ae58e0a52cb3e67 /src/l2_packet
parent5e29a9007946fe9309ffb9c4eff673f95f82af08 (diff)
downloadhostap-7d20dd66f3c7eab7c9107816161342e9f6dc22ba.zip
hostap-7d20dd66f3c7eab7c9107816161342e9f6dc22ba.tar.gz
hostap-7d20dd66f3c7eab7c9107816161342e9f6dc22ba.tar.bz2
l2_packet: Add support for DHCP packet filter in l2_packet_linux
Signed-off-by: Kyeyoon Park <kyeyoonp@qca.qualcomm.com>
Diffstat (limited to 'src/l2_packet')
-rw-r--r--src/l2_packet/l2_packet.h16
-rw-r--r--src/l2_packet/l2_packet_freebsd.c7
-rw-r--r--src/l2_packet/l2_packet_linux.c52
-rw-r--r--src/l2_packet/l2_packet_ndis.c7
-rw-r--r--src/l2_packet/l2_packet_none.c7
-rw-r--r--src/l2_packet/l2_packet_pcap.c7
-rw-r--r--src/l2_packet/l2_packet_privsep.c7
7 files changed, 103 insertions, 0 deletions
diff --git a/src/l2_packet/l2_packet.h b/src/l2_packet/l2_packet.h
index dd825b5..f391f36 100644
--- a/src/l2_packet/l2_packet.h
+++ b/src/l2_packet/l2_packet.h
@@ -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 */
diff --git a/src/l2_packet/l2_packet_freebsd.c b/src/l2_packet/l2_packet_freebsd.c
index 2e9a04c..d87c32b 100644
--- a/src/l2_packet/l2_packet_freebsd.c
+++ b/src/l2_packet/l2_packet_freebsd.c
@@ -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;
+}
diff --git a/src/l2_packet/l2_packet_linux.c b/src/l2_packet/l2_packet_linux.c
index 1419830..fcbf7e0 100644
--- a/src/l2_packet/l2_packet_linux.c
+++ b/src/l2_packet/l2_packet_linux.c
@@ -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;
+}
diff --git a/src/l2_packet/l2_packet_ndis.c b/src/l2_packet/l2_packet_ndis.c
index 23b8ddc..39a62a0 100644
--- a/src/l2_packet/l2_packet_ndis.c
+++ b/src/l2_packet/l2_packet_ndis.c
@@ -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;
+}
diff --git a/src/l2_packet/l2_packet_none.c b/src/l2_packet/l2_packet_none.c
index 6896c4e..0501925 100644
--- a/src/l2_packet/l2_packet_none.c
+++ b/src/l2_packet/l2_packet_none.c
@@ -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;
+}
diff --git a/src/l2_packet/l2_packet_pcap.c b/src/l2_packet/l2_packet_pcap.c
index 45aef56..f064172 100644
--- a/src/l2_packet/l2_packet_pcap.c
+++ b/src/l2_packet/l2_packet_pcap.c
@@ -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;
+}
diff --git a/src/l2_packet/l2_packet_privsep.c b/src/l2_packet/l2_packet_privsep.c
index 6b117ca..8b95247 100644
--- a/src/l2_packet/l2_packet_privsep.c
+++ b/src/l2_packet/l2_packet_privsep.c
@@ -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;
+}