wpa_supplicant: wired driver

Edgar E. Iglesias edgar.iglesias at axis.com
Mon Sep 19 09:46:58 EDT 2005


On Sat, Sep 17, 2005 at 05:57:18PM -0700, Jouni Malinen wrote:
> On Thu, Sep 15, 2005 at 03:25:20PM +0200, Cristian Ionescu-Idbohrn wrote:
> 
> > I'm trying to use wpa_supplicant, the wired driver, EAP-TLS.
> > I've got it working, but also discovered (I think) a small glitch.
> > I have to set the nic in promiscuous mode, else it won't see the
> > 802.1x frames sent by the switch the nic is connected to.
> 
> Which kernel version and which driver are you using?
> 
> > My understanding is that both wpa_supplicant and the switch send their
> > frames to the multicast address 01:80:c2:00:00:03. wpa_supplicant
> > misses frames comming from the switch, like:
> 
> That's correct.
> 
> > unless the nic in the supplicant side is set in promiscuous mode or
> > wpa_supplicant requires PACKET_ADD_MEMBERSHIP with setsockopt.
> > 
> > I'd like to skip the promiscuous mode stuff. Can anyone point me to what
> > (and maybe where) I need to add a small hack.
> 
> For some reason, all my test systems work without doing this. Anyway,
> PACKET_ADD_MEMBERSHIP is indeed what should be done on Linux (and
> SIOCADDMULTI on BSD). I modified driver_wired.c to do this. I haven't
> been able to verify whether this actually works since my test
> configurations work with and without these modifications.
> 
> I would appreciate it if you could take the modified version of
> driver_wired.c from my CVS repository (or a full devel snapshot, for
> that maetter) and let me know whether it resolves this issue in your
> setup.
> 

Hi,

Linux will drop the multicast memberships when the sockets that added them are
not around anymore. We need to keep the pf-socket alive as long as we have 
active memberships. The BSD ioctl's are ok in CVS.

This patch fixes the issue on linux.

Best regards
-- 
        Programmer
        Edgar E. Iglesias <edgar at axis.com> 46.46.272.1946

Index: driver_wired.c
===================================================================
RCS file: /cvs/hostap/wpa_supplicant/driver_wired.c,v
retrieving revision 1.3
diff -b -u -r1.3 driver_wired.c
--- driver_wired.c	18 Sep 2005 00:53:30 -0000	1.3
+++ driver_wired.c	18 Sep 2005 16:25:23 -0000
@@ -33,6 +33,7 @@
 
 struct wpa_driver_wired_data {
 	void *ctx;
+	int pf_sock;
 	char ifname[IFNAMSIZ + 1];
 	int membership, multi, iff_allmulti, iff_up;
 };
@@ -133,42 +134,28 @@
 }
 
 
-static int wpa_driver_wired_membership(const char *ifname, const u8 *addr,
+static int wpa_driver_wired_membership(struct wpa_driver_wired_data *drv,
+				       const u8 *addr,
 				       int add)
 {
 #ifdef __linux__
-	int s;
-	struct ifreq ifr;
 	struct packet_mreq mreq;
 
-	s = socket(PF_PACKET, SOCK_DGRAM, 0);
-	if (s < 0) {
-		perror("socket(PF_PACKET)");
-		return -1;
-	}
-
-	memset(&ifr, 0, sizeof(ifr));
-	strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
-	if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
-		close(s);
+	if (drv->pf_sock == -1)
 		return -1;
-	}
 
 	memset(&mreq, 0, sizeof(mreq));
-	mreq.mr_ifindex = ifr.ifr_ifindex;
+	mreq.mr_ifindex = if_nametoindex(drv->ifname);
 	mreq.mr_type = PACKET_MR_MULTICAST;
 	mreq.mr_alen = ETH_ALEN;
 	memcpy(mreq.mr_address, addr, ETH_ALEN);
 
-	if (setsockopt(s, SOL_PACKET,
+	if (setsockopt(drv->pf_sock, SOL_PACKET,
 		       add ? PACKET_ADD_MEMBERSHIP : PACKET_DROP_MEMBERSHIP,
 		       &mreq, sizeof(mreq)) < 0) {
 		perror("setsockopt");
-		close(s);
 		return -1;
 	}
-
-	close(s);
 	return 0;
 #else /* __linux__ */
 	return -1;
@@ -188,13 +175,24 @@
 	strncpy(drv->ifname, ifname, sizeof(drv->ifname));
 	drv->ctx = ctx;
 
+#ifdef __linux__
+	if (drv->pf_sock == -1) {
+		drv->pf_sock = socket(PF_PACKET, SOCK_DGRAM, 0);
+		if (drv->pf_sock < 0) {
+			perror("socket(PF_PACKET)");
+		}
+	}
+#else
+	drv->pf_sock = -1;       
+#endif
+	
 	if (wpa_driver_wired_get_ifflags(ifname, &flags) == 0 &&
 	    !(flags & IFF_UP) &&
 	    wpa_driver_wired_set_ifflags(ifname, flags | IFF_UP) == 0) {
 		drv->iff_up = 1;
 	}
 
-	if (wpa_driver_wired_membership(ifname, pae_group_addr, 1) == 0) {
+	if (wpa_driver_wired_membership(drv, pae_group_addr, 1) == 0) {
 		wpa_printf(MSG_DEBUG, "%s: Added multicast membership with "
 			   "packet socket", __func__);
 		drv->membership = 1;
@@ -232,7 +230,7 @@
 	int flags;
 
 	if (drv->membership &&
-	    wpa_driver_wired_membership(drv->ifname, pae_group_addr, 0) < 0) {
+	    wpa_driver_wired_membership(drv, pae_group_addr, 0) < 0) {
 		wpa_printf(MSG_DEBUG, "%s: Failed to remove PAE multicast "
 			   "group (PACKET)", __func__);
 	}
@@ -259,6 +257,9 @@
 			   __func__);
 	}
 
+	if (drv->pf_sock != -1)
+		close(drv->pf_sock);
+	
 	free(drv);
 }
 



More information about the HostAP mailing list