Exemple #1
0
void cw_dbg_msg(int level,struct conn *conn, uint8_t * packet, int len,struct sockaddr *from)
{
	if (!cw_dbg_is_level(level))
		return;

	char buf[1024];
	char *s = buf;



	uint8_t * msgptr = cw_get_hdr_msg_ptr(packet);
//	int pplen = len - (msgptr-packet);

	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:
	cw_dbg(level,"%s",buf);
}
Exemple #2
0
int netconn_process_packet(struct netconn *nc, uint8_t * packet, int len,
			struct sockaddr *from)
{
	char sock_buf[SOCK_ADDR_BUFSIZE];

/*//	cw_dbg_pkt_nc(DBG_PKT_IN, nc, packet, len, from);*/
	if (len < 8) {
		/* packet too short */
		cw_dbg(DBG_PKT_ERR,
		       "Discarding packet from %s, packet too short, len=%d,  at least 8 expected.",
		       sock_addr2str(&nc->addr,sock_buf), len);
		errno = EAGAIN;
		return -1;
	}

	int preamble = cw_get_hdr_preamble(packet);

	if ((preamble & 0xf0) != (CAPWAP_VERSION << 4)) {
		/* wrong version */
		cw_dbg(DBG_PKT_ERR,
		       "Discarding packet from %s, wrong version, version=%d, version %d expected.",
		       sock_addr2str(&nc->addr,sock_buf), (preamble & 0xf0) >> 4,
		       CAPWAP_VERSION);
		errno = EAGAIN;
		return -1;
	}
Exemple #3
0
static void wtpman_image_data(struct wtpman *wtpman)
{
	struct conn *conn = wtpman->conn;

	/* Image upload */
	const char *filename = mbag_get_str(conn->outgoing, CW_ITEM_IMAGE_FILENAME, NULL);
	if (!filename) {
		cw_log(LOG_ERR,
		       "Can't send image to %s. No Image Filename Item found.",
		       sock_addr2str(&conn->addr));
		return;
	}
	cw_dbg(DBG_INFO, "Sending image file '%s' to '%s'.", filename,
	       sock_addr2str(&conn->addr));
	FILE *infile = fopen(filename, "rb");
	if (infile == NULL) {
		cw_log(LOG_ERR, "Can't open image %s: %s",
		       sock_addr2str(&conn->addr), strerror(errno));
		return;
	}



	CW_CLOCK_DEFINE(clk);
	cw_clock_start(&clk);

	mbag_item_t *eof = mbag_set_const_ptr(conn->outgoing, CW_ITEM_IMAGE_FILEHANDLE,
					      infile);

	int 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 = mbag_get(conn->outgoing, CW_ITEM_IMAGE_FILEHANDLE);
	}


	if (rc) {
		cw_log(LOG_ERR, "Error sending image to %s: %s",
		       sock_addr2str(&conn->addr), cw_strrc(rc));
	} else {
		cw_dbg(DBG_INFO, "Image '%s' sucessful sent to %s in %0.1f seconds.",
		       filename, sock_addr2str(&conn->addr), cw_clock_stop(&clk));
		conn->capwap_state = CW_STATE_NONE;
	}

