Ответ части 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);
}