View | Details | Raw Unified | Return to bug 264238 | Differences between
and this patch

Collapse All | Expand All

(-)b/contrib/wpa/src/drivers/driver_bsd.c (-315 / +302 lines)
Lines 9-14 Link Here
9
9
10
#include "includes.h"
10
#include "includes.h"
11
#include <sys/ioctl.h>
11
#include <sys/ioctl.h>
12
#include <sys/sysctl.h>
12
13
13
#include "common.h"
14
#include "common.h"
14
#include "driver.h"
15
#include "driver.h"
Lines 16-24 Link Here
16
#include "common/ieee802_11_defs.h"
17
#include "common/ieee802_11_defs.h"
17
#include "common/wpa_common.h"
18
#include "common/wpa_common.h"
18
19
19
#include <ifaddrs.h>
20
#include <net/if.h>
20
#include <net/if.h>
21
#include <net/if_dl.h>
22
#include <net/if_media.h>
21
#include <net/if_media.h>
23
22
24
#ifdef __NetBSD__
23
#ifdef __NetBSD__
Lines 52-70 struct bsd_driver_global { Link Here
52
	void		*ctx;
51
	void		*ctx;
53
	int		sock;			/* socket for 802.11 ioctls */
52
	int		sock;			/* socket for 802.11 ioctls */
54
	int		route;			/* routing socket for events */
53
	int		route;			/* routing socket for events */
54
	char		*event_buf;
55
	size_t		event_buf_len;
55
	struct dl_list	ifaces;			/* list of interfaces */
56
	struct dl_list	ifaces;			/* list of interfaces */
56
};
57
};
57
58
58
struct bsd_driver_data {
59
struct bsd_driver_data {
59
	struct dl_list	list;
60
	struct dl_list	list;
60
	struct bsd_driver_global *global;
61
	struct bsd_driver_global *global;
61
	void	*ctx;
62
	struct hostapd_data *hapd;	/* back pointer */
62
63
63
	struct l2_packet_data *sock_xmit;/* raw packet xmit socket */
64
	struct l2_packet_data *sock_xmit;/* raw packet xmit socket */
64
	char	ifname[IFNAMSIZ+1];	/* interface name */
65
	char	ifname[IFNAMSIZ+1];	/* interface name */
65
	int	flags;
66
	int	flags;
66
	unsigned int ifindex;		/* interface index */
67
	unsigned int ifindex;		/* interface index */
67
	int	if_removed;		/* has the interface been removed? */
68
	int	if_removed;		/* has the interface been removed? */
69
	void	*ctx;
68
	struct wpa_driver_capa capa;	/* driver capability */
70
	struct wpa_driver_capa capa;	/* driver capability */
69
	int	is_ap;			/* Access point mode */
71
	int	is_ap;			/* Access point mode */
70
	int	prev_roaming;	/* roaming state to restore on deinit */
72
	int	prev_roaming;	/* roaming state to restore on deinit */
Lines 88-93 bsd_get_drvindex(void *priv, unsigned int ifindex) Link Here
88
	return NULL;
90
	return NULL;
89
}
91
}
90
92
93
#ifndef HOSTAPD
91
static struct bsd_driver_data *
94
static struct bsd_driver_data *
92
bsd_get_drvname(void *priv, const char *ifname)
95
bsd_get_drvname(void *priv, const char *ifname)
93
{
96
{
Lines 100-105 bsd_get_drvname(void *priv, const char *ifname) Link Here
100
	}
103
	}
101
	return NULL;
104
	return NULL;
102
}
105
}
106
#endif /* HOSTAPD */
103
107
104
static int
108
static int
105
bsd_set80211(void *priv, int op, int val, const void *arg, int arg_len)
109
bsd_set80211(void *priv, int op, int val, const void *arg, int arg_len)
Lines 139-147 bsd_get80211(void *priv, struct ieee80211req *ireq, int op, void *arg, Link Here
139
	ireq->i_data = arg;
143
	ireq->i_data = arg;
140
144
141
	if (ioctl(drv->global->sock, SIOCG80211, ireq) < 0) {
145
	if (ioctl(drv->global->sock, SIOCG80211, ireq) < 0) {
142
		int level = drv->if_removed ? MSG_DEBUG : MSG_ERROR;
146
		wpa_printf(MSG_ERROR, "ioctl[SIOCG80211, op=%u, "
143
144
		wpa_printf(level, "ioctl[SIOCG80211, op=%u, "
145
			   "arg_len=%u]: %s", op, arg_len, strerror(errno));
147
			   "arg_len=%u]: %s", op, arg_len, strerror(errno));
146
		return -1;
148
		return -1;
147
	}
149
	}
Lines 293-300 bsd_send_mlme_param(void *priv, const u8 op, const u16 reason, const u8 *addr) Link Here
293
}
295
}
294
296
295
static int
297
static int
296
bsd_get_iface_flags(struct bsd_driver_data *drv)
298
bsd_ctrl_iface(void *priv, int enable)
297
{
299
{
300
	struct bsd_driver_data *drv = priv;
298
	struct ifreq ifr;
301
	struct ifreq ifr;
299
302
300
	os_memset(&ifr, 0, sizeof(ifr));
303
	os_memset(&ifr, 0, sizeof(ifr));
Lines 305-329 bsd_get_iface_flags(struct bsd_driver_data *drv) Link Here
305
			   strerror(errno));
308
			   strerror(errno));
306
		return -1;
309
		return -1;
307
	}
310
	}
311
	drv->flags = ifr.ifr_flags;
