Newer
Older
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
// Copyright (C) 2007
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum NETwork research (NET)
// David Wagner <david.wagner@fokus.fraunhofer.de>
//
#ifndef DTCPPACKET_HH_
#define DTCPPACKET_HH_
#include "../../Packets/Packets.hh"
#include "../../Packets/DefaultBundle/IpV4Packet.hh"
#include "../../Packets/DefaultBundle/IpV6Packet.hh"
namespace senf {
//first we have to define some helpers
struct DTCPIpV4AddressListParser : public PacketParserBase {
# include SENF_PARSER()
SENF_PARSER_PRIVATE_FIELD ( num_of_fbips, Parse_UInt8 );
SENF_PARSER_PRIVATE_FIELD ( reserved , Parse_UInt8 ); //must be zero
SENF_PARSER_VEC_N ( fbiplist, num_of_fbips, Parse_INet4Address );
SENF_PARSER_FINALIZE(DTCPIpV4AddressListParser);
};
struct DTCPIpV6AddressListParser : public PacketParserBase {
# include SENF_PARSER()
SENF_PARSER_PRIVATE_FIELD ( num_of_fbips, Parse_UInt8 );
SENF_PARSER_PRIVATE_FIELD ( reserved, Parse_UInt8 ); //must be zero
SENF_PARSER_VEC_N ( fbiplist, num_of_fbips, Parse_INet6Address );
SENF_PARSER_FINALIZE(DTCPIpV6AddressListParser);
};
/** \brief Parse a DTCP packet
Parser implementing the DTCP packet according to RFC 3077
\see DTCPPacketType
*/
struct Parse_DTCPPacket : public PacketParserBase
{
# include SENF_PARSER()
SENF_PARSER_BITFIELD ( version_number, 4, unsigned ); // =1 according to rfc3077
SENF_PARSER_BITFIELD ( command, 4, unsigned ); // 1=JOIN 2=LEAVE
SENF_PARSER_FIELD ( interval, Parse_UInt8 ); // 5 according to rfc3077
SENF_PARSER_FIELD ( sequence_number, Parse_UInt16 );
SENF_PARSER_PRIVATE_BITFIELD ( reserved, 3, unsigned );
SENF_PARSER_BITFIELD ( receive_capable_feed, 1, bool ); // 0=send only, 1=receive_capable_feed
SENF_PARSER_BITFIELD ( ip_version, 4, unsigned ); // 4=IPv4, 6=IPv6
SENF_PARSER_FIELD ( tunnel_protocol, Parse_UInt8 );
/* Please consider the following comments on the implementation given in this class:
* 1. you could think of simply using SENF_PARSER_PRIVATE_VARIANT and List / Vectorparser like this:
* SENF_PARSER_PRIVATE_VARIANT ( fbiplist, ip_version,
* (senf::VoidPacketParser) //ip_version=0
* (senf::VoidPacketParser) //1
* (senf::VoidPacketParser) //2
* (senf::VoidPacketParser) //3
* (senf::Parse_ListB< IpV4Packet, num_of_fbips>) //4
* (senf::VoidPacketParser) //5
* (senf::Parse_ListB< IpV6Packet, num_of_fbips>) ); //6
* This can't work for two reasons:
* -SENF_PARSER_PRIVATE_VARIANT only accepts 6 templates in types but you have to start from 0.
* -you NEVER can use templated Parsers in these macros since the macro-preprocessor won't recognize the <> brackets and will
* interpret the ","
*
* The first problem is solved by using (actually inventing) SENF_PARSER_VARIANT_TRANS which has the same limitations
* concerning the number of types but isn't limited to the values used. This is achieved by a translating function
* as you can see.
* The second problem is solved by introducing Helper-Parser which cover both the list and the number field. By that no
* templates have to be used.
*/
struct ip_version_translator {
static unsigned fromChooser(ip_version_t::value_type in) {
switch (in) {
case 4: return 0;
case 6: return 1;
}
}
static ip_version_t::value_type toChooser(unsigned in) {
switch (in) {
case 0: return 4;
case 1: return 6;
}
}
};
SENF_PARSER_VARIANT_TRANS ( fbiplist, ip_version, ip_version_translator,
(senf::DTCPIpV4AddressListParser) //IPv4
(senf::DTCPIpV6AddressListParser) ); //IPv6
SENF_PARSER_FINALIZE(Parse_DTCPPacket);
};
/** \brief DTCP packet
\par Packet type (typedef):
\ref DTCPPacket
\par Fields:
\ref Parse_DTCPPacket
\ingroup protocolbundle_mpegdvb
*/
struct DTCPPacketType
: public PacketTypeBase,
public PacketTypeMixin<DTCPPacketType>
{
typedef PacketTypeMixin<DTCPPacketType> mixin;
typedef ConcretePacket<DTCPPacketType> packet;
typedef Parse_DTCPPacket parser;
using mixin::nextPacketRange;
using mixin::init;
using mixin::initSize;
static void dump(packet p, std::ostream & os);
};
/** \brief DTCP packet typedef */
typedef DTCPPacketType::packet DTCPPacket;
}
#endif /*DTCPPACKET_HH_*/