Deleted Added
sdiff udiff text old ( 190094 ) new ( 190391 )
full compact
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 ---