From 3c410aba9723d503205a5dafb05c486258b42326 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Mon, 11 Jun 2018 19:47:52 -0400 Subject: [PATCH] freebsd11_wlan: Copy Haiku-specific files from FreeBSD 9 directory. Again, unmodified. --- .../compat/freebsd11_wlan/net80211/Jamfile | 65 ++ .../net80211/ieee80211_haiku.cpp | 753 ++++++++++++++++++ .../freebsd11_wlan/net80211/ieee80211_haiku.h | 395 +++++++++ .../compat/freebsd11_wlan/net80211/opt_inet.h | 6 + .../freebsd11_wlan/net80211/opt_inet6.h | 6 + .../compat/freebsd11_wlan/net80211/opt_ipx.h | 6 + .../compat/freebsd11_wlan/net80211/opt_wlan.h | 8 + 7 files changed, 1239 insertions(+) create mode 100644 src/libs/compat/freebsd11_wlan/net80211/Jamfile create mode 100644 src/libs/compat/freebsd11_wlan/net80211/ieee80211_haiku.cpp create mode 100644 src/libs/compat/freebsd11_wlan/net80211/ieee80211_haiku.h create mode 100644 src/libs/compat/freebsd11_wlan/net80211/opt_inet.h create mode 100644 src/libs/compat/freebsd11_wlan/net80211/opt_inet6.h create mode 100644 src/libs/compat/freebsd11_wlan/net80211/opt_ipx.h create mode 100644 src/libs/compat/freebsd11_wlan/net80211/opt_wlan.h diff --git a/src/libs/compat/freebsd11_wlan/net80211/Jamfile b/src/libs/compat/freebsd11_wlan/net80211/Jamfile new file mode 100644 index 0000000000..bff3d75686 --- /dev/null +++ b/src/libs/compat/freebsd11_wlan/net80211/Jamfile @@ -0,0 +1,65 @@ +SubDir HAIKU_TOP src libs compat freebsd_wlan net80211 ; + +UseHeaders [ FDirName $(SUBDIR) .. .. freebsd_network ] : true ; +UseHeaders [ FDirName $(SUBDIR) .. .. freebsd_network compat ] : true ; +UseHeaders [ FDirName $(SUBDIR) .. ] : true ; +UseHeaders [ FDirName $(SUBDIR) ] : true ; +UsePrivateHeaders net system ; +UsePrivateKernelHeaders ; + +# Enabling C++ structures in C only code +Includes [ FGristFiles kernel_c++_structs.h ] + : kernel_c++_struct_sizes.h ; + +SubDirCcFlags [ FDefines _KERNEL=1 FBSD_DRIVER=1 ] + -Wno-format -Wno-unused -Wno-uninitialized ; +SubDirC++Flags [ FDefines _KERNEL=1 FBSD_DRIVER=1 ] + -Wno-format -Wno-unused -Wno-uninitialized ; + +SEARCH_SOURCE += [ FDirName $(SUBDIR) .. crypto rijndael ] ; + +KernelStaticLibrary libfreebsd_wlan.a : + ieee80211.c + ieee80211_action.c + ieee80211_adhoc.c + ieee80211_ageq.c + ieee80211_amrr.c + ieee80211_crypto.c + ieee80211_crypto_ccmp.c + ieee80211_crypto_none.c + ieee80211_crypto_tkip.c + ieee80211_crypto_wep.c + ieee80211_dfs.c + ieee80211_haiku.cpp + ieee80211_ht.c + ieee80211_input.c + ieee80211_ioctl.c + ieee80211_hostap.c + ieee80211_monitor.c + ieee80211_node.c + ieee80211_output.c + ieee80211_phy.c + ieee80211_power.c + ieee80211_proto.c + ieee80211_radiotap.c + ieee80211_ratectl.c + ieee80211_ratectl_none.c + ieee80211_regdomain.c + ieee80211_rssadapt.c + ieee80211_scan_sta.c + ieee80211_scan.c + ieee80211_sta.c + ieee80211_wds.c + + # Rijndael (aka AES) cryptographic support for crypto_ccmp + rijndael-alg-fst.c + rijndael-api.c + + # NOT SUPPORTED YET ieee80211_acl.c + # NOT SUPPORTED YET ieee80211_ddb.c + # NOT SUPPORTED YET ieee80211_hwmp.c + # NOT SUPPORTED YET ieee80211_mesh.c + # NOT SUPPORTED YET ieee80211_superg.c + # NOT SUPPORTED YET ieee80211_tdma.c + ieee80211_xauth.c +; diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_haiku.cpp b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_haiku.cpp new file mode 100644 index 0000000000..54e7ce714b --- /dev/null +++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_haiku.cpp @@ -0,0 +1,753 @@ +/* + * Copyright 2009, Colin Günther, coling@gmx.de. + * All rights reserved. Distributed under the terms of the MIT License. + */ + + +/*- + * Copyright (c) 2003-2009 Sam Leffler, Errno Consulting + * 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 ``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 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. + */ + + +/* + * IEEE 802.11 support (Haiku-specific code) + */ + + +#include "ieee80211_haiku.h" + +extern "C" { +# include +# include +# include +# include + +# include +# include +# include +# include + +# include "ieee80211_var.h" +}; + +#include + +#include + +#include +#include +#include + +#include + + +#define TRACE_WLAN +#ifdef TRACE_WLAN +# define TRACE(x...) dprintf(x); +#else +# define TRACE(x...) ; +#endif + + +#define MC_ALIGN(m, len) \ +do { \ + (m)->m_data += (MCLBYTES - (len)) &~ (sizeof(long) - 1);\ +} while (/* CONSTCOND */ 0) + + +static net_notifications_module_info* sNotificationModule; + + +static struct ifnet* +get_ifnet(device_t device, int& i) +{ + int unit = device_get_unit(device); + + for (i = 0; i < MAX_DEVICES; i++) { + if (gDevices[i] != NULL && gDevices[i]->if_dunit == unit) + return gDevices[i]; + } + + return NULL; +} + + +status_t +init_wlan_stack(void) +{ + ieee80211_phy_init(); + ieee80211_auth_setup(); + ieee80211_ht_init(); + + get_module(NET_NOTIFICATIONS_MODULE_NAME, + (module_info**)&sNotificationModule); + + return B_OK; +} + + +void +uninit_wlan_stack(void) +{ + if (sNotificationModule != NULL) + put_module(NET_NOTIFICATIONS_MODULE_NAME); +} + + +status_t +start_wlan(device_t device) +{ + int i; + struct ifnet* ifp = get_ifnet(device, i); + if (ifp == NULL) + return B_BAD_VALUE; + +// TODO: review this and find a cleaner solution! + // This ensures that the cloned device gets + // the same index assigned as the base device + // Resulting in the same device name + // e.g.: /dev/net/atheros/0 instead of + // /dev/net/atheros/1 + gDevices[i] = NULL; + + struct ieee80211com* ic = (ieee80211com*)ifp->if_l2com; + + struct ieee80211vap* vap = ic->ic_vap_create(ic, "wlan", + device_get_unit(device), + IEEE80211_M_STA, // mode + 0, // flags + NULL, // BSSID + IF_LLADDR(ifp)); // MAC address + + if (vap == NULL) { + gDevices[i] = ifp; + return B_ERROR; + } + + // ic_vap_create() established that gDevices[i] links to vap->iv_ifp now + KASSERT(gDevices[i] == vap->iv_ifp, + ("start_wlan: gDevices[i] != vap->iv_ifp")); + + vap->iv_ifp->scan_done_sem = create_sem(0, "wlan scan done"); + + // We aren't connected to a WLAN, yet. + if_link_state_change(vap->iv_ifp, LINK_STATE_DOWN); + + dprintf("%s: wlan started.\n", __func__); + + return B_OK; +} + + +status_t +stop_wlan(device_t device) +{ + int i; + struct ifnet* ifp = get_ifnet(device, i); + if (ifp == NULL) + return B_BAD_VALUE; + + if (ifp->if_type == IFT_IEEE80211) { + // This happens when there was an error in starting the wlan before, + // resulting in never creating a clone device + return B_OK; + } + + delete_sem(ifp->scan_done_sem); + + struct ieee80211vap* vap = (ieee80211vap*)ifp->if_softc; + struct ieee80211com* ic = vap->iv_ic; + + ic->ic_vap_delete(vap); + + // ic_vap_delete freed gDevices[i] + KASSERT(gDevices[i] == NULL, ("stop_wlan: gDevices[i] != NULL")); + + // assign the base device ifp again + gDevices[i] = ic->ic_ifp; + + return B_OK; +} + + +status_t +wlan_open(void* cookie) +{ + dprintf("wlan_open(%p)\n", cookie); + struct ifnet* ifp = (struct ifnet*)cookie; + + ifp->if_init(ifp->if_softc); + + ifp->if_flags |= IFF_UP; + ifp->if_ioctl(ifp, SIOCSIFFLAGS, NULL); + + return B_OK; +} + + +status_t +wlan_close(void* cookie) +{ + dprintf("wlan_close(%p)\n", cookie); + struct ifnet* ifp = (struct ifnet*)cookie; + + ifp->if_flags &= ~IFF_UP; + ifp->if_ioctl(ifp, SIOCSIFFLAGS, NULL); + + return release_sem_etc(ifp->scan_done_sem, 1, B_RELEASE_ALL); +} + + +status_t +wlan_control(void* cookie, uint32 op, void* arg, size_t length) +{ + struct ifnet* ifp = (struct ifnet*)cookie; + + switch (op) { + case BOSII_DEVICE: + return B_OK; + + case BOSII_DETECT_NETWORKS: + { + struct ieee80211req request; + struct ieee80211_scan_req scanRequest; + + if_printf(ifp, "%s: BOSII_DETECT_NETWORKS\n", __func__); + memset(&scanRequest, 0, sizeof(scanRequest)); + scanRequest.sr_flags = IEEE80211_IOC_SCAN_ACTIVE + | IEEE80211_IOC_SCAN_NOPICK + | IEEE80211_IOC_SCAN_ONCE; + scanRequest.sr_duration = 10000; // 10 s + scanRequest.sr_nssid = 0; + + memset(&request, 0, sizeof(request)); + request.i_type = IEEE80211_IOC_SCAN_REQ; + request.i_data = &scanRequest; + request.i_len = sizeof(scanRequest); + + ifp->if_ioctl(ifp, SIOCS80211, (caddr_t)&request); + + acquire_sem_etc(ifp->scan_done_sem, 1, B_RELATIVE_TIMEOUT, + 10000000); // 10 s + + return B_OK; + } + + case BOSII_GET_DETECTED_NETWORKS: + { + struct ieee80211req request; + struct ifreq ifRequest; + struct route_entry* networkRequest = &ifRequest.ifr_route; + + if_printf(ifp, "%s: BOSII_GET_DETECTED_NETWORKS\n", __func__); + + if (length < sizeof(struct ieee80211req_scan_result)) + return B_BAD_VALUE; + + if (user_memcpy(&ifRequest, arg, sizeof(ifRequest)) < B_OK) + return B_BAD_ADDRESS; + + memset(&request, 0, sizeof(request)); + request.i_type = IEEE80211_IOC_SCAN_RESULTS; + request.i_len = length; + request.i_data = networkRequest->destination; + + // After return value of request.i_data is copied into user + // space, already. + if (ifp->if_ioctl(ifp, SIOCG80211, (caddr_t)&request) < B_OK) + return B_BAD_ADDRESS; + + // Tell the user space how much data was copied + networkRequest->mtu = request.i_len; + if (user_memcpy(&((struct ifreq*)arg)->ifr_route.mtu, + &networkRequest->mtu, sizeof(networkRequest->mtu)) < B_OK) + return B_BAD_ADDRESS; + + return B_OK; + } + + case BOSII_JOIN_NETWORK: + { + struct ieee80211req request; + struct ifreq ifRequest; + struct route_entry* networkRequest = &ifRequest.ifr_route; + struct ieee80211req_scan_result network; + + if_printf(ifp, "%s: BOSII_JOIN_NETWORK\n", __func__); + + if (length < sizeof(struct ifreq)) + return B_BAD_VALUE; + + if (user_memcpy(&ifRequest, arg, sizeof(ifRequest)) != B_OK + || user_memcpy(&network, networkRequest->source, + sizeof(ieee80211req_scan_result)) != B_OK) + return B_BAD_ADDRESS; + + memset(&request, 0, sizeof(ieee80211req)); + + request.i_type = IEEE80211_IOC_SSID; + request.i_val = 0; + request.i_len = network.isr_ssid_len; + request.i_data = (uint8*)networkRequest->source + + network.isr_ie_off; + if (ifp->if_ioctl(ifp, SIOCS80211, (caddr_t)&request) < B_OK) + return B_ERROR; + + // wait for network join + + return B_OK; + } + + case BOSII_GET_ASSOCIATED_NETWORK: + { + struct ieee80211req request; + struct ifreq ifRequest; + struct route_entry* networkRequest = &ifRequest.ifr_route; + + if_printf(ifp, "%s: BOSII_GET_ASSOCIATED_NETWORK\n", __func__); + + if (length < sizeof(struct ieee80211req_sta_req)) + return B_BAD_VALUE; + + if (user_memcpy(&ifRequest, arg, sizeof(ifRequest)) < B_OK) + return B_BAD_ADDRESS; + + // Only want station information about associated network. + memset(&request, 0, sizeof(request)); + request.i_type = IEEE80211_IOC_BSSID; + request.i_len = IEEE80211_ADDR_LEN; + request.i_data = ((struct ieee80211req_sta_req*)networkRequest-> + destination)->is_u.macaddr; + if (ifp->if_ioctl(ifp, SIOCG80211, (caddr_t)&request) < B_OK) + return B_BAD_ADDRESS; + + request.i_type = IEEE80211_IOC_STA_INFO; + request.i_len = length; + request.i_data = networkRequest->destination; + + // After return value of request.i_data is copied into user + // space, already. + if (ifp->if_ioctl(ifp, SIOCG80211, (caddr_t)&request) < B_OK) + return B_BAD_ADDRESS; + + // Tell the user space how much data was copied + networkRequest->mtu = request.i_len; + if (user_memcpy(&((struct ifreq*)arg)->ifr_route.mtu, + &networkRequest->mtu, sizeof(networkRequest->mtu)) != B_OK) + return B_BAD_ADDRESS; + + return B_OK; + } + + case SIOCG80211: + case SIOCS80211: + { + // Allowing FreeBSD based WLAN ioctls to pass, as those will become + // the future Haiku WLAN ioctls anyway. + + // FreeBSD drivers assume that the request structure has already + // been copied into kernel space + struct ieee80211req request; + if (user_memcpy(&request, arg, sizeof(struct ieee80211req)) != B_OK) + return B_BAD_ADDRESS; + + if (request.i_type == IEEE80211_IOC_HAIKU_COMPAT_WLAN_UP) + return wlan_open(cookie); + else if (request.i_type == IEEE80211_IOC_HAIKU_COMPAT_WLAN_DOWN) + return wlan_close(cookie); + + TRACE("wlan_control: %ld, %d\n", op, request.i_type); + status_t status = ifp->if_ioctl(ifp, op, (caddr_t)&request); + if (status != B_OK) + return status; + + if (op == SIOCG80211 && user_memcpy(arg, &request, + sizeof(struct ieee80211req)) != B_OK) + return B_BAD_ADDRESS; + return B_OK; + } + + case SIOCSIFFLAGS: + case SIOCSIFMEDIA: + case SIOCGIFMEDIA: + case SIOCSIFMTU: + // Requests that make it here always come from the kernel + return ifp->if_ioctl(ifp, op, (caddr_t)arg); + } + + return B_BAD_VALUE; +} + + +status_t +wlan_if_l2com_alloc(void* data) +{ + struct ifnet* ifp = (struct ifnet*)data; + + ifp->if_l2com = _kernel_malloc(sizeof(struct ieee80211com), M_ZERO); + if (ifp->if_l2com == NULL) + return B_NO_MEMORY; + ((struct ieee80211com*)(ifp->if_l2com))->ic_ifp = ifp; + return B_OK; +} + + +void +get_random_bytes(void* p, size_t n) +{ + uint8_t* dp = (uint8_t*)p; + + while (n > 0) { + uint32_t v = arc4random(); + size_t nb = n > sizeof(uint32_t) ? sizeof(uint32_t) : n; + bcopy(&v, dp, n > sizeof(uint32_t) ? sizeof(uint32_t) : n); + dp += sizeof(uint32_t), n -= nb; + } +} + + +struct mbuf* +ieee80211_getmgtframe(uint8_t** frm, int headroom, int pktlen) +{ + struct mbuf* m; + u_int len; + + len = roundup2(headroom + pktlen, 4); + KASSERT(len <= MCLBYTES, ("802.11 mgt frame too large: %u", len)); + if (len < MINCLSIZE) { + m = m_gethdr(M_NOWAIT, MT_DATA); + if (m != NULL) + MH_ALIGN(m, len); + } else { + m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); + if (m != NULL) + MC_ALIGN(m, len); + } + if (m != NULL) { + m->m_data += headroom; + *frm = (uint8_t*)m->m_data; + } + return m; +} + + +/* + * Decrements the reference-counter and + * tests whether it became zero. If so, sets it to one. + * + * @return 1 reference-counter became zero + * @return 0 reference-counter didn't became zero + */ +int +ieee80211_node_dectestref(struct ieee80211_node* ni) +{ + atomic_subtract_int(&ni->ni_refcnt, 1); + return atomic_cmpset_int(&ni->ni_refcnt, 0, 1); +} + + +void +ieee80211_drain_ifq(struct ifqueue* ifq) +{ + struct ieee80211_node* ni; + struct mbuf* m; + + for (;;) { + IF_DEQUEUE(ifq, m); + if (m == NULL) + break; + + ni = (struct ieee80211_node*)m->m_pkthdr.rcvif; + KASSERT(ni != NULL, ("frame w/o node")); + ieee80211_free_node(ni); + m->m_pkthdr.rcvif = NULL; + + m_freem(m); + } +} + + +void +ieee80211_flush_ifq(struct ifqueue* ifq, struct ieee80211vap* vap) +{ + struct ieee80211_node* ni; + struct mbuf* m; + struct mbuf** mprev; + + IF_LOCK(ifq); + mprev = &ifq->ifq_head; + while ((m = *mprev) != NULL) { + ni = (struct ieee80211_node*)m->m_pkthdr.rcvif; + if (ni != NULL && ni->ni_vap == vap) { + *mprev = m->m_nextpkt; + // remove from list + ifq->ifq_len--; + + m_freem(m); + ieee80211_free_node(ni); + // reclaim ref + } else + mprev = &m->m_nextpkt; + } + // recalculate tail ptr + m = ifq->ifq_head; + for (; m != NULL && m->m_nextpkt != NULL; m = m->m_nextpkt); + ifq->ifq_tail = m; + IF_UNLOCK(ifq); +} + + +int +ieee80211_add_callback(struct mbuf* m, + void (*func)(struct ieee80211_node*, void*, int), void* arg) +{ + struct m_tag* mtag; + struct ieee80211_cb* cb; + + mtag = m_tag_alloc(MTAG_ABI_NET80211, NET80211_TAG_CALLBACK, + sizeof(struct ieee80211_cb), M_NOWAIT); + if (mtag == NULL) + return 0; + + cb = (struct ieee80211_cb*)(mtag+1); + cb->func = func; + cb->arg = arg; + m_tag_prepend(m, mtag); + m->m_flags |= M_TXCB; + return 1; +} + + +void +ieee80211_process_callback(struct ieee80211_node* ni, struct mbuf* m, + int status) +{ + struct m_tag* mtag; + + mtag = m_tag_locate(m, MTAG_ABI_NET80211, NET80211_TAG_CALLBACK, NULL); + if (mtag != NULL) { + struct ieee80211_cb* cb = (struct ieee80211_cb*)(mtag+1); + cb->func(ni, cb->arg, status); + } +} + + +void +ieee80211_sysctl_vattach(struct ieee80211vap* vap) +{ + vap->iv_debug = IEEE80211_MSG_XRATE + | IEEE80211_MSG_NODE + | IEEE80211_MSG_ASSOC + | IEEE80211_MSG_AUTH + | IEEE80211_MSG_STATE + | IEEE80211_MSG_POWER + | IEEE80211_MSG_WME + | IEEE80211_MSG_DOTH + | IEEE80211_MSG_INACT + | IEEE80211_MSG_ROAM + | IEEE80211_MSG_RATECTL; +} + + +void +ieee80211_sysctl_vdetach(struct ieee80211vap* vap) +{ + dprintf("%s not implemented, yet.\n", __func__); +} + + +void +ieee80211_vap_destroy(struct ieee80211vap* vap) +{ + struct ieee80211com* ic = vap->iv_ic; + + ic->ic_vap_delete(vap); + dprintf("%s: done.\n", __func__); +} + + +void +ieee80211_load_module(const char* modname) +{ + dprintf("%s not implemented, yet: modname %s\n", __func__, modname); +} + + +void +ieee80211_notify_node_join(struct ieee80211_node* ni, int newassoc) +{ + struct ieee80211vap* vap = ni->ni_vap; + struct ifnet* ifp = vap->iv_ifp; + + if (ni == vap->iv_bss) + if_link_state_change(ifp, LINK_STATE_UP); + + TRACE("%s\n", __FUNCTION__); + + if (sNotificationModule != NULL) { + char messageBuffer[512]; + KMessage message; + message.SetTo(messageBuffer, sizeof(messageBuffer), B_NETWORK_MONITOR); + message.AddInt32("opcode", B_NETWORK_WLAN_JOINED); + message.AddString("interface", ifp->device_name); + // TODO: add data about the node + + sNotificationModule->send_notification(&message); + } +} + + +void +ieee80211_notify_node_leave(struct ieee80211_node* ni) +{ + struct ieee80211vap* vap = ni->ni_vap; + struct ifnet* ifp = vap->iv_ifp; + + if (ni == vap->iv_bss) + if_link_state_change(ifp, LINK_STATE_DOWN); + + TRACE("%s\n", __FUNCTION__); + + if (sNotificationModule != NULL) { + char messageBuffer[512]; + KMessage message; + message.SetTo(messageBuffer, sizeof(messageBuffer), B_NETWORK_MONITOR); + message.AddInt32("opcode", B_NETWORK_WLAN_LEFT); + message.AddString("interface", ifp->device_name); + // TODO: add data about the node + + sNotificationModule->send_notification(&message); + } +} + + +void +ieee80211_notify_scan_done(struct ieee80211vap* vap) +{ + release_sem_etc(vap->iv_ifp->scan_done_sem, 1, + B_DO_NOT_RESCHEDULE | B_RELEASE_ALL); + + TRACE("%s\n", __FUNCTION__); + + if (sNotificationModule != NULL) { + char messageBuffer[512]; + KMessage message; + message.SetTo(messageBuffer, sizeof(messageBuffer), B_NETWORK_MONITOR); + message.AddInt32("opcode", B_NETWORK_WLAN_SCANNED); + message.AddString("interface", vap->iv_ifp->device_name); + + sNotificationModule->send_notification(&message); + } +} + + +void +ieee80211_notify_replay_failure(struct ieee80211vap* vap, + const struct ieee80211_frame* wh, const struct ieee80211_key* k, + u_int64_t rsc, int tid) +{ + dprintf("%s not implemented, yet.\n", __func__); +} + + +void +ieee80211_notify_michael_failure(struct ieee80211vap* vap, + const struct ieee80211_frame* wh, u_int keyix) +{ + dprintf("%s not implemented, yet.\n", __func__); +} + + +void +ieee80211_notify_wds_discover(struct ieee80211_node* ni) +{ + dprintf("%s not implemented, yet.\n", __func__); +} + + +void +ieee80211_notify_csa(struct ieee80211com* ic, + const struct ieee80211_channel* c, int mode, int count) +{ + dprintf("%s not implemented, yet.\n", __func__); +} + + +void +ieee80211_notify_radar(struct ieee80211com* ic, + const struct ieee80211_channel* c) +{ + dprintf("%s not implemented, yet.\n", __func__); +} + + +void +ieee80211_notify_cac(struct ieee80211com* ic, + const struct ieee80211_channel* c, enum ieee80211_notify_cac_event type) +{ + dprintf("%s not implemented, yet.\n", __func__); +} + + +void +ieee80211_notify_node_deauth(struct ieee80211_node* ni) +{ + dprintf("%s not implemented, yet.\n", __func__); +} + + +void +ieee80211_notify_node_auth(struct ieee80211_node* ni) +{ + dprintf("%s not implemented, yet.\n", __func__); +} + + +void +ieee80211_notify_country(struct ieee80211vap* vap, + const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t cc[2]) +{ + dprintf("%s not implemented, yet.\n", __func__); +} + + +void +ieee80211_notify_radio(struct ieee80211com* ic, int state) +{ + dprintf("%s not implemented, yet.\n", __func__); +} + + +void +ieee80211_sysctl_attach(struct ieee80211com* ic) +{ + dprintf("%s not implemented, yet.\n", __func__); +} + + +void +ieee80211_sysctl_detach(struct ieee80211com* ic) +{ + dprintf("%s not implemented, yet.\n", __func__); +} diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_haiku.h b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_haiku.h new file mode 100644 index 0000000000..c2735078f1 --- /dev/null +++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_haiku.h @@ -0,0 +1,395 @@ +/*- + * Copyright (c) 2003-2008 Sam Leffler, Errno Consulting + * 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 ``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 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$ + */ +#ifndef _FBSD_COMPAT_NET80211_IEEE80211_HAIKU_H_ +#define _FBSD_COMPAT_NET80211_IEEE80211_HAIKU_H_ + + +#include + + +#ifdef _KERNEL + +# ifdef __cplusplus +// Those includes are needed to avoid C/C++ function export clashes +# include +# include +extern "C" { +# endif + +#define INVARIANTS 1 + +#include +#include +#include +#include + + +#define IEEE80211_CRYPTO_MODULE(name, version) \ + void \ + ieee80211_crypto_##name##_load() { \ + ieee80211_crypto_register(&name); \ + } \ +\ +\ + void \ + ieee80211_crypto_##name##_unload() \ + { \ + ieee80211_crypto_unregister(&name); \ + } + + +/* + * Common state locking definitions. + */ +typedef struct { + char name[16]; /* e.g. "ath0_com_lock" */ + struct mtx mtx; +} ieee80211_com_lock_t; +#define IEEE80211_LOCK_INIT(_ic, _name) do { \ + ieee80211_com_lock_t *cl = &(_ic)->ic_comlock; \ + snprintf(cl->name, sizeof(cl->name), "%s_com_lock", _name); \ + mtx_init(&cl->mtx, cl->name, NULL, MTX_DEF | MTX_RECURSE); \ +} while (0) +#define IEEE80211_LOCK_OBJ(_ic) (&(_ic)->ic_comlock.mtx) +#define IEEE80211_LOCK_DESTROY(_ic) mtx_destroy(IEEE80211_LOCK_OBJ(_ic)) +#define IEEE80211_LOCK(_ic) mtx_lock(IEEE80211_LOCK_OBJ(_ic)) +#define IEEE80211_UNLOCK(_ic) mtx_unlock(IEEE80211_LOCK_OBJ(_ic)) +#define IEEE80211_LOCK_ASSERT(_ic) \ + mtx_assert(IEEE80211_LOCK_OBJ(_ic), MA_OWNED) + +/* + * Node locking definitions. + */ +typedef struct { + char name[16]; /* e.g. "ath0_node_lock" */ + struct mtx mtx; +} ieee80211_node_lock_t; +#define IEEE80211_NODE_LOCK_INIT(_nt, _name) do { \ + ieee80211_node_lock_t *nl = &(_nt)->nt_nodelock; \ + snprintf(nl->name, sizeof(nl->name), "%s_node_lock", _name); \ + mtx_init(&nl->mtx, nl->name, NULL, MTX_DEF | MTX_RECURSE); \ +} while (0) +#define IEEE80211_NODE_LOCK_OBJ(_nt) (&(_nt)->nt_nodelock.mtx) +#define IEEE80211_NODE_LOCK_DESTROY(_nt) \ + mtx_destroy(IEEE80211_NODE_LOCK_OBJ(_nt)) +#define IEEE80211_NODE_LOCK(_nt) \ + mtx_lock(IEEE80211_NODE_LOCK_OBJ(_nt)) +#define IEEE80211_NODE_IS_LOCKED(_nt) \ + mtx_owned(IEEE80211_NODE_LOCK_OBJ(_nt)) +#define IEEE80211_NODE_UNLOCK(_nt) \ + mtx_unlock(IEEE80211_NODE_LOCK_OBJ(_nt)) +#define IEEE80211_NODE_LOCK_ASSERT(_nt) \ + mtx_assert(IEEE80211_NODE_LOCK_OBJ(_nt), MA_OWNED) + +/* + * Node table iteration locking definitions; this protects the + * scan generation # used to iterate over the station table + * while grabbing+releasing the node lock. + */ +typedef struct { + char name[16]; /* e.g. "ath0_scan_lock" */ + struct mtx mtx; +} ieee80211_scan_lock_t; +#define IEEE80211_NODE_ITERATE_LOCK_INIT(_nt, _name) do { \ + ieee80211_scan_lock_t *sl = &(_nt)->nt_scanlock; \ + snprintf(sl->name, sizeof(sl->name), "%s_scan_lock", _name); \ + mtx_init(&sl->mtx, sl->name, NULL, MTX_DEF); \ +} while (0) +#define IEEE80211_NODE_ITERATE_LOCK_OBJ(_nt) (&(_nt)->nt_scanlock.mtx) +#define IEEE80211_NODE_ITERATE_LOCK_DESTROY(_nt) \ + mtx_destroy(IEEE80211_NODE_ITERATE_LOCK_OBJ(_nt)) +#define IEEE80211_NODE_ITERATE_LOCK(_nt) \ + mtx_lock(IEEE80211_NODE_ITERATE_LOCK_OBJ(_nt)) +#define IEEE80211_NODE_ITERATE_UNLOCK(_nt) \ + mtx_unlock(IEEE80211_NODE_ITERATE_LOCK_OBJ(_nt)) + +/* + * Power-save queue definitions. + */ +typedef struct mtx ieee80211_psq_lock_t; +#define IEEE80211_PSQ_INIT(_psq, _name) \ + mtx_init(&(_psq)->psq_lock, _name, "802.11 ps q", MTX_DEF) +#define IEEE80211_PSQ_DESTROY(_psq) mtx_destroy(&(_psq)->psq_lock) +#define IEEE80211_PSQ_LOCK(_psq) mtx_lock(&(_psq)->psq_lock) +#define IEEE80211_PSQ_UNLOCK(_psq) mtx_unlock(&(_psq)->psq_lock) + +#ifndef IF_PREPEND_LIST +#define _IF_PREPEND_LIST(ifq, mhead, mtail, mcount) do { \ + (mtail)->m_nextpkt = (ifq)->ifq_head; \ + if ((ifq)->ifq_tail == NULL) \ + (ifq)->ifq_tail = (mtail); \ + (ifq)->ifq_head = (mhead); \ + (ifq)->ifq_len += (mcount); \ +} while (0) +#define IF_PREPEND_LIST(ifq, mhead, mtail, mcount) do { \ + IF_LOCK(ifq); \ + _IF_PREPEND_LIST(ifq, mhead, mtail, mcount); \ + IF_UNLOCK(ifq); \ +} while (0) +#endif /* IF_PREPEND_LIST */ + +/* + * Age queue definitions. + */ +typedef struct mtx ieee80211_ageq_lock_t; +#define IEEE80211_AGEQ_INIT(_aq, _name) \ + mtx_init(&(_aq)->aq_lock, _name, "802.11 age q", MTX_DEF) +#define IEEE80211_AGEQ_DESTROY(_aq) mtx_destroy(&(_aq)->aq_lock) +#define IEEE80211_AGEQ_LOCK(_aq) mtx_lock(&(_aq)->aq_lock) +#define IEEE80211_AGEQ_UNLOCK(_aq) mtx_unlock(&(_aq)->aq_lock) + +/* + * Scan table definitions. + */ +typedef struct mtx ieee80211_scan_table_lock_t; +#define IEEE80211_SCAN_TABLE_LOCK_INIT(_st, _name) \ + mtx_init(&(_st)->st_lock, _name, "802.11 scan table", MTX_DEF) +#define IEEE80211_SCAN_TABLE_LOCK_DESTROY(_st) mtx_destroy(&(_st)->st_lock) +#define IEEE80211_SCAN_TABLE_LOCK(_st) mtx_lock(&(_st)->st_lock) +#define IEEE80211_SCAN_TABLE_UNLOCK(_st) mtx_unlock(&(_st)->st_lock) + +/* + * Node reference counting definitions. + * + * ieee80211_node_initref initialize the reference count to 1 + * ieee80211_node_incref add a reference + * ieee80211_node_decref remove a reference + * ieee80211_node_dectestref remove a reference and return 1 if this + * is the last reference, otherwise 0 + * ieee80211_node_refcnt reference count for printing (only) + */ +#include + +#define ieee80211_node_initref(_ni) \ + do { ((_ni)->ni_refcnt = 1); } while (0) +#define ieee80211_node_incref(_ni) \ + atomic_add_int(&(_ni)->ni_refcnt, 1) +#define ieee80211_node_decref(_ni) \ + atomic_subtract_int(&(_ni)->ni_refcnt, 1) +struct ieee80211_node; +int ieee80211_node_dectestref(struct ieee80211_node *ni); +#define ieee80211_node_refcnt(_ni) (_ni)->ni_refcnt + +struct ifqueue; +struct ieee80211vap; +void ieee80211_drain_ifq(struct ifqueue *); +void ieee80211_flush_ifq(struct ifqueue *, struct ieee80211vap *); + +void ieee80211_vap_destroy(struct ieee80211vap *); + +#define IFNET_IS_UP_RUNNING(_ifp) \ + (((_ifp)->if_flags & IFF_UP) && \ + ((_ifp)->if_drv_flags & IFF_DRV_RUNNING)) + +#define msecs_to_ticks(ms) (((ms)*hz)/1000) +#define ticks_to_msecs(t) (1000*(t) / hz) +#define ticks_to_secs(t) ((t) / hz) +#define time_after(a,b) ((long long)(b) - (long long)(a) < 0) +#define time_before(a,b) time_after(b,a) +#define time_after_eq(a,b) ((long long)(a) - (long long)(b) >= 0) +#define time_before_eq(a,b) time_after_eq(b,a) + +struct mbuf *ieee80211_getmgtframe(uint8_t **frm, int headroom, int pktlen); + +/* tx path usage */ +#define M_ENCAP M_PROTO1 /* 802.11 encap done */ +#define M_EAPOL M_PROTO3 /* PAE/EAPOL frame */ +#define M_PWR_SAV M_PROTO4 /* bypass PS handling */ +#define M_MORE_DATA M_PROTO5 /* more data frames to follow */ +#define M_FF M_PROTO6 /* fast frame */ +#define M_TXCB M_PROTO7 /* do tx complete callback */ +#define M_AMPDU_MPDU M_PROTO8 /* ok for A-MPDU aggregation */ +#define M_80211_TX \ + (M_FRAG|M_FIRSTFRAG|M_LASTFRAG|M_ENCAP|M_EAPOL|M_PWR_SAV|\ + M_MORE_DATA|M_FF|M_TXCB|M_AMPDU_MPDU) + +/* rx path usage */ +#define M_AMPDU M_PROTO1 /* A-MPDU subframe */ +#define M_WEP M_PROTO2 /* WEP done by hardware */ +#if 0 +#define M_AMPDU_MPDU M_PROTO8 /* A-MPDU re-order done */ +#endif +#define M_80211_RX (M_AMPDU|M_WEP|M_AMPDU_MPDU) + +/* + * Store WME access control bits in the vlan tag. + * This is safe since it's done after the packet is classified + * (where we use any previous tag) and because it's passed + * directly in to the driver and there's no chance someone + * else will clobber them on us. + */ +#define M_WME_SETAC(m, ac) \ + ((m)->m_pkthdr.ether_vtag = (ac)) +#define M_WME_GETAC(m) ((m)->m_pkthdr.ether_vtag) + +/* + * Mbufs on the power save queue are tagged with an age and + * timed out. We reuse the hardware checksum field in the + * mbuf packet header to store this data. + */ +#define M_AGE_SET(m,v) (m->m_pkthdr.csum_data = v) +#define M_AGE_GET(m) (m->m_pkthdr.csum_data) +#define M_AGE_SUB(m,adj) (m->m_pkthdr.csum_data -= adj) + +/* + * Store the sequence number. + */ +#define M_SEQNO_SET(m, seqno) \ + ((m)->m_pkthdr.tso_segsz = (seqno)) +#define M_SEQNO_GET(m) ((m)->m_pkthdr.tso_segsz) + +#define MTAG_ABI_NET80211 1132948340 /* net80211 ABI */ + +struct ieee80211_cb { + void (*func)(struct ieee80211_node *, void *, int status); + void *arg; +}; +#define NET80211_TAG_CALLBACK 0 /* xmit complete callback */ + +int ieee80211_add_callback(struct mbuf *m, + void (*func)(struct ieee80211_node *, void *, int), void *arg); +void ieee80211_process_callback(struct ieee80211_node *, struct mbuf *, int); + +void get_random_bytes(void *, size_t); + +struct ieee80211com; + +void ieee80211_sysctl_attach(struct ieee80211com *); +void ieee80211_sysctl_detach(struct ieee80211com *); +void ieee80211_sysctl_vattach(struct ieee80211vap *); +void ieee80211_sysctl_vdetach(struct ieee80211vap *); + +void ieee80211_load_module(const char *); + +/* + * A "policy module" is an adjunct module to net80211 that provides + * functionality that typically includes policy decisions. This + * modularity enables extensibility and vendor-supplied functionality. + */ +#define _IEEE80211_POLICY_MODULE(policy, name, version) \ +typedef void (*policy##_setup)(int); \ +SET_DECLARE(policy##_set, policy##_setup); + +/* + * Authenticator modules handle 802.1x/WPA authentication. + */ +#define IEEE80211_AUTH_MODULE(name, version) \ + _IEEE80211_POLICY_MODULE(auth, name, version) + +#define IEEE80211_AUTH_ALG(name, alg, v) \ +static void \ +name##_modevent(int type) \ +{ \ + if (type == MOD_LOAD) \ + ieee80211_authenticator_register(alg, &v); \ + else \ + ieee80211_authenticator_unregister(alg); \ +} \ +TEXT_SET(auth_set, name##_modevent) + +/* + * Scanner modules provide scanning policy. + */ +#define IEEE80211_SCANNER_MODULE(name, version) +#define IEEE80211_SCANNER_ALG(name, alg, v) + + +void ieee80211_scan_sta_init(void); +void ieee80211_scan_sta_uninit(void); + + +/* + * Rate control modules provide tx rate control support. + */ +#define IEEE80211_RATECTL_MODULE(alg, version) \ + _IEEE80211_POLICY_MODULE(ratectl, alg, version); \ + +#define IEEE80211_RATECTL_ALG(name, alg, v) \ + void \ + ieee80211_ratectl_##name##_load() { \ + ieee80211_ratectl_register(alg, &v); \ + } \ +\ +\ + void \ + ieee80211_ratectl_##name##_unload() \ + { \ + ieee80211_ratectl_unregister(alg); \ + } + + +struct ieee80211req; +typedef int ieee80211_ioctl_getfunc(struct ieee80211vap *, + struct ieee80211req *); +SET_DECLARE(ieee80211_ioctl_getset, ieee80211_ioctl_getfunc); +#define IEEE80211_IOCTL_GET(_name, _get) TEXT_SET(ieee80211_ioctl_getset, _get) + +typedef int ieee80211_ioctl_setfunc(struct ieee80211vap *, + struct ieee80211req *); +SET_DECLARE(ieee80211_ioctl_setset, ieee80211_ioctl_setfunc); +#define IEEE80211_IOCTL_SET(_name, _set) TEXT_SET(ieee80211_ioctl_setset, _set) + +#ifdef __cplusplus +} +#endif +#endif /* _KERNEL */ + +/* + * Structure prepended to raw packets sent through the bpf + * interface when set to DLT_IEEE802_11_RADIO. This allows + * user applications to specify pretty much everything in + * an Atheros tx descriptor. XXX need to generalize. + * + * XXX cannot be more than 14 bytes as it is copied to a sockaddr's + * XXX sa_data area. + */ +struct ieee80211_bpf_params { + uint8_t ibp_vers; /* version */ +#define IEEE80211_BPF_VERSION 0 + uint8_t ibp_len; /* header length in bytes */ + uint8_t ibp_flags; +#define IEEE80211_BPF_SHORTPRE 0x01 /* tx with short preamble */ +#define IEEE80211_BPF_NOACK 0x02 /* tx with no ack */ +#define IEEE80211_BPF_CRYPTO 0x04 /* tx with h/w encryption */ +#define IEEE80211_BPF_FCS 0x10 /* frame incldues FCS */ +#define IEEE80211_BPF_DATAPAD 0x20 /* frame includes data padding */ +#define IEEE80211_BPF_RTS 0x40 /* tx with RTS/CTS */ +#define IEEE80211_BPF_CTS 0x80 /* tx with CTS only */ + uint8_t ibp_pri; /* WME/WMM AC+tx antenna */ + uint8_t ibp_try0; /* series 1 try count */ + uint8_t ibp_rate0; /* series 1 IEEE tx rate */ + uint8_t ibp_power; /* tx power (device units) */ + uint8_t ibp_ctsrate; /* IEEE tx rate for CTS */ + uint8_t ibp_try1; /* series 2 try count */ + uint8_t ibp_rate1; /* series 2 IEEE tx rate */ + uint8_t ibp_try2; /* series 3 try count */ + uint8_t ibp_rate2; /* series 3 IEEE tx rate */ + uint8_t ibp_try3; /* series 4 try count */ + uint8_t ibp_rate3; /* series 4 IEEE tx rate */ +}; + +#endif /* _FBSD_COMPAT_NET80211_IEEE80211_HAIKU_H_ */ diff --git a/src/libs/compat/freebsd11_wlan/net80211/opt_inet.h b/src/libs/compat/freebsd11_wlan/net80211/opt_inet.h new file mode 100644 index 0000000000..16007efdfa --- /dev/null +++ b/src/libs/compat/freebsd11_wlan/net80211/opt_inet.h @@ -0,0 +1,6 @@ +#ifndef _FBSD_COMPAT_NET80211_OPT_INET_H_ +#define _FBSD_COMPAT_NET80211_OPT_INET_H_ + +#define INET 1 + +#endif /* _FBSD_COMPAT_NET80211_OPT_INET_H_ */ diff --git a/src/libs/compat/freebsd11_wlan/net80211/opt_inet6.h b/src/libs/compat/freebsd11_wlan/net80211/opt_inet6.h new file mode 100644 index 0000000000..6ae7676ed4 --- /dev/null +++ b/src/libs/compat/freebsd11_wlan/net80211/opt_inet6.h @@ -0,0 +1,6 @@ +#ifndef _FBSD_COMPAT_NET80211_OPT_INET6_H_ +#define _FBSD_COMPAT_NET80211_OPT_INET6_H_ + +//#define INET6 1 + +#endif /* _FBSD_COMPAT_NET80211_OPT_INET6_H_ */ diff --git a/src/libs/compat/freebsd11_wlan/net80211/opt_ipx.h b/src/libs/compat/freebsd11_wlan/net80211/opt_ipx.h new file mode 100644 index 0000000000..f54c7169a6 --- /dev/null +++ b/src/libs/compat/freebsd11_wlan/net80211/opt_ipx.h @@ -0,0 +1,6 @@ +#ifndef _FBSD_COMPAT_NET80211_OPT_IPX_H_ +#define _FBSD_COMPAT_NET80211_OPT_IPX_H_ + +//define IPX 1 + +#endif /* _FBSD_COMPAT_NET80211_OPT_IPX_H_ */ diff --git a/src/libs/compat/freebsd11_wlan/net80211/opt_wlan.h b/src/libs/compat/freebsd11_wlan/net80211/opt_wlan.h new file mode 100644 index 0000000000..accc87e7b2 --- /dev/null +++ b/src/libs/compat/freebsd11_wlan/net80211/opt_wlan.h @@ -0,0 +1,8 @@ +#ifndef _FBSD_COMPAT_NET80211_OPT_WLAN_H_ +#define _FBSD_COMPAT_NET80211_OPT_WLAN_H_ + +#define IEEE80211_DEBUG 1 +//#define IEEE80211_AMDPU_AGE 1 +//#define IEEE80211_SUPPORT_MESH 1 + +#endif /* _FBSD_COMPAT_NET80211_OPT_WLAN_H_ */