Ticket #517: madwifi-appie.2.diff

File madwifi-appie.2.diff, 22.2 kB (added by ccpearson, 6 years ago)

Updated patch, replaces previous attachments (iemanagement.diff and ieee80211_ioctl.h)

  • madwifi/ath/if_ath.c

    old new  
    11881188        struct ath_hal *ah = sc->sc_ah; 
    11891189        struct ath_vap *avp = ATH_VAP(vap); 
    11901190        int decrease = 1; 
     1191        int i; 
    11911192        KASSERT(vap->iv_state == IEEE80211_S_INIT, ("vap not stopped")); 
    11921193 
    11931194        if (dev->flags & IFF_RUNNING) { 
     
    12611262        } 
    12621263#endif 
    12631264 
     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 
    12641273        if (dev->flags & IFF_RUNNING) { 
    12651274                /* 
    12661275                 * Restart rx+tx machines if device is still running. 
  • madwifi/net80211/ieee80211.h

    old new  
    353353}; 
    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 */ 
    358367#define IEEE80211_COUNTRY_MAX_TRIPLETS (83) 
  • madwifi/net80211/ieee80211_beacon.c

    old new  
    183183        if (vap->iv_xrvap && vap->iv_ath_cap & IEEE80211_ATHC_XR)       /* XR */ 
    184184                frm = ieee80211_add_xr_param(frm, vap); 
    185185#endif 
     186        bo->bo_appie_buf = frm; 
     187        bo->bo_appie_buf_len = 0; 
    186188         
    187189        bo->bo_tim_trailerlen = frm - bo->bo_tim_trailer; 
    188190        bo->bo_chanswitch_trailerlen = frm - bo->bo_chanswitch; 
     
    524526            IEEE80211_IS_CHAN_TURBO(ic->ic_curchan)) 
    525527                ieee80211_add_athAdvCap(bo->bo_ath_caps, vap->iv_bss->ni_ath_flags, 
    526528                        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 
    527554        IEEE80211_UNLOCK(ic); 
    528555 
    529556        return len_changed; 
  • madwifi/net80211/ieee80211_input.c

    old new  
    22092209#endif /* ATH_SUPERG_DYNTURBO */ 
    22102210} 
    22112211 
     2212static void 
     2213forward_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 
    22122266void 
    22132267ieee80211_saveath(struct ieee80211_node *ni, u_int8_t *ie) 
    22142268{ 
     
    23802434        wh = (struct ieee80211_frame *) skb->data; 
    23812435        frm = (u_int8_t *)&wh[1]; 
    23822436        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 
    23832442        switch (subtype) { 
    23842443        case IEEE80211_FC0_SUBTYPE_PROBE_RESP: 
    23852444        case IEEE80211_FC0_SUBTYPE_BEACON: { 
  • madwifi/net80211/ieee80211_ioctl.h

    old new  
    471471#define IEEE80211_IOC_DELMAC            55      /* del sta from MAC ACL table */ 
    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/* 
    476478 * Scan result data returned for IEEE80211_IOC_SCAN_RESULTS. 
     
    514516#define IEEE80211_IOCTL_SETCHANLIST     (SIOCIWFIRSTPRIV+6) 
    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) 
    519524#define IEEE80211_IOCTL_GETOPTIE        (SIOCIWFIRSTPRIV+15) 
     
    525530#define IEEE80211_IOCTL_WDSADDMAC       (SIOCIWFIRSTPRIV+26) 
    526531#define IEEE80211_IOCTL_WDSDELMAC       (SIOCIWFIRSTPRIV+28) 
    527532#define IEEE80211_IOCTL_KICKMAC         (SIOCIWFIRSTPRIV+30) 
     533 
    528534enum { 
    529535        IEEE80211_WMMPARAMS_CWMIN       = 1, 
    530536        IEEE80211_WMMPARAMS_CWMAX       = 2, 
     
    612618#define IEEE80211_NO_STABEACONS 0x0002          /* Do not setup the station beacon timers */ 
    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 
    617659#endif /* _NET80211_IEEE80211_IOCTL_H_ */ 
  • madwifi/net80211/ieee80211_output.c

    old new  
    17191719        skb = ieee80211_getmgtframe(&frm, 2 + IEEE80211_NWID_LEN +  
    17201720               2 + IEEE80211_RATE_SIZE +  
    17211721               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); 
    17231724        if (skb == NULL) { 
    17241725                vap->iv_stats.is_tx_nobuf++; 
    17251726                ieee80211_free_node(ni); 
     
    17351736                memcpy(frm, optie, optielen); 
    17361737                frm += optielen; 
    17371738        } 
     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 
    17381746        skb_trim(skb, frm - skb->data); 
    17391747 
    17401748        cb = (struct ieee80211_cb *)skb->cb; 
     
    18311839                        + (vap->iv_ath_cap & IEEE80211_ATHC_XR ?        /* XR */ 
    18321840                                sizeof(struct ieee80211_xr_param) : 0) 
    18331841#endif 
     1842                        + vap->app_ie[IEEE80211_APPIE_FRAME_PROBE_RESP].length 
    18341843                ); 
    18351844                if (skb == NULL) 
    18361845                        senderr(ENOMEM, is_tx_nobuf); 
     
    19261935                if (vap->iv_xrvap && vap->iv_ath_cap & IEEE80211_ATHC_XR) 
    19271936                        frm = ieee80211_add_xr_param(frm, vap); 
    19281937#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 
    19291944                skb_trim(skb, frm - skb->data); 
    19301945                break; 
    19311946 
     
    20262041                        2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) + 
    20272042                        sizeof(struct ieee80211_ie_wme) + 
    20282043                        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); 
    20302046                if (skb == NULL) 
    20312047                        senderr(ENOMEM, is_tx_nobuf); 
    20322048 
     
    20972113                        memcpy(frm, vap->iv_opt_ie, vap->iv_opt_ie_len); 
    20982114                        frm += vap->iv_opt_ie_len; 
    20992115                } 
     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 
    21002123                skb_trim(skb, frm - skb->data); 
    21012124 
    21022125                timer = IEEE80211_TRANS_WAIT; 
     
    21192142                        2 + IEEE80211_RATE_SIZE + 
    21202143                        2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) + 
    21212144                        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); 
    21232147                if (skb == NULL) 
    21242148                        senderr(ENOMEM, is_tx_nobuf); 
    21252149 
     
    21642188                                vap->iv_ath_cap & ni->ni_ath_flags, 
    21652189                                ni->ni_ath_defkeyindex);  
    21662190 
     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 
    21672197                skb_trim(skb, frm - skb->data); 
    21682198                break; 
    21692199 
  • madwifi/net80211/ieee80211_proto.h

    old new  
    265265        u_int8_t *bo_ath_caps;          /* where ath caps is */ 
    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}; 
    270272struct sk_buff *ieee80211_beacon_alloc(struct ieee80211_node *, 
  • madwifi/net80211/ieee80211_var.h

    old new  
    8888#define IEEE80211_TU_TO_MS(x)   (((x) * 1024) / 1000) 
    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) ? \ 
    9395            (ic)->ic_bsschan->ic_maxregpower - (ic)->ic_curchanmaxpwr : 0) 
     
    290292}; 
    291293#endif 
    292294 
     295struct ieee80211_app_ie_t { 
     296        u_int32_t               length;         /* buffer length */ 
     297        struct ieee80211_ie    *ie;             /* buffer containing one or more IEs */ 
     298}; 
     299 
    293300struct ieee80211vap { 
    294301        struct net_device *iv_dev;              /* associated device */ 
    295302        struct net_device_stats iv_devstats;    /* interface statistics */ 
     
    393400        unsigned int iv_nsdone;                 /* Done with scheduled newstate tasklet */ 
    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); 
    398408 
     
    452462#define IEEE80211_FEXT_ERPUPDATE 0x00000200     /* STATUS: update ERP element */ 
    453463#define IEEE80211_FEXT_SWBMISS 0x00000400       /* CONF: use software beacon timer */ 
    454464#define IEEE80211_FEXT_DROPUNENC_EAPOL 0x00000800      /* CONF: drop unencrypted eapol frames */ 
     465#define IEEE80211_FEXT_APPIE_UPDATE 0x00001000  /* STATE: beacon APP IE updated */ 
    455466 
    456467#define IEEE80211_COM_UAPSD_ENABLE(_ic)         ((_ic)->ic_flags_ext |= IEEE80211_FEXT_UAPSD) 
    457468#define IEEE80211_COM_UAPSD_DISABLE(_ic)        ((_ic)->ic_flags_ext &= ~IEEE80211_FEXT_UAPSD) 
  • madwifi/net80211/ieee80211_wireless.c

    old new  
    17321732          return E2BIG; 
    17331733 
    17341734        if (se->se_rsn_ie != NULL) { 
    1735           last_ev = current_ev; 
    17361735#ifdef IWEVGENIE 
    17371736                memset(&iwe, 0, sizeof(iwe)); 
    17381737                memcpy(buf, se->se_rsn_ie, se->se_rsn_ie[1] + 2); 
     
    17471746                                se->se_rsn_ie, se->se_rsn_ie[1] + 2, 
    17481747                                rsn_leader, sizeof(rsn_leader) - 1); 
    17491748#endif 
     1749                last_ev = current_ev; 
    17501750                if (iwe.u.data.length != 0) { 
    17511751                        current_ev = iwe_stream_add_point(current_ev, end_buf, 
    17521752                                &iwe, buf); 
     
    17581758        } 
    17591759 
    17601760        if (se->se_wpa_ie != NULL) { 
    1761           last_ev = current_ev; 
    17621761#ifdef IWEVGENIE 
    17631762                memset(&iwe, 0, sizeof(iwe)); 
    17641763                memcpy(buf, se->se_wpa_ie, se->se_wpa_ie[1] + 2); 
     
    17721771                        se->se_wpa_ie, se->se_wpa_ie[1] + 2, 
    17731772                        wpa_leader, sizeof(wpa_leader) - 1); 
    17741773#endif 
     1774                last_ev = current_ev; 
    17751775                if (iwe.u.data.length != 0) { 
    17761776                        current_ev = iwe_stream_add_point(current_ev, end_buf, 
    17771777                                &iwe, buf); 
     
    28452845        return 0; 
    28462846} 
    28472847 
     2848/* returns non-zero if ID is for a system IE (not for app use) */ 
     2849static int 
     2850is_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 */ 
     2886static int 
     2887is_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 
    28482904static int 
    28492905ieee80211_ioctl_setoptie(struct net_device *dev, struct iw_request_info *info, 
    28502906        struct iw_point *wri, char *extra) 
     
    28602916         */ 
    28612917        if (vap->iv_opmode != IEEE80211_M_STA) 
    28622918                return -EINVAL; 
     2919        if (! is_valid_ie_list(wri->length, extra, 0)) 
     2920                return -EINVAL; 
    28632921        /* NB: wri->length is validated by the wireless extensions code */ 
    28642922        MALLOC(ie, void *, wri->length, M_DEVBUF, M_WAITOK); 
    28652923        if (ie == NULL) 
    28662924                return -ENOMEM; 
    28672925        memcpy(ie, extra, wri->length); 
    2868         /* XXX sanity check data? */ 
    28692926        if (vap->iv_opt_ie != NULL) 
    28702927                FREE(vap->iv_opt_ie, M_DEVBUF); 
    28712928        vap->iv_opt_ie = ie; 
     
    28932950        return 0; 
    28942951} 
    28952952 
     2953/* the following functions are used by the set/get appiebuf functions */ 
     2954static int 
     2955add_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 
     2976static int 
     2977remove_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 
     2988static int 
     2989get_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 
     3001static int 
     3002ieee80211_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 
     3041static int 
     3042ieee80211_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 
     3068static int 
     3069ieee80211_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 
    28963083static int 
    28973084ieee80211_ioctl_setkey(struct net_device *dev, struct iw_request_info *info, 
    28983085        void *w, char *extra) 
     
    46124799        IW_PRIV_TYPE_BYTE | sizeof(struct ieee80211req_chanlist) 
    46134800#define IW_PRIV_TYPE_CHANINFO \ 
    46144801        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) 
    46154806 
    46164807static const struct iw_priv_args ieee80211_priv_args[] = { 
    46174808        /* NB: setoptie & getoptie are !IW_PRIV_SIZE_FIXED */ 
     
    49385129          IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "markdfs" }, 
    49395130        { IEEE80211_PARAM_MARKDFS, 
    49405131          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" }, 
    49415138 
    49425139#endif /* WIRELESS_EXT >= 12 */ 
    49435140}; 
     
    50245221        (iw_handler) ieee80211_ioctl_setchanlist,       /* SIOCIWFIRSTPRIV+6 */ 
    50255222        (iw_handler) ieee80211_ioctl_getchanlist,       /* SIOCIWFIRSTPRIV+7 */ 
    50265223        (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 */ 
    50295226        (iw_handler) ieee80211_ioctl_getscanresults,    /* SIOCIWFIRSTPRIV+11 */ 
    5030         (iw_handler) NULL,                            /* SIOCIWFIRSTPRIV+12 */ 
     5227        (iw_handler) ieee80211_ioctl_setfilter,               /* SIOCIWFIRSTPRIV+12 */ 
    50315228        (iw_handler) ieee80211_ioctl_getchaninfo,       /* SIOCIWFIRSTPRIV+13 */ 
    50325229        (iw_handler) ieee80211_ioctl_setoptie,          /* SIOCIWFIRSTPRIV+14 */ 
    50335230        (iw_handler) ieee80211_ioctl_getoptie,          /* SIOCIWFIRSTPRIV+15 */