首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >基于ioctl SIOCGIWSCAN的wifi扫描

基于ioctl SIOCGIWSCAN的wifi扫描
EN

Stack Overflow用户
提问于 2018-12-05 13:12:46
回答 2查看 1.7K关注 0票数 2

我想知道是否有人能告诉我如何解释wifi扫描产生的数据

代码语言:javascript
运行
复制
if (-1 != (status = ioctl(handle, SIOCGIWSCAN, &data)))
{
    data.u.data.pointer = ? what struct is this ?
}

它看起来像是一大团数据,但背后一定有某种结构。

谢谢你

EN

回答 2

Stack Overflow用户

发布于 2019-05-01 14:37:20

答案2的第2部分。为传送/ C++兼容性而修改的

linuxwifistream.h

代码语言:javascript
运行
复制
#ifndef LINUX_WIFI_STREAM_H
#define LINUX_WIFI_STREAM_H

#include <linux/wireless.h>

#define IW_DESCR_FLAG_NONE        0x0000
#define IW_DESCR_FLAG_DUMP        0x0001
#define IW_DESCR_FLAG_EVENT       0x0002
#define IW_DESCR_FLAG_RESTRICT    0x0004
#define IW_DESCR_FLAG_NOMAX       0x0008
#define IW_DESCR_FLAG_WAIT        0x0100

struct iw_event_stream {
    char *end;
    char *current;
    char *value;
};

int iw_extract_event_stream(
    struct iw_event_stream *stream, struct iw_event *iwe, int we_version );

#endif // LINUX_WIFI_STREAM_H

linuxwifistream.cpp

代码语言:javascript
运行
复制
#include "linuxwifistream.h"

#define IW_HEADER_TYPE_NULL    0    
#define IW_HEADER_TYPE_CHAR    2    
#define IW_HEADER_TYPE_UINT    4    
#define IW_HEADER_TYPE_FREQ    5    
#define IW_HEADER_TYPE_ADDR    6    
#define IW_HEADER_TYPE_POINT    8   
#define IW_HEADER_TYPE_PARAM    9   
#define IW_HEADER_TYPE_QUAL    10   

struct iw_ioctl_description
{
    __u8    header_type;        
    __u8    token_type;        
    __u16    token_size;       
    __u16    min_tokens;       
    __u16    max_tokens;       
    __u32    flags;            
};

// Fill Missing Defines
#ifndef SIOCSIWMODUL
#define SIOCSIWMODUL    0x8B2E        /* set Modulations settings */
#endif
#ifndef SIOCGIWMODUL
#define SIOCGIWMODUL    0x8B2F        /* get Modulations settings */
#endif

