Deleted Added
full compact
ieee80211_output.c (190094) ieee80211_output.c (190391)
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>
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 190094 2009-03-19 18:45:37Z rpaulo $");
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>
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
50#ifdef IEEE80211_SUPPORT_TDMA
51#include <net80211/ieee80211_tdma.h>
52#endif
53#include <net80211/ieee80211_wds.h>
54
55#ifdef INET
56#include <netinet/in.h>
57#include <netinet/if_ether.h>
58#include <netinet/in_systm.h>
59#include <netinet/ip.h>
60#endif
61
62#define ETHER_HEADER_COPY(dst, src) \
63 memcpy(dst, src, sizeof(struct ether_header))
64
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
65static struct mbuf *ieee80211_encap_fastframe(struct ieee80211vap *,
66 struct mbuf *m1, const struct ether_header *eh1,
67 struct mbuf *m2, const struct ether_header *eh2);
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 */
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 */
734static struct mbuf *
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;
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, isff, is4addr;
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
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 ((isff = m->m_flags & M_FF) != 0) {
939 struct mbuf *m2;
940 struct ether_header eh2;
941
938 if (__predict_true((m->m_flags & M_FF) == 0)) {
942 /*
939 /*
943 * Fast frame encapsulation. There must be two packets
944 * chained with m_nextpkt. We do header adjustment for
945 * each, add the tunnel encapsulation, and then concatenate
946 * the mbuf chains to form a single frame for transmission.
947 */
948 m2 = m->m_nextpkt;
949 if (m2 == NULL) {
950 IEEE80211_DPRINTF(vap, IEEE80211_MSG_SUPERG,
951 "%s: only one frame\n", __func__);
952 goto bad;
953 }
954 m->m_nextpkt = NULL;
955 /*
956 * Include fast frame headers in adjusting header
957 * layout; this allocates space according to what
958 * ieee80211_encap_fastframe will do.
959 */
960 m = ieee80211_mbuf_adjust(vap,
961 hdrspace + sizeof(struct llc) + sizeof(uint32_t) + 2 +
962 sizeof(struct ether_header),
963 key, m);
964 if (m == NULL) {
965 /* NB: ieee80211_mbuf_adjust handles msgs+statistics */
966 m_freem(m2);
967 goto bad;
968 }
969 /*
970 * Copy second frame's Ethernet header out of line
971 * and adjust for encapsulation headers. Note that
972 * we make room for padding in case there isn't room
973 * at the end of first frame.
974 */
975 KASSERT(m2->m_len >= sizeof(eh2), ("no ethernet header!"));
976 ETHER_HEADER_COPY(&eh2, mtod(m2, caddr_t));
977 m2 = ieee80211_mbuf_adjust(vap,
978 ATH_FF_MAX_HDR_PAD + sizeof(struct ether_header),
979 NULL, m2);
980 if (m2 == NULL) {
981 /* NB: ieee80211_mbuf_adjust handles msgs+statistics */
982 goto bad;
983 }
984 m = ieee80211_encap_fastframe(vap, m, &eh, m2, &eh2);
985 if (m == NULL)
986 goto bad;
987 } else {
988 /*
989 * Normal frame.
990 */
991 m = ieee80211_mbuf_adjust(vap, hdrspace, key, m);
992 if (m == NULL) {
993 /* NB: ieee80211_mbuf_adjust handles msgs+statistics */
994 goto bad;
995 }
996 /* NB: this could be optimized 'cuz of ieee80211_mbuf_adjust */
997 m_adj(m, sizeof(struct ether_header) - sizeof(struct llc));
998 llc = mtod(m, struct llc *);
999 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
1000 llc->llc_control = LLC_UI;
1001 llc->llc_snap.org_code[0] = 0;
1002 llc->llc_snap.org_code[1] = 0;
1003 llc->llc_snap.org_code[2] = 0;
1004 llc->llc_snap.ether_type = eh.ether_type;
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;
1005 }
1006 datalen = m->m_pkthdr.len; /* NB: w/o 802.11 header */
1007
1008 M_PREPEND(m, hdrspace, M_DONTWAIT);
1009 if (m == NULL) {
1010 vap->iv_stats.is_tx_nobuf++;
1011 goto bad;
1012 }

--- 29 unchanged lines hidden (view full) ---

1042 IEEE80211_ADDR_COPY(wh->i_addr1, eh.ether_dhost);
1043 IEEE80211_ADDR_COPY(wh->i_addr2, ni->ni_bssid);
1044 IEEE80211_ADDR_COPY(wh->i_addr3, eh.ether_shost);
1045 break;
1046 case IEEE80211_M_MONITOR:
1047 case IEEE80211_M_WDS: /* NB: is4addr should always be true */
1048 goto bad;
1049 }
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 }
1050 if (m->m_flags & M_MORE_DATA)
1007 if (m->m_flags & M_MORE_DATA)
1051 wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA;
1052 if (addqos) {
1053 uint8_t *qos;
1054 int ac, tid;
1055
1056 if (is4addr) {
1057 qos = ((struct ieee80211_qosframe_addr4 *) wh)->i_qos;
1058 } else

--- 64 unchanged lines hidden (view full) ---

1123 *(uint16_t *)wh->i_seq =
1124 htole16(ni->ni_txseqs[IEEE80211_NONQOS_TID] << IEEE80211_SEQ_SEQ_SHIFT);
1125 ni->ni_txseqs[IEEE80211_NONQOS_TID]++;
1126 }
1127 /* check if xmit fragmentation is required */
1128 txfrag = (m->m_pkthdr.len > vap->iv_fragthreshold &&
1129 !IEEE80211_IS_MULTICAST(wh->i_addr1) &&
1130 (vap->iv_caps & IEEE80211_C_TXFRAG) &&
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) &&
1131 !isff); /* NB: don't fragment ff's */
1088 (m->m_flags & M_FF) == 0); /* NB: don't fragment ff's */
1132 if (key != NULL) {
1133 /*
1134 * IEEE 802.1X: send EAPOL frames always in the clear.
1135 * WPA/WPA2: encrypt EAPOL keys when pairwise keys are set.
1136 */
1137 if ((m->m_flags & M_EAPOL) == 0 ||
1138 ((vap->iv_flags & IEEE80211_F_WPA) &&
1139 (vap->iv_opmode == IEEE80211_M_STA ?

--- 30 unchanged lines hidden (view full) ---

1170bad:
1171 if (m != NULL)
1172 m_freem(m);
1173 return NULL;
1174#undef WH4
1175}
1176
1177/*
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/*
1178 * Do Ethernet-LLC encapsulation for each payload in a fast frame
1179 * tunnel encapsulation. The frame is assumed to have an Ethernet
1180 * header at the front that must be stripped before prepending the
1181 * LLC followed by the Ethernet header passed in (with an Ethernet
1182 * type that specifies the payload size).
1183 */
1184static struct mbuf *
1185ieee80211_encap1(struct ieee80211vap *vap, struct mbuf *m,
1186 const struct ether_header *eh)
1187{
1188 struct llc *llc;
1189 uint16_t payload;
1190
1191 /* XXX optimize by combining m_adj+M_PREPEND */
1192 m_adj(m, sizeof(struct ether_header) - sizeof(struct llc));
1193 llc = mtod(m, struct llc *);
1194 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
1195 llc->llc_control = LLC_UI;
1196 llc->llc_snap.org_code[0] = 0;
1197 llc->llc_snap.org_code[1] = 0;
1198 llc->llc_snap.org_code[2] = 0;
1199 llc->llc_snap.ether_type = eh->ether_type;
1200 payload = m->m_pkthdr.len; /* NB: w/o Ethernet header */
1201
1202 M_PREPEND(m, sizeof(struct ether_header), M_DONTWAIT);
1203 if (m == NULL) { /* XXX cannot happen */
1204 IEEE80211_DPRINTF(vap, IEEE80211_MSG_SUPERG,
1205 "%s: no space for ether_header\n", __func__);
1206 vap->iv_stats.is_tx_nobuf++;
1207 return NULL;
1208 }
1209 ETHER_HEADER_COPY(mtod(m, void *), eh);
1210 mtod(m, struct ether_header *)->ether_type = htons(payload);
1211 return m;
1212}
1213
1214/*
1215 * Do fast frame tunnel encapsulation. The two frames and
1216 * Ethernet headers are supplied. The caller is assumed to
1217 * have arrange for space in the mbuf chains for encapsulating
1218 * headers (to avoid major mbuf fragmentation).
1219 *
1220 * The encapsulated frame is returned or NULL if there is a
1221 * problem (should not happen).
1222 */
1223static struct mbuf *
1224ieee80211_encap_fastframe(struct ieee80211vap *vap,
1225 struct mbuf *m1, const struct ether_header *eh1,
1226 struct mbuf *m2, const struct ether_header *eh2)
1227{
1228 struct llc *llc;
1229 struct mbuf *m;
1230 int pad;
1231
1232 /*
1233 * First, each frame gets a standard encapsulation.
1234 */
1235 m1 = ieee80211_encap1(vap, m1, eh1);
1236 if (m1 == NULL) {
1237 m_freem(m2);
1238 return NULL;
1239 }
1240 m2 = ieee80211_encap1(vap, m2, eh2);
1241 if (m2 == NULL) {
1242 m_freem(m1);
1243 return NULL;
1244 }
1245
1246 /*
1247 * Pad leading frame to a 4-byte boundary. If there
1248 * is space at the end of the first frame, put it
1249 * there; otherwise prepend to the front of the second
1250 * frame. We know doing the second will always work
1251 * because we reserve space above. We prefer appending
1252 * as this typically has better DMA alignment properties.
1253 */
1254 for (m = m1; m->m_next != NULL; m = m->m_next)
1255 ;
1256 pad = roundup2(m1->m_pkthdr.len, 4) - m1->m_pkthdr.len;
1257 if (pad) {
1258 if (M_TRAILINGSPACE(m) < pad) { /* prepend to second */
1259 m2->m_data -= pad;
1260 m2->m_len += pad;
1261 m2->m_pkthdr.len += pad;
1262 } else { /* append to first */
1263 m->m_len += pad;
1264 m1->m_pkthdr.len += pad;
1265 }
1266 }
1267
1268 /*
1269 * Now, stick 'em together and prepend the tunnel headers;
1270 * first the Atheros tunnel header (all zero for now) and
1271 * then a special fast frame LLC.
1272 *
1273 * XXX optimize by prepending together
1274 */
1275 m->m_next = m2; /* NB: last mbuf from above */
1276 m1->m_pkthdr.len += m2->m_pkthdr.len;
1277 M_PREPEND(m1, sizeof(uint32_t)+2, M_DONTWAIT);
1278 if (m1 == NULL) { /* XXX cannot happen */
1279 IEEE80211_DPRINTF(vap, IEEE80211_MSG_SUPERG,
1280 "%s: no space for tunnel header\n", __func__);
1281 vap->iv_stats.is_tx_nobuf++;
1282 return NULL;
1283 }
1284 memset(mtod(m1, void *), 0, sizeof(uint32_t)+2);
1285
1286 M_PREPEND(m1, sizeof(struct llc), M_DONTWAIT);
1287 if (m1 == NULL) { /* XXX cannot happen */
1288 IEEE80211_DPRINTF(vap, IEEE80211_MSG_SUPERG,
1289 "%s: no space for llc header\n", __func__);
1290 vap->iv_stats.is_tx_nobuf++;
1291 return NULL;
1292 }
1293 llc = mtod(m1, struct llc *);
1294 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
1295 llc->llc_control = LLC_UI;
1296 llc->llc_snap.org_code[0] = ATH_FF_SNAP_ORGCODE_0;
1297 llc->llc_snap.org_code[1] = ATH_FF_SNAP_ORGCODE_1;
1298 llc->llc_snap.org_code[2] = ATH_FF_SNAP_ORGCODE_2;
1299 llc->llc_snap.ether_type = htons(ATH_FF_ETH_TYPE);
1300
1301 vap->iv_stats.is_ff_encap++;
1302
1303 return m1;
1304}
1305
1306/*
1307 * Fragment the frame according to the specified mtu.
1308 * The size of the 802.11 header (w/o padding) is provided
1309 * so we don't need to recalculate it. We create a new
1310 * mbuf for each fragment and chain it through m_nextpkt;
1311 * we might be able to optimize this by reusing the original
1312 * packet's mbufs but that is significantly more complicated.
1313 */
1314static int

--- 248 unchanged lines hidden (view full) ---

1563 ADDSHORT(frm, ac->wmep_txopLimit);
1564 }
1565 return frm;
1566#undef SM
1567#undef ADDSHORT
1568}
1569#undef WME_OUI_BYTES
1570
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
1571#define ATH_OUI_BYTES 0x00, 0x03, 0x7f
1572/*
1399/*
1573 * Add a WME information element to a frame.
1574 */
1575static uint8_t *
1576ieee80211_add_ath(uint8_t *frm, uint8_t caps, uint16_t defkeyix)
1577{
1578 static const struct ieee80211_ath_ie info = {
1579 .ath_id = IEEE80211_ELEMID_VENDOR,
1580 .ath_len = sizeof(struct ieee80211_ath_ie) - 2,
1581 .ath_oui = { ATH_OUI_BYTES },
1582 .ath_oui_type = ATH_OUI_TYPE,
1583 .ath_oui_subtype= ATH_OUI_SUBTYPE,
1584 .ath_version = ATH_OUI_VERSION,
1585 };
1586 struct ieee80211_ath_ie *ath = (struct ieee80211_ath_ie *) frm;
1587
1588 memcpy(frm, &info, sizeof(info));
1589 ath->ath_capability = caps;
1590 ath->ath_defkeyix[0] = (defkeyix & 0xff);
1591 ath->ath_defkeyix[1] = ((defkeyix >> 8) & 0xff);
1592 return frm + sizeof(info);
1593}
1594#undef ATH_OUI_BYTES
1595
1596/*
1597 * Add an 11h Power Constraint element to a frame.
1598 */
1599static uint8_t *
1600ieee80211_add_powerconstraint(uint8_t *frm, struct ieee80211vap *vap)
1601{
1602 const struct ieee80211_channel *c = vap->iv_bss->ni_chan;
1603 /* XXX per-vap tx power limit? */
1604 int8_t limit = vap->iv_ic->ic_txpowlimit / 2;

--- 367 unchanged lines hidden (view full) ---

1972 + 2 + IEEE80211_NWID_LEN
1973 + 2 + IEEE80211_RATE_SIZE
1974 + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE)
1975 + 4
1976 + 2 + 26
1977 + sizeof(struct ieee80211_wme_info)
1978 + sizeof(struct ieee80211_ie_htcap)
1979 + 4 + sizeof(struct ieee80211_ie_htcap)
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
1980 + sizeof(struct ieee80211_ath_ie)
1784 + sizeof(struct ieee80211_ath_ie)
1785#endif
1981 + (vap->iv_appie_wpa != NULL ?
1982 vap->iv_appie_wpa->ie_len : 0)
1983 + (vap->iv_appie_assocreq != NULL ?
1984 vap->iv_appie_assocreq->ie_len : 0)
1985 );
1986 if (m == NULL)
1987 senderr(ENOMEM, is_tx_nobuf);
1988

