Ticket #517: madwifi-0.9.2-appie.diff

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

Alternate version of patch for MadWifi 0.9.2 distro

  • madwifi-0.9.2/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-0.9.2/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-0.9.2/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-0.9.2/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-0.9.2/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-0.9.2/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-0.9.2/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-0.9.2/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) 
     
    289291}; 
    290292#endif 
    291293 
     294struct ieee80211_app_ie_t { 
     295        u_int32_t               length;         /* buffer length */ 
     296        struct ieee80211_ie    *ie;             /* buffer containing one or more IEs */ 
     297}; 
     298 
    292299struct ieee80211vap { 
    293300        struct net_device *iv_dev;              /* associated device */ 
    294301        struct net_device_stats iv_devstats;    /* interface statistics */ 
     
    392399        unsigned int iv_nsdone;                 /* Done with scheduled newstate tasklet */ 
    393400        uint8_t wds_mac[IEEE80211_ADDR_LEN]; 
    394401        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 
    395405}; 
    396406MALLOC_DECLARE(M_80211_VAP); 
    397407 
     
    451461#define IEEE80211_FEXT_ERPUPDATE 0x00000200     /* STATUS: update ERP element */ 
    452462#define IEEE80211_FEXT_SWBMISS 0x00000400       /* CONF: use software beacon timer */ 
    453463#define IEEE80211_FEXT_DROPUNENC_EAPOL 0x00000800      /* CONF: drop unencrypted eapol frames */ 
     464#define IEEE80211_FEXT_APPIE_UPDATE 0x00001000  /* STATE: beacon APP IE updated */ 
    454465 
    455466#define IEEE80211_COM_UAPSD_ENABLE(_ic)         ((_ic)->ic_flags_ext |= IEEE80211_FEXT_UAPSD) 
    456467#define IEEE80211_COM_UAPSD_DISABLE(_ic)        ((_ic)->ic_flags_ext &= ~IEEE80211_FEXT_UAPSD) 
  • madwifi-0.9.2/net80211/ieee80211_wireless.c

    old new  
    27472747        return 0; 
    27482748} 
    27492749 
     2750/* returns non-zero if ID is for a system IE (not for app use) */ 
     2751static int 
     2752is_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 */ 
     2788static int 
     2789is_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 
    27502806static int 
    27512807ieee80211_ioctl_setoptie(struct net_device *dev, struct iw_request_info *info, 
    27522808        struct iw_point *wri, char *extra) 
     
    27622818         */ 
    27632819        if (vap->iv_opmode != IEEE80211_M_STA) 
    27642820                return -EINVAL; 
     2821        if (! is_valid_ie_list(wri->length, extra, 0)) 
     2822                return -EINVAL; 
    27652823        /* NB: wri->length is validated by the wireless extensions code */ 
    27662824        MALLOC(ie, void *, wri->length, M_DEVBUF, M_WAITOK); 
    27672825        if (ie == NULL) 
    27682826                return -ENOMEM; 
    27692827        memcpy(ie, extra, wri->length); 
    2770         /* XXX sanity check data? */ 
    27712828        if (vap->iv_opt_ie != NULL) 
    27722829                FREE(vap->iv_opt_ie, M_DEVBUF); 
    27732830        vap->iv_opt_ie = ie; 
     
    27952852        return 0; 
    27962853} 
    27972854 
     2855/* the following functions are used by the set/get appiebuf functions */ 
     2856static int 
     2857add_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 
     2878static int 
     2879remove_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 
     2890static int 
     2891get_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 
     2903static int 
     2904ieee80211_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 
     2943static int 
     2944ieee80211_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 
     2970static int 
     2971ieee80211_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 
    27982985static int 
    27992986ieee80211_ioctl_setkey(struct net_device *dev, struct iw_request_info *info, 
    28002987        void *w, char *extra) 
     
    45064693        IW_PRIV_TYPE_BYTE | sizeof(struct ieee80211req_chanlist) 
    45074694#define IW_PRIV_TYPE_CHANINFO \ 
    45084695        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) 
    45094700 
    45104701static const struct iw_priv_args ieee80211_priv_args[] = { 
    45114702        /* NB: setoptie & getoptie are !IW_PRIV_SIZE_FIXED */ 
     
    48325023          IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "markdfs" }, 
    48335024        { IEEE80211_PARAM_MARKDFS, 
    48345025          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" }, 
    48355032 
    48365033#endif /* WIRELESS_EXT >= 12 */ 
    48375034}; 
     
    49135110        (iw_handler) ieee80211_ioctl_setchanlist,       /* SIOCIWFIRSTPRIV+6 */ 
    49145111        (iw_handler) ieee80211_ioctl_getchanlist,       /* SIOCIWFIRSTPRIV+7 */ 
    49155112        (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 */ 
    49185115        (iw_handler) ieee80211_ioctl_getscanresults,    /* SIOCIWFIRSTPRIV+11 */ 
    4919         (iw_handler) NULL,                            /* SIOCIWFIRSTPRIV+12 */ 
     5116        (iw_handler) ieee80211_ioctl_setfilter,               /* SIOCIWFIRSTPRIV+12 */ 
    49205117        (iw_handler) ieee80211_ioctl_getchaninfo,       /* SIOCIWFIRSTPRIV+13 */ 
    49215118        (iw_handler) ieee80211_ioctl_setoptie,          /* SIOCIWFIRSTPRIV+14 */ 
    49225119        (iw_handler) ieee80211_ioctl_getoptie,          /* SIOCIWFIRSTPRIV+15 */