Ticket #517: madwifi-appie.2.diff
| File madwifi-appie.2.diff, 22.2 kB (added by ccpearson, 6 years ago) |
|---|
-
madwifi/ath/if_ath.c
old new 1188 1188 struct ath_hal *ah = sc->sc_ah; 1189 1189 struct ath_vap *avp = ATH_VAP(vap); 1190 1190 int decrease = 1; 1191 int i; 1191 1192 KASSERT(vap->iv_state == IEEE80211_S_INIT, ("vap not stopped")); 1192 1193 1193 1194 if (dev->flags & IFF_RUNNING) { … … 1261 1262 } 1262 1263 #endif 1263 1264 1265 for (i = 0; i < IEEE80211_APPIE_NUM_OF_FRAME; ++ i) { 1266 if (vap->app_ie[i].ie != NULL) { 1267 FREE(vap->app_ie[i].ie, M_DEVBUF); 1268 vap->app_ie[i].ie = NULL; 1269 vap->app_ie[i].length = 0; 1270 } 1271 } 1272 1264 1273 if (dev->flags & IFF_RUNNING) { 1265 1274 /* 1266 1275 * Restart rx+tx machines if device is still running. -
madwifi/net80211/ieee80211.h
old new 353 353 }; 354 354 355 355 /* 356 * Generic information element 357 */ 358 struct ieee80211_ie { 359 u_int8_t id; 360 u_int8_t len; 361 u_int8_t info[]; 362 } __packed; 363 364 /* 356 365 * Country information element. 357 366 */ 358 367 #define IEEE80211_COUNTRY_MAX_TRIPLETS (83) -
madwifi/net80211/ieee80211_beacon.c
old new 183 183 if (vap->iv_xrvap && vap->iv_ath_cap & IEEE80211_ATHC_XR) /* XR */ 184 184 frm = ieee80211_add_xr_param(frm, vap); 185 185 #endif 186 bo->bo_appie_buf = frm; 187 bo->bo_appie_buf_len = 0; 186 188 187 189 bo->bo_tim_trailerlen = frm - bo->bo_tim_trailer; 188 190 bo->bo_chanswitch_trailerlen = frm - bo->bo_chanswitch; … … 524 526 IEEE80211_IS_CHAN_TURBO(ic->ic_curchan)) 525 527 ieee80211_add_athAdvCap(bo->bo_ath_caps, vap->iv_bss->ni_ath_flags, 526 528 vap->iv_bss->ni_ath_defkeyindex); 529 /* add APP_IE buffer if app updated it */ 530 if (vap->iv_flags_ext & IEEE80211_FEXT_APPIE_UPDATE) { 531 /* adjust the buffer size if the size is changed */ 532 if (vap->app_ie[IEEE80211_APPIE_FRAME_BEACON].length != bo->bo_appie_buf_len) { 533 int diff_len; 534 diff_len = vap->app_ie[IEEE80211_APPIE_FRAME_BEACON].length - bo->bo_appie_buf_len; 535 536 if (diff_len > 0) 537 skb_put(skb, diff_len); 538 else 539 skb_trim(skb, skb->len + diff_len); 540 541 bo->bo_appie_buf_len = vap->app_ie[IEEE80211_APPIE_FRAME_BEACON].length; 542 /* update the trailer lens */ 543 bo->bo_chanswitch_trailerlen += diff_len; 544 bo->bo_tim_trailerlen += diff_len; 545 546 len_changed = 1; 547 } 548 memcpy(bo->bo_appie_buf,vap->app_ie[IEEE80211_APPIE_FRAME_BEACON].ie, 549 vap->app_ie[IEEE80211_APPIE_FRAME_BEACON].length); 550 551 vap->iv_flags_ext &= ~IEEE80211_FEXT_APPIE_UPDATE; 552 } 553 527 554 IEEE80211_UNLOCK(ic); 528 555 529 556 return len_changed; -
madwifi/net80211/ieee80211_input.c
old new 2209 2209 #endif /* ATH_SUPERG_DYNTURBO */ 2210 2210 } 2211 2211 2212 static void 2213 forward_mgmt_to_app(struct ieee80211vap *vap, int subtype, struct sk_buff *skb, 2214 struct ieee80211_frame *wh) 2215 { 2216 struct net_device *dev = vap->iv_dev; 2217 int filter_type = 0; 2218 2219 switch (subtype) { 2220 case IEEE80211_FC0_SUBTYPE_BEACON: 2221 filter_type = IEEE80211_FILTER_TYPE_BEACON; 2222 break; 2223 case IEEE80211_FC0_SUBTYPE_PROBE_REQ: 2224 filter_type = IEEE80211_FILTER_TYPE_PROBE_REQ; 2225 break; 2226 case IEEE80211_FC0_SUBTYPE_PROBE_RESP: 2227 filter_type = IEEE80211_FILTER_TYPE_PROBE_RESP; 2228 break; 2229 case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: 2230 case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: 2231 filter_type = IEEE80211_FILTER_TYPE_ASSOC_REQ; 2232 break; 2233 case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: 2234 case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: 2235 filter_type = IEEE80211_FILTER_TYPE_ASSOC_RESP; 2236 break; 2237 case IEEE80211_FC0_SUBTYPE_AUTH: 2238 filter_type = IEEE80211_FILTER_TYPE_AUTH; 2239 break; 2240 case IEEE80211_FC0_SUBTYPE_DEAUTH: 2241 filter_type = IEEE80211_FILTER_TYPE_DEAUTH; 2242 break; 2243 case IEEE80211_FC0_SUBTYPE_DISASSOC: 2244 filter_type = IEEE80211_FILTER_TYPE_DISASSOC; 2245 break; 2246 default: 2247 break; 2248 } 2249 2250 if (filter_type && ((vap->app_filter & filter_type) == filter_type)) { 2251 struct sk_buff *skb1; 2252 2253 skb1 = skb_copy(skb, GFP_ATOMIC); 2254 if (skb1 == NULL) 2255 return; 2256 skb1->dev = dev; 2257 skb1->mac.raw = skb1->data; 2258 skb1->ip_summed = CHECKSUM_NONE; 2259 skb1->pkt_type = PACKET_OTHERHOST; 2260 skb1->protocol = __constant_htons(0x0019); /* ETH_P_80211_RAW */ 2261 2262 netif_rx(skb1); 2263 } 2264 } 2265 2212 2266 void 2213 2267 ieee80211_saveath(struct ieee80211_node *ni, u_int8_t *ie) 2214 2268 { … … 2380 2434 wh = (struct ieee80211_frame *) skb->data; 2381 2435 frm = (u_int8_t *)&wh[1]; 2382 2436 efrm = skb->data + skb->len; 2437 2438 /* forward management frame to application */ 2439 if (vap->iv_opmode != IEEE80211_M_MONITOR) 2440 forward_mgmt_to_app(vap, subtype, skb, wh); 2441 2383 2442 switch (subtype) { 2384 2443 case IEEE80211_FC0_SUBTYPE_PROBE_RESP: 2385 2444 case IEEE80211_FC0_SUBTYPE_BEACON: { -
madwifi/net80211/ieee80211_ioctl.h
old new 471 471 #define IEEE80211_IOC_DELMAC 55 /* del sta from MAC ACL table */ 472 472 #define IEEE80211_IOC_FF 56 /* ATH fast frames (on, off) */ 473 473 #define IEEE80211_IOC_TURBOP 57 /* ATH turbo' (on, off) */ 474 #define IEEE80211_IOC_APPIEBUF 58 /* IE in the management frame */ 475 #define IEEE80211_IOC_FILTERFRAME 59 /* management frame filter */ 474 476 475 477 /* 476 478 * Scan result data returned for IEEE80211_IOC_SCAN_RESULTS. … … 514 516 #define IEEE80211_IOCTL_SETCHANLIST (SIOCIWFIRSTPRIV+6) 515 517 #define IEEE80211_IOCTL_GETCHANLIST (SIOCIWFIRSTPRIV+7) 516 518 #define IEEE80211_IOCTL_CHANSWITCH (SIOCIWFIRSTPRIV+8) 519 #define IEEE80211_IOCTL_GET_APPIEBUF (SIOCIWFIRSTPRIV+9) 520 #define IEEE80211_IOCTL_SET_APPIEBUF (SIOCIWFIRSTPRIV+10) 521 #define IEEE80211_IOCTL_FILTERFRAME (SIOCIWFIRSTPRIV+12) 517 522 #define IEEE80211_IOCTL_GETCHANINFO (SIOCIWFIRSTPRIV+13) 518 523 #define IEEE80211_IOCTL_SETOPTIE (SIOCIWFIRSTPRIV+14) 519 524 #define IEEE80211_IOCTL_GETOPTIE (SIOCIWFIRSTPRIV+15) … … 525 530 #define IEEE80211_IOCTL_WDSADDMAC (SIOCIWFIRSTPRIV+26) 526 531 #define IEEE80211_IOCTL_WDSDELMAC (SIOCIWFIRSTPRIV+28) 527 532 #define IEEE80211_IOCTL_KICKMAC (SIOCIWFIRSTPRIV+30) 533 528 534 enum { 529 535 IEEE80211_WMMPARAMS_CWMIN = 1, 530 536 IEEE80211_WMMPARAMS_CWMAX = 2, … … 612 618 #define IEEE80211_NO_STABEACONS 0x0002 /* Do not setup the station beacon timers */ 613 619 }; 614 620 621 /* APPIEBUF related definitions */ 622 623 /* Management frame type to which application IE is added */ 624 enum { 625 IEEE80211_APPIE_FRAME_BEACON = 0, 626 IEEE80211_APPIE_FRAME_PROBE_REQ = 1, 627 IEEE80211_APPIE_FRAME_PROBE_RESP = 2, 628 IEEE80211_APPIE_FRAME_ASSOC_REQ = 3, 629 IEEE80211_APPIE_FRAME_ASSOC_RESP = 4, 630 IEEE80211_APPIE_NUM_OF_FRAME = 5 631 }; 632 633 struct ieee80211req_getset_appiebuf { 634 u_int32_t app_frmtype; /* management frame type for which buffer is added */ 635 u_int32_t app_buflen; /* application-supplied buffer length */ 636 u_int8_t app_buf[]; /* application-supplied IE(s) */ 637 }; 638 639 /* Flags ORed by application to set filter for receiving management frames */ 640 enum { 641 IEEE80211_FILTER_TYPE_BEACON = 1<<0, 642 IEEE80211_FILTER_TYPE_PROBE_REQ = 1<<1, 643 IEEE80211_FILTER_TYPE_PROBE_RESP = 1<<2, 644 IEEE80211_FILTER_TYPE_ASSOC_REQ = 1<<3, 645 IEEE80211_FILTER_TYPE_ASSOC_RESP = 1<<4, 646 IEEE80211_FILTER_TYPE_AUTH = 1<<5, 647 IEEE80211_FILTER_TYPE_DEAUTH = 1<<6, 648 IEEE80211_FILTER_TYPE_DISASSOC = 1<<7, 649 IEEE80211_FILTER_TYPE_ALL = 0xFF /* used to check the valid filter bits */ 650 }; 651 652 struct ieee80211req_set_filter { 653 u_int32_t app_filterype; /* management frame filter type */ 654 }; 655 656 615 657 #endif /* __linux__ */ 616 658 617 659 #endif /* _NET80211_IEEE80211_IOCTL_H_ */ -
madwifi/net80211/ieee80211_output.c
old new 1719 1719 skb = ieee80211_getmgtframe(&frm, 2 + IEEE80211_NWID_LEN + 1720 1720 2 + IEEE80211_RATE_SIZE + 1721 1721 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) + 1722 (optie != NULL ? optielen : 0)); 1722 (optie != NULL ? optielen : 0) + 1723 vap->app_ie[IEEE80211_APPIE_FRAME_PROBE_REQ].length); 1723 1724 if (skb == NULL) { 1724 1725 vap->iv_stats.is_tx_nobuf++; 1725 1726 ieee80211_free_node(ni); … … 1735 1736 memcpy(frm, optie, optielen); 1736 1737 frm += optielen; 1737 1738 } 1739 1740 if (vap->app_ie[IEEE80211_APPIE_FRAME_PROBE_REQ].ie) { 1741 memcpy(frm, vap->app_ie[IEEE80211_APPIE_FRAME_PROBE_REQ].ie, 1742 vap->app_ie[IEEE80211_APPIE_FRAME_PROBE_REQ].length); 1743 frm += vap->app_ie[IEEE80211_APPIE_FRAME_PROBE_REQ].length; 1744 } 1745 1738 1746 skb_trim(skb, frm - skb->data); 1739 1747 1740 1748 cb = (struct ieee80211_cb *)skb->cb; … … 1831 1839 + (vap->iv_ath_cap & IEEE80211_ATHC_XR ? /* XR */ 1832 1840 sizeof(struct ieee80211_xr_param) : 0) 1833 1841 #endif 1842 + vap->app_ie[IEEE80211_APPIE_FRAME_PROBE_RESP].length 1834 1843 ); 1835 1844 if (skb == NULL) 1836 1845 senderr(ENOMEM, is_tx_nobuf); … … 1926 1935 if (vap->iv_xrvap && vap->iv_ath_cap & IEEE80211_ATHC_XR) 1927 1936 frm = ieee80211_add_xr_param(frm, vap); 1928 1937 #endif 1938 if (vap->app_ie[IEEE80211_APPIE_FRAME_PROBE_RESP].ie) { 1939 memcpy(frm, vap->app_ie[IEEE80211_APPIE_FRAME_PROBE_RESP].ie, 1940 vap->app_ie[IEEE80211_APPIE_FRAME_PROBE_RESP].length); 1941 frm += vap->app_ie[IEEE80211_APPIE_FRAME_PROBE_RESP].length; 1942 } 1943 1929 1944 skb_trim(skb, frm - skb->data); 1930 1945 break; 1931 1946 … … 2026 2041 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) + 2027 2042 sizeof(struct ieee80211_ie_wme) + 2028 2043 sizeof(struct ieee80211_ie_athAdvCap) + 2029 (vap->iv_opt_ie != NULL ? vap->iv_opt_ie_len : 0)); 2044 (vap->iv_opt_ie != NULL ? vap->iv_opt_ie_len : 0) + 2045 vap->app_ie[IEEE80211_APPIE_FRAME_ASSOC_REQ].length); 2030 2046 if (skb == NULL) 2031 2047 senderr(ENOMEM, is_tx_nobuf); 2032 2048 … … 2097 2113 memcpy(frm, vap->iv_opt_ie, vap->iv_opt_ie_len); 2098 2114 frm += vap->iv_opt_ie_len; 2099 2115 } 2116 2117 if (vap->app_ie[IEEE80211_APPIE_FRAME_ASSOC_REQ].ie) { 2118 memcpy(frm, vap->app_ie[IEEE80211_APPIE_FRAME_ASSOC_REQ].ie, 2119 vap->app_ie[IEEE80211_APPIE_FRAME_ASSOC_REQ].length); 2120 frm += vap->app_ie[IEEE80211_APPIE_FRAME_ASSOC_REQ].length; 2121 } 2122 2100 2123 skb_trim(skb, frm - skb->data); 2101 2124 2102 2125 timer = IEEE80211_TRANS_WAIT; … … 2119 2142 2 + IEEE80211_RATE_SIZE + 2120 2143 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) + 2121 2144 sizeof(struct ieee80211_wme_param) + 2122 (vap->iv_ath_cap ? sizeof(struct ieee80211_ie_athAdvCap):0)); 2145 (vap->iv_ath_cap ? sizeof(struct ieee80211_ie_athAdvCap):0) + 2146 vap->app_ie[IEEE80211_APPIE_FRAME_ASSOC_RESP].length); 2123 2147 if (skb == NULL) 2124 2148 senderr(ENOMEM, is_tx_nobuf); 2125 2149 … … 2164 2188 vap->iv_ath_cap & ni->ni_ath_flags, 2165 2189 ni->ni_ath_defkeyindex); 2166 2190 2191 if (vap->app_ie[IEEE80211_APPIE_FRAME_ASSOC_RESP].ie) { 2192 memcpy(frm, vap->app_ie[IEEE80211_APPIE_FRAME_ASSOC_RESP].ie, 2193 vap->app_ie[IEEE80211_APPIE_FRAME_ASSOC_RESP].length); 2194 frm += vap->app_ie[IEEE80211_APPIE_FRAME_ASSOC_RESP].length; 2195 } 2196 2167 2197 skb_trim(skb, frm - skb->data); 2168 2198 break; 2169 2199 -
madwifi/net80211/ieee80211_proto.h
old new 265 265 u_int8_t *bo_ath_caps; /* where ath caps is */ 266 266 u_int8_t *bo_xr; /* start of xr element */ 267 267 u_int8_t *bo_erp; /* start of ERP element */ 268 u_int8_t *bo_appie_buf; /* start of APP IE buf */ 269 u_int16_t bo_appie_buf_len; /* APP IE buf length in bytes */ 268 270 u_int16_t bo_chanswitch_trailerlen; 269 271 }; 270 272 struct sk_buff *ieee80211_beacon_alloc(struct ieee80211_node *, -
madwifi/net80211/ieee80211_var.h
old new 88 88 #define IEEE80211_TU_TO_MS(x) (((x) * 1024) / 1000) 89 89 #define IEEE80211_TU_TO_JIFFIES(x) ((IEEE80211_TU_TO_MS(x) * HZ) / 1000) 90 90 91 #define IEEE80211_APPIE_MAX 1024 92 91 93 #define IEEE80211_PWRCONSTRAINT_VAL(ic) \ 92 94 (((ic)->ic_bsschan->ic_maxregpower > (ic)->ic_curchanmaxpwr) ? \ 93 95 (ic)->ic_bsschan->ic_maxregpower - (ic)->ic_curchanmaxpwr : 0) … … 290 292 }; 291 293 #endif 292 294 295 struct ieee80211_app_ie_t { 296 u_int32_t length; /* buffer length */ 297 struct ieee80211_ie *ie; /* buffer containing one or more IEs */ 298 }; 299 293 300 struct ieee80211vap { 294 301 struct net_device *iv_dev; /* associated device */ 295 302 struct net_device_stats iv_devstats; /* interface statistics */ … … 393 400 unsigned int iv_nsdone; /* Done with scheduled newstate tasklet */ 394 401 uint8_t wds_mac[IEEE80211_ADDR_LEN]; 395 402 struct ieee80211_spy iv_spy; /* IWSPY support */ 403 struct ieee80211_app_ie_t app_ie[IEEE80211_APPIE_NUM_OF_FRAME]; /* app-specified IEs by frame type */ 404 u_int32_t app_filter; /* filters which management frames are forwarded to app */ 405 396 406 }; 397 407 MALLOC_DECLARE(M_80211_VAP); 398 408 … … 452 462 #define IEEE80211_FEXT_ERPUPDATE 0x00000200 /* STATUS: update ERP element */ 453 463 #define IEEE80211_FEXT_SWBMISS 0x00000400 /* CONF: use software beacon timer */ 454 464 #define IEEE80211_FEXT_DROPUNENC_EAPOL 0x00000800 /* CONF: drop unencrypted eapol frames */ 465 #define IEEE80211_FEXT_APPIE_UPDATE 0x00001000 /* STATE: beacon APP IE updated */ 455 466 456 467 #define IEEE80211_COM_UAPSD_ENABLE(_ic) ((_ic)->ic_flags_ext |= IEEE80211_FEXT_UAPSD) 457 468 #define IEEE80211_COM_UAPSD_DISABLE(_ic) ((_ic)->ic_flags_ext &= ~IEEE80211_FEXT_UAPSD) -
madwifi/net80211/ieee80211_wireless.c
old new 1732 1732 return E2BIG; 1733 1733 1734 1734 if (se->se_rsn_ie != NULL) { 1735 last_ev = current_ev;1736 1735 #ifdef IWEVGENIE 1737 1736 memset(&iwe, 0, sizeof(iwe)); 1738 1737 memcpy(buf, se->se_rsn_ie, se->se_rsn_ie[1] + 2); … … 1747 1746 se->se_rsn_ie, se->se_rsn_ie[1] + 2, 1748 1747 rsn_leader, sizeof(rsn_leader) - 1); 1749 1748 #endif 1749 last_ev = current_ev; 1750 1750 if (iwe.u.data.length != 0) { 1751 1751 current_ev = iwe_stream_add_point(current_ev, end_buf, 1752 1752 &iwe, buf); … … 1758 1758 } 1759 1759 1760 1760 if (se->se_wpa_ie != NULL) { 1761 last_ev = current_ev;1762 1761 #ifdef IWEVGENIE 1763 1762 memset(&iwe, 0, sizeof(iwe)); 1764 1763 memcpy(buf, se->se_wpa_ie, se->se_wpa_ie[1] + 2); … … 1772 1771 se->se_wpa_ie, se->se_wpa_ie[1] + 2, 1773 1772 wpa_leader, sizeof(wpa_leader) - 1); 1774 1773 #endif 1774 last_ev = current_ev; 1775 1775 if (iwe.u.data.length != 0) { 1776 1776 current_ev = iwe_stream_add_point(current_ev, end_buf, 1777 1777 &iwe, buf); … … 2845 2845 return 0; 2846 2846 } 2847 2847 2848 /* returns non-zero if ID is for a system IE (not for app use) */ 2849 static int 2850 is_sys_ie(u_int8_t ie_id) 2851 { 2852 /* XXX review this list */ 2853 switch (ie_id) { 2854 case IEEE80211_ELEMID_SSID: 2855 case IEEE80211_ELEMID_RATES: 2856 case IEEE80211_ELEMID_FHPARMS: 2857 case IEEE80211_ELEMID_DSPARMS: 2858 case IEEE80211_ELEMID_CFPARMS: 2859 case IEEE80211_ELEMID_TIM: 2860 case IEEE80211_ELEMID_IBSSPARMS: 2861 case IEEE80211_ELEMID_COUNTRY: 2862 case IEEE80211_ELEMID_REQINFO: 2863 case IEEE80211_ELEMID_CHALLENGE: 2864 case IEEE80211_ELEMID_PWRCNSTR: 2865 case IEEE80211_ELEMID_PWRCAP: 2866 case IEEE80211_ELEMID_TPCREQ: 2867 case IEEE80211_ELEMID_TPCREP: 2868 case IEEE80211_ELEMID_SUPPCHAN: 2869 case IEEE80211_ELEMID_CHANSWITCHANN: 2870 case IEEE80211_ELEMID_MEASREQ: 2871 case IEEE80211_ELEMID_MEASREP: 2872 case IEEE80211_ELEMID_QUIET: 2873 case IEEE80211_ELEMID_IBSSDFS: 2874 case IEEE80211_ELEMID_ERP: 2875 case IEEE80211_ELEMID_RSN: 2876 case IEEE80211_ELEMID_XRATES: 2877 case IEEE80211_ELEMID_TPC: 2878 case IEEE80211_ELEMID_CCKM: 2879 return 1; 2880 default: 2881 return 0; 2882 } 2883 } 2884 2885 /* returns non-zero if the buffer appears to contain a valid IE list */ 2886 static int 2887 is_valid_ie_list(u_int32_t buf_len, void *buf, int exclude_sys_ies) 2888 { 2889 struct ieee80211_ie *ie = (struct ieee80211_ie *)buf; 2890 2891 while (buf_len >= sizeof(*ie)) { 2892 int ie_elem_len = sizeof(*ie) + ie->len; 2893 if (buf_len < ie_elem_len) 2894 break; 2895 if (exclude_sys_ies && is_sys_ie(ie->id)) 2896 break; 2897 buf_len -= ie_elem_len; 2898 ie = (struct ieee80211_ie *)(ie->info + ie->len); 2899 } 2900 2901 return (buf_len == 0) ? 1 : 0; 2902 } 2903 2848 2904 static int 2849 2905 ieee80211_ioctl_setoptie(struct net_device *dev, struct iw_request_info *info, 2850 2906 struct iw_point *wri, char *extra) … … 2860 2916 */ 2861 2917 if (vap->iv_opmode != IEEE80211_M_STA) 2862 2918 return -EINVAL; 2919 if (! is_valid_ie_list(wri->length, extra, 0)) 2920 return -EINVAL; 2863 2921 /* NB: wri->length is validated by the wireless extensions code */ 2864 2922 MALLOC(ie, void *, wri->length, M_DEVBUF, M_WAITOK); 2865 2923 if (ie == NULL) 2866 2924 return -ENOMEM; 2867 2925 memcpy(ie, extra, wri->length); 2868 /* XXX sanity check data? */2869 2926 if (vap->iv_opt_ie != NULL) 2870 2927 FREE(vap->iv_opt_ie, M_DEVBUF); 2871 2928 vap->iv_opt_ie = ie; … … 2893 2950 return 0; 2894 2951 } 2895 2952 2953 /* the following functions are used by the set/get appiebuf functions */ 2954 static int 2955 add_app_ie(unsigned int frame_type_index, struct ieee80211vap *vap, 2956 struct ieee80211req_getset_appiebuf *iebuf) 2957 { 2958 struct ieee80211_ie *ie; 2959 2960 if (! is_valid_ie_list(iebuf->app_buflen, iebuf->app_buf, 1)) 2961 return -EINVAL; 2962 /* NB: data.length is validated by the wireless extensions code */ 2963 MALLOC(ie, struct ieee80211_ie *, iebuf->app_buflen, M_DEVBUF, M_WAITOK); 2964 if (ie == NULL) 2965 return -ENOMEM; 2966 2967 memcpy(ie, iebuf->app_buf, iebuf->app_buflen); 2968 if (vap->app_ie[frame_type_index].ie != NULL) 2969 FREE(vap->app_ie[frame_type_index].ie, M_DEVBUF); 2970 vap->app_ie[frame_type_index].ie = ie; 2971 vap->app_ie[frame_type_index].length = iebuf->app_buflen; 2972 2973 return 0; 2974 } 2975 2976 static int 2977 remove_app_ie(unsigned int frame_type_index, struct ieee80211vap *vap) 2978 { 2979 struct ieee80211_app_ie_t *app_ie = &vap->app_ie[frame_type_index]; 2980 if (app_ie->ie != NULL) { 2981 FREE(app_ie->ie, M_DEVBUF); 2982 app_ie->ie = NULL; 2983 app_ie->length = 0; 2984 } 2985 return 0; 2986 } 2987 2988 static int 2989 get_app_ie(unsigned int frame_type_index, struct ieee80211vap *vap, 2990 struct ieee80211req_getset_appiebuf *iebuf) 2991 { 2992 struct ieee80211_app_ie_t *app_ie = &vap->app_ie[frame_type_index]; 2993 if (iebuf->app_buflen < app_ie->length) 2994 return -EINVAL; 2995 2996 iebuf->app_buflen = app_ie->length; 2997 memcpy(iebuf->app_buf, app_ie->ie, app_ie->length); 2998 return 0; 2999 } 3000 3001 static int 3002 ieee80211_ioctl_setappiebuf(struct net_device *dev, 3003 struct iw_request_info *info, 3004 void *w, char *extra) 3005 { 3006 struct ieee80211vap *vap = dev->priv; 3007 struct ieee80211req_getset_appiebuf *iebuf = 3008 (struct ieee80211req_getset_appiebuf *)extra; 3009 enum ieee80211_opmode chk_opmode; 3010 int rc = 0; 3011 3012 if (iebuf->app_buflen > IEEE80211_APPIE_MAX) 3013 return -EINVAL; 3014 3015 switch (iebuf->app_frmtype) { 3016 case IEEE80211_APPIE_FRAME_BEACON: 3017 case IEEE80211_APPIE_FRAME_PROBE_RESP: 3018 case IEEE80211_APPIE_FRAME_ASSOC_RESP: 3019 chk_opmode = IEEE80211_M_HOSTAP; 3020 break; 3021 case IEEE80211_APPIE_FRAME_PROBE_REQ: 3022 case IEEE80211_APPIE_FRAME_ASSOC_REQ: 3023 chk_opmode = IEEE80211_M_STA; 3024 break; 3025 default: 3026 return -EINVAL; 3027 } 3028 if (vap->iv_opmode != chk_opmode) 3029 return -EINVAL; 3030 3031 if (iebuf->app_buflen) 3032 rc = add_app_ie(iebuf->app_frmtype, vap, iebuf); 3033 else 3034 rc = remove_app_ie(iebuf->app_frmtype, vap); 3035 if ((iebuf->app_frmtype == IEEE80211_APPIE_FRAME_BEACON) && (rc == 0)) 3036 vap->iv_flags_ext |= IEEE80211_FEXT_APPIE_UPDATE; 3037 3038 return rc; 3039 } 3040 3041 static int 3042 ieee80211_ioctl_getappiebuf(struct net_device *dev, struct iw_request_info *info, 3043 void *w, char *extra) 3044 { 3045 struct ieee80211vap *vap = dev->priv; 3046 struct ieee80211req_getset_appiebuf *iebuf = 3047 (struct ieee80211req_getset_appiebuf *)extra; 3048 3049 switch (iebuf->app_frmtype) { 3050 case IEEE80211_APPIE_FRAME_BEACON: 3051 case IEEE80211_APPIE_FRAME_PROBE_RESP: 3052 case IEEE80211_APPIE_FRAME_ASSOC_RESP: 3053 if (vap->iv_opmode == IEEE80211_M_STA) 3054 return -EINVAL; 3055 break; 3056 case IEEE80211_APPIE_FRAME_PROBE_REQ: 3057 case IEEE80211_APPIE_FRAME_ASSOC_REQ: 3058 if (vap->iv_opmode != IEEE80211_M_STA) 3059 return -EINVAL; 3060 break; 3061 default: 3062 return -EINVAL; 3063 } 3064 3065 return get_app_ie(iebuf->app_frmtype, vap, iebuf); 3066 } 3067 3068 static int 3069 ieee80211_ioctl_setfilter(struct net_device *dev, struct iw_request_info *info, 3070 void *w, char *extra) 3071 { 3072 struct ieee80211vap *vap = dev->priv; 3073 struct ieee80211req_set_filter *app_filter = (struct ieee80211req_set_filter *)extra; 3074 3075 if ((extra == NULL) || (app_filter->app_filterype & ~IEEE80211_FILTER_TYPE_ALL)) 3076 return -EINVAL; 3077 3078 vap->app_filter = app_filter->app_filterype; 3079 3080 return 0; 3081 } 3082 2896 3083 static int 2897 3084 ieee80211_ioctl_setkey(struct net_device *dev, struct iw_request_info *info, 2898 3085 void *w, char *extra) … … 4612 4799 IW_PRIV_TYPE_BYTE | sizeof(struct ieee80211req_chanlist) 4613 4800 #define IW_PRIV_TYPE_CHANINFO \ 4614 4801 IW_PRIV_TYPE_BYTE | sizeof(struct ieee80211req_chaninfo) 4802 #define IW_PRIV_TYPE_APPIEBUF \ 4803 (IW_PRIV_TYPE_BYTE | IEEE80211_APPIE_MAX) 4804 #define IW_PRIV_TYPE_FILTER \ 4805 IW_PRIV_TYPE_BYTE | sizeof(struct ieee80211req_set_filter) 4615 4806 4616 4807 static const struct iw_priv_args ieee80211_priv_args[] = { 4617 4808 /* NB: setoptie & getoptie are !IW_PRIV_SIZE_FIXED */ … … 4938 5129 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "markdfs" }, 4939 5130 { IEEE80211_PARAM_MARKDFS, 4940 5131 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_markdfs" }, 5132 { IEEE80211_IOCTL_SET_APPIEBUF, 5133 IW_PRIV_TYPE_APPIEBUF, 0, "setiebuf" }, 5134 { IEEE80211_IOCTL_GET_APPIEBUF, 5135 0, IW_PRIV_TYPE_APPIEBUF, "getiebuf" }, 5136 { IEEE80211_IOCTL_FILTERFRAME, 5137 IW_PRIV_TYPE_FILTER , 0, "setfilter" }, 4941 5138 4942 5139 #endif /* WIRELESS_EXT >= 12 */ 4943 5140 }; … … 5024 5221 (iw_handler) ieee80211_ioctl_setchanlist, /* SIOCIWFIRSTPRIV+6 */ 5025 5222 (iw_handler) ieee80211_ioctl_getchanlist, /* SIOCIWFIRSTPRIV+7 */ 5026 5223 (iw_handler) ieee80211_ioctl_chanswitch, /* SIOCIWFIRSTPRIV+8 */ 5027 (iw_handler) NULL,/* SIOCIWFIRSTPRIV+9 */5028 (iw_handler) NULL,/* SIOCIWFIRSTPRIV+10 */5224 (iw_handler) ieee80211_ioctl_getappiebuf, /* SIOCIWFIRSTPRIV+9 */ 5225 (iw_handler) ieee80211_ioctl_setappiebuf, /* SIOCIWFIRSTPRIV+10 */ 5029 5226 (iw_handler) ieee80211_ioctl_getscanresults, /* SIOCIWFIRSTPRIV+11 */ 5030 (iw_handler) NULL,/* SIOCIWFIRSTPRIV+12 */5227 (iw_handler) ieee80211_ioctl_setfilter, /* SIOCIWFIRSTPRIV+12 */ 5031 5228 (iw_handler) ieee80211_ioctl_getchaninfo, /* SIOCIWFIRSTPRIV+13 */ 5032 5229 (iw_handler) ieee80211_ioctl_setoptie, /* SIOCIWFIRSTPRIV+14 */ 5033 5230 (iw_handler) ieee80211_ioctl_getoptie, /* SIOCIWFIRSTPRIV+15 */
