Browse code

sipdump: refactored to enable more storage engines

- pass data via structure instead of data printed in text format

Daniel-Constantin Mierla authored on 15/07/2020 06:44:01
Showing 3 changed files
... ...
@@ -47,7 +47,7 @@ int sipdump_rotate = 7200;
47 47
 static int sipdump_wait = 100;
48 48
 static str sipdump_folder = str_init("/tmp");
49 49
 static str sipdump_fprefix = str_init("kamailio-sipdump-");
50
-static int sipdump_mode = SIPDUMP_MODE_WFILE;
50
+int sipdump_mode = SIPDUMP_MODE_WTEXT;
51 51
 static str sipdump_event_callback = STR_NULL;
52 52
 
53 53
 static int sipdump_event_route_idx = -1;
... ...
@@ -112,7 +112,8 @@ struct module_exports exports = {
112 112
  */
113 113
 static int mod_init(void)
114 114
 {
115
-	if(!(sipdump_mode & (SIPDUMP_MODE_WFILE | SIPDUMP_MODE_EVROUTE))) {
115
+	if(!(sipdump_mode & (SIPDUMP_MODE_WTEXT |SIPDUMP_MODE_WPCAP
116
+							| SIPDUMP_MODE_EVROUTE))) {
116 117
 		LM_ERR("invalid mode parameter\n");
117 118
 		return -1;
118 119
 	}
... ...
@@ -143,7 +144,7 @@ static int mod_init(void)
143 144
 		}
144 145
 	}
145 146
 
146
-	if(sipdump_mode & SIPDUMP_MODE_WFILE) {
147
+	if(sipdump_mode & (SIPDUMP_MODE_WTEXT|SIPDUMP_MODE_WPCAP)) {
147 148
 		register_basic_timers(1);
148 149
 	}
149 150
 
... ...
@@ -162,7 +163,7 @@ static int child_init(int rank)
162 163
 	if(rank != PROC_MAIN)
163 164
 		return 0;
164 165
 
165
-	if(!(sipdump_mode & SIPDUMP_MODE_WFILE)) {
166
+	if(!(sipdump_mode & (SIPDUMP_MODE_WTEXT|SIPDUMP_MODE_WPCAP))) {
166 167
 		return 0;
167 168
 	}
168 169
 
... ...
@@ -184,115 +185,59 @@ static void mod_destroy(void)
184 185
 	sipdump_list_destroy();
185 186
 }
186 187
 
187
-#define SIPDUMP_WBUF_SIZE 65536
188
-static char _sipdump_wbuf[SIPDUMP_WBUF_SIZE];
189
-
190
-typedef struct sipdump_info {
191
-	str tag;
192
-	str buf;
193
-	str af;
194
-	str proto;
195
-	str src_ip;
196
-	int src_port;
197
-	str dst_ip;
198
-	int dst_port;
199
-} sipdump_info_t;
200
-
201
-/**
202
- *
203
- */
204
-int sipdump_buffer_write(sipdump_info_t *sdi, str *obuf)
205
-{
206
-	struct timeval tv;
207
-	struct tm ti;
208
-	char t_buf[26] = {0};
209
-
210
-	gettimeofday(&tv, NULL);
211
-	localtime_r(&tv.tv_sec, &ti);
212
-	obuf->len = snprintf(_sipdump_wbuf, SIPDUMP_WBUF_SIZE,
213
-		"====================\n"
214
-		"tag: %.*s\n"
215
-		"pid: %d\n"
216
-		"process: %d\n"
217
-		"time: %lu.%06lu\n"
218
-		"date: %s"
219
-		"proto: %.*s %.*s\n"
220
-		"srcip: %.*s\n"
221
-		"srcport: %d\n"
222
-		"dstip: %.*s\n"
223
-		"dstport: %d\n"
224
-		"~~~~~~~~~~~~~~~~~~~~\n"
225
-		"%.*s"
226
-		"||||||||||||||||||||\n",
227
-		sdi->tag.len, sdi->tag.s,
228
-		my_pid(),
229
-		process_no,
230
-		(unsigned long)tv.tv_sec, (unsigned long)tv.tv_usec,
231
-		asctime_r(&ti, t_buf),
232
-		sdi->proto.len, sdi->proto.s, sdi->af.len, sdi->af.s,
233
-		sdi->src_ip.len, sdi->src_ip.s, sdi->src_port,
234
-		sdi->dst_ip.len, sdi->dst_ip.s, sdi->dst_port,
235
-		sdi->buf.len, sdi->buf.s
236
-	);
237
-	obuf->s = _sipdump_wbuf;
238
-
239
-	return 0;
240
-}
241
-
242 188
 /**
243 189
  *
244 190
  */
245 191
 int ki_sipdump_send(sip_msg_t *msg, str *stag)
246 192
 {
247
-	str wdata;
248
-	sipdump_info_t sdi;
193
+	sipdump_data_t isd;
194
+	sipdump_data_t *osd = NULL;
249 195
 	char srcip_buf[IP_ADDR_MAX_STRZ_SIZE];
250 196
 
251 197
 	if(!sipdump_enabled())
252 198
 		return 1;
253 199
 
254
-	if(!(sipdump_mode & SIPDUMP_MODE_WFILE)) {
200
+	if(!(sipdump_mode & (SIPDUMP_MODE_WTEXT|SIPDUMP_MODE_WPCAP))) {
255 201
 		LM_WARN("writing to file is disabled - ignoring\n");
256 202
 		return 1;
257 203
 	}
258 204
 
259
-	memset(&sdi, 0, sizeof(sipdump_info_t));
205
+	memset(&isd, 0, sizeof(sipdump_data_t));
260 206
 
261
-	sdi.buf.s = msg->buf;
262
-	sdi.buf.len = msg->len;
263
-	sdi.tag = *stag;
264
-	sdi.src_ip.len = ip_addr2sbufz(&msg->rcv.src_ip, srcip_buf,
207
+	gettimeofday(&isd.tv, NULL);
208
+	isd.data.s = msg->buf;
209
+	isd.data.len = msg->len;
210
+	isd.pid = my_pid();
211
+	isd.procno = process_no;
212
+	isd.tag = *stag;
213
+	isd.protoid = msg->rcv.proto;
214
+	isd.afid = msg->rcv.src_ip.af;
215
+	isd.src_ip.len = ip_addr2sbufz(&msg->rcv.src_ip, srcip_buf,
265 216
 			IP_ADDR_MAX_STRZ_SIZE);
266
-	sdi.src_ip.s = srcip_buf;
267
-	sdi.src_port = msg->rcv.src_port;
217
+	isd.src_ip.s = srcip_buf;
218
+	isd.src_port = msg->rcv.src_port;
268 219
 	if(msg->rcv.bind_address==NULL
269 220
 			|| msg->rcv.bind_address->address_str.s==NULL) {
270
-		sdi.dst_ip.len = 7;
271
-		sdi.dst_ip.s = "0.0.0.0";
272
-		sdi.dst_port = 0;
273
-	} else {
274
-		sdi.dst_ip = msg->rcv.bind_address->address_str;
275
-		sdi.dst_port = (int)msg->rcv.bind_address->port_no;
276
-	}
277
-
278
-	sdi.af.len = 4;
279
-	if(msg->rcv.bind_address!=NULL
280
-			&& msg->rcv.bind_address->address.af==AF_INET6) {
281
-		sdi.af.s = "ipv6";
221
+		if(msg->rcv.src_ip.af == AF_INET6) {
222
+			isd.dst_ip.len = 3;
223
+			isd.dst_ip.s = "::2";
224
+		} else {
225
+			isd.dst_ip.len = 7;
226
+			isd.dst_ip.s = "0.0.0.0";
227
+		}
228
+		isd.dst_port = 0;
282 229
 	} else {
283
-		sdi.af.s = "ipv4";
230
+		isd.dst_ip = msg->rcv.bind_address->address_str;
231
+		isd.dst_port = (int)msg->rcv.bind_address->port_no;
284 232
 	}
285
-	sdi.proto.s = "none";
286
-	sdi.proto.len = 4;
287
-	get_valid_proto_string(msg->rcv.proto, 0, 0, &sdi.proto);
288 233
 
289
-	if(sipdump_buffer_write(&sdi, &wdata)<0) {
290
-		LM_ERR("failed to write to buffer\n");
234
+	if(sipdump_data_clone(&isd, &osd)<0) {
235
+		LM_ERR("failed to clone sipdump data\n");
291 236
 		return -1;
292 237
 	}
293 238
 
294
-	if(sipdump_list_add(&wdata)<0) {
295
-		LM_ERR("failed to add data to write list\n");
239
+	if(sipdump_list_add(osd)<0) {
240
+		LM_ERR("failed to add data to dump queue\n");
296 241
 		return -1;
297 242
 	}
298 243
 	return 1;
... ...
@@ -318,12 +263,12 @@ static int w_sipdump_send(sip_msg_t *msg, char *ptag, char *str2)
318 263
 /**
319 264
  *
320 265
  */
321
-static sipdump_info_t* sipdump_event_info = NULL;
266
+static sipdump_data_t* sipdump_event_data = NULL;
322 267
 
323 268
 /**
324 269
  *
325 270
  */
326
-int sipdump_event_route(sipdump_info_t* sdi)
271
+int sipdump_event_route(sipdump_data_t* sdi)
327 272
 {
328 273
 	int backup_rt;
329 274
 	run_act_ctx_t ctx;
... ...
@@ -336,7 +281,7 @@ int sipdump_event_route(sipdump_info_t* sdi)
336 281
 	set_route_type(EVENT_ROUTE);
337 282
 	init_run_actions_ctx(&ctx);
338 283
 	fmsg = faked_msg_next();
339
-	sipdump_event_info = sdi;
284
+	sipdump_event_data = sdi;
340 285
 
341 286
 	if(sipdump_event_route_idx>=0) {
342 287
 		run_top_route(event_rt.rlist[sipdump_event_route_idx], fmsg, 0);
... ...
@@ -350,7 +295,7 @@ int sipdump_event_route(sipdump_info_t* sdi)
350 295
 			sr_kemi_act_ctx_set(bctx);
351 296
 		}
352 297
 	}
353
-	sipdump_event_info = NULL;
298
+	sipdump_event_data = NULL;
354 299
 	set_route_type(backup_rt);
355 300
 	if(ctx.run_flags & DROP_R_F) {
356 301
 		return DROP_R_F;
... ...
@@ -363,60 +308,61 @@ int sipdump_event_route(sipdump_info_t* sdi)
363 308
  */
364 309
 int sipdump_msg_received(sr_event_param_t *evp)
365 310
 {
366
-	str wdata;
367
-	sipdump_info_t sdi;
311
+	sipdump_data_t isd;
312
+	sipdump_data_t *osd = NULL;
368 313
 	char srcip_buf[IP_ADDR_MAX_STRZ_SIZE];
369 314
 
370 315
 	if(!sipdump_enabled())
371 316
 		return 0;
372 317
 
373
-	memset(&sdi, 0, sizeof(sipdump_info_t));
374
-
375
-	sdi.buf = *((str*)evp->data);
376
-	sdi.tag.s = "rcv";
377
-	sdi.tag.len = 3;
378
-	sdi.src_ip.len = ip_addr2sbufz(&evp->rcv->src_ip, srcip_buf,
318
+	memset(&isd, 0, sizeof(sipdump_data_t));
319
+
320
+	gettimeofday(&isd.tv, NULL);
321
+	isd.data = *((str*)evp->data);
322
+	isd.tag.s = "rcv";
323
+	isd.tag.len = 3;
324
+	isd.pid = my_pid();
325
+	isd.procno = process_no;
326
+	isd.protoid = evp->rcv->proto;
327
+	isd.afid = (evp->rcv->bind_address!=NULL
328
+				&& evp->rcv->bind_address->address.af==AF_INET6)?AF_INET6:AF_INET;
329
+	isd.src_ip.len = ip_addr2sbufz(&evp->rcv->src_ip, srcip_buf,
379 330
 					IP_ADDR_MAX_STRZ_SIZE);
380
-	sdi.src_ip.s = srcip_buf;
381
-	sdi.src_port = evp->rcv->src_port;
331
+	isd.src_ip.s = srcip_buf;
332
+	isd.src_port = evp->rcv->src_port;
382 333
 	if(evp->rcv->bind_address==NULL
383 334
 			|| evp->rcv->bind_address->address_str.s==NULL) {
384
-		sdi.dst_ip.len = 7;
385
-		sdi.dst_ip.s = "0.0.0.0";
386
-		sdi.dst_port = 0;
387
-	} else {
388
-		sdi.dst_ip = evp->rcv->bind_address->address_str;
389
-		sdi.dst_port = (int)evp->rcv->bind_address->port_no;
390
-	}
391
-	sdi.af.len = 4;
392
-	if(evp->rcv->bind_address!=NULL
393
-			&& evp->rcv->bind_address->address.af==AF_INET6) {
394
-		sdi.af.s = "ipv6";
335
+		if(isd.afid == AF_INET6) {
336
+			isd.dst_ip.len = 3;
337
+			isd.dst_ip.s = "::2";
338
+		} else {
339
+			isd.dst_ip.len = 7;
340
+			isd.dst_ip.s = "0.0.0.0";
341
+		}
342
+		isd.dst_port = 0;
395 343
 	} else {
396
-		sdi.af.s = "ipv4";
344
+		isd.dst_ip = evp->rcv->bind_address->address_str;
345
+		isd.dst_port = (int)evp->rcv->bind_address->port_no;
397 346
 	}
398
-	sdi.proto.s = "none";
399
-	sdi.proto.len = 4;
400
-	get_valid_proto_string(evp->rcv->proto, 0, 0, &sdi.proto);
401 347
 
402 348
 	if(sipdump_mode & SIPDUMP_MODE_EVROUTE) {
403
-		if(sipdump_event_route(&sdi) == DROP_R_F) {
349
+		if(sipdump_event_route(&isd) == DROP_R_F) {
404 350
 			/* drop() used in event_route - all done */
405 351
 			return 0;
406 352
 		}
407 353
 	}
408 354
 
409
-	if(!(sipdump_mode & SIPDUMP_MODE_WFILE)) {
355
+	if(!(sipdump_mode & (SIPDUMP_MODE_WTEXT|SIPDUMP_MODE_WPCAP))) {
410 356
 		return 0;
411 357
 	}
412 358
 
413
-	if(sipdump_buffer_write(&sdi, &wdata)<0) {
414
-		LM_ERR("failed to write to buffer\n");
359
+	if(sipdump_data_clone(&isd, &osd)<0) {
360
+		LM_ERR("failed to close sipdump data\n");
415 361
 		return -1;
416 362
 	}
417 363
 
418
-	if(sipdump_list_add(&wdata)<0) {
419
-		LM_ERR("failed to add data to write list\n");
364
+	if(sipdump_list_add(osd)<0) {
365
+		LM_ERR("failed to add data to dump queue\n");
420 366
 		return -1;
421 367
 	}
422 368
 	return 0;
... ...
@@ -427,58 +373,58 @@ int sipdump_msg_received(sr_event_param_t *evp)
427 373
  */
428 374
 int sipdump_msg_sent(sr_event_param_t *evp)
429 375
 {
430
-	str wdata;
431
-	sipdump_info_t sdi;
376
+	sipdump_data_t isd;
377
+	sipdump_data_t *osd = NULL;
432 378
 	ip_addr_t ip;
433 379
 	char dstip_buf[IP_ADDR_MAX_STRZ_SIZE];
434 380
 
435 381
 	if(!sipdump_enabled())
436 382
 		return 0;
437 383
 
438
-	memset(&sdi, 0, sizeof(sipdump_info_t));
384
+	memset(&isd, 0, sizeof(sipdump_data_t));
439 385
 
440
-	sdi.buf = *((str*)evp->data);
441
-	sdi.tag.s = "snd";
442
-	sdi.tag.len = 3;
386
+	gettimeofday(&isd.tv, NULL);
387
+	isd.data = *((str*)evp->data);
388
+	isd.tag.s = "snd";
389
+	isd.tag.len = 3;
390
+	isd.pid = my_pid();
391
+	isd.procno = process_no;
392
+	isd.protoid = evp->dst->proto;
393
+	isd.afid = evp->dst->send_sock->address.af;
443 394
 
444 395
 	if(evp->dst->send_sock==NULL || evp->dst->send_sock->address_str.s==NULL) {
445
-		sdi.src_ip.len = 7;
446
-		sdi.src_ip.s = "0.0.0.0";
447
-		sdi.src_port = 0;
396
+		if(evp->dst->send_sock->address.af == AF_INET6) {
397
+			isd.src_ip.len = 3;
398
+			isd.src_ip.s = "::2";
399
+		} else {
400
+			isd.src_ip.len = 7;
401
+			isd.src_ip.s = "0.0.0.0";
402
+		}
403
+		isd.src_port = 0;
448 404
 	} else {
449
-		sdi.src_ip = evp->dst->send_sock->address_str;
450
-		sdi.src_port = (int)evp->dst->send_sock->port_no;
405
+		isd.src_ip = evp->dst->send_sock->address_str;
406
+		isd.src_port = (int)evp->dst->send_sock->port_no;
451 407
 	}
452 408
 	su2ip_addr(&ip, &evp->dst->to);
453
-	sdi.dst_ip.len = ip_addr2sbufz(&ip, dstip_buf, IP_ADDR_MAX_STRZ_SIZE);
454
-	sdi.dst_ip.s = dstip_buf;
455
-	sdi.dst_port = (int)su_getport(&evp->dst->to);
456
-
457
-	sdi.af.len = 4;
458
-	if(evp->dst->send_sock->address.af==AF_INET6) {
459
-		sdi.af.s = "ipv6";
460
-	} else {
461
-		sdi.af.s = "ipv4";
462
-	}
463
-	sdi.proto.s = "none";
464
-	sdi.proto.len = 4;
465
-	get_valid_proto_string(evp->dst->proto, 0, 0, &sdi.proto);
409
+	isd.dst_ip.len = ip_addr2sbufz(&ip, dstip_buf, IP_ADDR_MAX_STRZ_SIZE);
410
+	isd.dst_ip.s = dstip_buf;
411
+	isd.dst_port = (int)su_getport(&evp->dst->to);
466 412
 
467 413
 	if(sipdump_mode & SIPDUMP_MODE_EVROUTE) {
468
-		sipdump_event_route(&sdi);
414
+		sipdump_event_route(&isd);
469 415
 	}
470 416
 
471
-	if(!(sipdump_mode & SIPDUMP_MODE_WFILE)) {
417
+	if(!(sipdump_mode & (SIPDUMP_MODE_WTEXT|SIPDUMP_MODE_WPCAP))) {
472 418
 		return 0;
473 419
 	}
474 420
 
475
-	if(sipdump_buffer_write(&sdi, &wdata)<0) {
476
-		LM_ERR("failed to write to buffer\n");
421
+	if(sipdump_data_clone(&isd, &osd)<0) {
422
+		LM_ERR("failed to clone sipdump data\n");
477 423
 		return -1;
478 424
 	}
479 425
 
480
-	if(sipdump_list_add(&wdata)<0) {
481
-		LM_ERR("failed to add data to write list\n");
426
+	if(sipdump_list_add(osd)<0) {
427
+		LM_ERR("failed to add data to dump queue\n");
482 428
 		return -1;
483 429
 	}
484 430
 	return 0;
... ...
@@ -496,12 +442,12 @@ static sr_kemi_xval_t* ki_sipdump_get_buf(sip_msg_t *msg)
496 442
 {
497 443
 	memset(&_ksr_kemi_sipdump_xval, 0, sizeof(sr_kemi_xval_t));
498 444
 
499
-	if (sipdump_event_info==NULL) {
445
+	if (sipdump_event_data==NULL) {
500 446
 		sr_kemi_xval_null(&_ksr_kemi_sipdump_xval, SR_KEMI_XVAL_NULL_EMPTY);
501 447
 		return &_ksr_kemi_sipdump_xval;
502 448
 	}
503 449
 	_ksr_kemi_sipdump_xval.vtype = SR_KEMIP_STR;
504
-	_ksr_kemi_sipdump_xval.v.s = sipdump_event_info->buf;
450
+	_ksr_kemi_sipdump_xval.v.s = sipdump_event_data->data;
505 451
 	return &_ksr_kemi_sipdump_xval;
506 452
 }
507 453
 
... ...
@@ -512,12 +458,12 @@ static sr_kemi_xval_t* ki_sipdump_get_tag(sip_msg_t *msg)
512 458
 {
513 459
 	memset(&_ksr_kemi_sipdump_xval, 0, sizeof(sr_kemi_xval_t));
514 460
 
515
-	if (sipdump_event_info==NULL) {
461
+	if (sipdump_event_data==NULL) {
516 462
 		sr_kemi_xval_null(&_ksr_kemi_sipdump_xval, SR_KEMI_XVAL_NULL_EMPTY);
517 463
 		return &_ksr_kemi_sipdump_xval;
518 464
 	}
519 465
 	_ksr_kemi_sipdump_xval.vtype = SR_KEMIP_STR;
520
-	_ksr_kemi_sipdump_xval.v.s = sipdump_event_info->tag;
466
+	_ksr_kemi_sipdump_xval.v.s = sipdump_event_data->tag;
521 467
 	return &_ksr_kemi_sipdump_xval;
522 468
 }
523 469
 
... ...
@@ -528,12 +474,12 @@ static sr_kemi_xval_t* ki_sipdump_get_src_ip(sip_msg_t *msg)
528 474
 {
529 475
 	memset(&_ksr_kemi_sipdump_xval, 0, sizeof(sr_kemi_xval_t));
530 476
 
531
-	if (sipdump_event_info==NULL) {
477
+	if (sipdump_event_data==NULL) {
532 478
 		sr_kemi_xval_null(&_ksr_kemi_sipdump_xval, SR_KEMI_XVAL_NULL_EMPTY);
533 479
 		return &_ksr_kemi_sipdump_xval;
534 480
 	}
535 481
 	_ksr_kemi_sipdump_xval.vtype = SR_KEMIP_STR;
536
-	_ksr_kemi_sipdump_xval.v.s = sipdump_event_info->src_ip;
482
+	_ksr_kemi_sipdump_xval.v.s = sipdump_event_data->src_ip;
537 483
 	return &_ksr_kemi_sipdump_xval;
538 484
 }
539 485
 
... ...
@@ -544,12 +490,12 @@ static sr_kemi_xval_t* ki_sipdump_get_dst_ip(sip_msg_t *msg)
544 490
 {
545 491
 	memset(&_ksr_kemi_sipdump_xval, 0, sizeof(sr_kemi_xval_t));
546 492
 
547
-	if (sipdump_event_info==NULL) {
493
+	if (sipdump_event_data==NULL) {
548 494
 		sr_kemi_xval_null(&_ksr_kemi_sipdump_xval, SR_KEMI_XVAL_NULL_EMPTY);
549 495
 		return &_ksr_kemi_sipdump_xval;
550 496
 	}
551 497
 	_ksr_kemi_sipdump_xval.vtype = SR_KEMIP_STR;
552
-	_ksr_kemi_sipdump_xval.v.s = sipdump_event_info->dst_ip;
498
+	_ksr_kemi_sipdump_xval.v.s = sipdump_event_data->dst_ip;
553 499
 	return &_ksr_kemi_sipdump_xval;
554 500
 }
555 501
 
... ...
@@ -652,30 +598,37 @@ error:
652 598
 int pv_get_sipdump(sip_msg_t *msg, pv_param_t *param,
653 599
 		pv_value_t *res)
654 600
 {
655
-	if (sipdump_event_info==NULL) {
601
+	str saf = str_init("ipv4");
602
+	str sproto = str_init("none");
603
+
604
+	if (sipdump_event_data==NULL) {
656 605
 		return pv_get_null(msg, param, res);
657 606
 	}
658 607
 
659 608
 	switch(param->pvn.u.isname.name.n) {
660 609
 		case 1: /* buf */
661
-			return pv_get_strval(msg, param, res, &sipdump_event_info->buf);
610
+			return pv_get_strval(msg, param, res, &sipdump_event_data->data);
662 611
 		case 2: /* len */
663
-			return pv_get_uintval(msg, param, res, sipdump_event_info->buf.len);
612
+			return pv_get_uintval(msg, param, res, sipdump_event_data->data.len);
664 613
 		case 3: /* af */
665
-			return pv_get_strval(msg, param, res, &sipdump_event_info->af);
614
+			if(sipdump_event_data->afid==AF_INET6) {
615
+				saf.s = "ipv6";
616
+			}
617
+			return pv_get_strval(msg, param, res, &saf);
666 618
 		case 4: /* proto */
667
-			return pv_get_strval(msg, param, res, &sipdump_event_info->proto);
619
+			get_valid_proto_string(sipdump_event_data->protoid, 0, 0, &sproto);
620
+			return pv_get_strval(msg, param, res, &sproto);
668 621
 		case 6: /* src_ip*/
669
-			return pv_get_strval(msg, param, res, &sipdump_event_info->src_ip);
622
+			return pv_get_strval(msg, param, res, &sipdump_event_data->src_ip);
670 623
 		case 7: /* dst_ip*/
671
-			return pv_get_strval(msg, param, res, &sipdump_event_info->dst_ip);
624
+			return pv_get_strval(msg, param, res, &sipdump_event_data->dst_ip);
672 625
 		case 8: /* src_port */
673
-			return pv_get_uintval(msg, param, res, sipdump_event_info->src_port);
626
+			return pv_get_uintval(msg, param, res, sipdump_event_data->src_port);
674 627
 		case 9: /* dst_port */
675
-			return pv_get_uintval(msg, param, res, sipdump_event_info->dst_port);
628
+			return pv_get_uintval(msg, param, res, sipdump_event_data->dst_port);
676 629
 		default:
677 630
 			/* 0 - tag */
678
-			return pv_get_strval(msg, param, res, &sipdump_event_info->tag);
631
+			return pv_get_strval(msg, param, res, &sipdump_event_data->tag);
679 632
 	}
680 633
 }
681 634
 
... ...
@@ -36,6 +36,7 @@
36 36
 #include "sipdump_write.h"
37 37
 
38 38
 extern int sipdump_rotate;
39
+extern int sipdump_mode;
39 40
 
40 41
 static time_t sipdump_last_rotate = 0;
41 42
 
... ...
@@ -45,7 +46,8 @@ static sipdump_list_t *_sipdump_list = NULL;
45 46
 static char _sipdump_fpath[SIPDUMP_FPATH_SIZE];
46 47
 static str _sipdump_fpath_prefix = {0, 0};
47 48
 
48
-static FILE *_sipdump_file = NULL;
49
+static FILE *_sipdump_text_file = NULL;
50
+static FILE *_sipdump_pcap_file = NULL;
49 51
 
50 52
 /**
51 53
  *
... ...
@@ -102,21 +104,8 @@ int sipdump_list_destroy(void)
102 104
 /**
103 105
  *
104 106
  */
105
-int sipdump_list_add(str *data)
107
+int sipdump_list_add(sipdump_data_t *sdd)
106 108
 {
107
-	sipdump_data_t *sdd = NULL;
108
-
109
-	sdd = (sipdump_data_t*)shm_malloc(sizeof(sipdump_data_t)
110
-				+ (data->len+1)*sizeof(char));
111
-	if(sdd==NULL) {
112
-		LM_ERR("no more shared memory\n");
113
-		return -1;
114
-	}
115
-	memset(sdd, 0, sizeof(sipdump_data_t));
116
-	sdd->data.s = (char*)sdd + sizeof(sipdump_data_t);
117
-	sdd->data.len = data->len;
118
-	memcpy(sdd->data.s, data->s, data->len);
119
-	sdd->data.s[data->len] = '\0';
120 109
 	lock_get(&_sipdump_list->lock);
121 110
 	if(_sipdump_list->last) {
122 111
 		_sipdump_list->last->next = sdd;
... ...
@@ -128,6 +117,53 @@ int sipdump_list_add(str *data)
128 117
 	return 0;
129 118
 }
130 119
 
120
+/**
121
+ *
122
+ */
123
+int sipdump_data_clone(sipdump_data_t *isd, sipdump_data_t **osd)
124
+{
125
+	int dsize = 0;
126
+	sipdump_data_t *sdd = NULL;
127
+
128
+	*osd = NULL;
129
+
130
+	dsize = sizeof(sipdump_data_t) + (isd->data.len + 1 + isd->tag.len + 1
131
+				+ isd->src_ip.len + 1 + isd->dst_ip.len + 1)*sizeof(char);
132
+	sdd = (sipdump_data_t*)shm_malloc(dsize);
133
+	if(sdd==NULL) {
134
+		LM_ERR("no more shared memory\n");
135
+		return -1;
136
+	}
137
+	memset(sdd, 0, dsize);
138
+
139
+	memcpy(sdd, isd, sizeof(sipdump_data_t));
140
+	sdd->next = NULL;
141
+
142
+	sdd->data.s = (char*)sdd + sizeof(sipdump_data_t);
143
+	sdd->data.len = isd->data.len;
144
+	memcpy(sdd->data.s, isd->data.s, isd->data.len);
145
+	sdd->data.s[sdd->data.len] = '\0';
146
+
147
+	sdd->tag.s = sdd->data.s + sdd->data.len + 1;
148
+	sdd->tag.len = isd->tag.len;
149
+	memcpy(sdd->tag.s, isd->tag.s, isd->tag.len);
150
+	sdd->tag.s[sdd->tag.len] = '\0';
151
+
152
+	sdd->src_ip.s = sdd->tag.s + sdd->tag.len + 1;
153
+	sdd->src_ip.len = isd->src_ip.len;
154
+	memcpy(sdd->src_ip.s, isd->src_ip.s, isd->src_ip.len);
155
+	sdd->src_ip.s[sdd->src_ip.len] = '\0';
156
+
157
+	sdd->dst_ip.s = sdd->src_ip.s + sdd->src_ip.len + 1;
158
+	sdd->dst_ip.len = isd->dst_ip.len;
159
+	memcpy(sdd->dst_ip.s, isd->dst_ip.s, isd->dst_ip.len);
160
+	sdd->dst_ip.s[sdd->dst_ip.len] = '\0';
161
+
162
+	*osd = sdd;
163
+
164
+	return 0;
165
+}
166
+
131 167
 /**
132 168
  *
133 169
  */
... ...
@@ -188,28 +224,54 @@ static int sipdump_rotate_file(void)
188 224
 
189 225
 	tv = time(NULL);
190 226
 
191
-	if(_sipdump_file!=NULL
227
+	if(_sipdump_text_file!=NULL
228
+			&& sipdump_last_rotate>0
229
+			&& sipdump_last_rotate+sipdump_rotate>tv) {
230
+		/* not yet the time for rotation */
231
+		return 0;
232
+	}
233
+	if(_sipdump_pcap_file!=NULL
192 234
 			&& sipdump_last_rotate>0
193 235
 			&& sipdump_last_rotate+sipdump_rotate>tv) {
194 236
 		/* not yet the time for rotation */
195 237
 		return 0;
196 238
 	}
197 239
 
198
-	if(_sipdump_file != NULL) {
199
-		fclose(_sipdump_file);
240
+	if(_sipdump_text_file != NULL) {
241
+		fclose(_sipdump_text_file);
242
+	}
243
+	if(_sipdump_pcap_file != NULL) {
244
+		fclose(_sipdump_pcap_file);
200 245
 	}
246
+
201 247
 	localtime_r(&tv, &ti);
202
-	n = snprintf(_sipdump_fpath+_sipdump_fpath_prefix.len,
203
-			SIPDUMP_FPATH_SIZE-_sipdump_fpath_prefix.len,
204
-			"%d-%02d-%02d--%02d-%02d-%02d.data",
205
-			1900+ti.tm_year, ti.tm_mon+1, ti.tm_mday,
206
-			ti.tm_hour, ti.tm_min, ti.tm_sec);
207
-	LM_DBG("writing to file: %s (%d)\n", _sipdump_fpath, n);
208
-	_sipdump_file = fopen( _sipdump_fpath, "w" );
209
-	if(_sipdump_file==NULL) {
210
-		LM_ERR("failed to open file %s\n", _sipdump_fpath);
211
-		return -1;
248
+	if(sipdump_mode & SIPDUMP_MODE_WTEXT) {
249
+		n = snprintf(_sipdump_fpath+_sipdump_fpath_prefix.len,
250
+				SIPDUMP_FPATH_SIZE-_sipdump_fpath_prefix.len,
251
+				"%d-%02d-%02d--%02d-%02d-%02d.data",
252
+				1900+ti.tm_year, ti.tm_mon+1, ti.tm_mday,
253
+				ti.tm_hour, ti.tm_min, ti.tm_sec);
254
+		LM_DBG("writing to text file: %s (%d)\n", _sipdump_fpath, n);
255
+		_sipdump_text_file = fopen( _sipdump_fpath, "w" );
256
+		if(_sipdump_text_file==NULL) {
257
+			LM_ERR("failed to open file %s\n", _sipdump_fpath);
258
+			return -1;
259
+		}
212 260
 	}
261
+	if(sipdump_mode & SIPDUMP_MODE_WPCAP) {
262
+		n = snprintf(_sipdump_fpath+_sipdump_fpath_prefix.len,
263
+				SIPDUMP_FPATH_SIZE-_sipdump_fpath_prefix.len,
264
+				"%d-%02d-%02d--%02d-%02d-%02d.pcap",
265
+				1900+ti.tm_year, ti.tm_mon+1, ti.tm_mday,
266
+				ti.tm_hour, ti.tm_min, ti.tm_sec);
267
+		LM_DBG("writing to pcap file: %s (%d)\n", _sipdump_fpath, n);
268
+		_sipdump_pcap_file = fopen( _sipdump_fpath, "w" );
269
+		if(_sipdump_pcap_file==NULL) {
270
+			LM_ERR("failed to open file %s\n", _sipdump_fpath);
271
+			return -1;
272
+		}
273
+	}
274
+
213 275
 	sipdump_write_meta(_sipdump_fpath);
214 276
 	sipdump_last_rotate = tv;
215 277
 
... ...
@@ -234,12 +296,63 @@ int sipdump_file_init(str *folder, str *fprefix)
234 296
 	return 0;
235 297
 }
236 298
 
299
+#define SIPDUMP_WBUF_SIZE 65536
300
+static char _sipdump_wbuf[SIPDUMP_WBUF_SIZE];
301
+
302
+/**
303
+ *
304
+ */
305
+int sipdump_data_print(sipdump_data_t *sd, str *obuf)
306
+{
307
+	struct tm ti;
308
+	char t_buf[26] = {0};
309
+	str sproto = str_init("none");
310
+	str saf = str_init("ipv4");
311
+
312
+	if(sd->afid==AF_INET6) {
313
+		saf.s = "ipv6";
314
+	}
315
+
316
+	get_valid_proto_string(sd->protoid, 0, 0, &sproto);
317
+
318
+	localtime_r(&sd->tv.tv_sec, &ti);
319
+	obuf->len = snprintf(_sipdump_wbuf, SIPDUMP_WBUF_SIZE,
320
+		"====================\n"
321
+		"tag: %.*s\n"
322
+		"pid: %d\n"
323
+		"process: %d\n"
324
+		"time: %lu.%06lu\n"
325
+		"date: %s"
326
+		"proto: %.*s %.*s\n"
327
+		"srcip: %.*s\n"
328
+		"srcport: %d\n"
329
+		"dstip: %.*s\n"
330
+		"dstport: %d\n"
331
+		"~~~~~~~~~~~~~~~~~~~~\n"
332
+		"%.*s"
333
+		"||||||||||||||||||||\n",
334
+		sd->tag.len, sd->tag.s,
335
+		sd->pid,
336
+		sd->procno,
337
+		(unsigned long)sd->tv.tv_sec, (unsigned long)sd->tv.tv_usec,
338
+		asctime_r(&ti, t_buf),
339
+		sproto.len, sproto.s, saf.len, saf.s,
340
+		sd->src_ip.len, sd->src_ip.s, sd->src_port,
341
+		sd->dst_ip.len, sd->dst_ip.s, sd->dst_port,
342
+		sd->data.len, sd->data.s
343
+	);
344
+	obuf->s = _sipdump_wbuf;
345
+
346
+	return 0;
347
+}
348
+
237 349
 /**
238 350
  *
239 351
  */
240 352
 void sipdump_timer_exec(unsigned int ticks, void *param)
241 353
 {
242 354
 	sipdump_data_t *sdd = NULL;
355
+	str odata = str_init("");
243 356
 	int cnt = 0;
244 357
 
245 358
 	if(_sipdump_list==NULL || _sipdump_list->first==NULL)
... ...
@@ -254,7 +367,7 @@ void sipdump_timer_exec(unsigned int ticks, void *param)
254 367
 		lock_get(&_sipdump_list->lock);
255 368
 		if(_sipdump_list->first==NULL) {
256 369
 			lock_release(&_sipdump_list->lock);
257
-			if(_sipdump_file) fflush(_sipdump_file);
370
+			if(_sipdump_text_file) fflush(_sipdump_text_file);
258 371
 			return;
259 372
 		}
260 373
 		sdd = _sipdump_list->first;
... ...
@@ -272,13 +385,23 @@ void sipdump_timer_exec(unsigned int ticks, void *param)
272 385
 			}
273 386
 			cnt=0;
274 387
 		}
275
-		if(_sipdump_file==NULL) {
276
-			LM_ERR("sipdump file is not open\n");
277
-			return;
388
+		if(sipdump_mode & SIPDUMP_MODE_WTEXT) {
389
+			if(_sipdump_text_file==NULL) {
390
+				LM_ERR("sipdump text file is not open\n");
391
+				return;
392
+			}
393
+			sipdump_data_print(sdd, &odata);
394
+			/* LM_NOTICE("writing: [[%.*s]] (%d)\n", odata.len,
395
+					odata.s, odata.len); */
396
+			fwrite(odata.s, 1, odata.len, _sipdump_text_file);
397
+		}
398
+		if(sipdump_mode & SIPDUMP_MODE_WPCAP) {
399
+			if(_sipdump_pcap_file==NULL) {
400
+				LM_ERR("sipdump pcap file is not open\n");
401
+				return;
402
+			}
403
+			sipdump_write_pcap(_sipdump_pcap_file, sdd);
278 404
 		}
279
-		/* LM_NOTICE("writing: [[%.*s]] (%d)\n",
280
-			sdd->data.len, sdd->data.s, sdd->data.len); */
281
-		fwrite(sdd->data.s, 1, sdd->data.len, _sipdump_file);
282 405
 		shm_free(sdd);
283 406
 	}
284 407
 }
... ...
@@ -23,14 +23,28 @@
23 23
 #ifndef _SIPDUMP_WRITE_H_
24 24
 #define _SIPDUMP_WRITE_H_
25 25
 
26
+#include <sys/time.h>
27
+
26 28
 #include "../../core/str.h"
27 29
 #include "../../core/locking.h"
28 30
 
29
-#define SIPDUMP_MODE_WFILE (1<<0)
31
+#define SIPDUMP_MODE_WTEXT (1<<0)
30 32
 #define SIPDUMP_MODE_EVROUTE (1<<1)
33
+#define SIPDUMP_MODE_WPCAP (1<<2)
34
+#define SIPDUMP_MODE_WPCAPEX (1<<3)
31 35
 
32 36
 typedef struct sipdump_data {
37
+	int pid;
38
+	int procno;
39
+	struct timeval tv;
33 40
 	str data;
41
+	str tag;
42
+	int afid;
43
+	int protoid;
44
+	str src_ip;
45
+	int src_port;
46
+	str dst_ip;
47
+	int dst_port;
34 48
 	struct sipdump_data *next;
35 49
 } sipdump_data_t;
36 50
 
... ...
@@ -46,12 +60,20 @@ int sipdump_list_init(int en);
46 60
 
47 61
 int sipdump_list_destroy(void);
48 62
 
49
-int sipdump_list_add(str *data);
63
+int sipdump_list_add(sipdump_data_t *sdd);
50 64
 
51 65
 void sipdump_timer_exec(unsigned int ticks, void *param);
52 66
 
53 67
 int sipdump_file_init(str *folder, str *fprefix);
54 68
 
69
+void sipdump_init_pcap(FILE *fs);
70
+
71
+void sipdump_write_pcap(FILE *fs, sipdump_data_t *sd);
72
+
73
+int sipdump_data_print(sipdump_data_t *sd, str *obuf);
74
+
75
+int sipdump_data_clone(sipdump_data_t *isd, sipdump_data_t **osd);
76
+
55 77
 int sipdump_enabled(void);
56 78
 
57 79
 int sipdump_rpc_init(void);