Ticket #517: madwifi-0.9.2-appie.diff
| File madwifi-0.9.2-appie.diff, 21.5 kB (added by ccpearson, 6 years ago) |
|---|
-
madwifi-0.9.2/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-0.9.2/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-0.9.2/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-0.9.2/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-0.9.2/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-0.9.2/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-0.9.2/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-0.9.2/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) … … 289 291 }; 290 292 #endif 291 293 294 struct ieee80211_app_ie_t { 295 u_int32_t length; /* buffer length */ 296 struct ieee80211_ie *ie; /* buffer containing one or more IEs */ 297 }; 298 292 299 struct ieee80211vap { 293 300 struct net_device *iv_dev; /* associated device */ 294 301 struct net_device_stats iv_devstats; /* interface statistics */ … … 392 399 unsigned int iv_nsdone; /* Done with scheduled newstate tasklet */ 393 400 uint8_t wds_mac[IEEE80211_ADDR_LEN]; 394 401 struct ieee80211_spy iv_spy; /* IWSPY support */ 402 struct ieee80211_app_ie_t app_ie[IEEE80211_APPIE_NUM_OF_FRAME]; /* app-specified IEs by frame type */ 403 u_int32_t app_filter; /* filters which management frames are forwarded to app */ 404 395 405 }; 396 406 MALLOC_DECLARE(M_80211_VAP); 397 407 … … 451 461 #define IEEE80211_FEXT_ERPUPDATE 0x00000200 /* STATUS: update ERP element */ 452 462 #define IEEE80211_FEXT_SWBMISS 0x00000400 /* CONF: use software beacon timer */ 453 463 #define IEEE80211_FEXT_DROPUNENC_EAPOL 0x00000800 /* CONF: drop unencrypted eapol frames */ 464 #define IEEE80211_FEXT_APPIE_UPDATE 0x00001000 /* STATE: beacon APP IE updated */ 454 465 455 466 #define IEEE80211_COM_UAPSD_ENABLE(_ic) ((_ic)->ic_flags_ext |= IEEE80211_FEXT_UAPSD) 456 467 #define IEEE80211_COM_UAPSD_DISABLE(_ic) ((_ic)->ic_flags_ext &= ~IEEE80211_FEXT_UAPSD) -
madwifi-0.9.2/net80211/ieee80211_wireless.c
old new 2747 2747 return 0; 2748 2748 } 2749 2749 2750 /* returns non-zero if ID is for a system IE (not for app use) */ 2751 static int 2752 is_sys_ie(u_int8_t ie_id) 2753 { 2754 /* XXX review this list */ 2755 switch (ie_id) { 2756 case IEEE80211_ELEMID_SSID: 2757 case IEEE80211_ELEMID_RATES: 2758 case IEEE80211_ELEMID_FHPARMS: 2759 case IEEE80211_ELEMID_DSPARMS: 2760 case IEEE80211_ELEMID_CFPARMS: 2761 case IEEE80211_ELEMID_TIM: 2762 case IEEE80211_ELEMID_IBSSPARMS: 2763 case IEEE80211_ELEMID_COUNTRY: 2764 case IEEE80211_ELEMID_REQINFO: 2765 case IEEE80211_ELEMID_CHALLENGE: 2766 case IEEE80211_ELEMID_PWRCNSTR: 2767 case IEEE80211_ELEMID_PWRCAP: 2768 case IEEE80211_ELEMID_TPCREQ: 2769 case IEEE80211_ELEMID_TPCREP: 2770 case IEEE80211_ELEMID_SUPPCHAN: 2771 case IEEE80211_ELEMID_CHANSWITCHANN: 2772 case IEEE80211_ELEMID_MEASREQ: 2773 case IEEE80211_ELEMID_MEASREP: 2774 case IEEE80211_ELEMID_QUIET: 2775 case IEEE80211_ELEMID_IBSSDFS: 2776 case IEEE80211_ELEMID_ERP: 2777 case IEEE80211_ELEMID_RSN: 2778 case IEEE80211_ELEMID_XRATES: 2779 case IEEE80211_ELEMID_TPC: 2780 case IEEE80211_ELEMID_CCKM: 2781 return 1; 2782 default: 2783 return 0; 2784 } 2785 } 2786 2787 /* returns non-zero if the buffer appears to contain a valid IE list */ 2788 static int 2789 is_valid_ie_list(u_int32_t buf_len, void *buf, int exclude_sys_ies) 2790 { 2791 struct ieee80211_ie *ie = (struct ieee80211_ie *)buf; 2792 2793 while (buf_len >= sizeof(*ie)) { 2794 int ie_elem_len = sizeof(*ie) + ie->len; 2795 if (buf_len < ie_elem_len) 2796 break; 2797 if (exclude_sys_ies && is_sys_ie(ie->id)) 2798 break; 2799 buf_len -= ie_elem_len; 2800 ie = (struct ieee80211_ie *)(ie->info + ie->len); 2801 } 2802 2803 return (buf_len == 0) ? 1 : 0; 2804 } 2805 2750 2806 static int 2751 2807 ieee80211_ioctl_setoptie(struct net_device *dev, struct iw_request_info *info, 2752 2808 struct iw_point *wri, char *extra) … … 2762 2818 */ 2763 2819 if (vap->iv_opmode != IEEE80211_M_STA) 2764 2820 return -EINVAL; 2821 if (! is_valid_ie_list(wri->length, extra, 0)) 2822 return -EINVAL; 2765 2823 /* NB: wri->length is validated by the wireless extensions code */ 2766 2824 MALLOC(ie, void *, wri->length, M_DEVBUF, M_WAITOK); 2767 2825 if (ie == NULL) 2768 2826 return -ENOMEM; 2769 2827 memcpy(ie, extra, wri->length); 2770 /* XXX sanity check data? */2771 2828 if (vap->iv_opt_ie != NULL) 2772 2829 FREE(vap->iv_opt_ie, M_DEVBUF); 2773 2830 vap->iv_opt_ie = ie; … … 2795 2852 return 0; 2796 2853 } 2797 2854 2855 /* the following functions are used by the set/get appiebuf functions */ 2856 static int 2857 add_app_ie(unsigned int frame_type_index, struct ieee80211vap *vap, 2858 struct ieee80211req_getset_appiebuf *iebuf) 2859 { 2860 struct ieee80211_ie *ie; 2861 2862 if (! is_valid_ie_list(iebuf->app_buflen, iebuf->app_buf, 1)) 2863 return -EINVAL; 2864 /* NB: data.length is validated by the wireless extensions code */ 2865 MALLOC(ie, struct ieee80211_ie *, iebuf->app_buflen, M_DEVBUF, M_WAITOK); 2866 if (ie == NULL) 2867 return -ENOMEM; 2868 2869 memcpy(ie, iebuf->app_buf, iebuf->app_buflen); 2870 if (vap->app_ie[frame_type_index].ie != NULL) 2871 FREE(vap->app_ie[frame_type_index].ie, M_DEVBUF); 2872 vap->app_ie[frame_type_index].ie = ie; 2873 vap->app_ie[frame_type_index].length = iebuf->app_buflen; 2874 2875 return 0; 2876 } 2877 2878 static int 2879 remove_app_ie(unsigned int frame_type_index, struct ieee80211vap *vap) 2880 { 2881 struct ieee80211_app_ie_t *app_ie = &vap->app_ie[frame_type_index]; 2882 if (app_ie->ie != NULL) { 2883 FREE(app_ie->ie, M_DEVBUF); 2884 app_ie->ie = NULL; 2885 app_ie->length = 0; 2886 } 2887 return 0; 2888 } 2889 2890 static int 2891 get_app_ie(unsigned int frame_type_index, struct ieee80211vap *vap, 2892 struct ieee80211req_getset_appiebuf *iebuf) 2893 { 2894 struct ieee80211_app_ie_t *app_ie = &vap->app_ie[frame_type_index]; 2895 if (iebuf->app_buflen < app_ie->length) 2896 return -EINVAL; 2897 2898 iebuf->app_buflen = app_ie->length; 2899 memcpy(iebuf->app_buf, app_ie->ie, app_ie->length); 2900 return 0; 2901 } 2902 2903 static int 2904 ieee80211_ioctl_setappiebuf(struct net_device *dev, 2905 struct iw_request_info *info, 2906 void *w, char *extra) 2907 { 2908 struct ieee80211vap *vap = dev->priv; 2909 struct ieee80211req_getset_appiebuf *iebuf = 2910 (struct ieee80211req_getset_appiebuf *)extra; 2911 enum ieee80211_opmode chk_opmode; 2912 int rc = 0; 2913 2914 if (iebuf->app_buflen > IEEE80211_APPIE_MAX) 2915 return -EINVAL; 2916 2917 switch (iebuf->app_frmtype) { 2918 case IEEE80211_APPIE_FRAME_BEACON: 2919 case IEEE80211_APPIE_FRAME_PROBE_RESP: 2920 case IEEE80211_APPIE_FRAME_ASSOC_RESP: 2921 chk_opmode = IEEE80211_M_HOSTAP; 2922 break; 2923 case IEEE80211_APPIE_FRAME_PROBE_REQ: 2924 case IEEE80211_APPIE_FRAME_ASSOC_REQ: 2925 chk_opmode = IEEE80211_M_STA; 2926 break; 2927 default: 2928 return -EINVAL; 2929 } 2930 if (vap->iv_opmode != chk_opmode) 2931 return -EINVAL; 2932 2933 if (iebuf->app_buflen) 2934 rc = add_app_ie(iebuf->app_frmtype, vap, iebuf); 2935 else 2936 rc = remove_app_ie(iebuf->app_frmtype, vap); 2937 if ((iebuf->app_frmtype == IEEE80211_APPIE_FRAME_BEACON) && (rc == 0)) 2938 vap->iv_flags_ext |= IEEE80211_FEXT_APPIE_UPDATE; 2939 2940 return rc; 2941 } 2942 2943 static int 2944 ieee80211_ioctl_getappiebuf(struct net_device *dev, struct iw_request_info *info, 2945 void *w, char *extra) 2946 { 2947 struct ieee80211vap *vap = dev->priv; 2948 struct ieee80211req_getset_appiebuf *iebuf = 2949 (struct ieee80211req_getset_appiebuf *)extra; 2950 2951 switch (iebuf->app_frmtype) { 2952 case IEEE80211_APPIE_FRAME_BEACON: 2953 case IEEE80211_APPIE_FRAME_PROBE_RESP: 2954 case IEEE80211_APPIE_FRAME_ASSOC_RESP: 2955 if (vap->iv_opmode == IEEE80211_M_STA) 2956 return -EINVAL; 2957 break; 2958 case IEEE80211_APPIE_FRAME_PROBE_REQ: 2959 case IEEE80211_APPIE_FRAME_ASSOC_REQ: 2960 if (vap->iv_opmode != IEEE80211_M_STA) 2961 return -EINVAL; 2962 break; 2963 default: 2964 return -EINVAL; 2965 } 2966 2967 return get_app_ie(iebuf->app_frmtype, vap, iebuf); 2968 } 2969 2970 static int 2971 ieee80211_ioctl_setfilter(struct net_device *dev, struct iw_request_info *info, 2972 void *w, char *extra) 2973 { 2974 struct ieee80211vap *vap = dev->priv; 2975 struct ieee80211req_set_filter *app_filter = (struct ieee80211req_set_filter *)extra; 2976 2977 if ((extra == NULL) || (app_filter->app_filterype & ~IEEE80211_FILTER_TYPE_ALL)) 2978 return -EINVAL; 2979 2980 vap->app_filter = app_filter->app_filterype; 2981 2982 return 0; 2983 } 2984 2798 2985 static int 2799 2986 ieee80211_ioctl_setkey(struct net_device *dev, struct iw_request_info *info, 2800 2987 void *w, char *extra) … … 4506 4693 IW_PRIV_TYPE_BYTE | sizeof(struct ieee80211req_chanlist) 4507 4694 #define IW_PRIV_TYPE_CHANINFO \ 4508 4695 IW_PRIV_TYPE_BYTE | sizeof(struct ieee80211req_chaninfo) 4696 #define IW_PRIV_TYPE_APPIEBUF \ 4697 (IW_PRIV_TYPE_BYTE | IEEE80211_APPIE_MAX) 4698 #define IW_PRIV_TYPE_FILTER \ 4699 IW_PRIV_TYPE_BYTE | sizeof(struct ieee80211req_set_filter) 4509 4700 4510 4701 static const struct iw_priv_args ieee80211_priv_args[] = { 4511 4702 /* NB: setoptie & getoptie are !IW_PRIV_SIZE_FIXED */ … … 4832 5023 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "markdfs" }, 4833 5024 { IEEE80211_PARAM_MARKDFS, 4834 5025 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_markdfs" }, 5026 { IEEE80211_IOCTL_SET_APPIEBUF, 5027 IW_PRIV_TYPE_APPIEBUF, 0, "setiebuf" }, 5028 { IEEE80211_IOCTL_GET_APPIEBUF, 5029 0, IW_PRIV_TYPE_APPIEBUF, "getiebuf" }, 5030 { IEEE80211_IOCTL_FILTERFRAME, 5031 IW_PRIV_TYPE_FILTER , 0, "setfilter" }, 4835 5032 4836 5033 #endif /* WIRELESS_EXT >= 12 */ 4837 5034 }; … … 4913 5110 (iw_handler) ieee80211_ioctl_setchanlist, /* SIOCIWFIRSTPRIV+6 */ 4914 5111 (iw_handler) ieee80211_ioctl_getchanlist, /* SIOCIWFIRSTPRIV+7 */ 4915 5112 (iw_handler) ieee80211_ioctl_chanswitch, /* SIOCIWFIRSTPRIV+8 */ 4916 (iw_handler) NULL,/* SIOCIWFIRSTPRIV+9 */4917 (iw_handler) NULL,/* SIOCIWFIRSTPRIV+10 */5113 (iw_handler) ieee80211_ioctl_getappiebuf, /* SIOCIWFIRSTPRIV+9 */ 5114 (iw_handler) ieee80211_ioctl_setappiebuf, /* SIOCIWFIRSTPRIV+10 */ 4918 5115 (iw_handler) ieee80211_ioctl_getscanresults, /* SIOCIWFIRSTPRIV+11 */ 4919 (iw_handler) NULL,/* SIOCIWFIRSTPRIV+12 */5116 (iw_handler) ieee80211_ioctl_setfilter, /* SIOCIWFIRSTPRIV+12 */ 4920 5117 (iw_handler) ieee80211_ioctl_getchaninfo, /* SIOCIWFIRSTPRIV+13 */ 4921 5118 (iw_handler) ieee80211_ioctl_setoptie, /* SIOCIWFIRSTPRIV+14 */ 4922 5119 (iw_handler) ieee80211_ioctl_getoptie, /* SIOCIWFIRSTPRIV+15 */
