sip_call_t * call_create(char *callid, char *xcallid) { sip_call_t *call; // Initialize a new call structure if (!(call = sng_malloc(sizeof(sip_call_t)))) return NULL; // Create a vector to store call messages call->msgs = vector_create(2, 2); vector_set_destroyer(call->msgs, msg_destroyer); // Create an empty vector to store rtp packets if (setting_enabled(SETTING_CAPTURE_RTP)) { call->rtp_packets = vector_create(0, 40); vector_set_destroyer(call->rtp_packets, packet_destroyer); } // Create an empty vector to strore stream data call->streams = vector_create(0, 2); vector_set_destroyer(call->streams, vector_generic_destroyer); // Create an empty vector to store x-calls call->xcalls = vector_create(0, 1); // Initialize call filter status call->filtered = -1; // Set message callid call->callid = strdup(callid); call->xcallid = strdup(xcallid); return call; }
void capture_deinit() { // Close pcap handler capture_close(); // Deallocate vectors vector_set_destroyer(capture_cfg.sources, vector_generic_destroyer); vector_destroy(capture_cfg.sources); vector_set_destroyer(capture_cfg.tcp_reasm, packet_destroyer); vector_destroy(capture_cfg.tcp_reasm); vector_set_destroyer(capture_cfg.ip_reasm, packet_destroyer); vector_destroy(capture_cfg.ip_reasm); // Remove capture mutex pthread_mutex_destroy(&capture_cfg.lock); }
void msg_add_media(sip_msg_t *msg, sdp_media_t *media) { if (!msg->medias) { // Create a vector to store sdp msg->medias = vector_create(2, 2); vector_set_destroyer(msg->medias, media_destroyer); } vector_append(msg->medias, media); }
void call_add_stream(sip_call_t *call, rtp_stream_t *stream) { if (!call->streams) { // Create a vector to store RTP streams call->streams = vector_create(2, 2); vector_set_destroyer(call->streams, vector_generic_destroyer); } vector_append(call->streams, stream); }
void call_add_rtp_packet(sip_call_t *call, capture_packet_t *packet) { if (!call->rtp_packets) { // Create a vector to store RTP streams call->rtp_packets = vector_create(20, 40); vector_set_destroyer(call->rtp_packets, capture_packet_destroyer); } vector_append(call->rtp_packets, packet); }
void sip_sort_list() { // Cloning the vector automatically sorts it vector_t *clone = vector_clone(calls.list); // FIXME FIXME FIXME // There should be a way to destroy the vector without calling the // vector destroyer for each item... vector_set_destroyer(calls.list, NULL); vector_destroy(calls.list); // The new sorted list calls.list = clone; }
sdp_media_t * media_create(struct sip_msg *msg) { sdp_media_t *media;; // Allocate memory for this media structure if (!(media = sng_malloc(sizeof(sdp_media_t)))) return NULL; // Initialize all fields media->msg = msg; media->formats = vector_create(0, 1); vector_set_destroyer(media->formats, vector_generic_destroyer); return media; }
sip_call_t * call_create(char *callid) { sip_call_t *call; // Initialize a new call structure if (!(call = sng_malloc(sizeof(sip_call_t)))) return NULL; // Create a vector to store call messages call->msgs = vector_create(2, 2); vector_set_destroyer(call->msgs, msg_destroyer); // Create a vector to store call attributes call->attrs = vector_create(1, 1); vector_set_destroyer(call->attrs, sip_attr_destroyer); // Initialize call filter status call->filtered = -1; // Set message callid call_set_attribute(call, SIP_ATTR_CALLID, callid); return call; }
void sip_init(int limit, int only_calls, int no_incomplete) { int match_flags; // Store capture limit calls.limit = limit; calls.only_calls = only_calls; calls.ignore_incomplete = no_incomplete; calls.last_index = 0; // Create a vector to store calls calls.list = vector_create(200, 50); vector_set_destroyer(calls.list, call_destroyer); vector_set_sorter(calls.list, sip_list_sorter); calls.active = vector_create(10, 10); // Create hash table for callid search calls.callids = htable_create(calls.limit); // By default sort by call index ascending calls.sort.by = SIP_ATTR_CALLINDEX; calls.sort.asc = true; // Initialize payload parsing regexp match_flags = REG_EXTENDED | REG_ICASE | REG_NEWLINE; regcomp(&calls.reg_method, "^([a-zA-Z]+) sips?:[^ ]+ SIP/2.0\r", match_flags & ~REG_NEWLINE); regcomp(&calls.reg_callid, "^(Call-ID|i):[ ]*([^ ]+)\r$", match_flags); regcomp(&calls.reg_xcallid, "^(X-Call-ID|X-CID):[ ]*([^ ]+)\r$", match_flags); regcomp(&calls.reg_response, "^SIP/2.0[ ]*(([0-9]{3}) [^\r]*)\r", match_flags & ~REG_NEWLINE); regcomp(&calls.reg_cseq, "^CSeq:[ ]*([0-9]+) .+\r$", match_flags); regcomp(&calls.reg_from, "^(From|f):[ ]*[^:]*:(([^@]+)@?[^\r>;]+)", match_flags); regcomp(&calls.reg_to, "^(To|t):[ ]*[^:]*:(([^@]+)@?[^\r>;]+)", match_flags); regcomp(&calls.reg_valid, "^([A-Z]+ sip:|SIP/2.0 [0-9]{3})", match_flags & ~REG_NEWLINE); regcomp(&calls.reg_cl, "^(Content-Length|l):[ ]*([0-9]+)\r$", match_flags); regcomp(&calls.reg_body, "\r\n\r\n(.*)", match_flags & ~REG_NEWLINE); }
vector_t * vector_clone(vector_t *original) { vector_t *clone; vector_iter_t it; void *item; // Check we have a valid vector pointer if (!original) return NULL; // Create a new vector structure clone = vector_create(original->limit, original->step); vector_set_destroyer(clone, original->destroyer); vector_set_sorter(clone, original->sorter); // Fill the clone vector with the same elements it = vector_iterator(original); while ((item = vector_iterator_next(&it))) vector_append(clone, item); // Return the cloned vector return clone; }
void sip_init(int limit, int only_calls, int no_incomplete) { int match_flags, reg_rule_len, reg_rule_err; char reg_rule[SIP_ATTR_MAXLEN]; const char *setting = NULL; // Store capture limit calls.limit = limit; calls.only_calls = only_calls; calls.ignore_incomplete = no_incomplete; calls.last_index = 0; // Create a vector to store calls calls.list = vector_create(200, 50); vector_set_destroyer(calls.list, call_destroyer); vector_set_sorter(calls.list, sip_list_sorter); calls.active = vector_create(10, 10); // Create hash table for callid search calls.callids = htable_create(calls.limit); // Set default sorting field if (sip_attr_from_name(setting_get_value(SETTING_CL_SORTFIELD)) >= 0) { calls.sort.by = sip_attr_from_name(setting_get_value(SETTING_CL_SORTFIELD)); calls.sort.asc = (!strcmp(setting_get_value(SETTING_CL_SORTORDER), "asc")); } else { // Fallback to default sorting field calls.sort.by = SIP_ATTR_CALLINDEX; calls.sort.asc = true; } // Initialize payload parsing regexp match_flags = REG_EXTENDED | REG_ICASE | REG_NEWLINE; regcomp(&calls.reg_method, "^([a-zA-Z]+) [a-zA-Z]+:.+ SIP/2.0[ ]*\r", match_flags & ~REG_NEWLINE); regcomp(&calls.reg_callid, "^(Call-ID|i):[ ]*([^ ]+)[ ]*\r$", match_flags); setting = setting_get_value(SETTING_SIP_HEADER_X_CID); reg_rule_len = strlen(setting) + 22; if (reg_rule_len >= SIP_ATTR_MAXLEN) { setting = "X-Call-ID|X-CID"; reg_rule_len = strlen(setting) + 22; fprintf(stderr, "%s setting too long, using default.\n", setting_name(SETTING_SIP_HEADER_X_CID)); } snprintf(reg_rule, reg_rule_len, "^(%s):[ ]*([^ ]+)[ ]*\r$", setting); reg_rule_err = regcomp(&calls.reg_xcallid, reg_rule, match_flags); if(reg_rule_err != 0) { regerror(reg_rule_err, &calls.reg_xcallid, reg_rule, SIP_ATTR_MAXLEN); regfree(&calls.reg_xcallid); fprintf(stderr, "%s setting produces regex compilation error: %s" "using default value instead\n", setting_name(SETTING_SIP_HEADER_X_CID), reg_rule); regcomp(&calls.reg_xcallid, "^(X-Call-ID|X-CID):[ ]*([^ ]+)[ ]*\r$", match_flags); } regcomp(&calls.reg_response, "^SIP/2.0[ ]*(([0-9]{3}) [^\r]*)[ ]*\r", match_flags & ~REG_NEWLINE); regcomp(&calls.reg_cseq, "^CSeq:[ ]*([0-9]{1,10}) .+\r$", match_flags); regcomp(&calls.reg_from, "^(From|f):[ ]*[^:]*:(([^@>]+)@?[^\r>;]+)", match_flags); regcomp(&calls.reg_to, "^(To|t):[ ]*[^:]*:(([^@>]+)@?[^\r>;]+)", match_flags); regcomp(&calls.reg_valid, "^([A-Z]+ [a-zA-Z]+:|SIP/2.0 [0-9]{3})", match_flags & ~REG_NEWLINE); regcomp(&calls.reg_cl, "^(Content-Length|l):[ ]*([0-9]+)[ ]*\r$", match_flags); regcomp(&calls.reg_body, "\r\n\r\n(.*)", match_flags & ~REG_NEWLINE); regcomp(&calls.reg_reason, "Reason:[ ]*[^\r]*;text=\"([^\r]+)\"", match_flags); regcomp(&calls.reg_warning, "Warning:[ ]*([0-9]*)", match_flags); }