const struct iw_ioctl_description standard_ioctl_descr[] = {
    [SIOCSIWCOMMIT    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_NULL,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = 0,
    },
    [SIOCGIWNAME    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_CHAR,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = IW_DESCR_FLAG_DUMP,
    },
    [SIOCSIWNWID    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = IW_DESCR_FLAG_EVENT,
    },
    [SIOCGIWNWID    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = IW_DESCR_FLAG_DUMP,
    },
    [SIOCSIWFREQ    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_FREQ,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = IW_DESCR_FLAG_EVENT,
    },
    [SIOCGIWFREQ    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_FREQ,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = IW_DESCR_FLAG_DUMP,
    },
    [SIOCSIWMODE    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_UINT,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = IW_DESCR_FLAG_EVENT,
    },
    [SIOCGIWMODE    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_UINT,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = IW_DESCR_FLAG_DUMP,
    },
    [SIOCSIWSENS    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = 0,
    },
    [SIOCGIWSENS    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = 0,
    },
    [SIOCSIWRANGE    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_NULL,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = 0,
    },
    [SIOCGIWRANGE    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_type     = 0,
        .token_size     = 1,
        .min_tokens     = 0,
        .max_tokens     = sizeof(struct iw_range),
        .flags          = IW_DESCR_FLAG_DUMP,
    },
    [SIOCSIWPRIV    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_NULL,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = 0,
    },
    [SIOCGIWPRIV    - SIOCIWFIRST] = { // (handled directly by us)
        .header_type    = IW_HEADER_TYPE_NULL,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = 0,
    },
    [SIOCSIWSTATS    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_NULL,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = 0,
    },
    [SIOCGIWSTATS    - SIOCIWFIRST] = { // (handled directly by us)
        .header_type    = IW_HEADER_TYPE_NULL,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = IW_DESCR_FLAG_DUMP,
    },
    [SIOCSIWSPY    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_type     = 0,
        .token_size     = sizeof(struct sockaddr),
        .min_tokens     = 0,
        .max_tokens     = IW_MAX_SPY,
        .flags          = 0,
    },
    [SIOCGIWSPY    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_type     = 0,
        .token_size     = sizeof(struct sockaddr) +
                          sizeof(struct iw_quality),
        .min_tokens     = 0,
        .max_tokens     = IW_MAX_SPY,
        .flags          = 0,
    },
    [SIOCSIWTHRSPY    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_type     = 0,
        .token_size     = sizeof(struct iw_thrspy),
        .min_tokens     = 1,
        .max_tokens     = 1,
        .flags          = 0,
    },
    [SIOCGIWTHRSPY    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_type     = 0,
        .token_size     = sizeof(struct iw_thrspy),
        .min_tokens     = 1,
        .max_tokens     = 1,
        .flags          = 0,
    },
    [SIOCSIWAP    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_ADDR,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = 0,
    },
    [SIOCGIWAP    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_ADDR,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = IW_DESCR_FLAG_DUMP,
    },
    [SIOCSIWMLME    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_type     = 0,
        .token_size     = 1,
        .min_tokens     = sizeof(struct iw_mlme),
        .max_tokens     = sizeof(struct iw_mlme),
        .flags          = 0,
    },
    [SIOCGIWAPLIST    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_type     = 0,
        .token_size     = sizeof(struct sockaddr) +
                          sizeof(struct iw_quality),
        .min_tokens     = 0,
        .max_tokens     = IW_MAX_AP,
        .flags          = IW_DESCR_FLAG_NOMAX,
    },
    [SIOCSIWSCAN    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_type     = 0,
        .token_size     = 1,
        .min_tokens     = 0,
        .max_tokens     = sizeof(struct iw_scan_req),
        .flags          = 0,
    },
    [SIOCGIWSCAN    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_type     = 0,
        .token_size     = 1,
        .min_tokens     = 0,
        .max_tokens     = IW_SCAN_MAX_DATA,
        .flags          = IW_DESCR_FLAG_NOMAX,
    },
    [SIOCSIWESSID    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_type     = 0,
        .token_size     = 1,
        .min_tokens     = 0,
        .max_tokens     = IW_ESSID_MAX_SIZE + 1,
        .flags          = IW_DESCR_FLAG_EVENT,
    },
    [SIOCGIWESSID    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_type     = 0,
        .token_size     = 1,
        .min_tokens     = 0,
        .max_tokens     = IW_ESSID_MAX_SIZE + 1,
        .flags          = IW_DESCR_FLAG_DUMP,
    },
    [SIOCSIWNICKN    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_type     = 0,
        .token_size     = 1,
        .min_tokens     = 0,
        .max_tokens     = IW_ESSID_MAX_SIZE + 1,
        .flags          = 0,
    },
    [SIOCGIWNICKN    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_type     = 0,
        .token_size     = 1,
        .min_tokens     = 0,
        .max_tokens     = IW_ESSID_MAX_SIZE + 1,
        .flags          = 0,
    },
// PATCH: MAKE ERROR THROWN WITHOUT THESE ARRAY ELEMENTS!!!
    [0x8B1E    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = 0,
    },
    [0x8B1F    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = 0,
    },
//
    [SIOCSIWRATE    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = 0,
    },
    [SIOCGIWRATE    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = 0,
    },
    [SIOCSIWRTS    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = 0,
    },
    [SIOCGIWRTS    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = 0,
    },
    [SIOCSIWFRAG    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = 0,
    },
    [SIOCGIWFRAG    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = 0,
    },
    [SIOCSIWTXPOW    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = 0,
    },
    [SIOCGIWTXPOW    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = 0,
    },
    [SIOCSIWRETRY    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = 0,
    },
    [SIOCGIWRETRY    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = 0,
    },
    [SIOCSIWENCODE    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_type     = 0,
        .token_size     = 1,
        .min_tokens     = 0,
        .max_tokens     = IW_ENCODING_TOKEN_MAX,
        .flags          = IW_DESCR_FLAG_EVENT | IW_DESCR_FLAG_RESTRICT,
    },
    [SIOCGIWENCODE    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_type     = 0,
        .token_size     = 1,
        .min_tokens     = 0,
        .max_tokens     = IW_ENCODING_TOKEN_MAX,
        .flags          = IW_DESCR_FLAG_DUMP | IW_DESCR_FLAG_RESTRICT,
    },
    [SIOCSIWPOWER    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = 0,
    },
    [SIOCGIWPOWER    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = 0,
    },
    [SIOCSIWMODUL    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = 0,
    },
    [SIOCGIWMODUL    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = 0,
    },
    [SIOCSIWGENIE    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_type     = 0,
        .token_size     = 1,
        .min_tokens     = 0,
        .max_tokens     = IW_GENERIC_IE_MAX,
        .flags          = 0,
    },
    [SIOCGIWGENIE    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_type     = 0,
        .token_size     = 1,
        .min_tokens     = 0,
        .max_tokens     = IW_GENERIC_IE_MAX,
        .flags          = 0,
    },
    [SIOCSIWAUTH    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = 0,
    },
    [SIOCGIWAUTH    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = 0,
    },
    [SIOCSIWENCODEEXT - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_type     = 0,
        .token_size     = 1,
        .min_tokens     = sizeof(struct iw_encode_ext),
        .max_tokens     = sizeof(struct iw_encode_ext) +
                          IW_ENCODING_TOKEN_MAX,
        .flags          = 0,
    },
    [SIOCGIWENCODEEXT - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_type     = 0,
        .token_size     = 1,
        .min_tokens     = sizeof(struct iw_encode_ext),
        .max_tokens     = sizeof(struct iw_encode_ext) +
                          IW_ENCODING_TOKEN_MAX,
        .flags          = 0,
    },
    [SIOCSIWPMKSA - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_type     = 0,
        .token_size     = 1,
        .min_tokens     = sizeof(struct iw_pmksa),
        .max_tokens     = sizeof(struct iw_pmksa),
        .flags          = 0,
    },
};