312
313
	if (enable) {
314
		if (ifr.ifr_flags & IFF_UP)
315
			return 0;
316
		ifr.ifr_flags |= IFF_UP;
317
	} else {
318
		if (!(ifr.ifr_flags & IFF_UP))
319
			return 0;
320
		ifr.ifr_flags &= ~IFF_UP;
321
	}
322
323
	if (ioctl(drv->global->sock, SIOCSIFFLAGS, &ifr) < 0) {
324
		wpa_printf(MSG_ERROR, "ioctl[SIOCSIFFLAGS]: %s",
325
			   strerror(errno));
326
		return -1;
327
	}
328
308
	drv->flags = ifr.ifr_flags;
329
	drv->flags = ifr.ifr_flags;
309
	return 0;
330
	return 0;
310
}
331
}
311
332
312
static int
333
static int
313
bsd_set_key(void *priv, struct wpa_driver_set_key_params *params)
334
bsd_set_key(const char *ifname, void *priv, enum wpa_alg alg,
335
	    const unsigned char *addr, int key_idx, int set_tx, const u8 *seq,
336
	    size_t seq_len, const u8 *key, size_t key_len)
314
{
337
{
315
	struct ieee80211req_key wk;
338
	struct ieee80211req_key wk;
316
#ifdef IEEE80211_KEY_NOREPLAY
339
#ifdef IEEE80211_KEY_NOREPLAY
317
	struct bsd_driver_data *drv = priv;
340
	struct bsd_driver_data *drv = priv;
318
#endif /* IEEE80211_KEY_NOREPLAY */
341
#endif /* IEEE80211_KEY_NOREPLAY */
319
	enum wpa_alg alg = params->alg;
320
	const u8 *addr = params->addr;
321
	int key_idx = params->key_idx;
322
	int set_tx = params->set_tx;
323
	const u8 *seq = params->seq;
324
	size_t seq_len = params->seq_len;
325
	const u8 *key = params->key;
326
	size_t key_len = params->key_len;
327
342
328
	wpa_printf(MSG_DEBUG, "%s: alg=%d addr=%p key_idx=%d set_tx=%d "
343
	wpa_printf(MSG_DEBUG, "%s: alg=%d addr=%p key_idx=%d set_tx=%d "
329
		   "seq_len=%zu key_len=%zu", __func__, alg, addr, key_idx,
344
		   "seq_len=%zu key_len=%zu", __func__, alg, addr, key_idx,
Lines 525-531 bsd_set_ieee8021x(void *priv, struct wpa_bss_params *params) Link Here
525
			   __func__);
540
			   __func__);
526
		return -1;
541
		return -1;
527
	}
542
	}
528
	return 0;
543
	return bsd_ctrl_iface(priv, 1);
529
}
544
}
530
545
531
static void
546
static void
Lines 580-592 bsd_set_freq(void *priv, struct hostapd_freq_params *freq) Link Here
580
595
581
	if (channel < 14) {
596
	if (channel < 14) {
582
		mode =
597
		mode =
598
#ifdef CONFIG_IEEE80211N
583
			freq->ht_enabled ? IFM_IEEE80211_11NG :
599
			freq->ht_enabled ? IFM_IEEE80211_11NG :
584
			IFM_IEEE80211_11G;
600
#endif /* CONFIG_IEEE80211N */
601
		        IFM_IEEE80211_11G;
585
	} else if (channel == 14) {
602
	} else if (channel == 14) {
586
		mode = IFM_IEEE80211_11B;
603
		mode = IFM_IEEE80211_11B;
587
	} else {
604
	} else {
588
		mode =
605
		mode =
606
#ifdef CONFIG_IEEE80211N
589
			freq->ht_enabled ? IFM_IEEE80211_11NA :
607
			freq->ht_enabled ? IFM_IEEE80211_11NA :
608
#endif /* CONFIG_IEEE80211N */
590
			IFM_IEEE80211_11A;
609
			IFM_IEEE80211_11A;
591
	}
610
	}
592
	if (bsd_set_mediaopt(drv, IFM_MMASK, mode) < 0) {
611
	if (bsd_set_mediaopt(drv, IFM_MMASK, mode) < 0) {
Lines 617-878 bsd_set_opt_ie(void *priv, const u8 *ie, size_t ie_len) Link Here
617
	return 0;
636
	return 0;
618
}
637
}
619
638
620
#ifdef SO_RERROR
639
static size_t
621
static void
640
rtbuf_len(void)
622
bsd_route_overflow(int sock, void *ctx, struct bsd_driver_global *global)
623
{
641
{
624
	char event_buf[2048]; /* max size of a single route(4) msg */
642
	size_t len;
625
	int n;
626
	struct ifaddrs *ifaddrs, *ifa;
627
	struct bsd_driver_data *drv;
628
	struct sockaddr_dl *sdl;
629
	union wpa_event_data event;
630
631
	/* We need to match the system state, so drain the route
632
	 * socket to avoid stale messages. */
633
	do {
634
		n = read(sock, event_buf, sizeof(event_buf));
635
	} while (n != -1 || errno == ENOBUFS);
636
637
	if (getifaddrs(&ifaddrs) == -1) {
638
		wpa_printf(MSG_ERROR, "%s getifaddrs() failed: %s",
639
			   __func__, strerror(errno));
640
		return;
641
	}
642
643
	/* add or update existing interfaces */
644
	for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
645
		if (ifa->ifa_addr == NULL ||
646
		    ifa->ifa_addr->sa_family != AF_LINK)
647
			continue;
648
		sdl = (struct sockaddr_dl *) (void *) ifa->ifa_addr;
649
		drv = bsd_get_drvname(global, ifa->ifa_name);
650
		if (drv != NULL &&
651
		    (drv->ifindex != sdl->sdl_index || drv->if_removed)) {
652
			wpa_printf(MSG_DEBUG,
653
				   "RTM_IFANNOUNCE: Interface '%s' added",
654
				   drv->ifname);
655
			drv->ifindex = sdl->sdl_index;
656
			drv->if_removed = 0;
657
			event.interface_status.ievent = EVENT_INTERFACE_ADDED;
658
			os_strlcpy(event.interface_status.ifname, ifa->ifa_name,
659
				   sizeof(event.interface_status.ifname));
660
			wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS,
661
					     &event);
662
		}
663
		if (!drv &&
664
		    (drv = bsd_get_drvindex(global, sdl->sdl_index)) != NULL) {
665
			/* Driver name is invalid */
666
			wpa_printf(MSG_DEBUG,
667
				   "RTM_IFANNOUNCE: Interface '%s' removed",
668
				   drv->ifname);
669
			drv->if_removed = 1;
670
			event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
671
			os_strlcpy(event.interface_status.ifname, drv->ifname,
672
				   sizeof(event.interface_status.ifname));
673
			wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS,
674
					     &event);
675
		}
