remove dos style newlines

This commit is contained in:
Andreas Schultz
2016-02-05 17:38:49 +01:00
parent 6e3ce9ed74
commit 8c20d78941
104 changed files with 21740 additions and 21740 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,54 +1,54 @@
#ifndef __CAPWAP_HASH_HEADER__
#define __CAPWAP_HASH_HEADER__
typedef unsigned long (*capwap_hash_item_gethash)(const void* key, unsigned long hashsize);
typedef const void* (*capwap_hash_item_getkey)(const void* data);
typedef int (*capwap_hash_item_cmp)(const void* key1, const void* key2);
typedef void (*capwap_hash_item_free)(void* data);
#define HASH_BREAK 0
#define HASH_CONTINUE 1
#define HASH_DELETE_AND_BREAK 2
#define HASH_DELETE_AND_CONTINUE 3
typedef int (*capwap_hash_item_foreach)(void* data, void* param);
struct capwap_hash_item {
void* data;
int height;
struct capwap_hash_item* parent;
struct capwap_hash_item* left;
struct capwap_hash_item* right;
struct capwap_hash_item* removenext;
};
struct capwap_hash {
struct capwap_hash_item** items;
unsigned long hashsize;
/* */
unsigned long count;
/* */
struct capwap_hash_item* removeitems;
/* Callback functions */
capwap_hash_item_gethash item_gethash;
capwap_hash_item_getkey item_getkey;
capwap_hash_item_cmp item_cmp;
capwap_hash_item_free item_free;
};
struct capwap_hash* capwap_hash_create(unsigned long hashsize);
void capwap_hash_free(struct capwap_hash* hash);
void capwap_hash_add(struct capwap_hash* hash, void* data);
void capwap_hash_delete(struct capwap_hash* hash, const void* key);
void capwap_hash_deleteall(struct capwap_hash* hash);
void* capwap_hash_search(struct capwap_hash* hash, const void* key);
void capwap_hash_foreach(struct capwap_hash* hash, capwap_hash_item_foreach item_foreach, void* param);
#endif /* __CAPWAP_HASH_HEADER__ */
#ifndef __CAPWAP_HASH_HEADER__
#define __CAPWAP_HASH_HEADER__
typedef unsigned long (*capwap_hash_item_gethash)(const void* key, unsigned long hashsize);
typedef const void* (*capwap_hash_item_getkey)(const void* data);
typedef int (*capwap_hash_item_cmp)(const void* key1, const void* key2);
typedef void (*capwap_hash_item_free)(void* data);
#define HASH_BREAK 0
#define HASH_CONTINUE 1
#define HASH_DELETE_AND_BREAK 2
#define HASH_DELETE_AND_CONTINUE 3
typedef int (*capwap_hash_item_foreach)(void* data, void* param);
struct capwap_hash_item {
void* data;
int height;
struct capwap_hash_item* parent;
struct capwap_hash_item* left;
struct capwap_hash_item* right;
struct capwap_hash_item* removenext;
};
struct capwap_hash {
struct capwap_hash_item** items;
unsigned long hashsize;
/* */
unsigned long count;
/* */
struct capwap_hash_item* removeitems;
/* Callback functions */
capwap_hash_item_gethash item_gethash;
capwap_hash_item_getkey item_getkey;
capwap_hash_item_cmp item_cmp;
capwap_hash_item_free item_free;
};
struct capwap_hash* capwap_hash_create(unsigned long hashsize);
void capwap_hash_free(struct capwap_hash* hash);
void capwap_hash_add(struct capwap_hash* hash, void* data);
void capwap_hash_delete(struct capwap_hash* hash, const void* key);
void capwap_hash_deleteall(struct capwap_hash* hash);
void* capwap_hash_search(struct capwap_hash* hash, const void* key);
void capwap_hash_foreach(struct capwap_hash* hash, capwap_hash_item_foreach item_foreach, void* param);
#endif /* __CAPWAP_HASH_HEADER__ */

View File