const unsigned int standard_ioctl_num = (sizeof(standard_ioctl_descr) /
                        sizeof(struct iw_ioctl_description));

//
// Meta-data about all the additional standard Wireless Extension events
// we know about.
//
//
const struct iw_ioctl_description standard_event_descr[] = {
    [IWEVTXDROP    - IWEVFIRST] = {
        .header_type    = IW_HEADER_TYPE_ADDR,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = 0,
    },
    [IWEVQUAL    - IWEVFIRST] = {
        .header_type    = IW_HEADER_TYPE_QUAL,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = 0,
    },
    [IWEVCUSTOM    - IWEVFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_type     = 0,
        .token_size     = 1,
        .min_tokens     = 0,
        .max_tokens     = IW_CUSTOM_MAX,
        .flags          = 0,
    },
    [IWEVREGISTERED    - IWEVFIRST] = {
        .header_type    = IW_HEADER_TYPE_ADDR,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = 0,
    },
    [IWEVEXPIRED    - IWEVFIRST] = {
        .header_type    = IW_HEADER_TYPE_ADDR,
        .token_type     = 0,
        .token_size     = 0,
        .min_tokens     = 0,
        .max_tokens     = 0,
        .flags          = 0,
    },
    [IWEVGENIE    - IWEVFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_type     = 0,
        .token_size     = 1,
        .min_tokens     = 0,
        .max_tokens     = IW_GENERIC_IE_MAX,
        .flags          = 0,
    },
    [IWEVMICHAELMICFAILURE    - IWEVFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_type     = 0,
        .token_size     = 1,
        .min_tokens     = 0,
        .max_tokens     = sizeof(struct iw_michaelmicfailure),
        .flags          = 0,
    },
    [IWEVASSOCREQIE    - IWEVFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_type     = 0,
        .token_size     = 1,
        .min_tokens     = 0,
        .max_tokens     = IW_GENERIC_IE_MAX,
        .flags          = 0,
    },
    [IWEVASSOCRESPIE    - IWEVFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_type     = 0,
        .token_size     = 1,
        .min_tokens     = 0,
        .max_tokens     = IW_GENERIC_IE_MAX,
        .flags          = 0,
    },
    [IWEVPMKIDCAND    - IWEVFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_type     = 0,
        .token_size     = 1,
        .min_tokens     = 0,
        .max_tokens     = sizeof(struct iw_pmkid_cand),
        .flags          = 0,
    },
};

const unsigned int standard_event_num = (sizeof(standard_event_descr) /
    sizeof(struct iw_ioctl_description));

// Size (in bytes) of various events
const int event_type_size[] = {
    IW_EV_LCP_PK_LEN,    // IW_HEADER_TYPE_NULL
    0,
    IW_EV_CHAR_PK_LEN,    // IW_HEADER_TYPE_CHAR
    0,
    IW_EV_UINT_PK_LEN,    // IW_HEADER_TYPE_UINT
    IW_EV_FREQ_PK_LEN,    // IW_HEADER_TYPE_FREQ
    IW_EV_ADDR_PK_LEN,    // IW_HEADER_TYPE_ADDR
    0,
    IW_EV_POINT_PK_LEN,    // Without variable payload
    IW_EV_PARAM_PK_LEN,    // IW_HEADER_TYPE_PARAM
    IW_EV_QUAL_PK_LEN,    // IW_HEADER_TYPE_QUAL *
};