--- 52 unchanged lines hidden (view full) ---

2041 }
2042 if ((ic->ic_flags & IEEE80211_F_WME) &&
2043 ni->ni_ies.wme_ie != NULL)
2044 frm = ieee80211_add_wme_info(frm, &ic->ic_wme);
2045 if ((vap->iv_flags_ext & IEEE80211_FEXT_HT) &&
2046 ni->ni_ies.htcap_ie != NULL &&
2047 ni->ni_ies.htcap_ie[0] == IEEE80211_ELEMID_VENDOR)
2048 frm = ieee80211_add_htcap_vendor(frm, ni);
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
2049 if (IEEE80211_ATH_CAP(vap, ni, IEEE80211_F_ATHEROS))
2050 frm = ieee80211_add_ath(frm,
2051 IEEE80211_ATH_CAP(vap, ni, IEEE80211_F_ATHEROS),
2052 (vap->iv_flags & IEEE80211_F_WPA) == 0 &&
2053 ni->ni_authmode != IEEE80211_AUTH_8021X &&
2054 vap->iv_def_txkey != IEEE80211_KEYIX_NONE ?
2055 vap->iv_def_txkey : 0x7fff);
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 */
2056 if (vap->iv_appie_assocreq != NULL)
2057 frm = add_appie(frm, vap->iv_appie_assocreq);
2058 m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *);
2059
2060 ieee80211_add_callback(m, ieee80211_tx_mgt_cb,
2061 (void *) vap->iv_state);
2062 break;
2063

