mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-26 10:06:51 +00:00
supplicant/esp_wifi: move supplicant to idf
Move supplicant to idf and do following refactoring: 1. Make the folder structure consitent with supplicant upstream 2. Remove duplicated header files and minimize the public header files 3. Refactor for WiFi/supplicant interfaces
This commit is contained in:
155
components/wpa_supplicant/src/utils/base64.c
Normal file
155
components/wpa_supplicant/src/utils/base64.c
Normal file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Base64 encoding/decoding (RFC1341)
|
||||
* Copyright (c) 2005-2011, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "utils/includes.h"
|
||||
|
||||
#include "os.h"
|
||||
#include "base64.h"
|
||||
|
||||
static const unsigned char base64_table[65] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
/**
|
||||
* base64_encode - Base64 encode
|
||||
* @src: Data to be encoded
|
||||
* @len: Length of the data to be encoded
|
||||
* @out_len: Pointer to output length variable, or %NULL if not used
|
||||
* Returns: Allocated buffer of out_len bytes of encoded data,
|
||||
* or %NULL on failure
|
||||
*
|
||||
* Caller is responsible for freeing the returned buffer. Returned buffer is
|
||||
* nul terminated to make it easier to use as a C string. The nul terminator is
|
||||
* not included in out_len.
|
||||
*/
|
||||
unsigned char * base64_encode(const unsigned char *src, size_t len,
|
||||
size_t *out_len)
|
||||
{
|
||||
unsigned char *out, *pos;
|
||||
const unsigned char *end, *in;
|
||||
size_t olen;
|
||||
int line_len;
|
||||
|
||||
olen = len * 4 / 3 + 4; /* 3-byte blocks to 4-byte */
|
||||
olen += olen / 72; /* line feeds */
|
||||
olen++; /* nul termination */
|
||||
if (olen < len)
|
||||
return NULL; /* integer overflow */
|
||||
out = os_malloc(olen);
|
||||
if (out == NULL)
|
||||
return NULL;
|
||||
|
||||
end = src + len;
|
||||
in = src;
|
||||
pos = out;
|
||||
line_len = 0;
|
||||
while (end - in >= 3) {
|
||||
*pos++ = base64_table[in[0] >> 2];
|
||||
*pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)];
|
||||
*pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)];
|
||||
*pos++ = base64_table[in[2] & 0x3f];
|
||||
in += 3;
|
||||
line_len += 4;
|
||||
if (line_len >= 72) {
|
||||
*pos++ = '\n';
|
||||
line_len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (end - in) {
|
||||
*pos++ = base64_table[in[0] >> 2];
|
||||
if (end - in == 1) {
|
||||
*pos++ = base64_table[(in[0] & 0x03) << 4];
|
||||
*pos++ = '=';
|
||||
} else {
|
||||
*pos++ = base64_table[((in[0] & 0x03) << 4) |
|
||||
(in[1] >> 4)];
|
||||
*pos++ = base64_table[(in[1] & 0x0f) << 2];
|
||||
}
|
||||
*pos++ = '=';
|
||||
line_len += 4;
|
||||
}
|
||||
|
||||
if (line_len)
|
||||
*pos++ = '\n';
|
||||
|
||||
*pos = '\0';
|
||||
if (out_len)
|
||||
*out_len = pos - out;
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* base64_decode - Base64 decode
|
||||
* @src: Data to be decoded
|
||||
* @len: Length of the data to be decoded
|
||||
* @out_len: Pointer to output length variable
|
||||
* Returns: Allocated buffer of out_len bytes of decoded data,
|
||||
* or %NULL on failure
|
||||
*
|
||||
* Caller is responsible for freeing the returned buffer.
|
||||
*/
|
||||
unsigned char * base64_decode(const unsigned char *src, size_t len,
|
||||
size_t *out_len)
|
||||
{
|
||||
unsigned char dtable[256], *out, *pos, block[4], tmp;
|
||||
size_t i, count, olen;
|
||||
int pad = 0;
|
||||
|
||||
os_memset(dtable, 0x80, 256);
|
||||
for (i = 0; i < sizeof(base64_table) - 1; i++)
|
||||
dtable[base64_table[i]] = (unsigned char) i;
|
||||
dtable['='] = 0;
|
||||
|
||||
count = 0;
|
||||
for (i = 0; i < len; i++) {
|
||||
if (dtable[src[i]] != 0x80)
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count == 0 || count % 4)
|
||||
return NULL;
|
||||
|
||||
olen = count / 4 * 3;
|
||||
pos = out = os_malloc(olen);
|
||||
if (out == NULL)
|
||||
return NULL;
|
||||
|
||||
count = 0;
|
||||
for (i = 0; i < len; i++) {
|
||||
tmp = dtable[src[i]];
|
||||
if (tmp == 0x80)
|
||||
continue;
|
||||
|
||||
if (src[i] == '=')
|
||||
pad++;
|
||||
block[count] = tmp;
|
||||
count++;
|
||||
if (count == 4) {
|
||||
*pos++ = (block[0] << 2) | (block[1] >> 4);
|
||||
*pos++ = (block[1] << 4) | (block[2] >> 2);
|
||||
*pos++ = (block[2] << 6) | block[3];
|
||||
count = 0;
|
||||
if (pad) {
|
||||
if (pad == 1)
|
||||
pos--;
|
||||
else if (pad == 2)
|
||||
pos -= 2;
|
||||
else {
|
||||
/* Invalid padding */
|
||||
os_free(out);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*out_len = pos - out;
|
||||
return out;
|
||||
}
|
23
components/wpa_supplicant/src/utils/base64.h
Normal file
23
components/wpa_supplicant/src/utils/base64.h
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Base64 encoding/decoding (RFC1341)
|
||||
* Copyright (c) 2005, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of BSD
|
||||
* license.
|
||||
*
|
||||
* See README and COPYING for more details.
|
||||
*/
|
||||
|
||||
#ifndef BASE64_H
|
||||
#define BASE64_H
|
||||
|
||||
unsigned char * base64_encode(const unsigned char *src, size_t len,
|
||||
size_t *out_len);
|
||||
unsigned char * base64_decode(const unsigned char *src, size_t len,
|
||||
size_t *out_len);
|
||||
|
||||
#endif /* BASE64_H */
|
166
components/wpa_supplicant/src/utils/common.c
Normal file
166
components/wpa_supplicant/src/utils/common.c
Normal file
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* wpa_supplicant/hostapd / common helper functions, etc.
|
||||
* Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of BSD
|
||||
* license.
|
||||
*
|
||||
* See README and COPYING for more details.
|
||||
*/
|
||||
|
||||
#include "utils/includes.h"
|
||||
|
||||
#include "utils/common.h"
|
||||
|
||||
/**
|
||||
* inc_byte_array - Increment arbitrary length byte array by one
|
||||
* @counter: Pointer to byte array
|
||||
* @len: Length of the counter in bytes
|
||||
*
|
||||
* This function increments the last byte of the counter by one and continues
|
||||
* rolling over to more significant bytes if the byte was incremented from
|
||||
* 0xff to 0x00.
|
||||
*/
|
||||
void inc_byte_array(u8 *counter, size_t len)
|
||||
{
|
||||
int pos = len - 1;
|
||||
while (pos >= 0) {
|
||||
counter[pos]++;
|
||||
if (counter[pos] != 0)
|
||||
break;
|
||||
pos--;
|
||||
}
|
||||
}
|
||||
|
||||
static int hex2num(char c)
|
||||
{
|
||||
if (c >= '0' && c <= '9')
|
||||
return c - '0';
|
||||
if (c >= 'a' && c <= 'f')
|
||||
return c - 'a' + 10;
|
||||
if (c >= 'A' && c <= 'F')
|
||||
return c - 'A' + 10;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int hex2byte(const char *hex)
|
||||
{
|
||||
int a, b;
|
||||
a = hex2num(*hex++);
|
||||
if (a < 0)
|
||||
return -1;
|
||||
b = hex2num(*hex++);
|
||||
if (b < 0)
|
||||
return -1;
|
||||
return (a << 4) | b;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* hexstr2bin - Convert ASCII hex string into binary data
|
||||
* @hex: ASCII hex string (e.g., "01ab")
|
||||
* @buf: Buffer for the binary data
|
||||
* @len: Length of the text to convert in bytes (of buf); hex will be double
|
||||
* this size
|
||||
* Returns: 0 on success, -1 on failure (invalid hex string)
|
||||
*/
|
||||
int hexstr2bin(const char *hex, u8 *buf, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
int a;
|
||||
const char *ipos = hex;
|
||||
u8 *opos = buf;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
a = hex2byte(ipos);
|
||||
if (a < 0)
|
||||
return -1;
|
||||
*opos++ = a;
|
||||
ipos += 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void wpa_get_ntp_timestamp(u8 *buf)
|
||||
{
|
||||
struct os_time now;
|
||||
u32 sec, usec;
|
||||
be32 tmp;
|
||||
|
||||
/* 64-bit NTP timestamp (time from 1900-01-01 00:00:00) */
|
||||
os_get_time(&now);
|
||||
sec = now.sec + 2208988800U; /* Epoch to 1900 */
|
||||
/* Estimate 2^32/10^6 = 4295 - 1/32 - 1/512 */
|
||||
usec = now.usec;
|
||||
usec = 4295 * usec - (usec >> 5) - (usec >> 9);
|
||||
tmp = host_to_be32(sec);
|
||||
memcpy(buf, (u8 *) &tmp, 4);
|
||||
tmp = host_to_be32(usec);
|
||||
memcpy(buf + 4, (u8 *) &tmp, 4);
|
||||
}
|
||||
|
||||
char * wpa_config_parse_string(const char *value, size_t *len)
|
||||
{
|
||||
if (*value == '"' && (strlen(value) == 7 || strlen(value) == 15)) {
|
||||
const char *pos;
|
||||
char *str;
|
||||
value++;
|
||||
pos = (char *)strrchr(value, '"');
|
||||
if (pos == NULL)
|
||||
return NULL;
|
||||
*len = pos - value;
|
||||
str = (char *)os_malloc(*len + 1);
|
||||
if (str == NULL)
|
||||
return NULL;
|
||||
memcpy(str, value, *len);
|
||||
str[*len] = '\0';
|
||||
return str;
|
||||
} else {
|
||||
u8 *str;
|
||||
size_t tlen, hlen = strlen(value);
|
||||
if (hlen == 5 || hlen == 13) {
|
||||
*len = hlen;
|
||||
str = (u8 *)os_malloc(*len + 1);
|
||||
if (str == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
memcpy(str, value, *len);
|
||||
str[*len] = '\0';
|
||||
} else if (hlen == 10 || hlen == 26) {
|
||||
tlen = hlen / 2;
|
||||
str = (u8 *)os_malloc(tlen + 1);
|
||||
if (str == NULL)
|
||||
return NULL;
|
||||
if (hexstr2bin(value, str, tlen)) {
|
||||
os_free(str);
|
||||
return NULL;
|
||||
}
|
||||
str[tlen] = '\0';
|
||||
*len = tlen;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
return (char *) str;
|
||||
}
|
||||
}
|
||||
|
||||
char * dup_binstr(const void *src, size_t len)
|
||||
{
|
||||
char *res;
|
||||
|
||||
if (src == NULL)
|
||||
return NULL;
|
||||
res = os_malloc(len + 1);
|
||||
if (res == NULL)
|
||||
return NULL;
|
||||
memcpy(res, src, len);
|
||||
res[len] = '\0';
|
||||
|
||||
return res;
|
||||
}
|
||||
|
114
components/wpa_supplicant/src/utils/ext_password.c
Normal file
114
components/wpa_supplicant/src/utils/ext_password.c
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* External password backend
|
||||
* Copyright (c) 2012, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "utils/includes.h"
|
||||
|
||||
#include "utils/common.h"
|
||||
#include "ext_password_i.h"
|
||||
|
||||
#ifdef CONFIG_EXT_PASSWORD_TEST
|
||||
extern struct ext_password_backend ext_password_test;
|
||||
#endif /* CONFIG_EXT_PASSWORD_TEST */
|
||||
|
||||
#ifdef CONFIG_EXT_PASSWORD
|
||||
static const struct ext_password_backend *backends[] = {
|
||||
#ifdef CONFIG_EXT_PASSWORD_TEST
|
||||
&ext_password_test,
|
||||
#endif /* CONFIG_EXT_PASSWORD_TEST */
|
||||
NULL
|
||||
};
|
||||
#endif
|
||||
|
||||
struct ext_password_data {
|
||||
const struct ext_password_backend *backend;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_EXT_PASSWORD
|
||||
struct ext_password_data * ext_password_init(const char *backend,
|
||||
const char *params)
|
||||
{
|
||||
struct ext_password_data *data;
|
||||
int i;
|
||||
|
||||
data = (struct ext_password_data *)os_zalloc(sizeof(*data));
|
||||
if (data == NULL)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; backends[i]; i++) {
|
||||
if (os_strcmp(backends[i]->name, backend) == 0) {
|
||||
data->backend = backends[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!data->backend) {
|
||||
os_free(data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
data->priv = data->backend->init(params);
|
||||
if (data->priv == NULL) {
|
||||
os_free(data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
void ext_password_deinit(struct ext_password_data *data)
|
||||
{
|
||||
if (data && data->backend && data->priv)
|
||||
data->backend->deinit(data->priv);
|
||||
os_free(data);
|
||||
}
|
||||
|
||||
|
||||
struct wpabuf * ext_password_get(struct ext_password_data *data,
|
||||
const char *name)
|
||||
{
|
||||
if (data == NULL)
|
||||
return NULL;
|
||||
return data->backend->get(data->priv, name);
|
||||
}
|
||||
#endif /* CONFIG_EXT_PASSWORD */
|
||||
|
||||
struct wpabuf * ext_password_alloc(size_t len)
|
||||
{
|
||||
struct wpabuf *buf;
|
||||
|
||||
buf = wpabuf_alloc(len);
|
||||
if (buf == NULL)
|
||||
return NULL;
|
||||
|
||||
#ifdef __linux__
|
||||
if (mlock(wpabuf_head(buf), wpabuf_len(buf)) < 0) {
|
||||
wpa_printf(MSG_ERROR, "EXT PW: mlock failed: %s",
|
||||
strerror(errno));
|
||||
}
|
||||
#endif /* __linux__ */
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_EXT_PASSWORD
|
||||
void ext_password_free(struct wpabuf *pw)
|
||||
{
|
||||
if (pw == NULL)
|
||||
return;
|
||||
os_memset(wpabuf_mhead(pw), 0, wpabuf_len(pw));
|
||||
#ifdef __linux__
|
||||
if (munlock(wpabuf_head(pw), wpabuf_len(pw)) < 0) {
|
||||
wpa_printf(MSG_ERROR, "EXT PW: munlock failed: %s",
|
||||
strerror(errno));
|
||||
}
|
||||
#endif /* __linux__ */
|
||||
wpabuf_free(pw);
|
||||
}
|
||||
#endif /* CONFIG_EXT_PASSWORD */
|
33
components/wpa_supplicant/src/utils/ext_password.h
Normal file
33
components/wpa_supplicant/src/utils/ext_password.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* External password backend
|
||||
* Copyright (c) 2012, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef EXT_PASSWORD_H
|
||||
#define EXT_PASSWORD_H
|
||||
|
||||
struct ext_password_data;
|
||||
|
||||
#ifdef CONFIG_EXT_PASSWORD
|
||||
|
||||
struct ext_password_data * ext_password_init(const char *backend,
|
||||
const char *params);
|
||||
void ext_password_deinit(struct ext_password_data *data);
|
||||
|
||||
struct wpabuf * ext_password_get(struct ext_password_data *data,
|
||||
const char *name);
|
||||
void ext_password_free(struct wpabuf *pw);
|
||||
|
||||
#else /* CONFIG_EXT_PASSWORD */
|
||||
|
||||
#define ext_password_init(b, p)
|
||||
#define ext_password_deinit(d)
|
||||
#define ext_password_get(d, n)
|
||||
#define ext_password_free(p)
|
||||
|
||||
#endif /* CONFIG_EXT_PASSWORD */
|
||||
|
||||
#endif /* EXT_PASSWORD_H */
|
23
components/wpa_supplicant/src/utils/ext_password_i.h
Normal file
23
components/wpa_supplicant/src/utils/ext_password_i.h
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* External password backend - internal definitions
|
||||
* Copyright (c) 2012, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef EXT_PASSWORD_I_H
|
||||
#define EXT_PASSWORD_I_H
|
||||
|
||||
#include "ext_password.h"
|
||||
|
||||
struct ext_password_backend {
|
||||
const char *name;
|
||||
void * (*init)(const char *params);
|
||||
void (*deinit)(void *ctx);
|
||||
struct wpabuf * (*get)(void *ctx, const char *name);
|
||||
};
|
||||
|
||||
struct wpabuf * ext_password_alloc(size_t len);
|
||||
|
||||
#endif /* EXT_PASSWORD_I_H */
|
62
components/wpa_supplicant/src/utils/includes.h
Normal file
62
components/wpa_supplicant/src/utils/includes.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* wpa_supplicant/hostapd - Default include files
|
||||
* Copyright (c) 2005-2006, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of BSD
|
||||
* license.
|
||||
*
|
||||
* See README and COPYING for more details.
|
||||
*
|
||||
* This header file is included into all C files so that commonly used header
|
||||
* files can be selected with OS specific ifdef blocks in one place instead of
|
||||
* having to have OS/C library specific selection in many files.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDES_H
|
||||
#define INCLUDES_H
|
||||
|
||||
#include "supplicant_opt.h"
|
||||
|
||||
/* Include possible build time configuration before including anything else */
|
||||
#ifndef __ets__
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#ifndef _WIN32_WCE
|
||||
#ifndef CONFIG_TI_COMPILER
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#endif /* CONFIG_TI_COMPILER */
|
||||
#include <errno.h>
|
||||
#endif /* _WIN32_WCE */
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifndef CONFIG_TI_COMPILER
|
||||
#ifndef _MSC_VER
|
||||
#include <unistd.h>
|
||||
#endif /* _MSC_VER */
|
||||
#endif /* CONFIG_TI_COMPILER */
|
||||
|
||||
#ifndef CONFIG_NATIVE_WINDOWS
|
||||
#ifndef CONFIG_TI_COMPILER
|
||||
#ifndef __vxworks
|
||||
#ifndef __SYMBIAN32__
|
||||
#endif /* __SYMBIAN32__ */
|
||||
#include <sys/time.h>
|
||||
#endif /* __vxworks */
|
||||
#endif /* CONFIG_TI_COMPILER */
|
||||
#endif /* CONFIG_NATIVE_WINDOWS */
|
||||
|
||||
#else
|
||||
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
|
||||
#endif /* !__ets__ */
|
||||
|
||||
#endif /* INCLUDES_H */
|
103
components/wpa_supplicant/src/utils/list.h
Normal file
103
components/wpa_supplicant/src/utils/list.h
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Doubly-linked list
|
||||
* Copyright (c) 2009, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of BSD
|
||||
* license.
|
||||
*
|
||||
* See README and COPYING for more details.
|
||||
*/
|
||||
|
||||
#ifndef LIST_H
|
||||
#define LIST_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/**
|
||||
* struct dl_list - Doubly-linked list
|
||||
*/
|
||||
struct dl_list {
|
||||
struct dl_list *next;
|
||||
struct dl_list *prev;
|
||||
};
|
||||
|
||||
static inline void dl_list_init(struct dl_list *list)
|
||||
{
|
||||
list->next = list;
|
||||
list->prev = list;
|
||||
}
|
||||
|
||||
static inline void dl_list_add(struct dl_list *list, struct dl_list *item)
|
||||
{
|
||||
item->next = list->next;
|
||||
item->prev = list;
|
||||
list->next->prev = item;
|
||||
list->next = item;
|
||||
}
|
||||
|
||||
static inline void dl_list_add_tail(struct dl_list *list, struct dl_list *item)
|
||||
{
|
||||
dl_list_add(list->prev, item);
|
||||
}
|
||||
|
||||
static inline void dl_list_del(struct dl_list *item)
|
||||
{
|
||||
item->next->prev = item->prev;
|
||||
item->prev->next = item->next;
|
||||
item->next = NULL;
|
||||
item->prev = NULL;
|
||||
}
|
||||
|
||||
static inline int dl_list_empty(struct dl_list *list)
|
||||
{
|
||||
return list->next == list;
|
||||
}
|
||||
|
||||
static inline unsigned int dl_list_len(struct dl_list *list)
|
||||
{
|
||||
struct dl_list *item;
|
||||
int count = 0;
|
||||
for (item = list->next; item != list; item = item->next)
|
||||
count++;
|
||||
return count;
|
||||
}
|
||||
|
||||
#ifndef offsetof
|
||||
#define offsetof(type, member) ((long) &((type *) 0)->member)
|
||||
#endif
|
||||
|
||||
#define dl_list_entry(item, type, member) \
|
||||
((type *) ((char *) item - offsetof(type, member)))
|
||||
|
||||
#define dl_list_first(list, type, member) \
|
||||
(dl_list_empty((list)) ? NULL : \
|
||||
dl_list_entry((list)->next, type, member))
|
||||
|
||||
#define dl_list_last(list, type, member) \
|
||||
(dl_list_empty((list)) ? NULL : \
|
||||
dl_list_entry((list)->prev, type, member))
|
||||
|
||||
#define dl_list_for_each(item, list, type, member) \
|
||||
for (item = dl_list_entry((list)->next, type, member); \
|
||||
&item->member != (list); \
|
||||
item = dl_list_entry(item->member.next, type, member))
|
||||
|
||||
#define dl_list_for_each_safe(item, n, list, type, member) \
|
||||
for (item = dl_list_entry((list)->next, type, member), \
|
||||
n = dl_list_entry(item->member.next, type, member); \
|
||||
&item->member != (list); \
|
||||
item = n, n = dl_list_entry(n->member.next, type, member))
|
||||
|
||||
#define dl_list_for_each_reverse(item, list, type, member) \
|
||||
for (item = dl_list_entry((list)->prev, type, member); \
|
||||
&item->member != (list); \
|
||||
item = dl_list_entry(item->member.prev, type, member))
|
||||
|
||||
#define DEFINE_DL_LIST(name) \
|
||||
struct dl_list name = { &(name), &(name) }
|
||||
|
||||
#endif /* LIST_H */
|
138
components/wpa_supplicant/src/utils/state_machine.h
Normal file
138
components/wpa_supplicant/src/utils/state_machine.h
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* wpa_supplicant/hostapd - State machine definitions
|
||||
* Copyright (c) 2002-2005, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*
|
||||
* This file includes a set of pre-processor macros that can be used to
|
||||
* implement a state machine. In addition to including this header file, each
|
||||
* file implementing a state machine must define STATE_MACHINE_DATA to be the
|
||||
* data structure including state variables (enum machine_state,
|
||||
* Boolean changed), and STATE_MACHINE_DEBUG_PREFIX to be a string that is used
|
||||
* as a prefix for all debug messages. If SM_ENTRY_MA macro is used to define
|
||||
* a group of state machines with shared data structure, STATE_MACHINE_ADDR
|
||||
* needs to be defined to point to the MAC address used in debug output.
|
||||
* SM_ENTRY_M macro can be used to define similar group of state machines
|
||||
* without this additional debug info.
|
||||
*/
|
||||
|
||||
#ifndef STATE_MACHINE_H
|
||||
#define STATE_MACHINE_H
|
||||
|
||||
/**
|
||||
* SM_STATE - Declaration of a state machine function
|
||||
* @machine: State machine name
|
||||
* @state: State machine state
|
||||
*
|
||||
* This macro is used to declare a state machine function. It is used in place
|
||||
* of a C function definition to declare functions to be run when the state is
|
||||
* entered by calling SM_ENTER or SM_ENTER_GLOBAL.
|
||||
*/
|
||||
#define SM_STATE(machine, state) \
|
||||
static void sm_ ## machine ## _ ## state ## _Enter(STATE_MACHINE_DATA *sm, \
|
||||
int global)
|
||||
|
||||
/**
|
||||
* SM_ENTRY - State machine function entry point
|
||||
* @machine: State machine name
|
||||
* @state: State machine state
|
||||
*
|
||||
* This macro is used inside each state machine function declared with
|
||||
* SM_STATE. SM_ENTRY should be in the beginning of the function body, but
|
||||
* after declaration of possible local variables. This macro prints debug
|
||||
* information about state transition and update the state machine state.
|
||||
*/
|
||||
#define SM_ENTRY(machine, state) \
|
||||
if (!global || sm->machine ## _state != machine ## _ ## state) { \
|
||||
sm->changed = TRUE; \
|
||||
wpa_printf(MSG_DEBUG, STATE_MACHINE_DEBUG_PREFIX ": " #machine \
|
||||
" entering state " #state); \
|
||||
} \
|
||||
sm->machine ## _state = machine ## _ ## state;
|
||||
|
||||
/**
|
||||
* SM_ENTRY_M - State machine function entry point for state machine group
|
||||
* @machine: State machine name
|
||||
* @_state: State machine state
|
||||
* @data: State variable prefix (full variable: prefix_state)
|
||||
*
|
||||
* This macro is like SM_ENTRY, but for state machine groups that use a shared
|
||||
* data structure for more than one state machine. Both machine and prefix
|
||||
* parameters are set to "sub-state machine" name. prefix is used to allow more
|
||||
* than one state variable to be stored in the same data structure.
|
||||
*/
|
||||
#define SM_ENTRY_M(machine, _state, data) \
|
||||
if (!global || sm->data ## _ ## state != machine ## _ ## _state) { \
|
||||
sm->changed = TRUE; \
|
||||
wpa_printf(MSG_DEBUG, STATE_MACHINE_DEBUG_PREFIX ": " \
|
||||
#machine " entering state " #_state); \
|
||||
} \
|
||||
sm->data ## _ ## state = machine ## _ ## _state;
|
||||
|
||||
/**
|
||||
* SM_ENTRY_MA - State machine function entry point for state machine group
|
||||
* @machine: State machine name
|
||||
* @_state: State machine state
|
||||
* @data: State variable prefix (full variable: prefix_state)
|
||||
*
|
||||
* This macro is like SM_ENTRY_M, but a MAC address is included in debug
|
||||
* output. STATE_MACHINE_ADDR has to be defined to point to the MAC address to
|
||||
* be included in debug.
|
||||
*/
|
||||
#define SM_ENTRY_MA(machine, _state, data) \
|
||||
if (!global || sm->data ## _ ## state != machine ## _ ## _state) { \
|
||||
sm->changed = TRUE; \
|
||||
wpa_printf(MSG_DEBUG, STATE_MACHINE_DEBUG_PREFIX ": " MACSTR " " \
|
||||
#machine " entering state " #_state"\n", \
|
||||
MAC2STR(STATE_MACHINE_ADDR)); \
|
||||
} \
|
||||
sm->data ## _ ## state = machine ## _ ## _state;
|
||||
|
||||
/**
|
||||
* SM_ENTER - Enter a new state machine state
|
||||
* @machine: State machine name
|
||||
* @state: State machine state
|
||||
*
|
||||
* This macro expands to a function call to a state machine function defined
|
||||
* with SM_STATE macro. SM_ENTER is used in a state machine step function to
|
||||
* move the state machine to a new state.
|
||||
*/
|
||||
#define SM_ENTER(machine, state) \
|
||||
sm_ ## machine ## _ ## state ## _Enter(sm, 0)
|
||||
|
||||
/**
|
||||
* SM_ENTER_GLOBAL - Enter a new state machine state based on global rule
|
||||
* @machine: State machine name
|
||||
* @state: State machine state
|
||||
*
|
||||
* This macro is like SM_ENTER, but this is used when entering a new state
|
||||
* based on a global (not specific to any particular state) rule. A separate
|
||||
* macro is used to avoid unwanted debug message floods when the same global
|
||||
* rule is forcing a state machine to remain in on state.
|
||||
*/
|
||||
#define SM_ENTER_GLOBAL(machine, state) \
|
||||
sm_ ## machine ## _ ## state ## _Enter(sm, 1)
|
||||
|
||||
/**
|
||||
* SM_STEP - Declaration of a state machine step function
|
||||
* @machine: State machine name
|
||||
*
|
||||
* This macro is used to declare a state machine step function. It is used in
|
||||
* place of a C function definition to declare a function that is used to move
|
||||
* state machine to a new state based on state variables. This function uses
|
||||
* SM_ENTER and SM_ENTER_GLOBAL macros to enter new state.
|
||||
*/
|
||||
#define SM_STEP(machine) \
|
||||
static void sm_ ## machine ## _Step(STATE_MACHINE_DATA *sm)
|
||||
|
||||
/**
|
||||
* SM_STEP_RUN - Call the state machine step function
|
||||
* @machine: State machine name
|
||||
*
|
||||
* This macro expands to a function call to a state machine step function
|
||||
* defined with SM_STEP macro.
|
||||
*/
|
||||
#define SM_STEP_RUN(machine) sm_ ## machine ## _Step(sm)
|
||||
|
||||
#endif /* STATE_MACHINE_H */
|
71
components/wpa_supplicant/src/utils/uuid.c
Normal file
71
components/wpa_supplicant/src/utils/uuid.c
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Universally Unique IDentifier (UUID)
|
||||
* Copyright (c) 2008, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "utils/includes.h"
|
||||
|
||||
#include "utils/common.h"
|
||||
#include "utils/uuid.h"
|
||||
|
||||
int uuid_str2bin(const char *str, u8 *bin)
|
||||
{
|
||||
const char *pos;
|
||||
u8 *opos;
|
||||
|
||||
pos = str;
|
||||
opos = bin;
|
||||
|
||||
if (hexstr2bin(pos, opos, 4))
|
||||
return -1;
|
||||
pos += 8;
|
||||
opos += 4;
|
||||
|
||||
if (*pos++ != '-' || hexstr2bin(pos, opos, 2))
|
||||
return -1;
|
||||
pos += 4;
|
||||
opos += 2;
|
||||
|
||||
if (*pos++ != '-' || hexstr2bin(pos, opos, 2))
|
||||
return -1;
|
||||
pos += 4;
|
||||
opos += 2;
|
||||
|
||||
if (*pos++ != '-' || hexstr2bin(pos, opos, 2))
|
||||
return -1;
|
||||
pos += 4;
|
||||
opos += 2;
|
||||
|
||||
if (*pos++ != '-' || hexstr2bin(pos, opos, 6))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uuid_bin2str(const u8 *bin, char *str, size_t max_len)
|
||||
{
|
||||
int len;
|
||||
len = snprintf(str, max_len, "%02x%02x%02x%02x-%02x%02x-%02x%02x-"
|
||||
"%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||
bin[0], bin[1], bin[2], bin[3],
|
||||
bin[4], bin[5], bin[6], bin[7],
|
||||
bin[8], bin[9], bin[10], bin[11],
|
||||
bin[12], bin[13], bin[14], bin[15]);
|
||||
if (len < 0 || (size_t) len >= max_len)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int is_nil_uuid(const u8 *uuid)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < UUID_LEN; i++)
|
||||
if (uuid[i])
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
18
components/wpa_supplicant/src/utils/uuid.h
Normal file
18
components/wpa_supplicant/src/utils/uuid.h
Normal file
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Universally Unique IDentifier (UUID)
|
||||
* Copyright (c) 2008, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef UUID_H
|
||||
#define UUID_H
|
||||
|
||||
#define UUID_LEN 16
|
||||
|
||||
int uuid_str2bin(const char *str, u8 *bin);
|
||||
int uuid_bin2str(const u8 *bin, char *str, size_t max_len);
|
||||
int is_nil_uuid(const u8 *uuid);
|
||||
|
||||
#endif /* UUID_H */
|
114
components/wpa_supplicant/src/utils/wpa_debug.c
Normal file
114
components/wpa_supplicant/src/utils/wpa_debug.c
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* wpa_supplicant/hostapd / Debug prints
|
||||
* Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of BSD
|
||||
* license.
|
||||
*
|
||||
* See README and COPYING for more details.
|
||||
*/
|
||||
#ifdef ESP_SUPPLICANT
|
||||
#include "utils/includes.h"
|
||||
#include "utils/common.h"
|
||||
#include "utils/wpa_debug.h"
|
||||
|
||||
static inline int _wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len, int uppercase)
|
||||
{
|
||||
size_t i;
|
||||
char *pos = buf, *end = buf + buf_size;
|
||||
int ret;
|
||||
|
||||
if (buf_size == 0)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
ret = snprintf(pos, end - pos, uppercase? "%02X":"%02x", data[i]);
|
||||
if (ret < 0 || ret >= end - pos) {
|
||||
end[-1] = '\0';
|
||||
return pos - buf;
|
||||
}
|
||||
pos += ret;
|
||||
}
|
||||
end[-1]='\0';
|
||||
return pos - buf;
|
||||
}
|
||||
|
||||
int wpa_snprintf_hex_uppercase(char *buf, size_t buf_size, const u8 *data, size_t len)
|
||||
{
|
||||
return _wpa_snprintf_hex(buf, buf_size, data, len, 1);
|
||||
}
|
||||
|
||||
int wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len)
|
||||
{
|
||||
return _wpa_snprintf_hex(buf, buf_size, data, len, 0);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_PRINT
|
||||
void wpa_dump_mem(char* desc, uint8_t *addr, uint16_t len)
|
||||
{
|
||||
wpa_printf(MSG_DEBUG, "%s\n", desc);
|
||||
if (addr){
|
||||
uint16_t i=0;
|
||||
for (i=0; i<len; i++){
|
||||
if (i%16==0) wpa_printf(MSG_DEBUG, "\n");
|
||||
wpa_printf(MSG_DEBUG, "%02x ", addr[i]);
|
||||
}
|
||||
wpa_printf(MSG_DEBUG, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
void wpa_debug_print_timestamp(void)
|
||||
{
|
||||
#ifdef DEBUG_PRINT
|
||||
struct os_time tv;
|
||||
os_get_time(&tv);
|
||||
wpa_printf(MSG_DEBUG, "%ld.%06u: ", (long) tv.sec, (unsigned int) tv.usec);
|
||||
#endif
|
||||
}
|
||||
|
||||
void wpa_hexdump(int level, const char *title, const u8 *buf, size_t len)
|
||||
{
|
||||
#ifdef DEBUG_PRINT
|
||||
size_t i;
|
||||
|
||||
if (level < MSG_MSGDUMP)
|
||||
return;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "%s - hexdump(len=%lu):\n", title, (unsigned long) len);
|
||||
if (buf == NULL) {
|
||||
wpa_printf(MSG_DEBUG, " [NULL]\n");
|
||||
} else {
|
||||
for (i = 0; i < len; i++) {
|
||||
wpa_printf(MSG_DEBUG, " %02x", buf[i]);
|
||||
if((i+1) % 16 == 0)
|
||||
wpa_printf(MSG_DEBUG, "\n");
|
||||
}
|
||||
}
|
||||
wpa_printf(MSG_DEBUG, "\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
void wpa_hexdump_key(int level, const char *title, const u8 *buf, size_t len)
|
||||
{
|
||||
wpa_hexdump(level, title, buf, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
int eloop_cancel_timeout(eloop_timeout_handler handler,
|
||||
void *eloop_data, void *user_data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int eloop_register_timeout(unsigned int secs, unsigned int usecs,
|
||||
eloop_timeout_handler handler,
|
||||
void *eloop_data, void *user_data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif // ESP_SUPPLICANT
|
||||
|
300
components/wpa_supplicant/src/utils/wpabuf.c
Normal file
300
components/wpa_supplicant/src/utils/wpabuf.c
Normal file
@@ -0,0 +1,300 @@
|
||||
/*
|
||||
* Dynamic data buffer
|
||||
* Copyright (c) 2007-2009, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of BSD
|
||||
* license.
|
||||
*
|
||||
* See README and COPYING for more details.
|
||||
*/
|
||||
|
||||
#include "utils/includes.h"
|
||||
|
||||
#include "utils/common.h"
|
||||
#include "utils/wpabuf.h"
|
||||
#include "stdio.h"
|
||||
#include "stdarg.h"
|
||||
|
||||
#ifdef WPA_TRACE
|
||||
#define WPABUF_MAGIC 0x51a974e3
|
||||
|
||||
struct wpabuf_trace {
|
||||
unsigned int magic;
|
||||
};
|
||||
|
||||
static struct wpabuf_trace * wpabuf_get_trace(const struct wpabuf *buf)
|
||||
{
|
||||
return (struct wpabuf_trace *)
|
||||
((const u8 *) buf - sizeof(struct wpabuf_trace));
|
||||
}
|
||||
#endif /* WPA_TRACE */
|
||||
|
||||
|
||||
static void wpabuf_overflow(const struct wpabuf *buf, size_t len)
|
||||
{
|
||||
#ifdef WPA_TRACE
|
||||
struct wpabuf_trace *trace = wpabuf_get_trace(buf);
|
||||
if (trace->magic != WPABUF_MAGIC) {
|
||||
wpa_printf( MSG_ERROR, "wpabuf: invalid magic %x",
|
||||
trace->magic);
|
||||
}
|
||||
#endif /* WPA_TRACE */
|
||||
wpa_printf( MSG_ERROR, "wpabuf %p (size=%lu used=%lu) overflow len=%lu",
|
||||
buf, (unsigned long) buf->size, (unsigned long) buf->used,
|
||||
(unsigned long) len);
|
||||
}
|
||||
|
||||
|
||||
int wpabuf_resize(struct wpabuf **_buf, size_t add_len)
|
||||
{
|
||||
struct wpabuf *buf = *_buf;
|
||||
#ifdef WPA_TRACE
|
||||
struct wpabuf_trace *trace;
|
||||
#endif /* WPA_TRACE */
|
||||
|
||||
if (buf == NULL) {
|
||||
*_buf = wpabuf_alloc(add_len);
|
||||
return *_buf == NULL ? -1 : 0;
|
||||
}
|
||||
|
||||
#ifdef WPA_TRACE
|
||||
trace = wpabuf_get_trace(buf);
|
||||
if (trace->magic != WPABUF_MAGIC) {
|
||||
wpa_printf( MSG_ERROR, "wpabuf: invalid magic %x",
|
||||
trace->magic);
|
||||
abort();
|
||||
}
|
||||
#endif /* WPA_TRACE */
|
||||
|
||||
if (buf->used + add_len > buf->size) {
|
||||
unsigned char *nbuf;
|
||||
if (buf->ext_data) {
|
||||
nbuf = (unsigned char*)os_realloc(buf->ext_data, buf->used + add_len);
|
||||
if (nbuf == NULL)
|
||||
return -1;
|
||||
memset(nbuf + buf->used, 0, add_len);
|
||||
buf->ext_data = nbuf;
|
||||
} else {
|
||||
#ifdef WPA_TRACE
|
||||
nbuf = os_realloc(trace, sizeof(struct wpabuf_trace) +
|
||||
sizeof(struct wpabuf) +
|
||||
buf->used + add_len);
|
||||
if (nbuf == NULL)
|
||||
return -1;
|
||||
trace = (struct wpabuf_trace *) nbuf;
|
||||
buf = (struct wpabuf *) (trace + 1);
|
||||
memset(nbuf + sizeof(struct wpabuf_trace) +
|
||||
sizeof(struct wpabuf) + buf->used, 0,
|
||||
add_len);
|
||||
#else /* WPA_TRACE */
|
||||
nbuf = (unsigned char*)os_realloc(buf, sizeof(struct wpabuf) +
|
||||
buf->used + add_len);
|
||||
if (nbuf == NULL)
|
||||
return -1;
|
||||
buf = (struct wpabuf *) nbuf;
|
||||
memset(nbuf + sizeof(struct wpabuf) + buf->used, 0,
|
||||
add_len);
|
||||
#endif /* WPA_TRACE */
|
||||
*_buf = buf;
|
||||
}
|
||||
buf->size = buf->used + add_len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* wpabuf_alloc - Allocate a wpabuf of the given size
|
||||
* @len: Length for the allocated buffer
|
||||
* Returns: Buffer to the allocated wpabuf or %NULL on failure
|
||||
*/
|
||||
struct wpabuf * wpabuf_alloc(size_t len)
|
||||
{
|
||||
#ifdef WPA_TRACE
|
||||
struct wpabuf_trace *trace = os_zalloc(sizeof(struct wpabuf_trace) +
|
||||
sizeof(struct wpabuf) + len);
|
||||
struct wpabuf *buf;
|
||||
if (trace == NULL)
|
||||
return NULL;
|
||||
trace->magic = WPABUF_MAGIC;
|
||||
buf = (struct wpabuf *) (trace + 1);
|
||||
#else /* WPA_TRACE */
|
||||
struct wpabuf *buf = (struct wpabuf *)os_zalloc(sizeof(struct wpabuf) + len);
|
||||
if (buf == NULL)
|
||||
return NULL;
|
||||
#endif /* WPA_TRACE */
|
||||
|
||||
buf->size = len;
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
struct wpabuf * wpabuf_alloc_ext_data(u8 *data, size_t len)
|
||||
{
|
||||
#ifdef WPA_TRACE
|
||||
struct wpabuf_trace *trace = os_zalloc(sizeof(struct wpabuf_trace) +
|
||||
sizeof(struct wpabuf));
|
||||
struct wpabuf *buf;
|
||||
if (trace == NULL)
|
||||
return NULL;
|
||||
trace->magic = WPABUF_MAGIC;
|
||||
buf = (struct wpabuf *) (trace + 1);
|
||||
#else /* WPA_TRACE */
|
||||
struct wpabuf *buf = (struct wpabuf *)os_zalloc(sizeof(struct wpabuf));
|
||||
if (buf == NULL)
|
||||
return NULL;
|
||||
#endif /* WPA_TRACE */
|
||||
|
||||
buf->size = len;
|
||||
buf->used = len;
|
||||
buf->ext_data = data;
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
struct wpabuf * wpabuf_alloc_copy(const void *data, size_t len)
|
||||
{
|
||||
struct wpabuf *buf = wpabuf_alloc(len);
|
||||
if (buf)
|
||||
wpabuf_put_data(buf, data, len);
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
struct wpabuf * wpabuf_dup(const struct wpabuf *src)
|
||||
{
|
||||
struct wpabuf *buf = wpabuf_alloc(wpabuf_len(src));
|
||||
if (buf)
|
||||
wpabuf_put_data(buf, wpabuf_head(src), wpabuf_len(src));
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* wpabuf_free - Free a wpabuf
|
||||
* @buf: wpabuf buffer
|
||||
*/
|
||||
void wpabuf_free(struct wpabuf *buf)
|
||||
{
|
||||
#ifdef WPA_TRACE
|
||||
struct wpabuf_trace *trace;
|
||||
if (buf == NULL)
|
||||
return;
|
||||
trace = wpabuf_get_trace(buf);
|
||||
if (trace->magic != WPABUF_MAGIC) {
|
||||
wpa_printf( MSG_ERROR, "wpabuf_free: invalid magic %x",
|
||||
trace->magic);
|
||||
abort();
|
||||
}
|
||||
os_free(buf->ext_data);
|
||||
os_free(trace);
|
||||
#else /* WPA_TRACE */
|
||||
if (buf == NULL)
|
||||
return;
|
||||
os_free(buf->ext_data);
|
||||
os_free(buf);
|
||||
#endif /* WPA_TRACE */
|
||||
}
|
||||
|
||||
|
||||
void * wpabuf_put(struct wpabuf *buf, size_t len)
|
||||
{
|
||||
void *tmp = wpabuf_mhead_u8(buf) + wpabuf_len(buf);
|
||||
buf->used += len;
|
||||
if (buf->used > buf->size) {
|
||||
wpabuf_overflow(buf, len);
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* wpabuf_concat - Concatenate two buffers into a newly allocated one
|
||||
* @a: First buffer
|
||||
* @b: Second buffer
|
||||
* Returns: wpabuf with concatenated a + b data or %NULL on failure
|
||||
*
|
||||
* Both buffers a and b will be freed regardless of the return value. Input
|
||||
* buffers can be %NULL which is interpreted as an empty buffer.
|
||||
*/
|
||||
struct wpabuf * wpabuf_concat(struct wpabuf *a, struct wpabuf *b)
|
||||
{
|
||||
struct wpabuf *n = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
if (b == NULL)
|
||||
return a;
|
||||
|
||||
if (a)
|
||||
len += wpabuf_len(a);
|
||||
if (b)
|
||||
len += wpabuf_len(b);
|
||||
|
||||
n = wpabuf_alloc(len);
|
||||
if (n) {
|
||||
if (a)
|
||||
wpabuf_put_buf(n, a);
|
||||
if (b)
|
||||
wpabuf_put_buf(n, b);
|
||||
}
|
||||
|
||||
wpabuf_free(a);
|
||||
wpabuf_free(b);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* wpabuf_zeropad - Pad buffer with 0x00 octets (prefix) to specified length
|
||||
* @buf: Buffer to be padded
|
||||
* @len: Length for the padded buffer
|
||||
* Returns: wpabuf padded to len octets or %NULL on failure
|
||||
*
|
||||
* If buf is longer than len octets or of same size, it will be returned as-is.
|
||||
* Otherwise a new buffer is allocated and prefixed with 0x00 octets followed
|
||||
* by the source data. The source buffer will be freed on error, i.e., caller
|
||||
* will only be responsible on freeing the returned buffer. If buf is %NULL,
|
||||
* %NULL will be returned.
|
||||
*/
|
||||
struct wpabuf * wpabuf_zeropad(struct wpabuf *buf, size_t len)
|
||||
{
|
||||
struct wpabuf *ret;
|
||||
size_t blen;
|
||||
|
||||
if (buf == NULL)
|
||||
return NULL;
|
||||
|
||||
blen = wpabuf_len(buf);
|
||||
if (blen >= len)
|
||||
return buf;
|
||||
|
||||
ret = wpabuf_alloc(len);
|
||||
if (ret) {
|
||||
memset(wpabuf_put(ret, len - blen), 0, len - blen);
|
||||
wpabuf_put_buf(ret, buf);
|
||||
}
|
||||
wpabuf_free(buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void wpabuf_printf(struct wpabuf *buf, char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
void *tmp = wpabuf_mhead_u8(buf) + wpabuf_len(buf);
|
||||
int res;
|
||||
|
||||
va_start(ap, fmt);
|
||||
res = vsnprintf(tmp, buf->size - buf->used, fmt, ap);
|
||||
va_end(ap);
|
||||
if (res < 0 || (size_t) res >= buf->size - buf->used)
|
||||
wpabuf_overflow(buf, res);
|
||||
buf->used += res;
|
||||
}
|
Reference in New Issue
Block a user