int iw_extract_event_stream( iw_event_stream *stream,    /* Stream of events */
            struct iw_event *    iwe,    /* Extracted event */
            int            we_version)
{
  const struct iw_ioctl_description *    descr = NULL;
  int        event_type = 0;
  unsigned int    event_len = 1;        /* Invalid */
  char *    pointer;
  /* Don't "optimise" the following variable, it will crash */
  unsigned    cmd_index;        /* *MUST* be unsigned */

  /* Check for end of stream */
  if((stream->current + IW_EV_LCP_PK_LEN) > stream->end)
    return(0);

#ifdef DEBUG
  printf("DBG - stream->current = %p, stream->value = %p, stream->end = %p\n",
     stream->current, stream->value, stream->end);
#endif

  /* Extract the event header (to get the event id).
   * Note : the event may be unaligned, therefore copy... */
  memcpy((char *) iwe, stream->current, IW_EV_LCP_PK_LEN);

#ifdef DEBUG
  printf("DBG - iwe->cmd = 0x%X, iwe->len = %d\n",
     iwe->cmd, iwe->len);
#endif

  /* Check invalid events */
  if(iwe->len <= IW_EV_LCP_PK_LEN)
    return(-1);

  /* Get the type and length of that event */
  if(iwe->cmd <= SIOCIWLAST)
    {
      cmd_index = iwe->cmd - SIOCIWFIRST;
      if(cmd_index < standard_ioctl_num)
    descr = &(standard_ioctl_descr[cmd_index]);
    }
  else
    {
      cmd_index = iwe->cmd - IWEVFIRST;
      if(cmd_index < standard_event_num)
    descr = &(standard_event_descr[cmd_index]);
    }
  if(descr != NULL)
    event_type = descr->header_type;
  /* Unknown events -> event_type=0 => IW_EV_LCP_PK_LEN */
  event_len = event_type_size[event_type];
  /* Fixup for earlier version of WE */
  if((we_version <= 18) && (event_type == IW_HEADER_TYPE_POINT))
    event_len += IW_EV_POINT_OFF;

  /* Check if we know about this event */
  if(event_len <= IW_EV_LCP_PK_LEN)
    {
      /* Skip to next event */
      stream->current += iwe->len;
      return(2);
    }
  event_len -= IW_EV_LCP_PK_LEN;

  /* Set pointer on data */
  if(stream->value != NULL)
    pointer = stream->value;            /* Next value in event */
  else
    pointer = stream->current + IW_EV_LCP_PK_LEN;    /* First value in event */

#ifdef DEBUG
  printf("DBG - event_type = %d, event_len = %d, pointer = %p\n",
     event_type, event_len, pointer);
#endif

  /* Copy the rest of the event (at least, fixed part) */
  if((pointer + event_len) > stream->end)
    {
      /* Go to next event */
      stream->current += iwe->len;
      return(-2);
    }
  /* Fixup for WE-19 and later : pointer no longer in the stream */
  /* Beware of alignement. Dest has local alignement, not packed */
  if((we_version > 18) && (event_type == IW_HEADER_TYPE_POINT))
    memcpy((char *) iwe + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
       pointer, event_len);
  else
    memcpy((char *) iwe + IW_EV_LCP_LEN, pointer, event_len);

  /* Skip event in the stream */
  pointer += event_len;

  /* Special processing for iw_point events */
  if(event_type == IW_HEADER_TYPE_POINT)
    {
      /* Check the length of the payload */
      unsigned int    extra_len = iwe->len - (event_len + IW_EV_LCP_PK_LEN);
      if(extra_len > 0)
    {
      /* Set pointer on variable part (warning : non aligned) */
      iwe->u.data.pointer = pointer;

      /* Check that we have a descriptor for the command */
      if(descr == NULL)
        /* Can't check payload -> unsafe... */
        iwe->u.data.pointer = NULL;    /* Discard paylod */
      else
        {
          /* Those checks are actually pretty hard to trigger,
           * because of the checks done in the kernel... */

          unsigned int    token_len = iwe->u.data.length * descr->token_size;

          /* Ugly fixup for alignement issues.
           * If the kernel is 64 bits and userspace 32 bits,
           * we have an extra 4+4 bytes.
           * Fixing that in the kernel would break 64 bits userspace. */
          if((token_len != extra_len) && (extra_len >= 4))
        {
          __u16        alt_dlen = *((__u16 *) pointer);
          unsigned int    alt_token_len = alt_dlen * descr->token_size;
          if((alt_token_len + 8) == extra_len)
            {
#ifdef DEBUG
              printf("DBG - alt_token_len = %d\n", alt_token_len);
#endif
              /* Ok, let's redo everything */
              pointer -= event_len;
              pointer += 4;
              /* Dest has local alignement, not packed */
              memcpy((char *) iwe + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
                 pointer, event_len);
              pointer += event_len + 4;
              iwe->u.data.pointer = pointer;
              token_len = alt_token_len;
            }
        }

          /* Discard bogus events which advertise more tokens than
           * what they carry... */
          if(token_len > extra_len)
        iwe->u.data.pointer = NULL;    /* Discard paylod */
          /* Check that the advertised token size is not going to
           * produce buffer overflow to our caller... */
          if((iwe->u.data.length > descr->max_tokens)
         && !(descr->flags & IW_DESCR_FLAG_NOMAX))
        iwe->u.data.pointer = NULL;    /* Discard paylod */
          /* Same for underflows... */
          if(iwe->u.data.length < descr->min_tokens)
        iwe->u.data.pointer = NULL;    /* Discard paylod */
#ifdef DEBUG
          printf("DBG - extra_len = %d, token_len = %d, token = %d, max = %d, min = %d\n",
             extra_len, token_len, iwe->u.data.length, descr->max_tokens, descr->min_tokens);
#endif
        }
    }
      else
    /* No data */
    iwe->u.data.pointer = NULL;

      /* Go to next event */
      stream->current += iwe->len;
    }
  else
    {
      /* Ugly fixup for alignement issues.
       * If the kernel is 64 bits and userspace 32 bits,
       * we have an extra 4 bytes.
       * Fixing that in the kernel would break 64 bits userspace. */
      if((stream->value == NULL)
     && ((((iwe->len - IW_EV_LCP_PK_LEN) % event_len) == 4)
         || ((iwe->len == 12) && ((event_type == IW_HEADER_TYPE_UINT) ||
                      (event_type == IW_HEADER_TYPE_QUAL))) ))
    {
#ifdef DEBUG
      printf("DBG - alt iwe->len = %d\n", iwe->len - 4);
#endif
      pointer -= event_len;
      pointer += 4;
      /* Beware of alignement. Dest has local alignement, not packed */
      memcpy((char *) iwe + IW_EV_LCP_LEN, pointer, event_len);
      pointer += event_len;
    }

      /* Is there more value in the event ? */
      if((pointer + event_len) <= (stream->current + iwe->len))
    /* Go to next value */
    stream->value = pointer;
      else
    {
      /* Go to next event */
      stream->value = NULL;
      stream->current += iwe->len;
    }
    }
  return(1);
}
票数 3
EN

Stack Overflow用户