@ -1,236 +1,236 @@
#ifndef __CAPWAP_RFC_HEADER__
#define __CAPWAP_RFC_HEADER__
#include <inttypes.h>
#ifndef STRUCT_PACKED
#define STRUCT_PACKED __attribute__((__packed__))
#endif
#define CAPWAP_PROTOCOL_VERSION 0
#define CAPWAP_MTU_DEFAULT 1400
#define CAPWAP_DONT_FRAGMENT 0
/* Capwap preamble */
#define CAPWAP_PREAMBLE_HEADER 0
#define CAPWAP_PREAMBLE_DTLS_HEADER 1
struct capwap_preamble {
#ifdef CAPWAP_BIG_ENDIAN
uint8_t version : 4;
uint8_t type : 4;
#else
uint8_t type : 4;
uint8_t version : 4;
#endif
} STRUCT_PACKED;
/* Capwap DTLS header */
struct capwap_dtls_header {
struct capwap_preamble preamble;
uint8_t reserved1;
uint8_t reserved2;
uint8_t reserved3;
} STRUCT_PACKED;
/* Capwap header: 8 (header) + 12 (radio mac) + 256 (wireless info) */
#define CAPWAP_HEADER_MAX_SIZE 276
struct capwap_header {
struct capwap_preamble preamble;
#ifdef CAPWAP_BIG_ENDIAN
uint16_t hlen : 5;
uint16_t rid : 5;
uint16_t wbid : 5;
uint16_t flag_t : 1;
uint8_t flag_f : 1;
uint8_t flag_l : 1;
uint8_t flag_w : 1;
uint8_t flag_m : 1;
uint8_t flag_k : 1;
uint8_t flag_res : 3;
#else
uint16_t _rid_hi : 3;
uint16_t hlen : 5;
uint16_t flag_t : 1;
uint16_t wbid : 5;
uint16_t _rid_lo : 2;
uint8_t flag_res : 3;
uint8_t flag_k : 1;
uint8_t flag_m : 1;
uint8_t flag_w : 1;
uint8_t flag_l : 1;
uint8_t flag_f : 1;
#endif
uint16_t frag_id;
uint16_t frag_off; /* Only first 13 bit */
} STRUCT_PACKED;
#define FRAGMENT_OFFSET_MASK 0xfff8
/* Mac Address */
struct capwap_mac_address {
uint8_t length;
uint8_t address[0];
} STRUCT_PACKED;
/* Wireless Information */
struct capwap_wireless_information {
uint8_t length;
uint8_t data[0];
} STRUCT_PACKED;
/* IEEE802.11 Wireless Information */
struct capwap_ieee80211_frame_info {
uint8_t rssi;
uint8_t snr;
uint16_t rate;
} STRUCT_PACKED;
/* Message element */
struct capwap_message_element {
uint16_t type;
uint16_t length;
uint8_t data[0];
} STRUCT_PACKED;
/* Control Message Type */
#define CAPWAP_FIRST_MESSAGE_TYPE 1
#define CAPWAP_DISCOVERY_REQUEST 1
#define CAPWAP_DISCOVERY_RESPONSE 2
#define CAPWAP_JOIN_REQUEST 3
#define CAPWAP_JOIN_RESPONSE 4
#define CAPWAP_CONFIGURATION_STATUS_REQUEST 5
#define CAPWAP_CONFIGURATION_STATUS_RESPONSE 6
#define CAPWAP_CONFIGURATION_UPDATE_REQUEST 7
#define CAPWAP_CONFIGURATION_UPDATE_RESPONSE 8
#define CAPWAP_WTP_EVENT_REQUEST 9
#define CAPWAP_WTP_EVENT_RESPONSE 10
#define CAPWAP_CHANGE_STATE_EVENT_REQUEST 11
#define CAPWAP_CHANGE_STATE_EVENT_RESPONSE 12
#define CAPWAP_ECHO_REQUEST 13
#define CAPWAP_ECHO_RESPONSE 14
#define CAPWAP_IMAGE_DATA_REQUEST 15
#define CAPWAP_IMAGE_DATA_RESPONSE 16
#define CAPWAP_RESET_REQUEST 17
#define CAPWAP_RESET_RESPONSE 18
#define CAPWAP_PRIMARY_DISCOVERY_REQUEST 19
#define CAPWAP_PRIMARY_DISCOVERY_RESPONSE 20
#define CAPWAP_DATA_TRANSFER_REQUEST 21
#define CAPWAP_DATA_TRANSFER_RESPONSE 22
#define CAPWAP_CLEAR_CONFIGURATION_REQUEST 23
#define CAPWAP_CLEAR_CONFIGURATION_RESPONSE 24
#define CAPWAP_STATION_CONFIGURATION_REQUEST 25
#define CAPWAP_STATION_CONFIGURATION_RESPONSE 26
#define CAPWAP_LAST_MESSAGE_TYPE 26
#define CAPWAP_VALID_MESSAGE_TYPE(x) (((x) >= CAPWAP_FIRST_MESSAGE_TYPE) && ((x) <= CAPWAP_LAST_MESSAGE_TYPE))
#define CAPWAP_IEEE80211_FIRST_MESSAGE_TYPE 3398913
#define CAPWAP_IEEE80211_WLAN_CONFIGURATION_REQUEST 3398913
#define CAPWAP_IEEE80211_WLAN_CONFIGURATION_RESPONSE 3398914
#define CAPWAP_IEEE80211_LAST_MESSAGE_TYPE 3398914
#define CAPWAP_VALID_IEEE80211_MESSAGE_TYPE(x) (((x) >= CAPWAP_IEEE80211_FIRST_MESSAGE_TYPE) && ((x) <= CAPWAP_IEEE80211_LAST_MESSAGE_TYPE))
/* Control Message */
#define CAPWAP_CONTROL_MESSAGE_MIN_LENGTH 3
struct capwap_control_message {
uint32_t type;
uint8_t seq;
uint16_t length;
uint8_t flags;
uint8_t elements[0];
} STRUCT_PACKED;
/* Data Message Keep-Alive*/
#define CAPWAP_DATA_MESSAGE_KEEPALIVE_MIN_LENGTH 2
struct capwap_data_message {
uint16_t length;
uint8_t elements[0];
} STRUCT_PACKED;
/* Capwap dtls header helper */
#define GET_DTLS_BODY(x) (void*)(((uint8_t*)(x)) + sizeof(struct capwap_dtls_header))
/* Capwap header helper */
#define GET_VERSION_HEADER(x) ((x)->preamble.version)
#define SET_VERSION_HEADER(x, y) ((x)->preamble.version = (uint8_t)(y))
#define GET_TYPE_HEADER(x) ((x)->preamble.type)
#define SET_TYPE_HEADER(x, y) ((x)->preamble.type = (uint8_t)(y))
#define GET_HLEN_HEADER(x) ((x)->hlen)
#define SET_HLEN_HEADER(x, y) ((x)->hlen = (uint16_t)(y))
#ifdef CAPWAP_BIG_ENDIAN
#define GET_RID_HEADER(x) ((uint8_t)((x)->rid))
#define SET_RID_HEADER(x, y) ((x)->rid = (uint16_t)(y))
#else
#define GET_RID_HEADER(x) ((uint8_t)((uint16_t)((x)->_rid_hi << 2 | (x)->_rid_lo)))
#define SET_RID_HEADER(x, y) ({ (x)->_rid_hi = (uint16_t)((y) >> 2); (x)->_rid_lo = (uint16_t)((y) & 0x0003); })
#endif
#define GET_WBID_HEADER(x) ((x)->wbid)
#define SET_WBID_HEADER(x, y) ((x)->wbid = (uint16_t)(y))
#define IS_FLAG_T_HEADER(x) ((x)->flag_t)
#define SET_FLAG_T_HEADER(x, y) ((x)->flag_t = ((y) ? 1 : 0))
#define IS_FLAG_F_HEADER(x) ((x)->flag_f)
#define SET_FLAG_F_HEADER(x, y) ((x)->flag_f = ((y) ? 1 : 0))
#define IS_FLAG_L_HEADER(x) ((x)->flag_l)
#define SET_FLAG_L_HEADER(x, y) ((x)->flag_l = ((y) ? 1 : 0))
#define IS_FLAG_W_HEADER(x) ((x)->flag_w)
#define SET_FLAG_W_HEADER(x, y) ((x)->flag_w = ((y) ? 1 : 0))
#define IS_FLAG_M_HEADER(x) ((x)->flag_m)
#define SET_FLAG_M_HEADER(x, y) ((x)->flag_m = ((y) ? 1 : 0))
#define IS_FLAG_K_HEADER(x) ((x)->flag_k)
#define SET_FLAG_K_HEADER(x, y) ((x)->flag_k = ((y) ? 1 : 0))
#define GET_FRAGMENT_ID_HEADER(x) (ntohs((x)->frag_id))
#define SET_FRAGMENT_ID_HEADER(x, y) ((x)->frag_id = htons((uint16_t)(y)))
#define GET_FRAGMENT_OFFSET_HEADER(x) (ntohs((x)->frag_off) & FRAGMENT_OFFSET_MASK)
#define SET_FRAGMENT_OFFSET_HEADER(x, y) ((x)->frag_off &= ~FRAGMENT_OFFSET_MASK, (x)->frag_off |= htons((uint16_t)(y) & FRAGMENT_OFFSET_MASK))
#define GET_RADIO_MAC_ADDRESS_STRUCT(x) ((struct capwap_mac_address*)(((uint8_t*)(x)) + sizeof(struct capwap_header)))
#define GET_WIRELESS_INFORMATION_STRUCT(x) ((struct capwap_wireless_information*)(((uint8_t*)(x)) + sizeof(struct capwap_header) + (IS_FLAG_M_HEADER(x) ? (((GET_RADIO_MAC_ADDRESS_STRUCT(x)->length + sizeof(struct capwap_mac_address)) + 3) / 4) * 4 : 0)))
#define GET_PAYLOAD_HEADER(x) ((void*)(((uint8_t*)(x)) + GET_HLEN_HEADER(x) * 4))
#define IS_SEQUENCE_SMALLER(s1, s2) (((((s1) < (s2)) && (((s2) - (s1)) < 128)) || (((s1) > (s2)) && (((s1) - (s2)) > 128))) ? 1 : 0)
/* */
#define MACADDRESS_NONE_LENGTH 0
/* */
#define MACADDRESS_EUI48_LENGTH 6
struct capwap_macaddress_eui48 {
uint8_t macaddress[MACADDRESS_EUI48_LENGTH];
} STRUCT_PACKED;
/* */
#define MACADDRESS_EUI64_LENGTH 8
struct capwap_macaddress_eui64 {
uint8_t macaddress[MACADDRESS_EUI64_LENGTH];
} STRUCT_PACKED;
#define IS_VALID_MACADDRESS_LENGTH(x) ((x == MACADDRESS_EUI48_LENGTH) || (x == MACADDRESS_EUI64_LENGTH))
#define RADIOID_MAX_COUNT 31
#define IS_VALID_RADIOID(x) ((x >= 1) && (x <= RADIOID_MAX_COUNT))
#define WLANID_MAX_COUNT 16
#define IS_VALID_WLANID(x) ((x >= 1) && (x <= WLANID_MAX_COUNT))
/* Standard message elements 1 -> 52 (1 - 1023) */
#define CAPWAP_MESSAGE_ELEMENTS_START 1
#define CAPWAP_MESSAGE_ELEMENTS_STOP 53
#define CAPWAP_MESSAGE_ELEMENTS_COUNT ((CAPWAP_MESSAGE_ELEMENTS_STOP - CAPWAP_MESSAGE_ELEMENTS_START) + 1)
#define IS_MESSAGE_ELEMENTS(x) (((x >= CAPWAP_MESSAGE_ELEMENTS_START) && (x <= CAPWAP_MESSAGE_ELEMENTS_STOP)) ? 1 : 0)
/* 802.11 message elements 1024 -> 1024 (1024 - 2047) */
#define CAPWAP_80211_MESSAGE_ELEMENTS_START 1024
#define CAPWAP_80211_MESSAGE_ELEMENTS_STOP 1048
#define CAPWAP_80211_MESSAGE_ELEMENTS_COUNT ((CAPWAP_80211_MESSAGE_ELEMENTS_STOP - CAPWAP_80211_MESSAGE_ELEMENTS_START) + 1)
#define IS_80211_MESSAGE_ELEMENTS(x) (((x >= CAPWAP_80211_MESSAGE_ELEMENTS_START) && (x <= CAPWAP_80211_MESSAGE_ELEMENTS_STOP)) ? 1 : 0)
/* */
#define IS_VALID_MESSAGE_ELEMENTS(x) (IS_MESSAGE_ELEMENTS(x) || IS_80211_MESSAGE_ELEMENTS(x))
#endif /* __CAPWAP_RFC_HEADER__ */
#ifndef __CAPWAP_RFC_HEADER__
#define __CAPWAP_RFC_HEADER__
#include <inttypes.h>
#ifndef STRUCT_PACKED
#define STRUCT_PACKED __attribute__((__packed__))
#endif
#define CAPWAP_PROTOCOL_VERSION 0
#define CAPWAP_MTU_DEFAULT 1400
#define CAPWAP_DONT_FRAGMENT 0
/* Capwap preamble */
#define CAPWAP_PREAMBLE_HEADER 0
#define CAPWAP_PREAMBLE_DTLS_HEADER 1
struct capwap_preamble {
#ifdef CAPWAP_BIG_ENDIAN
uint8_t version : 4;
uint8_t type : 4;
#else
uint8_t type : 4;
uint8_t version : 4;
#endif
} STRUCT_PACKED;
/* Capwap DTLS header */
struct capwap_dtls_header {
struct capwap_preamble preamble;
uint8_t reserved1;
uint8_t reserved2;
uint8_t reserved3;
} STRUCT_PACKED;
/* Capwap header: 8 (header) + 12 (radio mac) + 256 (wireless info) */
#define CAPWAP_HEADER_MAX_SIZE 276
struct capwap_header {
struct capwap_preamble preamble;
#ifdef CAPWAP_BIG_ENDIAN
uint16_t hlen : 5;
uint16_t rid : 5;
uint16_t wbid : 5;
uint16_t flag_t : 1;
uint8_t flag_f : 1;
uint8_t flag_l : 1;
uint8_t flag_w : 1;
uint8_t flag_m : 1;
uint8_t flag_k : 1;
uint8_t flag_res : 3;
#else
uint16_t _rid_hi : 3;
uint16_t hlen : 5;
uint16_t flag_t : 1;
uint16_t wbid : 5;
uint16_t _rid_lo : 2;
uint8_t flag_res : 3;
uint8_t flag_k : 1;
uint8_t flag_m : 1;
uint8_t flag_w : 1;
uint8_t flag_l : 1;
uint8_t flag_f : 1;
#endif
uint16_t frag_id;
uint16_t frag_off; /* Only first 13 bit */
} STRUCT_PACKED;
#define FRAGMENT_OFFSET_MASK 0xfff8
/* Mac Address */
struct capwap_mac_address {
uint8_t length;
uint8_t address[0];
} STRUCT_PACKED;
/* Wireless Information */
struct capwap_wireless_information {
uint8_t length;
uint8_t data[0];
} STRUCT_PACKED;
/* IEEE802.11 Wireless Information */
struct capwap_ieee80211_frame_info {
uint8_t rssi;
uint8_t snr;
uint16_t rate;
} STRUCT_PACKED;
/* Message element */
struct capwap_message_element {
uint16_t type;
uint16_t length;
uint8_t data[0];
} STRUCT_PACKED;
/* Control Message Type */
#define CAPWAP_FIRST_MESSAGE_TYPE 1
#define CAPWAP_DISCOVERY_REQUEST 1
#define CAPWAP_DISCOVERY_RESPONSE 2
#define CAPWAP_JOIN_REQUEST 3
#define CAPWAP_JOIN_RESPONSE 4
#define CAPWAP_CONFIGURATION_STATUS_REQUEST 5
#define CAPWAP_CONFIGURATION_STATUS_RESPONSE 6
#define CAPWAP_CONFIGURATION_UPDATE_REQUEST 7
#define CAPWAP_CONFIGURATION_UPDATE_RESPONSE 8
#define CAPWAP_WTP_EVENT_REQUEST 9
#define CAPWAP_WTP_EVENT_RESPONSE 10
#define CAPWAP_CHANGE_STATE_EVENT_REQUEST 11
#define CAPWAP_CHANGE_STATE_EVENT_RESPONSE 12
#define CAPWAP_ECHO_REQUEST 13
#define CAPWAP_ECHO_RESPONSE 14
#define CAPWAP_IMAGE_DATA_REQUEST 15
#define CAPWAP_IMAGE_DATA_RESPONSE 16
#define CAPWAP_RESET_REQUEST 17
#define CAPWAP_RESET_RESPONSE 18
#define CAPWAP_PRIMARY_DISCOVERY_REQUEST 19
#define CAPWAP_PRIMARY_DISCOVERY_RESPONSE 20
#define CAPWAP_DATA_TRANSFER_REQUEST 21
#define CAPWAP_DATA_TRANSFER_RESPONSE 22
#define CAPWAP_CLEAR_CONFIGURATION_REQUEST 23
#define CAPWAP_CLEAR_CONFIGURATION_RESPONSE 24
#define CAPWAP_STATION_CONFIGURATION_REQUEST 25
#define CAPWAP_STATION_CONFIGURATION_RESPONSE 26
#define CAPWAP_LAST_MESSAGE_TYPE 26
#define CAPWAP_VALID_MESSAGE_TYPE(x) (((x) >= CAPWAP_FIRST_MESSAGE_TYPE) && ((x) <= CAPWAP_LAST_MESSAGE_TYPE))
#define CAPWAP_IEEE80211_FIRST_MESSAGE_TYPE 3398913
#define CAPWAP_IEEE80211_WLAN_CONFIGURATION_REQUEST 3398913
#define CAPWAP_IEEE80211_WLAN_CONFIGURATION_RESPONSE 3398914
#define CAPWAP_IEEE80211_LAST_MESSAGE_TYPE 3398914
#define CAPWAP_VALID_IEEE80211_MESSAGE_TYPE(x) (((x) >= CAPWAP_IEEE80211_FIRST_MESSAGE_TYPE) && ((x) <= CAPWAP_IEEE80211_LAST_MESSAGE_TYPE))
/* Control Message */
#define CAPWAP_CONTROL_MESSAGE_MIN_LENGTH 3
struct capwap_control_message {
uint32_t type;
uint8_t seq;
uint16_t length;
uint8_t flags;
uint8_t elements[0];
} STRUCT_PACKED;
/* Data Message Keep-Alive*/
#define CAPWAP_DATA_MESSAGE_KEEPALIVE_MIN_LENGTH 2
struct capwap_data_message {
uint16_t length;
uint8_t elements[0];
} STRUCT_PACKED;
/* Capwap dtls header helper */
#define GET_DTLS_BODY(x) (void*)(((uint8_t*)(x)) + sizeof(struct capwap_dtls_header))
/* Capwap header helper */
#define GET_VERSION_HEADER(x) ((x)->preamble.version)
#define SET_VERSION_HEADER(x, y) ((x)->preamble.version = (uint8_t)(y))
#define GET_TYPE_HEADER(x) ((x)->preamble.type)
#define SET_TYPE_HEADER(x, y) ((x)->preamble.type = (uint8_t)(y))
#define GET_HLEN_HEADER(x) ((x)->hlen)
#define SET_HLEN_HEADER(x, y) ((x)->hlen = (uint16_t)(y))
#ifdef CAPWAP_BIG_ENDIAN
#define GET_RID_HEADER(x) ((uint8_t)((x)->rid))
#define SET_RID_HEADER(x, y) ((x)->rid = (uint16_t)(y))
#else
#define GET_RID_HEADER(x) ((uint8_t)((uint16_t)((x)->_rid_hi << 2 | (x)->_rid_lo)))
#define SET_RID_HEADER(x, y) ({ (x)->_rid_hi = (uint16_t)((y) >> 2); (x)->_rid_lo = (uint16_t)((y) & 0x0003); })
#endif
#define GET_WBID_HEADER(x) ((x)->wbid)
#define SET_WBID_HEADER(x, y) ((x)->wbid = (uint16_t)(y))
#define IS_FLAG_T_HEADER(x) ((x)->flag_t)
#define SET_FLAG_T_HEADER(x, y) ((x)->flag_t = ((y) ? 1 : 0))
#define IS_FLAG_F_HEADER(x) ((x)->flag_f)
#define SET_FLAG_F_HEADER(x, y) ((x)->flag_f = ((y) ? 1 : 0))
#define IS_FLAG_L_HEADER(x) ((x)->flag_l)
#define SET_FLAG_L_HEADER(x, y) ((x)->flag_l = ((y) ? 1 : 0))
#define IS_FLAG_W_HEADER(x) ((x)->flag_w)
#define SET_FLAG_W_HEADER(x, y) ((x)->flag_w = ((y) ? 1 : 0))
#define IS_FLAG_M_HEADER(x) ((x)->flag_m)
#define SET_FLAG_M_HEADER(x, y) ((x)->flag_m = ((y) ? 1 : 0))
#define IS_FLAG_K_HEADER(x) ((x)->flag_k)
#define SET_FLAG_K_HEADER(x, y) ((x)->flag_k = ((y) ? 1 : 0))
#define GET_FRAGMENT_ID_HEADER(x) (ntohs((x)->frag_id))
#define SET_FRAGMENT_ID_HEADER(x, y) ((x)->frag_id = htons((uint16_t)(y)))
#define GET_FRAGMENT_OFFSET_HEADER(x) (ntohs((x)->frag_off) & FRAGMENT_OFFSET_MASK)
#define SET_FRAGMENT_OFFSET_HEADER(x, y) ((x)->frag_off &= ~FRAGMENT_OFFSET_MASK, (x)->frag_off |= htons((uint16_t)(y) & FRAGMENT_OFFSET_MASK))
#define GET_RADIO_MAC_ADDRESS_STRUCT(x) ((struct capwap_mac_address*)(((uint8_t*)(x)) + sizeof(struct capwap_header)))
#define GET_WIRELESS_INFORMATION_STRUCT(x) ((struct capwap_wireless_information*)(((uint8_t*)(x)) + sizeof(struct capwap_header) + (IS_FLAG_M_HEADER(x) ? (((GET_RADIO_MAC_ADDRESS_STRUCT(x)->length + sizeof(struct capwap_mac_address)) + 3) / 4) * 4 : 0)))
#define GET_PAYLOAD_HEADER(x) ((void*)(((uint8_t*)(x)) + GET_HLEN_HEADER(x) * 4))
#define IS_SEQUENCE_SMALLER(s1, s2) (((((s1) < (s2)) && (((s2) - (s1)) < 128)) || (((s1) > (s2)) && (((s1) - (s2)) > 128))) ? 1 : 0)
/* */
#define MACADDRESS_NONE_LENGTH 0
/* */
#define MACADDRESS_EUI48_LENGTH 6
struct capwap_macaddress_eui48 {
uint8_t macaddress[MACADDRESS_EUI48_LENGTH];
} STRUCT_PACKED;
/* */
#define MACADDRESS_EUI64_LENGTH 8
struct capwap_macaddress_eui64 {
uint8_t macaddress[MACADDRESS_EUI64_LENGTH];
} STRUCT_PACKED;
#define IS_VALID_MACADDRESS_LENGTH(x) ((x == MACADDRESS_EUI48_LENGTH) || (x == MACADDRESS_EUI64_LENGTH))
#define RADIOID_MAX_COUNT 31
#define IS_VALID_RADIOID(x) ((x >= 1) && (x <= RADIOID_MAX_COUNT))
#define WLANID_MAX_COUNT 16
#define IS_VALID_WLANID(x) ((x >= 1) && (x <= WLANID_MAX_COUNT))
/* Standard message elements 1 -> 52 (1 - 1023) */
#define CAPWAP_MESSAGE_ELEMENTS_START 1
#define CAPWAP_MESSAGE_ELEMENTS_STOP 53
#define CAPWAP_MESSAGE_ELEMENTS_COUNT ((CAPWAP_MESSAGE_ELEMENTS_STOP - CAPWAP_MESSAGE_ELEMENTS_START) + 1)
#define IS_MESSAGE_ELEMENTS(x) (((x >= CAPWAP_MESSAGE_ELEMENTS_START) && (x <= CAPWAP_MESSAGE_ELEMENTS_STOP)) ? 1 : 0)
/* 802.11 message elements 1024 -> 1024 (1024 - 2047) */
#define CAPWAP_80211_MESSAGE_ELEMENTS_START 1024
#define CAPWAP_80211_MESSAGE_ELEMENTS_STOP 1048
#define CAPWAP_80211_MESSAGE_ELEMENTS_COUNT ((CAPWAP_80211_MESSAGE_ELEMENTS_STOP - CAPWAP_80211_MESSAGE_ELEMENTS_START) + 1)
#define IS_80211_MESSAGE_ELEMENTS(x) (((x >= CAPWAP_80211_MESSAGE_ELEMENTS_START) && (x <= CAPWAP_80211_MESSAGE_ELEMENTS_STOP)) ? 1 : 0)
/* */
#define IS_VALID_MESSAGE_ELEMENTS(x) (IS_MESSAGE_ELEMENTS(x) || IS_80211_MESSAGE_ELEMENTS(x))
#endif /* __CAPWAP_RFC_HEADER__ */

