Changeset 1756

Show
Ignore:
Timestamp:
10/18/06 13:41:05 (2 years ago)
Author:
kelmo
Message:

New IOCTL interface to allow application to pass IE to be sent in Management
frames.

Signed-off-by: pramod Babu Gummaraj <pramod@atheros.com>
Signed-off-by: Chris Pearson <Christopher.C.Pearson@intel.com>

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/ath/if_ath.c

    r1755 r1756  
    12131213        struct ath_vap *avp = ATH_VAP(vap); 
    12141214        int decrease = 1; 
     1215        int i; 
    12151216        KASSERT(vap->iv_state == IEEE80211_S_INIT, ("vap not stopped")); 
    12161217 
     
    12851286        } 
    12861287#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        } 
    12871296 
    12881297        if (dev->flags & IFF_RUNNING) { 
  • trunk/net80211/ieee80211.h

    r1712 r1756  
    354354 
    355355/*  
     356 * Generic information element 
     357 */ 
     358struct ieee80211_ie { 
     359        u_int8_t id; 
     360        u_int8_t len; 
     361        u_int8_t info[]; 
     362} __packed; 
     363 
     364/*  
    356365 * Country information element. 
    357366 */ 
  • trunk/net80211/ieee80211_beacon.c

    r1721 r1756  
    186186                frm = ieee80211_add_xr_param(frm, vap); 
    187187#endif 
     188        bo->bo_appie_buf = frm; 
     189        bo->bo_appie_buf_len = 0; 
    188190         
    189191        bo->bo_tim_trailerlen = frm - bo->bo_tim_trailer; 
     
    527529                ieee80211_add_athAdvCap(bo->bo_ath_caps, vap->iv_bss->ni_ath_flags, 
    528530                        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 
    529556        IEEE80211_UNLOCK(ic); 
    530557 
  • trunk/net80211/ieee80211_input.c

    r1721 r1756  
    22092209} 
    22102210 
     2211static void 
     2212forward_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 
    22112265void 
    22122266ieee80211_saveath(struct ieee80211_node *ni, u_int8_t *ie) 
     
    23802434        frm = (u_int8_t *)&wh[1]; 
    23812435        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 
    23822441        switch (subtype) { 
    23832442        case IEEE80211_FC0_SUBTYPE_PROBE_RESP: 
  • trunk/net80211/ieee80211_ioctl.h

    r1676 r1756  
    472472#define IEEE80211_IOC_FF                56      /* ATH fast frames (on, off) */ 
    473473#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 */ 
    474476 
    475477/* 
     
    515517#define IEEE80211_IOCTL_GETCHANLIST     (SIOCIWFIRSTPRIV+7) 
    516518#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) 
    517522#define IEEE80211_IOCTL_GETCHANINFO     (SIOCIWFIRSTPRIV+13) 
    518523#define IEEE80211_IOCTL_SETOPTIE        (SIOCIWFIRSTPRIV+14) 
     
    526531#define IEEE80211_IOCTL_WDSDELMAC       (SIOCIWFIRSTPRIV+28) 
    527532#define IEEE80211_IOCTL_KICKMAC         (SIOCIWFIRSTPRIV+30) 
     533 
    528534enum { 
    529535        IEEE80211_WMMPARAMS_CWMIN       = 1, 
     
    613619}; 
    614620 
     621/* APPIEBUF related definitions */ 
     622 
     623/* Management frame type to which application IE is added */ 
     624enum { 
     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 
     633struct 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 */ 
     640enum { 
     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 
     652struct ieee80211req_set_filter { 
     653        u_int32_t app_filterype;                /* management frame filter type */ 
     654}; 
     655 
     656 
    615657#endif /* __linux__ */ 
    616658 
  • trunk/net80211/ieee80211_output.c

    r1721 r1756  
    17221722               2 + IEEE80211_RATE_SIZE +  
    17231723               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); 
    17251726        if (skb == NULL) { 
    17261727                vap->iv_stats.is_tx_nobuf++; 
     
    17381739                frm += optielen; 
    17391740        } 
     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 
    17401748        skb_trim(skb, frm - skb->data); 
    17411749 
     
    18341842                                sizeof(struct ieee80211_xr_param) : 0) 
    18351843#endif 
     1844                        + vap->app_ie[IEEE80211_APPIE_FRAME_PROBE_RESP].length 
    18361845                ); 
    18371846                if (skb == NULL) 
     
    19291938                        frm = ieee80211_add_xr_param(frm, vap); 
    19301939#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 
    19311946                skb_trim(skb, frm - skb->data); 
    19321947                break; 
     
    20292044                        sizeof(struct ieee80211_ie_wme) + 
    20302045                        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); 
    20322048                if (skb == NULL) 
    20332049                        senderr(ENOMEM, is_tx_nobuf); 
     
    21002116                        frm += vap->iv_opt_ie_len; 
    21012117                } 
     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 
    21022125                skb_trim(skb, frm - skb->data); 
    21032126 
     
    21222145                        2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) + 
    21232146                        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); 
    21252149                if (skb == NULL) 
    21262150                        senderr(ENOMEM, is_tx_nobuf); 
     
    21662190                                vap->iv_ath_cap & ni->ni_ath_flags, 
    21672191                                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                } 
    21682198 
    21692199                skb_trim(skb, frm - skb->data); 
  • trunk/net80211/ieee80211_proto.h

    r1637 r1756  
    266266        u_int8_t *bo_xr;                        /* start of xr element */ 
    267267        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 */ 
    268270        u_int16_t bo_chanswitch_trailerlen; 
    269271}; 
  • trunk/net80211/ieee80211_var.h

    r1732 r1756  
    8989#define IEEE80211_TU_TO_JIFFIES(x) ((IEEE80211_TU_TO_MS(x) * HZ) / 1000) 
    9090 
     91#define IEEE80211_APPIE_MAX     1024 
     92 
    9193#define IEEE80211_PWRCONSTRAINT_VAL(ic) \ 
    9294        (((ic)->ic_bsschan->ic_maxregpower > (ic)->ic_curchanmaxpwr) ? \ 
     
    290292}; 
    291293#endif 
     294 
     295struct ieee80211_app_ie_t { 
     296        u_int32_t               length;         /* buffer length */ 
     297        struct ieee80211_ie    *ie;             /* buffer containing one or more IEs */ 
     298}; 
    292299 
    293300struct ieee80211vap { 
     
    394401        uint8_t wds_mac[IEEE80211_ADDR_LEN]; 
    395402        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 
    396406}; 
    397407MALLOC_DECLARE(M_80211_VAP); 
     
    454464#define IEEE80211_FEXT_SWBMISS 0x00000400       /* CONF: use software beacon timer */ 
    455465#define IEEE80211_FEXT_DROPUNENC_EAPOL 0x00000800      /* CONF: drop unencrypted eapol frames */ 
     466#define IEEE80211_FEXT_APPIE_UPDATE 0x00001000  /* STATE: beacon APP IE updated */ 
    456467 
    457468#define IEEE80211_COM_UAPSD_ENABLE(_ic)         ((_ic)->ic_flags_ext |= IEEE80211_FEXT_UAPSD) 
  • trunk/net80211/ieee80211_wireless.c

    r1751 r1756  
    28442844} 
    28452845 
     2846/* returns non-zero if ID is for a system IE (not for app use) */ 
     2847static int 
     2848is_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 */ 
     2884static int 
     2885is_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 
    28462902static int 
    28472903ieee80211_ioctl_setoptie(struct net_device *dev, struct iw_request_info *info, 
     
    28592915        if (vap->iv_opmode != IEEE80211_M_STA) 
    28602916                return -EINVAL; 
     2917        if (! is_valid_ie_list(wri->length, extra, 0)) 
     2918                return -EINVAL; 
    28612919        /* NB: wri->length is validated by the wireless extensions code */ 
    28622920        MALLOC(ie, void *, wri->length, M_DEVBUF, M_WAITOK); 
     
    28642922                return -ENOMEM; 
    28652923        memcpy(ie, extra, wri->length); 
    2866         /* XXX sanity check data? */ 
    28672924        if (vap->iv_opt_ie != NULL) 
    28682925                FREE(vap->iv_opt_ie, M_DEVBUF); 
     
    28892946        wri->length = vap->iv_opt_ie_len; 
    28902947        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 */ 
     2952static int 
     2953add_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 
     2974static int 
     2975remove_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 
     2986static int 
     2987get_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 
     2999static int 
     3000ieee80211_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 
     3039static int 
     3040ieee80211_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 
     3066static int 
     3067ieee80211_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 
    28913078        return 0; 
    28923079} 
     
    46114798#define IW_PRIV_TYPE_CHANINFO \ 
    46124799        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) 
    46134804 
    46144805static const struct iw_priv_args ieee80211_priv_args[] = { 
     
    49375128        { IEEE80211_PARAM_MARKDFS, 
    49385129          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" }, 
    49395136 
    49405137#endif /* WIRELESS_EXT >= 12 */ 
     
    50235220        (iw_handler) ieee80211_ioctl_getchanlist,       /* SIOCIWFIRSTPRIV+7 */ 
    50245221        (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 */ 
    50275224        (iw_handler) ieee80211_ioctl_getscanresults,    /* SIOCIWFIRSTPRIV+11 */ 
    5028         (iw_handler) NULL,                            /* SIOCIWFIRSTPRIV+12 */ 
     5225        (iw_handler) ieee80211_ioctl_setfilter,               /* SIOCIWFIRSTPRIV+12 */ 
    50295226        (iw_handler) ieee80211_ioctl_getchaninfo,       /* SIOCIWFIRSTPRIV+13 */ 
    50305227        (iw_handler) ieee80211_ioctl_setoptie,          /* SIOCIWFIRSTPRIV+14 */