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