	fclose(infile);
	wtpman_remove(wtpman);


}
Exemple #4
0
static int wtpman_join(void *arg, time_t timer)
{
	struct wtpman *wtpman = (struct wtpman *) arg;
	struct conn *conn = wtpman->conn;

	wtpman->conn->outgoing = mbag_create();
	wtpman->conn->incomming = mbag_create();
	conn->config = conn->incomming;
//      wtpman->conn->local = ac_config;

	mbag_set_str(conn->local, CW_ITEM_AC_NAME, conf_acname);



	wtpman->conn->capwap_state = CW_STATE_JOIN;
//	wtpman->conn->actions = &capwap_actions;

//      wtpman->conn->itemstore = mbag_create();


	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) {
		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);

		return 0;
	}


	return 1;


}
Exemple #5
0
int cw_in_check_disc_req(struct conn *conn, struct cw_action_in *a, uint8_t * data,
			 int len,struct sockaddr *from)
{

	cw_action_in_t *mlist[120];
	int n = cw_check_missing_mand(mlist, conn, a);

	conn->capwap_state = CW_STATE_NONE;


	if (n && conn->strict_capwap) {
		cw_dbg_missing_mand(DBG_MSG_ERR, conn, mlist, n, a);
		/* if mandatory elements are missing, in strict 
		   mode send no discovery response */
		cw_dbg(DBG_MSG_ERR,
		       "Ignoring Discovery Request from %s - missing mandatory elements.",
		       sock_addr2str(from));
		return -1;
	}

	if ( n ) {
		/* put a warning here */
		cw_dbg_missing_mand(DBG_RFC, conn, mlist, n, a);
	}

		

	/* ok, send response */
	conn->capwap_state = CW_STATE_JOIN;

	return 0;
}
Exemple #6
0
static int wtpman_join(void *arg)
{
	int rc;
	char sock_buf[SOCK_ADDR_BUFSIZE];
	struct wtpman *wtpman = (struct wtpman *) arg;
	struct conn *conn = wtpman->conn;
	time_t timer, wait_join;

	cw_dbg(DBG_INFO, "Join State - %s", sock_addr2str(&conn->addr,sock_buf));
	
	wait_join = cw_ktv_get_word(conn->global_cfg,"wait-join",CAPWAP_WAIT_JOIN);

	timer = cw_timer_start(wait_join);


	while (!cw_timer_timeout(timer) && wtpman->conn->capwap_state == CAPWAP_STATE_JOIN) {
		rc = cw_read_messages(wtpman->conn);
		if (rc < 0) {
			if (errno == EAGAIN)
				continue;
				
			break;
		}
		cw_dbg_ktv_dump(conn->remote_cfg,DBG_INFO,
		"-------------dump------------",
		"DMP","---------end dump --------");
	}

	if (rc != 0) {
		cw_log(LOG_ERR, "Error joining WTP %s", cw_strerror(rc));
		return 0;
	}


	if (wtpman->conn->capwap_state != CAPWAP_STATE_JOIN_COMPLETE) {
		cw_dbg(DBG_MSG_ERR, "No join request from %s after %d seconds, WTP died.",
		       sock_addr2str(&wtpman->conn->addr,sock_buf), wait_join);

		return 0;
	}


	return 1;


}
void cwsend_change_state_event_response(struct conn * conn,int seqnum, struct radioinfo * radioinfo)
{
	cw_dbg(DBG_CW_MSG,"Sending change state response to %s, seq = %d",sock_addr2str(&conn->addr),seqnum);

	struct cwmsg * cwmsg = &conn->resp_msg;	
	cwmsg_init(cwmsg,conn->resp_buffer,CWMSG_CHANGE_STATE_EVENT_RESPONSE,seqnum,NULL);

	cwmsg_addelem_result_code(cwmsg,0);
	cwmsg_addelem_radio_operational_state(cwmsg,radioinfo);
	
	conn_send_response(conn,cwmsg,seqnum);
}
Exemple #8
0
void props_to_sql(struct conn *conn, mbag_t  mb, const char *mid)
{
	// XXX for the now we use just the IP adress as ID
	char *wtp_id = sock_addr2str(&conn->addr);

//	cw_dbg(DBG_X, "WTPID: %s\n", wtp_id);

	MAVLITER_DEFINE(it, mb);
	mavliter_foreach(&it) {
		mbag_item_t *i = mavliter_get(&it);

		const struct cw_itemdef *cwi;

		if (!mid){
		    cwi = cw_itemdef_get(conn->actions->items, i->id, NULL);
		}
		else{
		    cwi = cw_itemdef_get(conn->actions->items, mid,i->id);
		}

		if (!cwi){
			cw_dbg(DBG_WARN,"No definition for item %s found.",i->id);
			continue;
		}

		if (i->type==MBAG_MBAG){
			if (mid){
				cw_log(LOG_ERROR,"Depth for %s",i->id);
				continue;
			}

			props_to_sql(conn,i->data,i->id);
			continue;
		}	


		DBGX("SQL ID %s,%s", i->id, cwi->id);
		DBGX("SQL Type %s,Typecwd %s", i->type->name, cwi->type->name);

		//              printf("%s != %s ?\n",i->type->name,cwi->type->name);
		char str[256];
		if (i->type->to_str) {
			i->type->to_str(i, str);
			db_put_wtp_prop(wtp_id, cwi->id, cwi->sub_id, str);
		} else {
			cw_log(LOG_ERR, "Can't converto to str for %s", cwi->id,
			       cwi->sub_id);

		}

	}
}
Exemple #9
0
void radios_to_sql(struct conn *conn)
{
	char *wtp_id = sock_addr2str(&conn->addr);
	MAVLITER_DEFINE(it, conn->radios);
	mavliter_foreach(&it) {
		struct mbag_item * i = mavliter_get(&it);
		int rid = i->iid;

		radio_to_sql(conn,wtp_id,rid,i->data);


	}
}
Exemple #10
0
static int to_str ( const struct cw_KTV *data, char *dst, int max_len )
{

	int l;
	struct sockaddr_storage addr;

	l = bstr_len(data->val.ptr);
	if (l==4){
		addr.ss_family = AF_INET;
		memcpy(&(((struct sockaddr_in*)&addr)->sin_addr),bstr_data(data->val.ptr),4);
		sock_addr2str(&addr,dst);
		return 4;
	}
	if (l==16){
		addr.ss_family = AF_INET6;
		memcpy(&(((struct sockaddr_in6*)&addr)->sin6_addr),bstr_data(data->val.ptr),16);
		sock_addr2str(&addr,dst);
		return 16;
	}
	
	*dst=0;
	return 0;

}
Exemple #11
0
int cw_send_request(struct conn *conn,int msg_id)
{
	time_t timer;
	int i;
	int rc;
	char sock_buf[SOCK_ADDR_BUFSIZE];
	cw_init_request(conn, msg_id);
	if ( cw_put_msg(conn, conn->req_buffer) == -1 ){
		errno=ENOMSG;
		return -1;
	}
	conn_send_msg(conn, conn->req_buffer);

	

	rc=-1;
	for (i=0; i<conn->max_retransmit && rc<0; i++){
		if ( i>0 ){
			cw_log(LOG_WARNING,"Retransmitting request ... %d",i);
		}
		timer = cw_timer_start(conn->retransmit_interval);
		while (!cw_timer_timeout(timer) && rc<0){
	
        	        rc =cw_read_messages(conn);
			if(rc<0){
				if (errno!=EAGAIN)
					break;
			}

		}
		if (rc<0){
			if(errno!=EAGAIN)
				break;
			
		}

	}

	if ( rc <0 && errno != EAGAIN) {
		cw_log(LOG_ERR,"Can't read from %s: %s",sock_addr2str(&conn->addr,sock_buf),strerror(errno));
	}
	if ( rc <0 && errno == EAGAIN) {
		errno=ETIMEDOUT;
		rc=-1;
	}

	return rc;
}
Exemple #12
0
int wtpconf_ac_list()
{
	if (conf_ac_list)
		return 1;

	int i;
	int len=0;
	int bcrc;
	struct sockaddr_storage bcaddr;

	bcrc = sock_getifaddr(conf_primary_if,AF_INET,IFF_BROADCAST,(struct sockaddr*)&bcaddr);
	if (bcrc)
		len++;

	int deflen = sizeof(default_ac_list)/sizeof(char*);

	len += deflen;
	conf_ac_list = malloc(len*sizeof(char*));
	if (!conf_ac_list)
		return 0;

	for (i=0; i<deflen; i++){
		conf_ac_list[i]=strdup(default_ac_list[i]);
		if (!conf_ac_list[i])
			return 0;
	}

	if (bcrc){
//		char bcstr[100];
		char *bcstr;
//		sock_addrtostr((struct sockaddr*)&bcaddr,bcstr,100);
		bcstr = sock_addr2str((struct sockaddr*)&bcaddr); 
//		char * c = strchr(bcstr,':');
//		*c=0;
		conf_ac_list[i]=strdup(bcstr);
	}

	conf_ac_list_len=len;

#ifdef WITH_CW_LOG_DEBUG
	for (i=0; i<conf_ac_list_len; i++){
		cw_dbg(DBG_INFO,"Using AC: %s",conf_ac_list[i]);
	}
#endif

	return 1;
}
void cwmsg_addelem_vendor_cisco_mwar_addr(struct cwmsg *msg, struct conn *conn)
{
    uint8_t data [7];

    switch (((struct sockaddr*)&conn->addr)->sa_family) {
    case AF_INET:
    {
        data[0]=2;	/* mwar type */
        data[5]=0;
        data[6]=0;

        printf("Adding mwar addr %s\n",sock_addr2str(&conn->addr));

        struct sockaddr_in  * sain = (struct sockaddr_in*)&conn->addr;
        memcpy(data+1,(uint8_t*)&sain->sin_addr,4);
        cwmsg_addelem_vendor_specific_payload(msg, CW_VENDOR_ID_CISCO,
                                              CW_CISCO_MWAR_ADDR,
                                              data,7);


        break;
    }


        /*		case AF_INET6:
        		{
        			int id;
        			if (cw_mode == CWMODE_CISCO)
        				id = CWMSGELEM_WTP_IPV6_IP_ADDR;
        			else
        				id = CWMSGELEM_CAPWAP_LOCAL_IPV6_ADDRESS;
        			struct sockaddr_in6  * sain = (struct sockaddr_in6*)&a;
        			return cwmsg_addelem(msg,id,(uint8_t*)&sain->sin6_addr,16);
        		}
        		break;
        */
    }




}
Exemple #14
0
void onaccept_proc(void* userptr, SOCK_HANDLE sock, const SOCK_ADDR* pname)
{
	char addr[50];
	NETWORK_EVENT event;

	printf("accept from %s\n", sock_addr2str(pname, addr));
	sock_nonblock(sock);

	event.OnConnect = onconnect_proc;
	event.OnData = ondata_proc;
	event.OnDisconnect = ondisconnect_proc;
	event.recvbuf_pool = recvbuf_pool;
	event.recvbuf_buf = NULL;
	event.recvbuf_max = recvbuf_size;

	if(!network_add(sock, &event, NULL)) {
		sock_disconnect(sock);
		sock_close(sock);
	}
}
Exemple #15
0
void ondata_proc(NETWORK_HANDLE handle, void* userptr)
{
	unsigned int count;
	NETWORK_DOWNBUF* bufs[10];

	char addr[50];
	sock_addr2str(network_get_peername(handle), addr);
	printf("%p ondata(%d).\n", handle, network_recvbuf_len(handle));

	count = network_downbufs_alloc(bufs, sizeof(bufs)/sizeof(bufs[0]), network_recvbuf_len(handle));
	if(count>0) {
		const void* buf;
		buf = network_recvbuf_ptr(handle, 0, network_recvbuf_len(handle));
		if(buf) {
			network_downbufs_fill(bufs, count, 0, buf, network_recvbuf_len(handle));
			network_send(handle, bufs, count);
		}
	}

	network_recvbuf_commit(handle, network_recvbuf_len(handle));
}
Exemple #16
0
void config_to_sql(struct conn *conn)
{
	// XXX for the moment we use just the IP adress as ID
	char *wtp_id = sock_addr2str(&conn->addr);

//	cw_dbg(DBG_X, "WTPID: %s\n", wtp_id);

	MAVLITER_DEFINE(it, conn->incomming);
	mavliter_foreach(&it) {
		mbag_item_t *i = mavliter_get(&it);

		const struct cw_itemdef *cwi =
		    cw_itemdef_get(conn->actions->items, i->id, NULL);

		cw_dbg(DBG_X,"ID GOT: %s",i->id);

		if (cwi) {
			DBGX("SQL ID %s,%s", i->id, cwi->id);
			DBGX("SQL Type %s,Typecwd %s", i->type->name, cwi->type->name);

			//              printf("%s != %s ?\n",i->type->name,cwi->type->name);
			char str[256];
			if (i->type->to_str) {
				i->type->to_str(i, str);
				db_put_wtp_prop(wtp_id, cwi->id, cwi->sub_id, str);
			} else {
				cw_log(LOG_ERR, "Can't converto to str for %s", cwi->id,
				       cwi->sub_id);

			}


		} else {
			//      DBGX("ID %d",i->id);

		}

	}
}
Exemple #17
0
void conn_q_add_packet(struct conn * conn,uint8_t *packet,int len)
{
	int qwpos = conn->qwpos;
	if (qwpos==conn->qsize)
		qwpos=0;

	if (conn->qrpos==qwpos){
		/* no buffers, discard packet */
		cw_dbg(DBG_PKT_ERR, "Discarding packet from %s, no queue buffers left",
			sock_addr2str(&conn->addr));
		return;
	}

	conn->q[qwpos]=malloc(len+4);
	if (conn->q[qwpos]==NULL)
		return;
	
	*((uint32_t*)(conn->q[qwpos]))=len;
	memcpy(conn->q[qwpos]+4,packet,len);	
	conn->qwpos=qwpos+1;

	sem_post(&conn->q_sem);
}
Exemple #18
0
void netconn_q_add_packet(struct netconn * nc,uint8_t *packet,int len)
{
	char sock_buf[SOCK_ADDR_BUFSIZE];
	int qwpos = nc->qwpos;
	if (qwpos==nc->qsize)
		qwpos=0;

	if (nc->qrpos==qwpos){
		/* no buffers, discard packet */
		cw_dbg(DBG_PKT_ERR, "Discarding packet from %s, no queue buffers left",
			sock_addr2str(&nc->addr,sock_buf));
		return;
	}

	nc->q[qwpos]=malloc(len+4);
	if (nc->q[qwpos]==NULL)
		return;
	
	*((uint32_t*)(nc->q[qwpos]))=len;
	memcpy(nc->q[qwpos]+4,packet,len);	
	nc->qwpos=qwpos+1;

	sem_post(&nc->q_sem);
}
Exemple #19
0
static int process_elements(struct conn *conn, uint8_t * rawmsg, int len,
			    struct sockaddr *from)
{
	struct cw_action_in as, *af, *afm;

