common: Add strongly typed element iteration macros
Rather than always iterating elements from frames with pure u8 pointers, add a type "struct element" that encapsulates the id/datalen/data format of them. Then, add the element iteration macros * for_each_element * for_each_element_id * for_each_element_extid which take, as their first 'argument', such a structure and iterate through a given u8 array interpreting it as elements. While at it also add * for_each_subelement * for_each_subelement_id * for_each_subelement_extid which instead of taking data/length just take an outer element and use its data/datalen. Also add for_each_element_completed() to determine if any of the loops above completed, i.e., it was able to parse all of the elements successfully and no data remained. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
51c83edfca
commit
0e0c31bdc5
1 changed files with 53 additions and 0 deletions
|
@ -12,6 +12,12 @@
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
#include "ieee802_11_defs.h"
|
#include "ieee802_11_defs.h"
|
||||||
|
|
||||||
|
struct element {
|
||||||
|
u8 id;
|
||||||
|
u8 datalen;
|
||||||
|
u8 data[];
|
||||||
|
} STRUCT_PACKED;
|
||||||
|
|
||||||
struct hostapd_hw_modes;
|
struct hostapd_hw_modes;
|
||||||
|
|
||||||
#define MAX_NOF_MB_IES_SUPPORTED 5
|
#define MAX_NOF_MB_IES_SUPPORTED 5
|
||||||
|
@ -214,4 +220,51 @@ int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep,
|
||||||
|
|
||||||
int ieee802_11_ext_capab(const u8 *ie, unsigned int capab);
|
int ieee802_11_ext_capab(const u8 *ie, unsigned int capab);
|
||||||
|
|
||||||
|
/* element iteration helpers */
|
||||||
|
#define for_each_element(_elem, _data, _datalen) \
|
||||||
|
for (_elem = (const struct element *) (_data); \
|
||||||
|
(const u8 *) (_data) + (_datalen) - (const u8 *) _elem >= \
|
||||||
|
(int) sizeof(*_elem) && \
|
||||||
|
(const u8 *) (_data) + (_datalen) - (const u8 *) _elem >= \
|
||||||
|
(int) sizeof(*_elem) + _elem->datalen; \
|
||||||
|
_elem = (const struct element *) (_elem->data + _elem->datalen))
|
||||||
|
|
||||||
|
#define for_each_element_id(element, _id, data, datalen) \
|
||||||
|
for_each_element(element, data, datalen) \
|
||||||
|
if (element->id == (_id))
|
||||||
|
|
||||||
|
#define for_each_element_extid(element, extid, _data, _datalen) \
|
||||||
|
for_each_element(element, _data, _datalen) \
|
||||||
|
if (element->id == WLAN_EID_EXTENSION && \
|
||||||
|
element->datalen > 0 && \
|
||||||
|
element->data[0] == (extid))
|
||||||
|
|
||||||
|
#define for_each_subelement(sub, element) \
|
||||||
|
for_each_element(sub, (element)->data, (element)->datalen)
|
||||||
|
|
||||||
|
#define for_each_subelement_id(sub, id, element) \
|
||||||
|
for_each_element_id(sub, id, (element)->data, (element)->datalen)
|
||||||
|
|
||||||
|
#define for_each_subelement_extid(sub, extid, element) \
|
||||||
|
for_each_element_extid(sub, extid, (element)->data, (element)->datalen)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* for_each_element_completed - Determine if element parsing consumed all data
|
||||||
|
* @element: Element pointer after for_each_element() or friends
|
||||||
|
* @data: Same data pointer as passed to for_each_element() or friends
|
||||||
|
* @datalen: Same data length as passed to for_each_element() or friends
|
||||||
|
*
|
||||||
|
* This function returns 1 if all the data was parsed or considered
|
||||||
|
* while walking the elements. Only use this if your for_each_element()
|
||||||
|
* loop cannot be broken out of, otherwise it always returns 0.
|
||||||
|
*
|
||||||
|
* If some data was malformed, this returns %false since the last parsed
|
||||||
|
* element will not fill the whole remaining data.
|
||||||
|
*/
|
||||||
|
static inline int for_each_element_completed(const struct element *element,
|
||||||
|
const void *data, size_t datalen)
|
||||||
|
{
|
||||||
|
return (const u8 *) element == (const u8 *) data + datalen;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* IEEE802_11_COMMON_H */
|
#endif /* IEEE802_11_COMMON_H */
|
||||||
|
|
Loading…
Reference in a new issue