static int put_ip(void *priv, void *data) { uint8_t ** dptr = (uint8_t **)priv; cw_acip_t *acip=(cw_acip_t*)data; uint8_t * dst = *dptr; uint8_t *d = dst+4; d+=cw_put_sockaddr(d,&acip->ip); d+=cw_put_word(d,acip->wtp_count); int fam = sock_addrfamily(&acip->ip); int elem_id=-1; switch (fam) { case AF_INET: elem_id = CW_ELEM_CAPWAP_CONTROL_IPV4_ADDRESS; break; case AF_INET6: elem_id = CW_ELEM_CAPWAP_CONTROL_IPV6_ADDRESS; break; default: cw_log(LOG_ERR,"Unknown adress family %d",fam); break; } if (elem_id != -1 ) { d+=cw_put_elem_hdr(dst,elem_id,d-dst-4); *dptr = d-4; } return 1; }
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); }
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 capwap_out_capwap_control_ip_address(struct cw_ElemHandler * eh, struct cw_ElemHandlerParams * params, uint8_t * dst) { char key[CW_KTV_MAX_KEY_LEN]; int i; int wtps; cw_KTV_t * address; uint8_t *d; d = dst; i=0; do { /* uint8_t * msg;*/ int l; sprintf(key,"%s/address.%d",eh->key,i); address = cw_ktv_get(params->conn->local_cfg,key,CW_TYPE_IPADDRESS); sprintf(key,"%s/wtps.%d",eh->key,i); wtps = cw_ktv_get_word(params->conn->local_cfg,key,0); i++; if (address==NULL){ break; } /* msg = d;*/ l = address->type->len(address); switch(eh->id){ case CAPWAP_ELEM_CAPWAP_CONTROL_IPV4_ADDRESS: if (l!=4){ continue; } break; case CAPWAP_ELEM_CAPWAP_CONTROL_IPV6_ADDRESS: if (l!=16){ continue; } break; default: continue; } l = address->type->put(address,d+4); l+=cw_put_word(dst+4+l,wtps); l+=cw_put_elem_hdr(d,eh->id,l); cw_dbg_elem(DBG_ELEM_OUT,params->conn,params->msgdata->type,eh,d+4,l-4); d+=l; }while(address != NULL); return d-dst; }
int cw_out_generic(struct conn *conn, struct cw_action_out *a, uint8_t * dst) // ,struct mbag_item * item) { /* Get the item to put */ struct mbag_item *item = NULL; if (a->get) { item = a->get(conn, a); } /* Size for msg elem header depends on vendor specific payload */ int start = a->vendor_id ? 10 : 4; int len; if (!item) { const char *vendor=""; if ( a->vendor_id ) { vendor=cw_strvendor(a->vendor_id); } if (a->mand) { cw_log(LOG_ERR, "Can't put mandatory element %s%d - (%s) into %s. No value found.", vendor, a->elem_id, cw_strelemp(conn->actions, a->elem_id) , cw_strmsg(a->msg_id) ); } else{ cw_dbg(DBG_WARN,"No output for element %s%d -(%s) in %s. Item %s not found.", vendor, a->elem_id, cw_strelemp(conn->actions, a->elem_id) , cw_strmsg(a->msg_id),a->item_id); } return 0; } else { len = cw_put_item(dst + start, item); } if (a->vendor_id) return len + cw_put_elem_vendor_hdr(dst, a->vendor_id, a->elem_id, len); return len + cw_put_elem_hdr(dst, a->elem_id, len); }
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_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); }
int cw_put_elem_radio_administrative_state(uint8_t *dst,int radio_id,mbag_t radio) { cw_put_byte(dst+4,radio_id); cw_put_byte(dst+5,mbag_get_byte(radio,CW_RADIO_ADMIN_STATE,9)); return 2 + cw_put_elem_hdr(dst,CW_ELEM_RADIO_ADMINISTRATIVE_STATE,2); }
int cw_out_ac_name(uint8_t * dst,cw_item *item) { uint8_t *data = item->data; int len = cw_put_data(dst+4,data,strlen(data)); return len + cw_put_elem_hdr(str,CW_ELEM_AC_NAME,len); }