676
	}
677
643
678
	/* punt missing interfaces and update flags */
644
	int mib[6] = {CTL_NET, AF_ROUTE, 0, AF_INET, NET_RT_DUMP, 0};
679
	dl_list_for_each(drv, &global->ifaces, struct bsd_driver_data, list) {
680
		for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
681
			if (ifa->ifa_addr == NULL ||
682
			    ifa->ifa_addr->sa_family != AF_LINK)
683
				continue;
684
			sdl = (struct sockaddr_dl *) (void *) ifa->ifa_addr;
685
			if (os_strcmp(drv->ifname, ifa->ifa_name) == 0)
686
				break;
687
		}
688
		if (ifa == NULL && !drv->if_removed) {
689
			wpa_printf(MSG_DEBUG,
690
				   "RTM_IFANNOUNCE: Interface '%s' removed",
691
				   drv->ifname);
692
			drv->if_removed = 1;
693
			event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
694
			os_strlcpy(event.interface_status.ifname, drv->ifname,
695
				   sizeof(event.interface_status.ifname));
696
			wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS,
697
					     &event);
698
		}
699
		if (!ifa)
700
			continue;
701
645
702
		if ((ifa->ifa_flags & IFF_UP) == 0 &&
646
	if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
703
		    (drv->flags & IFF_UP) != 0) {
647
		wpa_printf(MSG_WARNING, "%s failed: %s", __func__,
704
			wpa_printf(MSG_DEBUG, "RTM_IFINFO: Interface '%s' DOWN",
648
			   strerror(errno));
705
				   drv->ifname);
649
		len = 2048;
706
			wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_DISABLED,
707
					     NULL);
708
		} else if ((ifa->ifa_flags & IFF_UP) != 0 &&
709
			   (drv->flags & IFF_UP) == 0) {
710
			wpa_printf(MSG_DEBUG, "RTM_IFINFO: Interface '%s' UP",
711
				   drv->ifname);
712
			wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED,
713
					     NULL);
714
		}
715
		drv->flags = ifa->ifa_flags;
716
	}
717
718
	freeifaddrs(ifaddrs);
719
}
720
#endif /* SO_RERROR */
721
722
static void
723
bsd_wireless_event_receive(int sock, void *ctx, void *sock_ctx)
724
{
725
	char event_buf[2048]; /* max size of a single route(4) msg */
726
	struct bsd_driver_global *global = sock_ctx;
727
	struct bsd_driver_data *drv;
728
	struct if_announcemsghdr *ifan;
729
	struct if_msghdr *ifm;
730
	struct rt_msghdr *rtm;
731
	union wpa_event_data event;
732
	struct ieee80211_michael_event *mic;
733
	struct ieee80211_leave_event *leave;
734
	struct ieee80211_join_event *join;
735
	int n;
736
737
	n = read(sock, event_buf, sizeof(event_buf));
738
	if (n < 0) {
739
		if (errno != EINTR && errno != EAGAIN)
740
			wpa_printf(MSG_ERROR, "%s read() failed: %s",
741
				   __func__, strerror(errno));
742
#ifdef SO_RERROR
743
		if (errno == ENOBUFS)
744
			bsd_route_overflow(sock, ctx, sock_ctx);
745
#endif /* SO_RERROR */
746
		return;
747
	}
650
	}
748
651
749
	rtm = (struct rt_msghdr *) event_buf;
652
	return len;
750
	if (rtm->rtm_version != RTM_VERSION) {
751
		wpa_printf(MSG_DEBUG, "Invalid routing message version=%d",
752
			   rtm->rtm_version);
753
		return;
754
	}
755
	os_memset(&event, 0, sizeof(event));
756
	switch (rtm->rtm_type) {
757
	case RTM_IEEE80211:
758
		ifan = (struct if_announcemsghdr *) rtm;
759
		drv = bsd_get_drvindex(global, ifan->ifan_index);
760
		if (drv == NULL)
761
			return;
762
		switch (ifan->ifan_what) {
763
		case RTM_IEEE80211_ASSOC:
764
		case RTM_IEEE80211_REASSOC:
765
			if (drv->is_ap)
766
				break;
767
			wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL);
768
			break;
769
		case RTM_IEEE80211_DISASSOC:
770
			if (drv->is_ap)
771
				break;
772
			wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);
773
			break;
774
		case RTM_IEEE80211_SCAN:
775
			if (drv->is_ap)
776
				break;
777
			wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS,
