diff --git a/src/cntlr_cmdu.c b/src/cntlr_cmdu.c index 8d4a85b5d7eed86658f797bf1f34bd94ade23d3e..4863e4242eebe69a2cd11c6b03af07bcf4ee0ec3 100644 --- a/src/cntlr_cmdu.c +++ b/src/cntlr_cmdu.c @@ -521,7 +521,11 @@ out: } struct cmdu_buff *cntlr_gen_ap_autoconfig_response(struct controller *c, - uint8_t *dest, uint8_t band, uint16_t mid) +#if (EASYMESH_VERSION > 2) + struct dpp_enrollee *e, bool hash_validity, +#endif + uint8_t *dest, uint8_t band, uint16_t mid + ) { struct cmdu_buff *resp; int ret; @@ -553,11 +557,13 @@ struct cmdu_buff *cntlr_gen_ap_autoconfig_response(struct controller *c, ret = cntlr_gen_device_1905_layer_security_cap(c, resp); if (ret) goto out; -#if 0 - ret = cntlr_gen_chirp_value_tlv(c, resp); - if (ret) - goto out; -#endif + + if (e) { + ret = cntlr_gen_chirp_value_tlv(c, resp, e->mac, 32, e->hash); + if (ret) + goto out; + } + ret = cntlr_gen_cntlr_capability(c, resp, 0x00); if (ret) goto out; @@ -1072,7 +1078,10 @@ error: } #if (EASYMESH_VERSION > 2) -struct cmdu_buff *cntlr_gen_direct_encap_dpp(struct controller *c) +struct cmdu_buff *cntlr_gen_direct_encap_dpp(struct controller *c, + uint8_t *dst, + uint16_t framelen, + uint8_t *frame) { struct cmdu_buff *frm; uint16_t mid = 0; @@ -1086,7 +1095,7 @@ struct cmdu_buff *cntlr_gen_direct_encap_dpp(struct controller *c) } /* One DPP Message TLV */ - if (cntlr_gen_dpp_message_tlv(c, frm)) { + if (cntlr_gen_dpp_message_tlv(c, frm, framelen, frame)) { dbg("%s: cntlr_gen_dpp_message_tlv failed.\n", __func__); goto out; } diff --git a/src/cntlr_cmdu.h b/src/cntlr_cmdu.h index 968c24a04b58ec9951876a48faa116d26c2cef9a..a2ab5fd81ba1132cec13e005b20d14cae3e3a9fa 100644 --- a/src/cntlr_cmdu.h +++ b/src/cntlr_cmdu.h @@ -42,6 +42,9 @@ struct cmdu_buff *cntlr_gen_unassoc_sta_metric_query(struct controller *c, struct cmdu_buff *cntlr_gen_ap_autoconfig_search(struct controller *c, uint8_t profile, uint8_t band); struct cmdu_buff *cntlr_gen_ap_autoconfig_response(struct controller *c, +#if (EASYMESH_VERSION > 2) + struct dpp_enrollee *e, bool hash_validity, +#endif uint8_t *dest, uint8_t band, uint16_t mid); struct cmdu_buff *cntlr_gen_ap_autoconfig_wsc(struct controller *c, struct node *n, struct cmdu_buff *rx_cmdu, uint8_t *radio_id, @@ -99,7 +102,10 @@ struct cmdu_buff *cntlr_gen_proxied_encap_dpp(struct controller *c, uint8_t *frame, uint16_t hashlen, uint8_t *hash); -struct cmdu_buff *cntlr_gen_direct_encap_dpp(struct controller *c); +struct cmdu_buff *cntlr_gen_direct_encap_dpp(struct controller *c, + uint8_t *dst, + uint16_t framelen, + uint8_t *frame); struct cmdu_buff *cntrl_gen_bss_configuration_response(struct controller *c, struct cmdu_buff *request_cmdu); struct cmdu_buff *cntlr_gen_dpp_cce_indication(struct controller *c, uint8_t *agent, bool cce_advertise); diff --git a/src/cntlr_map.c b/src/cntlr_map.c index 832376a5d80719ce4c182ac19462e3de56aee3f3..09c94389ffe56b0d8d723810b06ef268591ef04e 100644 --- a/src/cntlr_map.c +++ b/src/cntlr_map.c @@ -950,6 +950,9 @@ int handle_ap_autoconfig_search(void *cntlr, struct cmdu_buff *rx_cmdu, struct controller *c = (struct controller *) cntlr; struct tlv_autoconfig_band *freq; struct tlv_aladdr *aladdr; +#if (EASYMESH_VERSION > 2) + struct dpp_enrollee *e = NULL; +#endif struct tlv *t; struct cmdu_buff *cmdu; uint8_t almac[6] = {0}; @@ -1042,9 +1045,47 @@ int handle_ap_autoconfig_search(void *cntlr, struct cmdu_buff *rx_cmdu, if (tv[3][0]) handle_supported_service(c, almac, tv[3][0]); +#if (EASYMESH_VERSION > 2) + if (tv[6][0]) { + int offset = 0; + uint8_t flag = 0; + bool mac_present; + bool hash_validity; + uint8_t *mac; + uint8_t hashlen; + uint8_t *hash; + + flag = tv[6][0]->data[offset++]; + + mac_present = (flag & DPP_CHIRP_ENROLLEE_MAC_PRESENT); + hash_validity = (flag & DPP_CHIRP_HASH_VALIDITY); + UNUSED(hash_validity); + + if (mac_present) { + mac = &tv[6][0]->data[offset]; + UNUSED(mac); + offset += 6; + } + + hashlen = tv[6][0]->data[offset++]; + hash = &tv[6][0]->data[offset]; + err("|%s:%d| hashlen:%d\n", __func__, __LINE__, hashlen); + dump(hash, hashlen, "autoconf search chirp hash"); + e = dpp_enrollee_get_hash(c, hash); + if (e) { + err("|%s:%d| WE FOUND A MATCH FOR AUTOCONIFG SEARCH!\n", __func__, __LINE__); + } + } + +#endif + trace("%s: sending autoconfig response for band = %d, node %p\n", __func__, freq->band, n); - cmdu = cntlr_gen_ap_autoconfig_response(cntlr, almac, + cmdu = cntlr_gen_ap_autoconfig_response(cntlr, +#if (EASYMESH_VERSION > 2) + e, !!e, +#endif + almac, freq->band, cmdu_get_mid(rx_cmdu)); if (!cmdu) @@ -3564,23 +3605,101 @@ int handle_direct_encap_dpp(void *cntlr, struct cmdu_buff *cmdu, struct node *n) { trace("%s: --->\n", __func__); - struct controller *c = (struct controller *)cntlr; struct tlv *tlv; struct tlv *tlvs[DIRECT_ENCAP_DPP_MAX_NUMBER_OF_TLV_TYPES][TLV_MAXNUM] = { 0 }; + struct tlv_dpp_message *dpp_msg; + uint16_t framelen; + uint8_t *frame; + int frametype; + struct dpp_enrollee *e = NULL; + struct dpp_frame *dpp_frm; + + UNUSED(c); if (!validate_direct_encap_dpp(cmdu, tlvs)) { dbg("cmdu validation: [DIRECT_ENCAP_DPP] failed\n"); return -1; } + /* POSSIBLY MID CHECK HERE? */ + /* One DPP Message TLV */ tlv = tlvs[DIRECT_ENCAP_DPP_MESSAGE_IDX][0]; - (void) tlv; - (void) c; + dpp_msg = (struct tlv_dpp_message *) tlv->data; - // TODO: process DPP Message TLV + frame = dpp_msg->frame; + framelen = tlv->len; + if (FRAME_IS_DPP_PUB_AF(frame)) + frametype = dpp_get_pub_af_type(frame, framelen); + else if (FRAME_IS_DPP_GAS_FRAME(frame)) + frametype = dpp_get_gas_frame_type(frame, framelen); + else + return -1; + + if (frametype == 255) + return -1; + + /* Encapsulated frame length */ + dump(frame, framelen, "DIRECT CMDU FRAME"); + + if (frametype == DPP_PA_PRESENCE_ANNOUNCEMENT) { + uint16_t attrlen = 0; + uint8_t *pos; + + pos = dpp_get_attr(frame + 7, /* meta data to attributes */ + framelen - 7, + DPP_ATTR_R_BOOTSTRAP_KEY_HASH, + &attrlen); + if (pos) { + struct dpp_chirp *chirp; + + chirp = dpp_chirp_get(c, pos); + if (!chirp) { + dbg("|%s:%d| matching chrip not found, allocate\n", + __func__, __LINE__); + chirp = dpp_chirp_alloc(c, pos); + if (!chirp) { + dbg("|%s:%d| Failed to allocate chirp\n", + __func__, __LINE__); + goto out; + } + } + + //if (chirp->auth_req /* && chirp->chirp_fd.fd > 0 */) { + //struct dpp_frame *auth_req = chirp->auth_req; + + //socket_send_dpp_tcp_message(c->chirp_fd.fd, + // auth_req->data, + // auth_req->len); + //warn("|%s:%d| already have assoc req frame!\n", __func__, __LINE__); + //goto out; + //} + + e = dpp_enrollee_alloc(c, cmdu->origin); + if (!e) + goto out; + + e->chirp = chirp; + } + } + + if (!e) { + e = dpp_enrollee_get(c, cmdu->origin); + if (!e) { + err("|%s:%d|\n", __func__, __LINE__); + return -1; + } + } + + dpp_frm = dpp_enrollee_add_frame(c, e, frametype, framelen, frame, cmdu->origin); + if (!dpp_frm) { + dbg("|%s:%d| frame for type:%d failed to allocate!\n", __func__, + __LINE__, frametype); + return -1; + } +out: return 0; } diff --git a/src/cntlr_tlv.c b/src/cntlr_tlv.c index 041b24c1a957c8863991ab2aa81ef9c0227f0127..6303f8bc309469df7ad6a19f3d8a2f67a021500a 100644 --- a/src/cntlr_tlv.c +++ b/src/cntlr_tlv.c @@ -1680,14 +1680,10 @@ int cntlr_gen_dpp_cce_indication_tlv(struct controller *c, return 0; } -/* TODO: fill the DPP frame field */ -int cntlr_gen_dpp_message_tlv(struct controller *c, struct cmdu_buff *frm) +int cntlr_gen_dpp_message_tlv(struct controller *c, struct cmdu_buff *frm, + uint16_t framelen, uint8_t *frame) { struct tlv *t; - int offset = 0; - /* dummy values */ - int framelen = 1; - uint8_t frame[1] = { 0xff }; t = cmdu_reserve_tlv(frm, 512); if (!t) @@ -1695,14 +1691,9 @@ int cntlr_gen_dpp_message_tlv(struct controller *c, struct cmdu_buff *frm) t->type = MAP_TLV_DPP_MESSAGE; - /* DPP Frame length */ - t->data[offset++] = framelen; + memcpy(&t->data[0], frame, framelen); - /* DPP Frame */ - memcpy(&t->data[offset], frame, framelen); - offset += framelen; - - t->len = offset; + t->len = framelen; if (cmdu_put_tlv(frm, t)) return -1; diff --git a/src/cntlr_tlv.h b/src/cntlr_tlv.h index 1479c98a85a67afdd035c090bdac32078df687c0..dfc5839e143b12f65e2d3bc213a62e681895ea1f 100644 --- a/src/cntlr_tlv.h +++ b/src/cntlr_tlv.h @@ -115,8 +115,8 @@ int cntlr_gen_tlv_higher_layer_data(struct controller *c, struct cmdu_buff *frm, uint8_t proto, uint8_t *data, int len); #if (EASYMESH_VERSION > 2) -int cntlr_gen_dpp_message_tlv(struct controller *c, - struct cmdu_buff *frm); +int cntlr_gen_dpp_message_tlv(struct controller *c, struct cmdu_buff *frm, + uint16_t framelen, uint8_t *frame); int cntlr_gen_1905_encap_dpp_tlv(struct controller *c, struct cmdu_buff *frm, uint8_t *enrollee, uint8_t frametype, uint16_t framelen, uint8_t *frame); diff --git a/src/dpp.c b/src/dpp.c index 2f9e2894ce80482bb5bf028698fda9110da3b430..e97053a8e0459b97893caeda7e57d5548121d667 100644 --- a/src/dpp.c +++ b/src/dpp.c @@ -50,6 +50,7 @@ #include "utils/dpp_sock.h" #if (EASYMESH_VERSION > 2) #include "dpp.h" +#include <math.h> #endif //#include "config.h" #include "cntlr.h" @@ -193,6 +194,9 @@ struct dpp_enrollee *dpp_enrollee_get_hash(struct controller *c, uint8_t *hash) list_for_each_entry(e, &c->dpp_ctx.enrolleelist, list) { struct dpp_chirp *p = e->chirp; + if (!memcmp(e->hash, hash, 32)) + return e; + if (!p) continue; @@ -214,6 +218,7 @@ struct dpp_enrollee *dpp_enrollee_alloc(struct controller *c, uint8_t *mac) return NULL; } + e->band = BAND_UNKNOWN; e->c = c; /* TODO: deprecate */ memcpy(e->mac, mac, 6); INIT_LIST_HEAD(&e->framelist); @@ -605,6 +610,8 @@ struct dpp_enrollee *dpp_process_new_uri(struct controller *c, char *uri) char *macstr; uint8_t enrollee[6] = {0}; struct dpp_enrollee *e; + char *hashstr; + char *hashend; int rc; if (strncmp(uri, "DPP:", 4)) { @@ -614,16 +621,22 @@ struct dpp_enrollee *dpp_process_new_uri(struct controller *c, char *uri) macstr = strstr(uri, ";M:"); // find mac address in URI if (!macstr) { - dbg("|%s:%d| URI has invalid format! (Right now) MAC is mandated\n", __func__, __LINE__); - return NULL; + macstr = strstr(uri, "DPP:M:"); // find mac address in URI + if (!macstr) { + dbg("|%s:%d| URI has invalid format! (Right now) MAC is mandated\n", __func__, __LINE__); + return NULL; + } + macstr += 3; /* step past DPP identifier */ } - if (*(macstr + 15) != ';') { + macstr += 3; /* step past mac identifier */ + + + if (*(macstr + 12) != ';') { dbg("|%s:%d| URI MAC has invalid format!\n", __func__, __LINE__); return NULL; } - macstr += 3; /* step past mac identifier */ strtob(macstr, 6, enrollee); e = dpp_enrollee_get(c, enrollee); @@ -640,15 +653,32 @@ struct dpp_enrollee *dpp_process_new_uri(struct controller *c, char *uri) strncpy(e->uri, uri, sizeof(e->uri) - 1); + { + hashstr = strstr(uri, ";K:"); + hashstr += 3 + 36; /* TODO: probably step 36 is not correct, but gives correct bytes in hashb output */ + hashend = strstr(hashstr, ";"); + + if (hashstr && hashend) { + uint8_t len = 0; + uint8_t hashb[128] = {0}; + size_t hlen = 128; + + len = abs(hashend - hashstr); + rc = base64_decode((unsigned char *) hashstr, (size_t)len, (unsigned char *) hashb, &hlen); + memcpy(e->hash, hashb, hlen); + dump(e->hash, hlen, "jakob haha"); + } + } + dbg("|%s:%d| MAC "MACFMT" has URI %s\n", __func__, __LINE__, MAC2STR(e->mac), e->uri); send_dpp_cce_indication_all(c, true); rc = dpp_parse_uri_chan_list(c, e, e->uri); if (rc < 0) { - dbg("|%s:%d| URI MAC has invalid format! (Right now) Opclass/Channel list is mandated\n", __func__, __LINE__); - dpp_enrollee_free(e); - return NULL; + dbg("|%s:%d| URI chanlist has invalid format! (Right now) Opclass/Channel list is mandated\n", __func__, __LINE__); + // dpp_enrollee_free(e); + // return NULL; } if (e->num_chan) { e->band = wifi_channel_to_band(e->chan[0].channel); @@ -658,26 +688,26 @@ struct dpp_enrollee *dpp_process_new_uri(struct controller *c, char *uri) } - { - /* THIS IS A HACK */ - uint8_t bssid[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - uint8_t radio[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - struct cmdu_buff *cmdu; - int len = 0; - - len = strlen(e->uri); - cmdu = cntlr_gen_dpp_bootstrapping_uri_notification(c, radio, bssid, - enrollee, len, e->uri); - if (cmdu) { - struct node *n; - - list_for_each_entry(n, &c->nodelist, list) { - memcpy(cmdu->origin, n->alid, 6); - send_cmdu(c, cmdu); - } - cmdu_free(cmdu); - } - } +// { +// /* THIS IS A HACK */ +// uint8_t bssid[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +// uint8_t radio[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +// struct cmdu_buff *cmdu; +// int len = 0; +// +// len = strlen(e->uri); +// cmdu = cntlr_gen_dpp_bootstrapping_uri_notification(c, radio, bssid, +// enrollee, len, e->uri); +// if (cmdu) { +// struct node *n; +// +// list_for_each_entry(n, &c->nodelist, list) { +// memcpy(cmdu->origin, n->alid, 6); +// send_cmdu(c, cmdu); +// } +// cmdu_free(cmdu); +// } +// } return e; } @@ -736,6 +766,10 @@ out: return rc; } +//int dpp_handle_frame(struct controller *c, uint8_t frame) +//{ +// +//} static void dpp_fd_timeout(atimer_t *t) { diff --git a/src/dpp.h b/src/dpp.h index a32f58c6bc00aafe77509885e654f9f51c15b7e5..8da9f2527d5c2b13fe5efe92af3572cc12e5c8b2 100644 --- a/src/dpp.h +++ b/src/dpp.h @@ -125,8 +125,10 @@ struct dpp_chan { struct dpp_enrollee { struct controller *c; /* TODO: lazy, should all be part of some dpp_ctx which can be traced back to cntlr */ + uint8_t almac[6]; uint8_t mac[6]; char uri[128]; + uint8_t hash[32]; bool onboarded; uint8_t bootstrap_id; @@ -164,6 +166,7 @@ struct dpp_chirp *dpp_chirp_alloc(struct controller *c, uint8_t *hash); struct dpp_enrollee *dpp_enrollee_get(struct controller *c, uint8_t *mac); +struct dpp_enrollee *dpp_enrollee_get_hash(struct controller *c, uint8_t *hash); struct dpp_enrollee *dpp_enrollee_alloc(struct controller *c, uint8_t *mac); void dpp_enrollee_free(struct dpp_enrollee *e);