Пример #1
0
int cw_out_generic(struct conn *conn, struct cw_action_out *a, uint8_t * dst)	// ,struct mbag_item * item) 
{


	/* Get the item to put */
	struct mbag_item *item = NULL;
	if (a->get) {
		item = a->get(conn, a);
	}


	/* Size for msg elem header depends on 
	   vendor specific payload */
	int start = a->vendor_id ? 10 : 4;


	int len;
	if (!item) {
		const char *vendor="";
		if ( a->vendor_id ) {
			vendor=cw_strvendor(a->vendor_id);
		}
		if (a->mand) {
			cw_log(LOG_ERR,
			       "Can't put mandatory element %s%d - (%s) into %s. No value found.",
				vendor,
			       a->elem_id, cw_strelemp(conn->actions, a->elem_id)
			       , cw_strmsg(a->msg_id)
			    );
		}
		else{
			cw_dbg(DBG_WARN,"No output for element %s%d -(%s) in %s. Item %s not found.",
				vendor,
			       a->elem_id, cw_strelemp(conn->actions, a->elem_id)
			       , cw_strmsg(a->msg_id),a->item_id);

		}
		return 0;
	} else {
		len = cw_put_item(dst + start, item);
	}


	if (a->vendor_id)
		return len + cw_put_elem_vendor_hdr(dst, a->vendor_id, a->elem_id, len);

	return len + cw_put_elem_hdr(dst, a->elem_id, len);
}
Пример #2
0
int static check_len(struct conn *conn, struct cw_action_in *a, uint8_t * data, int len,
		     struct sockaddr *from)
{
	if (len < a->min_len) {
		cw_dbg(DBG_ELEM_ERR,
		       "%d (%s) message element too short, len=%d, min len=%d",
		       a->elem_id, cw_strelemp(conn->actions, a->elem_id), len,
		       a->min_len);
		return 0;
	}
	if (len > a->max_len) {
		cw_dbg(DBG_ELEM_ERR,
		       "%d (%s) message element too big, len=%d, max len=%d", a->elem_id,
		       cw_strelemp(conn->actions, a->elem_id), len, a->max_len);
		return 0;
	}

	return 1;
}
Пример #3
0
Файл: dbg.c Проект: yskcg/actube
void cw_dbg_elem_colored(int level, struct conn *conn, int msg, int msgelem,
			 const uint8_t * msgbuf, int len)
{
	if (!cw_dbg_is_level(level))
		return;

	const char *elemname;
	char vendorname[256];
	char vendor_details[265];
	*vendor_details = 0;

	if (msgelem == CW_ELEM_VENDOR_SPECIFIC_PAYLOAD) {
		uint32_t vendor_id = ntohl(*((uint32_t *) msgbuf));
		int type = ntohs(*((uint16_t *) (msgbuf + 4)));
		cw_format_vendor(vendor_details, vendor_id, type, msgbuf);
		sprintf(vendorname, "%s/%s/%s",
			cw_strelemp(conn->actions, msgelem),
			(char *) cw_strvendor(vendor_id), vendor_details);
		elemname = vendorname;

	} else {
		elemname = cw_strelemp(conn->actions, msgelem);
	}


	if (!cw_dbg_is_level(DBG_ELEM_DMP)){
		cw_dbg(DBG_ELEM, "%d (%s), len=%d",
		       msgelem, elemname, len);
	}
	else{
		char *dmp = cw_dbg_mkdmp(msgbuf,len);

		cw_dbg(DBG_ELEM, "%d (%s), len=%d%s%s",
			msgelem, 
			elemname, 
			len, 
			get_dbg_color_ontext(DBG_ELEM_DMP),
			dmp);

		free(dmp);
	}
}
Пример #4
0
Файл: dbg.c Проект: yskcg/actube
/**
 * Put a list of missing mandatory message elements to debug output
 */
void cw_dbg_missing_mand(int level, struct conn *conn, cw_action_in_t ** ml, int n,
			 cw_action_in_t * a)
{
//	if (!cw_dbg_is_level(DBG_MSG_ERR) || n == 0)
//		return;

	if ( !cw_dbg_is_level(level) || n==0)
		return;

	char buffer[2000];
	char *p = buffer;
	int i;
	char *delim = "";
	for (i = 0; i < n; i++) {
		p += sprintf(p, "%s", delim);
		delim = ", ";
		p += sprintf(p, "%s", cw_strelemp(conn->actions, ml[i]->elem_id));
	}
	cw_dbg(level, "Missing mandatory elements: [%s]", buffer);
}
Пример #5
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);
		}

	}