Files
freeswitch/libs/sipcc/core/sipstack/ccsip_debug.c
T
2012-12-17 20:15:23 -05:00

393 lines
13 KiB
C

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "debug.h"
#include "phone_debug.h"
#include "ccsip_publish.h"
#include "util_string.h"
#include "sip_interface_regmgr.h"
extern boolean dump_reg_msg;
/* SIP flags */
cc_int32_t SipDebugMessage = 1; /* SIP messaging output */
cc_int32_t SipDebugState = 0; /* SIP State Machine output */
cc_int32_t SipDebugTask = 1; /* SIP Task output */
cc_int32_t SipDebugRegState = 0; /* SIP Registration State Mach. output */
/**
* SipRelDevEnabled flag is not a debug print flag. It actually turns
* on and off reliable delivery module in sip layer. We will keep
* this on as retransmissions are enabled on CUCM by default even for TCP transport
*/
int32_t SipRelDevEnabled = 1; /* Is reliable delivery on? */
int32_t SipDebugGenContactHeader = 0; /* Generate Contact header */
cc_int32_t SipDebugTrx = 0; /* SIP Transaction Layer output */
cc_int32_t GSMDebug = 0;
cc_int32_t FIMDebug = 0;
cc_int32_t LSMDebug = 0;
cc_int32_t FSMDebugSM = 0;
int32_t CSMDebugSM = 0;
cc_int32_t CCDebug = 0;
cc_int32_t CCDebugMsg = 0;
cc_int32_t AuthDebug = 0;
cc_int32_t g_DEFDebug = 1;
cc_int32_t TNPDebug = 1;
cc_int32_t VCMDebug = 0;
cc_int32_t CCEVENTDebug = 0;
cc_int32_t PLATDebug = 0;
cc_int32_t TMRDebug = 0;
cc_int32_t g_dcsmDebug = 0;
/**
*
* Dump sip messages
*
* @param msg - message buffer
* pSIPMessage - parsed message structure
* cc_remote_ipaddr - remote ip address
* cc_remote_port - remote port number
*
* @return none
*
* @pre (valid pSIPMessage AND
* valid cc_remote_ipaddr)
*/
void ccsip_dump_send_msg_info (char *msg, sipMessage_t *pSIPMessage,
cpr_ip_addr_t *cc_remote_ipaddr,
uint16_t cc_remote_port)
{
char *disp_buf;
const char *req_uri;
const char *cseq;
const char *callid;
char ipaddr_str[MAX_IPADDR_STR_LEN];
static const char fname[] = "ccsip_dump_send_msg_info";
ipaddr2dotted(ipaddr_str, cc_remote_ipaddr);
req_uri = sippmh_get_header_val(pSIPMessage, SIP_HEADER_TO, NULL);
if (req_uri == NULL) {
/* No REQ URI, fill with blank */
req_uri = "";
}
cseq = sippmh_get_header_val(pSIPMessage, SIP_HEADER_CSEQ, NULL);
if (cseq == NULL) {
/* No REQ CSEQ, fill with blank */
cseq = "";
}
callid = sippmh_get_header_val(pSIPMessage, SIP_HEADER_CALLID, NULL);
if (callid == NULL) {
/* No REQ CSEQ, fill with blank */
callid = "";
}
/* For messages starting with SIP add 8 byte. default
* debugs do not show all the SIP message information
* rather show initial msg.
*/
if (msg != NULL) {
if (msg[0] == 'S' &&
msg[1] == 'I' &&
msg[2] == 'P') {
disp_buf = &msg[8];
} else {
disp_buf = msg;
}
if ((strncmp(disp_buf, SIP_METHOD_REGISTER, sizeof(SIP_METHOD_REGISTER)-1) == 0) &&
(!dump_reg_msg)) {
return;
}
} else {
/* No msg. buffer */
disp_buf = NULL;
}
if (disp_buf != NULL) {
DEF_DEBUG(DEB_F_PREFIX"<%s:%-4d>:%c%c%c%c%c%c%c: %-10s :%-6s::%s\n",
DEB_F_PREFIX_ARGS(SIP_MSG_SEND, fname),
ipaddr_str, cc_remote_port,
disp_buf[0],
disp_buf[1],
disp_buf[2],
disp_buf[3],
disp_buf[4],
disp_buf[5],
disp_buf[6],
req_uri,
cseq, callid);
} else {
/* No msg to send */
DEF_DEBUG(DEB_F_PREFIX"<%s:%-4d>: empty message\n",
DEB_F_PREFIX_ARGS(SIP_MSG_SEND, fname),
ipaddr_str, cc_remote_port);
}
}
/**
*
* Dump sip messages
*
* @param msg - message buffer
* pSIPMessage - parsed message structure
* cc_remote_ipaddr - remote ip address
* cc_remote_port - remote port number
*
* @return none
*
* @pre (valid pSIPMessage AND
* valid cc_remote_ipaddr)
*/
void ccsip_dump_recv_msg_info (sipMessage_t *pSIPMessage,
cpr_ip_addr_t *cc_remote_ipaddr,
uint16_t cc_remote_port)
{
char *disp_buf;
const char *req_uri;
const char *cseq;
const char *callid;
char ipaddr_str[MAX_IPADDR_STR_LEN];
cpr_ip_addr_t cc_ipaddr;
static const char fname[] = "ccsip_dump_recv_msg_info";
util_ntohl(&cc_ipaddr, cc_remote_ipaddr);
ipaddr2dotted(ipaddr_str, &cc_ipaddr);
req_uri = sippmh_get_cached_header_val(pSIPMessage, FROM);
if (req_uri == NULL) {
/* No REQ URI, fill with blank */
req_uri = "";
}
cseq = sippmh_get_cached_header_val(pSIPMessage, CSEQ);
if (cseq == NULL) {
/* No REQ CSEQ, fill with blank */
cseq = "";
}
callid = sippmh_get_cached_header_val(pSIPMessage, CALLID);
if (callid == NULL) {
/* No REQ CSEQ, fill with blank */
callid = "";
}
if (!dump_reg_msg) {
if (strstr(cseq, SIP_METHOD_REGISTER) != NULL) {
return;
}
}
/* For messages starting with SIP add 8 byte. default
* debugs do not show all the SIP message information
* rather show initial msg.
*/
if (pSIPMessage->mesg_line != NULL) {
if (pSIPMessage->mesg_line[0] == 'S' &&
pSIPMessage->mesg_line[1] == 'I' &&
pSIPMessage->mesg_line[2] == 'P') {
disp_buf = &(pSIPMessage->mesg_line[8]);
} else {
disp_buf = pSIPMessage->mesg_line;
}
} else {
/*
* It is possible that this function is called with
* invalid message or partially received.
*/
disp_buf = NULL;
}
if (disp_buf != NULL) {
DEF_DEBUG(DEB_F_PREFIX"<%s:%-4d>:%c%c%c%c%c%c%c: %-10s :%-6s::%s\n",
DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname),
ipaddr_str, cc_remote_port,
disp_buf[0],
disp_buf[1],
disp_buf[2],
disp_buf[3],
disp_buf[4],
disp_buf[5],
disp_buf[6],
req_uri,
cseq, callid);
} else {
/* No line received */
DEF_DEBUG(DEB_F_PREFIX"<%s:%-4d>: empty message\n",
DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname),
ipaddr_str, cc_remote_port);
}
}
/**
*
* platform_print_sip_msg
*
* The function perform printing SIP msg.
*
* Parameters: msg - pointer to character strings of the SIP messages.
*
* Return Value: None
*
*/
void
platform_print_sip_msg (const char *msg)
{
char *buf;
int msg_to_crypto_line_len, msg_to_digits_tag_len, buf_len;
const char *c_line_begin, *c_line_end;
static const char crypto_line_tag[] = "a=crypto:";
static const char crypto_mask[] = "...";
static const char digits_tag[] = "digits=";
if (msg == NULL) {
return;
}
buginf_msg("\n");
/* replace digits for security reasons */
if (strstr(msg, "kpml-response")) {
/* This is kpml response. so supress printing digits. */
c_line_begin = strstr(msg, digits_tag);
if (c_line_begin == NULL) {
/* No digits, print everything */
buginf_msg(msg);
return;
}
/*
* Calculate the length of the msg. to print from
* from the beginning to the end of the "digits=" i.e.
*/
msg_to_digits_tag_len = c_line_begin - msg + sizeof(digits_tag);
buf_len = msg_to_digits_tag_len + sizeof(crypto_mask);
buf = (char *) cpr_malloc(buf_len);
if (buf == NULL) {
/* No memory */
return;
}
/* Copy the message upto "digits=" */
memcpy(buf, msg, msg_to_digits_tag_len);
/* Copy mask and the end NULL terminating char to the buffer */
memcpy(&buf[msg_to_digits_tag_len], crypto_mask, sizeof(crypto_mask));
/* Print it out now */
buginf_msg(buf);
cpr_free(buf);
c_line_end = c_line_begin + sizeof(digits_tag) + 3; /* 3 beacuse " + digit + " */
msg = c_line_end;
buginf_msg(msg);
} else if (sip_regmgr_get_sec_level(1) == ENCRYPTED) {
/* The 1st. line is using encrypted signaling */
while (TRUE) {
c_line_begin = strstr(msg, crypto_line_tag);
if (c_line_begin == NULL) {
/* No more crypto line, print whatever left and done */
buginf_msg(msg);
return;
} else {
/*
* Found a crypto line:
*
* Allocate buffer to print the msg. including this
* instance of crypto line but no crypto parameter.
* For example:
*
* v=0
* o=Cisco-SIPUA 3052 7 IN IP4 10.80.35.217
* s=SIP Call
* t=0 0
* m=audio 28926 RTP/SAVP 0 8 18 101
* c=IN IP4 10.80.35.217
* a=crypto:1 AES_CM_128_HMAC_SHA1_32 inline:GqT...
* a=rtpmap:0 PCMU/8000
*
*
* The output of printing will be
*
* v=0
* o=Cisco-SIPUA 3052 7 IN IP4 10.80.35.217
* s=SIP Call
* t=0 0
* m=audio 28926 RTP/SAVP 0 8 18 101
* c=IN IP4 10.80.35.217
* a=crypto:1...
* a=rtpmap:0 PCMU/8000
*
*/
/*
* Calculate the length of the msg. to print from
* current position to the end of the "a=crypto:n" i.e.
* from the current of msg passes the ":" by one character
* after of the "a=crypto:". This allows the first character
* of the crypto tag field character to be included in the
* output. Note that there is no explicit adding this
* extra character in the code below because of the
* sizeof(crypto_line_tag) includes extra 1 byte of string
* termination character already. It will be the extra
* character to print after the ":".
*/
msg_to_crypto_line_len = c_line_begin - msg +
sizeof(crypto_line_tag);
/*
* The buffer allocated to print includes the length from
* current msg pointer to this instance of crypto line +
* the mask length plus 1 byte for NULL terminating character.
* The NULL terminating character is included in the
* sizeof(crypto_mask) below.
*/
buf_len = msg_to_crypto_line_len + sizeof(crypto_mask);
buf = (char *) cpr_malloc(buf_len);
if (buf == NULL) {
/* No memory */
return;
}
/* Copy the message including this instance of crypto line */
memcpy(buf, msg, msg_to_crypto_line_len);
/* Copy mask and the end NULL terminating char to the buffer */
memcpy(&buf[msg_to_crypto_line_len], crypto_mask,
sizeof(crypto_mask));
/* Print it out now */
buginf_msg(buf);
cpr_free(buf);
/* Find the end of the crypto line */
c_line_end = strpbrk(c_line_begin, "\n");
if (c_line_end != NULL) {
/* Skip pass the "\n" character of the crypto line */
msg = c_line_end + 1;
} else {
/* Some thing is wrong, no end line character in SDP */
return;
}
}
}
} else {
/* print full content */
buginf_msg(msg);
}
}
/*
* Function: ccsip_debug_init()
*
* Parameters: None
*
* Description: Initialize the Debug keywords used by the SIP protocol stack.
*
* Returns: None
*
*/
void
ccsip_debug_init (void)
{
/* Placeholder for doing any initialization related tasks */
}