	int offset = cw_get_hdr_msg_offset(rawmsg);

	uint8_t *msg_ptr = rawmsg + offset;

	int elems_len = cw_get_msg_elems_len(msg_ptr);

	int payloadlen = len - offset;


	/* pre-check message */
	if (payloadlen - 8 != elems_len) {

		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);
			errno = EAGAIN;
			return -1;
		}


		if (elems_len < payloadlen - 8) {
			cw_dbg(DBG_RFC,
			       "Packet from from %s has %d bytes of extra data, ignoring.",
			       sock_addr2str(&conn->addr), payloadlen - 8 - elems_len);
			elems_len = len - 8;
		}

		if (elems_len > payloadlen - 8) {

			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;
		}
	}



	if (!conn->detected) {
		//struct mod_ac *mod;
		struct cw_actiondef *ad = load_mods(conn, rawmsg, len, elems_len, from);
		if (!ad) {
			cw_log(LOG_ERR, "Error");
			errno = EAGAIN;
			return -1;
		}
		conn->actions = ad;
		conn->detected = 1;

	}



	/* prepare struct for search operation */
	as.capwap_state = conn->capwap_state;
	as.msg_id = cw_get_msg_id(msg_ptr);
	as.vendor_id = 0;
	as.elem_id = 0;
	as.proto = 0;


	/* Search for state/message combination */
	afm = cw_actionlist_in_get(conn->actions->in, &as);

	if (!afm) {
		/* Throw away unexpected response messages */
		if (!(as.msg_id & 1)) {
			cw_dbg(DBG_MSG_ERR,
			       "Message type %d (%s) unexpected/illegal in %s State, discarding.",
			       as.msg_id, cw_strmsg(as.msg_id),
			       cw_strstate(conn->capwap_state));
			errno = EAGAIN;
			return -1;
		}

		/* Request message not found in current state, check if we know 
		   anything else about this message type */
		const char *str = cw_strheap_get(conn->actions->strmsg, as.msg_id);
		int result_code = 0;
		if (str) {
			/* Message found, but it was in wrong state */
			cw_dbg(DBG_MSG_ERR,
			       "Message type %d (%s) not allowed in %s State.", as.msg_id,
			       cw_strmsg(as.msg_id), cw_strstate(as.capwap_state));
			result_code = CW_RESULT_MSG_INVALID_IN_CURRENT_STATE;
		} else {
			/* Message is unknown */
			cw_dbg(DBG_MSG_ERR, "Message type %d (%s) unknown.",
			       as.msg_id, cw_strmsg(as.msg_id),
			       cw_strstate(as.capwap_state));
			result_code = CW_RESULT_MSG_UNRECOGNIZED;

		}
		cw_send_error_response(conn, rawmsg, result_code);
		errno = EAGAIN;
		return -1;
	}

	
	if (conn->msg_start){
		conn->msg_start(conn, afm, rawmsg, len, from);
	}

	/* Execute start processor for message */
	if (afm->start) {
		afm->start(conn, afm, rawmsg, len, from);
	}

	uint8_t *elems_ptr = cw_get_msg_elems_ptr(msg_ptr);
	uint8_t *elem;

	/* Create an avltree to catch the found mandatory elements */
	conn->mand = stravltree_create();

	int unrecognized = 0;

	/* iterate through message elements */
	cw_foreach_elem(elem, elems_ptr, elems_len) {

		as.elem_id = cw_get_elem_id(elem);
		int elem_len = cw_get_elem_len(elem);


		af = cw_actionlist_in_get(conn->actions->in, &as);

		if (!af) {
			unrecognized++;
			cw_dbg(DBG_ELEM_ERR,
			       "Element %d (%s) not allowed in msg of type %d (%s), ignoring.",
			       as.elem_id, cw_strelemp(conn->actions, as.elem_id),
			       as.msg_id, cw_strmsg(as.msg_id));
			continue;
		}

		if (!check_len(conn, af, cw_get_elem_data(elem), elem_len, from)) {
			continue;
		}
		cw_dbg_elem(DBG_ELEM, conn, as.msg_id, as.elem_id, cw_get_elem_data(elem),
			    elem_len);



		int afrc = 1;
		if (af->start) {
			afrc =
			    af->start(conn, af, cw_get_elem_data(elem), elem_len, from);

		}

		if (af->mand && afrc) {
			/* add found mandatory message element 
			   to mand list */
			stravltree_add(conn->mand, af->item_id);
		}

		if(conn->elem_end){
			afrc = conn->elem_end(conn,af,afrc,cw_get_elem_data(elem), elem_len,from);
		}

	}
Exemple #20
0
/**
 * Run discovery for on address (eg broadcast 255.255.255.255)
 */