View File

@ -1,388 +1,388 @@
#include "capwap.h"
#include "capwap_network.h"
#include "capwap_socket.h"
#include <cyassl/options.h>
#include <cyassl/ssl.h>
/* */
static int capwap_socket_nonblocking(int sock, int nonblocking) {
int flags;
ASSERT(sock >= 0);
/* Retrieve file descriptor flags */
flags = fcntl(sock, F_GETFL, NULL);
if (flags < 0) {
return 0;
}
if (nonblocking) {
flags |= O_NONBLOCK;
} else {
flags &= ~O_NONBLOCK;
}
if(fcntl(sock, F_SETFL, flags) < 0) {
return 0;
}
return 1;
}
/* */
int capwap_socket_connect(int sock, union sockaddr_capwap* address, int timeout) {
int result;
struct pollfd fds;
socklen_t size;
ASSERT(sock >= 0);
ASSERT(address != NULL);
/* Non blocking socket */
if (!capwap_socket_nonblocking(sock, 1)) {
return 0;
}
/* */
result = connect(sock, &address->sa, sizeof(union sockaddr_capwap));
if (result < 0) {
if (errno == EINPROGRESS) {
/* Wait to connection complete */
for (;;) {
memset(&fds, 0, sizeof(struct pollfd));
fds.fd = sock;
fds.events = POLLOUT;
result = poll(&fds, 1, timeout);
if (!result || ((result < 0) && (errno != EINTR))) {
return 0;
} else if (result > 0) {
/* Check connection status */
size = sizeof(int);
if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)&result, &size) < 0) {
return 0;
}
if (result) {
return 0;
}
/* Connection complete */
break;
}
}
} else {
/* Unable to connect to remote host */
return 0;
}
}
return 1;
}
/* */
static int capwap_socket_crypto_verifycertificate(int preverify, CYASSL_X509_STORE_CTX* store) {
return preverify;
}
/* */
void* capwap_socket_crypto_createcontext(char* calist, char* cert, char* privatekey) {
CYASSL_CTX* context = NULL;
ASSERT(calist != NULL);
ASSERT(cert != NULL);
ASSERT(privatekey != NULL);
/* Create SSL context */
context = CyaSSL_CTX_new(CyaTLSv1_2_client_method());
if (context) {
/* Public certificate */
if (!CyaSSL_CTX_use_certificate_file(context, cert, SSL_FILETYPE_PEM)) {
capwap_logging_debug("Error to load certificate file");
capwap_socket_crypto_freecontext(context);
return NULL;
}
/* Private key */
if (!CyaSSL_CTX_use_PrivateKey_file(context, privatekey, SSL_FILETYPE_PEM)) {
capwap_logging_debug("Error to load private key file");
capwap_socket_crypto_freecontext(context);
return NULL;
}
if (!CyaSSL_CTX_check_private_key(context)) {
capwap_logging_debug("Error to check private key");
capwap_socket_crypto_freecontext(context);
return NULL;
}
/* Certificate Authority */
if (!CyaSSL_CTX_load_verify_locations(context, calist, NULL)) {
capwap_logging_debug("Error to load ca file");
capwap_socket_crypto_freecontext(context);
return NULL;
}
/* Verify certificate callback */
CyaSSL_CTX_set_verify(context, SSL_VERIFY_PEER, capwap_socket_crypto_verifycertificate);
/* Set only high security cipher list */
if (!CyaSSL_CTX_set_cipher_list(context, "AES256-SHA")) {
capwap_logging_debug("Error to select cipher list");
capwap_socket_crypto_freecontext(context);
return NULL;
}
}
return (void*)context;
}
/* */
void capwap_socket_crypto_freecontext(void* context) {
CYASSL_CTX* sslcontext = (CYASSL_CTX*)context;
if (sslcontext) {
CyaSSL_CTX_free(sslcontext);
}
}
/* */
struct capwap_socket_ssl* capwap_socket_ssl_connect(int sock, void* sslcontext, int timeout) {
int result;
struct pollfd fds;
struct capwap_socket_ssl* sslsock;
ASSERT(sock >= 0);
ASSERT(sslcontext != NULL);
/* Create SSL session */
sslsock = capwap_alloc(sizeof(struct capwap_socket_ssl));
sslsock->sock = sock;
sslsock->sslcontext = sslcontext;
sslsock->sslsession = (void*)CyaSSL_new((CYASSL_CTX*)sslcontext);
if (!sslsock->sslsession) {
capwap_free(sslsock);
return NULL;
}
/* Set socket to SSL session */
if (!CyaSSL_set_fd((CYASSL*)sslsock->sslsession, sock)) {
CyaSSL_free((CYASSL*)sslsock->sslsession);
capwap_free(sslsock);
return NULL;
}
/* */
CyaSSL_set_using_nonblock((CYASSL*)sslsock->sslsession, 1);
/* Establish SSL connection */
for (;;) {
result = CyaSSL_connect((CYASSL*)sslsock->sslsession);
if (result == SSL_SUCCESS) {
break; /* Connection complete */
} else {
int error = CyaSSL_get_error((CYASSL*)sslsock->sslsession, 0);
if ((error == SSL_ERROR_WANT_READ) || (error == SSL_ERROR_WANT_WRITE)) {
memset(&fds, 0, sizeof(struct pollfd));
fds.fd = sock;
fds.events = ((error == SSL_ERROR_WANT_READ) ? POLLIN : POLLOUT);
result = poll(&fds, 1, timeout);
if (((result < 0) && (errno != EINTR)) || ((result > 0) && (fds.events != fds.revents))) {
CyaSSL_free((CYASSL*)sslsock->sslsession);
capwap_free(sslsock);
return NULL;
}
} else {
CyaSSL_free((CYASSL*)sslsock->sslsession);
capwap_free(sslsock);
return NULL;
}
}
}
return sslsock;
}
/* */
int capwap_socket_crypto_send(struct capwap_socket_ssl* sslsock, void* buffer, size_t length, int timeout) {
int result;
ASSERT(sslsock != NULL);
ASSERT(sslsock->sslsession != NULL);
ASSERT(sslsock->sock >= 0);
ASSERT(buffer != NULL);
ASSERT(length > 0);
result = CyaSSL_write((CYASSL*)sslsock->sslsession, buffer, length);
if (result != length) {
return -1;
}
return length;
}
/* */
int capwap_socket_crypto_recv(struct capwap_socket_ssl* sslsock, void* buffer, size_t length, int timeout) {
int result;
struct pollfd fds;
ASSERT(sslsock != NULL);
ASSERT(sslsock->sslsession != NULL);
ASSERT(sslsock->sock >= 0);
ASSERT(buffer != NULL);
ASSERT(length > 0);
for (;;) {
result = CyaSSL_read((CYASSL*)sslsock->sslsession, buffer, length);
if (result >= 0) {
return result;
} else {
int error = CyaSSL_get_error((CYASSL*)sslsock->sslsession, 0);
if ((error == SSL_ERROR_WANT_READ) || (error == SSL_ERROR_WANT_WRITE)) {
memset(&fds, 0, sizeof(struct pollfd));
fds.fd = sslsock->sock;
fds.events = ((error == SSL_ERROR_WANT_READ) ? POLLIN : POLLOUT);
result = poll(&fds, 1, timeout);
if (((result < 0) && (errno != EINTR)) || ((result > 0) && (fds.events != fds.revents))) {
break;
}
} else {
break;
}
}
}
return -1;
}
/* */
void capwap_socket_ssl_shutdown(struct capwap_socket_ssl* sslsock, int timeout) {
int result;
struct pollfd fds;
ASSERT(sslsock != NULL);
ASSERT(sslsock->sslsession != NULL);
ASSERT(sslsock->sock >= 0);
/* */
for (;;) {
result = CyaSSL_shutdown((CYASSL*)sslsock->sslsession);
if (result >= 0) {
break; /* Shutdown complete */
} else {
int error = CyaSSL_get_error((CYASSL*)sslsock->sslsession, 0);
if ((error == SSL_ERROR_WANT_READ) || (error == SSL_ERROR_WANT_WRITE)) {
memset(&fds, 0, sizeof(struct pollfd));
fds.fd = sslsock->sock;
fds.events = ((error == SSL_ERROR_WANT_READ) ? POLLIN : POLLOUT);
result = poll(&fds, 1, timeout);
if (((result < 0) && (errno != EINTR)) || ((result > 0) && (fds.events != fds.revents))) {
break; /* Shutdown error */
}
} else {
break; /* Shutdown error */
}
}
}
}
/* */
void capwap_socket_ssl_close(struct capwap_socket_ssl* sslsock) {
ASSERT(sslsock != NULL);
ASSERT(sslsock->sslsession != NULL);
CyaSSL_free((CYASSL*)sslsock->sslsession);
sslsock->sslsession = NULL;
}
/* */
void capwap_socket_shutdown(int sock) {
ASSERT(sock >= 0);
shutdown(sock, SHUT_RDWR);
}
/* */
void capwap_socket_close(int sock) {
ASSERT(sock >= 0);
capwap_socket_shutdown(sock);
capwap_socket_nonblocking(sock, 0);
close(sock);
}
/* */
int capwap_socket_send(int sock, void* buffer, size_t length, int timeout) {
int result;
struct pollfd fds;
size_t sendlength;
ASSERT(sock >= 0);
ASSERT(buffer != NULL);
ASSERT(length > 0);
sendlength = 0;
while (sendlength < length) {
memset(&fds, 0, sizeof(struct pollfd));
fds.fd = sock;
fds.events = POLLOUT;
result = poll(&fds, 1, timeout);
if ((result < 0) && (errno != EINTR)) {
return -1;
} else if (result > 0) {
if (fds.revents == POLLOUT) {
size_t leftlength = length - sendlength;
result = send(sock, &((char*)buffer)[sendlength], leftlength, 0);
if ((result < 0) && (errno != EINTR)) {
return -1;
} else if (result > 0) {
sendlength += result;
}
} else {
return -1;
}
}
}
return sendlength;
}
/* */
int capwap_socket_recv(int sock, void* buffer, size_t length, int timeout) {
int result;
struct pollfd fds;
ASSERT(sock >= 0);
ASSERT(buffer != NULL);
ASSERT(length > 0);
for (;;) {
memset(&fds, 0, sizeof(struct pollfd));
fds.fd = sock;
fds.events = POLLIN;
result = poll(&fds, 1, timeout);
if ((result < 0) && (errno != EINTR)) {
break;
} else if (result > 0) {
if (fds.revents == POLLIN) {
result = recv(sock, buffer, length, 0);
if ((result < 0) && (errno != EINTR)) {
break;
} else if (result >= 0) {
return result;
}
} else {
break;
}
}
}
return -1;
}
#include "capwap.h"
#include "capwap_network.h"
#include "capwap_socket.h"
#include <cyassl/options.h>
#include <cyassl/ssl.h>
/* */
static int capwap_socket_nonblocking(int sock, int nonblocking) {
int flags;
ASSERT(sock >= 0);
/* Retrieve file descriptor flags */
flags = fcntl(sock, F_GETFL, NULL);
if (flags < 0) {
return 0;
}
if (nonblocking) {
flags |= O_NONBLOCK;
} else {
flags &= ~O_NONBLOCK;
}
if(fcntl(sock, F_SETFL, flags) < 0) {
return 0;
}
return 1;
}
/* */
int capwap_socket_connect(int sock, union sockaddr_capwap* address, int timeout) {
int result;
struct pollfd fds;
socklen_t size;
ASSERT(sock >= 0);
ASSERT(address != NULL);
/* Non blocking socket */
if (!capwap_socket_nonblocking(sock, 1)) {
return 0;
}
/* */
result = connect(sock, &address->sa, sizeof(union sockaddr_capwap));
if (result < 0) {
if (errno == EINPROGRESS) {
/* Wait to connection complete */
for (;;) {
memset(&fds, 0, sizeof(struct pollfd));
fds.fd = sock;
fds.events = POLLOUT;
result = poll(&fds, 1, timeout);
if (!result || ((result < 0) && (errno != EINTR))) {
return 0;
} else if (result > 0) {
/* Check connection status */
size = sizeof(int);
if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)&result, &size) < 0) {
return 0;
}
if (result) {
return 0;
}
/* Connection complete */
break;
}
}
} else {
/* Unable to connect to remote host */
return 0;
}
}
return 1;
}
/* */
static int capwap_socket_crypto_verifycertificate(int preverify, CYASSL_X509_STORE_CTX* store) {
return preverify;
}
/* */
void* capwap_socket_crypto_createcontext(char* calist, char* cert, char* privatekey) {
CYASSL_CTX* context = NULL;
ASSERT(calist != NULL);
ASSERT(cert != NULL);
ASSERT(privatekey != NULL);
/* Create SSL context */
context = CyaSSL_CTX_new(CyaTLSv1_2_client_method());
if (context) {
/* Public certificate */
if (!CyaSSL_CTX_use_certificate_file(context, cert, SSL_FILETYPE_PEM)) {
capwap_logging_debug("Error to load certificate file");
capwap_socket_crypto_freecontext(context);
return NULL;
}
/* Private key */
if (!CyaSSL_CTX_use_PrivateKey_file(context, privatekey, SSL_FILETYPE_PEM)) {
capwap_logging_debug("Error to load private key file");
capwap_socket_crypto_freecontext(context);
return NULL;
}
if (!CyaSSL_CTX_check_private_key(context)) {
capwap_logging_debug("Error to check private key");
capwap_socket_crypto_freecontext(context);
return NULL;
}
/* Certificate Authority */
if (!CyaSSL_CTX_load_verify_locations(context, calist, NULL)) {
capwap_logging_debug("Error to load ca file");
capwap_socket_crypto_freecontext(context);
return NULL;
}
/* Verify certificate callback */
CyaSSL_CTX_set_verify(context, SSL_VERIFY_PEER, capwap_socket_crypto_verifycertificate);
/* Set only high security cipher list */
if (!CyaSSL_CTX_set_cipher_list(context, "AES256-SHA")) {
capwap_logging_debug("Error to select cipher list");
capwap_socket_crypto_freecontext(context);
return NULL;
}
}
return (void*)context;
}
/* */
void capwap_socket_crypto_freecontext(void* context) {
CYASSL_CTX* sslcontext = (CYASSL_CTX*)context;
if (sslcontext) {
CyaSSL_CTX_free(sslcontext);
}
}
/* */
struct capwap_socket_ssl* capwap_socket_ssl_connect(int sock, void* sslcontext, int timeout) {
int result;
struct pollfd fds;
struct capwap_socket_ssl* sslsock;
ASSERT(sock >= 0);
ASSERT(sslcontext != NULL);
/* Create SSL session */
sslsock = capwap_alloc(sizeof(struct capwap_socket_ssl));
sslsock->sock = sock;
sslsock->sslcontext = sslcontext;
sslsock->sslsession = (void*)CyaSSL_new((CYASSL_CTX*)sslcontext);
if (!sslsock->sslsession) {
capwap_free(sslsock);
return NULL;
}
/* Set socket to SSL session */
if (!CyaSSL_set_fd((CYASSL*)sslsock->sslsession, sock)) {
CyaSSL_free((CYASSL*)sslsock->sslsession);
capwap_free(sslsock);
return NULL;
}
/* */
CyaSSL_set_using_nonblock((CYASSL*)sslsock->sslsession, 1);
/* Establish SSL connection */
for (;;) {
result = CyaSSL_connect((CYASSL*)sslsock->sslsession);
if (result == SSL_SUCCESS) {
break; /* Connection complete */
} else {
int error = CyaSSL_get_error((CYASSL*)sslsock->sslsession, 0);
if ((error == SSL_ERROR_WANT_READ) || (error == SSL_ERROR_WANT_WRITE)) {
memset(&fds, 0, sizeof(struct pollfd));
fds.fd = sock;
fds.events = ((error == SSL_ERROR_WANT_READ) ? POLLIN : POLLOUT);
result = poll(&fds, 1, timeout);
if (((result < 0) && (errno != EINTR)) || ((result > 0) && (fds.events != fds.revents))) {
CyaSSL_free((CYASSL*)sslsock->sslsession);
capwap_free(sslsock);
return NULL;
}
} else {
CyaSSL_free((CYASSL*)sslsock->sslsession);
capwap_free(sslsock);
return NULL;
}
}
}
return sslsock;
}
/* */
int capwap_socket_crypto_send(struct capwap_socket_ssl* sslsock, void* buffer, size_t length, int timeout) {
int result;
ASSERT(sslsock != NULL);
ASSERT(sslsock->sslsession != NULL);
ASSERT(sslsock->sock >= 0);
ASSERT(buffer != NULL);
ASSERT(length > 0);
result = CyaSSL_write((CYASSL*)sslsock->sslsession, buffer, length);
if (result != length) {
return -1;
}
return length;
}
/* */
int capwap_socket_crypto_recv(struct capwap_socket_ssl* sslsock, void* buffer, size_t length, int timeout) {
int result;
struct pollfd fds;
ASSERT(sslsock != NULL);
ASSERT(sslsock->sslsession != NULL);
ASSERT(sslsock->sock >= 0);
ASSERT(buffer != NULL);
ASSERT(length > 0);
for (;;) {
result = CyaSSL_read((CYASSL*)sslsock->sslsession, buffer, length);
if (result >= 0) {
return result;
} else {
int error = CyaSSL_get_error((CYASSL*)sslsock->sslsession, 0);
if ((error == SSL_ERROR_WANT_READ) || (error == SSL_ERROR_WANT_WRITE)) {
memset(&fds, 0, sizeof(struct pollfd));
fds.fd = sslsock->sock;
fds.events = ((error == SSL_ERROR_WANT_READ) ? POLLIN : POLLOUT);
result = poll(&fds, 1, timeout);
if (((result < 0) && (errno != EINTR)) || ((result > 0) && (fds.events != fds.revents))) {
break;
}
} else {
break;
}
}
}
return -1;
}
/* */
void capwap_socket_ssl_shutdown(struct capwap_socket_ssl* sslsock, int timeout) {
int result;
struct pollfd fds;
ASSERT(sslsock != NULL);
ASSERT(sslsock->sslsession != NULL);
ASSERT(sslsock->sock >= 0);
/* */
for (;;) {
result = CyaSSL_shutdown((CYASSL*)sslsock->sslsession);
if (result >= 0) {
break; /* Shutdown complete */
} else {
int error = CyaSSL_get_error((CYASSL*)sslsock->sslsession, 0);
if ((error == SSL_ERROR_WANT_READ) || (error == SSL_ERROR_WANT_WRITE)) {
memset(&fds, 0, sizeof(struct pollfd));
fds.fd = sslsock->sock;
fds.events = ((error == SSL_ERROR_WANT_READ) ? POLLIN : POLLOUT);
result = poll(&fds, 1, timeout);
if (((result < 0) && (errno != EINTR)) || ((result > 0) && (fds.events != fds.revents))) {
break; /* Shutdown error */
}
} else {
break; /* Shutdown error */
}
}
}
}
/* */
void capwap_socket_ssl_close(struct capwap_socket_ssl* sslsock) {
ASSERT(sslsock != NULL);
ASSERT(sslsock->sslsession != NULL);
CyaSSL_free((CYASSL*)sslsock->sslsession);
sslsock->sslsession = NULL;
}
/* */
void capwap_socket_shutdown(int sock) {
ASSERT(sock >= 0);
shutdown(sock, SHUT_RDWR);
}
/* */
void capwap_socket_close(int sock) {
ASSERT(sock >= 0);
capwap_socket_shutdown(sock);
capwap_socket_nonblocking(sock, 0);
close(sock);
}
/* */
int capwap_socket_send(int sock, void* buffer, size_t length, int timeout) {
int result;
struct pollfd fds;
size_t sendlength;
ASSERT(sock >= 0);
ASSERT(buffer != NULL);
ASSERT(length > 0);
sendlength = 0;
while (sendlength < length) {
memset(&fds, 0, sizeof(struct pollfd));
fds.fd = sock;
fds.events = POLLOUT;
result = poll(&fds, 1, timeout);
if ((result < 0) && (errno != EINTR)) {
return -1;
} else if (result > 0) {
if (fds.revents == POLLOUT) {
size_t leftlength = length - sendlength;
result = send(sock, &((char*)buffer)[sendlength], leftlength, 0);
if ((result < 0) && (errno != EINTR)) {
return -1;
} else if (result > 0) {
sendlength += result;
}
} else {
return -1;
}
}
}
return sendlength;
}
/* */
int capwap_socket_recv(int sock, void* buffer, size_t length, int timeout) {
int result;
struct pollfd fds;
ASSERT(sock >= 0);
ASSERT(buffer != NULL);
ASSERT(length > 0);
for (;;) {
memset(&fds, 0, sizeof(struct pollfd));
fds.fd = sock;
fds.events = POLLIN;
result = poll(&fds, 1, timeout);
if ((result < 0) && (errno != EINTR)) {
break;
} else if (result > 0) {
if (fds.revents == POLLIN) {
result = recv(sock, buffer, length, 0);
if ((result < 0) && (errno != EINTR)) {
break;
} else if (result >= 0) {
return result;
}
} else {
break;
}
}
}
return -1;
}