--- 19 unchanged lines hidden (view full) ---

2083 sizeof(uint16_t)
2084 + sizeof(uint16_t)
2085 + sizeof(uint16_t)
2086 + 2 + IEEE80211_RATE_SIZE
2087 + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE)
2088 + sizeof(struct ieee80211_ie_htcap) + 4
2089 + sizeof(struct ieee80211_ie_htinfo) + 4
2090 + sizeof(struct ieee80211_wme_param)
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
2091 + sizeof(struct ieee80211_ath_ie)
1899 + sizeof(struct ieee80211_ath_ie)
1900#endif
2092 + (vap->iv_appie_assocresp != NULL ?
2093 vap->iv_appie_assocresp->ie_len : 0)
2094 );
2095 if (m == NULL)
2096 senderr(ENOMEM, is_tx_nobuf);
2097
2098 capinfo = getcapinfo(vap, bss->ni_chan);
2099 *(uint16_t *)frm = htole16(capinfo);

--- 18 unchanged lines hidden (view full) ---

2118 }
2119 if ((vap->iv_flags & IEEE80211_F_WME) &&
2120 ni->ni_ies.wme_ie != NULL)
2121 frm = ieee80211_add_wme_param(frm, &ic->ic_wme);
2122 if ((ni->ni_flags & HTFLAGS) == HTFLAGS) {
2123 frm = ieee80211_add_htcap_vendor(frm, ni);
2124 frm = ieee80211_add_htinfo_vendor(frm, ni);
2125 }
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
2126 if (IEEE80211_ATH_CAP(vap, ni, IEEE80211_F_ATHEROS))
2127 frm = ieee80211_add_ath(frm,
2128 IEEE80211_ATH_CAP(vap, ni, IEEE80211_F_ATHEROS),
2129 ni->ni_ath_defkeyix);
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 */
2130 if (vap->iv_appie_assocresp != NULL)
2131 frm = add_appie(frm, vap->iv_appie_assocresp);
2132 m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *);
2133 break;
2134
2135 case IEEE80211_FC0_SUBTYPE_DISASSOC:
2136 IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni,
2137 "send station disassociate (reason %d)", arg);