778
					     NULL);
779
			break;
780
		case RTM_IEEE80211_LEAVE:
781
			leave = (struct ieee80211_leave_event *) &ifan[1];
782
			drv_event_disassoc(drv->ctx, leave->iev_addr);
783
			break;
784
		case RTM_IEEE80211_JOIN:
785
#ifdef RTM_IEEE80211_REJOIN
786
		case RTM_IEEE80211_REJOIN:
787
#endif
788
			join = (struct ieee80211_join_event *) &ifan[1];
789
			bsd_new_sta(drv, drv->ctx, join->iev_addr);
790
			break;
791
		case RTM_IEEE80211_REPLAY:
792
			/* ignore */
793
			break;
794
		case RTM_IEEE80211_MICHAEL:
795
			mic = (struct ieee80211_michael_event *) &ifan[1];
796
			wpa_printf(MSG_DEBUG,
797
				"Michael MIC failure wireless event: "
798
				"keyix=%u src_addr=" MACSTR, mic->iev_keyix,
799
				MAC2STR(mic->iev_src));
800
			os_memset(&event, 0, sizeof(event));
801
			event.michael_mic_failure.unicast =
802
				!IEEE80211_IS_MULTICAST(mic->iev_dst);
803
			event.michael_mic_failure.src = mic->iev_src;
804
			wpa_supplicant_event(drv->ctx,
805
					     EVENT_MICHAEL_MIC_FAILURE, &event);
806
			break;
807
		}
808
		break;
809
	case RTM_IFANNOUNCE:
810
		ifan = (struct if_announcemsghdr *) rtm;
811
		switch (ifan->ifan_what) {
812
		case IFAN_DEPARTURE:
813
			drv = bsd_get_drvindex(global, ifan->ifan_index);
814
			if (drv)
815
				drv->if_removed = 1;
816
			event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
817
			break;
818
		case IFAN_ARRIVAL:
819
			drv = bsd_get_drvname(global, ifan->ifan_name);
820
			if (drv) {
821
				drv->ifindex = ifan->ifan_index;
822
				drv->if_removed = 0;
823
			}
824
			event.interface_status.ievent = EVENT_INTERFACE_ADDED;
825
			break;
826
		default:
827
			wpa_printf(MSG_DEBUG, "RTM_IFANNOUNCE: unknown action");
828
			return;
829
		}
830
		wpa_printf(MSG_DEBUG, "RTM_IFANNOUNCE: Interface '%s' %s",
831
			   ifan->ifan_name,
832
			   ifan->ifan_what == IFAN_DEPARTURE ?
833
				"removed" : "added");
834
		os_strlcpy(event.interface_status.ifname, ifan->ifan_name,
835
			   sizeof(event.interface_status.ifname));
836
		if (drv) {
837
			wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS,
838
					     &event);
839
			/*
840
			 * Set ifindex to zero after sending the event as the
841
			 * event might query the driver to ensure a match.
842
			 */
843
			if (ifan->ifan_what == IFAN_DEPARTURE)
844
				drv->ifindex = 0;
845
		} else {
846
			wpa_supplicant_event_global(global->ctx,
847
						    EVENT_INTERFACE_STATUS,
848
						    &event);
849
		}
850
		break;
851
	case RTM_IFINFO:
852
		ifm = (struct if_msghdr *) rtm;
853
		drv = bsd_get_drvindex(global, ifm->ifm_index);
854
		if (drv == NULL)
855
			return;
856
		if (((ifm->ifm_flags & IFF_UP) == 0 ||
857
		    (ifm->ifm_flags & IFF_RUNNING) == 0) &&
858
		    (drv->flags & IFF_UP) != 0 &&
859
		    (drv->flags & IFF_RUNNING) != 0) {
860
			wpa_printf(MSG_DEBUG, "RTM_IFINFO: Interface '%s' DOWN",
861
				   drv->ifname);
862
			wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_DISABLED,
863
					     NULL);
864
		} else if ((ifm->ifm_flags & IFF_UP) != 0 &&
865
		    (ifm->ifm_flags & IFF_RUNNING) != 0 &&
866
		    ((drv->flags & IFF_UP) == 0 ||
867
		    (drv->flags & IFF_RUNNING)  == 0)) {
868
			wpa_printf(MSG_DEBUG, "RTM_IFINFO: Interface '%s' UP",
869
				   drv->ifname);
870
			wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED,
871
					     NULL);
872
		}
873
		drv->flags = ifm->ifm_flags;
874
		break;
875
	}
876
}
653
}
877
654
878
#ifdef HOSTAPD
655
#ifdef HOSTAPD
Lines 992-1002 bsd_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr, Link Here
992
				   addr);
769
				   addr);