View File

@ -1,30 +1,30 @@
#ifndef __CAPWAP_SOCKET_HEADER__
#define __CAPWAP_SOCKET_HEADER__
/* */
int capwap_socket_connect(int sock, union sockaddr_capwap* address, int timeout);
void capwap_socket_shutdown(int sock);
void capwap_socket_close(int sock);
/* Plain send/recv */
int capwap_socket_send(int sock, void* buffer, size_t length, int timeout);
int capwap_socket_recv(int sock, void* buffer, size_t length, int timeout);
/* SSL send/recv */
struct capwap_socket_ssl {
int sock;
void* sslcontext;
void* sslsession;
};
void* capwap_socket_crypto_createcontext(char* calist, char* cert, char* privatekey);
void capwap_socket_crypto_freecontext(void* context);
int capwap_socket_crypto_send(struct capwap_socket_ssl* sslsock, void* buffer, size_t length, int timeout);
int capwap_socket_crypto_recv(struct capwap_socket_ssl* sslsock, void* buffer, size_t length, int timeout);
struct capwap_socket_ssl* capwap_socket_ssl_connect(int sock, void* sslcontext, int timeout);
void capwap_socket_ssl_shutdown(struct capwap_socket_ssl* sslsock, int timeout);
void capwap_socket_ssl_close(struct capwap_socket_ssl* sslsock);
#endif /* __CAPWAP_SOCKET_HEADER__ */
#ifndef __CAPWAP_SOCKET_HEADER__
#define __CAPWAP_SOCKET_HEADER__
/* */
int capwap_socket_connect(int sock, union sockaddr_capwap* address, int timeout);
void capwap_socket_shutdown(int sock);
void capwap_socket_close(int sock);
/* Plain send/recv */
int capwap_socket_send(int sock, void* buffer, size_t length, int timeout);
int capwap_socket_recv(int sock, void* buffer, size_t length, int timeout);
/* SSL send/recv */
struct capwap_socket_ssl {
int sock;
void* sslcontext;
void* sslsession;
};
void* capwap_socket_crypto_createcontext(char* calist, char* cert, char* privatekey);
void capwap_socket_crypto_freecontext(void* context);
int capwap_socket_crypto_send(struct capwap_socket_ssl* sslsock, void* buffer, size_t length, int timeout);
int capwap_socket_crypto_recv(struct capwap_socket_ssl* sslsock, void* buffer, size_t length, int timeout);
struct capwap_socket_ssl* capwap_socket_ssl_connect(int sock, void* sslcontext, int timeout);
void capwap_socket_ssl_shutdown(struct capwap_socket_ssl* sslsock, int timeout);
void capwap_socket_ssl_close(struct capwap_socket_ssl* sslsock);
#endif /* __CAPWAP_SOCKET_HEADER__ */

