Image download works now.
FossilOrigin-Name: 5d7b80e25523f943c8dfbef4d31649dfb128df5d79c4c7808de1f2ea122527f1
This commit is contained in:
		| @ -111,6 +111,7 @@ static void wtpman_run_discovery(void *arg) | ||||
| 	struct conn * conn = wtpman->conn; | ||||
|  | ||||
| conn->strict_capwap=0; | ||||
| conn->capwap_mode=CW_MODE_CIPWAP; | ||||
|  | ||||
|  | ||||
| 	time_t timer = cw_timer_start(10); | ||||
| @ -299,15 +300,28 @@ static int wtpman_join(void *arg, time_t timer) | ||||
|  | ||||
| 	struct conn * conn = wtpman->conn; | ||||
|  | ||||
| conn->strict_capwap=0; | ||||
| conn->capwap_mode=CW_MODE_CIPWAP; | ||||
|  | ||||
|  | ||||
|  | ||||
| 	cw_dbg(DBG_INFO,"Join State - %s",sock_addr2str(&conn->addr)); | ||||
|  | ||||
| 	int rc; | ||||
| 	while (!cw_timer_timeout(timer) && wtpman->conn->capwap_state == CW_STATE_JOIN) { | ||||
| 		int rc = cw_read_messages(wtpman->conn); | ||||
| 		rc = cw_read_messages(wtpman->conn); | ||||
| 		if (rc < 0) { | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (rc != 0  ) { | ||||
| 		cw_log(LOG_ERR,"Error joining WTP %s",cw_strerror(rc)); | ||||
| 		return 0; | ||||
|  | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	if (wtpman->conn->capwap_state == CW_STATE_JOIN) { | ||||
| 		cw_dbg(DBG_MSG_ERR, "No join request from %s after %d seconds, WTP died.", | ||||
| 		       sock_addr2str(&wtpman->conn->addr), wtpman->conn->wait_dtls); | ||||
| @ -436,16 +450,18 @@ static void wtpman_run(void *arg) | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		cw_itemstore_set_const_ptr(conn->outgoing, CW_ITEM_IMAGE_FILEHANDLE, | ||||
| 					   infile); | ||||
|  | ||||
|  | ||||
| 		DEFINE_CLOCK(clk); | ||||
| 		cw_clock_start(&clk); | ||||
|  | ||||
| 		cw_item_t *eof = cw_itemstore_set_const_ptr(conn->outgoing, CW_ITEM_IMAGE_FILEHANDLE, | ||||
| 					   infile); | ||||
|  | ||||
| 		int rc=0; | ||||
| 	        while (conn->capwap_state == CW_STATE_IMAGE_DATA && !feof(infile) && 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 = cw_itemstore_get(conn->outgoing,CW_ITEM_IMAGE_FILEHANDLE); | ||||
| 		} | ||||
|  | ||||
|  | ||||
| @ -459,7 +475,7 @@ static void wtpman_run(void *arg) | ||||
| 		} | ||||
| 			 | ||||
| 		fclose(infile); | ||||
|  | ||||
| 		wtpman_remove(wtpman); | ||||
|  | ||||
|  | ||||
| 	} | ||||
|  | ||||
| @ -80,6 +80,7 @@ LWAPPOBJS = \ | ||||
| 	lw_msg_id_to_str.o \ | ||||
| 	lw_cisco_id_to_str.o \ | ||||
| 	lw_put_sockaddr.o \ | ||||
| 	lw_put_image_data.o | ||||
|  | ||||
| #	lw_readelem_wtp_name.o \ | ||||
| 	lw_readelem_wtp_board_data.o \ | ||||
| @ -117,6 +118,7 @@ CAPWAPOBJS= \ | ||||
| 	cw_in_check_disc_req.o \ | ||||
| 	cw_in_check_disc_resp.o\ | ||||
| 	cw_in_check_join_req.o \ | ||||
| 	cw_in_check_cipwap_join_req.o \ | ||||
| 	cw_in_check_join_resp.o \ | ||||
| 	cw_in_check_img_data_req_ac.o \ | ||||
| 	cw_in_check_img_data_req_wtp.o \ | ||||
| @ -299,6 +301,7 @@ CWACTION=action.o \ | ||||
| 	capwap_strings_result.o\ | ||||
| 	cw_put_msg.o \ | ||||
| 	capwap_action_helpers.o \ | ||||
| 	cw_put_image_data.o | ||||
|  | ||||
| #	cw_process_msg.o \ | ||||
|  | ||||
|  | ||||
| @ -89,7 +89,7 @@ static inline uint8_t * bstr16_create(uint8_t *data, uint16_t len) | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| typedef uint8_t * vendorstr_t; | ||||
|  | ||||
| #define vendorstr_get_vendor_id(str)\ | ||||
| 	( *((uint32_t*)((str)+2))) | ||||
|  | ||||
| @ -729,6 +729,7 @@ static inline int cw_put_elem_vendor_hdr(uint8_t * dst, uint32_t vendorid, | ||||
|  | ||||
| #define cw_put_sockaddr lw_put_sockaddr | ||||
|  | ||||
| int cw_put_image_data(uint8_t *dst,FILE *infile); | ||||
|  | ||||
|  | ||||
| /** | ||||
| @ -855,7 +856,7 @@ extern struct cw_str capwap_strings_result[]; | ||||
|  | ||||
| #define cw_strrc(rc) \ | ||||
| 	((rc)<0 ? ((rc)!=EAGAIN ? strerror(errno):"Timed out"): cw_strresult(rc)) | ||||
|  | ||||
| #define cw_strerror(rc) cw_strrc(rc) | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -196,6 +196,12 @@ int cw_addelem_cisco_wtp_radio_cfg(uint8_t*dst,struct radioinfo * ri); | ||||
| extern int cw_out_cisco_ac_descriptor(struct conn *conn,struct cw_action_out * a,uint8_t *dst) ; | ||||
| int cw_in_cisco_image_identifier(struct conn *conn,struct cw_action_in * a,uint8_t *data,int len,struct sockaddr *from); | ||||
|  | ||||
| int cw_in_cipwap_wtp_descriptor(struct conn *conn, struct cw_action_in *a, uint8_t * data, | ||||
| 			 int len,struct sockaddr *from); | ||||
| int cw_in_check_cipwap_join_req(struct conn *conn, struct cw_action_in *a, uint8_t * data, | ||||
| 			 int len,struct sockaddr *from); | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| /* | ||||
|  | ||||
| @ -16,6 +16,24 @@ | ||||
| 	CW_ITEM_IMAGE_IDENTIFIER,			/* ID to use store */		\ | ||||
| 	1, 4096						/* min/max length */ | ||||
|  | ||||
| #define CW_ACTION_IN_CIPWAP_WTP_DESCRIPTOR	\ | ||||
| 	CW_ELEM_WTP_DESCRIPTOR,			/* Element ID */		\ | ||||
| 	cw_in_cipwap_wtp_descriptor, 0,		/* start/end callback */	\ | ||||
| 	0,									\ | ||||
| 	CW_ITEM_WTP_DESCRIPTOR,							\ | ||||
| 	0,0								 | ||||
|  | ||||
| /* For CIPWAP we allow a  | ||||
|    Session ID with 4 .. 16 bytes length */	 | ||||
| #define CW_ACTION_IN_CIPWAP_SESSION_ID	 	\ | ||||
| 	CW_ELEM_SESSION_ID, 		/* Element ID*/			\ | ||||
| 	cw_in_generic, 0,		/* start/end callback */	\ | ||||
| 	CW_ITEMTYPE_BSTR, 		/* Type of element */		\ | ||||
| 	CW_ITEM_SESSION_ID,		/* ID to use store */		\ | ||||
| 	4, 16				/* min/max length */ | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| cw_action_in_t cipwap_actions_ac_in[] = { | ||||
|  | ||||
| @ -27,11 +45,35 @@ cw_action_in_t cipwap_actions_ac_in[] = { | ||||
| 	cw_in_generic, 0, CW_ITEMTYPE_STR,CW_ITEM_WTP_NAME,1,512} | ||||
| 	, | ||||
|  | ||||
|  | ||||
| 	{CW_VENDOR_ID_CISCO, 0, CW_STATE_JOIN, CW_MSG_JOIN_REQUEST, CW_CISCO_AP_GROUP_NAME,  | ||||
| 	cw_in_generic, 0, CW_ITEMTYPE_STR,CW_ITEM_WTP_GROUP_NAME,1,512} | ||||
| 	, | ||||
|  | ||||
| 	{0, 0, CW_STATE_DISCOVERY, CW_MSG_DISCOVERY_REQUEST, | ||||
| 	 CW_ACTION_IN_CIPWAP_WTP_DESCRIPTOR, | ||||
| 	 1} | ||||
| 	, | ||||
|  | ||||
| 	/* ------------------------------------------------------------------------------- | ||||
| 	 * Join Request IN | ||||
| 	 */ | ||||
| 	{0, 0, CW_STATE_JOIN, CW_MSG_JOIN_REQUEST, 0, | ||||
| 	 0, cw_in_check_cipwap_join_req} | ||||
| 	, | ||||
|  | ||||
| 	{0, 0, CW_STATE_JOIN, CW_MSG_JOIN_REQUEST, | ||||
| 	 CW_ACTION_IN_CIPWAP_WTP_DESCRIPTOR, 1} | ||||
| 	, | ||||
| 	{0, 0, CW_STATE_JOIN, CW_MSG_JOIN_REQUEST, | ||||
| 	 CW_ACTION_IN_CIPWAP_SESSION_ID, 1} | ||||
| 	, | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| 	/* ------------------------------------------------------------------------------- | ||||
| 	 * Image Data Request - Conig State | ||||
| 	 */ | ||||
| @ -42,6 +84,15 @@ cw_action_in_t cipwap_actions_ac_in[] = { | ||||
| 	, | ||||
|  | ||||
| 	 | ||||
| 	/* Element: Result Code   | ||||
| 	   not mandatory in CIPWAP, while mandatory in CAPWAP | ||||
| 	 */ | ||||
| 	{0, 0, CW_STATE_IMAGE_DATA, CW_MSG_IMAGE_DATA_RESPONSE, | ||||
| 	 CW_ACTION_IN_RESULT_CODE, 0} | ||||
|  | ||||
| 	, | ||||
|  | ||||
|  | ||||
|  | ||||
| 	{0,0,0} | ||||
| }; | ||||
|  | ||||
| @ -154,10 +154,15 @@ struct conn { | ||||
| 	/* used to link the conn obj with other objects */ | ||||
| 	void *data; | ||||
|  | ||||
| 	/* misc */ | ||||
| 	/** Mode */ | ||||
| 	int capwap_mode; | ||||
| 	 | ||||
| 	/** CAWAP mode for outgoing messages */ | ||||
| 	int capwap_mode_out; | ||||
|  | ||||
|  | ||||
| 	int strict_capwap; | ||||
| 	int strict_hdr; | ||||
|  | ||||
| /* | ||||
| 	int (*request_handler) (void *); | ||||
|  | ||||
| @ -141,7 +141,7 @@ static int process_elements(struct conn *conn, uint8_t * rawmsg, int len,struct | ||||
| 	/* pre-check message */ | ||||
| 	if (payloadlen-8 !=  elems_len ) { | ||||
|  | ||||
| 		if (conn_is_strict_capwap(conn)) { | ||||
| 		if (conn->strict_hdr) { | ||||
| 			cw_dbg(DBG_MSG_ERR, | ||||
| 			       "Discarding message from %s, msgelems len=%d, payload len=%d, (Strict CAPWAP) ", | ||||
| 			       sock_addr2str(&conn->addr), elems_len, payloadlen-8); | ||||
| @ -159,6 +159,7 @@ static int process_elements(struct conn *conn, uint8_t * rawmsg, int len,struct | ||||
| 			cw_dbg(DBG_RFC, | ||||
| 			       "Packet from from %s has msgelems len of %d bytes, but has only %d bytes of data, truncating.", | ||||
| 			       sock_addr2str(&conn->addr), elems_len, payloadlen - 8); | ||||
| 			elems_len=payloadlen-8; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|  | ||||
| @ -10,6 +10,9 @@ 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); | ||||
|  | ||||
|  | ||||
| @ -32,6 +35,7 @@ int conn_send_msg(struct conn * conn, uint8_t *rawmsg) | ||||
|  | ||||
| 	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 ); | ||||
|  | ||||
| @ -14,10 +14,13 @@ int cw_in_check_join_req(struct conn *conn, struct cw_action_in *a, uint8_t * da | ||||
| 	/* Check for mandatory elements */ | ||||
| 	int n = cw_check_missing_mand(mlist,conn,a); | ||||
| 	if (n) { | ||||
| 		cw_dbg_missing_mand(DBG_ELEM,conn,mlist,n,a); | ||||
| 		if ( conn->strict_capwap ){ | ||||
| 			cw_dbg_missing_mand(DBG_MSG_ERR,conn,mlist,n,a); | ||||
| 			conn->capwap_state=CW_STATE_JOIN; | ||||
| 			return CW_RESULT_MISSING_MAND_ELEM; | ||||
| 		} | ||||
| 		cw_dbg_missing_mand(DBG_RFC,conn,mlist,n,a); | ||||
| 	} | ||||
|  | ||||
| 	 | ||||
| 	/* set result code to ok and change to configure state */ | ||||
|  | ||||
| @ -24,7 +24,7 @@ int cw_in_vendor_specific_payload(struct conn *conn,struct cw_action_in * a,uint | ||||
| //cw_dbg(DBG_ELEM,"From might be: %s\n",sock_addr2str(&conn->addr)); | ||||
|  | ||||
| 	if (!af) { | ||||
| 		cw_dbg(DBG_SUBELEM,"Can't handle Vendor Specific Payload %s/%d, in msg %d (%s) in %s state.", | ||||
| 		cw_dbg(DBG_WARN,"Can't handle Vendor Specific Payload %s/%d, in msg %d (%s) in %s state.", | ||||
| 			cw_strvendor(as.vendor_id), | ||||
| 			as.elem_id,as.msg_id,cw_strmsg(as.msg_id),cw_strstate(as.capwap_state)); | ||||
| 		return 0; | ||||
|  | ||||
| @ -28,14 +28,16 @@ | ||||
| #include "sock.h" | ||||
|  | ||||
|  | ||||
| static int cw_read_wtp_descriptor_versions(cw_itemstore_t itemstore, uint8_t *data,int len) | ||||
| static int cw_read_wtp_descriptor_versions(cw_itemstore_t itemstore, uint8_t * data, | ||||
| 					   int len, int silent) | ||||
| { | ||||
| 	int i = 0; | ||||
| 	do { | ||||
| 		if (i + 8 > len) { | ||||
| 			if (!silent) | ||||
| 				cw_dbg(DBG_ELEM_ERR, | ||||
| 			       "WTP descriptor subelement to long, length=%d>%d", i + 8, | ||||
| 			       len); | ||||
| 				       "WTP descriptor subelement to long, length=%d>%d", | ||||
| 				       i + 8, len); | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| @ -47,24 +49,27 @@ static int cw_read_wtp_descriptor_versions(cw_itemstore_t itemstore, uint8_t *da | ||||
| 		i += 8; | ||||
|  | ||||
| 		if (sublen + i > len) { | ||||
| 			if (!silent) | ||||
| 				cw_dbg(DBG_ELEM_ERR, | ||||
| 			       "WTP Descriptor subelement too long, length = %d", sublen); | ||||
| 				       "WTP Descriptor subelement too long, length = %d", | ||||
| 				       sublen); | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 		if (!silent) { | ||||
| 			char *dmp; | ||||
| 			char *dmpmem = NULL; | ||||
| 			if (cw_dbg_is_level(DBG_SUBELEM_DMP)) { | ||||
| 				dmpmem = cw_dbg_mkdmp(data + i, sublen); | ||||
| 				dmp = dmpmem; | ||||
| 		} | ||||
| 		else | ||||
| 			} else | ||||
| 				dmp = ""; | ||||
| 		cw_dbg(DBG_SUBELEM, "WTP Descriptor subtype=%d,len=%d%s", subtype, sublen,dmp); | ||||
| 			cw_dbg(DBG_SUBELEM, "WTP Descriptor subtype=%d,len=%d%s", subtype, | ||||
| 			       sublen, dmp); | ||||
|  | ||||
| 			if (dmpmem) | ||||
| 				free(dmpmem); | ||||
| 		 | ||||
| 		} | ||||
|  | ||||
| 		switch (subtype) { | ||||
| 			case CW_SUBELEM_WTP_HARDWARE_VERSION: | ||||
| @ -76,12 +81,18 @@ static int cw_read_wtp_descriptor_versions(cw_itemstore_t itemstore, uint8_t *da | ||||
| 						       data + i, sublen); | ||||
| 				break; | ||||
| 			case CW_SUBELEM_WTP_SOFTWARE_VERSION: | ||||
|  | ||||
| 				cw_itemstore_set_vendorstr(itemstore,CW_ITEM_WTP_SOFTWARE_VERSION, | ||||
| 								vendor_id,data+i,sublen); | ||||
| /* | ||||
| 				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, | ||||
| @ -92,6 +103,7 @@ static int cw_read_wtp_descriptor_versions(cw_itemstore_t itemstore, uint8_t *da | ||||
| 						       data + i, sublen); | ||||
| 				break; | ||||
| 			default: | ||||
| 				if (!silent) | ||||
| 					cw_dbg(DBG_ELEM_ERR, | ||||
| 					       "Unknown WTP descriptor subelement, type = %d", | ||||
| 					       subtype); | ||||
| @ -105,15 +117,11 @@ static int cw_read_wtp_descriptor_versions(cw_itemstore_t itemstore, uint8_t *da | ||||
|  | ||||
| } | ||||
|  | ||||
| static int readelem_wtp_descriptor(struct conn *conn, struct cw_action_in *a, | ||||
| 				   uint8_t * data, int len) | ||||
| static int cw_read_wtp_descriptor(cw_itemstore_t itemstore, struct conn *conn, | ||||
| 				  struct cw_action_in *a, uint8_t * data, int len, | ||||
| 				  int silent) | ||||
| { | ||||
|  | ||||
| 	if (len < 6) { | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	cw_itemstore_t itemstore = conn->incomming; | ||||
|  | ||||
| 	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, | ||||
| @ -124,54 +132,108 @@ static int readelem_wtp_descriptor(struct conn *conn, struct cw_action_in *a, | ||||
| 	int ncrypt = cw_get_byte(data + 2); | ||||
| 	if (ncrypt == 0) { | ||||
| 		if (conn->strict_capwap) { | ||||
| 			cw_dbg(DBG_ELEM_ERR,"Bad WTP Descriptor, number of encryption elements is 0."); | ||||
| 			if (!silent) | ||||
| 				cw_dbg(DBG_ELEM_ERR, | ||||
| 				       "Bad WTP Descriptor, number of encryption elements is 0."); | ||||
| 			return 0; | ||||
| 		} | ||||
| 		cw_dbg(DBG_RFC,"Non standard conform WTP Descriptor, number of encryptoin elements is 0."); | ||||
| 		if (!silent) | ||||
| 			cw_dbg(DBG_RFC, | ||||
| 			       "Non standard conform WTP Descriptor, number of encryptoin elements is 0."); | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	int pos = 3; | ||||
| 	int i; | ||||
| 	for (i = 0; i < ncrypt; i++) { | ||||
| 		// It's a dummy for now | ||||
| 		pos += 3; | ||||
| 	} | ||||
|  | ||||
| 	return cw_read_wtp_descriptor_versions(itemstore,data+pos,len-pos); | ||||
| 	return cw_read_wtp_descriptor_versions(itemstore, data + pos, len - pos, silent); | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Read WTP Descriptor in Cisco-Style (Draft 7) | ||||
|  */ | ||||
|  | ||||
| static int cw_read_cisco_wtp_descriptor(cw_itemstore_t itemstore, struct conn *conn, | ||||
| 					struct cw_action_in *a, uint8_t * data, int len, | ||||
| 					int silent) | ||||
| { | ||||
|  | ||||
| 	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 pos = 2; | ||||
|  | ||||
| 	/* Encryption element, for now dumy XXX */ | ||||
| 	cw_get_word(data + pos + 2); | ||||
| 	pos += 2; | ||||
|  | ||||
| 	return cw_read_wtp_descriptor_versions(itemstore, data + pos, len - pos, silent); | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| int cw_in_wtp_descriptor(struct conn *conn, struct cw_action_in *a, uint8_t * data, | ||||
| 			 int len, struct sockaddr *from) | ||||
| { | ||||
| 	cw_itemstore_t itemstore = conn->incomming; | ||||
|  | ||||
| /* | ||||
| 	switch (conn->capwap_mode) { | ||||
| 		case CW_MODE_STD: | ||||
| 	return cw_read_wtp_descriptor(itemstore, conn, a, data, len, 0); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| int cw_in_cipwap_wtp_descriptor(struct conn *conn, struct cw_action_in *a, uint8_t * data, | ||||
| 				int len, struct sockaddr *from) | ||||
| { | ||||
| 				int rc = | ||||
| 				    readelem_wtp_descriptor(conn, a, data, len, | ||||
| 							    CW_MODE_STD); | ||||
| 				if (!rc) { | ||||
| 					cw_dbg(DBG_ELEM_ERR, "Bad WTP descriptor from %s", | ||||
| 					       sock_addr2str(from)); | ||||
| 	cw_itemstore_t itemstore = conn->incomming; | ||||
|  | ||||
| 	switch (conn->capwap_mode) { | ||||
| 		case CW_MODE_CISCO: | ||||
| 			return cw_read_cisco_wtp_descriptor(itemstore, conn, a, data, len, | ||||
| 							    0); | ||||
| 		case CW_MODE_CIPWAP: | ||||
| 			{ | ||||
| 				/* try to get the right WTP Descriptor */ | ||||
| 				int rc; | ||||
| 				rc = cw_read_wtp_descriptor(itemstore, conn, a, data, len, | ||||
| 							    1); | ||||
|  | ||||
| 				if (rc) { | ||||
| 					return cw_read_wtp_descriptor(itemstore, conn, a, | ||||
| 								      data, len, 0); | ||||
| 				} | ||||
|  | ||||
| 				rc = cw_read_cisco_wtp_descriptor(itemstore, conn, a, | ||||
| 								  data, len, 0); | ||||
| 				if (rc) { | ||||
| 					return cw_read_cisco_wtp_descriptor(itemstore, | ||||
| 									    conn, a, data, | ||||
| 									    len, 0); | ||||
| 				} | ||||
|  | ||||
| 				return cw_read_wtp_descriptor(itemstore, conn, a, data, | ||||
| 							      len, 0); | ||||
|  | ||||
| 			} | ||||
| 		default: | ||||
| 			return cw_read_wtp_descriptor(itemstore, conn, a, data, len, 0); | ||||
|  | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
| 				return 1; | ||||
| 			} | ||||
|  | ||||
|  | ||||
|  | ||||
| 	} | ||||
| */ | ||||
|  | ||||
| 	int rc = readelem_wtp_descriptor(conn, a, data, len); | ||||
|  | ||||
| /* | ||||
| 	if (rc == -1) { | ||||
| 		cw_dbg(DBG_RFC, "Bad WTP descriptor, trying cisco hack"); | ||||
| 		rc = readelem_wtp_descriptor(conn, a, data, len, 1); | ||||
| 	} | ||||
| */ | ||||
| 	return rc; | ||||
| } | ||||
|  | ||||
| @ -5,15 +5,19 @@ | ||||
| #include "capwap_items.h" | ||||
|  | ||||
| #include "log.h" | ||||
| #include "dbg.h" | ||||
|  | ||||
|  | ||||
| #include "sock.h" | ||||
|  | ||||
|  | ||||
| #define BLOCK_SIZE 1024 | ||||
|  | ||||
|  | ||||
| int cw_out_image_data(struct conn *conn, struct cw_action_out *a, uint8_t * dst)	// ,struct cw_item * item)  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| int cw_out_image_data(struct conn *conn, struct cw_action_out *a, uint8_t * dst) | ||||
| { | ||||
| 	cw_item_t * item = cw_itemstore_get(conn->outgoing,CW_ITEM_IMAGE_FILEHANDLE); | ||||
| 	if (!item) { | ||||
| @ -22,31 +26,30 @@ int cw_out_image_data(struct conn *conn, struct cw_action_out *a, uint8_t * dst) | ||||
| 	} | ||||
|  | ||||
| 	FILE *infile = item->data; | ||||
| 	if (infile==NULL){ | ||||
| 		cw_log(LOG_ERR,"Image Data Request infile = NULL"); | ||||
| 		return 0; | ||||
| 	} | ||||
| 	 | ||||
| 	int bytes=0; | ||||
| 	switch ( conn->capwap_mode_out){ | ||||
| 		case CW_MODE_CISCO: | ||||
| 			bytes = lw_put_image_data(dst+4,infile); | ||||
| 			if ( bytes != LW_BLOCKSIZE_IMAGE_DATA + 3) { | ||||
|        		        	avltree_del(conn->outgoing, item); | ||||
| 			} | ||||
| 			break; | ||||
| 		default: | ||||
| 			bytes = cw_put_image_data(dst+4,infile); | ||||
| 			if (dst[4] != 1){ | ||||
|        		        	avltree_del(conn->outgoing, item); | ||||
| 			} | ||||
| 	} | ||||
|  | ||||
| 	int bytes = fread(dst+5,1,BLOCK_SIZE,infile); | ||||
|  | ||||
| 	if (feof(infile)){ | ||||
| 	if ( ferror(infile)){ | ||||
| 		cw_log(LOG_ERROR,"Aborting image data transfer: %s",strerror(errno)); | ||||
| 			bytes=1; | ||||
| 			cw_put_byte(dst+4,5); | ||||
| 			bytes=0; | ||||
|  | ||||
| 		} | ||||
| 		else{ | ||||
| 			/* Last image block */ | ||||
| 			cw_put_byte(dst+4,2);  | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	} | ||||
| 	else{ | ||||
| 		cw_put_byte(dst+4,1); | ||||
| 	} | ||||
| 		 | ||||
|  | ||||
| 	return bytes+1 + cw_put_elem_hdr(dst,a->elem_id,bytes+1); | ||||
|  | ||||
| 	return bytes + cw_put_elem_hdr(dst,a->elem_id,bytes); | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -89,7 +89,7 @@ int cw_put_msg(struct conn *conn, uint8_t * rawout) | ||||
|  | ||||
| 	cw_set_msg_elems_len(msgptr, len); | ||||
|  | ||||
| 	if (as.msg_id) { | ||||
| 	if (as.msg_id & 1) { | ||||
| 		/* It's a request, so we have to set seqnum */ | ||||
| 		int s = conn_get_next_seqnum(conn); | ||||
| 		cw_set_msg_seqnum(msgptr,s);	 | ||||
|  | ||||
| @ -43,11 +43,14 @@ uint32_t cw_dbg_opt_level = 0; | ||||
|  | ||||
|  | ||||
| #define DBG_CLR_MAGENTA "\x1b[35m" | ||||
| #define DBG_CLR_BLUE_I	"\x1b[3;34m" | ||||
|  | ||||
|  | ||||
| static struct cw_str color_on[] = { | ||||
| 	{ DBG_PKT_IN, "\x1b[33m" }, | ||||
| 	{ DBG_MSG_IN, "\x1b[34m" }, | ||||
| 	{ DBG_MSG_OUT, DBG_CLR_BLUE_I }, | ||||
|  | ||||
| 	{ DBG_ELEM, "\x1b[39m" }, | ||||
| 	{ DBG_MSG_ERR, "\x1b[31m" }, | ||||
| 	{ DBG_PKT_ERR, "\x1b[31m" }, | ||||
| @ -75,6 +78,8 @@ static struct cw_str prefix[] = { | ||||
| 	{ DBG_INFO, " Info -" }, | ||||
| 	{ DBG_PKT_IN, " Pkt IN -" }, | ||||
| 	{ DBG_MSG_IN, " Msg IN -" }, | ||||
| 	{ DBG_MSG_OUT, " Msg Out -" }, | ||||
|  | ||||
| 	{ DBG_ELEM,   " Msg Element -" }, | ||||
| 	{ DBG_MSG_ERR," Msg Error -" }, | ||||
| 	{ DBG_PKT_ERR," Pkt Error -" }, | ||||
| @ -340,7 +345,11 @@ void cw_dbg_msg(int level,struct conn *conn, uint8_t * packet, int len,struct so | ||||
|  | ||||
| 	int msg_id=cw_get_msg_id(msgptr); | ||||
| 	s+=sprintf(s,"%s Message (type=%d) ",cw_strmsg(msg_id),msg_id); | ||||
| 	if ( level == DBG_MSG_IN )  | ||||
| 		s+=sprintf(s,"from %s ",sock_addr2str(from)); | ||||
| 	else | ||||
| 		s+=sprintf(s,"to %s ",sock_addr2str(from)); | ||||
|  | ||||
| 	s+=sprintf(s,", Seqnum: %d ElemLen: %d",cw_get_msg_seqnum(msgptr),cw_get_msg_elems_len(msgptr)); | ||||
|  | ||||
| //abort: | ||||
|  | ||||
| @ -32,6 +32,7 @@ struct cw_str cw_dbg_strings[] = { | ||||
| 	{ DBG_SUBELEM, "subelem" }, | ||||
| 	{ DBG_SUBELEM_DMP, "subelem_dmp" }, | ||||
| 	{ DBG_MSG_IN, "msg_in" }, | ||||
| 	{ DBG_MSG_OUT, "msg_out"}, | ||||
| 	{ DBG_MSG_ERR, "msg_err" }, | ||||
| 	{ DBG_ELEM,  "elem" }, | ||||
| 	{ DBG_ELEM_DMP, "elem_dmp" }, | ||||
|  | ||||
| @ -169,14 +169,14 @@ int cw_itemstore_set_bstr16n(cw_itemstore_t s, uint32_t id, uint8_t * data, int | ||||
|  | ||||
|  | ||||
|  | ||||
| int cw_itemstore_set_const_ptr(cw_itemstore_t s, uint32_t id, void *ptr) | ||||
| cw_item_t * cw_itemstore_set_const_ptr(cw_itemstore_t s, uint32_t id, void *ptr) | ||||
| { | ||||
| 	struct cw_item *i = cw_item_create(s, id); | ||||
| 	if (!i) | ||||
| 		return 0; | ||||
| 	i->type = CW_ITEMTYPE_CONST_DATA; | ||||
| 	i->data = ptr; | ||||
| 	return 1; | ||||
| 	return i; | ||||
| } | ||||
|  | ||||
| int cw_itemstore_set_vendorstr(cw_itemstore_t s, uint32_t id, uint32_t vendor_id, | ||||
|  | ||||
| @ -71,7 +71,7 @@ static inline struct cw_item *cw_itemstore_get(cw_itemstore_t s, uint32_t id) | ||||
|  | ||||
|  | ||||
| extern cw_itemstore_t cw_itemstore_create(); | ||||
| extern int cw_itemstore_set_const_ptr(cw_itemstore_t s, uint32_t id, void *ptr); | ||||
| extern cw_item_t * cw_itemstore_set_const_ptr(cw_itemstore_t s, uint32_t id, void *ptr); | ||||
| extern int cw_itemstore_set_strn(cw_itemstore_t s, uint32_t id, const char *str, int n); | ||||
| extern int cw_itemstore_set_str(cw_itemstore_t s, uint32_t id, const char *str); | ||||
| extern int cw_itemstore_set_ptr(cw_itemstore_t s, uint32_t id, void *ptr); | ||||
|  | ||||
| @ -19,24 +19,42 @@ | ||||
| #ifndef __LWAPP_H | ||||
| #define __LWAPP_H | ||||
|  | ||||
| #include <stdio.h> | ||||
| #include <stdint.h> | ||||
| #include <string.h> | ||||
| #include <arpa/inet.h> | ||||
|  | ||||
| //#include "acinfo.h" | ||||
| #include "bstr.h" | ||||
|  | ||||
|  | ||||
| #include "wtpinfo.h" | ||||
|  | ||||
|  | ||||
| /* version */ | ||||
|  | ||||
| /**  | ||||
|  * @defgroup LWAPPConstants LWAPP Constats | ||||
|  * @{ | ||||
|  */ | ||||
|  | ||||
|  | ||||
| /** LWAPP Version */ | ||||
| #define LW_VERSION 0 | ||||
|  | ||||
| /** LWAPP Control Port */ | ||||
| #define LWAPP_CONTROL_PORT 12223 | ||||
| /** LWAPP Control Port as string */ | ||||
| #define LWAPP_CONTROL_PORT_STR "12223" | ||||
|  | ||||
| /** Block Size for Image Data */ | ||||
| #define LW_BLOCKSIZE_IMAGE_DATA 1024 | ||||
|  | ||||
|  | ||||
| /**@}*/ | ||||
|  | ||||
|  | ||||
| #define LW_VENDOR_ID_CISCO	4232704 | ||||
|  | ||||
|  | ||||
| /* ports */ | ||||
| #define LWAPP_CONTROL_PORT 12223 | ||||
| #define LWAPP_CONTROL_PORT_STR "12223" | ||||
|  | ||||
|  | ||||
| /* macros to access transport header */ | ||||
| #define LWTH_GET_VERSION(th) (th[0]>>6) | ||||
| @ -234,6 +252,7 @@ extern const char * lw_vendor_id_to_str(uint32_t vendor_id); | ||||
| extern const char * lw_elem_id_to_str(int elem_id); | ||||
| extern const char * lw_msg_id_to_str(int msg_id); | ||||
|  | ||||
| extern int lw_put_image_data(uint8_t *dst,FILE *infile); | ||||
|  | ||||
|  | ||||
| #endif | ||||
|  | ||||
| @ -81,11 +81,6 @@ static inline double cw_clock_lap(struct timeval *tv){ | ||||
|  */  | ||||
| #define cw_clock_stop cw_clock_lap | ||||
|  | ||||
|  | ||||
|  | ||||
| 	 | ||||
|  | ||||
|  | ||||
| /** @} */ | ||||
|  | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user