diff --git a/src/sip.c b/src/sip.c index 00361131..2760a87a 100644 --- a/src/sip.c +++ b/src/sip.c @@ -197,6 +197,7 @@ sip_init(int limit, int only_calls, int no_incomplete) 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_contact, "^(Contact|m):[ ]*[^:]*:(([^@>]+)@?[^\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); @@ -223,6 +224,7 @@ sip_deinit() regfree(&calls.reg_cseq); regfree(&calls.reg_from); regfree(&calls.reg_to); + regfree(&calls.reg_contact); regfree(&calls.reg_valid); regfree(&calls.reg_cl); regfree(&calls.reg_body); @@ -657,6 +659,13 @@ sip_parse_msg_payload(sip_msg_t *msg, const u_char *payload) sng_strncpy(msg->sip_to, "", 12); } + // Contact + if (regexec(&calls.reg_contact, (const char *)payload, 3, pmatch, 0) == 0) { + int len = (int)pmatch[2].rm_eo - pmatch[2].rm_so; + msg->sip_contact = sng_malloc(len + 1); + sng_strncpy(msg->sip_contact, (const char *)payload + pmatch[2].rm_so, len + 1); + } + return 0; } diff --git a/src/sip.h b/src/sip.h index 7267cf72..61d1bd6a 100644 --- a/src/sip.h +++ b/src/sip.h @@ -167,6 +167,7 @@ struct sip_call_list { regex_t reg_cseq; regex_t reg_from; regex_t reg_to; + regex_t reg_contact; regex_t reg_valid; regex_t reg_cl; regex_t reg_body; diff --git a/src/sip_attr.c b/src/sip_attr.c index 72f485e4..1df3578e 100644 --- a/src/sip_attr.c +++ b/src/sip_attr.c @@ -54,7 +54,8 @@ static sip_attr_hdr_t attrs[SIP_ATTR_COUNT] = { { SIP_ATTR_CONVDUR, "convdur", "ConvDur", "Conversation Duration", 7 }, { SIP_ATTR_TOTALDUR, "totaldur", "TotalDur", "Total Duration", 8 }, { SIP_ATTR_REASON_TXT, "reason", "Reason Text", "Reason Text", 25 }, - { SIP_ATTR_WARNING, "warning", "Warning", "Warning code", 4 } + { SIP_ATTR_WARNING, "warning", "Warning", "Warning code", 4 }, + { SIP_ATTR_CONTACT, "contact", NULL, "Contact", 30 } }; sip_attr_hdr_t * diff --git a/src/sip_attr.h b/src/sip_attr.h index 027bf42c..c9868fbb 100644 --- a/src/sip_attr.h +++ b/src/sip_attr.h @@ -85,6 +85,8 @@ enum sip_attr_id { SIP_ATTR_REASON_TXT, //! Warning Header SIP_ATTR_WARNING, + //! SIP Contact header + SIP_ATTR_CONTACT, //! SIP Attribute count SIP_ATTR_COUNT }; diff --git a/src/sip_msg.c b/src/sip_msg.c index 2366a8b9..4c961d51 100644 --- a/src/sip_msg.c +++ b/src/sip_msg.c @@ -54,6 +54,7 @@ msg_destroy(sip_msg_t *msg) sng_free(msg->resp_str); sng_free(msg->sip_from); sng_free(msg->sip_to); + sng_free(msg->sip_contact); sng_free(msg); } @@ -160,6 +161,11 @@ msg_get_attribute(sip_msg_t *msg, int id, char *value) case SIP_ATTR_TIME: timeval_to_time(msg_get_time(msg), value); break; + case SIP_ATTR_CONTACT: + if (msg->sip_contact) { + sprintf(value, "%.*s", SIP_ATTR_MAXLEN, msg->sip_contact); + } + break; default: fprintf(stderr, "Unhandled attribute %s (%d)\n", sip_attr_get_name(id), id); abort(); break; diff --git a/src/sip_msg.h b/src/sip_msg.h index 902623d2..37820177 100644 --- a/src/sip_msg.h +++ b/src/sip_msg.h @@ -60,6 +60,8 @@ struct sip_msg { char *sip_from; //! SIP To Header char *sip_to; + //! SIP Contact Header + char *sip_contact; //! SDP payload information (sdp_media_t *) vector_t *medias; //! Captured packet for this message