Сканирование Wi-Fi с ioctl SIOCGIWSCAN - PullRequest
0 голосов
/ 05 декабря 2018

Интересно, кто-нибудь может сказать мне, как интерпретировать данные, которые приходят в результате сканирования Wi-Fi с

if (-1 != (status = ioctl(handle, SIOCGIWSCAN, &data)))
{
    data.u.data.pointer = ? what struct is this ?
}

Это похоже на большой массив данных char [], но там должно быть какое-товид структуры позади.

Спасибо

Ответы [ 2 ]

0 голосов
/ 01 мая 2019

Ответ части 2 из 2. Пересмотрен для совместимости с выпуклостью / C ++.

linuxwifistream.h

#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

#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);
}
0 голосов
/ 30 апреля 2019

Ответьте часть 1 из 2.

Я опубликовал свой полный ответ в 2 частях, потому что я достиг предела ТАК, пытаясь получить его в одной!

Примечание в дополнение к ревизиям C ++, включенным в мою другую публикацию, о некотором стеке встроенных устройств, мне пришлось добавить #include <sys/socket.h> до #include <linux/wireless.h>.Иначе, у компилятора не было определения для sockaddr ...


В отличие от многих других запросов / запросов WiFi в Linux, SIOCGIWSCAN создает «поток» данных.Помните, что «сканирование» обнаружит все точки доступа Wi-Fi, доступные в радиусе действия, и выдаст огромную кучу информации.Таким образом, для данных не существует фиксированного размера и прямых средств преобразования в простую структуру.

Объяснение и предоставление всех подробностей, приведших к этому, займет ДЛИННОЕ время и потребует много кода для публикации.(обратите внимание, что это было проблемой, чтобы выложить столько информации здесь). Итак, вот пример того, как просто проанализировать те данные, о которых вы конкретно спрашиваете.

Примечания к примеру ниже:

  • resultBuffer - указатель на массив символов, который был заполнен в этой точке результатами SIOCGIWSCAN с использованием флага IW_DESCR_FLAG_DUMP (т.е. 1).
  • Возможность ошибки E2BIG уже была обработана для динамического изменения размера этого буфера в случае, если в потоке возвращается тонна данных (например, 10 или более точек доступа).
  • wifiRequest - это структура iwreq, которая использовалась для запроса.
  • weVersion - версия драйвера беспроводных расширений на активном интерфейсе (запрашивается с помощью другого предыдущего запроса)

Пример:

// 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 ...
    }
}

Затем,вот урезанный, слегка измененный фрагмент исходного кода за стандартной утилитой «iwlist», включенной в большинство дистрибутивов Linux (см .: https://github.com/HewlettPackard/wireless-tools/blob/master/wireless_tools/iwlib.c). Я попытался сократить это и очистить его, как я обнаружил, что могу сделать смного примеров из этого источника (или связанных), но когда дело дошло до этого, я обнаружил, что это гораздо больше проблем, чем стоит по сравнению с простым копированием и вставкой всего этого (а затем просто исправлением / настройкой по мере необходимости).Уберите это в другой файл в вашем проекте, вместо того, чтобы смешивать его прямо в вашем собственном коде.

...