genl: Implement message nesting
PATCH 1/2 genl: Implement message nesting
--- ell/genl.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ ell/genl.h | 2 ++ 2 files changed, 50 insertions(+)
ell/genl.c +48 -0
@@ -37,6 +37,8 @@#include "genl-private.h" #include "private.h" +#define MAX_NESTING_LEVEL 4 +struct l_genl {int ref_count;int fd;
@@ -65,6 +67,8 @@ struct l_genl_msg {void *data;uint32_t size;uint32_t len; +struct nlattr *nests[MAX_NESTING_LEVEL ]; +uint8_t nesting_level; };struct genl_request {
@@ -241,6 +245,7 @@ static struct l_genl_msg *msg_alloc(uint8_t cmd, uint8_t version, uint32_t size) msg->size = msg->len +NLMSG_ALIGN (size); msg->data = l_new(unsigned char, msg->size); + msg->nesting_level =0 ;return l_genl_msg_ref (msg); }
@@ -737,6 +742,49 @@ LIB_EXPORT bool l_genl_msg_append_attr(struct l_genl_msg *msg, uint16_t type,return true; } +LIB_EXPORT bool l_genl_msg_enter_nested(struct l_genl_msg *msg, uint16_t type) +{ +struct nlattr *nla; + +if (unlikely (!msg)) +return false; + +if (unlikely (msg->nesting_level ==MAX_NESTING_LEVEL )) +return false; + +if (msg->len +NLA_HDRLEN > msg->size) +return false; + + nla = msg->data + msg->len; + nla->nla_type = type; + nla->nla_len = msg->len;/* Save position */ + + msg->nests[msg->nesting_level] = nla; + msg->nesting_level +=1 ; + + msg->len +=NLA_HDRLEN ; + +return true; +} + +LIB_EXPORT bool l_genl_msg_leave_nested(struct l_genl_msg *msg) +{ +struct nlattr *nla; + +if (unlikely (!msg)) +return false; + +if (unlikely (msg->nesting_level ==0 )) +return false; + + nla = msg->nests[msg->nesting_level -1 ]; + nla->nla_len = msg->len - nla->nla_len; + + msg->nesting_level -=1 ; + +return true; +} +#define NLA_OK (nla,len) ((len) >= (int) sizeof(struct nlattr) && \ (nla)->nla_len >= sizeof(struct nlattr) && \ (nla)->nla_len <= (len))
ell/genl.h +2 -0
@@ -71,6 +71,8 @@ int l_genl_msg_get_error(struct l_genl_msg *msg);bool l_genl_msg_append_attr (struct l_genl_msg *msg,uint16_t type,uint16_t len,const void *data); +bool l_genl_msg_enter_nested (struct l_genl_msg *msg,uint16_t type); +bool l_genl_msg_leave_nested (struct l_genl_msg *msg);bool l_genl_attr_init (struct l_genl_attr *attr,struct l_genl_msg *msg); bool l_genl_attr_next(struct l_genl_attr *attr, uint16_t *type,
Signature · 1 line
2.0.4
PATCH 2/2 unit: Add unit test to build set rekey offload
--- unit/test-genl-msg.c | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-)
unit/test-genl-msg.c +43 -1
@@ -31,7 +31,7 @@#include "ell/genl-private.h" -static bool do_print = false; +static bool do_print = true;static void do_debug (const char *str,void *user_data) {
@@ -204,6 +204,46 @@ static void parse_set_rekey_offload(const void *data)l_genl_msg_unref (msg); } +static void build_set_rekey_offload (const void *data) +{ +static uint32_t index =3 ; +static const unsigned char kek[] = { +0x2f ,0x82 ,0xbb ,0x0d ,0x93 ,0x56 ,0x60 ,0x4b , +0xb1 ,0x55 ,0x1c ,0x85 ,0xc0 ,0xeb ,0x32 ,0x8b }; +static const unsigned char kck[] = { +0x43 ,0x25 ,0xcf ,0x08 ,0x0b ,0x92 ,0xa7 ,0x2d , +0x86 ,0xdc ,0x43 ,0x21 ,0xd6 ,0x0c ,0x12 ,0x03 }; +static const unsigned char replay_counter[] = { +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x01 }; +struct l_genl_msg *msg; +const void *raw; +size_t size; + + msg =l_genl_msg_new_sized (79 ,512 ); +assert (msg); + +assert (l_genl_msg_append_attr (msg,3 ,4 , &index)); + +assert (l_genl_msg_enter_nested (msg,122 )); +assert (l_genl_msg_append_attr (msg,1 ,16 , kek)); +assert (l_genl_msg_append_attr (msg,2 ,16 , kck)); +assert (l_genl_msg_append_attr (msg,3 ,8 , replay_counter)); +assert (l_genl_msg_leave_nested (msg)); + + raw =_genl_msg_as_bytes (msg,0x1b ,0x05 ,0x53e1a359 ,0xe74002ba , + &size); +if (do_print) { +l_util_hexdump (false, raw, size, do_debug,"[MSG] " ); +l_util_hexdump (true, set_rekey_offload_request, size, + do_debug,"[MSG] " ); + } + +assert (size ==sizeof (set_rekey_offload_request)); +assert (!memcmp (raw, set_rekey_offload_request, size)); + +l_genl_msg_unref (msg); +} +int main (int argc,char *argv[]) {l_test_add ("Parse Set Station Request" , parse_set_station,NULL );
@@ -211,6 +251,8 @@ int main(int argc, char *argv[]) parse_set_rekey_offload, NULL);l_test_add ("Build Set Station Request" , build_set_station,NULL ); +l_test_add ("Build Set Rekey Offload Request" , + build_set_rekey_offload,NULL );return l_test_run (); }
Signature · 1 line
2.0.4