00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00033 #include <stdio.h>
00034 #include <stdlib.h>
00035 #include <string.h>
00036 #include <time.h>
00037 #include "../../sr_module.h"
00038 #include "../../dprint.h"
00039 #include "../../ut.h"
00040 #include "../../ip_addr.h"
00041 #include "../../mem/mem.h"
00042 #include "../../mem/shm_mem.h"
00043 #include "../../lib/kmi/mi.h"
00044 #include "../../lib/srdb1/db.h"
00045 #include "../../parser/parse_content.h"
00046 #include "../../parser/parse_from.h"
00047 #include "../../parser/parse_cseq.h"
00048 #include "../../pvar.h"
00049 #include "../../modules/tm/tm_load.h"
00050 #include "../../modules/sl/sl.h"
00051 #include "../../str.h"
00052 #include "../../onsend.h"
00053
00054 #include "../../modules/sipcapture/sipcapture.h"
00055
00056 #ifdef STATISTICS
00057 #include "../../lib/kcore/statistics.h"
00058 #endif
00059
00060 MODULE_VERSION
00061
00062 struct _siptrace_data {
00063 struct usr_avp *avp;
00064 int_str avp_value;
00065 struct search_state state;
00066 str body;
00067 str callid;
00068 str method;
00069 str status;
00070 char *dir;
00071 str fromtag;
00072 str fromip;
00073 str toip;
00074 char toip_buff[IP_ADDR_MAX_STR_SIZE+12];
00075 char fromip_buff[IP_ADDR_MAX_STR_SIZE+12];
00076 struct timeval tv;
00077 #ifdef STATISTICS
00078 stat_var *stat;
00079 #endif
00080 };
00081
00082 struct tm_binds tmb;
00083
00085 sl_api_t slb;
00086
00087
00088 static int mod_init(void);
00089 static int child_init(int rank);
00090 static void destroy(void);
00091 static int sip_trace(struct sip_msg*, char*, char*);
00092
00093 static int sip_trace_store_db(struct _siptrace_data* sto);
00094 static int trace_send_duplicate(char *buf, int len);
00095
00096 static void trace_onreq_in(struct cell* t, int type, struct tmcb_params *ps);
00097 static void trace_onreq_out(struct cell* t, int type, struct tmcb_params *ps);
00098 static void trace_onreply_in(struct cell* t, int type, struct tmcb_params *ps);
00099 static void trace_onreply_out(struct cell* t, int type, struct tmcb_params *ps);
00100 static void trace_sl_onreply_out(sl_cbp_t *slcb);
00101 static void trace_sl_ack_in(sl_cbp_t *slcb);
00102
00103 static int trace_send_hep_duplicate(str *body, str *from, str *to);
00104 static int pipport2su (char *pipport, union sockaddr_union *tmp_su, unsigned int *proto);
00105
00106
00107 static struct mi_root* sip_trace_mi(struct mi_root* cmd, void* param );
00108
00109 static str db_url = str_init(DEFAULT_RODB_URL);
00110 static str siptrace_table = str_init("sip_trace");
00111 static str date_column = str_init("time_stamp");
00112 static str callid_column = str_init("callid");
00113 static str traced_user_column = str_init("traced_user");
00114 static str msg_column = str_init("msg");
00115 static str method_column = str_init("method");
00116 static str status_column = str_init("status");
00117 static str fromip_column = str_init("fromip");
00118 static str toip_column = str_init("toip");
00119 static str fromtag_column = str_init("fromtag");
00120 static str direction_column = str_init("direction");
00121 static str time_us_column = str_init("time_us");
00122
00123 #define NR_KEYS 11
00124
00125 #define XHEADERS_BUFSIZE 512
00126
00127 int trace_flag = -1;
00128 int trace_on = 0;
00129 int trace_sl_acks = 1;
00130
00131 int trace_to_database = 1;
00132 int trace_delayed = 0;
00133
00134 int hep_version = 1;
00135 int hep_capture_id = 1;
00136
00137 int xheaders_write = 0;
00138 int xheaders_read = 0;
00139
00140 str dup_uri_str = {0, 0};
00141 struct sip_uri *dup_uri = 0;
00142
00143 int *trace_on_flag = NULL;
00144 int *trace_to_database_flag = NULL;
00145
00146 int *xheaders_write_flag = NULL;
00147 int *xheaders_read_flag = NULL;
00148
00149 static unsigned short traced_user_avp_type = 0;
00150 static int_str traced_user_avp;
00151 static str traced_user_avp_str = {NULL, 0};
00152
00153 static unsigned short trace_table_avp_type = 0;
00154 static int_str trace_table_avp;
00155 static str trace_table_avp_str = {NULL, 0};
00156
00157 static str trace_local_ip = {NULL, 0};
00158
00159 int hep_mode_on = 0;
00160
00161 db1_con_t *db_con = NULL;
00162 db_func_t db_funcs;
00167 static cmd_export_t cmds[] = {
00168 {"sip_trace", (cmd_function)sip_trace, 0, 0, 0, ANY_ROUTE},
00169 {"sip_trace", (cmd_function)sip_trace, 1, 0, 0, ANY_ROUTE},
00170 {0, 0, 0, 0, 0, 0}
00171 };
00172
00173
00177 static param_export_t params[] = {
00178 {"db_url", STR_PARAM, &db_url.s },
00179 {"table", STR_PARAM, &siptrace_table.s },
00180 {"date_column", STR_PARAM, &date_column.s },
00181 {"callid_column", STR_PARAM, &callid_column.s },
00182 {"traced_user_column", STR_PARAM, &traced_user_column.s },
00183 {"msg_column", STR_PARAM, &msg_column.s },
00184 {"method_column", STR_PARAM, &method_column.s },
00185 {"status_column", STR_PARAM, &status_column.s },
00186 {"fromip_column", STR_PARAM, &fromip_column.s },
00187 {"toip_column", STR_PARAM, &toip_column.s },
00188 {"fromtag_column", STR_PARAM, &fromtag_column.s },
00189 {"direction_column", STR_PARAM, &direction_column.s },
00190 {"trace_flag", INT_PARAM, &trace_flag },
00191 {"trace_on", INT_PARAM, &trace_on },
00192 {"traced_user_avp", STR_PARAM, &traced_user_avp_str.s},
00193 {"trace_table_avp", STR_PARAM, &trace_table_avp_str.s},
00194 {"duplicate_uri", STR_PARAM, &dup_uri_str.s },
00195 {"trace_to_database", INT_PARAM, &trace_to_database },
00196 {"trace_local_ip", STR_PARAM, &trace_local_ip.s },
00197 {"trace_sl_acks", INT_PARAM, &trace_sl_acks },
00198 {"xheaders_write", INT_PARAM, &xheaders_write },
00199 {"xheaders_read", INT_PARAM, &xheaders_read },
00200 {"hep_mode_on", INT_PARAM, &hep_mode_on },
00201 {"hep_version", INT_PARAM, &hep_version },
00202 {"hep_capture_id", INT_PARAM, &hep_capture_id },
00203 {"trace_delayed", INT_PARAM, &trace_delayed },
00204 {0, 0, 0}
00205 };
00206
00210 static mi_export_t mi_cmds[] = {
00211 { "sip_trace", sip_trace_mi, 0, 0, 0 },
00212 { 0, 0, 0, 0, 0}
00213 };
00214
00215
00216 #ifdef STATISTICS
00217 stat_var* siptrace_req;
00218 stat_var* siptrace_rpl;
00219
00220 stat_export_t siptrace_stats[] = {
00221 {"traced_requests" , 0, &siptrace_req },
00222 {"traced_replies" , 0, &siptrace_rpl },
00223 {0,0,0}
00224 };
00225 #endif
00226
00228 struct module_exports exports = {
00229 "siptrace",
00230 DEFAULT_DLFLAGS,
00231 cmds,
00232 params,
00233 #ifdef STATISTICS
00234 siptrace_stats,
00235 #else
00236 0,
00237 #endif
00238 mi_cmds,
00239 0,
00240 0,
00241 mod_init,
00242 0,
00243 destroy,
00244 child_init
00245 };
00246
00247
00249 static int mod_init(void)
00250 {
00251 pv_spec_t avp_spec;
00252 sl_cbelem_t slcb;
00253
00254 #ifdef STATISTICS
00255
00256 if (register_module_stats(exports.name, siptrace_stats)!=0)
00257 {
00258 LM_ERR("failed to register core statistics\n");
00259 return -1;
00260 }
00261 #endif
00262
00263 if(register_mi_mod(exports.name, mi_cmds)!=0)
00264 {
00265 LM_ERR("failed to register MI commands\n");
00266 return -1;
00267 }
00268
00269 db_url.len = strlen(db_url.s);
00270 siptrace_table.len = strlen(siptrace_table.s);
00271 date_column.len = strlen(date_column.s);
00272 callid_column.len = strlen(callid_column.s);
00273 traced_user_column.len = strlen(traced_user_column.s);
00274 msg_column.len = strlen(msg_column.s);
00275 method_column.len = strlen(method_column.s);
00276 status_column.len = strlen(status_column.s);
00277 fromip_column.len = strlen(fromip_column.s);
00278 toip_column.len = strlen(toip_column.s);
00279 fromtag_column.len = strlen(fromtag_column.s);
00280 direction_column.len = strlen(direction_column.s);
00281 if (traced_user_avp_str.s)
00282 traced_user_avp_str.len = strlen(traced_user_avp_str.s);
00283 if (trace_table_avp_str.s)
00284 trace_table_avp_str.len = strlen(trace_table_avp_str.s);
00285 if (dup_uri_str.s)
00286 dup_uri_str.len = strlen(dup_uri_str.s);
00287 if (trace_local_ip.s)
00288 trace_local_ip.len = strlen(trace_local_ip.s);
00289
00290 if (trace_flag<0 || trace_flag>(int)MAX_FLAG)
00291 {
00292 LM_ERR("invalid trace flag %d\n", trace_flag);
00293 return -1;
00294 }
00295 trace_flag = 1<<trace_flag;
00296
00297 trace_to_database_flag = (int*)shm_malloc(sizeof(int));
00298 if(trace_to_database_flag==NULL) {
00299 LM_ERR("no more shm memory left\n");
00300 return -1;
00301 }
00302
00303 *trace_to_database_flag = trace_to_database;
00304
00305
00306 if(trace_to_database_flag!=NULL && *trace_to_database_flag!=0) {
00307 if (db_bind_mod(&db_url, &db_funcs))
00308 {
00309 LM_ERR("unable to bind database module\n");
00310 return -1;
00311 }
00312 if (trace_to_database_flag && !DB_CAPABILITY(db_funcs, DB_CAP_INSERT))
00313 {
00314 LM_ERR("database modules does not provide all functions needed"
00315 " by module\n");
00316 return -1;
00317 }
00318 }
00319
00320 if(hep_version != 1 && hep_version != 2) {
00321
00322 LM_ERR("unsupported version of HEP");
00323 return -1;
00324 }
00325
00326
00327 trace_on_flag = (int*)shm_malloc(sizeof(int));
00328 if(trace_on_flag==NULL) {
00329 LM_ERR("no more shm memory left\n");
00330 return -1;
00331 }
00332
00333 *trace_on_flag = trace_on;
00334
00335 xheaders_write_flag = (int*)shm_malloc(sizeof(int));
00336 xheaders_read_flag = (int*)shm_malloc(sizeof(int));
00337 if (!(xheaders_write_flag && xheaders_read_flag)) {
00338 LM_ERR("no more shm memory left\n");
00339 return -1;
00340 }
00341 *xheaders_write_flag = xheaders_write;
00342 *xheaders_read_flag = xheaders_read;
00343
00344
00345 if (load_tm_api(&tmb)!=0) {
00346 LM_WARN("can't load tm api. Will not install tm callbacks.\n");
00347 } else if(tmb.register_tmcb( 0, 0, TMCB_REQUEST_IN, trace_onreq_in, 0, 0) <=0) {
00348 LM_ERR("can't register trace_onreq_in\n");
00349 return -1;
00350 }
00351
00352
00353 if (sl_load_api(&slb)!=0) {
00354 LM_WARN("cannot bind to SL API. Will not install sl callbacks.\n");
00355 } else {
00356
00357 memset(&slcb, 0, sizeof(sl_cbelem_t));
00358
00359 slcb.type = SLCB_REPLY_READY;
00360 slcb.cbf = trace_sl_onreply_out;
00361 if (slb.register_cb(&slcb) != 0) {
00362 LM_ERR("can't register for SLCB_REPLY_READY\n");
00363 return -1;
00364 }
00365
00366 if(trace_sl_acks)
00367 {
00368 slcb.type = SLCB_ACK_FILTERED;
00369 slcb.cbf = trace_sl_ack_in;
00370 if (slb.register_cb(&slcb) != 0) {
00371 LM_ERR("can't register for SLCB_ACK_FILTERED\n");
00372 return -1;
00373 }
00374 }
00375 }
00376
00377 if(dup_uri_str.s!=0)
00378 {
00379 dup_uri_str.len = strlen(dup_uri_str.s);
00380 dup_uri = (struct sip_uri *)pkg_malloc(sizeof(struct sip_uri));
00381 if(dup_uri==0)
00382 {
00383 LM_ERR("no more pkg memory left\n");
00384 return -1;
00385 }
00386 memset(dup_uri, 0, sizeof(struct sip_uri));
00387 if(parse_uri(dup_uri_str.s, dup_uri_str.len, dup_uri)<0)
00388 {
00389 LM_ERR("bad dup uri\n");
00390 return -1;
00391 }
00392 }
00393
00394 if(traced_user_avp_str.s && traced_user_avp_str.len > 0)
00395 {
00396 if (pv_parse_spec(&traced_user_avp_str, &avp_spec)==0
00397 || avp_spec.type!=PVT_AVP)
00398 {
00399 LM_ERR("malformed or non AVP %.*s AVP definition\n",
00400 traced_user_avp_str.len, traced_user_avp_str.s);
00401 return -1;
00402 }
00403
00404 if(pv_get_avp_name(0, &avp_spec.pvp, &traced_user_avp,
00405 &traced_user_avp_type)!=0)
00406 {
00407 LM_ERR("[%.*s] - invalid AVP definition\n",
00408 traced_user_avp_str.len, traced_user_avp_str.s);
00409 return -1;
00410 }
00411 } else {
00412 traced_user_avp.n = 0;
00413 traced_user_avp_type = 0;
00414 }
00415 if(trace_table_avp_str.s && trace_table_avp_str.len > 0)
00416 {
00417 if (pv_parse_spec(&trace_table_avp_str, &avp_spec)==0
00418 || avp_spec.type!=PVT_AVP)
00419 {
00420 LM_ERR("malformed or non AVP %.*s AVP definition\n",
00421 trace_table_avp_str.len, trace_table_avp_str.s);
00422 return -1;
00423 }
00424
00425 if(pv_get_avp_name(0, &avp_spec.pvp, &trace_table_avp,
00426 &trace_table_avp_type)!=0)
00427 {
00428 LM_ERR("[%.*s] - invalid AVP definition\n",
00429 trace_table_avp_str.len, trace_table_avp_str.s);
00430 return -1;
00431 }
00432 } else {
00433 trace_table_avp.n = 0;
00434 trace_table_avp_type = 0;
00435 }
00436
00437 return 0;
00438 }
00439
00440
00441 static int child_init(int rank)
00442 {
00443 if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
00444 return 0;
00445
00446 if(trace_to_database_flag!=NULL && *trace_to_database_flag!=0) {
00447 db_con = db_funcs.init(&db_url);
00448 if (!db_con)
00449 {
00450 LM_ERR("unable to connect to database. Please check configuration.\n");
00451 return -1;
00452 }
00453 }
00454
00455 return 0;
00456 }
00457
00458
00459 static void destroy(void)
00460 {
00461 if(trace_to_database_flag!=NULL && *trace_to_database_flag!=0) {
00462 if (db_con!=NULL)
00463 db_funcs.close(db_con);
00464 }
00465
00466 if (trace_on_flag)
00467 shm_free(trace_on_flag);
00468
00469 }
00470
00471 static inline int siptrace_copy_proto(int proto, char *buf)
00472 {
00473 if(buf==0)
00474 return -1;
00475 if(proto==PROTO_TCP) {
00476 strcpy(buf, "tcp:");
00477 } else if(proto==PROTO_TLS) {
00478 strcpy(buf, "tls:");
00479 } else if(proto==PROTO_SCTP) {
00480 strcpy(buf, "sctp:");
00481 } else {
00482 strcpy(buf, "udp:");
00483 }
00484 return 0;
00485 }
00486
00487 static inline str* siptrace_get_table(void)
00488 {
00489 static int_str avp_value;
00490 struct usr_avp *avp;
00491
00492 if(trace_table_avp.n==0)
00493 return &siptrace_table;
00494
00495 avp = NULL;
00496 if(trace_table_avp.n!=0)
00497 avp=search_first_avp(trace_table_avp_type, trace_table_avp, &avp_value,
00498 0);
00499
00500 if(avp==NULL || !is_avp_str_val(avp) || avp_value.s.len<=0)
00501 return &siptrace_table;
00502
00503 return &avp_value.s;
00504 }
00505
00506 static int sip_trace_prepare(sip_msg_t *msg)
00507 {
00508 if(parse_from_header(msg)==-1 || msg->from==NULL || get_from(msg)==NULL) {
00509 LM_ERR("cannot parse FROM header\n");
00510 goto error;
00511 }
00512
00513 if(parse_headers(msg, HDR_CALLID_F, 0)!=0 || msg->callid==NULL
00514 || msg->callid->body.s==NULL) {
00515 LM_ERR("cannot parse call-id\n");
00516 goto error;
00517 }
00518
00519 return 0;
00520 error:
00521 return -1;
00522 }
00523
00524
00525 static int sip_trace_xheaders_write(struct _siptrace_data *sto)
00526 {
00527 char* buf = NULL;
00528 int bytes_written = 0;
00529 char* eoh = NULL;
00530 int eoh_offset = 0;
00531 char* new_eoh = NULL;
00532
00533 if(xheaders_write_flag==NULL || *xheaders_write_flag==0)
00534 return 0;
00535
00536
00537
00538 buf = pkg_malloc(sto->body.len + XHEADERS_BUFSIZE);
00539 if (buf == NULL) {
00540 LM_ERR("sip_trace_xheaders_write: out of memory\n");
00541 return -1;
00542 }
00543
00544
00545
00546 memcpy(buf, sto->body.s, sto->body.len);
00547 buf[sto->body.len] = '\0';
00548 eoh = strstr(buf, "\r\n\r\n");
00549 if (eoh == NULL) {
00550 LM_ERR("sip_trace_xheaders_write: malformed message\n");
00551 goto error;
00552 }
00553 eoh += 2;
00554
00555
00556
00557
00558 bytes_written = snprintf(eoh, XHEADERS_BUFSIZE,
00559 "X-Siptrace-Fromip: %.*s\r\n"
00560 "X-Siptrace-Toip: %.*s\r\n"
00561 "X-Siptrace-Time: %llu %llu\r\n"
00562 "X-Siptrace-Method: %.*s\r\n"
00563 "X-Siptrace-Dir: %s\r\n",
00564 sto->fromip.len, sto->fromip.s,
00565 sto->toip.len, sto->toip.s,
00566 (unsigned long long)sto->tv.tv_sec, (unsigned long long)sto->tv.tv_usec,
00567 sto->method.len, sto->method.s,
00568 sto->dir);
00569 if (bytes_written >= XHEADERS_BUFSIZE) {
00570 LM_ERR("sip_trace_xheaders_write: string too long\n");
00571 goto error;
00572 }
00573
00574
00575
00576 eoh_offset = eoh - buf;
00577 new_eoh = eoh + bytes_written;
00578 memcpy(new_eoh, sto->body.s + eoh_offset, sto->body.len - eoh_offset);
00579
00580
00581 sto->body.s = buf;
00582 sto->body.len += bytes_written;
00583 return 0;
00584 error:
00585 if(buf != NULL)
00586 pkg_free(buf);
00587 return -1;
00588 }
00589
00590
00591
00592 static int sip_trace_xheaders_read(struct _siptrace_data *sto)
00593 {
00594 char* searchend = NULL;
00595 char* eoh = NULL;
00596 char* xheaders = NULL;
00597 long long unsigned int tv_sec, tv_usec;
00598
00599 if(xheaders_read_flag==NULL || *xheaders_read_flag==0)
00600 return 0;
00601
00602
00603 searchend = sto->body.s + sto->body.len - 3;
00604 eoh = memchr(sto->body.s, '\r', searchend - eoh);
00605 while (eoh != NULL && eoh < searchend) {
00606 if (memcmp(eoh, "\r\n\r\n", 4) == 0)
00607 break;
00608 eoh = memchr(eoh + 1, '\r', searchend - eoh);
00609 }
00610 if (eoh == NULL) {
00611 LM_ERR("sip_trace_xheaders_read: malformed message\n");
00612 return -1;
00613 }
00614
00615
00616
00617
00618
00619 *eoh = '\0';
00620 xheaders = strstr(sto->body.s, "\r\nX-Siptrace-Fromip: ");
00621 if (xheaders == NULL) {
00622 LM_ERR("sip_trace_xheaders_read: message without x-headers "
00623 "from %.*s, callid %.*s\n",
00624 sto->fromip.len, sto->fromip.s, sto->callid.len, sto->callid.s);
00625 return -1;
00626 }
00627
00628
00629
00630 sto->fromip.s = pkg_malloc(51);
00631 sto->toip.s = pkg_malloc(51);
00632 sto->method.s = pkg_malloc(51);
00633 sto->dir = pkg_malloc(4);
00634 if (!(sto->fromip.s && sto->toip.s && sto->method.s && sto->dir)) {
00635 LM_ERR("sip_trace_xheaders_read: out of memory\n");
00636 goto erroraftermalloc;
00637 }
00638
00639
00640 if (sscanf(xheaders, "\r\n"
00641 "X-Siptrace-Fromip: %50s\r\n"
00642 "X-Siptrace-Toip: %50s\r\n"
00643 "X-Siptrace-Time: %llu %llu\r\n"
00644 "X-Siptrace-Method: %50s\r\n"
00645 "X-Siptrace-Dir: %3s",
00646 sto->fromip.s, sto->toip.s,
00647 &tv_sec, &tv_usec,
00648 sto->method.s,
00649 sto->dir) == EOF) {
00650 LM_ERR("sip_trace_xheaders_read: malformed x-headers\n");
00651 goto erroraftermalloc;
00652 }
00653 sto->fromip.len = strlen(sto->fromip.s);
00654 sto->toip.len = strlen(sto->toip.s);
00655 sto->tv.tv_sec = (time_t)tv_sec;
00656 sto->tv.tv_usec = (suseconds_t)tv_usec;
00657 sto->method.len = strlen(sto->method.s);
00658
00659
00660
00661
00662 *eoh = '\r';
00663 memmove(xheaders, eoh, sto->body.len - (eoh - sto->body.s));
00664 sto->body.len -= eoh - xheaders;
00665
00666 return 0;
00667
00668 erroraftermalloc:
00669 if (sto->fromip.s)
00670 pkg_free(sto->fromip.s);
00671 if (sto->toip.s)
00672 pkg_free(sto->toip.s);
00673 if (sto->method.s)
00674 pkg_free(sto->method.s);
00675 if (sto->dir)
00676 pkg_free(sto->dir);
00677 return -1;
00678 }
00679
00680
00681 static int sip_trace_xheaders_free(struct _siptrace_data *sto)
00682 {
00683 if (xheaders_write_flag != NULL && *xheaders_write_flag != 0) {
00684 if(sto->body.s)
00685 pkg_free(sto->body.s);
00686 }
00687
00688 if (xheaders_read_flag != NULL && *xheaders_read_flag != 0) {
00689 if(sto->fromip.s)
00690 pkg_free(sto->fromip.s);
00691 if(sto->toip.s)
00692 pkg_free(sto->toip.s);
00693 if(sto->dir)
00694 pkg_free(sto->dir);
00695 }
00696
00697 return 0;
00698 }
00699
00700 static int sip_trace_store(struct _siptrace_data *sto)
00701 {
00702 if(sto==NULL)
00703 {
00704 LM_DBG("invalid parameter\n");
00705 return -1;
00706 }
00707
00708 gettimeofday(&sto->tv, NULL);
00709
00710 if (sip_trace_xheaders_read(sto) != 0)
00711 return -1;
00712 int ret = sip_trace_store_db(sto);
00713
00714 if (sip_trace_xheaders_write(sto) != 0)
00715 return -1;
00716
00717 if(hep_mode_on) trace_send_hep_duplicate(&sto->body, &sto->fromip, &sto->toip);
00718 else trace_send_duplicate(sto->body.s, sto->body.len);
00719
00720 if (sip_trace_xheaders_free(sto) != 0)
00721 return -1;
00722
00723 return ret;
00724 }
00725
00726 static int sip_trace_store_db(struct _siptrace_data *sto)
00727 {
00728 if(trace_to_database_flag==NULL || *trace_to_database_flag==0)
00729 goto done;
00730
00731 db_key_t db_keys[NR_KEYS];
00732 db_val_t db_vals[NR_KEYS];
00733
00734 db_keys[0] = &msg_column;
00735 db_vals[0].type = DB1_BLOB;
00736 db_vals[0].nul = 0;
00737 db_vals[0].val.blob_val = sto->body;
00738
00739 db_keys[1] = &callid_column;
00740 db_vals[1].type = DB1_STR;
00741 db_vals[1].nul = 0;
00742 db_vals[1].val.str_val = sto->callid;
00743
00744 db_keys[2] = &method_column;
00745 db_vals[2].type = DB1_STR;
00746 db_vals[2].nul = 0;
00747 db_vals[2].val.str_val = sto->method;
00748
00749 db_keys[3] = &status_column;
00750 db_vals[3].type = DB1_STR;
00751 db_vals[3].nul = 0;
00752 db_vals[3].val.str_val = sto->status;
00753
00754 db_keys[4] = &fromip_column;
00755 db_vals[4].type = DB1_STR;
00756 db_vals[4].nul = 0;
00757 db_vals[4].val.str_val = sto->fromip;
00758
00759 db_keys[5] = &toip_column;
00760 db_vals[5].type = DB1_STR;
00761 db_vals[5].nul = 0;
00762 db_vals[5].val.str_val = sto->toip;
00763
00764 db_keys[6] = &date_column;
00765 db_vals[6].type = DB1_DATETIME;
00766 db_vals[6].nul = 0;
00767 db_vals[6].val.time_val = sto->tv.tv_sec;
00768
00769 db_keys[7] = &direction_column;
00770 db_vals[7].type = DB1_STRING;
00771 db_vals[7].nul = 0;
00772 db_vals[7].val.string_val = sto->dir;
00773
00774 db_keys[8] = &fromtag_column;
00775 db_vals[8].type = DB1_STR;
00776 db_vals[8].nul = 0;
00777 db_vals[8].val.str_val = sto->fromtag;
00778
00779 db_keys[9] = &traced_user_column;
00780 db_vals[9].type = DB1_STR;
00781 db_vals[9].nul = 0;
00782
00783 db_keys[10] = &time_us_column;
00784 db_vals[10].type = DB1_INT;
00785 db_vals[10].nul = 0;
00786 db_vals[10].val.int_val = sto->tv.tv_usec;
00787
00788 db_funcs.use_table(db_con, siptrace_get_table());
00789
00790 if(trace_on_flag!=NULL && *trace_on_flag!=0) {
00791 db_vals[9].val.str_val.s = "";
00792 db_vals[9].val.str_val.len = 0;
00793
00794 LM_DBG("storing info...\n");
00795 if(trace_delayed!=0 && db_funcs.insert_delayed!=NULL)
00796 {
00797 if(db_funcs.insert_delayed(db_con, db_keys, db_vals, NR_KEYS)<0) {
00798 LM_ERR("error storing trace\n");
00799 goto error;
00800 }
00801 } else {
00802 if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0) {
00803 LM_ERR("error storing trace\n");
00804 goto error;
00805 }
00806 }
00807 #ifdef STATISTICS
00808 update_stat(sto->stat, 1);
00809 #endif
00810 }
00811
00812 if(sto->avp==NULL)
00813 goto done;
00814
00815 db_vals[9].val.str_val = sto->avp_value.s;
00816
00817 LM_DBG("storing info...\n");
00818 if(trace_delayed!=0 && db_funcs.insert_delayed!=NULL)
00819 {
00820 if(db_funcs.insert_delayed(db_con, db_keys, db_vals, NR_KEYS) < 0) {
00821 LM_ERR("error storing trace\n");
00822 goto error;
00823 }
00824 } else {
00825 if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0) {
00826 LM_ERR("error storing trace\n");
00827 goto error;
00828 }
00829 }
00830
00831 sto->avp = search_next_avp(&sto->state, &sto->avp_value);
00832 while(sto->avp!=NULL) {
00833 db_vals[9].val.str_val = sto->avp_value.s;
00834
00835 LM_DBG("storing info...\n");
00836 if(trace_delayed!=0 && db_funcs.insert_delayed!=NULL)
00837 {
00838 if(db_funcs.insert_delayed(db_con, db_keys, db_vals, NR_KEYS) < 0) {
00839 LM_ERR("error storing trace\n");
00840 goto error;
00841 }
00842 } else {
00843 if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0) {
00844 LM_ERR("error storing trace\n");
00845 goto error;
00846 }
00847 }
00848 sto->avp = search_next_avp(&sto->state, &sto->avp_value);
00849 }
00850
00851 done:
00852 return 1;
00853 error:
00854 return -1;
00855 }
00856
00857 static int sip_trace(struct sip_msg *msg, char *dir, char *s2)
00858 {
00859 struct _siptrace_data sto;
00860 struct onsend_info *snd_inf = NULL;
00861
00862 if(msg==NULL) {
00863 LM_DBG("nothing to trace\n");
00864 return -1;
00865 }
00866 memset(&sto, 0, sizeof(struct _siptrace_data));
00867
00868 if(traced_user_avp.n!=0)
00869 sto.avp=search_first_avp(traced_user_avp_type, traced_user_avp,
00870 &sto.avp_value, &sto.state);
00871
00872 if((sto.avp==NULL) && (trace_on_flag==NULL || *trace_on_flag==0)) {
00873 LM_DBG("trace off...\n");
00874 return -1;
00875 }
00876 if(sip_trace_prepare(msg)<0)
00877 return -1;
00878
00879 sto.callid = msg->callid->body;
00880
00881 if(msg->first_line.type==SIP_REQUEST) {
00882 sto.method = msg->first_line.u.request.method;
00883 } else {
00884 if(parse_headers(msg, HDR_CSEQ_F, 0) != 0 || msg->cseq==NULL
00885 || msg->cseq->parsed==NULL) {
00886 LM_ERR("cannot parse cseq header\n");
00887 return -1;
00888 }
00889 sto.method = get_cseq(msg)->method;
00890 }
00891
00892 if(msg->first_line.type==SIP_REPLY) {
00893 sto.status = msg->first_line.u.reply.status;
00894 } else {
00895 sto.status.s = "";
00896 sto.status.len = 0;
00897 }
00898
00899 snd_inf=get_onsend_info();
00900 if(snd_inf==NULL) {
00901 sto.body.s = msg->buf;
00902 sto.body.len = msg->len;
00903
00904 siptrace_copy_proto(msg->rcv.proto, sto.fromip_buff);
00905 strcat(sto.fromip_buff, ip_addr2a(&msg->rcv.src_ip));
00906 strcat(sto.fromip_buff,":");
00907 strcat(sto.fromip_buff, int2str(msg->rcv.src_port, NULL));
00908 sto.fromip.s = sto.fromip_buff;
00909 sto.fromip.len = strlen(sto.fromip_buff);
00910
00911 siptrace_copy_proto(msg->rcv.proto, sto.toip_buff);
00912 strcat(sto.toip_buff, ip_addr2a(&msg->rcv.dst_ip));
00913 strcat(sto.toip_buff,":");
00914 strcat(sto.toip_buff, int2str(msg->rcv.dst_port, NULL));
00915 sto.toip.s = sto.toip_buff;
00916 sto.toip.len = strlen(sto.toip_buff);
00917
00918 sto.dir = (dir)?dir:"in";
00919 } else {
00920 sto.body.s = snd_inf->buf;
00921 sto.body.len = snd_inf->len;
00922
00923 strncpy(sto.fromip_buff, snd_inf->send_sock->sock_str.s,
00924 snd_inf->send_sock->sock_str.len);
00925 sto.fromip.s = sto.fromip_buff;
00926 sto.fromip.len = strlen(sto.fromip_buff);
00927
00928 siptrace_copy_proto(snd_inf->send_sock->proto, sto.toip_buff);
00929 strcat(sto.toip_buff, suip2a(snd_inf->to, sizeof(*snd_inf->to)));
00930 strcat(sto.toip_buff,":");
00931 strcat(sto.toip_buff, int2str((int)su_getport(snd_inf->to), NULL));
00932 sto.toip.s = sto.toip_buff;
00933 sto.toip.len = strlen(sto.toip_buff);
00934
00935 sto.dir = "out";
00936 }
00937
00938 sto.fromtag = get_from(msg)->tag_value;
00939
00940 #ifdef STATISTICS
00941 if(msg->first_line.type==SIP_REPLY) {
00942 sto.stat = siptrace_rpl;
00943 } else {
00944 sto.stat = siptrace_req;
00945 }
00946 #endif
00947 return sip_trace_store(&sto);
00948 }
00949
00950 #define trace_is_off(_msg) \
00951 (trace_on_flag==NULL || *trace_on_flag==0 || \
00952 ((_msg)->flags&trace_flag)==0)
00953
00954 static void trace_onreq_in(struct cell* t, int type, struct tmcb_params *ps)
00955 {
00956 struct sip_msg* msg;
00957 int_str avp_value;
00958 struct usr_avp* avp;
00959
00960 if(t==NULL || ps==NULL)
00961 {
00962 LM_DBG("no uas request, local transaction\n");
00963 return;
00964 }
00965
00966 msg = ps->req;
00967 if(msg==NULL)
00968 {
00969 LM_DBG("no uas request, local transaction\n");
00970 return;
00971 }
00972
00973 avp = NULL;
00974 if(traced_user_avp.n!=0)
00975 avp=search_first_avp(traced_user_avp_type, traced_user_avp, &avp_value,
00976 0);
00977
00978 if((avp==NULL) && trace_is_off(msg))
00979 {
00980 LM_DBG("trace off...\n");
00981 return;
00982 }
00983
00984 if(parse_from_header(msg)==-1 || msg->from==NULL || get_from(msg)==NULL)
00985 {
00986 LM_ERR("cannot parse FROM header\n");
00987 return;
00988 }
00989
00990 if(parse_headers(msg, HDR_CALLID_F, 0)!=0)
00991 {
00992 LM_ERR("cannot parse call-id\n");
00993 return;
00994 }
00995
00996 if(tmb.register_tmcb(0, t, TMCB_REQUEST_SENT, trace_onreq_out, 0, 0) <=0)
00997 {
00998 LM_ERR("can't register trace_onreq_out\n");
00999 return;
01000 }
01001 if(tmb.register_tmcb(0, t, TMCB_RESPONSE_IN, trace_onreply_in, 0, 0) <=0)
01002 {
01003 LM_ERR("can't register trace_onreply_in\n");
01004 return;
01005 }
01006
01007 if(tmb.register_tmcb(0, t, TMCB_RESPONSE_SENT, trace_onreply_out, 0, 0)<=0)
01008 {
01009 LM_ERR("can't register trace_onreply_out\n");
01010 return;
01011 }
01012 }
01013
01014 static void trace_onreq_out(struct cell* t, int type, struct tmcb_params *ps)
01015 {
01016 struct _siptrace_data sto;
01017 sip_msg_t *msg;
01018 struct ip_addr to_ip;
01019 int len;
01020 struct dest_info *dst;
01021
01022 if(t==NULL || ps==NULL) {
01023 LM_DBG("very weird\n");
01024 return;
01025 }
01026
01027 if(ps->flags&TMCB_RETR_F) {
01028 LM_DBG("retransmission\n");
01029 return;
01030 }
01031 msg=ps->req;
01032 if(msg==NULL) {
01033
01034
01035 if(is_invite(t) && ps->send_buf.len>7
01036 && strncmp(ps->send_buf.s, "CANCEL ", 7)==0) {
01037 msg = t->uas.request;
01038 if(msg==NULL) {
01039 LM_DBG("no uas msg for INVITE transaction\n");
01040 return;
01041 } else {
01042 LM_DBG("recording CANCEL based on INVITE transaction\n");
01043 }
01044 } else {
01045 LM_DBG("no uas msg, local transaction\n");
01046 return;
01047 }
01048 }
01049 memset(&sto, 0, sizeof(struct _siptrace_data));
01050
01051 if(traced_user_avp.n!=0)
01052 sto.avp=search_first_avp(traced_user_avp_type, traced_user_avp,
01053 &sto.avp_value, &sto.state);
01054
01055 if((sto.avp==NULL) && trace_is_off(msg) ) {
01056 LM_DBG("trace off...\n");
01057 return;
01058 }
01059
01060 if(sip_trace_prepare(msg)<0)
01061 return;
01062
01063 if(ps->send_buf.len>0) {
01064 sto.body = ps->send_buf;
01065 } else {
01066 sto.body.s = "No request buffer";
01067 sto.body.len = sizeof("No request buffer")-1;
01068 }
01069
01070 sto.callid = msg->callid->body;
01071
01072 if(ps->send_buf.len>10) {
01073 sto.method.s = ps->send_buf.s;
01074 sto.method.len = 0;
01075 while(sto.method.len<ps->send_buf.len) {
01076 if(ps->send_buf.s[sto.method.len]==' ')
01077 break;
01078 sto.method.len++;
01079 }
01080 if(sto.method.len==ps->send_buf.len)
01081 sto.method.len = 10;
01082 } else {
01083 sto.method = t->method;
01084 }
01085
01086 sto.status.s = "";
01087 sto.status.len = 0;
01088
01089 memset(&to_ip, 0, sizeof(struct ip_addr));
01090 dst = ps->dst;
01091
01092 if (trace_local_ip.s && trace_local_ip.len > 0) {
01093 sto.fromip = trace_local_ip;
01094 } else {
01095 if(dst==0 || dst->send_sock==0 || dst->send_sock->sock_str.s==0) {
01096 siptrace_copy_proto(msg->rcv.proto, sto.fromip_buff);
01097 strcat(sto.fromip_buff, ip_addr2a(&msg->rcv.dst_ip));
01098 strcat(sto.fromip_buff,":");
01099 strcat(sto.fromip_buff, int2str(msg->rcv.dst_port, NULL));
01100 sto.fromip.s = sto.fromip_buff;
01101 sto.fromip.len = strlen(sto.fromip_buff);
01102 } else {
01103 sto.fromip = dst->send_sock->sock_str;
01104 }
01105 }
01106
01107 if(dst==0) {
01108 sto.toip.s = "any:255.255.255.255";
01109 sto.toip.len = 19;
01110 } else {
01111 su2ip_addr(&to_ip, &dst->to);
01112 siptrace_copy_proto(dst->proto, sto.toip_buff);
01113 strcat(sto.toip_buff, ip_addr2a(&to_ip));
01114 strcat(sto.toip_buff, ":");
01115 strcat(sto.toip_buff,
01116 int2str((unsigned long)su_getport(&dst->to), &len));
01117 sto.toip.s = sto.toip_buff;
01118 sto.toip.len = strlen(sto.toip_buff);
01119 }
01120
01121 sto.dir = "out";
01122
01123 sto.fromtag = get_from(msg)->tag_value;
01124
01125 #ifdef STATISTICS
01126 sto.stat = siptrace_req;
01127 #endif
01128
01129 sip_trace_store(&sto);
01130 return;
01131 }
01132
01133 static void trace_onreply_in(struct cell* t, int type, struct tmcb_params *ps)
01134 {
01135 struct _siptrace_data sto;
01136 sip_msg_t *msg;
01137 sip_msg_t *req;
01138 char statusbuf[8];
01139
01140 if(t==NULL || t->uas.request==0 || ps==NULL) {
01141 LM_DBG("no uas request, local transaction\n");
01142 return;
01143 }
01144
01145 req = ps->req;
01146 msg = ps->rpl;
01147 if(msg==NULL || req==NULL) {
01148 LM_DBG("no reply\n");
01149 return;
01150 }
01151 memset(&sto, 0, sizeof(struct _siptrace_data));
01152
01153 if(traced_user_avp.n!=0)
01154 sto.avp=search_first_avp(traced_user_avp_type, traced_user_avp,
01155 &sto.avp_value, &sto.state);
01156
01157 if((sto.avp==NULL) && trace_is_off(req)) {
01158 LM_DBG("trace off...\n");
01159 return;
01160 }
01161
01162 if(sip_trace_prepare(msg)<0)
01163 return;
01164
01165 sto.body.s = msg->buf;
01166 sto.body.len = msg->len;
01167
01168 sto.callid = msg->callid->body;
01169
01170 sto.method = t->method;
01171
01172 strcpy(statusbuf, int2str(ps->code, &sto.status.len));
01173 sto.status.s = statusbuf;
01174
01175 siptrace_copy_proto(msg->rcv.proto, sto.fromip_buff);
01176 strcat(sto.fromip_buff, ip_addr2a(&msg->rcv.src_ip));
01177 strcat(sto.fromip_buff,":");
01178 strcat(sto.fromip_buff, int2str(msg->rcv.src_port, NULL));
01179 sto.fromip.s = sto.fromip_buff;
01180 sto.fromip.len = strlen(sto.fromip_buff);
01181
01182 if(trace_local_ip.s && trace_local_ip.len > 0) {
01183 sto.toip = trace_local_ip;
01184 } else {
01185 siptrace_copy_proto(msg->rcv.proto, sto.toip_buff);
01186 strcat(sto.toip_buff, ip_addr2a(&msg->rcv.dst_ip));
01187 strcat(sto.toip_buff,":");
01188 strcat(sto.toip_buff, int2str(msg->rcv.dst_port, NULL));
01189 sto.toip.s = sto.toip_buff;
01190 sto.toip.len = strlen(sto.toip_buff);
01191 }
01192
01193 sto.dir = "in";
01194
01195 sto.fromtag = get_from(msg)->tag_value;
01196 #ifdef STATISTICS
01197 sto.stat = siptrace_rpl;
01198 #endif
01199
01200 sip_trace_store(&sto);
01201 return;
01202 }
01203
01204 static void trace_onreply_out(struct cell* t, int type, struct tmcb_params *ps)
01205 {
01206 struct _siptrace_data sto;
01207 int faked = 0;
01208 struct sip_msg* msg;
01209 struct sip_msg* req;
01210 struct ip_addr to_ip;
01211 int len;
01212 char statusbuf[8];
01213 struct dest_info *dst;
01214
01215 if (t==NULL || t->uas.request==0 || ps==NULL) {
01216 LM_DBG("no uas request, local transaction\n");
01217 return;
01218 }
01219
01220 if(ps->flags&TMCB_RETR_F) {
01221 LM_DBG("retransmission\n");
01222 return;
01223 }
01224 memset(&sto, 0, sizeof(struct _siptrace_data));
01225 if(traced_user_avp.n!=0)
01226 sto.avp=search_first_avp(traced_user_avp_type, traced_user_avp,
01227 &sto.avp_value, &sto.state);
01228
01229 if((sto.avp==NULL) && trace_is_off(t->uas.request)) {
01230 LM_DBG("trace off...\n");
01231 return;
01232 }
01233
01234 req = ps->req;
01235 msg = ps->rpl;
01236 if(msg==NULL || msg==FAKED_REPLY) {
01237 msg = t->uas.request;
01238 faked = 1;
01239 }
01240
01241 if(sip_trace_prepare(msg)<0)
01242 return;
01243
01244 if(faked==0) {
01245 if(ps->send_buf.len>0) {
01246 sto.body = ps->send_buf;
01247 } else if(t->uas.response.buffer!=NULL) {
01248 sto.body.s = t->uas.response.buffer;
01249 sto.body.len = t->uas.response.buffer_len;
01250 } else if(msg->len>0) {
01251 sto.body.s = msg->buf;
01252 sto.body.len = msg->len;
01253 } else {
01254 sto.body.s = "No reply buffer";
01255 sto.body.len = sizeof("No reply buffer")-1;
01256 }
01257 } else {
01258 if(ps->send_buf.len>0) {
01259 sto.body = ps->send_buf;
01260 } else if(t->uas.response.buffer!=NULL) {
01261 sto.body.s = t->uas.response.buffer;
01262 sto.body.len = t->uas.response.buffer_len;
01263 } else {
01264 sto.body.s = "No reply buffer";
01265 sto.body.len = sizeof("No reply buffer")-1;
01266 }
01267 }
01268
01269 sto.callid = msg->callid->body;
01270 sto.method = t->method;
01271
01272 if(trace_local_ip.s && trace_local_ip.len > 0) {
01273 sto.fromip = trace_local_ip;
01274 } else {
01275 siptrace_copy_proto(msg->rcv.proto, sto.fromip_buff);
01276 strcat(sto.fromip_buff, ip_addr2a(&req->rcv.dst_ip));
01277 strcat(sto.fromip_buff,":");
01278 strcat(sto.fromip_buff, int2str(req->rcv.dst_port, NULL));
01279 sto.fromip.s = sto.fromip_buff;
01280 sto.fromip.len = strlen(sto.fromip_buff);
01281 }
01282
01283 strcpy(statusbuf, int2str(ps->code, &sto.status.len));
01284 sto.status.s = statusbuf;
01285
01286 memset(&to_ip, 0, sizeof(struct ip_addr));
01287 dst = ps->dst;
01288 if(dst==0) {
01289 sto.toip.s = "any:255.255.255.255";
01290 sto.toip.len = 19;
01291 } else {
01292 su2ip_addr(&to_ip, &dst->to);
01293 siptrace_copy_proto(dst->proto, sto.toip_buff);
01294 strcat(sto.toip_buff, ip_addr2a(&to_ip));
01295 strcat(sto.toip_buff, ":");
01296 strcat(sto.toip_buff,
01297 int2str((unsigned long)su_getport(&dst->to), &len));
01298 sto.toip.s = sto.toip_buff;
01299 sto.toip.len = strlen(sto.toip_buff);
01300 }
01301
01302 sto.dir = "out";
01303 sto.fromtag = get_from(msg)->tag_value;
01304
01305 #ifdef STATISTICS
01306 sto.stat = siptrace_rpl;
01307 #endif
01308
01309 sip_trace_store(&sto);
01310 return;
01311 }
01312
01313 static void trace_sl_ack_in(sl_cbp_t *slcbp)
01314 {
01315 sip_msg_t *req;
01316 LM_DBG("storing ack...\n");
01317 req = slcbp->req;
01318 sip_trace(req, 0, 0);
01319 }
01320
01321 static void trace_sl_onreply_out(sl_cbp_t *slcbp)
01322 {
01323 sip_msg_t *req;
01324 struct _siptrace_data sto;
01325 struct sip_msg* msg;
01326 struct ip_addr to_ip;
01327 int len;
01328 char statusbuf[5];
01329
01330 if(slcbp==NULL || slcbp->req==NULL)
01331 {
01332 LM_ERR("bad parameters\n");
01333 return;
01334 }
01335 req = slcbp->req;
01336
01337 memset(&sto, 0, sizeof(struct _siptrace_data));
01338 if(traced_user_avp.n!=0)
01339 sto.avp=search_first_avp(traced_user_avp_type, traced_user_avp,
01340 &sto.avp_value, &sto.state);
01341
01342 if((sto.avp==NULL) && trace_is_off(req)) {
01343 LM_DBG("trace off...\n");
01344 return;
01345 }
01346
01347 msg = req;
01348
01349 if(sip_trace_prepare(msg)<0)
01350 return;
01351
01352 sto.body.s = (slcbp->reply)?slcbp->reply->s:"";
01353 sto.body.len = (slcbp->reply)?slcbp->reply->len:0;
01354
01355 sto.callid = msg->callid->body;
01356 sto.method = msg->first_line.u.request.method;
01357
01358 if(trace_local_ip.len > 0) {
01359 sto.fromip = trace_local_ip;
01360 } else {
01361 siptrace_copy_proto(msg->rcv.proto, sto.fromip_buff);
01362 strcat(sto.fromip_buff, ip_addr2a(&req->rcv.dst_ip));
01363 strcat(sto.fromip_buff,":");
01364 strcat(sto.fromip_buff, int2str(req->rcv.dst_port, NULL));
01365 sto.fromip.s = sto.fromip_buff;
01366 sto.fromip.len = strlen(sto.fromip_buff);
01367 }
01368
01369 strcpy(statusbuf, int2str(slcbp->code, &sto.status.len));
01370 sto.status.s = statusbuf;
01371
01372 memset(&to_ip, 0, sizeof(struct ip_addr));
01373 if(slcbp->dst==0)
01374 {
01375 sto.toip.s = "any:255.255.255.255";
01376 sto.toip.len = 19;
01377 } else {
01378 su2ip_addr(&to_ip, &slcbp->dst->to);
01379 siptrace_copy_proto(req->rcv.proto, sto.toip_buff);
01380 strcat(sto.toip_buff, ip_addr2a(&to_ip));
01381 strcat(sto.toip_buff, ":");
01382 strcat(sto.toip_buff,
01383 int2str((unsigned long)su_getport(&slcbp->dst->to), &len));
01384 sto.toip.s = sto.toip_buff;
01385 sto.toip.len = strlen(sto.toip_buff);
01386 }
01387
01388 sto.dir = "out";
01389 sto.fromtag = get_from(msg)->tag_value;
01390
01391 #ifdef STATISTICS
01392 sto.stat = siptrace_rpl;
01393 #endif
01394
01395 sip_trace_store(&sto);
01396 return;
01397 }
01398
01399
01407 static struct mi_root* sip_trace_mi(struct mi_root* cmd_tree, void* param )
01408 {
01409 struct mi_node* node;
01410
01411 struct mi_node *rpl;
01412 struct mi_root *rpl_tree ;
01413
01414 node = cmd_tree->node.kids;
01415 if(node == NULL) {
01416 rpl_tree = init_mi_tree( 200, MI_SSTR(MI_OK));
01417 if (rpl_tree == 0)
01418 return 0;
01419 rpl = &rpl_tree->node;
01420
01421 if (*trace_on_flag == 0 ) {
01422 node = add_mi_node_child(rpl,0,0,0,MI_SSTR("off"));
01423 } else if (*trace_on_flag == 1) {
01424 node = add_mi_node_child(rpl,0,0,0,MI_SSTR("on"));
01425 }
01426 return rpl_tree ;
01427 }
01428 if(trace_on_flag==NULL)
01429 return init_mi_tree( 500, MI_SSTR(MI_INTERNAL_ERR));
01430
01431 if ( node->value.len==2 && (node->value.s[0]=='o'
01432 || node->value.s[0]=='O') &&
01433 (node->value.s[1]=='n'|| node->value.s[1]=='N')) {
01434 *trace_on_flag = 1;
01435 return init_mi_tree( 200, MI_SSTR(MI_OK));
01436 } else if ( node->value.len==3 && (node->value.s[0]=='o'
01437 || node->value.s[0]=='O')
01438 && (node->value.s[1]=='f'|| node->value.s[1]=='F')
01439 && (node->value.s[2]=='f'|| node->value.s[2]=='F')) {
01440 *trace_on_flag = 0;
01441 return init_mi_tree( 200, MI_SSTR(MI_OK));
01442 } else {
01443 return init_mi_tree( 400, MI_SSTR(MI_BAD_PARM));
01444 }
01445 }
01446
01447 static int trace_send_duplicate(char *buf, int len)
01448 {
01449 struct dest_info dst;
01450 struct proxy_l * p;
01451
01452 if(buf==NULL || len <= 0)
01453 return -1;
01454
01455 if(dup_uri_str.s==0 || dup_uri==NULL)
01456 return 0;
01457
01458 init_dest_info(&dst);
01459
01460 dst.proto = PROTO_UDP;
01461 p=mk_proxy(&dup_uri->host, (dup_uri->port_no)?dup_uri->port_no:SIP_PORT,
01462 dst.proto);
01463 if (p==0)
01464 {
01465 LM_ERR("bad host name in uri\n");
01466 return -1;
01467 }
01468
01469 hostent2su(&dst.to, &p->host, p->addr_idx, (p->port)?p->port:SIP_PORT);
01470
01471 dst.send_sock=get_send_socket(0, &dst.to, dst.proto);
01472 if (dst.send_sock==0)
01473 {
01474 LM_ERR("can't forward to af %d, proto %d no corresponding"
01475 " listening socket\n", dst.to.s.sa_family, dst.proto);
01476 goto error;
01477 }
01478
01479 if (msg_send(&dst, buf, len)<0)
01480 {
01481 LM_ERR("cannot send duplicate message\n");
01482 goto error;
01483 }
01484
01485 free_proxy(p);
01486 pkg_free(p);
01487 return 0;
01488 error:
01489 free_proxy(p);
01490 pkg_free(p);
01491 return -1;
01492 }
01493
01494 static int trace_send_hep_duplicate(str *body, str *from, str *to)
01495 {
01496 struct dest_info dst;
01497 struct proxy_l * p=NULL ;
01498 void* buffer = NULL;
01499 union sockaddr_union from_su;
01500 union sockaddr_union to_su;
01501 unsigned int len, buflen, proto;
01502 struct hep_hdr hdr;
01503 struct hep_iphdr hep_ipheader;
01504 struct hep_timehdr hep_time;
01505 struct timeval tvb;
01506 struct timezone tz;
01507
01508 #if USE_IPV6
01509 struct hep_ip6hdr hep_ip6header;
01510 #endif
01511
01512 if(body->s==NULL || body->len <= 0)
01513 return -1;
01514
01515 if(dup_uri_str.s==0 || dup_uri==NULL)
01516 return 0;
01517
01518
01519 gettimeofday( &tvb, &tz );
01520
01521
01522
01523 len = body->len
01524 #if USE_IPV6
01525 + sizeof(struct hep_ip6hdr)
01526 #else
01527 + sizeof(struct hep_iphdr)
01528 #endif
01529 + sizeof(struct hep_hdr) + sizeof(struct hep_timehdr);;
01530
01531
01532
01533 if (unlikely(len>BUF_SIZE)){
01534 goto error;
01535 }
01536
01537
01538 if (pipport2su(from->s, &from_su, &proto)==-1 || (pipport2su(to->s, &to_su, &proto)==-1))
01539 goto error;
01540
01541
01542 if(from_su.s.sa_family != to_su.s.sa_family) {
01543 LOG(L_ERR, "ERROR: trace_send_hep_duplicate: interworking detected ?\n");
01544 goto error;
01545 }
01546
01547 init_dest_info(&dst);
01548
01549 dst.proto = PROTO_UDP;
01550 p=mk_proxy(&dup_uri->host, (dup_uri->port_no)?dup_uri->port_no:SIP_PORT,
01551 dst.proto);
01552 if (p==0)
01553 {
01554 LM_ERR("bad host name in uri\n");
01555 goto error;
01556 }
01557
01558 hostent2su(&dst.to, &p->host, p->addr_idx, (p->port)?p->port:SIP_PORT);
01559
01560 dst.send_sock=get_send_socket(0, &dst.to, dst.proto);
01561 if (dst.send_sock==0)
01562 {
01563 LM_ERR("can't forward to af %d, proto %d no corresponding"
01564 " listening socket\n", dst.to.s.sa_family, dst.proto);
01565 goto error;
01566 }
01567
01568
01569 hdr.hp_l = sizeof(struct hep_hdr);
01570 hdr.hp_v = hep_version;
01571 hdr.hp_p = proto;
01572
01573
01574 if (from_su.s.sa_family==AF_INET){
01575
01576
01577 hdr.hp_f = AF_INET;
01578 hdr.hp_sport = htons(from_su.sin.sin_port);
01579 hdr.hp_dport = htons(to_su.sin.sin_port);
01580
01581 hep_ipheader.hp_src = from_su.sin.sin_addr;
01582 hep_ipheader.hp_dst = to_su.sin.sin_addr;
01583
01584 len = sizeof(struct hep_iphdr);
01585 }
01586 #ifdef USE_IPV6
01587 else if (from_su.s.sa_family==AF_INET6){
01588
01589
01590 hdr.hp_f = AF_INET6;
01591
01592 hdr.hp_sport = htons(from_su.sin6.sin6_port);
01593 hdr.hp_dport = htons(to_su.sin6.sin6_port);
01594
01595 hep_ip6header.hp6_src = from_su.sin6.sin6_addr;
01596 hep_ip6header.hp6_dst = to_su.sin6.sin6_addr;
01597
01598 len = sizeof(struct hep_ip6hdr);
01599 }
01600 #endif
01601 else {
01602 LOG(L_ERR, "ERROR: trace_send_hep_duplicate: Unsupported protocol family\n");
01603 goto error;;
01604 }
01605
01606 hdr.hp_l +=len;
01607 len += sizeof(struct hep_hdr) + body->len;
01608 buffer = (void *)pkg_malloc(len+1);
01609 if (buffer==0){
01610 LOG(L_ERR, "ERROR: trace_send_hep_duplicate: out of memory\n");
01611 goto error;
01612 }
01613
01614
01615 memset(buffer, '\0', len+1);
01616
01617
01618 memcpy((void*)buffer, &hdr, sizeof(struct hep_hdr));
01619 buflen = sizeof(struct hep_hdr);
01620
01621
01622 if(from_su.s.sa_family==AF_INET) {
01623 memcpy((void*)buffer + buflen, &hep_ipheader, sizeof(struct hep_iphdr));
01624 buflen += sizeof(struct hep_iphdr);
01625 }
01626 #if USE_IPV6
01627 else {
01628 memcpy((void*)buffer+buflen, &hep_ip6header, sizeof(struct hep_ip6hdr));
01629 buflen += sizeof(struct hep_ip6hdr);
01630 }
01631 #endif
01632
01633 if(hep_version == 2) {
01634
01635 hep_time.tv_sec = tvb.tv_sec;
01636 hep_time.tv_usec = tvb.tv_usec;
01637 hep_time.captid = hep_capture_id;
01638
01639 memcpy((void*)buffer+buflen, &hep_time, sizeof(struct hep_timehdr));
01640 buflen += sizeof(struct hep_timehdr);
01641 }
01642
01643
01644 memcpy((void*)(buffer + buflen) , (void*)body->s, body->len);
01645 buflen +=body->len;
01646
01647 if (msg_send(&dst, buffer, buflen)<0)
01648 {
01649 LM_ERR("cannot send hep duplicate message\n");
01650 goto error;
01651 }
01652
01653 free_proxy(p);
01654 pkg_free(p);
01655 pkg_free(buffer);
01656 return 0;
01657 error:
01658 if(p)
01659 {
01660 free_proxy(p);
01661 pkg_free(p);
01662 }
01663 if(buffer) pkg_free(buffer);
01664 return -1;
01665 }
01666
01675 static int pipport2su (char *pipport, union sockaddr_union *tmp_su, unsigned int *proto)
01676 {
01677 unsigned int port_no, cutlen = 4;
01678 struct ip_addr *ip;
01679 char *p, *host_s;
01680 str port_str, host_uri;
01681 unsigned len = 0;
01682 char tmp_piport[256];
01683
01684
01685 if(strncmp(pipport, "udp:",4) == 0) *proto = IPPROTO_UDP;
01686 else if(strncmp(pipport, "tcp:",4) == 0) *proto = IPPROTO_TCP;
01687 else if(strncmp(pipport, "tls:",4) == 0) *proto = IPPROTO_IDP;
01688 #ifdef USE_SCTP
01689 else if(strncmp(pipport, "sctp:",5) == 0) cutlen = 5, *proto = IPPROTO_SCTP;
01690 #endif
01691 else if(strncmp(pipport, "any:",4) == 0) *proto = IPPROTO_UDP;
01692 else {
01693 LM_ERR("bad protocol %s\n", pipport);
01694 return -1;
01695 }
01696
01697 if((len = strlen(pipport)) >= 256) {
01698 LM_ERR("too big pipport\n");
01699 goto error;
01700 }
01701
01702
01703 strncpy(tmp_piport, pipport, len+1);
01704
01705 len = 0;
01706
01707
01708 p = tmp_piport+cutlen;
01709 if( (*(p)) == '\0') {
01710 LM_ERR("malformed ip address\n");
01711 goto error;
01712 }
01713 host_s=p;
01714
01715 if( (p = strrchr(p+1, ':')) == 0 ) {
01716 LM_DBG("no port specified\n");
01717 port_no = 0;
01718 }
01719 else {
01720
01721 *p = '\0';
01722 p++;
01723 port_str.s = p;
01724 port_str.len = strlen(p);
01725 LM_DBG("the port string is %s\n", p);
01726 if(str2int(&port_str, &port_no) != 0 ) {
01727 LM_ERR("there is not a valid number port\n");
01728 goto error;
01729 }
01730 *p = '\0';
01731 }
01732
01733
01734 if (host_s[0] == '[') {
01735 len = strlen(host_s + 1) - 1;
01736 if(host_s[len+1] != ']') {
01737 LM_ERR("bracket not closed\n");
01738 goto error;
01739 }
01740 memmove(host_s, host_s + 1, len);
01741 host_s[len] = '\0';
01742 }
01743
01744 host_uri.s = host_s;
01745 host_uri.len = strlen(host_s);
01746
01747
01748 if (((ip=str2ip(&host_uri))!=0)
01749 #ifdef USE_IPV6
01750 || ((ip=str2ip6(&host_uri))!=0)
01751 #endif
01752 ) {
01753 ip_addr2su(tmp_su, ip, ntohs(port_no));
01754 return 0;
01755
01756 }
01757
01758 error:
01759 return -1;
01760 }