static int cw_run_discovery(struct conn *conn, const char *acaddr)
{

	/* get addr of destination */
	struct addrinfo hints;
	struct addrinfo *res, *res0;
	memset(&hints, 0, sizeof(hints));

	hints.ai_socktype = SOCK_DGRAM;
	hints.ai_family = PF_UNSPEC;

	int rc = getaddrinfo(acaddr, conf_control_port, &hints, &res0);
	if (rc) {
		cw_log(LOG_ERR, "Can't connect to AC %s: %s", acaddr, gai_strerror(rc));
		return 0;
	}

	for (res = res0; res; res = res->ai_next) {

		int sockfd;
		int opt;
		sockfd = socket(res->ai_family, SOCK_DGRAM, 0);
		if (sockfd == -1) {
			cw_log(LOG_ERR, "Can't create socket for %s: %s", acaddr,
			       strerror(errno));
			continue;
		}

		opt = 1;
		if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &opt, sizeof(opt)) < 0) {
			cw_log(LOG_ERR, "Can't set broadcast sockopt");
		}
		sock_set_recvtimeout(sockfd, 1);
		sock_set_dontfrag(sockfd, 0);

		sock_copyaddr(&conn->addr, res->ai_addr);

		
		if (conf_ip){		
			struct sockaddr bind_address;
			sock_strtoaddr(conf_ip,&bind_address); 
			int brc = bind(sockfd,&bind_address,sock_addrlen(&bind_address));
			if (brc<0) {
				cw_log(LOG_ERR,"Can't bind to %s",sock_addr2str(&bind_address));
				return 0;
			}
		}


		conn->sock = sockfd;
		conn->readfrom = conn_recvfrom_packet;

		run_discovery(conn);

		conn->readfrom=NULL;
		close(sockfd);


	}

	freeaddrinfo(res0);

	return 0;
}
Exemple #21
0
int wtpinfo_print(char *str, struct wtpinfo * wtpinfo)
{
	char hstr[64];

	char *s = str;




	s+=sprintf (s,"\tWTP Name: %s\n", (!wtpinfo->name ? (uint8_t*)"Not set" : wtpinfo->name) );
	s+=sprintf (s,"\tLocation: %s\n", (!wtpinfo->location ? (uint8_t*)"Not set" : wtpinfo->location) );

	s+=sprintf (s,"\tMAC Adress: ");
	if (wtpinfo->macaddress){
		sock_hwaddrtostr(wtpinfo->macaddress,wtpinfo->macaddress_len,hstr,":");
		s+=sprintf(s,"%s\n",hstr);

	}
	else
		s+=sprintf(s,"Not set\n");

	char disctypestr[32];
	switch(wtpinfo->discovery_type){
		case CW_DISCOVERY_TYPE_STATIC:
			sprintf(disctypestr,"Static");
			break;
			
		case CW_DISCOVERY_TYPE_DHCP:
			sprintf(disctypestr,"DHCP");
			break;
			
		case CW_DISCOVERY_TYPE_DNS:
			sprintf(disctypestr,"DNS");
			break;

		case CW_DISCOVERY_TYPE_AC_REFERRAL:
			sprintf(disctypestr,"AC Referral");
			break;

		default:
			sprintf(disctypestr,"Unknown");
			break;

	}
	s+=sprintf (s,"\tDiscovery Type: %s\n",disctypestr);



//	sock_addrtostr((struct sockaddr*)&wtpinfo->local_ip,hstr,64);

/*
int i0;
for (i0=0; i0<10; i0++){
	printf("%d\n", ((char*)(&wtpinfo->local_ip))[i0]  );
}

*/	s+=sprintf (s,"\tLocal IP: %s\n",sock_addr2str(&(wtpinfo->local_ip)));



	s+=sprintf (s,"\tVendor ID: %d, %s\n", wtpinfo->vendor_id,lw_vendor_id_to_str(wtpinfo->vendor_id) );

	s+=sprintf (s,"\tModel No.: "); //, (!wtpinfo->model_no ? (uint8_t*)"Not set" : wtpinfo->model_no) );
	s+=bstr_to_str(s,wtpinfo->model_no,0);
	s+=sprintf(s,"\n");
	

//	s+=sprintf (s,"\tSerial No.: %s\n", (!wtpinfo->serial_no ? (uint8_t*)"Not set" : wtpinfo->serial_no) );



	s+=sprintf (s,"\tSerial No.: "); 
	s+=bstr_to_str(s,wtpinfo->serial_no,0);
	s+=sprintf(s,"\n");

	s+=sprintf (s,"\tBoard ID: "); 
	s+=bstr_to_str(s,wtpinfo->board_id,0);
	s+=sprintf(s,"\n");

	s+=sprintf (s,"\tBoard Revision: "); 
	s+=bstr_to_str(s,wtpinfo->board_revision,0);
	s+=sprintf(s,"\n");


//	s+=sprintf (s,"\tBoard Id: %s\n", (!wtpinfo->board_id ? (uint8_t*)"Not set" : wtpinfo->board_id) );



	s+=sprintf (s,"\tSoftware Version: ");
//	s+=version_print(s,wtpinfo->software_version,wtpinfo->software_version_len,wtpinfo->software_vendor_id);
	s+=cw_format_version(s,wtpinfo->software_version,wtpinfo->software_vendor_id,"Not set");
	s+=sprintf (s,"\n");


	s+=sprintf (s,"\tHardware Version: ");
	s+=version_print(s,wtpinfo->hardware_version,wtpinfo->hardware_version_len,wtpinfo->hardware_vendor_id);
	s+=sprintf (s,"\tBootloader Version: ");
	s+=version_print(s,wtpinfo->bootloader_version,wtpinfo->bootloader_version_len,wtpinfo->bootloader_vendor_id);
		



//, (!wtpinfo->software_version ? (uint8_t*)"Not set" : wtpinfo->software_version) );



//	s+=sprintf (s,"\tHardware Version: %s\n", (!wtpinfo->hardware_version ? (uint8_t*)"Not set" : wtpinfo->hardware_version) );


	s+=sprintf (s,"\tMax Radios: %d\n",wtpinfo->max_radios);
	s+=sprintf (s,"\tRadios in use: %d\n",wtpinfo->radios_in_use);


	s+=sprintf (s,"\tSession ID: ");
	if (wtpinfo->session_id) {
		int i;
		for (i=0; i<bstr_len(wtpinfo->session_id); i++)
			s+=sprintf(s,"%02X",bstr_data(wtpinfo->session_id)[i]);
	}
	else 
		s+=sprintf(s,"Not set");
		s+=sprintf(s,"\n");

	s+=sprintf (s,"\tMAC Type: ");
	switch (wtpinfo->mac_type){
		case WTP_MAC_TYPE_LOCAL:
			s+=sprintf(s,"local");
			break;
		case WTP_MAC_TYPE_SPLIT:
			s+=sprintf(s,"split");
			break;
		case WTP_MAC_TYPE_BOTH:
			s+=sprintf(s,"local, split");
			break;
	}
	s+=sprintf(s,"\n");

	s+=sprintf (s,"\tFrame Tunnel Mode: ");
	s+=sprintf(s,"(%08X)",wtpinfo->frame_tunnel_mode);
	char * c="";
	if (wtpinfo->frame_tunnel_mode & WTP_FRAME_TUNNEL_MODE_N){
		s+=printf (s,"%snative",c);c=", ";
	}

	if (wtpinfo->frame_tunnel_mode & WTP_FRAME_TUNNEL_MODE_E){
		s+=sprintf (s,"%s802.3",c);c=", ";
	}

	if (wtpinfo->frame_tunnel_mode & WTP_FRAME_TUNNEL_MODE_L){
		s+=sprintf (s,"%sLocal bridging",c);c=", ";
	}
	if (wtpinfo->frame_tunnel_mode == 0)
		s+=sprintf(s," None");

	s+=sprintf(s,"\n");

	s+=sprintf(s,"\tRadios: %d\n",wtpinfo->max_radios);	
	int i;

	char ristr[2048];
	char *r = ristr;
	for (i=0; i<wtpinfo->max_radios; i++){
		if (wtpinfo->radioinfo[i].set)
			r+=radioinfo_print(r,&wtpinfo->radioinfo[i]);
	}

	s+=sprintf(s,"%s",ristr);


	s+=sprintf(s,"Encryption: %08x\n",wtpinfo->encryption_cap);

	s+=wtp_reboot_statistics_print(s,&wtpinfo->reboot_statistics);
	return s-str;


}
Exemple #22
0
int join(struct sockaddr *sa)
{
	int sockfd;
	int rc;

	sockfd = socket(AF_INET,SOCK_DGRAM,0);
	if (sockfd==-1){
		cw_log(LOG_ERR,"Can't create socket: %s\n",strerror(errno));
		return -1;
	}

	sock_set_recvtimeout(sockfd,1);

	rc = connect(sockfd,(struct sockaddr*)sa,sock_addrlen((struct sockaddr*)sa));
	if (rc<0){
		char str[100];
		sock_addrtostr(sa,str,100);
		cw_log(LOG_ERR,"Can't connect to %s: %s\n",str,strerror(errno));
		close(sockfd);
		return -1;
	}

	struct conn * conn = get_conn();
	conn->sock=sockfd;
	sock_copyaddr(&conn->addr,sa);

	
#ifdef WITH_DTLS
	cw_dbg (DBG_DTLS,"Establishing DTLS session with %s",sock_addr2str(sa)); 

/*
	#ifdef WITH_CW_LOG_DEBUG
	{
		char str[100];
		sock_addrtostr(sa,str,100);
		cw_log_debug0("Establishing DTLS connection to %s",str);
	}
	#endif
*/
	if (conf_dtls_psk){
		conn->dtls_psk=conf_dtls_psk;
		conn->dtls_psk_len=strlen(conn->dtls_psk);
		conn->dtls_cipher=conf_dtls_cipher;
	}

	if (conf_sslkeyfilename && conf_sslcertfilename){

		conn->dtls_key_file = conf_sslkeyfilename;
		conn->dtls_cert_file = conf_sslcertfilename;
		conn->dtls_key_pass = conf_sslkeypass;
		conn->dtls_cipher=conf_dtls_cipher;
	
	}



	rc = dtls_connect(conn);
	if (rc!=1){
		dtls_shutdown(conn);
		char str[100];
		sock_addrtostr(sa,str,100);
		cw_log(LOG_ERR,"Cant establish DTLS connection to %s",str);
		close(sockfd);
		return 0;
	}

#endif	
	cw_dbg (DBG_DTLS,"DTLS session established with %s, cipher=%s",sock_addr2str(sa),dtls_get_cipher(conn)); 
exit(0);


	#ifdef WITH_CW_LOG_DEBUG
	{
		char str[100];
		sock_addrtostr(sa,str,100);
		cw_log_debug0("DTLS connection to %s established",str);
	}
	#endif

	join_state(conn);

	return 1;
}
Exemple #23
0
int dtls_gnutls_accept(struct conn *conn)
{
	char sock_buf[SOCK_ADDR_BUFSIZE];
	char cookie_buf[SOCK_ADDR_BUFSIZE];
	struct dtls_gnutls_data *d;
	uint8_t buffer[2048];
	int tlen, rc;
	time_t c_timer;
	int bits;

	gnutls_datum_t cookie_key;
	gnutls_dtls_prestate_st prestate;




	gnutls_key_generate(&cookie_key, GNUTLS_COOKIE_KEY_SIZE);
	cw_dbg(DBG_DTLS, "Session cookie for %s generated: %s",
	       sock_addr2str(&conn->addr, sock_buf),
	       sock_hwaddrtostr((uint8_t *) (&cookie_key),
				sizeof(cookie_key), cookie_buf, ""));


	memset(&prestate, 0, sizeof(prestate));

	tlen = dtls_gnutls_bio_read(conn, buffer, sizeof(buffer));

	gnutls_dtls_cookie_send(&cookie_key, &conn->addr, sizeof(conn->addr),
				&prestate, (gnutls_transport_ptr_t) conn,
				dtls_gnutls_bio_write);

	rc = -1;



	c_timer = cw_timer_start(10);

	while (!cw_timer_timeout(c_timer)) {

		tlen = conn_q_recv_packet_peek(conn, buffer, sizeof(buffer));

		if (tlen < 0 && errno == EAGAIN)
			continue;
		if (tlen < 0) {
			/* something went wrong, we should log a message */
			continue;
		}

		rc = gnutls_dtls_cookie_verify(&cookie_key,
					       &conn->addr,
					       sizeof(conn->addr), buffer + 4, tlen - 4,
					       &prestate);

		if (rc < 0) {
			cw_dbg(DBG_DTLS, "Cookie couldn't be verified: %s",
			       gnutls_strerror(rc));
			dtls_gnutls_bio_read(conn, buffer, sizeof(buffer));
			continue;
		}

		break;

	}

	if (rc < 0) {
		cw_log(LOG_ERR, "Cookie couldn't be verified: %s", gnutls_strerror(rc));
		return 0;
	}


	cw_dbg(DBG_DTLS, "Cookie verified! Starting handshake with %s ...",
	       sock_addr2str(&conn->addr, sock_buf));



	d = dtls_gnutls_data_create(conn, GNUTLS_SERVER | GNUTLS_DATAGRAM);
	if (!d)
		return 0;


	if (conn->dtls_psk_enable) {
		gnutls_psk_server_credentials_t cred;
		rc = gnutls_psk_allocate_server_credentials(&cred);
		if (rc != 0) {
			cw_log(LOG_ERR,"gnutls_psk_allocate_server_credentials() failed.");
		}
		/* GnuTLS will call psk_creds to ask for the key associated with the
		client's username.*/
		gnutls_psk_set_server_credentials_function(cred, psk_creds);
		/* // Pass the "credentials" to the GnuTLS session. GnuTLS does NOT make an
		// internal copy of the information, so we have to keep the 'cred' structure
		// in memory (and not modify it) until we're done with this session.*/
		rc = gnutls_credentials_set(d->session, GNUTLS_CRD_PSK, cred);
		if (rc != 0) {
			cw_log(LOG_ERR,"gnutls_credentials_set() failed.\n");
		}

	}




	/* Generate Diffie-Hellman parameters - for use with DHE
	 * kx algorithms. When short bit length is used, it might
	 * be wise to regenerate parameters often.
	 */
	/*bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, GNUTLS_SEC_PARAM_LEGACY); */
	bits = conn->dtls_dhbits;

	gnutls_dh_params_init(&d->dh_params);

	cw_dbg(DBG_DTLS, "Generating DH params, %d", bits);
	gnutls_dh_params_generate2(d->dh_params, bits);
	cw_dbg(DBG_DTLS, "DH params generated, %d", bits);
	gnutls_certificate_set_dh_params(d->x509_cred, d->dh_params);

	gnutls_certificate_server_set_request(d->session, GNUTLS_CERT_REQUEST);
	gnutls_dtls_prestate_set(d->session, &prestate);

	c_timer = cw_timer_start(10);
	do {
		rc = gnutls_handshake(d->session);
	} while (!cw_timer_timeout(c_timer) && rc == GNUTLS_E_AGAIN);



	if (rc < 0) {
		cw_log(LOG_ERR, "Error in handshake with %s: %s",
		       sock_addr2str(&conn->addr, sock_buf), gnutls_strerror(rc));
		return 0;
	}


	cw_dbg(DBG_DTLS, "Handshake with %s successful.",
	       sock_addr2str(&conn->addr, sock_buf));

	conn->dtls_data = d;
	conn->read = dtls_gnutls_read;
	conn->write = dtls_gnutls_write;

	return 1;
}
Exemple #24
0
struct wtpman *wtpman_create(int socklistindex, struct sockaddr *srcaddr, int dtlsmode)
{
	struct sockaddr dbgaddr;
	socklen_t dbgaddrl;
	int sockfd, replyfd;
	char sock_buf[SOCK_ADDR_BUFSIZE];
	