993
}
770
}
994
771
772
static void
773
bsd_wireless_event_receive(int sock, void *ctx, void *sock_ctx)
774
{
775
	struct bsd_driver_global *global = sock_ctx;
776
	struct bsd_driver_data *drv;
777
	struct if_announcemsghdr *ifan;
778
	struct rt_msghdr *rtm;
779
	struct ieee80211_michael_event *mic;
780
	struct ieee80211_join_event *join;
781
	struct ieee80211_leave_event *leave;
782
	int n;
783
	union wpa_event_data data;
784
785
	n = read(sock, global->event_buf, global->event_buf_len);
786
	if (n < 0) {
787
		if (errno != EINTR && errno != EAGAIN)
788
			wpa_printf(MSG_ERROR, "%s read() failed: %s",
789
				   __func__, strerror(errno));
790
		return;
791
	}
792
793
	rtm = (struct rt_msghdr *) global->event_buf;
794
	if (rtm->rtm_version != RTM_VERSION) {
795
		wpa_printf(MSG_DEBUG, "Invalid routing message version=%d",
796
			   rtm->rtm_version);
797
		return;
798
	}
799
	switch (rtm->rtm_type) {
800
	case RTM_IEEE80211:
801
		ifan = (struct if_announcemsghdr *) rtm;
802
		drv = bsd_get_drvindex(global, ifan->ifan_index);
803
		if (drv == NULL)
804
			return;
805
		switch (ifan->ifan_what) {
806
		case RTM_IEEE80211_ASSOC:
807
		case RTM_IEEE80211_REASSOC:
808
		case RTM_IEEE80211_DISASSOC:
809
		case RTM_IEEE80211_SCAN:
810
			break;
811
		case RTM_IEEE80211_LEAVE:
812
			leave = (struct ieee80211_leave_event *) &ifan[1];
813
			drv_event_disassoc(drv->hapd, leave->iev_addr);
814
			break;
815
		case RTM_IEEE80211_JOIN:
816
#ifdef RTM_IEEE80211_REJOIN
817
		case RTM_IEEE80211_REJOIN:
818
#endif
819
			join = (struct ieee80211_join_event *) &ifan[1];
820
			bsd_new_sta(drv, drv->hapd, join->iev_addr);
821
			break;
822
		case RTM_IEEE80211_REPLAY:
823
			/* ignore */
824
			break;
825
		case RTM_IEEE80211_MICHAEL:
826
			mic = (struct ieee80211_michael_event *) &ifan[1];
827
			wpa_printf(MSG_DEBUG,
828
				"Michael MIC failure wireless event: "
829
				"keyix=%u src_addr=" MACSTR, mic->iev_keyix,
830
				MAC2STR(mic->iev_src));
831
			os_memset(&data, 0, sizeof(data));
832
			data.michael_mic_failure.unicast = 1;
833
			data.michael_mic_failure.src = mic->iev_src;
834
			wpa_supplicant_event(drv->hapd,
835
					     EVENT_MICHAEL_MIC_FAILURE, &data);
836
			break;
837
		}
838
		break;
839
	}
840
}
841
995
static void
842
static void
996
handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len)
843
handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len)
997
{
844
{
998
	struct bsd_driver_data *drv = ctx;
845
	struct bsd_driver_data *drv = ctx;
999
	drv_event_eapol_rx(drv->ctx, src_addr, buf, len);
846
	drv_event_eapol_rx(drv->hapd, src_addr, buf, len);
1000
}
847
}
1001
848
1002
static void *
849
static void *
Lines 1017-1024 bsd_init(struct hostapd_data *hapd, struct wpa_init_params *params) Link Here
1017
		goto bad;
864
		goto bad;
1018
	}
865
	}
1019
866
1020
	drv->ctx = hapd;
867
	drv->hapd = hapd;
1021
	drv->is_ap = 1;
1022
	drv->global = params->global_priv;
868
	drv->global = params->global_priv;
1023
	os_strlcpy(drv->ifname, params->ifname, sizeof(drv->ifname));
869
	os_strlcpy(drv->ifname, params->ifname, sizeof(drv->ifname));
1024
870
Lines 1029-1035 bsd_init(struct hostapd_data *hapd, struct wpa_init_params *params) Link Here
1029
	if (l2_packet_get_own_addr(drv->sock_xmit, params->own_addr))
875
	if (l2_packet_get_own_addr(drv->sock_xmit, params->own_addr))
1030
		goto bad;
876
		goto bad;
1031
877
1032
	if (bsd_get_iface_flags(drv) < 0)
878
	/* mark down during setup */
879
	if (bsd_ctrl_iface(drv, 0) < 0)
1033
		goto bad;
880
		goto bad;