View File

@ -1,342 +1,342 @@
#include "capwap.h"
/* */
#define CAPWAP_TIMEOUT_HASH_COUNT 128
/* */
/* #define CAPWAP_TIMEOUT_LOGGING_DEBUG 1 */
/* */
static unsigned long capwap_timeout_hash_item_gethash(const void* key, unsigned long hashsize) {
return (*((unsigned long*)key) % hashsize);
}
/* */
static const void* capwap_timeout_hash_item_getkey(const void* data) {
return (const void*)&((struct capwap_timeout_item*)((struct capwap_list_item*)data)->item)->index;
}
/* */
static int capwap_timeout_hash_item_cmp(const void* key1, const void* key2) {
unsigned long value1 = *(unsigned long*)key1;
unsigned long value2 = *(unsigned long*)key2;
return ((value1 == value2) ? 0 : ((value1 < value2) ? -1 : 1));
}
/* */
static long capwap_timeout_getdelta(struct timeval* time1, struct timeval* time2) {
return (time1->tv_sec - time2->tv_sec) * 1000 + (time1->tv_usec - time2->tv_usec) / 1000;
}
/* */
static unsigned long capwap_timeout_set_bitfield(struct capwap_timeout* timeout) {
int i, j;
ASSERT(timeout != NULL);
/* Search free bitfield */
for (i = 0; i < CAPWAP_TIMEOUT_BITFIELD_SIZE; i++) {
if (timeout->timeoutbitfield[i] != 0xffffffff) {
uint32_t bitfield = timeout->timeoutbitfield[i];
for (j = 0; j < 32; j++) {
if (!(bitfield & (1 << j))) {
timeout->timeoutbitfield[i] |= (1 << j);
return (i * 32 + j + 1);
}
}
}
}
return CAPWAP_TIMEOUT_INDEX_NO_SET;
}
/* */
static void capwap_timeout_clear_bitfield(struct capwap_timeout* timeout, unsigned long value) {
ASSERT(timeout != NULL);
ASSERT(value > 0);
timeout->timeoutbitfield[(value - 1) / 32] &= ~(1 << ((value - 1) % 32));
}
/* */
static void capwap_timeout_additem(struct capwap_list* itemstimeout, struct capwap_list_item* itemlist) {
struct capwap_list_item* search;
struct capwap_list_item* last = NULL;
struct capwap_timeout_item* item = (struct capwap_timeout_item*)itemlist->item;
/* */
search = itemstimeout->first;
while (search) {
struct capwap_timeout_item* itemsearch = (struct capwap_timeout_item*)search->item;
if (capwap_timeout_getdelta(&item->expire, &itemsearch->expire) < 0) {
capwap_itemlist_insert_before(itemstimeout, last, itemlist);
break;
}
/* Next */
last = search;
search = search->next;
}
/* */
if (!search) {
capwap_itemlist_insert_after(itemstimeout, NULL, itemlist);
}
}
/* */
static void capwap_timeout_setexpire(long durate, struct timeval* now, struct timeval* expire) {
expire->tv_sec = now->tv_sec + durate / 1000;
expire->tv_usec = now->tv_usec + durate % 1000;
if (expire->tv_usec >= 1000000) {
expire->tv_sec++;
expire->tv_usec -= 1000000;
}
}
/* */
struct capwap_timeout* capwap_timeout_init(void) {
struct capwap_timeout* timeout;
/* */
timeout = (struct capwap_timeout*)capwap_alloc(sizeof(struct capwap_timeout));
memset(timeout, 0, sizeof(struct capwap_timeout));
/* */
timeout->itemsreference = capwap_hash_create(CAPWAP_TIMEOUT_HASH_COUNT);
timeout->itemsreference->item_gethash = capwap_timeout_hash_item_gethash;
timeout->itemsreference->item_getkey = capwap_timeout_hash_item_getkey;
timeout->itemsreference->item_cmp = capwap_timeout_hash_item_cmp;
timeout->itemstimeout = capwap_list_create();
return timeout;
}
/* */
void capwap_timeout_free(struct capwap_timeout* timeout) {
ASSERT(timeout != NULL);
capwap_hash_free(timeout->itemsreference);
capwap_list_free(timeout->itemstimeout);
capwap_free(timeout);
}
/* */
unsigned long capwap_timeout_createtimer(struct capwap_timeout* timeout) {
unsigned long index;
ASSERT(timeout != NULL);
/* Create new timeout index */
index = capwap_timeout_set_bitfield(timeout);
#ifdef CAPWAP_TIMEOUT_LOGGING_DEBUG
capwap_logging_debug("Create new timer: %lu", index);
#endif
return index;
}
/* */
void capwap_timeout_deletetimer(struct capwap_timeout* timeout, unsigned long index) {
ASSERT(timeout != NULL);
if (index != CAPWAP_TIMEOUT_INDEX_NO_SET) {
#ifdef CAPWAP_TIMEOUT_LOGGING_DEBUG
capwap_logging_debug("Delete timer: %lu", index);
#endif
/* Unset timeout timer */
capwap_timeout_unset(timeout, index);
/* Release timer index */
capwap_timeout_clear_bitfield(timeout, index);
}
}
/* */
unsigned long capwap_timeout_set(struct capwap_timeout* timeout, unsigned long index, long durate, capwap_timeout_expire callback, void* context, void* param) {
struct capwap_list_item* itemlist;
struct capwap_timeout_item* item;
struct timeval now;
ASSERT(timeout != NULL);
ASSERT(durate >= 0);
gettimeofday(&now, NULL);
if (index == CAPWAP_TIMEOUT_INDEX_NO_SET) {
index = capwap_timeout_createtimer(timeout);
} else {
/* Check can update timeout timer */
itemlist = (struct capwap_list_item*)capwap_hash_search(timeout->itemsreference, &index);
if (itemlist) {
/* Remove from timeout list */
capwap_itemlist_remove(timeout->itemstimeout, itemlist);
/* Update timeout */
item = (struct capwap_timeout_item*)itemlist->item;
item->durate = durate;
capwap_timeout_setexpire(item->durate, &now, &item->expire);
item->callback = callback;
item->context = context;
item->param = param;
#ifdef CAPWAP_TIMEOUT_LOGGING_DEBUG
capwap_logging_debug("Update timeout: %lu %ld", item->index, item->durate);
#endif
/* Add itemlist into order list */
capwap_timeout_additem(timeout->itemstimeout, itemlist);
return index;
}
}
/* Create new timeout timer */
itemlist = capwap_itemlist_create(sizeof(struct capwap_timeout_item));
item = (struct capwap_timeout_item*)itemlist->item;
/* */
item->index = index;
item->durate = durate;
capwap_timeout_setexpire(item->durate, &now, &item->expire);
item->callback = callback;
item->context = context;
item->param = param;
#ifdef CAPWAP_TIMEOUT_LOGGING_DEBUG
capwap_logging_debug("Set timeout: %lu %ld", item->index, item->durate);
#endif
/* Add itemlist into hash for rapid searching */
capwap_hash_add(timeout->itemsreference, (void*)itemlist);
/* Add itemlist into order list */
capwap_timeout_additem(timeout->itemstimeout, itemlist);
return item->index;
}
/* */
void capwap_timeout_unset(struct capwap_timeout* timeout, unsigned long index) {
struct capwap_list_item* itemlist;
ASSERT(timeout != NULL);
if (index != CAPWAP_TIMEOUT_INDEX_NO_SET) {
itemlist = (struct capwap_list_item*)capwap_hash_search(timeout->itemsreference, &index);
if (itemlist) {
#ifdef CAPWAP_TIMEOUT_LOGGING_DEBUG
capwap_logging_debug("Unset timeout: %lu", index);
#endif
/* */
capwap_hash_delete(timeout->itemsreference, &index);
capwap_itemlist_free(capwap_itemlist_remove(timeout->itemstimeout, itemlist));
}
}
}
/* */
void capwap_timeout_unsetall(struct capwap_timeout* timeout) {
capwap_hash_deleteall(timeout->itemsreference);
capwap_list_flush(timeout->itemstimeout);
}
/* */
long capwap_timeout_getcoming(struct capwap_timeout* timeout) {
long delta;
struct timeval now;
struct capwap_list_item* search;
struct capwap_timeout_item* item;
ASSERT(timeout != NULL);
/* */
search = timeout->itemstimeout->first;
if (!search) {
return CAPWAP_TIMEOUT_INFINITE;
}
/* */
gettimeofday(&now, NULL);
item = (struct capwap_timeout_item*)search->item;
delta = capwap_timeout_getdelta(&item->expire, &now);
if (delta <= 0) {
return 0;
} else if (delta <= item->durate) {
return delta;
}
/* Recalculate all timeouts because delta > item->durate */
while (search) {
struct capwap_timeout_item* itemsearch = (struct capwap_timeout_item*)search->item;
capwap_timeout_setexpire(itemsearch->durate, &now, &itemsearch->expire);
search = search->next;
}
return item->durate;
}
/* */
unsigned long capwap_timeout_hasexpired(struct capwap_timeout* timeout) {
long delta;
struct capwap_timeout_item* item;
struct capwap_list_item* itemlist;
unsigned long index;
capwap_timeout_expire callback;
void* context;
void* param;
ASSERT(timeout != NULL);
/* */
delta = capwap_timeout_getcoming(timeout);
if ((delta > 0) || (delta == CAPWAP_TIMEOUT_INFINITE)) {
return 0;
}
/* */
itemlist = capwap_itemlist_remove_head(timeout->itemstimeout);
item = (struct capwap_timeout_item*)itemlist->item;
#ifdef CAPWAP_TIMEOUT_LOGGING_DEBUG
capwap_logging_debug("Expired timeout: %lu", item->index);
#endif
/* Cache callback before release timeout timer */
index = item->index;
callback = item->callback;
context = item->context;
param = item->param;
/* Free memory */
capwap_hash_delete(timeout->itemsreference, &index);
capwap_itemlist_free(itemlist);
/* */
if (callback) {
callback(timeout, index, context, param);
}
return index;
}
/* */
int capwap_timeout_wait(long durate) {
if (durate < 0) {
return -1;
} else if (durate > 0) {
if (usleep((useconds_t)durate * 1000)) {
return ((errno == EINTR) ? 0 : -1);
}
}
return 1;
}
#include "capwap.h"
/* */
#define CAPWAP_TIMEOUT_HASH_COUNT 128
/* */
/* #define CAPWAP_TIMEOUT_LOGGING_DEBUG 1 */
/* */
static unsigned long capwap_timeout_hash_item_gethash(const void* key, unsigned long hashsize) {
return (*((unsigned long*)key) % hashsize);
}
/* */
static const void* capwap_timeout_hash_item_getkey(const void* data) {
return (const void*)&((struct capwap_timeout_item*)((struct capwap_list_item*)data)->item)->index;
}
/* */
static int capwap_timeout_hash_item_cmp(const void* key1, const void* key2) {
unsigned long value1 = *(unsigned long*)key1;
unsigned long value2 = *(unsigned long*)key2;
return ((value1 == value2) ? 0 : ((value1 < value2) ? -1 : 1));
}
/* */
static long capwap_timeout_getdelta(struct timeval* time1, struct timeval* time2) {
return (time1->tv_sec - time2->tv_sec) * 1000 + (time1->tv_usec - time2->tv_usec) / 1000;
}
/* */
static unsigned long capwap_timeout_set_bitfield(struct capwap_timeout* timeout) {
int i, j;
ASSERT(timeout != NULL);
/* Search free bitfield */
for (i = 0; i < CAPWAP_TIMEOUT_BITFIELD_SIZE; i++) {
if (timeout->timeoutbitfield[i] != 0xffffffff) {
uint32_t bitfield = timeout->timeoutbitfield[i];
for (j = 0; j < 32; j++) {
if (!(bitfield & (1 << j))) {
timeout->timeoutbitfield[i] |= (1 << j);
return (i * 32 + j + 1);
}
}
}
}
return CAPWAP_TIMEOUT_INDEX_NO_SET;
}
/* */
static void capwap_timeout_clear_bitfield(struct capwap_timeout* timeout, unsigned long value) {
ASSERT(timeout != NULL);
ASSERT(value > 0);
timeout->timeoutbitfield[(value - 1) / 32] &= ~(1 << ((value - 1) % 32));
}
/* */
static void capwap_timeout_additem(struct capwap_list* itemstimeout, struct capwap_list_item* itemlist) {
struct capwap_list_item* search;
struct capwap_list_item* last = NULL;
struct capwap_timeout_item* item = (struct capwap_timeout_item*)itemlist->item;
/* */
search = itemstimeout->first;
while (search) {
struct capwap_timeout_item* itemsearch = (struct capwap_timeout_item*)search->item;
if (capwap_timeout_getdelta(&item->expire, &itemsearch->expire) < 0) {
capwap_itemlist_insert_before(itemstimeout, last, itemlist);
break;
}
/* Next */
last = search;
search = search->next;
}
/* */
if (!search) {
capwap_itemlist_insert_after(itemstimeout, NULL, itemlist);
}
}
/* */
static void capwap_timeout_setexpire(long durate, struct timeval* now, struct timeval* expire) {
expire->tv_sec = now->tv_sec + durate / 1000;
expire->tv_usec = now->tv_usec + durate % 1000;
if (expire->tv_usec >= 1000000) {
expire->tv_sec++;
expire->tv_usec -= 1000000;
}
}
/* */
struct capwap_timeout* capwap_timeout_init(void) {
struct capwap_timeout* timeout;
/* */
timeout = (struct capwap_timeout*)capwap_alloc(sizeof(struct capwap_timeout));
memset(timeout, 0, sizeof(struct capwap_timeout));
/* */
timeout->itemsreference = capwap_hash_create(CAPWAP_TIMEOUT_HASH_COUNT);
timeout->itemsreference->item_gethash = capwap_timeout_hash_item_gethash;
timeout->itemsreference->item_getkey = capwap_timeout_hash_item_getkey;
timeout->itemsreference->item_cmp = capwap_timeout_hash_item_cmp;
timeout->itemstimeout = capwap_list_create();
return timeout;
}
/* */
void capwap_timeout_free(struct capwap_timeout* timeout) {
ASSERT(timeout != NULL);
capwap_hash_free(timeout->itemsreference);
capwap_list_free(timeout->itemstimeout);
capwap_free(timeout);
}
/* */
unsigned long capwap_timeout_createtimer(struct capwap_timeout* timeout) {
unsigned long index;
ASSERT(timeout != NULL);
/* Create new timeout index */
index = capwap_timeout_set_bitfield(timeout);
#ifdef CAPWAP_TIMEOUT_LOGGING_DEBUG
capwap_logging_debug("Create new timer: %lu", index);
#endif
return index;
}
/* */
void capwap_timeout_deletetimer(struct capwap_timeout* timeout, unsigned long index) {
ASSERT(timeout != NULL);
if (index != CAPWAP_TIMEOUT_INDEX_NO_SET) {
#ifdef CAPWAP_TIMEOUT_LOGGING_DEBUG
capwap_logging_debug("Delete timer: %lu", index);
#endif
/* Unset timeout timer */
capwap_timeout_unset(timeout, index);
/* Release timer index */
capwap_timeout_clear_bitfield(timeout, index);
}
}
/* */
unsigned long capwap_timeout_set(struct capwap_timeout* timeout, unsigned long index, long durate, capwap_timeout_expire callback, void* context, void* param) {
struct capwap_list_item* itemlist;
struct capwap_timeout_item* item;
struct timeval now;
ASSERT(timeout != NULL);
ASSERT(durate >= 0);
gettimeofday(&now, NULL);
if (index == CAPWAP_TIMEOUT_INDEX_NO_SET) {
index = capwap_timeout_createtimer(timeout);
} else {
/* Check can update timeout timer */
itemlist = (struct capwap_list_item*)capwap_hash_search(timeout->itemsreference, &index);
if (itemlist) {
/* Remove from timeout list */
capwap_itemlist_remove(timeout->itemstimeout, itemlist);
/* Update timeout */
item = (struct capwap_timeout_item*)itemlist->item;
item->durate = durate;
capwap_timeout_setexpire(item->durate, &now, &item->expire);
item->callback = callback;
item->context = context;
item->param = param;
#ifdef CAPWAP_TIMEOUT_LOGGING_DEBUG
capwap_logging_debug("Update timeout: %lu %ld", item->index, item->durate);
#endif
/* Add itemlist into order list */
capwap_timeout_additem(timeout->itemstimeout, itemlist);
return index;
}
}
/* Create new timeout timer */
itemlist = capwap_itemlist_create(sizeof(struct capwap_timeout_item));
item = (struct capwap_timeout_item*)itemlist->item;
/* */
item->index = index;
item->durate = durate;
capwap_timeout_setexpire(item->durate, &now, &item->expire);
item->callback = callback;
item->context = context;
item->param = param;
#ifdef CAPWAP_TIMEOUT_LOGGING_DEBUG
capwap_logging_debug("Set timeout: %lu %ld", item->index, item->durate);
#endif
/* Add itemlist into hash for rapid searching */
capwap_hash_add(timeout->itemsreference, (void*)itemlist);
/* Add itemlist into order list */
capwap_timeout_additem(timeout->itemstimeout, itemlist);
return item->index;
}
/* */
void capwap_timeout_unset(struct capwap_timeout* timeout, unsigned long index) {
struct capwap_list_item* itemlist;
ASSERT(timeout != NULL);
if (index != CAPWAP_TIMEOUT_INDEX_NO_SET) {
itemlist = (struct capwap_list_item*)capwap_hash_search(timeout->itemsreference, &index);
if (itemlist) {
#ifdef CAPWAP_TIMEOUT_LOGGING_DEBUG
capwap_logging_debug("Unset timeout: %lu", index);
#endif
/* */
capwap_hash_delete(timeout->itemsreference, &index);
capwap_itemlist_free(capwap_itemlist_remove(timeout->itemstimeout, itemlist));
}
}
}
/* */
void capwap_timeout_unsetall(struct capwap_timeout* timeout) {
capwap_hash_deleteall(timeout->itemsreference);
capwap_list_flush(timeout->itemstimeout);
}
/* */
long capwap_timeout_getcoming(struct capwap_timeout* timeout) {
long delta;
struct timeval now;
struct capwap_list_item* search;
struct capwap_timeout_item* item;
ASSERT(timeout != NULL);
/* */
search = timeout->itemstimeout->first;
if (!search) {
return CAPWAP_TIMEOUT_INFINITE;
}
/* */
gettimeofday(&now, NULL);
item = (struct capwap_timeout_item*)search->item;
delta = capwap_timeout_getdelta(&item->expire, &now);
if (delta <= 0) {
return 0;
} else if (delta <= item->durate) {
return delta;
}
/* Recalculate all timeouts because delta > item->durate */
while (search) {
struct capwap_timeout_item* itemsearch = (struct capwap_timeout_item*)search->item;
capwap_timeout_setexpire(itemsearch->durate, &now, &itemsearch->expire);
search = search->next;
}
return item->durate;
}
/* */
unsigned long capwap_timeout_hasexpired(struct capwap_timeout* timeout) {
long delta;
struct capwap_timeout_item* item;
struct capwap_list_item* itemlist;
unsigned long index;
capwap_timeout_expire callback;
void* context;
void* param;
ASSERT(timeout != NULL);
/* */
delta = capwap_timeout_getcoming(timeout);
if ((delta > 0) || (delta == CAPWAP_TIMEOUT_INFINITE)) {
return 0;
}
/* */
itemlist = capwap_itemlist_remove_head(timeout->itemstimeout);
item = (struct capwap_timeout_item*)itemlist->item;
#ifdef CAPWAP_TIMEOUT_LOGGING_DEBUG
capwap_logging_debug("Expired timeout: %lu", item->index);
#endif
/* Cache callback before release timeout timer */
index = item->index;
callback = item->callback;
context = item->context;
param = item->param;
/* Free memory */
capwap_hash_delete(timeout->itemsreference, &index);
capwap_itemlist_free(itemlist);
/* */
if (callback) {
callback(timeout, index, context, param);
}
return index;
}
/* */
int capwap_timeout_wait(long durate) {
if (durate < 0) {
return -1;
} else if (durate > 0) {
if (usleep((useconds_t)durate * 1000)) {
return ((errno == EINTR) ? 0 : -1);
}
}
return 1;
}

