void cw_init_request(struct conn *conn, int msg_id) { uint8_t *buffer = conn->req_buffer; /* zero the first 8 bytes */ cw_put_dword(buffer + 0, 0); cw_put_dword(buffer + 4, 0); /* unencrypted */ cw_set_hdr_preamble(buffer, CAPWAP_VERSION << 4 | 0); cw_set_hdr_rmac(buffer, conn->base_rmac); //cw_set_hdr_hlen(buffer, 2); cw_set_hdr_wbid(buffer, conn->wbid); cw_set_hdr_rid(buffer, 0); uint8_t *msgptr = cw_get_hdr_msg_offset(buffer) + buffer; cw_set_msg_type(msgptr, msg_id); cw_set_msg_flags(msgptr, 0); cw_set_msg_elems_len(msgptr, 0); }
int cw_put_item(uint8_t * dst, struct mbag_item *item) { if (MBAG_STR == item->type ){ return cw_put_data(dst, item->data, strlen((char *) item->data)); } if (MBAG_BYTE == item->type){ return cw_put_byte(dst, item->byte); } if (MBAG_WORD == item->type){ return cw_put_word(dst, item->word); } if (MBAG_DWORD == item->type){ return cw_put_dword(dst, item->dword); } if (MBAG_BSTR == item->type) { return cw_put_bstr(dst, item->data); } if ( MBAG_BSTR16 == item->type) return cw_put_bstr16(dst,item->data); if (MBAG_VENDORSTR == item->type) { int l=0; l+=cw_put_dword(dst, bstrv_get_vendor_id(item->data)); l+=cw_put_data(dst+4, bstrv_data(item->data),bstrv_len(item->data)); return l; } cw_log(LOG_ERR,"No method to put items of type %d",item->type); return 0; }
int conn_send_msg(struct conn * conn, uint8_t *rawmsg) { int packetlen = cw_get_hdr_msg_total_len(rawmsg); cw_dbg_msg(DBG_MSG_OUT, conn,rawmsg, packetlen,(struct sockaddr*)&conn->addr); /* Zyxel doesn't count msg element length from behind seqnum */ if (conn->capwap_mode == CW_MODE_ZYXEL){ // XXX val-=3; } uint8_t * ptr = rawmsg; int fragoffset = 0; int hlen = cw_get_hdr_hlen(rawmsg)*4; int mtu = conn->mtu; while (packetlen>mtu){ cw_set_hdr_flags(rawmsg,CW_FLAG_HDR_F,1); cw_put_dword(ptr+4, conn->fragid<<16 | fragoffset<<3 ); cw_dbg_pkt(DBG_PKT_OUT,conn,ptr,mtu,(struct sockaddr*)&conn->addr); if (conn->write(conn,ptr,mtu)<0) return -1; // XXX Fragmentation stuff.. ptr +=mtu-hlen; fragoffset+=(mtu-hlen)/8; packetlen-=mtu-hlen; } if (fragoffset) cw_set_hdr_flags(rawmsg,CW_FLAG_HDR_F | CW_FLAG_HDR_L,1); else cw_set_hdr_flags(rawmsg,CW_FLAG_HDR_F,0); cw_put_dword(ptr+4, conn->fragid<<16 | fragoffset<<3 ); cw_dbg_pkt(DBG_PKT_OUT,conn,ptr,packetlen,(struct sockaddr*)&conn->addr); return conn->write(conn,ptr,packetlen-0); }
void cw_init_data_msg(struct conn *conn) { uint8_t *buffer = conn->req_buffer; cw_put_dword(buffer + 0, 0); cw_put_dword(buffer + 4, 0); /* unencrypted */ cw_set_hdr_preamble(buffer, CAPWAP_VERSION << 4 | 0); }
int cw_put_mbag_item(uint8_t * dst, struct mbag_item *item) { if (item->type->put){ cw_dbg(DBG_X,"User put method to put "); return item->type->put(item,dst); } if (MBAG_STR == item->type ){ return cw_put_data(dst, item->data, strlen((char *) item->data)); } if (MBAG_DATA == item->type){ return cw_put_data(dst, item->data+1, *((uint8_t*)item->data)); } if (MBAG_BYTE == item->type){ return cw_put_byte(dst, item->byte); } if (MBAG_WORD == item->type){ return cw_put_word(dst, item->word); } if (MBAG_DWORD == item->type){ return cw_put_dword(dst, item->dword); } if (MBAG_BSTR == item->type) { return cw_put_bstr(dst, item->data); } if ( MBAG_BSTR16 == item->type) return cw_put_bstr16(dst,item->data); if (MBAG_VENDORSTR == item->type) { int l=0; l+=cw_put_dword(dst, bstrv_get_vendor_id(item->data)); l+=cw_put_data(dst+4, bstrv_data(item->data),bstrv_len(item->data)); return l; } if (MBAG_MBAG == item->type){ *((void**)dst)=item->data; return sizeof(void *); } cw_log(LOG_ERR,"No method to put items of type %s",item->type->name); return 0; }
int cw_put_elem_radio_info(uint8_t*dst,int radio_id,mbag_t radio) { cw_put_byte(dst+4,radio_id); cw_put_dword(dst+5,mbag_get_dword(radio,CW_RADIO_TYPE,0)); return 5 + cw_put_elem_hdr(dst,CW_ELEM80211_WTP_RADIO_INFORMATION,5); }
/** * Put an cw_ac_stauts structure to a buffer * @param dst destination buffer * @param s #cw_ac_status to put * @return number of bytes put * This function is only useful (used) in conjunction with * putting AC Descriptor message elements. */ int cw_put_ac_status(uint8_t * dst, struct cw_ac_status *s, struct conn * conn) { uint8_t *d = dst; d += cw_put_dword(d, (s->stations << 16) | (s->limit)); d += cw_put_dword(d, (s->active_wtps << 16) | (s->max_wtps)); int security = 0; security |= conn->dtls_cert_file ? CW_FLAG_AC_SECURITY_X : 0; security |= conn->dtls_psk ? CW_FLAG_AC_SECURITY_S : 0; d += cw_put_dword(d, (security << 24) | (s->rmac_field << 16) | (s->dtls_policy)); return d - dst; }
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); }
int conn_send_msg(struct conn * conn, uint8_t *rawmsg) { int packetlen = cw_get_hdr_msg_total_len(rawmsg); cw_dbg_msg(DBG_MSG_OUT, conn,rawmsg, packetlen,(struct sockaddr*)&conn->addr); //uint8_t * msgptr = rawmsg + cw_get_hdr_msg_offset(rawmsg); /* Zyxel doesn't count msg element length from behind seqnum */ if (conn->capwap_mode == CW_MODE_ZYXEL){ // XXX val-=3; } uint8_t * ptr = rawmsg; int fragoffset = 0; int hlen = cw_get_hdr_hlen(rawmsg)*4; //cw_set_hdr_hlen(rawmsg,223); //*(rawmsg + 8)=99; //cw_set_hdr_flags(rawmsg,CW_FLAG_HDR_M,1); int mtu = conn->mtu; while (packetlen>mtu){ cw_set_hdr_flags(rawmsg,CW_FLAG_HDR_F,1); cw_put_dword(ptr+4, conn->fragid<<16 | fragoffset<<3 ); cw_dbg_pkt(DBG_PKT_OUT,conn,ptr,mtu,(struct sockaddr*)&conn->addr); //XXX { // char h[200]; // hdr_print(h,ptr,mtu); // cw_dbg(DBG_PKT_OUT,"Sending capwap packet to %s:\n%s",sock_addr2str(&conn->addr),h); } // cw_dbg_dmp(DBG_PKT_DMP,ptr,mtu,"Sending packet ..."); if (conn->write(conn,ptr,mtu)<0) return -1; ptr +=mtu-hlen; fragoffset+=(mtu-hlen)/8; packetlen-=mtu-hlen; //XXX if (hlen>8) // memcpy(ptr+8,cwmsg->ctrlhdr+8,hlen-8); } // val = (preamble << 24) | ((hlen/4)<<19) | (cwmsg->rid<<14) |(wbid<<9) | /*CWTH_FLAGS_T|*/ //cwmsg->flags; //printf("VAL = %08x, %08x\n",val,cwmsg->flags); //printf("FRag offset :::::::::::::::::::::::::::: %d\n",fragoffset); if (fragoffset) cw_set_hdr_flags(rawmsg,CW_FLAG_HDR_F | CW_FLAG_HDR_L,1); else cw_set_hdr_flags(rawmsg,CW_FLAG_HDR_F,0); // printf("Setting first byte %08X\n",val); // *((uint32_t*)ptr)=htonl(val); // val = conn->fragid<<16 | fragoffset<<3; // *((uint32_t*)(ptr+4))=htonl(val); cw_put_dword(ptr+4, conn->fragid<<16 | fragoffset<<3 ); { // char h[1024]; // hdr_print(h,ptr,msglen-fragoffset*8+hlen); // cw_dbg(DBG_CW_PKT_OUT,"Sending capwap packet to %s:\n%s",sock_addr2str(&conn->addr),h); } // cw_dbg_dmp(DBG_PKT_DMP,ptr,packetlen,"Sending packet ..."); //return conn->write(conn,ptr,msglen-fragoffset*8+hlen); //printf("Send packet len %p %d\n",ptr,packetlen); cw_dbg_pkt(DBG_PKT_OUT,conn,ptr,packetlen,(struct sockaddr*)&conn->addr); return conn->write(conn,ptr,packetlen-0); }
static int put(const struct cw_KTV *data, uint8_t * dst) { return cw_put_dword(dst, data->val.dword); }