diff --git a/src/cmdu_validate.c b/src/cmdu_validate.c index c4df27805a6209834e45341208315fc27229192f..7f394db0d823e9276cd15993547fac390d5d69e2 100644 --- a/src/cmdu_validate.c +++ b/src/cmdu_validate.c @@ -104,6 +104,14 @@ static int check_supported_band_tlv(struct tlv *t) sizeof(struct tlv_supported_band)); } +/* Check 1905.1 AL MAC address type TLV */ +static int check_client_assoc_event_tlv(struct tlv *t) +{ + /* macaddr (6 bytes) + macaddr (6 bytes) + assoc event (1 byte) */ + return check_serialized_tlv(t, + sizeof(struct tlv_client_assoc_event)); +} + static int check_service_tlv(struct tlv *t) { int offset = 0; @@ -824,3 +832,41 @@ bool validate_ap_autoconfig_response(struct cmdu_buff *cmdu, struct tlv *tv[][16 return true; } + +bool validate_topology_notification(struct cmdu_buff *cmdu, struct tlv *tv[][16]) +{ + struct tlv_policy a_policy[] = { + [0] = { .type = TLV_TYPE_AL_MAC_ADDRESS_TYPE, + .present = TLV_PRESENT_ONE, + .minlen = 6, + .maxlen = 6, + }, + [1] = { .type = MAP_TLV_CLIENT_ASSOCIATION_EVENT, + .present = TLV_PRESENT_OPTIONAL_MORE, + .minlen = 13, + .maxlen = 13, + } + }; + int ret; + int num = 0; + + trace("%s |" MACFMT "|CMDU: ap autoconfig response\n", + __func__, MAC2STR(cmdu->origin)); + + ret = cmdu_parse_tlvs(cmdu, tv, a_policy, 2); + if (ret) { + dbg("%s: parse_tlv failed\n", __func__); + return false; + } + + /* Parse SupportedRole TLV */ + if (check_al_mac_addr_type_tlv(tv[0][0])) + return false; + + while (tv[1][num]) { + if (check_client_assoc_event_tlv(tv[1][num++])) + return false; + } + + return true; +} diff --git a/src/cmdu_validate.h b/src/cmdu_validate.h index d173b6da23adc01da9ce8db44fabe4cd31cd22f4..61f8052c51694c39ca7231a9aa0a9c6ed608e2c3 100644 --- a/src/cmdu_validate.h +++ b/src/cmdu_validate.h @@ -9,5 +9,6 @@ bool validate_topology_response(struct cmdu_buff *cmdu, struct tlv *tv_tsp[][16] bool validate_ap_autoconfig_wsc(struct cmdu_buff *cmdu, struct tlv *tv[][16]); bool validate_ap_autoconfig_search(struct cmdu_buff *cmdu, struct tlv *tv[][16]); bool validate_ap_autoconfig_response(struct cmdu_buff *cmdu, struct tlv *tv[][16]); +bool validate_topology_notification(struct cmdu_buff *cmdu, struct tlv *tv[][16]); #endif // CMDU_VALIDATE diff --git a/src/cntlr_map.c b/src/cntlr_map.c index a1dec51628e020fa83f879c2e6eb51accc0e885d..78b270ab68f351a61b028d0f3ce56a7badba2cc1 100644 --- a/src/cntlr_map.c +++ b/src/cntlr_map.c @@ -63,6 +63,42 @@ struct map_cmdu_calltable_t { int handle_topology_notification(void *cntlr, struct cmdu_buff *cmdu) { trace("%s: --->\n", __func__); + struct controller *c = (struct controller *) cntlr; + struct tlv *tv[2][16] = {0}; + struct tlv_aladdr *aladdr_tlv; + uint8_t *aladdr; + int num = 0; + + if (!validate_topology_notification(cmdu, tv)) { + dbg("cmdu validation: [TOPOLOGY_NOTIFICATION] failed\n"); + return -1; + } + + aladdr_tlv = (struct tlv_aladdr *) tv[0][0]->data; + aladdr = aladdr_tlv->macaddr; + + if (tv[1][num]) { + /* client connect event*/ + } else { + /* neighbor addition event */ + struct node *n; + uint8_t wildcard[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + struct node_policy *np; + + np = agent_find_policy(c, aladdr); + if (!np) + return -1; + + n = find_node_by_mac(c, aladdr); + if (!n) + return -1; + + cmdu = cntlr_gen_policy_config_req(cntlr, aladdr, np, 0, + wildcard, 1, wildcard); + if (!cmdu) + return -1; + } + return 0; }