	struct wtpman *wtpman;
	wtpman = malloc(sizeof(struct wtpman));
	if (!wtpman)
		return 0;
	memset(wtpman, 0, sizeof(struct wtpman));

	if (socklist[socklistindex].type != SOCKLIST_UNICAST_SOCKET) {

		int port = sock_getport(&socklist[socklistindex].addr);
		replyfd = socklist_find_reply_socket(srcaddr, port);

		if (replyfd == -1) {
			cw_log(LOG_ERR, "Can't find reply socket for request from %s",
			       sock_addr2str(srcaddr,sock_buf));
			free(wtpman);
			return NULL;
		}
	} else {
		replyfd = socklist[socklistindex].sockfd;
	}

	sockfd = replyfd;	/*//socklist[socklistindex].reply_sockfd;*/
	
	
	
	
	


	dbgaddrl = sizeof(dbgaddr);
	getsockname(sockfd, &dbgaddr, &dbgaddrl);

	cw_dbg(DBG_INFO, "Creating wtpman on socket %d, %s:%d", sockfd,
	       sock_addr2str(&dbgaddr,sock_buf), sock_getport(&dbgaddr));



	wtpman->conn = conn_create(sockfd, srcaddr, 100);
	wtpman->conn->role = CW_ROLE_AC;

