Beispiel #1
0
static int analyzer_smtp_pkt_process(void *obj, struct packet *p, struct proto_process_stack *stack, unsigned int stack_index) {

	struct analyzer *analyzer = obj;
	struct proto_process_stack *s = &stack[stack_index - 1];
	if (!s->ce)
		return POM_ERR;

	struct analyzer_smtp_ce_priv *cpriv = conntrack_get_priv(s->ce, analyzer);

	if (!event_is_started(cpriv->evt_msg)) {
		pomlog(POMLOG_ERR "Payload received while data event not found");
		return POM_OK;
	}

	struct pload *pload_buff = event_get_priv(cpriv->evt_msg);

	if (!pload_buff) {
		pload_buff = pload_alloc(cpriv->evt_msg, 0);
		pload_set_type(pload_buff, ANALYZER_SMTP_RFC822_PLOAD_TYPE);
		if (!pload_buff)
			return POM_ERR;

		event_set_priv(cpriv->evt_msg, pload_buff);
	}

	struct proto_process_stack *pload_stack = &stack[stack_index];

	char *pload = pload_stack->pload;
	size_t plen = pload_stack->plen;


	// Look for the end of the "<CR><LF>.." sequence if any
	if (cpriv->dotdot_pos > 0){
		int i, found = 1;
		for (i = 0; i < ANALYZER_SMTP_DOTDOT_LEN - cpriv->dotdot_pos && i <= plen; i++) {
			if (*(char*)(pload + i) != ANALYZER_SMTP_DOTDOT[cpriv->dotdot_pos + i]) {
				found = 0;
				break;
			}
		}
		if (i >= ANALYZER_SMTP_DOTDOT_LEN - cpriv->dotdot_pos) {
			if (found && (i >= ANALYZER_SMTP_DOTDOT_LEN - cpriv->dotdot_pos)) {
				// Process up to the last dot
				size_t len = ANALYZER_SMTP_DOTDOT_LEN - cpriv->dotdot_pos;
				if (pload_append(pload_buff, pload, len - 1) != POM_OK)
					return POM_ERR;
				pload += len;
				plen -= len;

			}
			cpriv->dotdot_pos = 0;
		} else {
			cpriv->dotdot_pos += i;	
		}
	}

	while (plen) {
		char * dotdot = pom_strnstr(pload, ANALYZER_SMTP_DOTDOT, plen);

		if (!dotdot)
			break;

		size_t dotdot_len = dotdot - pload + ANALYZER_SMTP_DOTDOT_LEN;
		if (pload_append(pload_buff, pload, dotdot_len - 1) != POM_OK)
			return POM_ERR;
		pload = dotdot + ANALYZER_SMTP_DOTDOT_LEN;
		plen -= dotdot_len;

	}

	// Check for a possible partial dotdot at the end of the pload
	int i, found = 0;
	for (i = 1; (i < ANALYZER_SMTP_DOTDOT_LEN) && (i <= plen); i++) {
		if (!memcmp(pload + plen - i, ANALYZER_SMTP_DOTDOT, i)) {
			found = 1;
		}	break;
	}

	if (found)
		cpriv->dotdot_pos = i;

	// Add whatever remains
	if (plen && pload_append(pload_buff, pload, plen) != POM_OK)
		return POM_ERR;

	return POM_OK;
}
Beispiel #2
0
static int analyzer_rtp_pload_process(void *obj, struct packet *p, struct proto_process_stack *stack, unsigned int stack_index) {

	struct analyzer *analyzer = obj;
	struct analyzer_rtp_priv *priv = analyzer->priv;

	struct proto_process_stack *pload_stack = &stack[stack_index];
	struct proto_process_stack *s = &stack[stack_index - 1];

	if (!s->ce)
		return POM_ERR;

	struct analyzer_rtp_ce_priv *cp = conntrack_get_priv(s->ce, obj);
	if (!cp) {
		cp = malloc(sizeof(struct analyzer_rtp_ce_priv));
		if (!cp) {
			pom_oom(sizeof(struct analyzer_rtp_ce_priv));
			return POM_ERR;
		}
		memset(cp, 0, sizeof(struct analyzer_rtp_ce_priv));

		if (conntrack_add_priv(s->ce, obj, cp, analyzer_rtp_ce_cleanup) != POM_OK)
			return POM_ERR;
	}

	int dir = s->direction;

	if (!cp->evt[dir]) {
		cp->evt[dir] = event_alloc(priv->evt_rtp_stream);
		if (!cp->evt[dir])
			return POM_ERR;

		struct data *evt_data = event_get_data(cp->evt[dir]);
		ptype_copy(evt_data[analyzer_rtp_stream_ssrc].value, s->pkt_info->fields_value[proto_rtp_field_ssrc]);
		data_set(evt_data[analyzer_rtp_stream_ssrc]);

		// For now we always assume RTP is over UDP or TCP
		if (stack_index > 2) {
			struct proto_process_stack *l4_stack = &stack[stack_index - 2];
			unsigned int i;
			for (i = 0; !data_is_set(evt_data[analyzer_rtp_stream_src_port]) || !data_is_set(evt_data[analyzer_rtp_stream_dst_port]); i++) {
				struct proto_reg_info *l4_info = proto_get_info(l4_stack->proto);
				char *name = l4_info->pkt_fields[i].name;
				if (!name)
					break;
				if (!data_is_set(evt_data[analyzer_rtp_stream_src_port]) && !strcmp(name, "sport")) {
					ptype_copy(evt_data[analyzer_rtp_stream_src_port].value, l4_stack->pkt_info->fields_value[i]);
					data_set(evt_data[analyzer_rtp_stream_src_port]);
				} else if (!data_is_set(evt_data[analyzer_rtp_stream_dst_port]) && !strcmp(name, "dport")) {
					ptype_copy(evt_data[analyzer_rtp_stream_dst_port].value, l4_stack->pkt_info->fields_value[i]);
					data_set(evt_data[analyzer_rtp_stream_dst_port]);
				}
			}

		}

		if (stack_index > 3) {
			struct proto_process_stack *l3_stack = &stack[stack_index - 3];
			unsigned int i;
			for (i = 0; !data_is_set(evt_data[analyzer_rtp_stream_src_addr]) || !data_is_set(evt_data[analyzer_rtp_stream_dst_addr]); i++) {
				struct proto_reg_info *l3_info = proto_get_info(l3_stack->proto);
				char *name = l3_info->pkt_fields[i].name;
				if (!name)
					break;
				if (!data_is_set(evt_data[analyzer_rtp_stream_src_addr]) && !strcmp(name, "src")) {
					evt_data[analyzer_rtp_stream_src_addr].value = ptype_alloc_from(l3_stack->pkt_info->fields_value[i]);
					if (evt_data[analyzer_rtp_stream_src_addr].value)
						data_set(evt_data[analyzer_rtp_stream_src_addr]);
				} else if (!data_is_set(evt_data[analyzer_rtp_stream_dst_addr]) && !strcmp(name, "dst")) {
					evt_data[analyzer_rtp_stream_dst_addr].value = ptype_alloc_from(l3_stack->pkt_info->fields_value[i]);
					if (evt_data[analyzer_rtp_stream_dst_addr].value)
						data_set(evt_data[analyzer_rtp_stream_dst_addr]);
				}
			}

		}

		struct proto *sess_proto = telephony_stream_info_get_sess_proto(s->ce);
		if (sess_proto) {
			struct proto_reg_info *proto_reg = proto_get_info(sess_proto);
			PTYPE_STRING_SETVAL(evt_data[analyzer_rtp_stream_sess_proto].value, proto_reg->name);
			data_set(evt_data[analyzer_rtp_stream_sess_proto]);
		}

		char *call_id = telephony_stream_info_get_call_id(s->ce);
		if (call_id) {
			PTYPE_STRING_SETVAL_P(evt_data[analyzer_rtp_stream_call_id].value, call_id);
			data_set(evt_data[analyzer_rtp_stream_call_id]);
		}

		if (event_process_begin(cp->evt[dir], stack, stack_index, p->ts) != POM_OK)
			return POM_ERR;
	}

	if (!cp->pload[dir]) {
		cp->pload[dir] = pload_alloc(cp->evt[dir], 0);
		if (!cp->pload[dir])
			return POM_ERR;

		struct telephony_codec_info info = { 0 };
		if (telephony_stream_info_get_codec(&info, stack, stack_index - 1) == POM_OK) {
			char *pload_type = telephony_codec_info_get_pload_type(&info);
			if (pload_type)
				pload_set_type(cp->pload[dir], pload_type);
		}
	}

	if (pload_append(cp->pload[dir], pload_stack->pload, pload_stack->plen) != POM_OK)
		return POM_ERR;

	return POM_OK;
}