1034
881
1035
	if (bsd_set_mediaopt(drv, IFM_OMASK, IFM_IEEE80211_HOSTAP) < 0) {
882
	if (bsd_set_mediaopt(drv, IFM_OMASK, IFM_IEEE80211_HOSTAP) < 0) {
Lines 1054-1065 bsd_deinit(void *priv) Link Here
1054
{
901
{
1055
	struct bsd_driver_data *drv = priv;
902
	struct bsd_driver_data *drv = priv;
1056
903
904
	if (drv->ifindex != 0)
905
		bsd_ctrl_iface(drv, 0);
1057
	if (drv->sock_xmit != NULL)
906
	if (drv->sock_xmit != NULL)
1058
		l2_packet_deinit(drv->sock_xmit);
907
		l2_packet_deinit(drv->sock_xmit);
1059
	os_free(drv);
908
	os_free(drv);
1060
}
909
}
1061
910
1062
911
912
static int
913
bsd_commit(void *priv)
914
{
915
	return bsd_ctrl_iface(priv, 1);
916
}
917
918
1063
static int
919
static int
1064
bsd_set_sta_authorized(void *priv, const u8 *addr,
920
bsd_set_sta_authorized(void *priv, const u8 *addr,
1065
		       unsigned int total_flags, unsigned int flags_or,
921
		       unsigned int total_flags, unsigned int flags_or,
Lines 1313-1323 wpa_driver_bsd_scan(void *priv, struct wpa_driver_scan_params *params) Link Here
1313
	}
1169
	}
1314
1170
1315
	/* NB: interface must be marked UP to do a scan */
1171
	/* NB: interface must be marked UP to do a scan */
1316
	if (!(drv->flags & IFF_UP)) {
1172
	if (bsd_ctrl_iface(drv, 1) < 0)
1317
		wpa_printf(MSG_DEBUG, "%s: interface is not up, cannot scan",
1318
			   __func__);
1319
		return -1;
1173
		return -1;
1320
	}
1321
1174
1322
#ifdef IEEE80211_IOC_SCAN_MAX_SSID
1175
#ifdef IEEE80211_IOC_SCAN_MAX_SSID
1323
	os_memset(&sr, 0, sizeof(sr));
1176
	os_memset(&sr, 0, sizeof(sr));
Lines 1354-1359 wpa_driver_bsd_scan(void *priv, struct wpa_driver_scan_params *params) Link Here
1354
#endif /* IEEE80211_IOC_SCAN_MAX_SSID */
1207
#endif /* IEEE80211_IOC_SCAN_MAX_SSID */
1355
}
1208
}
1356
1209
1210
static void
1211
wpa_driver_bsd_event_receive(int sock, void *ctx, void *sock_ctx)
1212
{
1213
	struct bsd_driver_global *global = sock_ctx;
1214
	struct bsd_driver_data *drv;
1215
	struct if_announcemsghdr *ifan;
1216
	struct if_msghdr *ifm;
1217
	struct rt_msghdr *rtm;
1218
	union wpa_event_data event;
1219
	struct ieee80211_michael_event *mic;
1220
	struct ieee80211_leave_event *leave;
1221
	struct ieee80211_join_event *join;
1222
	int n;
1223
1224
	n = read(sock, global->event_buf, global->event_buf_len);
1225
	if (n < 0) {
1226
		if (errno != EINTR && errno != EAGAIN)
1227
			wpa_printf(MSG_ERROR, "%s read() failed: %s",
1228
				   __func__, strerror(errno));
1229
		return;
1230
	}
1231
1232
	rtm = (struct rt_msghdr *) global->event_buf;
1233
	if (rtm->rtm_version != RTM_VERSION) {
1234
		wpa_printf(MSG_DEBUG, "Invalid routing message version=%d",
1235
			   rtm->rtm_version);
1236
		return;
1237
	}
1238
	os_memset(&event, 0, sizeof(event));
1239
	switch (rtm->rtm_type) {
1240
	case RTM_IFANNOUNCE:
1241
		ifan = (struct if_announcemsghdr *) rtm;
1242
		switch (ifan->ifan_what) {
1243
		case IFAN_DEPARTURE:
1244
			drv = bsd_get_drvindex(global, ifan->ifan_index);
1245
			if (drv)
1246
				drv->if_removed = 1;
1247
			event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
1248
			break;
1249
		case IFAN_ARRIVAL:
1250
			drv = bsd_get_drvname(global, ifan->ifan_name);
1251
			if (drv) {
1252
				drv->ifindex = ifan->ifan_index;
1253
				drv->if_removed = 0;
1254
			}
1255
			event.interface_status.ievent = EVENT_INTERFACE_ADDED;
1256
			break;
1257
		default:
1258
			wpa_printf(MSG_DEBUG, "RTM_IFANNOUNCE: unknown action");
1259
			return;
1260
		}
1261
		wpa_printf(MSG_DEBUG, "RTM_IFANNOUNCE: Interface '%s' %s",
1262
			   ifan->ifan_name,
1263
			   ifan->ifan_what == IFAN_DEPARTURE ?
1264
				"removed" : "added");
1265
		os_strlcpy(event.interface_status.ifname, ifan->ifan_name,
1266
			   sizeof(event.interface_status.ifname));
1267
		if (drv) {
1268
			wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS,
1269
					     &event);
1270
			/*
1271
			 * Set ifindex to zero after sending the event as the
1272
			 * event might query the driver to ensure a match.
1273
			 */
1274
			if (ifan->ifan_what == IFAN_DEPARTURE)
1275
				drv->ifindex = 0;
1276
		} else {
1277
			wpa_supplicant_event_global(global->ctx,
1278
						    EVENT_INTERFACE_STATUS,
1279
						    &event);
1280
		}
1281
		break;
1282
	case RTM_IEEE80211:
1283
		ifan = (struct if_announcemsghdr *) rtm;
1284
		drv = bsd_get_drvindex(global, ifan->ifan_index);
1285
		if (drv == NULL)
1286
			return;
1287
		switch (ifan->ifan_what) {
1288
		case RTM_IEEE80211_ASSOC:
1289
		case RTM_IEEE80211_REASSOC:
1290
			if (drv->is_ap)
1291
				break;
1292
			wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL);
1293
			break;
1294
		case RTM_IEEE80211_DISASSOC:
1295
			if (drv->is_ap)
1296
				break;
1297
			wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);
1298
			break;
1299
		case RTM_IEEE80211_SCAN:
1300
			if (drv->is_ap)
1301
				break;
1302
			wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS,
1303
					     NULL);
1304
			break;
1305
		case RTM_IEEE80211_LEAVE:
1306
			leave = (struct ieee80211_leave_event *) &ifan[1];
1307
			drv_event_disassoc(drv->ctx, leave->iev_addr);
1308
			break;
1309
		case RTM_IEEE80211_JOIN:
1310
#ifdef RTM_IEEE80211_REJOIN
1311
		case RTM_IEEE80211_REJOIN:
1312
#endif
1313
			join = (struct ieee80211_join_event *) &ifan[1];
1314
			bsd_new_sta(drv, drv->ctx, join->iev_addr);
1315
			break;
1316
		case RTM_IEEE80211_REPLAY:
1317
			/* ignore */
1318
			break;
1319
		case RTM_IEEE80211_MICHAEL:
1320
			mic = (struct ieee80211_michael_event *) &ifan[1];