发布于 2019-04-30 20:11:13

答案2.的第1部分

我已经张贴了我的全部答案在两个部分,因为我达到了字符限制,试图在一个!

Note除了我的另一篇文章中包含的C++修订版之外,在某个嵌入式设备堆栈上,我不得不在#include <linux/wireless.h>之前添加#include <sys/socket.h>。否则,编译器没有定义sockaddr.

与许多其他linux查询/请求不同,SIOCGIWSCAN生成“数据流”。记住,“扫描”将检测到范围内所有可用的wifi访问点,并返回一大堆信息。因此,数据没有固定的大小,也没有将数据转换为简单结构的直接方法。

解释和提供导致这一切的所有细节需要很长时间,并且需要大量的代码来发布。(请注意,这是为了在这里张贴这么多信息而进行的一场斗争。)因此,下面是一个示例,说明如何解析您专门询问的数据。

关于以下例子的说明:

  • resultBuffer是一个指向char数组的指针,在此时使用标志IW_DESCR_FLAG_DUMP (即1)填充了SIOCGIWSCAN的结果。
  • E2BIG错误的可能性已经得到处理,以便在流中返回大量数据时动态地调整缓冲区的大小(比如10个访问点或更多)。
  • wifiRequest是用于请求的iwreq结构。
  • weVersion是活动接口上无线扩展驱动程序的版本(通过另一个先前的请求查询)。

示例:

代码语言:javascript
运行
复制
// Create and initialize an event stream
// binding the scan results buffer to it
struct iw_event_stream eventStream;
memset( &eventStream, 0, sizeof(struct iw_event_stream) );
eventStream.current = resultBuffer;
eventStream.end = &resultBuffer[ wifiRequest.u.data.length ];

// Loop though the stream, parsing each event, and gathering essids
// (i.e. access point names).  Note, iw_extract_event_stream is where 
// the real nastiness takes place...
struct iw_event event;
while( iw_extract_event_stream( &eventStream, &event, weVersion ) > 0 )
{
    if( event.cmd == SIOCGIWESSID )
    {
        // fetch the AP name via
        // (char *)event.u.essid.pointer and event.u.essid.length ...
    }
}

然后,在大多数Linux发行版中包含了标准的"iwlist“实用程序(请参阅:tools/iwlib.c)。我试着删掉它并清理它,因为我发现我可以用这个来源(或相关的)的许多例子来做,但是当涉及到这个问题时,我发现这比仅仅复制和粘贴所有这些(然后只是根据需要进行修补/调整)要麻烦得多。您可能希望将其放入项目中的另一个文件中,而不是直接将其混合到您自己的代码中。

代码语言:javascript
运行
复制
struct iw_event_stream {
    char *end;
    char *current;
    char *value;
};

// Type of headers we know about (basically union iwreq_data)
#define IW_HEADER_TYPE_NULL 0   // Not available
#define IW_HEADER_TYPE_CHAR 2   // char [IFNAMSIZ]
#define IW_HEADER_TYPE_UINT 4   // __u32
#define IW_HEADER_TYPE_FREQ 5   // struct iw_freq
#define IW_HEADER_TYPE_ADDR 6   // struct sockaddr
#define IW_HEADER_TYPE_POINT    8   // struct iw_point
#define IW_HEADER_TYPE_PARAM    9   // struct iw_param
#define IW_HEADER_TYPE_QUAL 10  // struct iw_quality

// Handling flags
// Most are not implemented. I just use them as a reminder of some
// cool features we might need one day ;-)
#define IW_DESCR_FLAG_NONE  0x0000  // Obvious
// Wrapper level flags
#define IW_DESCR_FLAG_DUMP  0x0001  // Not part of the dump command
#define IW_DESCR_FLAG_EVENT 0x0002  // Generate an event on SET
#define IW_DESCR_FLAG_RESTRICT  0x0004  // GET : request is ROOT only
                // SET : Omit payload from generated iwevent
#define IW_DESCR_FLAG_NOMAX 0x0008  // GET : no limit on request size
// Driver level flags
#define IW_DESCR_FLAG_WAIT  0x0100  // Wait for driver event

struct iw_ioctl_description
{
    __u8    header_type;        // NULL, iw_point or other
    __u8    token_type;     // Future
    __u16   token_size;     // Granularity of payload
    __u16   min_tokens;     // Min acceptable token number
    __u16   max_tokens;     // Max acceptable token number
    __u32   flags;          // Special handling of the request
};

// Fill Missing Defines
#ifndef SIOCSIWMODUL
#define SIOCSIWMODUL    0x8B2E      /* set Modulations settings */
#endif
#ifndef SIOCGIWMODUL
#define SIOCGIWMODUL    0x8B2F      /* get Modulations settings */
#endif

