1/*- 2 * Copyright (c) 2001 Atsushi Onoe 3 * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 11 unchanged lines hidden (view full) --- 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> |
28__FBSDID("$FreeBSD: head/sys/net80211/ieee80211_output.c 190391 2009-03-24 20:39:08Z sam $"); |
29 30#include "opt_inet.h" 31#include "opt_wlan.h" 32 33#include <sys/param.h> 34#include <sys/systm.h> 35#include <sys/mbuf.h> 36#include <sys/kernel.h> --- 5 unchanged lines hidden (view full) --- 42#include <net/ethernet.h> 43#include <net/if.h> 44#include <net/if_llc.h> 45#include <net/if_media.h> 46#include <net/if_vlan_var.h> 47 48#include <net80211/ieee80211_var.h> 49#include <net80211/ieee80211_regdomain.h> |
50#ifdef IEEE80211_SUPPORT_SUPERG 51#include <net80211/ieee80211_superg.h> 52#endif |
53#ifdef IEEE80211_SUPPORT_TDMA 54#include <net80211/ieee80211_tdma.h> 55#endif 56#include <net80211/ieee80211_wds.h> 57 58#ifdef INET 59#include <netinet/in.h> 60#include <netinet/if_ether.h> 61#include <netinet/in_systm.h> 62#include <netinet/ip.h> 63#endif 64 65#define ETHER_HEADER_COPY(dst, src) \ 66 memcpy(dst, src, sizeof(struct ether_header)) 67 |
68static int ieee80211_fragment(struct ieee80211vap *, struct mbuf *, 69 u_int hdrsize, u_int ciphdrsize, u_int mtu); 70static void ieee80211_tx_mgt_cb(struct ieee80211_node *, void *, int); 71 72#ifdef IEEE80211_DEBUG 73/* 74 * Decide if an outbound management frame should be 75 * printed when debugging is enabled. This filters some --- 650 unchanged lines hidden (view full) --- 726} 727 728/* 729 * Insure there is sufficient contiguous space to encapsulate the 730 * 802.11 data frame. If room isn't already there, arrange for it. 731 * Drivers and cipher modules assume we have done the necessary work 732 * and fail rudely if they don't find the space they need. 733 */ |
734struct mbuf * |
735ieee80211_mbuf_adjust(struct ieee80211vap *vap, int hdrsize, 736 struct ieee80211_key *key, struct mbuf *m) 737{ 738#define TO_BE_RECLAIMED (sizeof(struct ether_header) - sizeof(struct llc)) 739 int needed_space = vap->iv_ic->ic_headroom + hdrsize; 740 741 if (key != NULL) { 742 /* XXX belongs in crypto code? */ --- 113 unchanged lines hidden (view full) --- 856{ 857#define WH4(wh) ((struct ieee80211_frame_addr4 *)(wh)) 858 struct ieee80211vap *vap = ni->ni_vap; 859 struct ieee80211com *ic = ni->ni_ic; 860 struct ether_header eh; 861 struct ieee80211_frame *wh; 862 struct ieee80211_key *key; 863 struct llc *llc; |
864 int hdrsize, hdrspace, datalen, addqos, txfrag, is4addr; |
865 866 /* 867 * Copy existing Ethernet header to a safe place. The 868 * rest of the code assumes it's ok to strip it when 869 * reorganizing state for the final encapsulation. 870 */ 871 KASSERT(m->m_len >= sizeof(eh), ("no ethernet header!")); 872 ETHER_HEADER_COPY(&eh, mtod(m, caddr_t)); --- 57 unchanged lines hidden (view full) --- 930 /* 931 * Honor driver DATAPAD requirement. 932 */ 933 if (ic->ic_flags & IEEE80211_F_DATAPAD) 934 hdrspace = roundup(hdrsize, sizeof(uint32_t)); 935 else 936 hdrspace = hdrsize; 937 |
938 if (__predict_true((m->m_flags & M_FF) == 0)) { |
939 /* |
940 * Normal frame. 941 */ 942 m = ieee80211_mbuf_adjust(vap, hdrspace, key, m); 943 if (m == NULL) { 944 /* NB: ieee80211_mbuf_adjust handles msgs+statistics */ 945 goto bad; 946 } 947 /* NB: this could be optimized 'cuz of ieee80211_mbuf_adjust */ 948 m_adj(m, sizeof(struct ether_header) - sizeof(struct llc)); 949 llc = mtod(m, struct llc *); 950 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP; 951 llc->llc_control = LLC_UI; 952 llc->llc_snap.org_code[0] = 0; 953 llc->llc_snap.org_code[1] = 0; 954 llc->llc_snap.org_code[2] = 0; 955 llc->llc_snap.ether_type = eh.ether_type; |
956 } else { 957#ifdef IEEE80211_SUPPORT_SUPERG 958 m = ieee80211_ff_encap(vap, m, hdrspace, key); 959 if (m == NULL) 960#endif 961 goto bad; |
962 } 963 datalen = m->m_pkthdr.len; /* NB: w/o 802.11 header */ 964 965 M_PREPEND(m, hdrspace, M_DONTWAIT); 966 if (m == NULL) { 967 vap->iv_stats.is_tx_nobuf++; 968 goto bad; 969 } --- 29 unchanged lines hidden (view full) --- 999 IEEE80211_ADDR_COPY(wh->i_addr1, eh.ether_dhost); 1000 IEEE80211_ADDR_COPY(wh->i_addr2, ni->ni_bssid); 1001 IEEE80211_ADDR_COPY(wh->i_addr3, eh.ether_shost); 1002 break; 1003 case IEEE80211_M_MONITOR: 1004 case IEEE80211_M_WDS: /* NB: is4addr should always be true */ 1005 goto bad; 1006 } |
1007 if (m->m_flags & M_MORE_DATA) |
1008 wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA; 1009 if (addqos) { 1010 uint8_t *qos; 1011 int ac, tid; 1012 1013 if (is4addr) { 1014 qos = ((struct ieee80211_qosframe_addr4 *) wh)->i_qos; 1015 } else --- 64 unchanged lines hidden (view full) --- 1080 *(uint16_t *)wh->i_seq = 1081 htole16(ni->ni_txseqs[IEEE80211_NONQOS_TID] << IEEE80211_SEQ_SEQ_SHIFT); 1082 ni->ni_txseqs[IEEE80211_NONQOS_TID]++; 1083 } 1084 /* check if xmit fragmentation is required */ 1085 txfrag = (m->m_pkthdr.len > vap->iv_fragthreshold && 1086 !IEEE80211_IS_MULTICAST(wh->i_addr1) && 1087 (vap->iv_caps & IEEE80211_C_TXFRAG) && |
1088 (m->m_flags & M_FF) == 0); /* NB: don't fragment ff's */ |
1089 if (key != NULL) { 1090 /* 1091 * IEEE 802.1X: send EAPOL frames always in the clear. 1092 * WPA/WPA2: encrypt EAPOL keys when pairwise keys are set. 1093 */ 1094 if ((m->m_flags & M_EAPOL) == 0 || 1095 ((vap->iv_flags & IEEE80211_F_WPA) && 1096 (vap->iv_opmode == IEEE80211_M_STA ? --- 30 unchanged lines hidden (view full) --- 1127bad: 1128 if (m != NULL) 1129 m_freem(m); 1130 return NULL; 1131#undef WH4 1132} 1133 1134/* |
1135 * Fragment the frame according to the specified mtu. 1136 * The size of the 802.11 header (w/o padding) is provided 1137 * so we don't need to recalculate it. We create a new 1138 * mbuf for each fragment and chain it through m_nextpkt; 1139 * we might be able to optimize this by reusing the original 1140 * packet's mbufs but that is significantly more complicated. 1141 */ 1142static int --- 248 unchanged lines hidden (view full) --- 1391 ADDSHORT(frm, ac->wmep_txopLimit); 1392 } 1393 return frm; 1394#undef SM 1395#undef ADDSHORT 1396} 1397#undef WME_OUI_BYTES 1398 |
1399/* |
1400 * Add an 11h Power Constraint element to a frame. 1401 */ 1402static uint8_t * 1403ieee80211_add_powerconstraint(uint8_t *frm, struct ieee80211vap *vap) 1404{ 1405 const struct ieee80211_channel *c = vap->iv_bss->ni_chan; 1406 /* XXX per-vap tx power limit? */ 1407 int8_t limit = vap->iv_ic->ic_txpowlimit / 2; --- 367 unchanged lines hidden (view full) --- 1775 + 2 + IEEE80211_NWID_LEN 1776 + 2 + IEEE80211_RATE_SIZE 1777 + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) 1778 + 4 1779 + 2 + 26 1780 + sizeof(struct ieee80211_wme_info) 1781 + sizeof(struct ieee80211_ie_htcap) 1782 + 4 + sizeof(struct ieee80211_ie_htcap) |
1783#ifdef IEEE80211_SUPPORT_SUPERG |
1784 + sizeof(struct ieee80211_ath_ie) |
1785#endif |
1786 + (vap->iv_appie_wpa != NULL ? 1787 vap->iv_appie_wpa->ie_len : 0) 1788 + (vap->iv_appie_assocreq != NULL ? 1789 vap->iv_appie_assocreq->ie_len : 0) 1790 ); 1791 if (m == NULL) 1792 senderr(ENOMEM, is_tx_nobuf); 1793 --- 52 unchanged lines hidden (view full) --- 1846 } 1847 if ((ic->ic_flags & IEEE80211_F_WME) && 1848 ni->ni_ies.wme_ie != NULL) 1849 frm = ieee80211_add_wme_info(frm, &ic->ic_wme); 1850 if ((vap->iv_flags_ext & IEEE80211_FEXT_HT) && 1851 ni->ni_ies.htcap_ie != NULL && 1852 ni->ni_ies.htcap_ie[0] == IEEE80211_ELEMID_VENDOR) 1853 frm = ieee80211_add_htcap_vendor(frm, ni); |
1854#ifdef IEEE80211_SUPPORT_SUPERG |
1855 if (IEEE80211_ATH_CAP(vap, ni, IEEE80211_F_ATHEROS)) 1856 frm = ieee80211_add_ath(frm, 1857 IEEE80211_ATH_CAP(vap, ni, IEEE80211_F_ATHEROS), 1858 (vap->iv_flags & IEEE80211_F_WPA) == 0 && 1859 ni->ni_authmode != IEEE80211_AUTH_8021X && 1860 vap->iv_def_txkey != IEEE80211_KEYIX_NONE ? 1861 vap->iv_def_txkey : 0x7fff); |
1862#endif /* IEEE80211_SUPPORT_SUPERG */ |
1863 if (vap->iv_appie_assocreq != NULL) 1864 frm = add_appie(frm, vap->iv_appie_assocreq); 1865 m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); 1866 1867 ieee80211_add_callback(m, ieee80211_tx_mgt_cb, 1868 (void *) vap->iv_state); 1869 break; 1870 --- 19 unchanged lines hidden (view full) --- 1890 sizeof(uint16_t) 1891 + sizeof(uint16_t) 1892 + sizeof(uint16_t) 1893 + 2 + IEEE80211_RATE_SIZE 1894 + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) 1895 + sizeof(struct ieee80211_ie_htcap) + 4 1896 + sizeof(struct ieee80211_ie_htinfo) + 4 1897 + sizeof(struct ieee80211_wme_param) |
1898#ifdef IEEE80211_SUPPORT_SUPERG |
1899 + sizeof(struct ieee80211_ath_ie) |
1900#endif |
1901 + (vap->iv_appie_assocresp != NULL ? 1902 vap->iv_appie_assocresp->ie_len : 0) 1903 ); 1904 if (m == NULL) 1905 senderr(ENOMEM, is_tx_nobuf); 1906 1907 capinfo = getcapinfo(vap, bss->ni_chan); 1908 *(uint16_t *)frm = htole16(capinfo); --- 18 unchanged lines hidden (view full) --- 1927 } 1928 if ((vap->iv_flags & IEEE80211_F_WME) && 1929 ni->ni_ies.wme_ie != NULL) 1930 frm = ieee80211_add_wme_param(frm, &ic->ic_wme); 1931 if ((ni->ni_flags & HTFLAGS) == HTFLAGS) { 1932 frm = ieee80211_add_htcap_vendor(frm, ni); 1933 frm = ieee80211_add_htinfo_vendor(frm, ni); 1934 } |
1935#ifdef IEEE80211_SUPPORT_SUPERG |
1936 if (IEEE80211_ATH_CAP(vap, ni, IEEE80211_F_ATHEROS)) 1937 frm = ieee80211_add_ath(frm, 1938 IEEE80211_ATH_CAP(vap, ni, IEEE80211_F_ATHEROS), 1939 ni->ni_ath_defkeyix); |
1940#endif /* IEEE80211_SUPPORT_SUPERG */ |
1941 if (vap->iv_appie_assocresp != NULL) 1942 frm = add_appie(frm, vap->iv_appie_assocresp); 1943 m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); 1944 break; 1945 1946 case IEEE80211_FC0_SUBTYPE_DISASSOC: 1947 IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni, 1948 "send station disassociate (reason %d)", arg); --- 84 unchanged lines hidden (view full) --- 2033 + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) 2034 + sizeof(struct ieee80211_ie_wpa) 2035 + sizeof(struct ieee80211_ie_htcap) 2036 + sizeof(struct ieee80211_ie_htinfo) 2037 + sizeof(struct ieee80211_ie_wpa) 2038 + sizeof(struct ieee80211_wme_param) 2039 + 4 + sizeof(struct ieee80211_ie_htcap) 2040 + 4 + sizeof(struct ieee80211_ie_htinfo) |
2041#ifdef IEEE80211_SUPPORT_SUPERG |
2042 + sizeof(struct ieee80211_ath_ie) |
2043#endif |
2044 + (vap->iv_appie_proberesp != NULL ? 2045 vap->iv_appie_proberesp->ie_len : 0) 2046 ); 2047 if (m == NULL) { 2048 vap->iv_stats.is_tx_nobuf++; 2049 return NULL; 2050 } 2051 --- 66 unchanged lines hidden (view full) --- 2118 if (vap->iv_flags & IEEE80211_F_WME) 2119 frm = ieee80211_add_wme_param(frm, &ic->ic_wme); 2120 if (IEEE80211_IS_CHAN_HT(bss->ni_chan) && 2121 (vap->iv_flags_ext & IEEE80211_FEXT_HTCOMPAT) && 2122 legacy != IEEE80211_SEND_LEGACY_11B) { 2123 frm = ieee80211_add_htcap_vendor(frm, bss); 2124 frm = ieee80211_add_htinfo_vendor(frm, bss); 2125 } |
2126#ifdef IEEE80211_SUPPORT_SUPERG |
2127 if (bss->ni_ies.ath_ie != NULL && legacy != IEEE80211_SEND_LEGACY_11B) 2128 frm = ieee80211_add_ath(frm, bss->ni_ath_flags, 2129 bss->ni_ath_defkeyix); |
2130#endif |
2131 if (vap->iv_appie_proberesp != NULL) 2132 frm = add_appie(frm, vap->iv_appie_proberesp); 2133 m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); 2134 2135 return m; 2136} 2137 2138/* --- 622 unchanged lines hidden --- |