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);
}
|