const struct iw_ioctl_description standard_ioctl_descr[] = {
    [SIOCSIWCOMMIT  - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_NULL,
    },
    [SIOCGIWNAME    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_CHAR,
        .flags      = IW_DESCR_FLAG_DUMP,
    },
    [SIOCSIWNWID    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
        .flags      = IW_DESCR_FLAG_EVENT,
    },
    [SIOCGIWNWID    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
        .flags      = IW_DESCR_FLAG_DUMP,
    },
    [SIOCSIWFREQ    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_FREQ,
        .flags      = IW_DESCR_FLAG_EVENT,
    },
    [SIOCGIWFREQ    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_FREQ,
        .flags      = IW_DESCR_FLAG_DUMP,
    },
    [SIOCSIWMODE    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_UINT,
        .flags      = IW_DESCR_FLAG_EVENT,
    },
    [SIOCGIWMODE    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_UINT,
        .flags      = IW_DESCR_FLAG_DUMP,
    },
    [SIOCSIWSENS    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
    },
    [SIOCGIWSENS    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
    },
    [SIOCSIWRANGE   - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_NULL,
    },
    [SIOCGIWRANGE   - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_size = 1,
        .max_tokens = sizeof(struct iw_range),
        .flags      = IW_DESCR_FLAG_DUMP,
    },
    [SIOCSIWPRIV    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_NULL,
    },
    [SIOCGIWPRIV    - SIOCIWFIRST] = { // (handled directly by us)
        .header_type    = IW_HEADER_TYPE_NULL,
    },
    [SIOCSIWSTATS   - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_NULL,
    },
    [SIOCGIWSTATS   - SIOCIWFIRST] = { // (handled directly by us)
        .header_type    = IW_HEADER_TYPE_NULL,
        .flags      = IW_DESCR_FLAG_DUMP,
    },
    [SIOCSIWSPY - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_size = sizeof(struct sockaddr),
        .max_tokens = IW_MAX_SPY,
    },
    [SIOCGIWSPY - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_size = sizeof(struct sockaddr) +
                  sizeof(struct iw_quality),
        .max_tokens = IW_MAX_SPY,
    },
    [SIOCSIWTHRSPY  - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_size = sizeof(struct iw_thrspy),
        .min_tokens = 1,
        .max_tokens = 1,
    },
    [SIOCGIWTHRSPY  - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_size = sizeof(struct iw_thrspy),
        .min_tokens = 1,
        .max_tokens = 1,
    },
    [SIOCSIWAP  - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_ADDR,
    },
    [SIOCGIWAP  - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_ADDR,
        .flags      = IW_DESCR_FLAG_DUMP,
    },
    [SIOCSIWMLME    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_size = 1,
        .min_tokens = sizeof(struct iw_mlme),
        .max_tokens = sizeof(struct iw_mlme),
    },
    [SIOCGIWAPLIST  - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_size = sizeof(struct sockaddr) +
                  sizeof(struct iw_quality),
        .max_tokens = IW_MAX_AP,
        .flags      = IW_DESCR_FLAG_NOMAX,
    },
    [SIOCSIWSCAN    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_size = 1,
        .min_tokens = 0,
        .max_tokens = sizeof(struct iw_scan_req),
    },
    [SIOCGIWSCAN    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_size = 1,
        .max_tokens = IW_SCAN_MAX_DATA,
        .flags      = IW_DESCR_FLAG_NOMAX,
    },
    [SIOCSIWESSID   - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_size = 1,
        .max_tokens = IW_ESSID_MAX_SIZE + 1,
        .flags      = IW_DESCR_FLAG_EVENT,
    },
    [SIOCGIWESSID   - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_size = 1,
        .max_tokens = IW_ESSID_MAX_SIZE + 1,
        .flags      = IW_DESCR_FLAG_DUMP,
    },
    [SIOCSIWNICKN   - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_size = 1,
        .max_tokens = IW_ESSID_MAX_SIZE + 1,
    },
    [SIOCGIWNICKN   - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_size = 1,
        .max_tokens = IW_ESSID_MAX_SIZE + 1,
    },
// PATCH: MAKE ERROR THROWN WITHOUT THESE ARRAY ELEMENTS!!!
    [0x8B1E - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
    },
    [0x8B1F - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
    },
//
    [SIOCSIWRATE    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
    },
    [SIOCGIWRATE    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
    },
    [SIOCSIWRTS - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
    },
    [SIOCGIWRTS - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
    },
    [SIOCSIWFRAG    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
    },
    [SIOCGIWFRAG    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
    },
    [SIOCSIWTXPOW   - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
    },
    [SIOCGIWTXPOW   - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
    },
    [SIOCSIWRETRY   - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
    },
    [SIOCGIWRETRY   - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
    },
    [SIOCSIWENCODE  - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_size = 1,
        .max_tokens = IW_ENCODING_TOKEN_MAX,
        .flags      = IW_DESCR_FLAG_EVENT | IW_DESCR_FLAG_RESTRICT,
    },
    [SIOCGIWENCODE  - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_size = 1,
        .max_tokens = IW_ENCODING_TOKEN_MAX,
        .flags      = IW_DESCR_FLAG_DUMP | IW_DESCR_FLAG_RESTRICT,
    },
    [SIOCSIWPOWER   - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
    },
    [SIOCGIWPOWER   - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
    },
    [SIOCSIWMODUL   - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
    },
    [SIOCGIWMODUL   - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
    },
    [SIOCSIWGENIE   - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_size = 1,
        .max_tokens = IW_GENERIC_IE_MAX,
    },
    [SIOCGIWGENIE   - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_size = 1,
        .max_tokens = IW_GENERIC_IE_MAX,
    },
    [SIOCSIWAUTH    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
    },
    [SIOCGIWAUTH    - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_PARAM,
    },
    [SIOCSIWENCODEEXT - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_size = 1,
        .min_tokens = sizeof(struct iw_encode_ext),
        .max_tokens = sizeof(struct iw_encode_ext) +
                  IW_ENCODING_TOKEN_MAX,
    },
    [SIOCGIWENCODEEXT - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_size = 1,
        .min_tokens = sizeof(struct iw_encode_ext),
        .max_tokens = sizeof(struct iw_encode_ext) +
                  IW_ENCODING_TOKEN_MAX,
    },
    [SIOCSIWPMKSA - SIOCIWFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_size = 1,
        .min_tokens = sizeof(struct iw_pmksa),
        .max_tokens = sizeof(struct iw_pmksa),
    },
};

