diff --git a/src/cw/Makefile b/src/cw/Makefile index 76221f23..20931be9 100644 --- a/src/cw/Makefile +++ b/src/cw/Makefile @@ -59,6 +59,7 @@ CWSRC=\ cw_in_check_join_resp.c\ cw_in_generic.c\ cw_in_generic_struct.c\ + cw_out_generic_struct.c\ cw_init_data_keep_alive_msg.c\ cw_inline.c\ cw_in_radio_generic.c\ @@ -96,7 +97,6 @@ CWSRC=\ cw_type_ipaddress.c\ cw_type_word.c\ cw_type_sysptr.c\ - cw_util.c\ cw_write_descriptor_subelem.c\ cw_read_from.c \ cw_write_radio_element.c\ @@ -123,13 +123,13 @@ KTVSRC=\ cw_ktv_read_file.c\ cw_ktv_readline.c\ cw_ktv_read_struct.c\ + cw_ktv_write_struct.c\ cw_ktv_std_types.c\ LWSRC=\ lw_addelem.c\ lw_checksum.c\ - lw_cisco_id_to_str.c\ lw_elem_id_to_str.c\ lw_inline.c\ lw_msg_id_to_str.c\ @@ -138,7 +138,6 @@ LWSRC=\ lw_put_ac_descriptor.c\ lw_put_bstr.c\ lw_put_str.c\ - lw_put_cisco_path_mtu.c\ lw_put_image_data.c\ lw_put_sockaddr.c\ lw_readelem_wtp_name.c\ @@ -172,6 +171,7 @@ MAVLSRC=\ MLISTSRC=\ mlist_append.c\ + mlist_delete.c\ mlist_append_ptr.c\ mlist_create.c\ mlist_destroy.c\ diff --git a/src/cw/capwap_strings_elem.c b/src/cw/capwap_strings_elem.c index 32f56e1d..4eb78521 100644 --- a/src/cw/capwap_strings_elem.c +++ b/src/cw/capwap_strings_elem.c @@ -15,8 +15,8 @@ struct cw_StrListElem capwap_strings_elem[] = { {CW_ELEM_RESERVED_9, "Reserved 9"}, {CW_ELEM_CAPWAP_CONTROL_IPV4_ADDRESS, "Control IPv4 Address"}, {CW_ELEM_CAPWAP_CONTROL_IPV6_ADDRESS, "Control IPv6 Address"}, - {CW_ELEM_CAPWAP_LOCAL_IPV4_ADDRESS, "CAWPAP Local IPv4 Address"}, - {CW_ELEM_CAPWAP_LOCAL_IPV6_ADDRESS, "CAPWAP Local IPv6 Address"}, + {CAPWAP_ELEM_CAPWAP_LOCAL_IPV4_ADDRESS, "CAWPAP Local IPv4 Address"}, + {CAPWAP_ELEM_CAPWAP_LOCAL_IPV6_ADDRESS, "CAPWAP Local IPv6 Address"}, {CW_ELEM_CAPWAP_TIMERS, "CAPWAP Timers"}, {CW_ELEM_CAPWAP_TRANSPORT_PROTOCOL, "CAPWAP Transport Protocol"}, {CW_ELEM_DATA_TRANSFER_DATA, "Data Transfer Data"}, @@ -36,7 +36,7 @@ struct cw_StrListElem capwap_strings_elem[] = { {CW_ELEM_IMAGE_INFORMATION, "Image Information"}, {CW_ELEM_INITIATE_DOWNLOAD, "Initiate Download"}, {CAPWAP_ELEM_LOCATION_DATA, "Location Data"}, - {CW_ELEM_MAXIMUM_MESSAGE_LENGTH, "Maximum Message Length"}, + {CAPWAP_ELEM_MAXIMUM_MESSAGE_LENGTH, "Maximum Message Length"}, {CAPWAP_ELEM_MTU_DISCOVERY_PADDING, "MTU Discovery Padding"}, {CW_ELEM_RADIO_ADMINISTRATIVE_STATE, "Radio Administrative State"}, {CW_ELEM_RADIO_OPERATIONAL_STATE, "Radio Operational State"}, diff --git a/src/cw/conn.h b/src/cw/conn.h index d55291eb..27904277 100644 --- a/src/cw/conn.h +++ b/src/cw/conn.h @@ -39,11 +39,10 @@ /*#include "mbag.h"*/ #include "intavltree.h" - +#include "bstr.h" #include "mod.h" - struct cw_action_in; #define CONN_MAX_MSG_LENGTH 65536 diff --git a/src/cw/cw.h b/src/cw/cw.h index f5b0078e..03b933d1 100644 --- a/src/cw/cw.h +++ b/src/cw/cw.h @@ -399,7 +399,10 @@ int cw_in_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHandlerP int cw_out_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params , uint8_t * dst); - + +int cw_out_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params + , uint8_t * dst); + int cw_in_radio_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params, uint8_t * elem_data, int elem_len); @@ -486,6 +489,11 @@ int cw_put_elem_radio_administrative_state(uint8_t * dst, int rid, int state); +int cw_put_local_ip_address(uint8_t *dst, int id, int ipv_id, int ipv6_id, + uint8_t *src, int len); + + + uint8_t *cw_init_data_keep_alive_msg(uint8_t * buffer,uint8_t *rmac); /*int cw_out_radio_generic(struct conn *conn, struct cw_action_out *a, uint8_t * dst);*/ diff --git a/src/cw/cw_ktv_write_struct.c b/src/cw/cw_ktv_write_struct.c index e69de29b..27b56dad 100644 --- a/src/cw/cw_ktv_write_struct.c +++ b/src/cw/cw_ktv_write_struct.c @@ -0,0 +1,35 @@ +#include "ktv.h" +#include "dbg.h" +#include "log.h" + +int cw_ktv_write_struct(mavl_t ktv, const cw_KTVStruct_t * stru, const char *pkey, + uint8_t * dst) +{ + char key[CW_KTV_MAX_KEY_LEN]; + int pos, i; + cw_KTV_t * result; + + pos=0; i=0; + for(i=0; stru[i].type != NULL;i++){ + + if (stru[i].position!=-1){ + pos=stru[i].position; + } + memset(dst+pos,0,stru[i].len); + + sprintf(key,"%s/%s",pkey,stru[i].key); + result = cw_ktv_get(ktv,key,stru[i].type); + + if (result == NULL){ + cw_log(LOG_ERR,"Can't put %s, no value found",key); + continue; + } + + result->type->put(result,dst+pos); + + pos+=stru[i].len; + + } + + return pos; +} diff --git a/src/cw/cw_out_generic_struct.c b/src/cw/cw_out_generic_struct.c index e69de29b..42d1152f 100644 --- a/src/cw/cw_out_generic_struct.c +++ b/src/cw/cw_out_generic_struct.c @@ -0,0 +1,30 @@ +#include "capwap.h" +#include "msgset.h" +#include "ktv.h" +#include "log.h" +#include "cw.h" + +int cw_out_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params + , uint8_t * dst) +{ + int start; + int len,l; + + start = handler->vendor ? 10 : 4; + + if (!handler->type){ + cw_log(LOG_ERR,"Can't handle element: %s, no type defined",handler->name); + return CAPWAP_RESULT_UNRECOGNIZED_MESSAGE_ELEMENT; + } + + len = cw_ktv_write_struct(params->conn->local_cfg,handler->type,handler->key,dst+start); + + if (handler->vendor) + return len + cw_put_elem_vendor_hdr(dst, handler->vendor, handler->id, len); + + l = len + cw_put_elem_hdr(dst, handler->id, len); + + return l; + + +} diff --git a/src/cw/cw_process_element.c b/src/cw/cw_process_element.c index d3d1b450..e08630a1 100644 --- a/src/cw/cw_process_element.c +++ b/src/cw/cw_process_element.c @@ -25,6 +25,7 @@ int cw_process_element(struct cw_ElemHandlerParams *params, int proto, int vendo /* try to retrieve a handler for this message element */ handler = cw_msgset_get_elemhandler(params->conn->msgset,proto, vendor, elem_id); if (!handler) { + cw_dbg(DBG_ELEM_ERR, "Unrecognized message element: %d, ignoring", elem_id); return CAPWAP_RESULT_UNRECOGNIZED_MESSAGE_ELEMENT; diff --git a/src/cw/cw_put_local_ip_address.c b/src/cw/cw_put_local_ip_address.c index 471db6ee..cf621037 100644 --- a/src/cw/cw_put_local_ip_address.c +++ b/src/cw/cw_put_local_ip_address.c @@ -7,47 +7,26 @@ #include "dbg.h" #include "cw.h" -int cw_put_local_ip_address(int sock, uint8_t *dst, int ipv4elem_id, int ipv6elem_id) +int cw_put_local_ip_address(uint8_t *dst, int id, int ipv4_id, int ipv6_id, + uint8_t *src, int len) { - struct sockaddr_storage a; - int id; - - socklen_t alen = sizeof(struct sockaddr_storage); - int rc = getsockname(sock, (struct sockaddr *) &a, &alen); - if (rc != 0){ - cw_log(LOG_ERR,"Can't determine sock IP address - %s\n",strerror(errno)); - return 0; + if (len ==4 && id == ipv4_id){ + cw_put_data(dst + 4, src, 4); + return 4 + cw_put_elem_hdr(dst, id, 4); } - - - switch (((struct sockaddr *) &a)->sa_family) { - case AF_INET: - { - struct sockaddr_in *sain = (struct sockaddr_in *) &a; - id = ipv4elem_id; - cw_put_data(dst + 4, (uint8_t *) & sain->sin_addr, 4); - return 4 + cw_put_elem_hdr(dst, id, 4); - } - - case AF_INET6: - { - struct sockaddr_in6 *sain; - id = ipv6elem_id; - sain = (struct sockaddr_in6 *) &a; - cw_put_data(dst + 4, (uint8_t *) & sain->sin6_addr, 16); - return 16 + cw_put_elem_hdr(dst, id, 16); - - } + if (len ==16 && id == ipv6_id){ + + cw_put_data(dst + 4, src, 16); + return 4 + cw_put_elem_hdr(dst, id, 4); } - - cw_log(DBG_MSG_ERR, "Can't determine CAPWAP Local IP Adress"); return 0; - } + + diff --git a/src/cw/cw_type_ipaddress.c b/src/cw/cw_type_ipaddress.c index fc7f4096..08bd585a 100644 --- a/src/cw/cw_type_ipaddress.c +++ b/src/cw/cw_type_ipaddress.c @@ -102,6 +102,10 @@ static int len ( struct cw_KTV * data ){ return bstr_len(data->val.ptr); } +static void * data(cw_KTV_t * data) +{ + return bstr_data(data->val.ptr); +} const struct cw_Type cw_type_ipaddress = { "IPAddress", /* name */ @@ -110,7 +114,8 @@ const struct cw_Type cw_type_ipaddress = { get, /* get */ to_str, /* to_str */ from_str, /* from_str */ - len /* len */ + len, /* len */ + data /* data */ }; diff --git a/src/cw/cw_util.c b/src/cw/cw_util.c deleted file mode 100644 index 13a74d89..00000000 --- a/src/cw/cw_util.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - This file is part of libcapwap. - - libcapwap is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - libcapwap is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Foobar. If not, see . - -*/ - - -#include - -#include "cw_util.h" -#include "log.h" -#include "capwap.h" - -/* -void cw_mand_elem_found(int *l,int type) -{ - if (!cw_dbg_is_level(DBG_CW_RFC)) - return; - - int i; - for (i=0; l[i]!=-1; i++){ - if(l[i]==type){ - l[i]=0; - return; - } - - } -} -*/ - -/* -void cw_get_missing_mand_elems(char *dst, int *l) -{ - if (!cw_dbg_is_level(DBG_CW_RFC)) - return; - - char *s = dst; - int i; - const char * k = ""; - for (i=0; l[i]!=-1; i++){ - if(l[i]){ - s += sprintf(s,"%s[%s]",k,cw_strelem(l[i])); - k=","; - } - - } -} -*/ - -/* -int cw_is_missing_mand_elems(int *l) -{ - int i; - for (i=0; l[i]!=-1; i++){ - if(l[i]){ - return 1; - } - } - return 0; -} - -*/ diff --git a/src/cw/dbg.c b/src/cw/dbg.c index 3475f8f2..2b62738e 100644 --- a/src/cw/dbg.c +++ b/src/cw/dbg.c @@ -521,7 +521,7 @@ void cw_dbg_ktv_dump(mavl_t ktv, uint32_t dbglevel, type = data->type; type->to_str(data,value,0); - cw_dbg(dbglevel,"%s%s (%s): %s",prefix,data->key,type->name, value); + cw_dbg(dbglevel,"%s%s :%s: %s",prefix,data->key,type->name, value); } if (footer != NULL) diff --git a/src/cw/dtls_gnutls_accept.c b/src/cw/dtls_gnutls_accept.c index 4bff8228..4b702bc2 100644 --- a/src/cw/dtls_gnutls_accept.c +++ b/src/cw/dtls_gnutls_accept.c @@ -102,7 +102,7 @@ int dtls_gnutls_accept(struct conn *conn) if (tlen < 0 && errno == EAGAIN) continue; if (tlen < 0) { - /* something went wrong, iwe should log a message */ + /* something went wrong, we should log a message */ continue; } diff --git a/src/cw/ktv.h b/src/cw/ktv.h index 01c59414..f5622168 100644 --- a/src/cw/ktv.h +++ b/src/cw/ktv.h @@ -93,6 +93,10 @@ struct cw_KTVStruct { typedef struct cw_KTVStruct cw_KTVStruct_t; int cw_ktv_read_struct(mavl_t ktv,const cw_KTVStruct_t * stru, const char *pkey, uint8_t * data, int len); +int cw_ktv_write_struct(mavl_t ktv, const cw_KTVStruct_t * stru, const char *pkey, + uint8_t * dst); + + extern const struct cw_Type cw_type_byte; extern const struct cw_Type cw_type_word; diff --git a/src/cw/lw_addelem.c b/src/cw/lw_addelem.c index fbc524ec..efea646f 100644 --- a/src/cw/lw_addelem.c +++ b/src/cw/lw_addelem.c @@ -2,13 +2,13 @@ #include "lwapp.h" -#include "lwapp_cisco.h" +/*#include "lwapp_cisco.h"*/ #include "lw.h" #include "vendors.h" - +/* int lw_addelem(uint8_t*dst, uint8_t type, uint8_t *msgelem, uint16_t len) { *dst = type; @@ -30,11 +30,15 @@ int lw_addelem_vendor_specific(uint8_t *dst,uint32_t vendor_id,uint16_t elem_id, lw_set_word(dst+1,l); return l; } +*/ + /** * Add the vendor specific elem Cisco Padding * @param dst destination */ + +/* int lw_addelem_cisco_padding(uint8_t *dst, int len) { lw_set_dword(dst+3,LW_VENDOR_ID_CISCO); @@ -43,6 +47,7 @@ int lw_addelem_cisco_padding(uint8_t *dst, int len) memset(dst+11,0,len); return lw_put_elem_hdr(dst,LW_ELEM_VENDOR_SPECIFIC,11+len); } +*/ /* int lw_put_cisco_path_mtu(uint8_t *dst, uint16_t max, uint16_t padding) diff --git a/src/cw/mlist.h b/src/cw/mlist.h index 668fdadb..d97a0882 100644 --- a/src/cw/mlist.h +++ b/src/cw/mlist.h @@ -72,6 +72,8 @@ typedef struct mlist * mlist_t; mlist_t mlist_create(int (*cmp) (const void *v1, const void *v2), void (*del)(void *), size_t data_size); struct mlistelem *mlist_append(mlist_t l, void *data); +struct mlistelem * mlist_delete(mlist_t list, void *data); + struct mlistelem * mlist_get(mlist_t list, const void *data); void mlist_destroy(mlist_t l); struct mlistelem *mlist_replace(mlist_t l, void *data); diff --git a/src/cw/mlist_delete.c b/src/cw/mlist_delete.c index d48cda23..f35187ee 100644 --- a/src/cw/mlist_delete.c +++ b/src/cw/mlist_delete.c @@ -1,17 +1,60 @@ #include +#include #include "mlist.h" -struct mlistelem * mlist_replace(mlist_t list, void *data) +struct mlistelem * mlist_delete(mlist_t list, void *data) { struct mlistelem *e; - e = mlist_get(list,data); + mlist_foreach(e,list){ + void *tdata = mlistelem_dataptr(e); + if (list->cmp(tdata,data)==0){ + break; + } + } + if (e == NULL) return NULL; + if (e->prev==NULL && e->next==NULL){ + if (list->del) + list->del(e); + free(e); + list->count=0; + list->first=NULL; + list->last=NULL; + return NULL; + } + if (e==list->first){ + list->first=e->next; + e->next->prev=NULL; + if (list->del) + list->del(e); + list->count--; + free(e); + return NULL; + + } + + if (e==list->last){ + list->last=e->prev; + e->prev->next=NULL; + if (list->del) + list->del(e); + list->count--; + free(e); + return NULL; + + } - return e; + e->next->prev=e->prev; + e->prev->next=e->next; + if (list->del) + list->del(e); + list->count--; + free(e); + return NULL; } diff --git a/src/cw/msgset.c b/src/cw/msgset.c index 9a1bd38f..1096239b 100644 --- a/src/cw/msgset.c +++ b/src/cw/msgset.c @@ -198,11 +198,12 @@ static int update_msgdata(struct cw_MsgSet *set, struct cw_MsgData *msgdata, elemdef->vendor, elemdef->id, handler->name); } - /* add message elemeent to the elements list */ + /* add/delete/replace message elemeent to/from/in the elements list */ switch ( elemdef->op & 0xff){ case CW_IGNORE: break; case CW_DELETE: + mlist_delete(msgdata->elements_list, &ed); break; case CW_APPEND: mlist_append(msgdata->elements_list, &ed);