	wtpman->conn->data_sock = socklist[socklistindex].data_sockfd;
	sock_copyaddr(&wtpman->conn->data_addr, (struct sockaddr *) &wtpman->conn->addr);

	if (!wtpman->conn) {
		wtpman_destroy(wtpman);
		return NULL;
	}







	wtpman->conn->mods = conf_mods;

	wtpman->conn->strict_capwap = conf_strict_capwap;
	wtpman->conn->strict_hdr = conf_strict_headers;
/*
//	wtpman->conn->radios = mbag_i_create();
//	wtpman->conn->radios_upd = mbag_i_create();
//	wtpman->conn->local = ac_config;
//wtpman->conn->capwap_mode=0; //CW_MODE_STD; //CISCO;
//	wtpman->conn->capwap_mode = CW_MODE_CISCO;
//wtpman->conn->strict_capwap_hdr=0;
*/


	wtpman->conn->local_cfg = cw_ktv_create();
	wtpman->conn->global_cfg = actube_global_cfg;
	wtpman->conn->local_cfg = actube_global_cfg;

	/* when created caused by a packet in DTLS mode, we try
	 * to find out the modules to load, for detected connection 
	 * from discovery request */
	if (dtlsmode){
		int rc;
		struct cw_Mod *cmod, *bmod;
		
		rc = discovery_cache_get(discovery_cache,srcaddr,&cmod,&bmod);
		if (rc){
			cw_dbg(DBG_INFO, "Initializing with mod %s %s",cmod->name,bmod->name);
			wtpman->conn->msgset = cw_mod_get_msg_set(wtpman->conn,cmod,bmod);
			wtpman->conn->detected=1;
			cmod->setup_cfg(wtpman->conn);
		}
	}

	return wtpman;
}
Exemple #25
0
/**
 * Establish a DTLS connection using gnutls library
 * @see #dtls_connec
 */