1321
			wpa_printf(MSG_DEBUG,
1322
				"Michael MIC failure wireless event: "
1323
				"keyix=%u src_addr=" MACSTR, mic->iev_keyix,
1324
				MAC2STR(mic->iev_src));
1325
1326
			os_memset(&event, 0, sizeof(event));
1327
			event.michael_mic_failure.unicast =
1328
				!IEEE80211_IS_MULTICAST(mic->iev_dst);
1329
			wpa_supplicant_event(drv->ctx,
1330
					     EVENT_MICHAEL_MIC_FAILURE, &event);
1331
			break;
1332
		}
1333
		break;
1334
	case RTM_IFINFO:
1335
		ifm = (struct if_msghdr *) rtm;
1336
		drv = bsd_get_drvindex(global, ifm->ifm_index);
1337
		if (drv == NULL)
1338
			return;
1339
		if ((ifm->ifm_flags & IFF_UP) == 0 &&
1340
		    (drv->flags & IFF_UP) != 0) {
1341
			wpa_printf(MSG_DEBUG, "RTM_IFINFO: Interface '%s' DOWN",
1342
				   drv->ifname);
1343
			wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_DISABLED,
1344
					     NULL);
1345
		} else if ((ifm->ifm_flags & IFF_UP) != 0 &&
1346
		    (drv->flags & IFF_UP) == 0) {
1347
			wpa_printf(MSG_DEBUG, "RTM_IFINFO: Interface '%s' UP",
1348
				   drv->ifname);
1349
			wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED,
1350
					     NULL);
1351
		}
1352
		drv->flags = ifm->ifm_flags;
1353
		break;
1354
	}
1355
}
1356
1357
static void
1357
static void
1358
wpa_driver_bsd_add_scan_entry(struct wpa_scan_results *res,
1358
wpa_driver_bsd_add_scan_entry(struct wpa_scan_results *res,
1359
			      struct ieee80211req_scan_result *sr)
1359
			      struct ieee80211req_scan_result *sr)
Lines 1565-1576 wpa_driver_bsd_init(void *ctx, const char *ifname, void *priv) Link Here
1565
#define	GETPARAM(drv, param, v) \
1565
#define	GETPARAM(drv, param, v) \
1566
	(((v) = get80211param(drv, param)) != -1)
1566
	(((v) = get80211param(drv, param)) != -1)
1567
	struct bsd_driver_data *drv;
1567
	struct bsd_driver_data *drv;
1568
	int i;
1569
1568
1570
	drv = os_zalloc(sizeof(*drv));
1569
	drv = os_zalloc(sizeof(*drv));
1571
	if (drv == NULL)
1570
	if (drv == NULL)
1572
		return NULL;
1571
		return NULL;
1573
1572
1573
	/*
1574
	 * NB: We require the interface name be mappable to an index.
1575
	 *     This implies we do not support having wpa_supplicant
1576
	 *     wait for an interface to appear.  This seems ok; that
1577
	 *     doesn't belong here; it's really the job of devd.
1578
	 */
1574
	drv->ifindex = if_nametoindex(ifname);
1579
	drv->ifindex = if_nametoindex(ifname);
1575
	if (drv->ifindex == 0) {
1580
	if (drv->ifindex == 0) {
1576
		wpa_printf(MSG_DEBUG, "%s: interface %s does not exist",
1581
		wpa_printf(MSG_DEBUG, "%s: interface %s does not exist",
Lines 1582-1590 wpa_driver_bsd_init(void *ctx, const char *ifname, void *priv) Link Here
1582
	drv->global = priv;
1587
	drv->global = priv;
1583
	os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));
1588
	os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));
1584
1589
1585
	/* Set the interface as removed until proven to work. */
1586
	drv->if_removed = 1;
