Inital commit.
FossilOrigin-Name: 9da7cbe914e6f056bfbaed633219d34df26d12d7991097d2ffac288d66a1b139
This commit is contained in:
		
							
								
								
									
										111
									
								
								src/capwap/cw_in_wtp_descriptor.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								src/capwap/cw_in_wtp_descriptor.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,111 @@ | ||||
| /* | ||||
|     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 <http://www.gnu.org/licenses/>. | ||||
|  | ||||
| */ | ||||
|  | ||||
|  | ||||
| #include "capwap.h" | ||||
| #include "capwap_items.h" | ||||
|  | ||||
| #include "wtpinfo.h" | ||||
|  | ||||
| #include "cw_util.h" | ||||
| #include "cw_log.h" | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| static int readelem_wtp_descriptor(struct conn *conn, struct cw_action_in *a, uint8_t *data, int len, int cq) | ||||
| { | ||||
|  | ||||
| 	if (len<6) | ||||
| 		return -1; | ||||
|  | ||||
| 	cw_itemstore_t itemstore = conn->itemstore; | ||||
|  | ||||
| 	cw_itemstore_set_byte(itemstore,CW_ITEM_WTP_MAX_RADIOS,cw_get_byte(data)); | ||||
| 	cw_itemstore_set_byte(itemstore,CW_ITEM_WTP_RADIOS_IN_USE,cw_get_byte(data+1)); | ||||
|  | ||||
| 	int ncrypt = cw_get_byte(data+2); | ||||
| 	int i; | ||||
| 	if (ncrypt == 0 ){ | ||||
| 		/* non-conform */ | ||||
| 		cw_dbg(DBG_CW_RFC,"Non-standard-conform WTP descriptor detected (See RFC 5415)"); | ||||
| 		if (!cq)  | ||||
| 			i=3; | ||||
| 		else | ||||
| 			i=4; | ||||
| 	} | ||||
| 	else{ | ||||
| 		i=ncrypt*3+3; | ||||
| 	} | ||||
|  | ||||
| 	do { | ||||
| 		if (i+8>len) | ||||
| 		{ | ||||
| 			cw_dbg(DBG_ELEM_ERR,"WTP descriptor subelement to long, length=%d>%d",i+8,len); | ||||
| 			return -1; | ||||
| 		} | ||||
|  | ||||
| 		uint32_t vendor_id=cw_get_dword(data+i); //ntohl(*((uint32_t*)(msgelem+i))); | ||||
|  | ||||
| 		uint32_t val = cw_get_dword(data+i+4); | ||||
| 		int subtype= (val>>16)&0xffff; | ||||
| 		int sublen = val&0xffff; | ||||
| 		i+=8; | ||||
|  | ||||
| 		if (sublen+i>len){ | ||||
| 			cw_dbg(DBG_ELEM_ERR,"WTP descriptor subelement too long, length = %d",sublen); | ||||
| 			return -1; | ||||
| 		} | ||||
|  | ||||
| 		cw_dbg(DBG_ELEM,"Reading WTP descriptor subelement, type=%d,len=%d",subtype,sublen); | ||||
| 	 | ||||
| 		switch(subtype){ | ||||
| 			case CW_SUBELEM_WTP_HARDWARE_VERSION: | ||||
| 				cw_itemstore_set_dword(itemstore,CW_ITEM_WTP_HARDWARE_VENDOR,vendor_id); | ||||
| 				cw_itemstore_set_bstrn(itemstore,CW_ITEM_WTP_HARDWARE_VERSION,data+i,sublen); | ||||
| 				break; | ||||
| 			case CW_SUBELEM_WTP_SOFTWARE_VERSION: | ||||
| 				cw_itemstore_set_dword(itemstore,CW_ITEM_WTP_SOFTWARE_VENDOR,vendor_id); | ||||
| 				cw_itemstore_set_bstrn(itemstore,CW_ITEM_WTP_SOFTWARE_VERSION,data+i,sublen); | ||||
| 				break; | ||||
| 			case CW_SUBELEM_WTP_BOOTLOADER_VERSION: | ||||
| 				cw_itemstore_set_dword(itemstore,CW_ITEM_WTP_BOOTLOADER_VENDOR,vendor_id); | ||||
| 				cw_itemstore_set_bstrn(itemstore,CW_ITEM_WTP_BOOTLOADER_VERSION,data+i,sublen); | ||||
| 				break; | ||||
| 			default: | ||||
| 				cw_dbg(DBG_ELEM_ERR,"Unknown WTP descriptor subelement, type = %d",subtype); | ||||
| 				break; | ||||
| 		} | ||||
| 		i+=sublen; | ||||
|  | ||||
| 	}while(i<len); | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| int cw_in_wtp_descriptor(struct conn *conn,struct cw_action_in * a,uint8_t *data,int len) | ||||
| { | ||||
| 	int rc =readelem_wtp_descriptor(conn, a,data,len,0); | ||||
| 	if (rc==-1){ | ||||
| 		cw_dbg(DBG_CW_RFC,"Bad WTP descriptor, trying cisco hack"); | ||||
| 		rc =readelem_wtp_descriptor(conn, a,data,len,1); | ||||
| 	} | ||||
|  | ||||
| 	return rc; | ||||
| } | ||||
|  | ||||
							
								
								
									
										30
									
								
								src/capwap/cw_msg_init.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								src/capwap/cw_msg_init.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | ||||
|  | ||||
| #include "conn.h" | ||||
| #include "capwap.h" | ||||
|  | ||||
|  | ||||
|  | ||||
| void cw_init(struct conn * conn, uint8_t *buffer, int type, int seqnum, struct radioinfo * radioinfo) | ||||
| { | ||||
|  | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| void cw_init_response(struct conn * conn, uint8_t *req) | ||||
| { | ||||
| 	uint8_t *buffer=conn->resp_buffer; | ||||
| 	int hbytes = cw_get_hdr_msg_offset(req); | ||||
| 	memcpy(buffer,req,hbytes); | ||||
|  | ||||
| 	uint8_t * msgptr = req+hbytes; | ||||
| 	uint8_t * dmsgptr = buffer+hbytes; | ||||
|  | ||||
| 	cw_set_msg_type(dmsgptr,cw_get_msg_type(msgptr)+1); | ||||
| 	cw_set_msg_seqnum(dmsgptr,cw_get_msg_seqnum(msgptr)); | ||||
| 	cw_set_msg_flags(dmsgptr,0); | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										68
									
								
								src/capwap/cw_out_ac_descriptor.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								src/capwap/cw_out_ac_descriptor.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,68 @@ | ||||
| #include "cw_log.h" | ||||
| #include "conn.h" | ||||
|  | ||||
| #include "itemstore.h" | ||||
| #include "capwap_items.h" | ||||
| #include "capwap.h" | ||||
|  | ||||
|  | ||||
| int cw_put_subelem_version(uint8_t *dst,uint16_t subelem_id, uint32_t vendor_id,bstr16_t data) | ||||
| { | ||||
| printf("Vendor putter %d\n",vendor_id); | ||||
|  | ||||
| 	uint8_t *d=dst; | ||||
| 	d += cw_put_dword(d,vendor_id); | ||||
| 	d += cw_put_dword(d, (subelem_id<<16) | bstr16_len(data)); | ||||
| 	d += cw_put_data(d,bstr16_data(data),bstr16_len(data)); | ||||
| 	return d-dst; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| int cw_out_ac_descriptor(struct conn *conn,uint32_t elem_id,uint8_t *dst,struct cw_item * item)  | ||||
| { | ||||
|  | ||||
| 	uint8_t *d = dst+4; | ||||
| 	struct cw_item * i; | ||||
| 	i = cw_itemstore_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;  | ||||
| 	} | ||||
|  | ||||
| 	struct cw_ac_status *s = (struct cw_ac_status*)(i->data); | ||||
|  | ||||
| 	d += cw_put_dword (d, (s->stations << 16) | (s->limit) ); | ||||
| 	d += cw_put_dword (d, (s->active_wtps <<16) | (s->max_wtps) ); | ||||
| 	d += cw_put_dword (d, (s->security<<24) | (s->rmac_field<<16) | (s->dtls_policy)); | ||||
|  | ||||
|  | ||||
|  | ||||
| 	i = cw_itemstore_get(conn->local,CW_ITEM_AC_HARDWARE_VERSION); | ||||
|  | ||||
| 	if ( i ) {	 | ||||
| 	 	d += cw_put_subelem_version(d,CW_SUBELEM_AC_HARDWARE_VERSION,*((uint32_t*)(i->data)),i->data+4); | ||||
| 	} | ||||
| 	else { | ||||
| 		cw_dbg(DBG_ELEM_ERR, "Can't send hard version in AC descriptor, not set."); | ||||
| 	} | ||||
|  | ||||
| 	 | ||||
| 	i = cw_itemstore_get(conn->local,CW_ITEM_AC_SOFTWARE_VERSION); | ||||
|  | ||||
| 	if ( i ) {	 | ||||
| 	 	d += cw_put_subelem_version(d,CW_SUBELEM_AC_SOFTWARE_VERSION,*((uint32_t*)(i->data)),i->data+4); | ||||
| 	} | ||||
| 	else { | ||||
| 		cw_dbg(DBG_ELEM_ERR, "Can't send software version in AC descriptor, not set."); | ||||
| 	} | ||||
|  | ||||
| 	int len = d-dst-4; | ||||
| 	 | ||||
| 	return len + cw_put_elem_hdr(dst,CW_ELEM_AC_DESCRIPTOR,len); | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										9
									
								
								src/capwap/cw_out_ac_name.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/capwap/cw_out_ac_name.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | ||||
|  | ||||
| #include "capwap.h" | ||||
|  | ||||
| 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); | ||||
| } | ||||
							
								
								
									
										61
									
								
								src/capwap/cw_out_capwap_control_ip_addrs.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								src/capwap/cw_out_capwap_control_ip_addrs.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,61 @@ | ||||
|  | ||||
| #include "cw_log.h" | ||||
|  | ||||
| #include "capwap.h" | ||||
| #include "aciplist.h" | ||||
| #include "sock.h" | ||||
|  | ||||
|  | ||||
| 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_out_capwap_control_ip_addrs(struct conn *conn,uint32_t elem_id,uint8_t *dst,struct cw_item * item) | ||||
| { | ||||
| 	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) cw_item_get_data_ptr(item); | ||||
|  | ||||
|  | ||||
| 	uint8_t *d = dst; | ||||
| 	cw_aciplist_foreach(aciplist, put_ip, &d); | ||||
|  | ||||
| 	cw_item_release_data_ptr(item,aciplist);	 | ||||
| 	return  d-dst; | ||||
| } | ||||
|  | ||||
							
								
								
									
										35
									
								
								src/capwap/cw_out_generic.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/capwap/cw_out_generic.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | ||||
|  | ||||
|  | ||||
|  | ||||
| #include "capwap.h" | ||||
| #include "capwap_items.h" | ||||
|  | ||||
|  | ||||
| int cw_put_item(uint8_t *dst,struct cw_item*item) | ||||
| { | ||||
| 	switch (item->type){ | ||||
| 		case CW_ITEMTYPE_STR: | ||||
| 			printf("Outing str %s\n",item->data); | ||||
| 			return cw_put_data(dst,item->data,strlen( (char*)item->data)); | ||||
| 		case CW_ITEMTYPE_BYTE: | ||||
| 			return cw_put_byte(dst,item->byte); | ||||
| 		case CW_ITEMTYPE_WORD: | ||||
| 			return cw_put_word(dst,item->word); | ||||
| 		case CW_ITEMTYPE_DWORD: | ||||
| 			return cw_put_word(dst,item->dword); | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| int cw_out_generic(struct conn *conn,uint32_t elem_id,uint8_t *dst,struct cw_item * item)  | ||||
| { | ||||
| 	int len; | ||||
| 	if ( !item ) | ||||
| 		len=0; | ||||
| 	else | ||||
| 		len = cw_put_item(dst+4,item); | ||||
| 	return len + cw_put_elem_hdr(dst,elem_id,len);	 | ||||
| } | ||||
|  | ||||
|  | ||||
							
								
								
									
										0
									
								
								src/capwap/cw_strnelem.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								src/capwap/cw_strnelem.c
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										18
									
								
								src/capwap/dbg.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/capwap/dbg.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | ||||
| #ifndef __DBG_H | ||||
| #define __DBG_H | ||||
|  | ||||
|  | ||||
|  | ||||
| void cw_dbg_elem_(int msg, int msgelem, const uint8_t * msgbuf, int len); | ||||
|  | ||||
|  | ||||
| #ifdef WITH_CW_LOG_DEBUG | ||||
|  | ||||
| 	#define cw_dbg_elem(msgtype,msgelemtype,msgbuf,msglen) cw_dbg_elem_(msgtype,msgelemtype,msgbuf,msglen) | ||||
|  | ||||
| #else | ||||
|  | ||||
| 	#define cw_dbg_elem(...) | ||||
| #endif | ||||
|  | ||||
| #endif | ||||
		Reference in New Issue
	
	Block a user