source: tools/tracereport/locality_report.c @ bd4bec9

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since bd4bec9 was bd4bec9, checked in by Shane Alcock <salcock@…>, 14 years ago

tcpsegment, protocol and tos reports all now write to files.
Changed the output filenames to be *.rpt rather than *.out

  • Property mode set to 100644
File size: 5.6 KB
Line 
1#include <inttypes.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <sys/socket.h>
5#include <netinet/in.h>
6#include <arpa/inet.h>
7#include "libtrace.h"
8#include "tracereport.h"
9
10
11uint64_t byte_counter[3][2] = {{0,0},{0,0},{0,0}};
12uint64_t packet_counter[3][2] = {{0,0},{0,0},{0,0}};
13
14#define MAX_MAP_LINE_LEN 80
15
16struct pnode {
17  bool   local;        /*True if all IPs with this prefix are local*/
18  struct pnode *one;   /*link to tree if 1                */
19  struct pnode *zero;  /*link to tree if 0                */
20};
21
22enum {
23        NATIONAL,
24        INTERNATIONAL,
25        FOREIGN
26};
27
28struct pnode root;
29bool tree_created = false;
30
31void add(long bits, int prefix_len){
32        int bit;
33        int bit_no;
34        struct pnode *pos;
35
36        pos = &root;
37        for ( bit_no = 31; bit_no > 31 - prefix_len; --bit_no ) {
38                bit = (bits>>bit_no) & 0x1;
39
40                if ( bit == 0 ) {
41                        if ( pos->zero == NULL ) {
42                                pos->zero = (struct pnode *)malloc(sizeof(struct
43 pnode));
44                                pos->zero->zero = NULL;
45                                pos->zero->one  = NULL;
46                                pos->zero->local = false;
47                        }
48                        pos = pos->zero;
49                }
50                else {  /* ( bit == 1 ) */
51                        if ( pos->one == NULL ) {
52                                pos->one = (struct pnode *)malloc(sizeof(struct
53pnode));
54                                pos->one->zero = NULL;
55                                pos->one->one  = NULL;
56                                pos->one->local = false;
57                        }
58                        pos = pos->one;
59                } /*else*/
60        } /*for*/
61        pos->local = true;
62} /*void add()*/
63
64void init_tree(char *local_ip_file) {
65        FILE *map;
66        char line[MAX_MAP_LINE_LEN];
67        char addr[20];
68        int  prefix_len;
69
70        root.local = false;
71        root.one = NULL;
72        root.zero = NULL;
73
74        map = fopen(local_ip_file, "r");
75        if ( map == NULL ) { perror("Couldn't open map file"); exit(-0); }
76        while ( NULL != (fgets(line, MAX_MAP_LINE_LEN - 2, map))) {
77                line[MAX_MAP_LINE_LEN-1] = '\0';  /*ensure null termination*/
78                if ( 2 != sscanf(line, "%19[0-9.] %d\n", addr, &prefix_len) ) {
79                        fprintf(stderr, "Bad line in map: %s", line);
80                } else {
81                        add(htonl(inet_addr(addr)), prefix_len);
82                }
83        } /*while*/
84        fclose(map);
85
86}
87
88bool match(long bits){
89        /*bits must be in host byte order*/
90        int bit;
91        int bit_no;
92        struct pnode *pos;
93
94
95        pos = &root;
96
97
98        for ( bit_no = 31; bit_no >= 0; --bit_no ) {
99                bit = (bits>>bit_no) & 0x1;
100                if ( pos->local ) { goto exit_match; }
101                if ( bit == 0 ) pos = pos->zero;  else pos = pos->one;
102                if ( pos == NULL ) goto exit_match;
103        } /*for*/
104
105exit_match:
106        return(pos == NULL ? false : pos->local);
107} /*void match()*/
108
109void locality_per_packet(libtrace_packet_t *packet) {
110libtrace_ip_t *ip = trace_get_ip(packet);
111        uint32_t ip_a, ip_b;
112        uint8_t dir = trace_get_direction(packet);
113       
114        if (!ip)
115                return;
116
117        ip_a = ip->ip_src.s_addr;
118        ip_b = ip->ip_dst.s_addr;
119
120        if (match(ntohl(ip_a)) && match(ntohl(ip_b))) {
121                /* national */
122                byte_counter[NATIONAL][dir] += trace_get_wire_length(packet);
123                packet_counter[NATIONAL][dir] ++;
124        } else if (!match(ntohl(ip_a)) && !match(ntohl(ip_b))) {
125                byte_counter[FOREIGN][dir] += trace_get_wire_length(packet);
126                packet_counter[FOREIGN][dir] ++;
127        } else {
128                byte_counter[INTERNATIONAL][dir] += trace_get_wire_length(packet);
129                packet_counter[INTERNATIONAL][dir] ++;
130        }
131
132}
133
134void locality_report(void) {
135        int i;
136        int j;
137        uint64_t total_bytes = 0;
138        uint64_t total_packets = 0;
139       
140        FILE *out = fopen("locality.rpt", "w");
141        if (!out) {
142                perror("fopen");
143                return;
144        }
145
146        /* inefficient, but we only have three categories */
147        for (i = 0; i < 3; i++) {
148                total_bytes += byte_counter[i][0] + byte_counter[i][1];
149                total_packets += packet_counter[i][0] + packet_counter[i][1];
150        }
151       
152        fprintf(out, "%-16s\t%24s %24s\n", "", "BYTES", "PACKETS");
153        for (i=0; i<3; i++) {
154                switch(i) {
155                        case NATIONAL:
156                                fprintf(out, "%16s", "NATIONAL\n");
157                                break;
158                        case INTERNATIONAL:
159                                fprintf(out, "%16s", "INTERNATIONAL\n");
160                                break;
161                        case FOREIGN:
162                                fprintf(out, "%16s", "FOREIGN\n");
163                                break;
164                }
165                for (j = 0; j < 3; j++) {
166                        uint64_t bytes_to_report = 0;
167                        uint64_t pkts_to_report = 0;
168                        switch(j) {
169                                case TRACE_DIR_OUTGOING:
170                                        fprintf(out, "%16s", "Outgoing");
171                                        bytes_to_report = byte_counter[i][j];
172                                        pkts_to_report = packet_counter[i][j];
173                                        break;
174                                case TRACE_DIR_INCOMING:
175                                        fprintf(out, "%16s", "Incoming");
176                                        bytes_to_report = byte_counter[i][j];
177                                        pkts_to_report = packet_counter[i][j];
178                                        break;
179                                case 2:
180                                        fprintf(out, "%16s", "Total");
181                                        bytes_to_report = byte_counter[i][0] + byte_counter[i][1];
182                                        pkts_to_report = packet_counter[i][0] + packet_counter[i][1];
183                                        break; 
184                        }
185                        fprintf(out, "\t%16llu (%.2f) ", bytes_to_report, bytes_to_report / (total_bytes / 100.0));
186                        fprintf(out, "%16llu (%.2f)\n", pkts_to_report, pkts_to_report / (total_packets / 100.0));
187                }
188        }
189               
190}
191
192int locality_init(char *input_file) {
193       
194        if (!tree_created)      {
195                init_tree(input_file);
196                tree_created = true;
197                       
198        }
199        else {
200                printf("You shouldn't be asking for this report twice!\n");
201                return -1;
202        }
203        return 1;
204}
Note: See TracBrowser for help on using the repository browser.