int capwap_out_wtp_descriptor(struct conn *conn, struct cw_action_out *a, uint8_t * dst) { mbag_t mbag = conn->config; // XXX Dummy WTP Descriptor Header uint8_t *d = dst+4; //int n =conn->radios->count; //printf("radio count %d\n",n); d+=cw_put_byte(d,conn->radios->count); //max radios d+=cw_put_byte(d,2); //radios in use d+=cw_put_encryption_subelems(d,conn->capwap_mode); mbag_item_t * i; i = mbag_get(mbag,CW_ITEM_WTP_HARDWARE_VERSION); if ( i ) { d += cw_put_version(d,CW_SUBELEM_WTP_HARDWARE_VERSION,i->data); if (bstrv_get_vendor_id(i->data)){ d += cw_put_dword(d, 0); d += cw_put_word(d, CW_SUBELEM_WTP_HARDWARE_VERSION); d += cw_put_word(d, bstrv_len(i->data)); d += cw_put_data(d, bstrv_data(i->data), bstrv_len(i->data)); } } else { cw_log(LOG_ERR, "Can't send Hardware Version in WTP Descriptor, not set."); } i = mbag_get(mbag,CW_ITEM_WTP_SOFTWARE_VERSION); if ( i ) { d += cw_put_version(d,CW_SUBELEM_WTP_SOFTWARE_VERSION,i->data); } else { cw_log(LOG_ERR, "Can't send Software Version in WTP descriptor, not set."); } i = mbag_get(mbag,CW_ITEM_WTP_BOOTLOADER_VERSION); if ( i ) { d += cw_put_version(d,CW_SUBELEM_WTP_BOOTLOADER_VERSION,i->data); } else { cw_log(LOG_ERR, "Can't send Bootloader Version in WTP descriptor, not set."); } int len = d-dst-4; return len + cw_put_elem_hdr(dst,a->elem_id,len); }
static void wtpman_run_discovery(void *arg) { struct wtpman *wtpman = (struct wtpman *) arg; time_t timer = cw_timer_start(10); extern cw_actionlist_in_t the_tree; wtpman->conn->capwap_state = CW_STATE_DISCOVERY; wtpman->conn->actions = &capwap_actions; wtpman->conn->outgoing = mbag_create(); wtpman->conn->incomming = mbag_create(); while (!cw_timer_timeout(timer) && wtpman->conn->capwap_state == CW_STATE_DISCOVERY) { cw_read_messages(wtpman->conn); } struct mbag_item *wn = mbag_get(wtpman->conn->incomming, CW_ITEM_WTP_NAME); if (wn) { // printf("WTP Name: %s\n", wn->data); // exit(0); } wtpman_remove(wtpman); return; }
int cisco_out_ac_descriptor(struct conn *conn,struct cw_action_out * a,uint8_t *dst) { uint8_t *d = dst+4; struct mbag_item * i; i = mbag_get(conn->local,CW_ITEM_AC_STATUS); if (!i) { cw_log(LOG_ERR,"Can't send AC Descriptor, no AC Status Item found"); return 0; } d+=cw_put_ac_status(d ,(struct cw_ac_status*)(i->data),conn); /* Send back the same software as the WTP has, otherwise the AP wants us to send an image */ i = mbag_get(conn->incomming,CW_ITEM_WTP_SOFTWARE_VERSION); //i = mbag_get(conn->local,CW_ITEM_AC_SOFTWARE_VERSION); if ( i ) { d += cw_put_version(d,1,i->data); } else { cw_log(LOG_ERR, "Can't set Cisco Software Version in AC descriptor, No value defined."); } i = mbag_get(conn->local,CW_ITEM_AC_HARDWARE_VERSION); if ( i ) { d += cw_put_version(d,0,i->data); } else { cw_log(LOG_ERR, "Can't set Cisco Hardware Version in AC descriptor, No value defined."); } int len = d-dst-4; return len + cw_put_elem_hdr(dst,a->elem_id,len); }
int cw_in_check_img_data_req_wtp(struct conn *conn, struct cw_action_in *a, uint8_t * data, int len,struct sockaddr *from) { mbag_set_dword(conn->outgoing,CW_ITEM_RESULT_CODE,0); conn->capwap_state=CW_STATE_IMAGE_DATA; //usleep(100000); return 0; return CW_RESULT_IMAGE_DATA_ERROR; return 0; /* Check for mandatory elements */ cw_action_in_t * mlist[60]; int n = cw_check_missing_mand(mlist,conn,a); if (n) { cw_dbg_missing_mand(DBG_ELEM,conn,mlist,n,a); conn->capwap_state=CW_STATE_JOIN; return CW_RESULT_MISSING_MAND_ELEM; } struct mbag_item *i = mbag_get(conn->incomming,CW_ITEM_IMAGE_IDENTIFIER); if (i) { uint32_t vendor_id = vendorstr_get_vendor_id(i->data); const char * image_dir; image_dir = mbag_get_str(conn->local,CW_ITEM_AC_IMAGE_DIR,"./img"); char * image_filename = malloc(6+vendorstr_len(i->data)+1+strlen(image_dir)); if (!image_filename) return CW_RESULT_IMAGE_DATA_ERROR; sprintf(image_filename,"%s%04X/%s",image_dir,vendor_id,vendorstr_data(i->data)); FILE *infile = fopen(image_filename,"rb"); if (!infile){ cw_log(LOG_WARNING,"Can't open image file: %s - %s - requestet by WTP", image_filename,strerror(errno)); free(image_filename); return CW_RESULT_IMAGE_DATA_ERROR; } mbag_set_str(conn->outgoing,CW_ITEM_IMAGE_FILENAME,image_filename); mbag_set_dword(conn->outgoing,CW_ITEM_RESULT_CODE,0); conn->capwap_state=CW_STATE_IMAGE_DATA; return 0; } return CW_RESULT_IMAGE_DATA_ERROR; }
int cw_out_ac_descriptor(struct conn *conn,struct cw_action_out * a,uint8_t *dst) { uint8_t *d = dst+4; struct mbag_item * i; i = mbag_get(conn->local,CW_ITEM_AC_STATUS); if (!i) { cw_log(LOG_ERR,"Can't send AC Descriptor, no AC Status Item found"); return 0; } d+=cw_put_ac_status(d ,(struct cw_ac_status*)(i->data)); i = mbag_get(conn->local,CW_ITEM_AC_HARDWARE_VERSION); if ( i ) { d += cw_put_version(d,CW_SUBELEM_AC_HARDWARE_VERSION,i->data); } else { cw_log(LOG_ERR, "Can't send hard version in AC descriptor, not set."); } i = mbag_get(conn->local,CW_ITEM_AC_SOFTWARE_VERSION); if ( i ) { d += cw_put_version(d,CW_SUBELEM_AC_SOFTWARE_VERSION,i->data); } else { cw_log(LOG_ERR, "Can't send software version in AC descriptor, not set."); } int len = d-dst-4; return len + cw_put_elem_hdr(dst,a->elem_id,len); }
static void wtpman_image_data(struct wtpman *wtpman) { struct conn *conn = wtpman->conn; /* Image upload */ const char *filename = mbag_get_str(conn->outgoing, CW_ITEM_IMAGE_FILENAME, NULL); if (!filename) { cw_log(LOG_ERR, "Can't send image to %s. No Image Filename Item found.", sock_addr2str(&conn->addr)); return; } cw_dbg(DBG_INFO, "Sending image file '%s' to '%s'.", filename, sock_addr2str(&conn->addr)); FILE *infile = fopen(filename, "rb"); if (infile == NULL) { cw_log(LOG_ERR, "Can't open image %s: %s", sock_addr2str(&conn->addr), strerror(errno)); return; } CW_CLOCK_DEFINE(clk); cw_clock_start(&clk); mbag_item_t *eof = mbag_set_const_ptr(conn->outgoing, CW_ITEM_IMAGE_FILEHANDLE, infile); int rc = 0; while (conn->capwap_state == CW_STATE_IMAGE_DATA && rc == 0 && eof != NULL) { rc = cw_send_request(conn, CW_MSG_IMAGE_DATA_REQUEST); eof = mbag_get(conn->outgoing, CW_ITEM_IMAGE_FILEHANDLE); } if (rc) { cw_log(LOG_ERR, "Error sending image to %s: %s", sock_addr2str(&conn->addr), cw_strrc(rc)); } else { cw_dbg(DBG_INFO, "Image '%s' sucessful sent to %s in %0.1f seconds.", filename, sock_addr2str(&conn->addr), cw_clock_stop(&clk)); conn->capwap_state = CW_STATE_NONE; } fclose(infile); wtpman_remove(wtpman); }
int cw_out_capwap_control_ip_addr_list(struct conn *conn,struct cw_action_out *a,uint8_t *dst) { struct mbag_item * item = mbag_get(conn->local,a->item_id); if ( !item ) { cw_log(LOG_ERR, "Can't send CAPWAP Local IPv4/IPv6 Address, not found"); return 0; } cw_aciplist_t aciplist = (cw_aciplist_t) mbag_item_get_data_ptr(item); uint8_t *d = dst; cw_aciplist_foreach(aciplist, put_ip, &d); mbag_item_release_data_ptr(item,aciplist); return d-dst; }
int cw_detect_capwap(struct conn *conn) { mbag_t is = conn->incomming; mbag_item_t * item = mbag_get(is,CW_ITEM_WTP_SOFTWARE_VERSION); if (item) { vendorstr_t s = item->data; uint32_t v = vendorstr_get_vendor_id(s); switch(v) { case CW_VENDOR_ID_CISCO: cw_set_capwap_mode(conn,CW_MODE_CISCO); break; default: cw_set_capwap_mode(conn,CW_MODE_CAPWAP); break; } } return 0; }
int cw_in_check_join_resp(struct conn *conn, struct cw_action_in *a, uint8_t * data, int len,struct sockaddr *from) { cw_action_in_t * mlist[60]; mbag_item_t * jresult = mbag_get(conn->incomming,CW_ITEM_RESULT_CODE); if (jresult ) { if (!cw_rcok(jresult->dword)){ return jresult->dword; } } /* Check for mandatory elements */ int n = cw_check_missing_mand(mlist,conn,a); if (n && conn->strict_capwap) { cw_dbg_missing_mand(DBG_MSG_ERR,conn,mlist,n,a); conn->capwap_state=CW_STATE_JOIN; errno=EAGAIN; return -1; //CW_RESULT_MISSING_MAND_ELEM; } if (n){ cw_dbg_missing_mand(DBG_RFC,conn,mlist,n,a); } if ( jresult ) { return jresult->dword; } /* set result code to ok and change to configure state */ // mbag_set_dword(conn->outgoing,CW_ITEM_RESULT_CODE,0); return 0; }
int main() { signal (SIGINT, sig_handler); wtpconf_preinit(); if (!read_config("./wtp_uci.conf")) { return 1; } // cw_dbg_opt_level = conf_dbg_level; if (!wtpconf_init()){ return 1; }; cw_dbg_opt_display = DBG_DISP_ASC_DMP | DBG_DISP_COLORS; dtls_init(); the_conn = conn_create_noq(-1, NULL); struct conn *conn = the_conn; conn->radios = mbag_i_create(); conn->radios_upd=mbag_i_create(); mbag_i_set_mbag(conn->radios,0,mbag_create()); mbag_i_set_mbag(conn->radios_upd,0,mbag_create()); #define CWMOD "cisco" #define CWBIND "cisco" //#define CWMOD "capwap" //#define CWBIND "capwap80211" struct mod_wtp *mod = modload_wtp(CWMOD); if (!mod) { printf("Can't load mod capwap\n"); exit(0); } mod->init(); mod->register_actions(&capwap_actions,MOD_MODE_CAPWAP); mod = modload_wtp(CWBIND); if (!mod) { printf("Can't load mod capwap80211\n"); exit(0); } int rc = mod->register_actions(&capwap_actions,MOD_MODE_BINDINGS); conn->detected = 1; conn->dtls_verify_peer=0; conn->dtls_mtu = 12000; conn->actions = &capwap_actions; conn->outgoing = mbag_create(); conn->incomming = mbag_create(); conn->local = mbag_create(); conn->config = mbag_create(); the_conn->strict_capwap = 0; cfg_from_json(conn); setup_conf(conn); mbag_t r; // r = mbag_i_get_mbag(conn->radios,0,NULL); r = conn->radios; MAVLITER_DEFINE(it,r); mavliter_foreach(&it){ struct mbag_item *i=mavliter_get(&it); printf("RID = %d\n",i->iid); printf("DATA: %p\n",i->data); mbag_t radio= (mbag_t)i->data; struct mbag_item *mri = mbag_get(radio,CW_RADIOITEM80211_WTP_RADIO_INFORMATION); if (!mri){ printf("Setting to 8 %p %p\n",mri,r); mbag_set_dword(radio,CW_RADIOITEM80211_WTP_RADIO_INFORMATION,1); } else{ printf("MRI %p\n",mri); } } mod_init_config(mod,conn->config); cfg_to_json(); mbag_t mb = mbag_get_mbag(conn->config, CW_ITEM_WTP_BOARD_DATA, NULL); printf("mbag %p\n", mb); cw_acpriolist_t acprios = cw_acpriolist_create(); cw_acpriolist_set(acprios, "Master AC", strlen("Master AC"), 1); cw_acpriolist_set(acprios, "AC8new", strlen("AC8new"), 12); mbag_set_byte(conn->local, CW_ITEM_WTP_MAC_TYPE, CW_WTP_MAC_TYPE_SPLIT); mbag_set_byte(conn->local, CW_ITEM_WTP_FRAME_TUNNEL_MODE, CW_WTP_FRAME_TUNNEL_MODE_E); conn->wbid=1; // cw_set_msg_end_callback(conn->actions,CW_STATE_RUN,CW_MSG_CONFIGURATION_UPDATE_REQUEST,handle_update_req); if (!discovery()) return -1; if (!join()) return -1; if (!configure()) return -1; cw_dbg(DBG_X,"Saveing config 0"); cfg_to_json(); changestate(); run(); //image_update(); return 0; }