source: examples/rtt/rtt.cc @ ec73798

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since ec73798 was ec73798, checked in by Perry Lorier <perry@…>, 15 years ago

Don't output the resutls of the selftest

  • Property mode set to 100644
File size: 5.7 KB
Line 
1#include <stdio.h>
2#include <assert.h>
3#include "libtrace.h"
4#include <map>
5
6struct flow_id_t {
7        uint32_t ip_a;
8        uint32_t ip_b;
9        uint16_t port_a;
10        uint16_t port_b;
11
12        flow_id_t(void) : 
13                ip_a(0), ip_b(0), 
14                port_a(0), port_b(0) 
15                {};
16};
17
18int cmp(const flow_id_t &a, const flow_id_t &b) {
19        if (a.ip_a < b.ip_a)    return -1;
20        if (a.ip_a > b.ip_a)    return 1;
21
22        if (a.ip_b < b.ip_b)    return -1;
23        if (a.ip_b > b.ip_b)    return 1;
24
25        if (a.port_a < b.port_a) return -1;
26        if (a.port_a > b.port_a) return 1;
27
28        if (a.port_b < b.port_b) return -1;
29        if (a.port_b > b.port_b) return 1;
30
31        return 0;
32}
33
34bool operator <(const flow_id_t &a, const flow_id_t &b) 
35{ 
36        return cmp(a,b)<0; 
37}
38
39typedef uint32_t cookie_t;
40typedef double ts_t;
41
42typedef std::map<cookie_t,ts_t> cookie_jar_t;
43
44typedef std::map<flow_id_t, cookie_jar_t > state_info_t;
45
46state_info_t state_info;
47
48struct libtrace_packet_t packet;
49
50/** parse an option
51 * @param ptr   the pointer to the current option
52 * @param plen  the length of the remaining buffer
53 * @param type  the type of the option
54 * @param optlen the length of the option
55 * @param data  the data of the option
56 *
57 * @returns bool true if there is another option (and the fields are filled in)
58 */
59int get_next_option(unsigned char **ptr,int *len,
60                        unsigned char *type,
61                        unsigned char *optlen,
62                        unsigned char **data)
63{
64        if (*len<=0)
65                return 0;
66        *type=**ptr;
67        switch(*type) {
68                case 0: /* End of options */
69                        return 0;
70                case 1: /* Pad */
71                        (*ptr)++;
72                        (*len)--;
73                        return 1;
74                default:
75                        *optlen = *(*ptr+1);
76                        if (*optlen<2)
77                                return 0; // I have no idea wtf is going on
78                                          // with these packets
79                        (*len)-=*optlen;
80                        (*data)=(*ptr+2);
81                        (*ptr)+=*optlen;
82                        if (*len<0)
83                                return 0;
84                        return 1;
85        }
86        assert(0);
87}
88
89void expire(double now)
90{
91        state_info_t::iterator flow_i = state_info.begin();
92
93        for(; flow_i != state_info.end(); ++flow_i) {
94            cookie_jar_t &cookie_jar = flow_i->second;
95            cookie_jar_t::iterator cookie_i = cookie_jar.begin();
96            for(; cookie_i != cookie_jar.end();) {
97                if(now - cookie_i->second > 180) {
98                    cookie_jar_t::iterator j = cookie_i;
99                    ++j;
100                    cookie_jar.erase(cookie_i);
101                    cookie_i = j;
102                } else {
103                    ++cookie_i;
104                }
105            }
106        }
107}
108
109void dump_db(void)
110{
111        fflush(stderr); fflush(stdout);
112        for (state_info_t::const_iterator flow_i = state_info.begin();
113                        flow_i!=state_info.end();
114                        flow_i++) {
115                fprintf(stderr,"%08x:%i -> %08x:%i\n",
116                        flow_i->first.ip_a,
117                        flow_i->first.port_a,
118                        flow_i->first.ip_b,
119                        flow_i->first.port_b);
120                for(cookie_jar_t::const_iterator cookie_i=flow_i->second.begin();
121                                cookie_i!=flow_i->second.end();
122                                cookie_i++) {
123                        fprintf(stderr," %u -> %f\n",cookie_i->first,
124                                                cookie_i->second);
125                }
126        }
127        fprintf(stderr,"\n");
128        fflush(stderr); fflush(stdout);
129}
130
131int main(int argc, char *argv[])
132{
133        struct libtrace_t *trace;
134        double last = 0;
135        struct flow_id_t a,b;
136
137        /* Perform a self test to prove that the comparitor is working fine */
138        a.ip_a = 0x7f000001;
139        a.ip_b = 0x0ac0ffee;
140        a.port_a = 80;
141        a.port_b = 1024;
142        b.ip_a = 0x0ac0ffee;
143        b.ip_b = 0x7f000001;
144        b.port_a = 1024;
145        b.port_b = 80;
146
147        assert(cmp(a,b)==1);
148
149        /* Now that the self test has succeeded, try the full program */
150
151        trace = trace_create(argv[1]);
152
153        for (;;) {
154                struct libtrace_tcp *tcpptr;
155                struct libtrace_ip *ipptr;
156                int psize;
157
158                if ((psize = trace_read_packet(trace, &packet)) <= 0) {
159                        break;
160                }
161
162                ipptr = trace_get_ip(&packet);
163                if (!ipptr)
164                        continue;
165
166                if (ipptr->ip_p!=6)
167                        continue;
168
169                tcpptr = trace_get_tcp(&packet);
170
171                if (!tcpptr)
172                        continue;
173
174                struct flow_id_t fwd; 
175                struct flow_id_t rev;
176                fwd.ip_a = ipptr->ip_src.s_addr;
177                fwd.ip_b = ipptr->ip_dst.s_addr;
178                fwd.port_a = tcpptr->source;
179                fwd.port_b = tcpptr->dest;
180
181                rev.ip_b = ipptr->ip_src.s_addr;
182                rev.ip_a = ipptr->ip_dst.s_addr;
183                rev.port_b = tcpptr->source;
184                rev.port_a = tcpptr->dest;
185
186                double now = trace_get_seconds(&packet);
187
188                /* search for the timestamp option */   
189                unsigned char *pkt = (unsigned char *)tcpptr + sizeof(*tcpptr);
190                //int plen = (packet.size-(pkt-(unsigned char*)packet.buffer)) <? (tcpptr->doff*4-sizeof *tcpptr);
191                int plen = (tcpptr->doff*4-sizeof *tcpptr);
192                unsigned char type = 0;
193                unsigned char optlen = 0;
194                unsigned char *data = 0;
195
196                while (get_next_option(&pkt,&plen,&type,&optlen,&data)) {
197                        // ignore non timestamp options
198                        if (type!=8) {
199                                continue;
200                        }
201                        uint32_t *ts=(uint32_t *)&data[0];
202                        uint32_t *tsecho=(uint32_t*)&data[4];
203
204
205                        state_info_t::iterator si = state_info.find(rev);
206                        if(si != state_info.end()) {
207
208                            cookie_jar_t &cookie_jar = si->second;
209                            cookie_jar_t::iterator ci = cookie_jar.find(*tsecho);
210                            if(ci != cookie_jar.end()) {
211                                printf("%f %.12f\n",
212                                        now,
213                                        now-ci->second);
214                                cookie_jar.erase(ci);
215                            }
216
217                            assert(state_info.find(rev)!=state_info.end());
218                        }
219
220                        if (*ts) {
221                                state_info_t::iterator si = state_info.find(fwd);
222
223
224                                if (si==state_info.end()) {
225                                        si = state_info.insert(
226                                         std::pair< flow_id_t, cookie_jar_t>(
227                                                fwd, cookie_jar_t())).first;
228                                        assert(state_info.find(fwd)!=state_info.end());
229                                }
230                                assert(state_info.find(fwd)!=state_info.end());
231                                cookie_jar_t &cookie_jar = si->second;
232                                cookie_jar[*ts]=now;
233                                assert(state_info.find(fwd)!=state_info.end());
234                        }
235                }
236
237                if (now-last>60) {
238
239                        last=now;
240
241                        expire(now);
242
243                }
244
245        }
246
247        return 0;
248}
Note: See TracBrowser for help on using the repository browser.