const unsigned int standard_ioctl_num = (sizeof(standard_ioctl_descr) /
                        sizeof(struct iw_ioctl_description));

//
// Meta-data about all the additional standard Wireless Extension events
// we know about.
//
//
const struct iw_ioctl_description standard_event_descr[] = {
    [IWEVTXDROP - IWEVFIRST] = {
        .header_type    = IW_HEADER_TYPE_ADDR,
    },
    [IWEVQUAL   - IWEVFIRST] = {
        .header_type    = IW_HEADER_TYPE_QUAL,
    },
    [IWEVCUSTOM - IWEVFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_size = 1,
        .max_tokens = IW_CUSTOM_MAX,
    },
    [IWEVREGISTERED - IWEVFIRST] = {
        .header_type    = IW_HEADER_TYPE_ADDR,
    },
    [IWEVEXPIRED    - IWEVFIRST] = {
        .header_type    = IW_HEADER_TYPE_ADDR,
    },
    [IWEVGENIE  - IWEVFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_size = 1,
        .max_tokens = IW_GENERIC_IE_MAX,
    },
    [IWEVMICHAELMICFAILURE  - IWEVFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_size = 1,
        .max_tokens = sizeof(struct iw_michaelmicfailure),
    },
    [IWEVASSOCREQIE - IWEVFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_size = 1,
        .max_tokens = IW_GENERIC_IE_MAX,
    },
    [IWEVASSOCRESPIE    - IWEVFIRST] = {
        .header_type    = IW_HEADER_TYPE_POINT,
        .token_size = 1,
        .max_tokens = IW_GENERIC_IE_MAX,
    },
    [IWEVPMKIDCAND  - IWEVFIRST] = {
            .header_type    = IW_HEADER_TYPE_POINT,
            .token_size = 1,
            .max_tokens = sizeof(struct iw_pmkid_cand),
    },
};

const unsigned int standard_event_num = (sizeof(standard_event_descr) /
    sizeof(struct iw_ioctl_description));

// Size (in bytes) of various events
const int event_type_size[] = {
    IW_EV_LCP_PK_LEN,   // IW_HEADER_TYPE_NULL
    0,
    IW_EV_CHAR_PK_LEN,  // IW_HEADER_TYPE_CHAR
    0,
    IW_EV_UINT_PK_LEN,  // IW_HEADER_TYPE_UINT
    IW_EV_FREQ_PK_LEN,  // IW_HEADER_TYPE_FREQ
    IW_EV_ADDR_PK_LEN,  // IW_HEADER_TYPE_ADDR
    0,
    IW_EV_POINT_PK_LEN, // Without variable payload
    IW_EV_PARAM_PK_LEN, // IW_HEADER_TYPE_PARAM
    IW_EV_QUAL_PK_LEN,  // IW_HEADER_TYPE_QUAL *
};