--- 84 unchanged lines hidden (view full) ---

2222 + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE)
2223 + sizeof(struct ieee80211_ie_wpa)
2224 + sizeof(struct ieee80211_ie_htcap)
2225 + sizeof(struct ieee80211_ie_htinfo)
2226 + sizeof(struct ieee80211_ie_wpa)
2227 + sizeof(struct ieee80211_wme_param)
2228 + 4 + sizeof(struct ieee80211_ie_htcap)
2229 + 4 + sizeof(struct ieee80211_ie_htinfo)
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
2230 + sizeof(struct ieee80211_ath_ie)
2042 + sizeof(struct ieee80211_ath_ie)
2043#endif
2231 + (vap->iv_appie_proberesp != NULL ?
2232 vap->iv_appie_proberesp->ie_len : 0)
2233 );
2234 if (m == NULL) {
2235 vap->iv_stats.is_tx_nobuf++;
2236 return NULL;
2237 }
2238

--- 66 unchanged lines hidden (view full) ---

2305 if (vap->iv_flags & IEEE80211_F_WME)
2306 frm = ieee80211_add_wme_param(frm, &ic->ic_wme);
2307 if (IEEE80211_IS_CHAN_HT(bss->ni_chan) &&
2308 (vap->iv_flags_ext & IEEE80211_FEXT_HTCOMPAT) &&
2309 legacy != IEEE80211_SEND_LEGACY_11B) {
2310 frm = ieee80211_add_htcap_vendor(frm, bss);
2311 frm = ieee80211_add_htinfo_vendor(frm, bss);
2312 }
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
2313 if (bss->ni_ies.ath_ie != NULL && legacy != IEEE80211_SEND_LEGACY_11B)
2314 frm = ieee80211_add_ath(frm, bss->ni_ath_flags,
2315 bss->ni_ath_defkeyix);
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
2316 if (vap->iv_appie_proberesp != NULL)
2317 frm = add_appie(frm, vap->iv_appie_proberesp);
2318 m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *);
2319
2320 return m;
2321}
2322
2323/*

--- 622 unchanged lines hidden ---
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 ---