1587
1588
	if (!GETPARAM(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming)) {
1590
	if (!GETPARAM(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming)) {
1589
		wpa_printf(MSG_DEBUG, "%s: failed to get roaming state: %s",
1591
		wpa_printf(MSG_DEBUG, "%s: failed to get roaming state: %s",
1590
			__func__, strerror(errno));
1592
			__func__, strerror(errno));
Lines 1604-1620 wpa_driver_bsd_init(void *ctx, const char *ifname, void *priv) Link Here
1604
	if (wpa_driver_bsd_capa(drv))
1606
	if (wpa_driver_bsd_capa(drv))
1605
		goto fail;
1607
		goto fail;
1606
1608
1607
	/* Update per interface supported AKMs */
1608
	for (i = 0; i < WPA_IF_MAX; i++)
1609
		drv->capa.key_mgmt_iftype[i] = drv->capa.key_mgmt;
1610
1611
	/* Down interface during setup. */
1609
	/* Down interface during setup. */
1612
	if (bsd_get_iface_flags(drv) < 0)
1610
	if (bsd_ctrl_iface(drv, 0) < 0)
1613
		goto fail;
1611
		goto fail;
1614
1612
1615
	/* Proven to work, lets go! */
1616
	drv->if_removed = 0;
1617
1618
	drv->opmode = get80211opmode(drv);
1613
	drv->opmode = get80211opmode(drv);
1619
	dl_list_add(&drv->global->ifaces, &drv->list);
1614
	dl_list_add(&drv->global->ifaces, &drv->list);
1620
1615
Lines 1633-1638 wpa_driver_bsd_deinit(void *priv) Link Here
1633
	if (drv->ifindex != 0 && !drv->if_removed) {
1628
	if (drv->ifindex != 0 && !drv->if_removed) {
1634
		wpa_driver_bsd_set_wpa(drv, 0);
1629
		wpa_driver_bsd_set_wpa(drv, 0);
1635
1630
1631
		/* NB: mark interface down */
1632
		bsd_ctrl_iface(drv, 0);
1633
1636
		wpa_driver_bsd_set_wpa_internal(drv, drv->prev_wpa,
1634
		wpa_driver_bsd_set_wpa_internal(drv, drv->prev_wpa,
1637
						drv->prev_privacy);
1635
						drv->prev_privacy);
1638
1636
Lines 1663-1677 static void * Link Here
1663
bsd_global_init(void *ctx)
1661
bsd_global_init(void *ctx)
1664
{
1662
{
1665
	struct bsd_driver_global *global;
1663
	struct bsd_driver_global *global;
1666
#if defined(RO_MSGFILTER) || defined(ROUTE_MSGFILTER)
1667
	unsigned char msgfilter[] = {
1668
		RTM_IEEE80211,
1669
		RTM_IFINFO, RTM_IFANNOUNCE,
1670
	};
1671
#endif
1672
#ifdef ROUTE_MSGFILTER
1673
	unsigned int i, msgfilter_mask;
1674
#endif
1675
1664
1676
	global = os_zalloc(sizeof(*global));
1665
	global = os_zalloc(sizeof(*global));
1677
	if (global == NULL)
1666
	if (global == NULL)
Lines 1680-1718 bsd_global_init(void *ctx) Link Here
1680
	global->ctx = ctx;
1669
	global->ctx = ctx;
1681
	dl_list_init(&global->ifaces);
1670
	dl_list_init(&global->ifaces);
1682
1671
1683
	global->sock = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1672
	global->sock = socket(PF_INET, SOCK_DGRAM, 0);
1684
	if (global->sock < 0) {
1673
	if (global->sock < 0) {
1685
		wpa_printf(MSG_ERROR, "socket[PF_INET,SOCK_DGRAM]: %s",
1674
		wpa_printf(MSG_ERROR, "socket[PF_INET,SOCK_DGRAM]: %s",
1686
			   strerror(errno));
1675
			   strerror(errno));
1687
		goto fail1;
1676
		goto fail1;
1688
	}
1677
	}
1689
1678
1690
	global->route = socket(PF_ROUTE,
1679
	global->route = socket(PF_ROUTE, SOCK_RAW, 0);
1691
			       SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
1692
	if (global->route < 0) {
1680
	if (global->route < 0) {
1693
		wpa_printf(MSG_ERROR, "socket[PF_ROUTE,SOCK_RAW]: %s",
1681
		wpa_printf(MSG_ERROR, "socket[PF_ROUTE,SOCK_RAW]: %s",
1694
			   strerror(errno));
1682
			   strerror(errno));
1695
		goto fail;
1683
		goto fail;
1696
	}
1684
	}
1697
1685
1698
#if defined(RO_MSGFILTER)
1686
	global->event_buf_len = rtbuf_len();
1699
	if (setsockopt(global->route, PF_ROUTE, RO_MSGFILTER,
1687
	global->event_buf = os_malloc(global->event_buf_len);
1700
	    &msgfilter, sizeof(msgfilter)) < 0)
1688
	if (global->event_buf == NULL) {
1701
		wpa_printf(MSG_ERROR, "socket[PF_ROUTE,RO_MSGFILTER]: %s",
1689
		wpa_printf(MSG_ERROR, "%s: os_malloc() failed", __func__);
1702
			   strerror(errno));
1690
		goto fail;
1703
#elif defined(ROUTE_MSGFILTER)
1691
	}
1704
	msgfilter_mask = 0;
1705
	for (i = 0; i < (sizeof(msgfilter) / sizeof(msgfilter[0])); i++)
1706
		msgfilter_mask |= ROUTE_FILTER(msgfilter[i]);
1707
	if (setsockopt(global->route, PF_ROUTE, ROUTE_MSGFILTER,
1708
	    &msgfilter_mask, sizeof(msgfilter_mask)) < 0)
1709
		wpa_printf(MSG_ERROR, "socket[PF_ROUTE,ROUTE_MSGFILTER]: %s",
1710
			   strerror(errno));
1711
#endif
1712
1692
1693
#ifdef HOSTAPD
1713
	eloop_register_read_sock(global->route, bsd_wireless_event_receive,
1694
	eloop_register_read_sock(global->route, bsd_wireless_event_receive,
1714
				 NULL, global);
1695
				 NULL, global);
1715
1696
1697
#else /* HOSTAPD */
1698
	eloop_register_read_sock(global->route, wpa_driver_bsd_event_receive,
1699
				 NULL, global);
1700
#endif /* HOSTAPD */
1701
1716
	return global;
1702
	return global;
1717
1703
1718
fail:
1704
fail:
Lines 1749-1754 const struct wpa_driver_ops wpa_driver_bsd_ops = { Link Here
1749
	.sta_disassoc		= bsd_sta_disassoc,
1735
	.sta_disassoc		= bsd_sta_disassoc,
1750
	.sta_deauth		= bsd_sta_deauth,
1736
	.sta_deauth		= bsd_sta_deauth,
1751
	.sta_set_flags		= bsd_set_sta_authorized,
1737
	.sta_set_flags		= bsd_set_sta_authorized,
1738
	.commit			= bsd_commit,
1752
#else /* HOSTAPD */
1739
#else /* HOSTAPD */
1753
	.init2			= wpa_driver_bsd_init,
1740
	.init2			= wpa_driver_bsd_init,
1754
	.deinit			= wpa_driver_bsd_deinit,
1741
	.deinit			= wpa_driver_bsd_deinit,

Return to bug 264238