From: Sepherosa Ziehau Date: Sat, 2 Sep 2006 05:40:35 +0000 (+0000) Subject: - Move pcap_{get_selectable_fd,pcap_inject}() from 802_11/wpa_supplicant/Packet32.c X-Git-Tag: v2.0.1~4489 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/56b17b94dba7f95456e84a0747b1c7c0a847fc70 - Move pcap_{get_selectable_fd,pcap_inject}() from 802_11/wpa_supplicant/Packet32.c into 802_11/l2_packet.c - Add building infrastructures for hostapd(8) and hostapd_cli(8) - Hook hostapd(8) and hostapd_cli(8) into building Obtained-from: FreeBSD (mainly sam@freebsd.org) --- diff --git a/usr.sbin/802_11/Makefile b/usr.sbin/802_11/Makefile index 68c35fc287..8414cbf930 100644 --- a/usr.sbin/802_11/Makefile +++ b/usr.sbin/802_11/Makefile @@ -1,5 +1,5 @@ -# $DragonFly: src/usr.sbin/802_11/Makefile,v 1.2 2006/07/07 15:05:18 sephe Exp $ +# $DragonFly: src/usr.sbin/802_11/Makefile,v 1.3 2006/09/02 05:40:35 sephe Exp $ -SUBDIR= wpa_supplicant wpa_cli +SUBDIR= wpa_supplicant wpa_cli hostapd hostapd_cli .include diff --git a/usr.sbin/802_11/hostapd/Makefile b/usr.sbin/802_11/hostapd/Makefile new file mode 100644 index 0000000000..51f59ad122 --- /dev/null +++ b/usr.sbin/802_11/hostapd/Makefile @@ -0,0 +1,36 @@ +# $FreeBSD: src/usr.sbin/wpa/hostapd/Makefile,v 1.2 2005/06/17 05:37:08 sam Exp $ +# $DragonFly: src/usr.sbin/802_11/hostapd/Makefile,v 1.1 2006/09/02 05:40:35 sephe Exp $ + +SRCDIR= ${.CURDIR}/../../../contrib/hostapd-0.4.9 +.PATH: ${.CURDIR}/.. ${SRCDIR} + +PROG= hostapd +SRCS= hostapd.c eloop.c ieee802_1x.c eapol_sm.c radius.c md5.c rc4.c \ + common.c ieee802_11.c config.c ieee802_11_auth.c accounting.c \ + sta_info.c radius_client.c sha1.c wpa.c aes_wrap.c tls_none.c \ + ctrl_iface.c driver_conf.c l2_packet.c driver_dragonfly.c +CLEANFILES=driver_conf.c + +MAN= hostapd.8 hostapd.conf.5 + +CFLAGS+= -I${.CURDIR} -I${SRCDIR} +CFLAGS+= -DCONFIG_DRIVER_BSD +DPADD+= ${LIBPCAP} +LDADD+= -lpcap + +driver_conf.c: Makefile + rm -f driver_conf.c + echo '/* THIS FILE AUTOMATICALLY GENERATED, DO NOT EDIT! */' \ + > driver_conf.c + echo '#include ' >> driver_conf.c + echo '#include ' >> driver_conf.c + echo '#include ' >> driver_conf.c + echo '#include ' >> driver_conf.c + echo '#include "hostapd.h"' >> driver_conf.c + echo '#include "driver.h"' >> driver_conf.c + echo "void bsd_driver_register(void);" >> driver_conf.c + echo 'void register_drivers(void) {' >> driver_conf.c + echo "bsd_driver_register();" >> driver_conf.c + echo '}' >> driver_conf.c + +.include diff --git a/usr.sbin/802_11/hostapd/driver_dragonfly.c b/usr.sbin/802_11/hostapd/driver_dragonfly.c new file mode 100644 index 0000000000..515dd0665d --- /dev/null +++ b/usr.sbin/802_11/hostapd/driver_dragonfly.c @@ -0,0 +1,892 @@ +/* + * Host AP - driver interaction with BSD net80211 layer + * Copyright (c) 2004, Sam Leffler + * Copyright (c) 2004, 2Wire, Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + * + * $FreeBSD: src/usr.sbin/wpa/hostapd/driver_freebsd.c,v 1.2.2.1 2006/03/24 01:43:18 sam Exp $ + * $DragonFly: src/usr.sbin/802_11/hostapd/driver_dragonfly.c,v 1.1 2006/09/02 05:40:35 sephe Exp $ + */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "hostapd.h" +#include "driver.h" +#include "ieee802_1x.h" +#include "eloop.h" +#include "sta_info.h" +#include "l2_packet.h" + +#include "eapol_sm.h" +#include "wpa.h" +#include "radius.h" +#include "ieee802_11.h" +#include "common.h" +#include "hostap_common.h" + +struct bsd_driver_data { + struct driver_ops ops; /* base class */ + struct hostapd_data *hapd; /* back pointer */ + + char iface[IFNAMSIZ + 1]; + struct l2_packet_data *sock_xmit; /* raw packet xmit socket */ + int ioctl_sock; /* socket for ioctl() use */ + int wext_sock; /* socket for wireless events */ +}; + +static const struct driver_ops bsd_driver_ops; + +static int bsd_sta_deauth(void *priv, u8 *addr, int reason_code); + +static int +set80211var(struct bsd_driver_data *drv, int op, const void *arg, int arg_len) +{ + struct ieee80211req ireq; + + memset(&ireq, 0, sizeof(ireq)); + strncpy(ireq.i_name, drv->iface, IFNAMSIZ); + ireq.i_type = op; + ireq.i_len = arg_len; + ireq.i_data = (void *) arg; + + if (ioctl(drv->ioctl_sock, SIOCS80211, &ireq) < 0) { + perror("ioctl[SIOCS80211]"); + return -1; + } + return 0; +} + +static int +get80211var(struct bsd_driver_data *drv, int op, void *arg, int arg_len) +{ + struct ieee80211req ireq; + + memset(&ireq, 0, sizeof(ireq)); + strncpy(ireq.i_name, drv->iface, IFNAMSIZ); + ireq.i_type = op; + ireq.i_len = arg_len; + ireq.i_data = arg; + + if (ioctl(drv->ioctl_sock, SIOCG80211, &ireq) < 0) { + perror("ioctl[SIOCG80211]"); + return -1; + } + return ireq.i_len; +} + +static int +set80211param(struct bsd_driver_data *drv, int op, int arg) +{ + struct ieee80211req ireq; + + memset(&ireq, 0, sizeof(ireq)); + strncpy(ireq.i_name, drv->iface, IFNAMSIZ); + ireq.i_type = op; + ireq.i_val = arg; + + if (ioctl(drv->ioctl_sock, SIOCS80211, &ireq) < 0) { + perror("ioctl[SIOCS80211]"); + return -1; + } + return 0; +} + +static const char * +ether_sprintf(const u8 *addr) +{ + static char buf[sizeof(MACSTR)]; + + if (addr != NULL) + snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr)); + else + snprintf(buf, sizeof(buf), MACSTR, 0,0,0,0,0,0); + return buf; +} + +/* + * Configure WPA parameters. + */ +static int +bsd_configure_wpa(struct bsd_driver_data *drv) +{ + static const char *ciphernames[] = + { "WEP", "TKIP", "AES-OCB", "AES-CCM", "CKIP", "NONE" }; + hostapd *hapd = drv->hapd; + struct hostapd_config *conf = hapd->conf; + int v; + + switch (conf->wpa_group) { + case WPA_CIPHER_CCMP: + v = IEEE80211_CIPHER_AES_CCM; + break; + case WPA_CIPHER_TKIP: + v = IEEE80211_CIPHER_TKIP; + break; + case WPA_CIPHER_WEP104: + v = IEEE80211_CIPHER_WEP; + break; + case WPA_CIPHER_WEP40: + v = IEEE80211_CIPHER_WEP; + break; + case WPA_CIPHER_NONE: + v = IEEE80211_CIPHER_NONE; + break; + default: + printf("Unknown group key cipher %u\n", + conf->wpa_group); + return -1; + } + HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, + "%s: group key cipher=%s (%u)\n", __func__, ciphernames[v], v); + if (set80211param(drv, IEEE80211_IOC_MCASTCIPHER, v)) { + printf("Unable to set group key cipher to %u (%s)\n", + v, ciphernames[v]); + return -1; + } + if (v == IEEE80211_CIPHER_WEP) { + /* key length is done only for specific ciphers */ + v = (conf->wpa_group == WPA_CIPHER_WEP104 ? 13 : 5); + if (set80211param(drv, IEEE80211_IOC_MCASTKEYLEN, v)) { + printf("Unable to set group key length to %u\n", v); + return -1; + } + } + + v = 0; + if (conf->wpa_pairwise & WPA_CIPHER_CCMP) + v |= 1<wpa_pairwise & WPA_CIPHER_TKIP) + v |= 1<wpa_pairwise & WPA_CIPHER_NONE) + v |= 1<wpa_key_mgmt); + if (set80211param(drv, IEEE80211_IOC_KEYMGTALGS, conf->wpa_key_mgmt)) { + printf("Unable to set key management algorithms to 0x%x\n", + conf->wpa_key_mgmt); + return -1; + } + + v = 0; + if (conf->rsn_preauth) + v |= BIT(0); + HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, + "%s: rsn capabilities=0x%x\n", __func__, conf->rsn_preauth); + if (set80211param(drv, IEEE80211_IOC_RSNCAPS, v)) { + printf("Unable to set RSN capabilities to 0x%x\n", v); + return -1; + } + + HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, + "%s: enable WPA= 0x%x\n", __func__, conf->wpa); + if (set80211param(drv, IEEE80211_IOC_WPA, conf->wpa)) { + printf("Unable to set WPA to %u\n", conf->wpa); + return -1; + } + return 0; +} + + +static int +bsd_set_iface_flags(void *priv, int dev_up) +{ + struct bsd_driver_data *drv = priv; + hostapd *hapd = drv->hapd; + struct ifreq ifr; + + HOSTAPD_DEBUG(HOSTAPD_DEBUG_VERBOSE, + "%s: dev_up=%d\n", __func__, dev_up); + + if (drv->ioctl_sock < 0) + return -1; + + memset(&ifr, 0, sizeof(ifr)); + snprintf(ifr.ifr_name, IFNAMSIZ, "%s", drv->iface); + + if (ioctl(drv->ioctl_sock, SIOCGIFFLAGS, &ifr) != 0) { + perror("ioctl[SIOCGIFFLAGS]"); + return -1; + } + + if (dev_up) + ifr.ifr_flags |= IFF_UP; + else + ifr.ifr_flags &= ~IFF_UP; + + if (ioctl(drv->ioctl_sock, SIOCSIFFLAGS, &ifr) != 0) { + perror("ioctl[SIOCSIFFLAGS]"); + return -1; + } + + if (dev_up) { + memset(&ifr, 0, sizeof(ifr)); + snprintf(ifr.ifr_name, IFNAMSIZ, "%s", drv->iface); + ifr.ifr_mtu = HOSTAPD_MTU; + if (ioctl(drv->ioctl_sock, SIOCSIFMTU, &ifr) != 0) { + perror("ioctl[SIOCSIFMTU]"); + printf("Setting MTU failed - trying to survive with " + "current value\n"); + } + } + + return 0; +} + +static int +bsd_set_ieee8021x(void *priv, int enabled) +{ + struct bsd_driver_data *drv = priv; + hostapd *hapd = drv->hapd; + struct hostapd_config *conf = hapd->conf; + + HOSTAPD_DEBUG(HOSTAPD_DEBUG_VERBOSE, + "%s: enabled=%d\n", __func__, enabled); + + if (!enabled) { + /* XXX restore state */ + return set80211param(priv, IEEE80211_IOC_AUTHMODE, + IEEE80211_AUTH_AUTO); + } + if (!conf->wpa && !conf->ieee802_1x) { + hostapd_logger(hapd, NULL, HOSTAPD_MODULE_DRIVER, + HOSTAPD_LEVEL_WARNING, "No 802.1X or WPA enabled!"); + return -1; + } + if (conf->wpa && bsd_configure_wpa(drv) != 0) { + hostapd_logger(hapd, NULL, HOSTAPD_MODULE_DRIVER, + HOSTAPD_LEVEL_WARNING, "Error configuring WPA state!"); + return -1; + } + if (set80211param(priv, IEEE80211_IOC_AUTHMODE, + (conf->wpa ? IEEE80211_AUTH_WPA : IEEE80211_AUTH_8021X))) { + hostapd_logger(hapd, NULL, HOSTAPD_MODULE_DRIVER, + HOSTAPD_LEVEL_WARNING, "Error enabling WPA/802.1X!"); + return -1; + } + return bsd_set_iface_flags(priv, 1); +} + +static int +bsd_set_privacy(void *priv, int enabled) +{ + struct bsd_driver_data *drv = priv; + hostapd *hapd = drv->hapd; + + HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, + "%s: enabled=%d\n", __func__, enabled); + + return set80211param(priv, IEEE80211_IOC_PRIVACY, enabled); +} + +static int +bsd_set_sta_authorized(void *priv, u8 *addr, int authorized) +{ + struct bsd_driver_data *drv = priv; + hostapd *hapd = drv->hapd; + struct ieee80211req_mlme mlme; + + HOSTAPD_DEBUG(HOSTAPD_DEBUG_VERBOSE, + "%s: addr=%s authorized=%d\n", + __func__, ether_sprintf(addr), authorized); + + if (authorized) + mlme.im_op = IEEE80211_MLME_AUTHORIZE; + else + mlme.im_op = IEEE80211_MLME_UNAUTHORIZE; + mlme.im_reason = 0; + memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); + return set80211var(priv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme)); +} + +static int +bsd_del_key(void *priv, unsigned char *addr, int key_idx) +{ + struct bsd_driver_data *drv = priv; + hostapd *hapd = drv->hapd; + struct ieee80211req_del_key wk; + + HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, + "%s: addr=%s key_idx=%d\n", + __func__, ether_sprintf(addr), key_idx); + + memset(&wk, 0, sizeof(wk)); + if (addr != NULL) { + memcpy(wk.idk_macaddr, addr, IEEE80211_ADDR_LEN); + wk.idk_keyix = (u_int8_t) IEEE80211_KEYIX_NONE; /* XXX */ + } else { + wk.idk_keyix = key_idx; + } + + return set80211var(priv, IEEE80211_IOC_DELKEY, &wk, sizeof(wk)); +} + +static int +bsd_set_key(void *priv, const char *alg, + unsigned char *addr, int key_idx, + u8 *key, size_t key_len) +{ + struct bsd_driver_data *drv = priv; + hostapd *hapd = drv->hapd; + struct ieee80211req_key wk; + u_int8_t cipher; + + if (strcmp(alg, "none") == 0) + return bsd_del_key(priv, addr, key_idx); + + HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, + "%s: alg=%s addr=%s key_idx=%d\n", + __func__, alg, ether_sprintf(addr), key_idx); + + if (strcmp(alg, "WEP") == 0) + cipher = IEEE80211_CIPHER_WEP; + else if (strcmp(alg, "TKIP") == 0) + cipher = IEEE80211_CIPHER_TKIP; + else if (strcmp(alg, "CCMP") == 0) + cipher = IEEE80211_CIPHER_AES_CCM; + else { + printf("%s: unknown/unsupported algorithm %s\n", + __func__, alg); + return -1; + } + + if (key_len > sizeof(wk.ik_keydata)) { + printf("%s: key length %d too big\n", __func__, key_len); + return -3; + } + + memset(&wk, 0, sizeof(wk)); + wk.ik_type = cipher; + wk.ik_flags = IEEE80211_KEY_RECV | IEEE80211_KEY_XMIT; + if (addr == NULL) { + memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN); + wk.ik_keyix = key_idx; + wk.ik_flags |= IEEE80211_KEY_DEFAULT | IEEE80211_KEY_GROUP; + } else { + memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); + wk.ik_keyix = IEEE80211_KEYIX_NONE; + } + wk.ik_keylen = key_len; + memcpy(wk.ik_keydata, key, key_len); + + return set80211var(priv, IEEE80211_IOC_WPAKEY, &wk, sizeof(wk)); +} + + +static int +bsd_get_seqnum(void *priv, u8 *addr, int idx, u8 *seq) +{ + struct bsd_driver_data *drv = priv; + hostapd *hapd = drv->hapd; + struct ieee80211req_key wk; + + HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, + "%s: addr=%s idx=%d\n", __func__, ether_sprintf(addr), idx); + + memset(&wk, 0, sizeof(wk)); + if (addr == NULL) + memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN); + else + memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); + wk.ik_keyix = idx; + + if (get80211var(drv, IEEE80211_IOC_WPAKEY, &wk, sizeof(wk)) < 0) { + printf("Failed to get encryption.\n"); + return -1; + } else { + /* NB: upper layer expects tsc in network order */ + wk.ik_keytsc = htole64(wk.ik_keytsc); + memcpy(seq, &wk.ik_keytsc, sizeof(wk.ik_keytsc)); + return 0; + } +} + + +static int +bsd_flush(void *priv) +{ + u8 allsta[IEEE80211_ADDR_LEN]; + + memset(allsta, 0xff, IEEE80211_ADDR_LEN); + return bsd_sta_deauth(priv, allsta, IEEE80211_REASON_AUTH_LEAVE); +} + + +static int +bsd_read_sta_driver_data(void *priv, struct hostap_sta_driver_data *data, + u8 *addr) +{ + struct bsd_driver_data *drv = priv; + struct ieee80211req_sta_stats stats; + + memcpy(stats.is_u.macaddr, addr, IEEE80211_ADDR_LEN); + if (get80211var(drv, IEEE80211_IOC_STA_STATS, &stats, sizeof(stats)) > 0) { + /* XXX? do packets counts include non-data frames? */ + data->rx_packets = stats.is_stats.ns_rx_data; + data->rx_bytes = stats.is_stats.ns_rx_bytes; + data->tx_packets = stats.is_stats.ns_tx_data; + data->tx_bytes = stats.is_stats.ns_tx_bytes; + } + return 0; +} + +static int +bsd_sta_clear_stats(void *priv, u8 *addr) +{ + struct bsd_driver_data *drv = priv; + hostapd *hapd = drv->hapd; + struct ieee80211req_sta_stats stats; + + HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "%s: addr=%s\n", + __func__, ether_sprintf(addr)); + + /* zero station statistics */ + memset(&stats, 0, sizeof(stats)); + memcpy(stats.is_u.macaddr, addr, IEEE80211_ADDR_LEN); + return set80211var(drv, IEEE80211_IOC_STA_STATS, &stats, sizeof(stats)); +} + +static int +bsd_set_opt_ie(void *priv, const u8 *ie, size_t ie_len) +{ + /* + * Do nothing; we setup parameters at startup that define the + * contents of the beacon information element. + */ + return 0; +} + +static int +bsd_sta_deauth(void *priv, u8 *addr, int reason_code) +{ + struct bsd_driver_data *drv = priv; + hostapd *hapd = drv->hapd; + struct ieee80211req_mlme mlme; + + HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, + "%s: addr=%s reason_code=%d\n", + __func__, ether_sprintf(addr), reason_code); + + mlme.im_op = IEEE80211_MLME_DEAUTH; + mlme.im_reason = reason_code; + memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); + return set80211var(priv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme)); +} + +static int +bsd_sta_disassoc(void *priv, u8 *addr, int reason_code) +{ + struct bsd_driver_data *drv = priv; + hostapd *hapd = drv->hapd; + struct ieee80211req_mlme mlme; + + HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, + "%s: addr=%s reason_code=%d\n", + __func__, ether_sprintf(addr), reason_code); + + mlme.im_reason = reason_code; + memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); + return set80211var(priv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme)); +} + +static int +bsd_del_sta(struct bsd_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN]) +{ + struct hostapd_data *hapd = drv->hapd; + struct hostapd_config *conf = hapd->conf; + struct sta_info *sta; + + hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, + HOSTAPD_LEVEL_INFO, "deassociated"); + + sta = ap_get_sta(hapd, addr); + if (sta != NULL) { + sta->flags &= ~WLAN_STA_ASSOC; + if (conf->wpa) + wpa_sm_event(hapd, sta, WPA_DISASSOC); + sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST; + ieee802_1x_set_port_enabled(hapd, sta, 0); + ap_free_sta(hapd, sta); + } + return 0; +} + +static int +bsd_new_sta(struct bsd_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN]) +{ + struct hostapd_data *hapd = drv->hapd; + struct hostapd_config *conf = hapd->conf; + struct sta_info *sta; + struct ieee80211req_wpaie ie; + int new_assoc, ielen, res; + + hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, + HOSTAPD_LEVEL_INFO, "associated"); + + sta = ap_sta_add(hapd, addr); + if (sta == NULL) + return -1; + /* + * Fetch and validate any negotiated WPA/RSN parameters. + */ + if (conf->wpa) { + memset(&ie, 0, sizeof(ie)); + memcpy(ie.wpa_macaddr, addr, IEEE80211_ADDR_LEN); + if (get80211var(drv, IEEE80211_IOC_WPAIE, &ie, sizeof(ie)) < 0) { + printf("Failed to get WPA/RSN information element.\n"); + return -1; /* XXX not right */ + } + ielen = ie.wpa_ie[1]; + if (ielen == 0) { + printf("No WPA/RSN information element for station!\n"); + return -1; /* XXX not right */ + } + ielen += 2; + res = wpa_validate_wpa_ie(hapd, sta, ie.wpa_ie, ielen, + ie.wpa_ie[0] == WLAN_EID_RSN ? + HOSTAPD_WPA_VERSION_WPA2 : + HOSTAPD_WPA_VERSION_WPA); + if (res != WPA_IE_OK) { + printf("WPA/RSN information element rejected? " + "(res %u)\n", res); + return -1; + } + if (sta->wpa_ie != NULL) + free(sta->wpa_ie); + sta->wpa_ie = malloc(ielen); + if (sta->wpa_ie == NULL) { + printf("No memory for WPA/RSN information element!\n"); + return -1; + } + memcpy(sta->wpa_ie, ie.wpa_ie, ielen); + sta->wpa_ie_len = ielen; + } else { + if (sta->wpa_ie != NULL) + free(sta->wpa_ie); + sta->wpa_ie = NULL; + sta->wpa_ie_len = 0; + } + + /* + * Now that the internal station state is setup + * kick the authenticator into action. + */ + new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0; + sta->flags |= WLAN_STA_ASSOC; + if (new_assoc) { + if (conf->wpa) + wpa_sm_event(hapd, sta, WPA_ASSOC); + hostapd_new_assoc_sta(hapd, sta, !new_assoc); + } else { + if (conf->wpa) + wpa_sm_event(hapd, sta, WPA_REAUTH); + } + ieee802_1x_notify_port_enabled(sta->eapol_sm, 1); + return 0; +} + +#include +#include + +static void +bsd_wireless_event_receive(int sock, void *ctx, void *sock_ctx) +{ + struct bsd_driver_data *drv = ctx; + struct hostapd_data *hapd = drv->hapd; + char buf[2048]; + struct if_announcemsghdr *ifan; + struct rt_msghdr *rtm; + struct ieee80211_michael_event *mic; + struct ieee80211_join_event *join; + struct ieee80211_leave_event *leave; + int n; + + n = read(sock, buf, sizeof(buf)); + if (n < 0) { + if (errno != EINTR && errno != EAGAIN) + perror("read(PF_ROUTE)"); + return; + } + + rtm = (struct rt_msghdr *) buf; + if (rtm->rtm_version != RTM_VERSION) { + wpa_printf(MSG_DEBUG, "Routing message version %d not " + "understood\n", rtm->rtm_version); + return; + } + ifan = (struct if_announcemsghdr *) rtm; + switch (rtm->rtm_type) { + case RTM_IEEE80211: + switch (ifan->ifan_what) { + case RTM_IEEE80211_ASSOC: + case RTM_IEEE80211_REASSOC: + case RTM_IEEE80211_DISASSOC: + case RTM_IEEE80211_SCAN: + break; + case RTM_IEEE80211_LEAVE: + leave = (struct ieee80211_leave_event *) &ifan[1]; + bsd_del_sta(drv, leave->iev_addr); + break; + case RTM_IEEE80211_JOIN: +#ifdef RTM_IEEE80211_REJOIN + case RTM_IEEE80211_REJOIN: +#endif + join = (struct ieee80211_join_event *) &ifan[1]; + bsd_new_sta(drv, join->iev_addr); + break; + case RTM_IEEE80211_REPLAY: + /* ignore */ + break; + case RTM_IEEE80211_MICHAEL: + mic = (struct ieee80211_michael_event *) &ifan[1]; + wpa_printf(MSG_DEBUG, + "Michael MIC failure wireless event: " + "keyix=%u src_addr=" MACSTR, mic->iev_keyix, + MAC2STR(mic->iev_src)); + ieee80211_michael_mic_failure(hapd, mic->iev_src, 1); + break; + } + break; + } +} + +static int +bsd_wireless_event_init(void *priv) +{ + struct bsd_driver_data *drv = priv; + int s; + + drv->wext_sock = -1; + + s = socket(PF_ROUTE, SOCK_RAW, 0); + if (s < 0) { + perror("socket(PF_ROUTE,SOCK_RAW)"); + return -1; + } + eloop_register_read_sock(s, bsd_wireless_event_receive, drv, NULL); + drv->wext_sock = s; + + return 0; +} + +static void +bsd_wireless_event_deinit(void *priv) +{ + struct bsd_driver_data *drv = priv; + + if (drv != NULL) { + if (drv->wext_sock < 0) + return; + eloop_unregister_read_sock(drv->wext_sock); + close(drv->wext_sock); + } +} + + +static int +bsd_send_eapol(void *priv, u8 *addr, u8 *data, size_t data_len, int encrypt) +{ + struct bsd_driver_data *drv = priv; + hostapd *hapd = drv->hapd; + unsigned char buf[3000]; + unsigned char *bp = buf; + struct l2_ethhdr *eth; + size_t len; + int status; + + /* + * Prepend the Etherent header. If the caller left us + * space at the front we could just insert it but since + * we don't know we copy to a local buffer. Given the frequency + * and size of frames this probably doesn't matter. + */ + len = data_len + sizeof(struct l2_ethhdr); + if (len > sizeof(buf)) { + bp = malloc(len); + if (bp == NULL) { + printf("EAPOL frame discarded, cannot malloc temp " + "buffer of size %u!\n", len); + return -1; + } + } + eth = (struct l2_ethhdr *) bp; + memcpy(eth->h_dest, addr, ETH_ALEN); + memcpy(eth->h_source, drv->hapd->own_addr, ETH_ALEN); + eth->h_proto = htons(ETH_P_EAPOL); + memcpy(eth+1, data, data_len); + + if (HOSTAPD_DEBUG_COND(HOSTAPD_DEBUG_MSGDUMPS)) + hostapd_hexdump("TX EAPOL", bp, len); + + status = l2_packet_send(drv->sock_xmit, addr, ETH_P_EAPOL, bp, len); + + if (bp != buf) + free(bp); + return status; +} + +static void +handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len) +{ + struct bsd_driver_data *drv = ctx; + hostapd *hapd = drv->hapd; + struct sta_info *sta; + + sta = ap_get_sta(hapd, src_addr); + if (!sta || !(sta->flags & WLAN_STA_ASSOC)) { + printf("Data frame from not associated STA %s\n", + ether_sprintf(src_addr)); + /* XXX cannot happen */ + return; + } + ieee802_1x_receive(hapd, src_addr, buf + sizeof(struct l2_ethhdr), + len - sizeof(struct l2_ethhdr)); +} + +static int +bsd_get_ssid(void *priv, u8 *buf, int len) +{ + struct bsd_driver_data *drv = priv; + hostapd *hapd = drv->hapd; + int ssid_len = get80211var(priv, IEEE80211_IOC_SSID, buf, len); + + HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "%s: ssid=\"%.*s\"\n", + __func__, ssid_len, buf); + + return ssid_len; +} + +static int +bsd_set_ssid(void *priv, u8 *buf, int len) +{ + struct bsd_driver_data *drv = priv; + hostapd *hapd = drv->hapd; + + HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "%s: ssid=\"%.*s\"\n", + __func__, len, buf); + + return set80211var(priv, IEEE80211_IOC_SSID, buf, len); +} + +static int +bsd_set_countermeasures(void *priv, int enabled) +{ + struct bsd_driver_data *drv = priv; + + wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled); + return set80211param(drv, IEEE80211_IOC_COUNTERMEASURES, enabled); +} + +static int +bsd_init(struct hostapd_data *hapd) +{ + struct bsd_driver_data *drv; + + drv = malloc(sizeof(struct bsd_driver_data)); + if (drv == NULL) { + printf("Could not allocate memory for bsd driver data\n"); + goto bad; + } + + memset(drv, 0, sizeof(*drv)); + drv->ops = bsd_driver_ops; + drv->hapd = hapd; + drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0); + if (drv->ioctl_sock < 0) { + perror("socket[PF_INET,SOCK_DGRAM]"); + goto bad; + } + memcpy(drv->iface, hapd->conf->iface, sizeof(drv->iface)); + + drv->sock_xmit = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL, + handle_read, drv, 1); + if (drv->sock_xmit == NULL) + goto bad; + if (l2_packet_get_own_addr(drv->sock_xmit, hapd->own_addr)) + goto bad; + + bsd_set_iface_flags(drv, 0); /* mark down during setup */ + + hapd->driver = &drv->ops; + return 0; +bad: + if (drv->sock_xmit != NULL) + l2_packet_deinit(drv->sock_xmit); + if (drv->ioctl_sock >= 0) + close(drv->ioctl_sock); + if (drv != NULL) + free(drv); + return -1; +} + + +static void +bsd_deinit(void *priv) +{ + struct bsd_driver_data *drv = priv; + + drv->hapd->driver = NULL; + + (void) bsd_set_iface_flags(drv, 0); + if (drv->ioctl_sock >= 0) + close(drv->ioctl_sock); + if (drv->sock_xmit != NULL) + l2_packet_deinit(drv->sock_xmit); + free(drv); +} + +static const struct driver_ops bsd_driver_ops = { + .name = "bsd", + .init = bsd_init, + .deinit = bsd_deinit, + .set_ieee8021x = bsd_set_ieee8021x, + .set_privacy = bsd_set_privacy, + .set_encryption = bsd_set_key, + .get_seqnum = bsd_get_seqnum, + .flush = bsd_flush, + .set_generic_elem = bsd_set_opt_ie, + .wireless_event_init = bsd_wireless_event_init, + .wireless_event_deinit = bsd_wireless_event_deinit, + .set_sta_authorized = bsd_set_sta_authorized, + .read_sta_data = bsd_read_sta_driver_data, + .send_eapol = bsd_send_eapol, + .sta_disassoc = bsd_sta_disassoc, + .sta_deauth = bsd_sta_deauth, + .set_ssid = bsd_set_ssid, + .get_ssid = bsd_get_ssid, + .set_countermeasures = bsd_set_countermeasures, + .sta_clear_stats = bsd_sta_clear_stats, +}; + +void bsd_driver_register(void) +{ + driver_register(bsd_driver_ops.name, &bsd_driver_ops); +} diff --git a/usr.sbin/802_11/hostapd/hostapd.8 b/usr.sbin/802_11/hostapd/hostapd.8 new file mode 100644 index 0000000000..6737102f32 --- /dev/null +++ b/usr.sbin/802_11/hostapd/hostapd.8 @@ -0,0 +1,131 @@ +.\" Copyright (c) 2005 Sam Leffler +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD: src/usr.sbin/wpa/hostapd/hostapd.8,v 1.2 2005/06/27 06:40:43 ru Exp $ +.\" $DragonFly: src/usr.sbin/802_11/hostapd/hostapd.8,v 1.1 2006/09/02 05:40:35 sephe Exp $ +.\" +.Dd August 19, 2006 +.Dt HOSTAPD 8 +.Os +.Sh NAME +.Nm hostapd +.Nd "authenticator for IEEE 802.11 networks" +.Sh SYNOPSIS +.Nm +.Op Fl BdhKtv +.Ar config-file ... +.Sh DESCRIPTION +The +.Nm +utility +is an authenticator for IEEE 802.11 networks. +It provides full support for WPA/IEEE 802.11i and +can also act as an IEEE 802.1X Authenticator with a suitable +backend Authentication Server (typically +.Tn FreeRADIUS ) . +The +.Nm +utility +implements the authentication protocols that piggyback on top +of the normal IEEE 802.11 protocol mechanisms. +To use +.Nm +as an authenticator, the underlying device must support some +basic functionality such as the ability to set security information +in the 802.11 management frames. +Beware that not all devices have this support. +.Pp +The +.Nm +utility +is designed to be a +.Dq daemon +program that runs in the +background and acts as the backend component controlling +the wireless connection. +It supports separate frontend programs such as the +text-based frontend, +.Xr hostapd_cli 8 . +.Pp +The following arguments must be specified on the command line: +.Bl -tag -width indent +.It Ar config-file +Use the settings in the specified configuration file; the name of +the specified wireless interface is contained in this file. +See +.Xr hostapd.conf 5 +for a description of the configuration file syntax. +.Pp +Changes to the configuration file can be reloaded by sending a +.Dv SIGHUP +to the +.Nm +processor or with the +.Xr hostapd_cli 8 +utility, using +.Dq Li "hostapd_cli reconfigure" . +.El +.Sh OPTIONS +The options are as follows: +.Bl -tag -width indent +.It Fl d +Enable debugging messages. +If this option is supplied twice, more verbose messages are displayed. +.It Fl h +Show help text. +.It Fl t +Include timestamps in debugging output. +.It Fl v +Display version information on the terminal and exit. +.It Fl B +Detach from the controlling terminal and run as a daemon process +in the background. +.It Fl K +Include key information in debugging output. +.El +.Sh SEE ALSO +.Xr ath 4 , +.Xr ipw 4 , +.Xr iwi 4 , +.Xr ral 4 , +.\" .Xr ural 4 , +.Xr wi 4 , +.Xr hostapd.conf 5 , +.Xr hostapd_cli 8 , +.Xr ifconfig 8 +.Sh HISTORY +The +.Nm +utility first appeared in +.Fx 6.0 . +.Sh AUTHORS +The +.Nm +utility was written by +.An Jouni Malinen Aq jkmaline@cc.hut.fi . +This manual page is derived from the +.Pa README +file included in the +.Nm +distribution. diff --git a/usr.sbin/802_11/hostapd/hostapd.conf.5 b/usr.sbin/802_11/hostapd/hostapd.conf.5 new file mode 100644 index 0000000000..27a58f0b27 --- /dev/null +++ b/usr.sbin/802_11/hostapd/hostapd.conf.5 @@ -0,0 +1,56 @@ +.\" Copyright (c) 2005 Sam Leffler +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD: src/usr.sbin/wpa/hostapd/hostapd.conf.5,v 1.2 2005/06/27 06:40:43 ru Exp $ +.\" $DragonFly: src/usr.sbin/802_11/hostapd/hostapd.conf.5,v 1.1 2006/09/02 05:40:35 sephe Exp $ +.\" +.Dd August 19, 2006 +.Dt HOSTAPD.CONF 5 +.Os +.Sh NAME +.Nm hostapd.conf +.Nd configuration file for +.Xr hostapd 8 +utility +.Sh DESCRIPTION +This is a placeholder for a real manual page. +.Sh SEE ALSO +.Xr hostapd 8 , +.Xr hostapd_cli 8 +.Sh HISTORY +The +.Nm +manual page and +.Xr hostapd 8 +functionality first appeared in +.Fx 6.0 . +.Sh AUTHORS +This manual page is derived from the +.Pa README +and +.Pa hostapd.conf +files in the +.Nm hostapd +distribution provided by +.An Jouni Malinen Aq jkmaline@cc.hut.fi . diff --git a/usr.sbin/802_11/hostapd_cli/Makefile b/usr.sbin/802_11/hostapd_cli/Makefile new file mode 100644 index 0000000000..5d91703884 --- /dev/null +++ b/usr.sbin/802_11/hostapd_cli/Makefile @@ -0,0 +1,13 @@ +# $FreeBSD: src/usr.sbin/wpa/hostapd_cli/Makefile,v 1.2.2.1 2006/03/24 01:43:18 sam Exp $ +# $DragonFly: src/usr.sbin/802_11/hostapd_cli/Makefile,v 1.1 2006/09/02 05:40:35 sephe Exp $ + +SRCDIR= ${.CURDIR}/../../../contrib/hostapd-0.4.9 + +.PATH: ${SRCDIR} + +PROG= hostapd_cli +SRCS= hostapd_cli.c wpa_ctrl.c + +MAN= hostapd_cli.8 + +.include diff --git a/usr.sbin/802_11/hostapd_cli/hostapd_cli.8 b/usr.sbin/802_11/hostapd_cli/hostapd_cli.8 new file mode 100644 index 0000000000..03baa67ed9 --- /dev/null +++ b/usr.sbin/802_11/hostapd_cli/hostapd_cli.8 @@ -0,0 +1,113 @@ +.\" Copyright (c) 2005 Sam Leffler +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD: src/usr.sbin/wpa/hostapd_cli/hostapd_cli.8,v 1.2 2005/06/27 06:40:43 ru Exp $ +.\" $DragonFly: src/usr.sbin/802_11/hostapd_cli/hostapd_cli.8,v 1.1 2006/09/02 05:40:35 sephe Exp $ +.\" +.Dd August 19, 2006 +.Dt HOSTAPD_CLI 8 +.Os +.Sh NAME +.Nm hostapd_cli +.Nd text-based frontend program for interacting with +.Xr hostapd 8 +.Sh SYNOPSIS +.Nm +.Op Ar commands +.Sh DESCRIPTION +The +.Nm +utility +is a text-based frontend program for interacting with +.Xr hostapd 8 . +It is used to query the current status. +.Pp +The +.Nm +utility +can show the +current authentication status, +dot11 and dot1x MIBs, etc. +.Pp +The +.Nm +utility +supports two modes: interactive and command line. +Both modes share the same command set. +.Pp +Interactive mode is started when +.Nm +is executed without any parameters on the command line. +Commands are then entered from the controlling terminal in +response to the +.Nm +prompt. +In command line mode, the same commands are +entered as command line arguments. +.Sh COMMANDS +The following commands may be supplied on the command line +or at a prompt when operating interactively. +.Bl -tag -width indent +.It Ic mib +Report MIB variables (dot1x, dot11) for the current interface. +.It Ic sta Ar addr +Report the MIB variables for the associated station with MAC address +.Ar addr . +.It Ic all_sta +Report the MIB variables for all associated stations. +.It Ic help +Show usage help. +.It Ic interface Op Ar ifname +Show available interfaces and/or set the current interface +when multiple are available. +.It Ic level Ar debug_level +Change the debugging level in +.Xr hostapd 8 . +Larger numbers generate more messages. +.It Ic license +Display the full +license for +.Nm . +.It Ic quit +Exit +.Nm . +.El +.Sh SEE ALSO +.Xr hostapd.conf 5 , +.Xr hostapd 8 +.Sh HISTORY +The +.Nm +utility first appeared in +.Fx 6.0 . +.Sh AUTHORS +The +.Nm +utility was written by +.An Jouni Malinen Aq jkmaline@cc.hut.fi . +This manual page is derived from the +.Pa README +file included in the +.Nm hostapd +distribution. diff --git a/usr.sbin/802_11/l2_packet.c b/usr.sbin/802_11/l2_packet.c index 8b2147f15d..78bfda610d 100644 --- a/usr.sbin/802_11/l2_packet.c +++ b/usr.sbin/802_11/l2_packet.c @@ -13,7 +13,7 @@ * See README and COPYING for more details. * * $FreeBSD: src/usr.sbin/wpa/l2_packet.c,v 1.1.2.2 2006/03/24 01:43:17 sam Exp $ - * $DragonFly: src/usr.sbin/802_11/l2_packet.c,v 1.1 2006/06/24 07:29:44 sephe Exp $ + * $DragonFly: src/usr.sbin/802_11/l2_packet.c,v 1.2 2006/09/02 05:40:35 sephe Exp $ */ /* @@ -32,6 +32,7 @@ #include #include +#include #include #include #include @@ -52,6 +53,53 @@ struct l2_packet_data { * buffers */ }; +/* + * The version of libpcap in FreeBSD 5.2.1 doesn't have these routines. + * Call me insane if you will, but I still run 5.2.1 on my laptop, and + * I'd like to use WPA there. + */ + +int +pcap_get_selectable_fd(pcap_t *p) +{ + return(pcap_fileno(p)); +} + +/* + * The old version of libpcap opens its BPF descriptor in read-only + * mode. We need to temporarily create a new one we can write to. + */ + +int +pcap_inject(pcap_t *p, const void *buf, size_t len) +{ + int fd; + int res, n = 0; + char device[sizeof "/dev/bpf0000000000"]; + struct ifreq ifr; + + /* + * Go through all the minors and find one that isn't in use. + */ + do { + (void)snprintf(device, sizeof(device), "/dev/bpf%d", n++); + fd = open(device, O_RDWR); + } while (fd < 0 && errno == EBUSY); + + if (fd == -1) + return(-1); + + bzero((char *)&ifr, sizeof(ifr)); + ioctl(pcap_fileno(p), BIOCGETIF, (caddr_t)&ifr); + ioctl(fd, BIOCSETIF, (caddr_t)&ifr); + + res = write(fd, buf, len); + + close(fd); + + return(res); +} + int l2_packet_get_own_addr(struct l2_packet_data *l2, u8 *addr) { diff --git a/usr.sbin/802_11/wpa_supplicant/Packet32.c b/usr.sbin/802_11/wpa_supplicant/Packet32.c index 6ec865d1fd..577733905e 100644 --- a/usr.sbin/802_11/wpa_supplicant/Packet32.c +++ b/usr.sbin/802_11/wpa_supplicant/Packet32.c @@ -30,7 +30,7 @@ * THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/usr.sbin/wpa/wpa_supplicant/Packet32.c,v 1.2.2.2 2006/04/12 17:21:08 sam Exp $ - * $DragonFly: src/usr.sbin/802_11/wpa_supplicant/Packet32.c,v 1.1 2006/06/24 07:29:44 sephe Exp $ + * $DragonFly: src/usr.sbin/802_11/wpa_supplicant/Packet32.c,v 1.2 2006/09/02 05:40:35 sephe Exp $ */ /* @@ -345,53 +345,3 @@ PacketCloseAdapter(iface) return; } - -#if __FreeBSD_version < 600000 - -/* - * The version of libpcap in FreeBSD 5.2.1 doesn't have these routines. - * Call me insane if you will, but I still run 5.2.1 on my laptop, and - * I'd like to use WPA there. - */ - -int -pcap_get_selectable_fd(pcap_t *p) -{ - return(pcap_fileno(p)); -} - -/* - * The old version of libpcap opens its BPF descriptor in read-only - * mode. We need to temporarily create a new one we can write to. - */ - -int -pcap_inject(pcap_t *p, const void *buf, size_t len) -{ - int fd; - int res, n = 0; - char device[sizeof "/dev/bpf0000000000"]; - struct ifreq ifr; - - /* - * Go through all the minors and find one that isn't in use. - */ - do { - (void)snprintf(device, sizeof(device), "/dev/bpf%d", n++); - fd = open(device, O_RDWR); - } while (fd < 0 && errno == EBUSY); - - if (fd == -1) - return(-1); - - bzero((char *)&ifr, sizeof(ifr)); - ioctl(pcap_fileno(p), BIOCGETIF, (caddr_t)&ifr); - ioctl(fd, BIOCSETIF, (caddr_t)&ifr); - - res = write(fd, buf, len); - - close(fd); - - return(res); -} -#endif