// Copy the packet into a buffer for later use static int streambuf_keep(struct streambuf_unidir *dir) { if (! dir->buffer) return 0; if (dir->buffer_is_malloced) return 0; // we already own a copy, do not touch it. size_t const keep = dir->buffer_size > dir->restart_offset ? dir->buffer_size - dir->restart_offset : 0; SLOG(LOG_DEBUG, "Keeping only %zu bytes of streambuf_unidir@%p", keep, dir); if (keep > 0) { uint8_t *buf = objalloc_nice(keep, "streambufs"); if (! buf) { dir->buffer = NULL; // never escape from here with buffer referencing a non malloced packet return -1; } memcpy(buf, dir->buffer + dir->restart_offset, keep); dir->buffer = buf; dir->buffer_is_malloced = true; dir->buffer_size = keep; dir->restart_offset = 0; } else { dir->restart_offset -= dir->buffer_size; streambuf_empty(dir); } return 0; }
static struct parser *netbios_parser_new(struct proto *proto) { struct netbios_parser *netbios_parser = objalloc_nice(sizeof(*netbios_parser), "Netbios parsers"); if (! netbios_parser) return NULL; if (-1 == netbios_parser_ctor(netbios_parser, proto)) { objfree(netbios_parser); return NULL; } return &netbios_parser->parser; }
static struct callid_2_sdp *callid_2_sdp_new(char const *call_id, struct timeval const *now) { struct callid_2_sdp *c2s = objalloc_nice(sizeof(*c2s), "SIP->SDP"); if (! c2s) return NULL; if (0 != callid_2_sdp_ctor(c2s, call_id, now)) { objfree(c2s); return NULL; } return c2s; }
int netmatch_filter_ctor(struct netmatch_filter *netmatch, char const *libname) { netmatch->libname = objalloc_strdup(libname); if (! netmatch->libname) { goto err0; } netmatch->handle = lt_dlopen(libname); if (! netmatch->handle) { SLOG(LOG_CRIT, "Cannot load netmatch shared object %s: %s", libname, lt_dlerror()); goto err1; } (void)file_unlink(libname); netmatch->match_fun = lt_dlsym(netmatch->handle, "match"); if (! netmatch->match_fun) { SLOG(LOG_CRIT, "Cannot find match function in netmatch shared object %s", libname); goto err2; } unsigned const *nb_regs_ptr = lt_dlsym(netmatch->handle, "nb_registers"); if (! nb_regs_ptr) { SLOG(LOG_CRIT, "Cannot find nb_registers symbol in netmatch shared object %s", libname); goto err2; } netmatch->nb_registers = *nb_regs_ptr; if (netmatch->nb_registers > 0) { netmatch->regfile = objalloc_nice(netmatch->nb_registers * sizeof(*netmatch->regfile), "netmatches"); if (! netmatch->regfile) goto err3; memset(netmatch->regfile, 0, netmatch->nb_registers * sizeof(*netmatch->regfile)); } else { netmatch->regfile = NULL; } return 0; err3: if (netmatch->regfile) { objfree(netmatch->regfile); netmatch->regfile = NULL; } err2: if (netmatch->handle) { (void)lt_dlclose(netmatch->handle); netmatch->handle = NULL; } err1: if (netmatch->libname) { objfree(netmatch->libname); netmatch->libname = NULL; } err0: return -1; }
static enum proto_parse_status streambuf_append(struct streambuf *sbuf, unsigned way, uint8_t const *packet, size_t cap_len, size_t wire_len) { assert(way < 2); SLOG(LOG_DEBUG, "Append %zu bytes (%zu captured) to streambuf@%p[%u] of size %zu (restart @ %zu)", wire_len, cap_len, sbuf, way, sbuf->dir[way].buffer_size, sbuf->dir[way].restart_offset); // Naive implementation : each time we add some bytes we realloc buffer // FIXME: use a redim_array ? // FIXME: better yet, rewrite everything using pkt-lists from end to end struct streambuf_unidir *dir = sbuf->dir+way; if (! dir->buffer) { dir->buffer = packet; dir->buffer_size = cap_len; dir->buffer_is_malloced = false; } else { ssize_t const keep_size = dir->buffer_size - dir->restart_offset; ssize_t const new_size = keep_size + cap_len; if (new_size > 0) { // we restart in captured bytes if ((size_t)new_size > sbuf->max_size) return PROTO_PARSE_ERR; uint8_t *new_buffer = objalloc_nice(new_size, "streambufs"); if (! new_buffer) return PROTO_PARSE_ERR; // Assemble kept buffer and new payload if (keep_size > 0) memcpy(new_buffer, dir->buffer + dir->restart_offset, keep_size); else if (keep_size < 0) { // skip some part of captured bytes size_t const skip_size = -keep_size; assert(skip_size < cap_len); // since new_size > 0 packet += skip_size; cap_len -= skip_size; assert(wire_len >= cap_len); // thus skip_size < wire_len too wire_len -= skip_size; } memcpy(new_buffer + (keep_size > 0 ? keep_size:0), packet, cap_len); assert(dir->buffer); if (dir->buffer_is_malloced) objfree((void*)dir->buffer); dir->buffer = new_buffer; dir->buffer_size = new_size; dir->buffer_is_malloced = true; dir->restart_offset = 0; } else { // we restart after captured bytes ssize_t const new_restart_offset = dir->restart_offset - (dir->buffer_size + wire_len); // check we don't want to restart within uncaptured bytes if (new_restart_offset < 0) return PROTO_TOO_SHORT; dir->restart_offset = new_restart_offset; streambuf_empty(dir); } } return PROTO_OK; }
static struct parser *tns_parser_new(struct proto *proto) { struct tns_parser *tns_parser = objalloc_nice(sizeof(*tns_parser), "TNS parsers"); if (! tns_parser) return NULL; if (-1 == tns_parser_ctor(tns_parser, proto)) { objfree(tns_parser); return NULL; } return &tns_parser->parser; }
static struct parser *tds_parser_new(struct proto *proto) { struct tds_parser *tds_parser = objalloc_nice(sizeof(*tds_parser), "TDS(transp) parsers"); if (! tds_parser) return NULL; if (-1 == tds_parser_ctor(tds_parser, proto)) { objfree(tds_parser); return NULL; } return &tds_parser->parser; }
static struct capfile *capfile_new(struct capfile_ops const *ops, char const *path, unsigned max_pkts, size_t max_size, unsigned max_secs, size_t cap_len, unsigned rotation, struct timeval const *now) { struct capfile *capfile = objalloc_nice(sizeof(*capfile), "capfiles"); if (! capfile) return NULL; if (0 != capfile_ctor(capfile, ops, path, max_pkts, max_size, max_secs, cap_len, rotation, now)) { objfree(capfile); return NULL; } return capfile; }
static struct parser *mgcp_parser_new(struct proto *proto) { struct mgcp_parser *mgcp_parser = objalloc_nice(sizeof(*mgcp_parser), "MGCP parsers"); if (! mgcp_parser) return NULL; if (-1 == mgcp_parser_ctor(mgcp_parser, proto)) { objfree(mgcp_parser); return NULL; } return &mgcp_parser->parser; }
static struct parser *skinny_parser_new(struct proto *proto) { struct skinny_parser *skinny_parser = objalloc_nice(sizeof(*skinny_parser), "SKINNY parsers"); if (! skinny_parser) return NULL; if (-1 == skinny_parser_ctor(skinny_parser, proto)) { objfree(skinny_parser); return NULL; } return &skinny_parser->parser; }
static struct parser *sdp_parser_new(struct proto *proto) { struct sdp_parser *sdp_parser = objalloc_nice(sizeof *sdp_parser, "SDP parser"); if (! sdp_parser) return NULL; if (-1 == sdp_parser_ctor(sdp_parser, proto)) { objfree(sdp_parser); return NULL; } return &sdp_parser->parser; }
static struct parser *pg_parser_new(struct proto *proto) { struct pgsql_parser *pg_parser = objalloc_nice(sizeof(*pg_parser), "Pg parsers"); if (! pg_parser) return NULL; if (-1 == pg_parser_ctor(pg_parser, proto)) { objfree(pg_parser); return NULL; } return &pg_parser->parser; }