int iw_extract_event_stream( iw_event_stream *stream,   /* Stream of events */
            struct iw_event *   iwe,    /* Extracted event */
            int         we_version)
{
  const struct iw_ioctl_description *   descr = NULL;
  int       event_type = 0;
  unsigned int  event_len = 1;      /* Invalid */
  char *    pointer;
  /* Don't "optimise" the following variable, it will crash */
  unsigned  cmd_index;      /* *MUST* be unsigned */

  /* Check for end of stream */
  if((stream->current + IW_EV_LCP_PK_LEN) > stream->end)
    return(0);

#ifdef DEBUG
  printf("DBG - stream->current = %p, stream->value = %p, stream->end = %p\n",
     stream->current, stream->value, stream->end);
#endif

  /* Extract the event header (to get the event id).
   * Note : the event may be unaligned, therefore copy... */
  memcpy((char *) iwe, stream->current, IW_EV_LCP_PK_LEN);

#ifdef DEBUG
  printf("DBG - iwe->cmd = 0x%X, iwe->len = %d\n",
     iwe->cmd, iwe->len);
#endif

  /* Check invalid events */
  if(iwe->len <= IW_EV_LCP_PK_LEN)
    return(-1);

  /* Get the type and length of that event */
  if(iwe->cmd <= SIOCIWLAST)
    {
      cmd_index = iwe->cmd - SIOCIWFIRST;
      if(cmd_index < standard_ioctl_num)
    descr = &(standard_ioctl_descr[cmd_index]);
    }
  else
    {
      cmd_index = iwe->cmd - IWEVFIRST;
      if(cmd_index < standard_event_num)
    descr = &(standard_event_descr[cmd_index]);
    }
  if(descr != NULL)
    event_type = descr->header_type;
  /* Unknown events -> event_type=0 => IW_EV_LCP_PK_LEN */
  event_len = event_type_size[event_type];
  /* Fixup for earlier version of WE */
  if((we_version <= 18) && (event_type == IW_HEADER_TYPE_POINT))
    event_len += IW_EV_POINT_OFF;

  /* Check if we know about this event */
  if(event_len <= IW_EV_LCP_PK_LEN)
    {
      /* Skip to next event */
      stream->current += iwe->len;
      return(2);
    }
  event_len -= IW_EV_LCP_PK_LEN;

  /* Set pointer on data */
  if(stream->value != NULL)
    pointer = stream->value;            /* Next value in event */
  else
    pointer = stream->current + IW_EV_LCP_PK_LEN;   /* First value in event */

#ifdef DEBUG
  printf("DBG - event_type = %d, event_len = %d, pointer = %p\n",
     event_type, event_len, pointer);
#endif

  /* Copy the rest of the event (at least, fixed part) */
  if((pointer + event_len) > stream->end)
    {
      /* Go to next event */
      stream->current += iwe->len;
      return(-2);
    }
  /* Fixup for WE-19 and later : pointer no longer in the stream */
  /* Beware of alignement. Dest has local alignement, not packed */
  if((we_version > 18) && (event_type == IW_HEADER_TYPE_POINT))
    memcpy((char *) iwe + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
       pointer, event_len);
  else
    memcpy((char *) iwe + IW_EV_LCP_LEN, pointer, event_len);

  /* Skip event in the stream */
  pointer += event_len;

  /* Special processing for iw_point events */
  if(event_type == IW_HEADER_TYPE_POINT)
    {
      /* Check the length of the payload */
      unsigned int  extra_len = iwe->len - (event_len + IW_EV_LCP_PK_LEN);
      if(extra_len > 0)
    {
      /* Set pointer on variable part (warning : non aligned) */
      iwe->u.data.pointer = pointer;

      /* Check that we have a descriptor for the command */
      if(descr == NULL)
        /* Can't check payload -> unsafe... */
        iwe->u.data.pointer = NULL; /* Discard paylod */
      else
        {
          /* Those checks are actually pretty hard to trigger,
           * because of the checks done in the kernel... */

          unsigned int  token_len = iwe->u.data.length * descr->token_size;

          /* Ugly fixup for alignement issues.
           * If the kernel is 64 bits and userspace 32 bits,
           * we have an extra 4+4 bytes.
           * Fixing that in the kernel would break 64 bits userspace. */
          if((token_len != extra_len) && (extra_len >= 4))
        {
          __u16     alt_dlen = *((__u16 *) pointer);
          unsigned int  alt_token_len = alt_dlen * descr->token_size;
          if((alt_token_len + 8) == extra_len)
            {
#ifdef DEBUG
              printf("DBG - alt_token_len = %d\n", alt_token_len);
#endif
              /* Ok, let's redo everything */
              pointer -= event_len;
              pointer += 4;
              /* Dest has local alignement, not packed */
              memcpy((char *) iwe + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
                 pointer, event_len);
              pointer += event_len + 4;
              iwe->u.data.pointer = pointer;
              token_len = alt_token_len;
            }
        }

          /* Discard bogus events which advertise more tokens than
           * what they carry... */
          if(token_len > extra_len)
        iwe->u.data.pointer = NULL; /* Discard paylod */
          /* Check that the advertised token size is not going to
           * produce buffer overflow to our caller... */
          if((iwe->u.data.length > descr->max_tokens)
         && !(descr->flags & IW_DESCR_FLAG_NOMAX))
        iwe->u.data.pointer = NULL; /* Discard paylod */
          /* Same for underflows... */
          if(iwe->u.data.length < descr->min_tokens)
        iwe->u.data.pointer = NULL; /* Discard paylod */
#ifdef DEBUG
          printf("DBG - extra_len = %d, token_len = %d, token = %d, max = %d, min = %d\n",
             extra_len, token_len, iwe->u.data.length, descr->max_tokens, descr->min_tokens);
#endif
        }
    }
      else
    /* No data */
    iwe->u.data.pointer = NULL;

      /* Go to next event */
      stream->current += iwe->len;
    }
  else
    {
      /* Ugly fixup for alignement issues.
       * If the kernel is 64 bits and userspace 32 bits,
       * we have an extra 4 bytes.
       * Fixing that in the kernel would break 64 bits userspace. */
      if((stream->value == NULL)
     && ((((iwe->len - IW_EV_LCP_PK_LEN) % event_len) == 4)
         || ((iwe->len == 12) && ((event_type == IW_HEADER_TYPE_UINT) ||
                      (event_type == IW_HEADER_TYPE_QUAL))) ))
    {
#ifdef DEBUG
      printf("DBG - alt iwe->len = %d\n", iwe->len - 4);
#endif
      pointer -= event_len;
      pointer += 4;
      /* Beware of alignement. Dest has local alignement, not packed */
      memcpy((char *) iwe + IW_EV_LCP_LEN, pointer, event_len);
      pointer += event_len;
    }

      /* Is there more value in the event ? */
      if((pointer + event_len) <= (stream->current + iwe->len))
    /* Go to next value */
    stream->value = pointer;
      else
    {
      /* Go to next event */
      stream->value = NULL;
      stream->current += iwe->len;
    }
    }
  return(1);
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53633159

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档