File: tcpsegment_report.c

package info (click to toggle)
libtrace3 3.0.7-1
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 3,676 kB
  • ctags: 3,140
  • sloc: ansic: 20,551; sh: 10,125; cpp: 1,384; makefile: 415; yacc: 96; lex: 50
file content (88 lines) | stat: -rw-r--r-- 2,191 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include <netdb.h>
#include <inttypes.h>
#include <lt_inttypes.h>
#include <stdio.h>
#include "libtrace.h"
#include "tracereport.h"
#include "report.h"

#define MAX_SEG_SIZE 10000

static stat_t tcpseg_stat[3][MAX_SEG_SIZE + 1] = {{{0,0}}} ;
static bool suppress[3] = {true,true,true};

void tcpseg_per_packet(struct libtrace_packet_t *packet)
{
	struct libtrace_tcp *tcp = trace_get_tcp(packet);
	libtrace_ip_t *ip = trace_get_ip(packet);
	libtrace_direction_t dir = trace_get_direction(packet);
	int ss;
	uint16_t ip_len ;
	
	if (!tcp || !ip)
		return;

	if (dir != TRACE_DIR_INCOMING && dir != TRACE_DIR_OUTGOING)
		dir = TRACE_DIR_OTHER;
	
	ip_len = ntohs(ip->ip_len);
	ss = ip_len - (ip->ip_hl * 4);

	if (ss > MAX_SEG_SIZE) {
		fprintf(stderr, "Maximum segment size %u exceeded - size was %u\n",
				MAX_SEG_SIZE, ss);
		return;
	}


	tcpseg_stat[dir][ss].count++;
	tcpseg_stat[dir][ss].bytes+=trace_get_wire_length(packet);
	suppress[dir] = false;
}

void tcpseg_report(void)
{
	int i,j;
	FILE *out = fopen("tcpseg.rpt", "w");
	if (!out) {
		perror("fopen");
		return;
	}
	fprintf(out, "%-16s\t%10s\t%16s %16s\n",
			"SEGMENT SIZE",
			"DIRECTION",
			"BYTES",
			"PACKETS");
	
	for(i=0;i<2048;++i) {
		bool indent_needed;
		if (tcpseg_stat[0][i].count==0 && 
			tcpseg_stat[1][i].count==0 && tcpseg_stat[2][i].count==0)
			continue;
		fprintf(out, "%16i:",i);
		indent_needed=false;
		for(j=0;j<3;j++){
			if (indent_needed) {
				fprintf(out, "%16s", " ");
			}
			if (suppress[j])
				continue;
			switch (j) {
                                case 0:
                                        fprintf(out, "\t%10s", "Outbound");
                                        break;
                                case 1:
                                        fprintf(out, "\t%10s", "Inbound");
                                        break;
                                case 2:
                                        fprintf(out, "\t%10s", "Unknown");
                                        break;
                        }
			fprintf(out, "\t%16" PRIu64 " %16" PRIu64 "\n",
				tcpseg_stat[j][i].bytes,
				tcpseg_stat[j][i].count);	
			indent_needed=true;
		}
	}
	fclose(out);
}