int dtls_gnutls_connect(struct conn *conn)
{
	int rc;
	char sock_buf[SOCK_ADDR_BUFSIZE];
	struct dtls_gnutls_data *d;
	gnutls_datum_t key;
	d = dtls_gnutls_data_create(conn,
				    GNUTLS_CLIENT | GNUTLS_DATAGRAM | GNUTLS_NONBLOCK);

	if (!d)
		return 0;

/*//      gnutls_dh_set_prime_bits(d->session, 512);*/
/*#if GNUTLS_VERSION_NUMBER >= 0x030100
	gnutls_handshake_set_timeout(d->session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);

	gnutls_dtls_set_data_mtu(d->session, 1500);
#endif
	gnutls_dtls_set_mtu(d->session, 1500);
*/

/*
	if (conn->dtls_psk != NULL){
		key.data=(unsigned char*)conn->dtls_psk;
		key.size=strlen(conn->dtls_psk);
	
		rc = gnutls_credentials_set(d->session, GNUTLS_CRD_PSK, &key);
		if (rc<0) {
			cw_log(LOG_ERR, "DTLS - Can't set x.509 credentials: %s", gnutls_strerror(rc));
			dtls_gnutls_data_destroy(d);
			return 0;

		}
	}

*/


	if (conn->dtls_psk_enable){
		gnutls_psk_client_credentials_t cred;
		rc = gnutls_psk_allocate_client_credentials(&cred);
		if (rc != 0) {
			cw_dbg(DBG_DTLS,"gnutls_psk_allocate_client_credentials() failed.\n");
			return 0;
		}
		
		
		key.size = bstr16_len(conn->dtls_psk);
		key.data = bstr16_data(conn->dtls_psk);
		
		
		/* Put the username and key into the structure we use to tell GnuTLs what
		// the credentials are. The example server doesn't care about usernames, so
		// we use "Alice" here.*/
		rc = gnutls_psk_set_client_credentials(cred, "Alice", &key, GNUTLS_PSK_KEY_RAW);
		rc = gnutls_credentials_set(d->session, GNUTLS_CRD_PSK, cred);
		if (rc != 0) {
			cw_log(LOG_ERR,"gnutls_credentials_set() failed.");
		}

	
	
	}



	cw_dbg(DBG_DTLS,"Starting handshake");
	do {
		rc = gnutls_handshake(d->session);
	} while (rc == GNUTLS_E_AGAIN);


	if (rc < 0) {
		cw_log(LOG_ERR, "DTLS (gnutls) Can't connect to %s: %s",
		       sock_addr2str(&conn->addr,sock_buf), gnutls_strerror(rc));
		return 0;
	}


	cw_dbg(DBG_DTLS, "Handshake with %s successful", sock_addr2str(&conn->addr,sock_buf));

	conn->dtls_data = d;
	conn->read = dtls_gnutls_read;
	conn->write = dtls_gnutls_write;


	return 1;
}
Exemple #26
0
static void * wtpman_main(void *arg)
{
	mavl_t r;
	int rc ;
	time_t timer;
	char sock_buf[SOCK_ADDR_BUFSIZE];
	struct conn *conn;
	int last_state;

	struct wtpman *wtpman = (struct wtpman *) arg;

	wtpman->conn->seqnum = 0;
	conn = wtpman->conn;

	wtpman->conn->remote_cfg = cw_ktv_create(); 
	

	/* We were invoked with an unencrypted packet, 
	 * so assume, it is a discovery request */
	if (!wtpman->dtlsmode){
		wtpman_run_discovery(arg);
		wtpman_remove(wtpman);
		return NULL;
	}


	/* reject connections to our multi- or broadcast sockets */
	if (socklist[wtpman->socklistindex].type != SOCKLIST_UNICAST_SOCKET) {
		cw_dbg(DBG_DTLS,"Reject multi");
		wtpman_remove(wtpman);
		return NULL;
	}
	
	conn->capwap_state = CAPWAP_STATE_DTLS_SETUP;
	/* establish dtls session */
	if (!wtpman_dtls_setup(wtpman)) {
		wtpman_remove(wtpman);
		return NULL;
	}
	
	/*last_state = conn->capwap_state;
	conn->capwap_state = CAPWAP_STATE_JOIN;
*/
	conn->capwap_prevstate = CAPWAP_STATE_DTLS_SETUP;
	conn->capwap_state = CAPWAP_STATE_JOIN;
	rc = 0;
	
	while (1){
	
		int wait_join;
		int wait_change_state;
		
		
		
		if (!cw_run_state_machine(conn, &timer)){
			cw_dbg(DBG_INFO,"WTP died");
					wtpman_remove(wtpman);
				return NULL;		
		};
		




	/*	
		switch (conn->capwap_transition){
			case CW_TRANSITION(CAPWAP_STATE_DTLS_SETUP, CAPWAP_STATE_JOIN):
			{

				wait_join = cw_ktv_get_word(conn->global_cfg,"wait-join",CAPWAP_WAIT_JOIN);
				timer = cw_timer_start(wait_join);
				break;
			}
			case CW_TRANSITION(CAPWAP_STATE_JOIN, CAPWAP_STATE_JOIN):
			{	
				char wtpname[CAPWAP_MAX_WTP_NAME_LEN];
				cw_KTV_t * result;
				result = cw_ktv_get(conn->remote_cfg,"wtp-name",NULL);
				result->type->to_str(result,wtpname,CAPWAP_MAX_WTP_NAME_LEN);
				cw_dbg(DBG_INFO, "WTP joined: '%s', IP %s.",
					wtpname,
					sock_addr2str(&conn->addr,sock_buf)
					);
				break;
			}
			case CW_TRANSITION(CAPWAP_STATE_JOIN,CAPWAP_STATE_TIMEOUT):
			{
				cw_dbg(DBG_MSG_ERR, "No join request from %s after %d seconds, WTP died.",
				sock_addr2str(&wtpman->conn->addr,sock_buf), wait_join);
				wtpman_remove(wtpman);
				return NULL;
				break;
			}
			case CW_TRANSITION(CAPWAP_STATE_JOIN, CAPWAP_STATE_CONFIGURE):
			{
				
				wait_change_state = cw_ktv_get_word(conn->global_cfg,
					"capwap-timers/change-state-pending-timer",
					CAPWAP_TIMER_CHANGE_STATE_PENDING_TIMER);
				break;
			}
			case CW_TRANSITION(CAPWAP_STATE_CONFIGURE,CAPWAP_STATE_TIMEOUT):
			{
				cw_dbg(DBG_MSG_ERR, "No Change State Event Request %s after %d seconds, WTP died.",
				sock_addr2str(&wtpman->conn->addr,sock_buf), wait_change_state);
				wtpman_remove(wtpman);
				return NULL;
				break;
			}

		}
		
*/



		
		while (!cw_timer_timeout(timer)) {
			if (conn->update_cfg != NULL){
				mavl_t tmp;
		

				tmp = conn->local_cfg;

				mavl_merge(conn->default_cfg, conn->local_cfg);
				mavl_merge(conn->default_cfg, conn->remote_cfg);

				conn->local_cfg=conn->update_cfg;
								



								
				cw_dbg(DBG_INFO, "Updating WTP %s",sock_addr2str(&conn->addr,sock_buf));

				rc = cw_send_request(conn, CAPWAP_MSG_CONFIGURATION_UPDATE_REQUEST);
				conn->update_cfg=NULL;
				conn->local_cfg=tmp;
			}

			
			rc = cw_read_messages(wtpman->conn);
			if (rc < 0) {
				if (errno == EAGAIN)
					continue;
			}
			break;
		}
		
		if(rc<0){
			conn->capwap_prevstate = conn->capwap_state;
			conn->capwap_state = CAPWAP_STATE_TIMEOUT;
		}

	}
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	




	/* dtls is established, goto join state */

	conn->capwap_state = CAPWAP_STATE_JOIN;
	if (!wtpman_join(wtpman)) {
		wtpman_remove(wtpman);
		return NULL;
	}



	cw_dbg(DBG_INFO, "WTP from %s has joined with session id: %s",
			sock_addr2str_p(&conn->addr,sock_buf),
			format_bin2hex(conn->session_id,16));


exit(0);

/*
//	cw_dbg(DBG_INFO, "Creating data thread");
//	pthread_t thread;
//	pthread_create(&thread, NULL, (void *) wtpman_run_data, (void *) wtpman);
*/

	/* here the WTP has joined, now we assume an image data request  
	   or a configuration status request. Nothing else. 
	 */

	rc = 0;
	while (!cw_timer_timeout(timer)
	       && wtpman->conn->capwap_state == CAPWAP_STATE_CONFIGURE) {
		rc = cw_read_messages(wtpman->conn);
		if (rc < 0) {
			if (errno != EAGAIN)
				break;
		}
	}

cw_dbg_ktv_dump(conn->remote_cfg,DBG_INFO,"-------------dump------------","DMP","---------end dump --------");

	if (!cw_result_is_ok(rc)) {
		cw_dbg(DBG_INFO, "WTP Problem: %s", cw_strrc(rc));
		wtpman_remove(wtpman);
		return NULL;

	}


	if (conn->capwap_state == CW_STATE_IMAGE_DATA) {
		wtpman_image_data(wtpman);
		return NULL;
	}



	conn->capwap_state = CAPWAP_STATE_RUN;
/*
	// XXX testing ...
//	DBGX("Cofig to sql", "");
//	props_to_sql(conn,conn->incomming,0);
//	radios_to_sql(conn);
*/

	/*conn->msg_end=msg_end_handler;*/
	/* The main run loop */
	reset_echointerval_timer(wtpman);

	rc = 0;
	while (wtpman->conn->capwap_state == CAPWAP_STATE_RUN) {
		rc = cw_read_messages(wtpman->conn);
		if (rc < 0) {
			if (errno != EAGAIN)
				break;
		}

/*//		cw_dbg(DBG_X, "Time left: %d",
//*/
	       /*cw_timer_timeleft(wtpman->echointerval_timer);*/
	       
		if (cw_timer_timeout(wtpman->echointerval_timer)) {

			cw_dbg(DBG_INFO, "Lost connection to WTP:%s",
			       sock_addr2str_p(&conn->addr,sock_buf));
			break;
		}
/*
//		mavl_del_all(conn->outgoing);
//		conn_clear_upd(conn,1);

//	props_to_sql(conn,conn->incomming,0);
//	radios_to_sql(conn);
*/


	
		r = db_get_update_tasks(conn, sock_addr2str(&conn->addr,sock_buf));
		if (r) {

	/*		
//			if (!conn->outgoing->count)
//				continue;
*/
			cw_dbg(DBG_INFO, "Updating WTP %s",sock_addr2str(&conn->addr,sock_buf));

			rc = cw_send_request(conn, CAPWAP_MSG_CONFIGURATION_UPDATE_REQUEST);

/*
//			mavl_merge(conn->config, conn->outgoing);
//			mavl_destroy(conn->outgoing);
//			conn->outgoing = mbag_create();
//			props_to_sql(conn,conn->incomming,0);
//			radios_to_sql(conn);
//			mavl_destroy(r);
*/
		}

		r = db_get_radio_tasks(conn, sock_addr2str(&conn->addr,sock_buf));
		if (r) {

/*
			//			if (!conn->radios_upd->count)
//				continue;
*/
			cw_dbg(DBG_INFO, "Updating Radios for %s",sock_addr2str(&conn->addr,sock_buf));
			rc = cw_send_request(conn, CAPWAP_MSG_CONFIGURATION_UPDATE_REQUEST);

/*
//			conn_clear_upd(conn,1);

//			mavl_destroy(conn->radios_upd);
//			conn->radios_upd=mbag_i_create();


//			radios_to_sql(conn);
*/
			/*
			rc = cw_send_request(conn, CW_MSG_CONFIGURATION_UPDATE_REQUEST);
			mavl_merge(conn->config, conn->outgoing);
			mavl_destroy(conn->outgoing);
			conn->outgoing = mbag_create();
			config_to_sql(conn);
			radios_to_sql(conn);
			mavl_destroy(r);
			*/
		}



	}

	db_ping_wtp(sock_addr2str_p(&conn->addr,sock_buf), "");
	wtpman_remove(wtpman);
	return NULL;
}
Exemple #27
0
int socklist_add_unicast(const char *addr, const char *port, int ac_proto)
{


	if (!socklist_check_size())
		return 0;
	

	struct addrinfo hints;
	struct addrinfo *res, *res0;
	memset(&hints, 0, sizeof(hints));

	hints.ai_socktype = SOCK_DGRAM;
	hints.ai_family = PF_UNSPEC;
	hints.ai_flags = AI_PASSIVE;

	int rc = getaddrinfo(addr, port, &hints, &res0);
	if (rc != 0) {
		cw_log(LOG_ERR, "Can't bind unicast address '%s': %s", addr,
		       gai_strerror(rc));
		return 0;
	}

	for (res = res0; res; res = res->ai_next) {
		char ifname[64];
		struct sockaddr netmask;
		struct sockaddr broadcast;

		ifname[0] = 0;
		rc = sock_getifinfo(res->ai_addr, ifname, &broadcast, &netmask);
		if (!rc) {
			cw_log(LOG_ERR, "No interface found for %s, can't bind.", addr);
			continue;
		}

		/* Bind the control port */
		struct sockaddr *sa = res->ai_addr;
		int sockfd = socket(res->ai_addr->sa_family, SOCK_DGRAM, 0);
		/* create socket */
		if (sockfd == -1) {
			cw_log(LOG_ERR, "Can't create unicast socket: %s",
			       strerror(errno));
			continue;
		}

		/* bind address */
		if (bind(sockfd, sa, sock_addrlen(sa)) < 0) {
			close(sockfd);
			cw_log(LOG_ERR, "Can't bind unicast socket %s: %s", addr,
			       strerror(errno));
			continue;
		}


		socklist[socklist_len].sockfd = sockfd;
//		socklist[socklist_len].reply_sockfd = sockfd;
		socklist[socklist_len].family = sa->sa_family;
		socklist[socklist_len].type = SOCKLIST_UNICAST_SOCKET;
		socklist[socklist_len].ac_proto = ac_proto;


		



		if (res->ai_addr->sa_family == AF_INET) {
			memcpy(&socklist[socklist_len].netmask, &netmask,
			       sock_addrlen(&netmask));
			memcpy(&socklist[socklist_len].addr, res->ai_addr,
			       sock_addrlen(res->ai_addr));
			cw_log(LOG_INFO,
			       "Bound to: %s:%s (%i) on interface %s, netmask %s", addr,
			       port, sockfd, ifname, sock_addr2str(&netmask));
		} else {
			cw_log(LOG_INFO, "Bound to: [%s]:%s (%i) on interface %s", addr,
			       port, sockfd, ifname);
		}

		
		/* Bind the data port */
		sa = res->ai_addr;

		/* XXX data port is currently hard coded */
		sock_setport(sa,5247);

		sockfd = socket(res->ai_addr->sa_family, SOCK_DGRAM, 0);
		/* create socket */
		if (sockfd == -1) {
			cw_log(LOG_ERR, "Can't create unicast data socket: %s",
			       strerror(errno));
			continue;
		}

		/* bind address */
		if (bind(sockfd, sa, sock_addrlen(sa)) < 0) {
			close(sockfd);
			cw_log(LOG_ERR, "Can't bind unicast data socket %s: %s", addr,
			       strerror(errno));
			continue;
		}

		cw_log(LOG_INFO, "Bound to data port: [%s]:%s (%i) on interface %s", addr,
			       "5247", sockfd, ifname);

		socklist[socklist_len].data_sockfd = sockfd;

		socklist_len++;

	}

	freeaddrinfo(res0);
	return 1;
}
Exemple #28
0
void process_cw_ctrl_packet(int index,struct sockaddr * addr, uint8_t * buffer, int len)
{
	int sock = socklist[index].reply_sockfd;

	char hdrstr[1024];
	hdr_print(hdrstr,buffer,len);
	cw_log_debug2("Header for packet from %s\n%s",sock_addr2str(addr),hdrstr);
	


	/* first of all check preamble */
	int preamble = CWTH_GET_PREAMBLE(buffer);

#ifdef WITH_DTLS
	if (preamble != CAPWAP_PACKET_PREAMBLE && preamble != CAPWAP_DTLS_PACKET_PREAMBLE){
#else
	if (preamble != CAPWAP_PACKET_PREAMBLE ){
#endif
		cw_log_debug1("Discarding packet, wrong preamble, preamble = 0x%01X",preamble);
		return;
	}

	wtplist_lock();
	struct wtpman * wtpman = wtplist_get(addr);
	if (!wtpman){

		wtpman = wtpman_create(index,addr);

		if (!wtpman ){
			cw_log(LOG_ERR,"Error creating wtpman: %s",strerror(errno));
			wtplist_unlock();
			return;
		}
		

		if (!wtplist_add(wtpman)){
			cw_log(LOG_ERR,"Error adding wtpman: Too many wtp connections");
			wtpman_destroy(wtpman);
			wtplist_unlock();
			return;
		};

		wtpman_start(wtpman,preamble & 0xf);
	}


	wtpman_addpacket(wtpman,buffer,len);
	wtplist_unlock();
}



void process_lw_ctrl_packet(int index,struct sockaddr * addr, uint8_t * buffer, int len)
{
	int sock = socklist[index].reply_sockfd;

	uint8_t * m = buffer+6;
	uint32_t val = ntohl(*((uint32_t*)(m)));


	printf ("VAL: %08X\n",val);

	

	/* first of all check preamble */
	int version = LWTH_GET_VERSION(m);

	if (version != LW_VERSION){
		cw_log_debug1("Discarding LWAPP packet, wrong verson");
		return;
	}

	int l = LWTH_GET_LENGTH(m);
	printf ("LEN = %d\n",l);

	if (l+12 != len){
		cw_log_debug1("Discarding LWAPP packet, wrong length");
		return;
	}

	wtplist_lock();
	struct wtpman * wtpman = wtplist_get(addr);
	if (!wtpman){

		wtpman = wtpman_create(index,addr);

		if (!wtpman ){
			cw_log(LOG_ERR,"Error creating wtpman: %s",strerror(errno));
			wtplist_unlock();
			return;
		}
		

		if (!wtplist_add(wtpman)){
			cw_log(LOG_ERR,"Error adding wtpman: Too many wtp connections");
			wtpman_destroy(wtpman);
			wtplist_unlock();
			return;
		};

		wtpman_lw_start(wtpman);
	}

	wtpman_lw_addpacket(wtpman,buffer,len);
	wtplist_unlock();
}
Exemple #29
0
/**
 * Format a Packet Header
 */
int cw_format_pkt_hdr(char *dst,int level,struct conn *conn, uint8_t * packet, int len,struct sockaddr *from)
{
	char *s=dst;
	switch (level) {
		case DBG_PKT_IN:
			if (cw_get_hdr_flag_f(packet)){
				s+=sprintf(s,"Fragment from %s",sock_addr2str_p(from));
			}
			else{
				s+=sprintf(s,"From %s",sock_addr2str_p(from));
			}
			break;
		case DBG_PKT_OUT:
			if (cw_get_hdr_flag_f(packet)){
				s+=sprintf(s,"Fragment to %s",sock_addr2str(from));
			}
			else{
				s+=sprintf(s,"To %s",sock_addr2str(from));
			}
			break;
	}
	s+=sprintf(s," l=%d: ",len);

	int preamble = cw_get_hdr_preamble(packet); 
	if (preamble==01){
		s+=sprintf(s," (encrypted)");
		return s-dst;
	}

	if (len<4)
		goto abort;
		
/*		
	if (cw_get_hdr_flag_f(packet)){
		s+=sprintf(s," (fragmented)");
	}
*/
	int hlen = cw_get_hdr_hlen(packet); 
	int rid = cw_get_hdr_rid(packet);
	int wbid = cw_get_hdr_wbid(packet);
	s+=sprintf(s," H:%d R:%02d W:%02d",hlen,rid,wbid);


	s+=sprintf(s," Flgs:");
	s+=format_hdr_flags(s,packet);

	if (len<8)
		goto abort;
	int frag_id = cw_get_hdr_fragid(packet);
	int frag_offs = cw_get_hdr_fragoffset(packet);
	s+=sprintf(s," Frag/Offs:%d/%d",frag_id,frag_offs);


	if (cw_get_hdr_flag_m(packet)) {
		/* rmac is present, print the rmac */
		int rmac_len=cw_get_hdr_rmac_len(packet);
		int plen=rmac_len;
		if (rmac_len+8>len) 
			plen=len-8;
		if (rmac_len>10) 
			plen=10;
		
		s+=sprintf(s," R-MAC:");
		s+=format_mac(s,cw_get_hdr_rmac_data(packet),plen);
		if (rmac_len>10){
			s+=sprintf(s," ... (len=%d)",rmac_len);
		}
	}

	if (cw_get_hdr_flag_w(packet)){
		/* print wireless specific info */
		int ws_len = cw_get_hdr_ws_len(packet);
		int plen = ws_len > 20 ? 20:ws_len;
		s+=sprintf(s," WS:");
		s+=format_hexu(s,cw_get_hdr_ws_data(packet),plen);
		if (ws_len>20){
			s+=sprintf(s," ... (len=%d)",ws_len);
		}
	}

	

	return s-dst;	


	
abort:
	s+=sprintf(s," Incomplete...");
	return s-dst;

}
Exemple #30
0
void onconnect_proc(NETWORK_HANDLE handle, void* userptr)
{
	char addr[50];
	sock_addr2str(network_get_peername(handle), addr);
	printf("%p connected. from %s\n", handle, addr);
}