-
Notifications
You must be signed in to change notification settings - Fork 82
/
storeudptimeseqrecord.hh
110 lines (86 loc) · 3.82 KB
/
storeudptimeseqrecord.hh
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// -*- c-basic-offset: 4 -*-
/*
Programmer: Roman Chertov
* Copyright (c) 2010 The Aerospace Corporation
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, subject to the conditions
* listed in the Click LICENSE file. These conditions include: you must
* preserve this copyright notice, and you cannot mention the copyright
* holders in advertising related to the Software without their permission.
* The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
* notice is a summary of the Click LICENSE file; the license in that file is
* legally binding.
*/
#ifndef CLICK_STOREUDPTIMESEQRECORD_HH
#define CLICK_STOREUDPTIMESEQRECORD_HH
#include <click/element.hh>
CLICK_DECLS
/*
=c
StoreUDPTimeSeqRecord([I<keywords> OFFSET, DELTA])
=s timestamps
=d
StoreUDPTimeSeqRecord element can be handy when computing end-to-end UDP packet
delays. The element embeds a timestamp and a sequence number into a packet and
adjusts the checksum of the UDP packet. Once the initial timestamp has been
placed into the payload of the UDP packet, a time difference can be computed
once a packet passes through another StoreUDPTimeSeqRecord element. The data can be
accessed by examining the packet payload (e.g., do a tcpdump and then do post
processing of the data). The element uses partial checksums to speed up the
processing. The element works with IPv4 and IPv6 packets. In case of IPv6,
it assumes that the next header field is UDP. If this is not the case, the
element will discard the packet.
Packet payload found after the UDP header. Note, the UDP payload must be at least
22 bytes long. The values will be stored in network byte order.
uint32_t seq_num
uint32_t initial_second
uint32_t initial_nano_second
uint32_t difference_second
uint32_t difference_nano_second
Keyword arguments are:
=over 2
=item OFFSET
Number of bytes to offset from the beginning of the packet where the IPv4/6 header can be found.
If raw Ethernet packets are fed into this element, then OFFSET needs to be 14.
=item DELTA
Determines which time values are set. If DELTA is false (the default), then the initial_second
and initial_nano_second values are set to the current time, and the difference values are set to 0.
If DELTA is true, then the initial values are left as is, and the difference values are set to
the difference between the current time and the packet's initial time.
=back
=e
src :: RatedSource(\<00>, LENGTH 22, RATE 1, LIMIT 100)
-> UDPIPEncap(10.0.1.1, 6667, 20.0.0.2, 6667)
-> EtherEncap(0x0800, 00:04:23:D0:93:63, 00:17:cb:0d:f8:db)
-> StoreUDPTimeSeqRecord(OFFSET 14, DELTA false)
-> DelayShaper(100msec)
-> StoreUDPTimeSeqRecord(OFFSET 14, DELTA true)
-> ToDump("dump.dmp");
*/
class StoreUDPTimeSeqRecord : public Element
{
public:
StoreUDPTimeSeqRecord() CLICK_COLD;
const char *class_name() const override { return "StoreUDPTimeSeqRecord"; }
const char *port_count() const override { return PORTS_1_1; }
void add_handlers() CLICK_COLD;
int configure(Vector<String> &conf, ErrorHandler *errh) CLICK_COLD;
Packet *simple_action(Packet *);
// packet data payload access struct
// Header | PDATA | rest of data
// This comes out to 22 bytes which will fit into the smallest Ethernet frame
struct PData
{
uint32_t seq_num;
uint32_t data[4];
};
private:
unsigned long _count;
bool _delta; // if true put in_timestamp else out_timestamp
uint32_t _offset; //how much to shift to get to the IPv4/v6 header
static String read_handler(Element *, void *) CLICK_COLD;
static int reset_handler(const String &, Element *, void *, ErrorHandler *);
};
CLICK_ENDDECLS
#endif