int output_file_init(struct output *o) { struct output_file_priv *priv = malloc(sizeof(struct output_file_priv)); if (!priv) { pom_oom(sizeof(struct output_file_priv)); return POM_ERR; } memset(priv, 0, sizeof(struct output_file_priv)); output_set_priv(o, priv); priv->p_listen_pload_evt = ptype_alloc("bool"); priv->p_path = ptype_alloc("string"); priv->p_filter = ptype_alloc("string"); if (!priv->p_path || !priv->p_listen_pload_evt || !priv->p_filter) goto err; struct registry_instance *inst = output_get_reg_instance(o); priv->perf_files_closed = registry_instance_add_perf(inst, "files_closed", registry_perf_type_counter, "Number of files fully written and closed", "files"); priv->perf_files_open = registry_instance_add_perf(inst, "files_open", registry_perf_type_gauge, "Number of files currently open", "files"); priv->perf_bytes_written = registry_instance_add_perf(inst, "bytes_written", registry_perf_type_counter, "Number of bytes written", "bytes"); if (!priv->perf_files_closed || !priv->perf_files_open || !priv->perf_bytes_written) goto err; struct registry_param *p = registry_new_param("listen_pload_events", "no", priv->p_listen_pload_evt, "Listen to all events that generate payloads", 0); if (output_add_param(o, p) != POM_OK) goto err; p = registry_new_param("path", "/tmp/", priv->p_path, "Path where to store the files", 0); if (output_add_param(o, p) != POM_OK) goto err; p = registry_new_param("filter", "", priv->p_filter, "Payload filter", 0); if (output_add_param(o, p) != POM_OK) goto err; return POM_OK; err: if (p) registry_cleanup_param(p); output_file_cleanup(priv); return POM_ERR; }
int output_log_xml_init(struct output *o) { struct output_log_xml_priv *priv = log_xml_init(); if (!priv) return POM_ERR; priv->p_source = ptype_alloc("string"); if (!priv->p_source) goto err; output_set_priv(o, priv); struct registry_instance *inst = output_get_reg_instance(o); priv->perf_events = registry_instance_add_perf(inst, "events", registry_perf_type_counter, "Number of events process", "events"); if (!priv->perf_events) goto err; struct registry_param *p = registry_new_param("filename", "log.xml", priv->p_filename, "XML log file", 0); if (output_add_param(o, p) != POM_OK) goto err; p = registry_new_param("source", "", priv->p_source, "Define the type of event being logged", 0); if (output_add_param(o, p) != POM_OK) goto err; return POM_OK; err: output_log_xml_cleanup(priv); return POM_ERR; }
struct event_reg *event_register(struct event_reg_info *reg_info) { struct event_reg *evt; // Check if an event with the same name has already been registered for (evt = event_reg_head; evt && strcmp(evt->info->name, reg_info->name); evt = evt->next); if (evt) { pomlog(POMLOG_ERR "An event named %s has already been registered", reg_info->name); return NULL; } // Allocate the event_reg evt = malloc(sizeof(struct event_reg)); if (!evt) { pom_oom(sizeof(struct event_reg)); return NULL; } memset(evt, 0, sizeof(struct event_reg)); evt->reg_instance = registry_add_instance(event_registry_class, reg_info->name); if (!evt->reg_instance) { free(evt); return NULL; } evt->perf_listeners = registry_instance_add_perf(evt->reg_instance, "listeners", registry_perf_type_gauge, "Number of event listeners", "listeners"); evt->perf_ongoing = registry_instance_add_perf(evt->reg_instance, "ongoing", registry_perf_type_gauge, "Number of ongoing events", "events"); evt->perf_processed = registry_instance_add_perf(evt->reg_instance, "processed", registry_perf_type_counter, "Number of events fully processed", "events"); if (!evt->perf_listeners || !evt->perf_ongoing || !evt->perf_processed) { registry_remove_instance(evt->reg_instance); free(evt); return NULL; } evt->info = reg_info; evt->next = event_reg_head; if (evt->next) evt->next->prev = evt; event_reg_head = evt; pomlog(POMLOG_DEBUG "Event %s registered", reg_info->name); return evt; }
static int output_inject_init(struct output *o) { struct output_inject_priv *priv = malloc(sizeof(struct output_inject_priv)); if (!priv) { pom_oom(sizeof(struct output_inject_priv)); return POM_ERR; } memset(priv, 0, sizeof(struct output_inject_priv)); output_set_priv(o, priv); priv->p_interface = ptype_alloc("string"); priv->p_filter = ptype_alloc("string"); if (!priv->p_interface || !priv->p_filter) goto err; struct registry_instance *inst = output_get_reg_instance(o); priv->perf_pkts_out = registry_instance_add_perf(inst, "pkts_out", registry_perf_type_counter, "Number of packets injected", "pkts"); priv->perf_bytes_out = registry_instance_add_perf(inst, "bytes_out", registry_perf_type_counter, "Number of packet bytes injected", "bytes"); char err[PCAP_ERRBUF_SIZE] = { 0 }; char *dev = pcap_lookupdev(err); if (!dev) { pomlog(POMLOG_WARN, "Warning, could not find a suitable interface to inject packets to : %s", err); dev = "none"; } struct registry_param *p = registry_new_param("interface", dev, priv->p_interface, "Output interface", 0); if (output_add_param(o, p) != POM_OK) goto err; p = registry_new_param("filter", "", priv->p_filter, "Filter", REGISTRY_PARAM_FLAG_NOT_LOCKED_WHILE_RUNNING); if (output_add_param(o, p) != POM_OK) goto err; registry_param_set_callbacks(p, priv, output_inject_filter_parse, output_inject_filter_update); return POM_OK; err: output_inject_cleanup(priv); return POM_ERR; }
static int proto_ipv4_init(struct proto *proto, struct registry_instance *i) { if (proto_number_register("ethernet", 0x0800, proto) != POM_OK || proto_number_register("ip", IPPROTO_IPIP, proto) != POM_OK || proto_number_register("ppp", 0x21, proto) != POM_OK) return POM_ERR; perf_frags = registry_instance_add_perf(i, "fragments", registry_perf_type_counter, "Number of fragments received", "pkts"); perf_frags_dropped = registry_instance_add_perf(i, "dropped_fragments", registry_perf_type_counter, "Number of fragments dropped", "pkts"); perf_reassembled_pkts = registry_instance_add_perf(i, "reassembled_pkts", registry_perf_type_counter, "Number of reassembled packets", "pkts"); if (!perf_frags || !perf_frags_dropped || !perf_reassembled_pkts) return POM_ERR; param_frag_timeout = ptype_alloc_unit("uint32", "seconds"); if (!param_frag_timeout) return POM_ERR; param_conntrack_timeout = ptype_alloc_unit("uint32", "seconds"); if (!param_conntrack_timeout) return POM_ERR; struct registry_param *p = registry_new_param("fragment_timeout", "60", param_frag_timeout, "Timeout for incomplete ipv4 fragments", 0); if (registry_instance_add_param(i, p) != POM_OK) goto err; p = registry_new_param("conntrack_timeout", "7200", param_conntrack_timeout, "Timeout for ipv4 connections", 0); if (registry_instance_add_param(i, p) != POM_OK) goto err; return POM_OK; err: if (param_frag_timeout) { ptype_cleanup(param_frag_timeout); param_frag_timeout = NULL; } if (param_conntrack_timeout) { ptype_cleanup(param_conntrack_timeout); param_conntrack_timeout = NULL; } return POM_ERR; }
int output_tap_init(struct output *o) { struct output_tap_priv *priv = tap_init(); if (!priv) return POM_ERR; output_set_priv(o, priv); struct registry_instance *inst = output_get_reg_instance(o); priv->perf_pkts_out = registry_instance_add_perf(inst, "pkts_out", registry_perf_type_counter, "Number of packets processed", "pkts"); priv->perf_bytes_out = registry_instance_add_perf(inst, "bytes_out", registry_perf_type_counter, "Number of bytes processed", "bytes"); if (!priv->perf_pkts_out || !priv->perf_bytes_out) goto err; struct registry_param *p = registry_new_param("ifname", "pom0", priv->p_ifname, "Name of the interface to create", 0); if (output_add_param(o, p) != POM_OK) goto err; p = registry_new_param("persistent", "no", priv->p_persistent, "Create a persistent interface", 0); if (output_add_param(o, p) != POM_OK) goto err; p = registry_new_param("filter", "", priv->p_filter, "Filter", REGISTRY_PARAM_FLAG_NOT_LOCKED_WHILE_RUNNING); if (output_add_param(o, p) != POM_OK) goto err; registry_param_set_callbacks(p, priv, output_tap_filter_parse, output_tap_filter_update); return POM_OK; err: output_tap_cleanup(priv); return POM_ERR; }
int output_instance_add(char *type, char *name) { struct output_reg *reg; for (reg = output_reg_head; reg && strcmp(reg->reg_info->name, type); reg = reg->next); if (!reg) { pomlog(POMLOG_ERR "Output type %s does not exists", type); return POM_ERR; } struct output *res = malloc(sizeof(struct output)); if (!res) { pom_oom(sizeof(struct output)); return POM_ERR; } memset(res, 0, sizeof(struct output)); res->info = reg; res->name = strdup(name); if (!res->name) { pom_oom(strlen(name) + 1); goto err; } res->reg_instance = registry_add_instance(output_registry_class, name); if (!res->reg_instance) goto err; res->reg_instance->priv = res; res->perf_runtime = registry_instance_add_perf(res->reg_instance, "runtime", registry_perf_type_timeticks, "Runtime", NULL); if (!res->perf_runtime) goto err; struct ptype *param_running_val = ptype_alloc("bool"); if (!param_running_val) goto err; struct registry_param *param_running = registry_new_param("running", "no", param_running_val, "Running state of the output", REGISTRY_PARAM_FLAG_CLEANUP_VAL); if (!param_running) { ptype_cleanup(param_running_val); goto err; } if (registry_param_set_callbacks(param_running, res, NULL, output_instance_start_stop_handler) != POM_OK) { registry_cleanup_param(param_running); ptype_cleanup(param_running_val); goto err; } if (registry_instance_add_param(res->reg_instance, param_running) != POM_OK) { registry_cleanup_param(param_running); ptype_cleanup(param_running_val); goto err; } struct ptype *output_type = ptype_alloc("string"); if (!output_type) goto err; struct registry_param *type_param = registry_new_param("type", type, output_type, "Type of the output", REGISTRY_PARAM_FLAG_CLEANUP_VAL | REGISTRY_PARAM_FLAG_IMMUTABLE); if (!type_param) { ptype_cleanup(output_type); goto err; } if (registry_instance_add_param(res->reg_instance, type_param) != POM_OK) { registry_cleanup_param(type_param); ptype_cleanup(output_type); goto err; } if (registry_uid_create(res->reg_instance) != POM_OK) goto err; if (reg->reg_info->init) { if (reg->reg_info->init(res) != POM_OK) { pomlog(POMLOG_ERR "Error while initializing the output %s", name); goto err; } } res->next = output_head; if (res->next) res->next->prev = res; output_head = res; return POM_OK; err: if (res->reg_instance) { registry_remove_instance(res->reg_instance); } else { if (res->name) free(res->name); free(res); } return POM_ERR; }
int proto_register(struct proto_reg_info *reg_info) { if (reg_info->api_ver != PROTO_API_VER) { pomlog(POMLOG_ERR "Cannot register proto as API version differ : expected %u got %u", PROTO_API_VER, reg_info->api_ver); return POM_ERR; } // Check if the protocol already exists struct proto *proto; for (proto = proto_head; proto && strcmp(proto->info->name, reg_info->name); proto = proto->next); if (proto) return POM_ERR; // Allocate the protocol proto = malloc(sizeof(struct proto)); if (!proto) { pom_oom(sizeof(struct proto)); return POM_ERR; } memset(proto, 0, sizeof(struct proto)); proto->info = reg_info; proto->id = proto_count; proto_count++; if (reg_info->number_class) { proto->number_class = proto_number_class_get(reg_info->number_class); if (!proto->number_class) goto err_proto; } int res = pthread_rwlock_init(&proto->expectation_lock, NULL); if (res) { pomlog(POMLOG_ERR "Error while initializing the proto_expectation rwlock : %s", pom_strerror(res)); goto err_proto; } res = pthread_rwlock_init(&proto->listeners_lock, NULL); if (res) { pomlog(POMLOG_ERR "Error while initializing the proto_listeners rwlock : %s", pom_strerror(res)); goto err_lock1; } proto->reg_instance = registry_add_instance(proto_registry_class, reg_info->name); if (!proto->reg_instance) { pomlog(POMLOG_ERR "Error while adding the registry instanc for protocol %s", reg_info->name); goto err_lock; } // Allocate the conntrack table if (reg_info->ct_info) { proto->ct = conntrack_table_alloc(reg_info->ct_info->default_table_size, (reg_info->ct_info->rev_pkt_field_id == -1 ? 0 : 1)); if (!proto->ct) { pomlog(POMLOG_ERR "Error while allocating conntrack tables"); goto err_registry; } proto->perf_conn_cur = registry_instance_add_perf(proto->reg_instance, "conn_cur", registry_perf_type_gauge, "Current number of monitored connection", "connections"); proto->perf_conn_tot = registry_instance_add_perf(proto->reg_instance, "conn_tot", registry_perf_type_counter, "Total number of connections", "connections"); proto->perf_conn_hash_col = registry_instance_add_perf(proto->reg_instance, "conn_hash_col", registry_perf_type_counter, "Total number of conntrack hash collisions", "collisions"); if (!proto->perf_conn_cur || !proto->perf_conn_tot || !proto->perf_conn_hash_col) goto err_conntrack; } proto->perf_pkts = registry_instance_add_perf(proto->reg_instance, "pkts", registry_perf_type_counter, "Number of packets processed", "pkts"); proto->perf_bytes = registry_instance_add_perf(proto->reg_instance, "bytes", registry_perf_type_counter, "Number of bytes processed", "bytes"); proto->perf_expt_pending = registry_instance_add_perf(proto->reg_instance, "expectations_pending", registry_perf_type_gauge, "Number of expectations pending", "expectations"); proto->perf_expt_matched = registry_instance_add_perf(proto->reg_instance, "expectations_matched", registry_perf_type_counter, "Number of expectations matched", "expectations"); if (!proto->perf_pkts || !proto->perf_bytes || !proto->perf_expt_pending || !proto->perf_expt_matched) goto err_conntrack; if (reg_info->init) { if (reg_info->init(proto, proto->reg_instance) == POM_ERR) { pomlog(POMLOG_ERR "Error while registering proto %s", reg_info->name); goto err_conntrack; } } mod_refcount_inc(reg_info->mod); proto->next = proto_head; if (proto->next) proto->next->prev = proto; proto_head = proto; pomlog(POMLOG_DEBUG "Proto %s registered", reg_info->name); return POM_OK; err_conntrack: // Remove proto number if any proto_number_unregister(proto); conntrack_table_cleanup(proto->ct); err_registry: registry_remove_instance(proto->reg_instance); err_lock: pthread_rwlock_destroy(&proto->listeners_lock); err_lock1: pthread_rwlock_destroy(&proto->expectation_lock); err_proto: free(proto); return POM_ERR; }
static int input_pcap_interface_init(struct input *i) { if (input_pcap_common_init(i) != POM_OK) return POM_ERR; struct input_pcap_priv *priv = i->priv; struct registry_param *p = NULL; priv->tpriv.iface.p_interface = ptype_alloc("string"); priv->tpriv.iface.p_promisc = ptype_alloc("bool"); priv->tpriv.iface.p_buff_size = ptype_alloc_unit("uint32", "bytes"); if (!priv->tpriv.iface.p_interface || !priv->tpriv.iface.p_promisc || !priv->tpriv.iface.p_buff_size) goto err; priv->tpriv.iface.perf_dropped = registry_instance_add_perf(i->reg_instance, "dropped_pkt", registry_perf_type_counter, "Dropped packets", "pkts"); if (!priv->tpriv.iface.perf_dropped) goto err; registry_perf_set_update_hook(priv->tpriv.iface.perf_dropped, input_pcap_interface_perf_dropped, priv); char err[PCAP_ERRBUF_SIZE] = { 0 }; char *dev = "<none>"; pcap_if_t *alldevsp = NULL; if (pcap_findalldevs(&alldevsp, err)) { pomlog(POMLOG_WARN "Warning, could not find a suitable interface to sniff packets from : %s", err); alldevsp = NULL; } else { dev = alldevsp->name; } p = registry_new_param("interface", dev, priv->tpriv.iface.p_interface, "Interface to capture packets from", 0); if (alldevsp) { pcap_if_t *tmp; for (tmp = alldevsp; tmp; tmp = tmp->next) { if (registry_param_info_add_value(p, tmp->name) != POM_OK) { pcap_freealldevs(alldevsp); goto err; } } pcap_freealldevs(alldevsp); } if (input_add_param(i, p) != POM_OK) goto err; p = registry_new_param("promisc", "no", priv->tpriv.iface.p_promisc, "Promiscious mode", 0); if (input_add_param(i, p) != POM_OK) goto err; p = registry_new_param("buff_size", "16777216", priv->tpriv.iface.p_buff_size, "PCAP ring buffer size", 0); if (input_add_param(i, p) != POM_OK) goto err; priv->type = input_pcap_type_interface; return POM_OK; err: if (priv->tpriv.iface.p_interface) ptype_cleanup(priv->tpriv.iface.p_interface); if (priv->tpriv.iface.p_promisc) ptype_cleanup(priv->tpriv.iface.p_promisc); if (priv->tpriv.iface.p_buff_size) ptype_cleanup(priv->tpriv.iface.p_buff_size); if (p) registry_cleanup_param(p); free(priv); return POM_ERR; }