Changeset 1756
- Timestamp:
- 10/18/06 13:41:05 (2 years ago)
- Files:
-
- trunk/ath/if_ath.c (modified) (2 diffs)
- trunk/net80211/ieee80211.h (modified) (1 diff)
- trunk/net80211/ieee80211_beacon.c (modified) (2 diffs)
- trunk/net80211/ieee80211_input.c (modified) (2 diffs)
- trunk/net80211/ieee80211_ioctl.h (modified) (4 diffs)
- trunk/net80211/ieee80211_output.c (modified) (8 diffs)
- trunk/net80211/ieee80211_proto.h (modified) (1 diff)
- trunk/net80211/ieee80211_var.h (modified) (4 diffs)
- trunk/net80211/ieee80211_wireless.c (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/ath/if_ath.c
r1755 r1756 1213 1213 struct ath_vap *avp = ATH_VAP(vap); 1214 1214 int decrease = 1; 1215 int i; 1215 1216 KASSERT(vap->iv_state == IEEE80211_S_INIT, ("vap not stopped")); 1216 1217 … … 1285 1286 } 1286 1287 #endif 1288 1289 for (i = 0; i < IEEE80211_APPIE_NUM_OF_FRAME; ++ i) { 1290 if (vap->app_ie[i].ie != NULL) { 1291 FREE(vap->app_ie[i].ie, M_DEVBUF); 1292 vap->app_ie[i].ie = NULL; 1293 vap->app_ie[i].length = 0; 1294 } 1295 } 1287 1296 1288 1297 if (dev->flags & IFF_RUNNING) { trunk/net80211/ieee80211.h
r1712 r1756 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 */ trunk/net80211/ieee80211_beacon.c
r1721 r1756 186 186 frm = ieee80211_add_xr_param(frm, vap); 187 187 #endif 188 bo->bo_appie_buf = frm; 189 bo->bo_appie_buf_len = 0; 188 190 189 191 bo->bo_tim_trailerlen = frm - bo->bo_tim_trailer; … … 527 529 ieee80211_add_athAdvCap(bo->bo_ath_caps, vap->iv_bss->ni_ath_flags, 528 530 vap->iv_bss->ni_ath_defkeyindex); 531 /* add APP_IE buffer if app updated it */ 532 if (vap->iv_flags_ext & IEEE80211_FEXT_APPIE_UPDATE) { 533 /* adjust the buffer size if the size is changed */ 534 if (vap->app_ie[IEEE80211_APPIE_FRAME_BEACON].length != bo->bo_appie_buf_len) { 535 int diff_len; 536 diff_len = vap->app_ie[IEEE80211_APPIE_FRAME_BEACON].length - bo->bo_appie_buf_len; 537 538 if (diff_len > 0) 539 skb_put(skb, diff_len); 540 else 541 skb_trim(skb, skb->len + diff_len); 542 543 bo->bo_appie_buf_len = vap->app_ie[IEEE80211_APPIE_FRAME_BEACON].length; 544 /* update the trailer lens */ 545 bo->bo_chanswitch_trailerlen += diff_len; 546 bo->bo_tim_trailerlen += diff_len; 547 548 len_changed = 1; 549 } 550 memcpy(bo->bo_appie_buf,vap->app_ie[IEEE80211_APPIE_FRAME_BEACON].ie, 551 vap->app_ie[IEEE80211_APPIE_FRAME_BEACON].length); 552 553 vap->iv_flags_ext &= ~IEEE80211_FEXT_APPIE_UPDATE; 554 } 555 529 556 IEEE80211_UNLOCK(ic); 530 557 trunk/net80211/ieee80211_input.c
r1721 r1756 2209 2209 } 2210 2210 2211 static void 2212 forward_mgmt_to_app(struct ieee80211vap *vap, int subtype, struct sk_buff *skb, 2213 struct ieee80211_frame *wh) 2214 { 2215 struct net_device *dev = vap->iv_dev; 2216 int filter_type = 0; 2217 2218 switch (subtype) { 2219 case IEEE80211_FC0_SUBTYPE_BEACON: 2220 filter_type = IEEE80211_FILTER_TYPE_BEACON; 2221 break; 2222 case IEEE80211_FC0_SUBTYPE_PROBE_REQ: 2223 filter_type = IEEE80211_FILTER_TYPE_PROBE_REQ; 2224 break; 2225 case IEEE80211_FC0_SUBTYPE_PROBE_RESP: 2226 filter_type = IEEE80211_FILTER_TYPE_PROBE_RESP; 2227 break; 2228 case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: 2229 case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: 2230 filter_type = IEEE80211_FILTER_TYPE_ASSOC_REQ; 2231 break; 2232 case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: 2233 case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: 2234 filter_type = IEEE80211_FILTER_TYPE_ASSOC_RESP; 2235 break; 2236 case IEEE80211_FC0_SUBTYPE_AUTH: 2237 filter_type = IEEE80211_FILTER_TYPE_AUTH; 2238 break; 2239 case IEEE80211_FC0_SUBTYPE_DEAUTH: 2240 filter_type = IEEE80211_FILTER_TYPE_DEAUTH; 2241 break; 2242 case IEEE80211_FC0_SUBTYPE_DISASSOC: 2243 filter_type = IEEE80211_FILTER_TYPE_DISASSOC; 2244 break; 2245 default: 2246 break; 2247 } 2248 2249 if (filter_type && ((vap->app_filter & filter_type) == filter_type)) { 2250 struct sk_buff *skb1; 2251 2252 skb1 = skb_copy(skb, GFP_ATOMIC); 2253 if (skb1 == NULL) 2254 return; 2255 skb1->dev = dev; 2256 skb1->mac.raw = skb1->data; 2257 skb1->ip_summed = CHECKSUM_NONE; 2258 skb1->pkt_type = PACKET_OTHERHOST; 2259 skb1->protocol = __constant_htons(0x0019); /* ETH_P_80211_RAW */ 2260 2261 netif_rx(skb1); 2262 } 2263 } 2264 2211 2265 void 2212 2266 ieee80211_saveath(struct ieee80211_node *ni, u_int8_t *ie) … … 2380 2434 frm = (u_int8_t *)&wh[1]; 2381 2435 efrm = skb->data + skb->len; 2436 2437 /* forward management frame to application */ 2438 if (vap->iv_opmode != IEEE80211_M_MONITOR) 2439 forward_mgmt_to_app(vap, subtype, skb, wh); 2440 2382 2441 switch (subtype) { 2383 2442 case IEEE80211_FC0_SUBTYPE_PROBE_RESP: trunk/net80211/ieee80211_ioctl.h
r1676 r1756 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 /* … … 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) … … 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, … … 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 trunk/net80211/ieee80211_output.c
r1721 r1756 1722 1722 2 + IEEE80211_RATE_SIZE + 1723 1723 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) + 1724 (optie != NULL ? optielen : 0)); 1724 (optie != NULL ? optielen : 0) + 1725 vap->app_ie[IEEE80211_APPIE_FRAME_PROBE_REQ].length); 1725 1726 if (skb == NULL) { 1726 1727 vap->iv_stats.is_tx_nobuf++; … … 1738 1739 frm += optielen; 1739 1740 } 1741 1742 if (vap->app_ie[IEEE80211_APPIE_FRAME_PROBE_REQ].ie) { 1743 memcpy(frm, vap->app_ie[IEEE80211_APPIE_FRAME_PROBE_REQ].ie, 1744 vap->app_ie[IEEE80211_APPIE_FRAME_PROBE_REQ].length); 1745 frm += vap->app_ie[IEEE80211_APPIE_FRAME_PROBE_REQ].length; 1746 } 1747 1740 1748 skb_trim(skb, frm - skb->data); 1741 1749 … … 1834 1842 sizeof(struct ieee80211_xr_param) : 0) 1835 1843 #endif 1844 + vap->app_ie[IEEE80211_APPIE_FRAME_PROBE_RESP].length 1836 1845 ); 1837 1846 if (skb == NULL) … … 1929 1938 frm = ieee80211_add_xr_param(frm, vap); 1930 1939 #endif 1940 if (vap->app_ie[IEEE80211_APPIE_FRAME_PROBE_RESP].ie) { 1941 memcpy(frm, vap->app_ie[IEEE80211_APPIE_FRAME_PROBE_RESP].ie, 1942 vap->app_ie[IEEE80211_APPIE_FRAME_PROBE_RESP].length); 1943 frm += vap->app_ie[IEEE80211_APPIE_FRAME_PROBE_RESP].length; 1944 } 1945 1931 1946 skb_trim(skb, frm - skb->data); 1932 1947 break; … … 2029 2044 sizeof(struct ieee80211_ie_wme) + 2030 2045 sizeof(struct ieee80211_ie_athAdvCap) + 2031 (vap->iv_opt_ie != NULL ? vap->iv_opt_ie_len : 0)); 2046 (vap->iv_opt_ie != NULL ? vap->iv_opt_ie_len : 0) + 2047 vap->app_ie[IEEE80211_APPIE_FRAME_ASSOC_REQ].length); 2032 2048 if (skb == NULL) 2033 2049 senderr(ENOMEM, is_tx_nobuf); … … 2100 2116 frm += vap->iv_opt_ie_len; 2101 2117 } 2118 2119 if (vap->app_ie[IEEE80211_APPIE_FRAME_ASSOC_REQ].ie) { 2120 memcpy(frm, vap->app_ie[IEEE80211_APPIE_FRAME_ASSOC_REQ].ie, 2121 vap->app_ie[IEEE80211_APPIE_FRAME_ASSOC_REQ].length); 2122 frm += vap->app_ie[IEEE80211_APPIE_FRAME_ASSOC_REQ].length; 2123 } 2124 2102 2125 skb_trim(skb, frm - skb->data); 2103 2126 … … 2122 2145 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) + 2123 2146 sizeof(struct ieee80211_wme_param) + 2124 (vap->iv_ath_cap ? sizeof(struct ieee80211_ie_athAdvCap):0)); 2147 (vap->iv_ath_cap ? sizeof(struct ieee80211_ie_athAdvCap):0) + 2148 vap->app_ie[IEEE80211_APPIE_FRAME_ASSOC_RESP].length); 2125 2149 if (skb == NULL) 2126 2150 senderr(ENOMEM, is_tx_nobuf); … … 2166 2190 vap->iv_ath_cap & ni->ni_ath_flags, 2167 2191 ni->ni_ath_defkeyindex); 2192 2193 if (vap->app_ie[IEEE80211_APPIE_FRAME_ASSOC_RESP].ie) { 2194 memcpy(frm, vap->app_ie[IEEE80211_APPIE_FRAME_ASSOC_RESP].ie, 2195 vap->app_ie[IEEE80211_APPIE_FRAME_ASSOC_RESP].length); 2196 frm += vap->app_ie[IEEE80211_APPIE_FRAME_ASSOC_RESP].length; 2197 } 2168 2198 2169 2199 skb_trim(skb, frm - skb->data); trunk/net80211/ieee80211_proto.h
r1637 r1756 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 }; trunk/net80211/ieee80211_var.h
r1732 r1756 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) ? \ … … 290 292 }; 291 293 #endif 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 }; 292 299 293 300 struct ieee80211vap { … … 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); … … 454 464 #define IEEE80211_FEXT_SWBMISS 0x00000400 /* CONF: use software beacon timer */ 455 465 #define IEEE80211_FEXT_DROPUNENC_EAPOL 0x00000800 /* CONF: drop unencrypted eapol frames */ 466 #define IEEE80211_FEXT_APPIE_UPDATE 0x00001000 /* STATE: beacon APP IE updated */ 456 467 457 468 #define IEEE80211_COM_UAPSD_ENABLE(_ic) ((_ic)->ic_flags_ext |= IEEE80211_FEXT_UAPSD) trunk/net80211/ieee80211_wireless.c
r1751 r1756 2844 2844 } 2845 2845 2846 /* returns non-zero if ID is for a system IE (not for app use) */ 2847 static int 2848 is_sys_ie(u_int8_t ie_id) 2849 { 2850 /* XXX review this list */ 2851 switch (ie_id) { 2852 case IEEE80211_ELEMID_SSID: 2853 case IEEE80211_ELEMID_RATES: 2854 case IEEE80211_ELEMID_FHPARMS: 2855 case IEEE80211_ELEMID_DSPARMS: 2856 case IEEE80211_ELEMID_CFPARMS: 2857 case IEEE80211_ELEMID_TIM: 2858 case IEEE80211_ELEMID_IBSSPARMS: 2859 case IEEE80211_ELEMID_COUNTRY: 2860 case IEEE80211_ELEMID_REQINFO: 2861 case IEEE80211_ELEMID_CHALLENGE: 2862 case IEEE80211_ELEMID_PWRCNSTR: 2863 case IEEE80211_ELEMID_PWRCAP: 2864 case IEEE80211_ELEMID_TPCREQ: 2865 case IEEE80211_ELEMID_TPCREP: 2866 case IEEE80211_ELEMID_SUPPCHAN: 2867 case IEEE80211_ELEMID_CHANSWITCHANN: 2868 case IEEE80211_ELEMID_MEASREQ: 2869 case IEEE80211_ELEMID_MEASREP: 2870 case IEEE80211_ELEMID_QUIET: 2871 case IEEE80211_ELEMID_IBSSDFS: 2872 case IEEE80211_ELEMID_ERP: 2873 case IEEE80211_ELEMID_RSN: 2874 case IEEE80211_ELEMID_XRATES: 2875 case IEEE80211_ELEMID_TPC: 2876 case IEEE80211_ELEMID_CCKM: 2877 return 1; 2878 default: 2879 return 0; 2880 } 2881 } 2882 2883 /* returns non-zero if the buffer appears to contain a valid IE list */ 2884 static int 2885 is_valid_ie_list(u_int32_t buf_len, void *buf, int exclude_sys_ies) 2886 { 2887 struct ieee80211_ie *ie = (struct ieee80211_ie *)buf; 2888 2889 while (buf_len >= sizeof(*ie)) { 2890 int ie_elem_len = sizeof(*ie) + ie->len; 2891 if (buf_len < ie_elem_len) 2892 break; 2893 if (exclude_sys_ies && is_sys_ie(ie->id)) 2894 break; 2895 buf_len -= ie_elem_len; 2896 ie = (struct ieee80211_ie *)(ie->info + ie->len); 2897 } 2898 2899 return (buf_len == 0) ? 1 : 0; 2900 } 2901 2846 2902 static int 2847 2903 ieee80211_ioctl_setoptie(struct net_device *dev, struct iw_request_info *info, … … 2859 2915 if (vap->iv_opmode != IEEE80211_M_STA) 2860 2916 return -EINVAL; 2917 if (! is_valid_ie_list(wri->length, extra, 0)) 2918 return -EINVAL; 2861 2919 /* NB: wri->length is validated by the wireless extensions code */ 2862 2920 MALLOC(ie, void *, wri->length, M_DEVBUF, M_WAITOK); … … 2864 2922 return -ENOMEM; 2865 2923 memcpy(ie, extra, wri->length); 2866 /* XXX sanity check data? */2867 2924 if (vap->iv_opt_ie != NULL) 2868 2925 FREE(vap->iv_opt_ie, M_DEVBUF); … … 2889 2946 wri->length = vap->iv_opt_ie_len; 2890 2947 memcpy(extra, vap->iv_opt_ie, vap->iv_opt_ie_len); 2948 return 0; 2949 } 2950 2951 /* the following functions are used by the set/get appiebuf functions */ 2952 static int 2953 add_app_ie(unsigned int frame_type_index, struct ieee80211vap *vap, 2954 struct ieee80211req_getset_appiebuf *iebuf) 2955 { 2956 struct ieee80211_ie *ie; 2957 2958 if (! is_valid_ie_list(iebuf->app_buflen, iebuf->app_buf, 1)) 2959 return -EINVAL; 2960 /* NB: data.length is validated by the wireless extensions code */ 2961 MALLOC(ie, struct ieee80211_ie *, iebuf->app_buflen, M_DEVBUF, M_WAITOK); 2962 if (ie == NULL) 2963 return -ENOMEM; 2964 2965 memcpy(ie, iebuf->app_buf, iebuf->app_buflen); 2966 if (vap->app_ie[frame_type_index].ie != NULL) 2967 FREE(vap->app_ie[frame_type_index].ie, M_DEVBUF); 2968 vap->app_ie[frame_type_index].ie = ie; 2969 vap->app_ie[frame_type_index].length = iebuf->app_buflen; 2970 2971 return 0; 2972 } 2973 2974 static int 2975 remove_app_ie(unsigned int frame_type_index, struct ieee80211vap *vap) 2976 { 2977 struct ieee80211_app_ie_t *app_ie = &vap->app_ie[frame_type_index]; 2978 if (app_ie->ie != NULL) { 2979 FREE(app_ie->ie, M_DEVBUF); 2980 app_ie->ie = NULL; 2981 app_ie->length = 0; 2982 } 2983 return 0; 2984 } 2985 2986 static int 2987 get_app_ie(unsigned int frame_type_index, struct ieee80211vap *vap, 2988 struct ieee80211req_getset_appiebuf *iebuf) 2989 { 2990 struct ieee80211_app_ie_t *app_ie = &vap->app_ie[frame_type_index]; 2991 if (iebuf->app_buflen < app_ie->length) 2992 return -EINVAL; 2993 2994 iebuf->app_buflen = app_ie->length; 2995 memcpy(iebuf->app_buf, app_ie->ie, app_ie->length); 2996 return 0; 2997 } 2998 2999 static int 3000 ieee80211_ioctl_setappiebuf(struct net_device *dev, 3001 struct iw_request_info *info, 3002 void *w, char *extra) 3003 { 3004 struct ieee80211vap *vap = dev->priv; 3005 struct ieee80211req_getset_appiebuf *iebuf = 3006 (struct ieee80211req_getset_appiebuf *)extra; 3007 enum ieee80211_opmode chk_opmode; 3008 int rc = 0; 3009 3010 if (iebuf->app_buflen > IEEE80211_APPIE_MAX) 3011 return -EINVAL; 3012 3013 switch (iebuf->app_frmtype) { 3014 case IEEE80211_APPIE_FRAME_BEACON: 3015 case IEEE80211_APPIE_FRAME_PROBE_RESP: 3016 case IEEE80211_APPIE_FRAME_ASSOC_RESP: 3017 chk_opmode = IEEE80211_M_HOSTAP; 3018 break; 3019 case IEEE80211_APPIE_FRAME_PROBE_REQ: 3020 case IEEE80211_APPIE_FRAME_ASSOC_REQ: 3021 chk_opmode = IEEE80211_M_STA; 3022 break; 3023 default: 3024 return -EINVAL; 3025 } 3026 if (vap->iv_opmode != chk_opmode) 3027 return -EINVAL; 3028 3029 if (iebuf->app_buflen) 3030 rc = add_app_ie(iebuf->app_frmtype, vap, iebuf); 3031 else 3032 rc = remove_app_ie(iebuf->app_frmtype, vap); 3033 if ((iebuf->app_frmtype == IEEE80211_APPIE_FRAME_BEACON) && (rc == 0)) 3034 vap->iv_flags_ext |= IEEE80211_FEXT_APPIE_UPDATE; 3035 3036 return rc; 3037 } 3038 3039 static int 3040 ieee80211_ioctl_getappiebuf(struct net_device *dev, struct iw_request_info *info, 3041 void *w, char *extra) 3042 { 3043 struct ieee80211vap *vap = dev->priv; 3044 struct ieee80211req_getset_appiebuf *iebuf = 3045 (struct ieee80211req_getset_appiebuf *)extra; 3046 3047 switch (iebuf->app_frmtype) { 3048 case IEEE80211_APPIE_FRAME_BEACON: 3049 case IEEE80211_APPIE_FRAME_PROBE_RESP: 3050 case IEEE80211_APPIE_FRAME_ASSOC_RESP: 3051 if (vap->iv_opmode == IEEE80211_M_STA) 3052 return -EINVAL; 3053 break; 3054 case IEEE80211_APPIE_FRAME_PROBE_REQ: 3055 case IEEE80211_APPIE_FRAME_ASSOC_REQ: 3056 if (vap->iv_opmode != IEEE80211_M_STA) 3057 return -EINVAL; 3058 break; 3059 default: 3060 return -EINVAL; 3061 } 3062 3063 return get_app_ie(iebuf->app_frmtype, vap, iebuf); 3064 } 3065 3066 static int 3067 ieee80211_ioctl_setfilter(struct net_device *dev, struct iw_request_info *info, 3068 void *w, char *extra) 3069 { 3070 struct ieee80211vap *vap = dev->priv; 3071 struct ieee80211req_set_filter *app_filter = (struct ieee80211req_set_filter *)extra; 3072 3073 if ((extra == NULL) || (app_filter->app_filterype & ~IEEE80211_FILTER_TYPE_ALL)) 3074 return -EINVAL; 3075 3076 vap->app_filter = app_filter->app_filterype; 3077 2891 3078 return 0; 2892 3079 } … … 4611 4798 #define IW_PRIV_TYPE_CHANINFO \ 4612 4799 IW_PRIV_TYPE_BYTE | sizeof(struct ieee80211req_chaninfo) 4800 #define IW_PRIV_TYPE_APPIEBUF \ 4801 (IW_PRIV_TYPE_BYTE | IEEE80211_APPIE_MAX) 4802 #define IW_PRIV_TYPE_FILTER \ 4803 IW_PRIV_TYPE_BYTE | sizeof(struct ieee80211req_set_filter) 4613 4804 4614 4805 static const struct iw_priv_args ieee80211_priv_args[] = { … … 4937 5128 { IEEE80211_PARAM_MARKDFS, 4938 5129 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_markdfs" }, 5130 { IEEE80211_IOCTL_SET_APPIEBUF, 5131 IW_PRIV_TYPE_APPIEBUF, 0, "setiebuf" }, 5132 { IEEE80211_IOCTL_GET_APPIEBUF, 5133 0, IW_PRIV_TYPE_APPIEBUF, "getiebuf" }, 5134 { IEEE80211_IOCTL_FILTERFRAME, 5135 IW_PRIV_TYPE_FILTER , 0, "setfilter" }, 4939 5136 4940 5137 #endif /* WIRELESS_EXT >= 12 */ … … 5023 5220 (iw_handler) ieee80211_ioctl_getchanlist, /* SIOCIWFIRSTPRIV+7 */ 5024 5221 (iw_handler) ieee80211_ioctl_chanswitch, /* SIOCIWFIRSTPRIV+8 */ 5025 (iw_handler) NULL,/* SIOCIWFIRSTPRIV+9 */5026 (iw_handler) NULL,/* SIOCIWFIRSTPRIV+10 */5222 (iw_handler) ieee80211_ioctl_getappiebuf, /* SIOCIWFIRSTPRIV+9 */ 5223 (iw_handler) ieee80211_ioctl_setappiebuf, /* SIOCIWFIRSTPRIV+10 */ 5027 5224 (iw_handler) ieee80211_ioctl_getscanresults, /* SIOCIWFIRSTPRIV+11 */ 5028 (iw_handler) NULL,/* SIOCIWFIRSTPRIV+12 */5225 (iw_handler) ieee80211_ioctl_setfilter, /* SIOCIWFIRSTPRIV+12 */ 5029 5226 (iw_handler) ieee80211_ioctl_getchaninfo, /* SIOCIWFIRSTPRIV+13 */ 5030 5227 (iw_handler) ieee80211_ioctl_setoptie, /* SIOCIWFIRSTPRIV+14 */
