Example #1
0
static int proto_udp_init(struct proto *proto, struct registry_instance *i) {

	proto_dns = proto_get("dns");
	proto_tftp = proto_get("tftp");

	param_conntrack_timeout = ptype_alloc_unit("uint32", "seconds");
	if (!param_conntrack_timeout)
		return POM_ERR;

	struct registry_param *p = registry_new_param("conntrack_timeout", "600", param_conntrack_timeout, "Timeout for UDP connections", 0);
	if (!p)
		goto err;
	if (registry_instance_add_param(i, p) != POM_OK)
		goto err;

	return POM_OK;
err:
	if (p)
		registry_cleanup_param(p);

	if (param_conntrack_timeout) {
		ptype_cleanup(param_conntrack_timeout);
		param_conntrack_timeout = NULL;
	}

	return POM_ERR;
}
Example #2
0
static int input_kismet_drone_init(struct input *i) {


	struct input_kismet_drone_priv *priv;
	priv = malloc(sizeof(struct input_kismet_drone_priv));
	if (!priv) {
		pom_oom(sizeof(struct input_kismet_drone_priv));
		return POM_ERR;
	}
	memset(priv, 0, sizeof(struct input_kismet_drone_priv));
	priv->fd = -1;

	struct registry_param *p = NULL;

	priv->datalink_80211 = proto_get("80211");
	priv->datalink_radiotap = proto_get("radiotap");
	if (!priv->datalink_80211 || !priv->datalink_radiotap) {
		pomlog(POMLOG_ERR "Could not find datalink 80211 or radiotap");
		goto err;
	}

	priv->p_host = ptype_alloc("string");
	priv->p_port = ptype_alloc("uint16");
	if (!priv->p_host || !priv->p_port)
		goto err;

	p = registry_new_param("host", "localhost", priv->p_host, "Kismet drone host", 0);
	if (input_add_param(i, p) != POM_OK)
		goto err;
	
	p = registry_new_param("port", "2502", priv->p_port, "Kismet drone port", 0);
	if (input_add_param(i, p) != POM_OK)
		goto err;


	i->priv = priv;

	return POM_OK;
err:
	if (p)
		registry_cleanup_param(p);

	if (priv->p_host)
		ptype_cleanup(priv->p_host);

	if (priv->p_port)
		ptype_cleanup(priv->p_port);

	free(priv);

	return POM_ERR;
}
static int analyzer_docsis_event_listeners_notify(void *obj, struct event_reg *evt_reg, int has_listeners) {
	
	struct analyzer *analyzer = obj;
	struct analyzer_docsis_priv *priv = analyzer->priv;

	if (has_listeners) {

		// Check if we are already listening
		if (priv->pkt_listener)
			return POM_OK;

		if (!priv->filter) {
			priv->filter = packet_filter_compile("docsis_mgmt.type > 3");
			if (!priv->filter) {
				pomlog(POMLOG_ERR "Error while building filter");
				return POM_ERR;
			}
		}

		priv->pkt_listener = proto_packet_listener_register(proto_get("docsis_mgmt"), 0, obj, analyzer_docsis_pkt_process, priv->filter);
		if (!priv->pkt_listener)
			return POM_ERR;

	} else {
		
		if (event_has_listener(priv->evt_cm_new) || event_has_listener(priv->evt_cm_reg_status))
			return POM_OK;

		if (proto_packet_listener_unregister(priv->pkt_listener) != POM_OK)
			return POM_ERR;
		priv->pkt_listener = NULL;
	}

	return POM_OK;
}
Example #4
0
int output_tap_open(void *output_priv) {

	struct output_tap_priv *priv = output_priv;
	
	priv->fd = open("/dev/net/tun", O_RDWR | O_SYNC);
	if (priv->fd < 0) {
		pomlog(POMLOG_ERR "Error while opening the tap device : %s", pom_strerror(errno));
		return POM_ERR;
	}

	struct ifreq ifr;
	memset(&ifr, 0, sizeof(struct ifreq));
	ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
	strncpy(ifr.ifr_name, PTYPE_STRING_GETVAL(priv->p_ifname), IFNAMSIZ);
	if (ioctl(priv->fd, TUNSETIFF, (void *) &ifr) < 0) {
		pomlog(POMLOG_ERR "Unable to setup tap device %s : %s", PTYPE_STRING_GETVAL(priv->p_ifname), pom_strerror(errno));
		return POM_ERR;
	}

	if (ioctl(priv->fd, TUNSETPERSIST, *PTYPE_BOOL_GETVAL(priv->p_persistent)) < 0) {
		pomlog(POMLOG_WARN "Unable to set persistent mode to tap device %s : %s", PTYPE_STRING_GETVAL(priv->p_ifname), pom_strerror(errno));
	}

	priv->listener = proto_packet_listener_register(proto_get("ethernet"), 0, priv, output_tap_pkt_process, priv->filter);
	if (!priv->listener)
		goto err;

	return POM_OK;

err:
	close(priv->fd);
	priv->fd = -1;
	return POM_ERR;
}
Example #5
0
static int analyzer_arp_event_listeners_notify(void *obj, struct event_reg *evt_reg, int has_listeners) {
	
	struct analyzer *analyzer = obj;
	struct analyzer_arp_priv *priv = analyzer->priv;

	if (has_listeners) {

		// Check if we are already listening
		if (priv->pkt_listener)
			return POM_OK;

		priv->pkt_listener = proto_packet_listener_register(proto_get("arp"), 0, obj, analyzer_arp_pkt_process);
		if (!priv->pkt_listener)
			return POM_ERR;
	} else {

		// Check if there is still an event being listened
		if (event_has_listener(priv->evt_new_sta) || event_has_listener(priv->evt_sta_changed))
			return POM_OK;

		if (proto_packet_listener_unregister(priv->pkt_listener) != POM_OK)
			return POM_ERR;
		priv->pkt_listener = NULL;
	}

	return POM_OK;
}
Example #6
0
static void
tls_call_exec_client(struct proto_conn *sock, const char *srcaddr,
    const char *dstaddr, int timeout)
{
	char *timeoutstr, *startfdstr, *debugstr;
	int startfd;

	/* Declare that we are receiver. */
	proto_recv(sock, NULL, 0);

	if (pjdlog_mode_get() == PJDLOG_MODE_STD)
		startfd = 3;
	else /* if (pjdlog_mode_get() == PJDLOG_MODE_SYSLOG) */
		startfd = 0;

	if (proto_descriptor(sock) != startfd) {
		/* Move socketpair descriptor to descriptor number startfd. */
		if (dup2(proto_descriptor(sock), startfd) == -1)
			pjdlog_exit(EX_OSERR, "dup2() failed");
		proto_close(sock);
	} else {
		/*
		 * The FD_CLOEXEC is cleared by dup2(2), so when we not
		 * call it, we have to clear it by hand in case it is set.
		 */
		if (fcntl(startfd, F_SETFD, 0) == -1)
			pjdlog_exit(EX_OSERR, "fcntl() failed");
	}

	closefrom(startfd + 1);

	if (asprintf(&startfdstr, "%d", startfd) == -1)
		pjdlog_exit(EX_TEMPFAIL, "asprintf() failed");
	if (timeout == -1)
		timeout = TLS_DEFAULT_TIMEOUT;
	if (asprintf(&timeoutstr, "%d", timeout) == -1)
		pjdlog_exit(EX_TEMPFAIL, "asprintf() failed");
	if (asprintf(&debugstr, "%d", pjdlog_debug_get()) == -1)
		pjdlog_exit(EX_TEMPFAIL, "asprintf() failed");

	execl(proto_get("execpath"), proto_get("execpath"), "proto", "tls",
	    proto_get("user"), "client", startfdstr,
	    srcaddr == NULL ? "" : srcaddr, dstaddr,
	    proto_get("tls:fingerprint"), proto_get("tcp:port"), timeoutstr,
	    debugstr, NULL);
	pjdlog_exit(EX_SOFTWARE, "execl() failed");
}
Example #7
0
int proto_mpeg_sect_init(struct proto *proto, struct registry_instance *i) {

    proto_mpeg_dvb_mpe = proto_get("mpeg_dvb_mpe");
    if (!proto_mpeg_dvb_mpe)
        return POM_ERR;

    return POM_OK;
}
Example #8
0
int packet_filter_prop_compile(struct filter *f, char *prop_str, struct filter_value *v) {

	char *dot = strchr(prop_str, '.');
	if (dot)
		*dot = 0;

	struct proto *proto = proto_get(prop_str);
	if (!proto) {
		pomlog(POMLOG_ERR "Cannot parse filter. Protocol %s does not exists.", prop_str);
		return POM_ERR;
	}

	struct packet_filter_prop *prop = malloc(sizeof(struct packet_filter_prop));
	if (!prop) {
		pom_oom(sizeof(struct packet_filter_prop));
		return POM_ERR;
	}
	memset(prop, 0, sizeof(struct packet_filter_prop));

	v->type = filter_value_type_prop;
	v->val.prop.priv = prop;
	prop->proto = proto;

	if (dot) {
		dot++;

		int field_id;
		for (field_id = 0; proto->info->pkt_fields[field_id].name && strcmp(proto->info->pkt_fields[field_id].name, dot); field_id++);

		if (!proto->info->pkt_fields[field_id].name) {
			pomlog(POMLOG_ERR "Field %s doesn't exists for proto %s", dot, proto->info->name);
			return POM_ERR;
		}
		prop->field_id = field_id;
		prop->pt_reg = proto->info->pkt_fields[field_id].value_type;

		if (filter_ptype_is_integer(prop->pt_reg)) {
			v->val.prop.out_type = filter_value_type_int;
		} else if (filter_ptype_is_string(prop->pt_reg)) {
			v->val.prop.out_type = filter_value_type_string;
		} else {
			v->val.prop.out_type = filter_value_type_ptype;
			v->val.prop.out_ptype = prop->pt_reg;
		}
	} else {
		// We'll output the proto name
		v->val.prop.out_type = filter_value_type_string;
		prop->field_id = -1;
	}

	return POM_OK;
}
Example #9
0
static int proto_radiotap_init(struct proto *proto, struct registry_instance *i) {
	
	proto_80211 = proto_get("80211");

	if (!proto_80211) {
		pomlog(POMLOG_ERR "Protocol 80211 is not registered.");
		return POM_ERR;
	}


	return POM_OK;

}
Example #10
0
static int analyzer_smtp_event_listeners_notify(void *obj, struct event_reg *evt_reg, int has_listeners) {

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

	if (evt_reg == priv->evt_msg) {
		if (has_listeners) {
			priv->pkt_listener = proto_packet_listener_register(proto_get("smtp"), PROTO_PACKET_LISTENER_PLOAD_ONLY, obj, analyzer_smtp_pkt_process, NULL);
			if (!priv->pkt_listener)
				return POM_ERR;
		} else {
			if (proto_packet_listener_unregister(priv->pkt_listener) != POM_OK)
				return POM_ERR;
			priv->pkt_listener = NULL;
		}
	}

	if (!priv->listening && (event_has_listener(priv->evt_msg) || event_has_listener(priv->evt_auth))) {
		

		if (event_listener_register(priv->evt_cmd, analyzer, analyzer_smtp_event_process_begin, analyzer_smtp_event_process_end) != POM_OK) {
			return POM_ERR;
		} else if (event_listener_register(priv->evt_reply, analyzer, analyzer_smtp_event_process_begin, analyzer_smtp_event_process_end) != POM_OK) {
			event_listener_unregister(priv->evt_cmd, analyzer);
			return POM_ERR;
		}

		priv->listening = 1;

	} else if (priv->listening && !event_has_listener(priv->evt_msg) && !event_has_listener(priv->evt_auth)) {

		event_listener_unregister(priv->evt_cmd, analyzer);
		event_listener_unregister(priv->evt_reply, analyzer);

		priv->listening = 0;

	}



	return POM_OK;
}
Example #11
0
static int analyzer_tftp_event_listeners_notify(void *obj, struct event_reg *evt_reg, int has_listeners) {

	struct analyzer_tftp_priv *priv = obj;

	if (has_listeners) {
		if (priv->pkt_listener)
			return POM_OK;

		priv->pkt_listener = proto_packet_listener_register(proto_get("tftp"), PROTO_PACKET_LISTENER_PLOAD_ONLY, obj, analyzer_tftp_pkt_process, NULL);
		if (!priv->pkt_listener)
			return POM_ERR;
	} else {
		if (proto_packet_listener_unregister(priv->pkt_listener) != POM_OK)
			return POM_ERR;
		priv->pkt_listener = NULL;
	}


	return POM_OK;
}
Example #12
0
static int analyzer_docsis_event_listeners_notify(void *obj, struct event_reg *evt_reg, int has_listeners) {
	
	struct analyzer *analyzer = obj;
	struct analyzer_docsis_priv *priv = analyzer->priv;

	if (has_listeners) {

		// Check if we are already listening
		if (priv->pkt_listener)
			return POM_OK;

		if (!priv->filter) {
			priv->filter = filter_proto_build("docsis_mgmt", "type", PTYPE_OP_GT, "3");
			if (!priv->filter) {
				pomlog(POMLOG_ERR "Error while building filter");
				return POM_ERR;
			}
		}

		priv->pkt_listener = proto_packet_listener_register(proto_get("docsis_mgmt"), 0, obj, analyzer_docsis_pkt_process);
		if (!priv->pkt_listener)
			return POM_ERR;

		// Filter out useless broadcast docsis_mgmt packets
		proto_packet_listener_set_filter(priv->pkt_listener, priv->filter);

	} else {
		
		if (event_has_listener(priv->evt_cm_new) || event_has_listener(priv->evt_cm_reg_status))
			return POM_OK;

		if (proto_packet_listener_unregister(priv->pkt_listener) != POM_OK)
			return POM_ERR;
		priv->pkt_listener = NULL;
	}

	return POM_OK;
}
Example #13
0
static int output_inject_open(void *output_priv) {

	struct output_inject_priv *priv = output_priv;


	struct proto *proto = proto_get("ethernet");
	if (!proto) {
		pomlog(POMLOG_ERR "Protocol ethernet not available !");
		goto err;
	}

	int snaplen = 9999; // Not used anyway

	char errbuf[PCAP_ERRBUF_SIZE] = { 0 };

	priv->p = pcap_open_live(PTYPE_STRING_GETVAL(priv->p_interface), snaplen, 0, 0, errbuf);
	if (!priv->p) {
		pomlog(POMLOG_ERR "Cannot open interface %s with pcap : %s", PTYPE_STRING_GETVAL(priv->p_interface), errbuf);
		goto err;
	}

	priv->listener = proto_packet_listener_register(proto, 0, priv, output_inject_process, priv->filter);
	if (!priv->listener) 
		goto err;

	return POM_OK;

err:

	if (priv->p) {
		pcap_close(priv->p);
		priv->p = NULL;
	}

	return POM_ERR;

}
Example #14
0
static int analyzer_arp_init(struct analyzer *analyzer) {

	struct analyzer_arp_priv *priv = malloc(sizeof(struct analyzer_arp_priv));
	if (!priv) {
		pom_oom(sizeof(struct analyzer_arp_priv));
		return POM_ERR;
	}
	memset(priv, 0, sizeof(struct analyzer_arp_priv));

	analyzer->priv = priv;

	if (pthread_mutex_init(&priv->lock, NULL)) {
		pomlog(POMLOG_ERR "Error while initializing table lock : %s", pom_strerror(errno));
		free(priv);
		return POM_ERR;
	}

	priv->proto_vlan = proto_get("vlan");
	if (!priv->proto_vlan)
		goto err;

	static struct data_item_reg evt_new_sta_data_items[ANALYZER_ARP_EVT_NEW_STA_DATA_COUNT] = { { 0 } };

	evt_new_sta_data_items[analyzer_arp_new_sta_mac_addr].name = "mac_addr";
	evt_new_sta_data_items[analyzer_arp_new_sta_mac_addr].value_type = ptype_get_type("mac");
	evt_new_sta_data_items[analyzer_arp_new_sta_ip_addr].name = "ip_addr";
	evt_new_sta_data_items[analyzer_arp_new_sta_ip_addr].value_type = ptype_get_type("ipv4");
	evt_new_sta_data_items[analyzer_arp_new_sta_vlan].name = "vlan";
	evt_new_sta_data_items[analyzer_arp_new_sta_vlan].value_type = ptype_get_type("uint16");
	evt_new_sta_data_items[analyzer_arp_new_sta_input].name = "input";
	evt_new_sta_data_items[analyzer_arp_new_sta_input].value_type = ptype_get_type("string");


	static struct data_reg evt_new_sta_data = {
		.items = evt_new_sta_data_items,
		.data_count = ANALYZER_ARP_EVT_NEW_STA_DATA_COUNT
	};

	static struct event_reg_info analyzer_arp_evt_new_sta = { 0 };
	analyzer_arp_evt_new_sta.source_name = "analyzer_arp";
	analyzer_arp_evt_new_sta.source_obj = analyzer;
	analyzer_arp_evt_new_sta.name = "arp_new_sta";
	analyzer_arp_evt_new_sta.description = "New station found";
	analyzer_arp_evt_new_sta.data_reg = &evt_new_sta_data;
	analyzer_arp_evt_new_sta.listeners_notify = analyzer_arp_event_listeners_notify;

	priv->evt_new_sta = event_register(&analyzer_arp_evt_new_sta);
	if (!priv->evt_new_sta)
		goto err;

	static struct data_item_reg evt_sta_changed_data_items[ANALYZER_ARP_EVT_STA_CHANGED_DATA_COUNT] = { { 0 } };

	evt_sta_changed_data_items[analyzer_arp_sta_changed_old_mac_addr].name = "old_mac_addr";
	evt_sta_changed_data_items[analyzer_arp_sta_changed_old_mac_addr].value_type = ptype_get_type("mac");
	evt_sta_changed_data_items[analyzer_arp_sta_changed_new_mac_addr].name = "new_mac_addr";
	evt_sta_changed_data_items[analyzer_arp_sta_changed_new_mac_addr].value_type = ptype_get_type("mac");
	evt_sta_changed_data_items[analyzer_arp_sta_changed_ip_addr].name = "ip_addr";
	evt_sta_changed_data_items[analyzer_arp_sta_changed_ip_addr].value_type = ptype_get_type("ipv4");
	evt_sta_changed_data_items[analyzer_arp_sta_changed_vlan].name = "vlan";
	evt_sta_changed_data_items[analyzer_arp_sta_changed_vlan].value_type = ptype_get_type("uint16");
	evt_sta_changed_data_items[analyzer_arp_sta_changed_input].name = "input";
	evt_sta_changed_data_items[analyzer_arp_sta_changed_input].value_type = ptype_get_type("string");

	static struct data_reg evt_sta_changed_data = {
		.items = evt_sta_changed_data_items,
		.data_count = ANALYZER_ARP_EVT_STA_CHANGED_DATA_COUNT
	};

	static struct event_reg_info analyzer_arp_evt_sta_changed = { 0 };
	analyzer_arp_evt_sta_changed.source_name = "analyzer_arp";
	analyzer_arp_evt_sta_changed.source_obj = analyzer;
	analyzer_arp_evt_sta_changed.name = "arp_sta_changed";
	analyzer_arp_evt_sta_changed.description = "Station MAC address changed";
	analyzer_arp_evt_sta_changed.data_reg = &evt_sta_changed_data;
	analyzer_arp_evt_sta_changed.listeners_notify = analyzer_arp_event_listeners_notify;

	priv->evt_sta_changed = event_register(&analyzer_arp_evt_sta_changed);
	if (!priv->evt_sta_changed)
		goto err;

	return POM_OK;

err:
	analyzer_arp_cleanup(analyzer);

	return POM_ERR;
}
Example #15
0
static int input_pcap_common_open(struct input *i) {

	struct input_pcap_priv *priv = i->priv;

	if (!priv || !priv->p)
		return POM_ERR;

	char *datalink = "undefined";

	priv->datalink_type = pcap_datalink(priv->p);
	switch (priv->datalink_type) {
		case DLT_IEEE802_11:
			datalink = "80211";
			break;

		case DLT_IEEE802_11_RADIO:
			datalink = "radiotap";
			break;

		case DLT_EN10MB:
			datalink = "ethernet";
			// Ethernet is 14 bytes long
			priv->align_offset = 2;
			break;

		case DLT_DOCSIS:
			datalink = "docsis";
			break;

/*		case DLT_LINUX_SLL:
			datalink = "linux_cooked";
			break;
*/
		case DLT_RAW:
			datalink = "ipv4";
			break;
#ifdef DLT_MPEG_2_TS
		case DLT_MPEG_2_TS:
			datalink = "mpeg_ts";
			break;
#endif
		case DLT_PPI:
			datalink = "ppi";
			break;

		case DLT_PPP_WITH_DIR:
			datalink = "ppp";
			priv->skip_offset = 1;
			break;

		default:
			pomlog(POMLOG_ERR "Datalink %s (%u) is not supported", pcap_datalink_val_to_name(priv->datalink_type), priv->datalink_type);
	}

	priv->datalink_proto = proto_get(datalink);

	if (!priv->datalink_proto) {
		pomlog(POMLOG_ERR "Cannot open input pcap : protocol %s not registered", datalink);
		input_pcap_close(i);
		return POM_ERR;
	}


	if (input_pcap_set_filter(priv->p, PTYPE_STRING_GETVAL(priv->p_filter)) != POM_OK) {
		input_pcap_close(i);
		return POM_ERR;
	}

	return POM_OK;

}
Example #16
0
static void
tls_call_exec_server(struct proto_conn *sock, struct proto_conn *tcp)
{
	int startfd, sockfd, tcpfd, safefd;
	char *startfdstr, *debugstr;

	if (pjdlog_mode_get() == PJDLOG_MODE_STD)
		startfd = 3;
	else /* if (pjdlog_mode_get() == PJDLOG_MODE_SYSLOG) */
		startfd = 0;

	/* Declare that we are receiver. */
	proto_send(sock, NULL, 0);

	sockfd = proto_descriptor(sock);
	tcpfd = proto_descriptor(tcp);

	safefd = MAX(sockfd, tcpfd);
	safefd = MAX(safefd, startfd);
	safefd++;

	/* Move sockfd and tcpfd to safe numbers first. */
	if (dup2(sockfd, safefd) == -1)
		pjdlog_exit(EX_OSERR, "dup2() failed");
	proto_close(sock);
	sockfd = safefd;
	if (dup2(tcpfd, safefd + 1) == -1)
		pjdlog_exit(EX_OSERR, "dup2() failed");
	proto_close(tcp);
	tcpfd = safefd + 1;

	/* Move socketpair descriptor to descriptor number startfd. */
	if (dup2(sockfd, startfd) == -1)
		pjdlog_exit(EX_OSERR, "dup2() failed");
	(void)close(sockfd);
	/* Move tcp descriptor to descriptor number startfd + 1. */
	if (dup2(tcpfd, startfd + 1) == -1)
		pjdlog_exit(EX_OSERR, "dup2() failed");
	(void)close(tcpfd);

	closefrom(startfd + 2);

	/*
	 * Even if FD_CLOEXEC was set on descriptors before dup2(), it should
	 * have been cleared on dup2(), but better be safe than sorry.
	 */
	if (fcntl(startfd, F_SETFD, 0) == -1)
		pjdlog_exit(EX_OSERR, "fcntl() failed");
	if (fcntl(startfd + 1, F_SETFD, 0) == -1)
		pjdlog_exit(EX_OSERR, "fcntl() failed");

	if (asprintf(&startfdstr, "%d", startfd) == -1)
		pjdlog_exit(EX_TEMPFAIL, "asprintf() failed");
	if (asprintf(&debugstr, "%d", pjdlog_debug_get()) == -1)
		pjdlog_exit(EX_TEMPFAIL, "asprintf() failed");

	execl(proto_get("execpath"), proto_get("execpath"), "proto", "tls",
	    proto_get("user"), "server", startfdstr, proto_get("tls:keyfile"),
	    proto_get("tls:certfile"), debugstr, NULL);
	pjdlog_exit(EX_SOFTWARE, "execl() failed");
}
Example #17
0
static int analyzer_rtp_init(struct analyzer *analyzer) {

	struct analyzer_rtp_priv *priv = malloc(sizeof(struct analyzer_rtp_priv));
	if (!priv) {
		pom_oom(sizeof(struct analyzer_rtp_priv));
		return POM_ERR;
	}
	memset(priv, 0, sizeof(struct analyzer_rtp_priv));
	analyzer->priv = priv;

	priv->proto_rtp = proto_get("rtp");
	if (!priv->proto_rtp)
		goto err;

	static struct data_item_reg evt_rtp_stream_data_items[ANALYZER_RTP_STREAM_DATA_COUNT] = { { 0 } };

	evt_rtp_stream_data_items[analyzer_rtp_stream_src_addr].name = "src_addr";
	evt_rtp_stream_data_items[analyzer_rtp_stream_src_addr].flags = DATA_REG_FLAG_NO_ALLOC;

	evt_rtp_stream_data_items[analyzer_rtp_stream_dst_addr].name = "dst_addr";
	evt_rtp_stream_data_items[analyzer_rtp_stream_dst_addr].flags = DATA_REG_FLAG_NO_ALLOC;

	evt_rtp_stream_data_items[analyzer_rtp_stream_src_port].name = "src_port";
	evt_rtp_stream_data_items[analyzer_rtp_stream_src_port].value_type = ptype_get_type("uint16");

	evt_rtp_stream_data_items[analyzer_rtp_stream_dst_port].name = "dst_port";
	evt_rtp_stream_data_items[analyzer_rtp_stream_dst_port].value_type = ptype_get_type("uint16");

	evt_rtp_stream_data_items[analyzer_rtp_stream_sess_proto].name = "sess_proto";
	evt_rtp_stream_data_items[analyzer_rtp_stream_sess_proto].value_type = ptype_get_type("string");

	evt_rtp_stream_data_items[analyzer_rtp_stream_call_id].name = "call_id";
	evt_rtp_stream_data_items[analyzer_rtp_stream_call_id].value_type = ptype_get_type("string");

	evt_rtp_stream_data_items[analyzer_rtp_stream_ssrc].name = "ssrc";
	evt_rtp_stream_data_items[analyzer_rtp_stream_ssrc].value_type = ptype_get_type("uint32");

	static struct data_reg evt_rtp_stream_data = {
		.items = evt_rtp_stream_data_items,
		.data_count = ANALYZER_RTP_STREAM_DATA_COUNT
	};

	static struct event_reg_info analyzer_rtp_evt_stream = { 0 };
	analyzer_rtp_evt_stream.source_name = "analyzer_rtp";
	analyzer_rtp_evt_stream.source_obj = analyzer;
	analyzer_rtp_evt_stream.name = "rtp_stream";
	analyzer_rtp_evt_stream.description = "RTP stream in a single direction";
	analyzer_rtp_evt_stream.data_reg = &evt_rtp_stream_data;
	analyzer_rtp_evt_stream.flags = EVENT_REG_FLAG_PAYLOAD;
	analyzer_rtp_evt_stream.listeners_notify = analyzer_rtp_event_listeners_notify;
	analyzer_rtp_evt_stream.cleanup = analyzer_rtp_stream_event_cleanup;
	
	priv->evt_rtp_stream = event_register(&analyzer_rtp_evt_stream);
	if (!priv->evt_rtp_stream)
		goto err;

	return POM_OK;

err:
	analyzer_rtp_cleanup(analyzer);
	return POM_ERR;
}