14128050dd51a888b8516e33930b39edc1e5f161
[senf.git] / Packets / MPEGDVBBundle / DTCPPacket.hh
1 // $Id$
2 //
3 // Copyright (C) 2007 
4 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
5 // Kompetenzzentrum NETwork research (NET)
6 //     David Wagner <david.wagner@fokus.fraunhofer.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23
24 #ifndef DTCPPACKET_HH_
25 #define DTCPPACKET_HH_
26
27 #include "../../Packets/Packets.hh"
28 #include "../../Packets/DefaultBundle/IPv4Packet.hh"
29 #include "../../Packets/DefaultBundle/IPv6Packet.hh"
30
31 namespace senf {
32     
33     //first we have to define some helpers
34     struct DTCPIPv4AddressListParser : public PacketParserBase {
35 #       include SENF_PARSER()        
36         SENF_PARSER_PRIVATE_FIELD ( num_of_fbips, UInt8Parser );
37         SENF_PARSER_PRIVATE_FIELD ( reserved ,    UInt8Parser );   //must be zero 
38         SENF_PARSER_VEC_N         ( fbiplist,     num_of_fbips, INet4AddressParser );
39
40         SENF_PARSER_FINALIZE(DTCPIPv4AddressListParser);
41     };
42         
43     struct DTCPIPv6AddressListParser : public PacketParserBase {
44 #       include SENF_PARSER()        
45         SENF_PARSER_PRIVATE_FIELD ( num_of_fbips, UInt8Parser );
46         SENF_PARSER_PRIVATE_FIELD ( reserved,     UInt8Parser );   //must be zero 
47         SENF_PARSER_VEC_N         ( fbiplist,     num_of_fbips, INet6AddressParser );
48
49         SENF_PARSER_FINALIZE(DTCPIPv6AddressListParser);
50     };
51
52     /** \brief Parse a DTCP packet
53
54         Parser implementing the DTCP packet according to RFC 3077
55         
56         \see DTCPPacketType
57      */
58     struct DTCPPacketParser : public PacketParserBase
59     {
60 #       include SENF_PARSER()
61
62         SENF_PARSER_BITFIELD         ( version_number,       4, unsigned );  // =1 according to rfc3077
63         SENF_PARSER_BITFIELD         ( command,              4, unsigned );  // 1=JOIN 2=LEAVE
64         SENF_PARSER_FIELD            ( interval,             UInt8Parser );  // 5 according to rfc3077
65         SENF_PARSER_FIELD            ( sequence_number,      UInt16Parser );
66         SENF_PARSER_PRIVATE_BITFIELD ( reserved,             3, unsigned );
67         SENF_PARSER_BITFIELD         ( receive_capable_feed, 1, bool );      // 0=send only, 1=receive_capable_feed
68         SENF_PARSER_BITFIELD         ( ip_version,           4, unsigned );  // 4=IPv4, 6=IPv6
69         SENF_PARSER_FIELD            ( tunnel_protocol,      UInt8Parser ); 
70                 /* Please consider the following comments on the implementation given in this class: 
71                  * 1. you could think of simply using SENF_PARSER_PRIVATE_VARIANT and List / Vectorparser like this:
72                  * SENF_PARSER_PRIVATE_VARIANT  ( fbiplist,             ip_version,
73          *                                                       (senf::VoidPacketParser) //ip_version=0
74          *                                                       (senf::VoidPacketParser) //1
75          *                                                       (senf::VoidPacketParser) //2
76          *                                                       (senf::VoidPacketParser) //3
77          *                                                       (senf::ListBParser< IPv4Packet, num_of_fbips>) //4 
78          *                                                       (senf::VoidPacketParser) //5
79          *                                                       (senf::ListBParser< IPv6Packet, num_of_fbips>) ); //6
80          * This can't work for two reasons: 
81          *              -SENF_PARSER_PRIVATE_VARIANT only accepts 6 templates in types but you have to start from 0.
82          *              -you NEVER can use templated Parsers in these macros since the macro-preprocessor won't recognize the <> brackets and will
83          *                      interpret the ","
84          * 
85          * The first problem is solved by using (actually inventing)  SENF_PARSER_VARIANT_TRANS which has the same limitations 
86          *              concerning the number of types but isn't limited to the values used. This is achieved by a translating function 
87          *              as you can see. 
88          * The second problem is solved by introducing Helper-Parser which cover both the list and the number field. By that no 
89          *              templates have to be used. 
90                 */
91
92                 struct ip_version_translator {
93                     static unsigned fromChooser(ip_version_t::value_type in) {
94                         switch (in) { 
95                         case 4: return 0;
96                         case 6: return 1;
97                         }
98                     }
99                     static ip_version_t::value_type toChooser(unsigned in) {
100                         switch (in) {
101                             case 0: return 4;
102                             case 1: return 6; 
103                         }
104                     }
105                 };
106     
107         SENF_PARSER_VARIANT_TRANS    ( fbiplist,             ip_version, ip_version_translator,
108                                                                  (senf::DTCPIPv4AddressListParser)        //IPv4 
109                                                                  (senf::DTCPIPv6AddressListParser) );     //IPv6
110
111         SENF_PARSER_FINALIZE(DTCPPacketParser);
112     };
113     
114     /** \brief DTCP packet
115         
116         \par Packet type (typedef):
117             \ref DTCPPacket
118
119         \par Fields:
120             \ref DTCPPacketParser
121
122         \ingroup protocolbundle_mpegdvb
123      */
124     struct DTCPPacketType
125         : public PacketTypeBase,
126           public PacketTypeMixin<DTCPPacketType>
127     {
128         typedef PacketTypeMixin<DTCPPacketType> mixin;
129         typedef ConcretePacket<DTCPPacketType> packet;
130         typedef DTCPPacketParser parser;
131     
132         using mixin::nextPacketRange;
133         using mixin::init;
134         using mixin::initSize;
135         
136         static void dump(packet p, std::ostream & os);
137     };
138     
139     /** \brief DTCP packet typedef */
140     typedef DTCPPacketType::packet DTCPPacket;
141 }
142
143 #endif /*DTCPPACKET_HH_*/