View File

@ -1,49 +1,49 @@
#ifndef __CAPWAP_TIMEOUT_HEADER__
#define __CAPWAP_TIMEOUT_HEADER__
#include "capwap_hash.h"
#include "capwap_list.h"
/* */
#define CAPWAP_TIMEOUT_BITFIELD_SIZE 128
#define CAPWAP_TIMEOUT_INFINITE -1
#define CAPWAP_TIMEOUT_INDEX_NO_SET 0
/* */
struct capwap_timeout {
uint32_t timeoutbitfield[CAPWAP_TIMEOUT_BITFIELD_SIZE];
struct capwap_hash* itemsreference;
struct capwap_list* itemstimeout;
};
/* */
typedef void (*capwap_timeout_expire)(struct capwap_timeout* timeout, unsigned long index, void* context, void* param);
struct capwap_timeout_item {
unsigned long index;
long durate;
struct timeval expire;
capwap_timeout_expire callback;
void* context;
void* param;
};
/* */
struct capwap_timeout* capwap_timeout_init(void);
void capwap_timeout_free(struct capwap_timeout* timeout);
/* */
unsigned long capwap_timeout_createtimer(struct capwap_timeout* timeout);
void capwap_timeout_deletetimer(struct capwap_timeout* timeout, unsigned long index);
/* */
unsigned long capwap_timeout_set(struct capwap_timeout* timeout, unsigned long index, long durate, capwap_timeout_expire callback, void* context, void* param);
void capwap_timeout_unset(struct capwap_timeout* timeout, unsigned long index);
void capwap_timeout_unsetall(struct capwap_timeout* timeout);
long capwap_timeout_getcoming(struct capwap_timeout* timeout);
unsigned long capwap_timeout_hasexpired(struct capwap_timeout* timeout);
int capwap_timeout_wait(long durate);
#endif /* __CAPWAP_TIMEOUT_HEADER__ */
#ifndef __CAPWAP_TIMEOUT_HEADER__
#define __CAPWAP_TIMEOUT_HEADER__
#include "capwap_hash.h"
#include "capwap_list.h"
/* */
#define CAPWAP_TIMEOUT_BITFIELD_SIZE 128
#define CAPWAP_TIMEOUT_INFINITE -1
#define CAPWAP_TIMEOUT_INDEX_NO_SET 0
/* */
struct capwap_timeout {
uint32_t timeoutbitfield[CAPWAP_TIMEOUT_BITFIELD_SIZE];
struct capwap_hash* itemsreference;
struct capwap_list* itemstimeout;
};
/* */
typedef void (*capwap_timeout_expire)(struct capwap_timeout* timeout, unsigned long index, void* context, void* param);
struct capwap_timeout_item {
unsigned long index;
long durate;
struct timeval expire;
capwap_timeout_expire callback;
void* context;
void* param;
};
/* */
struct capwap_timeout* capwap_timeout_init(void);
void capwap_timeout_free(struct capwap_timeout* timeout);
/* */
unsigned long capwap_timeout_createtimer(struct capwap_timeout* timeout);
void capwap_timeout_deletetimer(struct capwap_timeout* timeout, unsigned long index);
/* */
unsigned long capwap_timeout_set(struct capwap_timeout* timeout, unsigned long index, long durate, capwap_timeout_expire callback, void* context, void* param);
void capwap_timeout_unset(struct capwap_timeout* timeout, unsigned long index);
void capwap_timeout_unsetall(struct capwap_timeout* timeout);
long capwap_timeout_getcoming(struct capwap_timeout* timeout);
unsigned long capwap_timeout_hasexpired(struct capwap_timeout* timeout);
int capwap_timeout_wait(long durate);
#endif /* __CAPWAP_TIMEOUT_HEADER__ */