5a114a5b061c961e11c48dac79c6125f504d394d
[senf.git] / Socket / LLAddressing.hh
1 // $Id$
2 //
3 // Copyright (C) 2006 
4 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
5 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
6 //     Stefan Bund <stefan.bund@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 /** \file
24     \brief LLSocketAddress and LLAddressingPolicy public header
25  */
26
27 #ifndef HH_LLAddressing_
28 #define HH_LLAddressing_ 1
29
30 // Custom includes
31 #include <boost/range/iterator_range.hpp>
32 #include <boost/utility/enable_if.hpp>
33 #include <boost/type_traits.hpp>
34
35 #include <sys/socket.h>
36 #include <netpacket/packet.h>
37
38 #include "SocketPolicy.hh"
39 #include "FileHandle.hh"
40 #include "GenericAddressingPolicy.hh"
41
42 //#include "LLAddressing.mpp"
43 #include "LLAddressing.ih"
44 ///////////////////////////////hh.p////////////////////////////////////////
45
46 namespace senf {
47
48     /// \addtogroup addr_group
49     /// @{
50
51     /** \brief Link local address
52
53         LLSocketAddress wrapps the standard sockaddr_ll datatype.
54
55         \todo I don't think the current implementation is
56             sensible. I'll have to reimplement this class probably
57             from scratch.
58
59         \implementation The class relies uses a very flexible
60             'ForwardRange' representation for a raw ll
61             address (See <a
62             href="http://www.boost.org/libs/range/index.html">Boost.Range</a>).
63             This representation allows zero-copy imlementations of
64             many operations, however it is probably not worth the
65             effort since the ll address is restricted to a max of 8
66             bytes. Therefore this will be changed and the concrete
67             implementation is not documented very well ...
68      */
69     class LLSocketAddress
70     {
71     public:
72         // Right now we use an arbitrary ForwardRange (see Boost.Range)
73         // as the representation for a hardware address. The restrictions
74         // for the range are:
75         // a) the range must never be larger than 8 elements
76         // b) the value_type must be convertible to unsigend char
77         // and really we need only a single-pass range.
78         //
79         // Since a hardware address is so short (a maximum of 8
80         // bytes), in the aftermath I think a simple container holding
81         // a maximum of 8 unsigned chars (e.g. Boost.Array with
82         // additional length parameter) will be much simpler and
83         // probably even more efficient. This should have a conversion
84         // constructor from an arbitrary ForwardRange to make it
85         // compatible e.g. with the Packet library.
86         //
87         // However, since I have implemented it already as it is now,
88         // I'll leave it as it is ...
89
90         typedef boost::iterator_range<unsigned char const *> LLAddress;
91         
92         LLSocketAddress();
93         // And this is for bind
94         explicit LLSocketAddress(unsigned protocol, std::string interface="");
95         explicit LLSocketAddress(std::string interface);
96         // This is for sending packets ..
97         // We must use enable_if here, so this constructor will not hide
98         // above constructor if passed a plain int or short argument
99         template <class ForwardRange>
100         explicit LLSocketAddress(ForwardRange const & address, std::string interface="",
101                                  typename boost::enable_if_c<! boost::is_integral<ForwardRange>::value >::type * = 0);
102
103         void clear();
104
105         unsigned protocol() const;
106         std::string interface() const;
107         unsigned arptype() const;
108         unsigned pkttype() const;
109         LLAddress address() const;
110
111         // The mutating interface is purposely restricted to allow only
112         // changing those members, which are sensible to be changed.
113
114         template <class ForwardRange>
115         void address(ForwardRange const & address);
116         void interface(std::string interface);
117         void protocol(unsigned protocol);
118
119         struct sockaddr * sockaddr_p();
120         struct sockaddr const * sockaddr_p() const;
121         unsigned sockaddr_len() const;
122
123     private:
124         struct ::sockaddr_ll addr_;
125     };
126
127     /** \brief
128         \related LLSocketAddress
129      */
130     detail::LLAddressFromStringRange llAddress(std::string address);
131
132     // The enable_if condition here allows only for classes as range.
133     // However, excluding zero-terminated strings (which we want to
134     // pass to above) I cannot think of a non-class ForwardRange
135     // except for academic cases
136     // STOP: ... how about std::vector<...>::iterator ?? isn't that a ..pointer ?
137     /** \brief Convert raw link-local address into printable form
138         \related LLSocketAddress
139      */
140     template <class ForwardRange>
141     std::string llAddress(ForwardRange const & address,
142                           typename boost::enable_if< boost::is_class<ForwardRange> >::type * = 0);
143
144     /** \brief Signal invalid link local address syntax
145         \related LLSocketAddress
146      */
147     struct InvalidLLSocketAddressException : public std::exception
148     { char const * what() const throw() { return "invalid ll address"; } };
149
150     /// @}
151
152     /// \addtogroup policy_impl_group
153     /// @{
154
155     /** \brief Addressing policy supporting link-local addressing
156
157         \par Address Type:
158             LLSocketAddress
159         
160         This addressing policy implements generic link local
161         addressing. The predominant type of link local addressing is
162         Ethernet addressing.
163
164         Since the link layer does not support the notion of
165         connections, link local addresses do not support the connect()
166         or peer() members.
167      */
168     struct LLAddressingPolicy
169         : public AddressingPolicyBase,
170           private GenericAddressingPolicy<LLSocketAddress>
171     {
172         typedef LLSocketAddress Address;
173
174         using GenericAddressingPolicy<LLSocketAddress>::local;
175         using GenericAddressingPolicy<LLSocketAddress>::bind;
176     };
177
178     /// @}
179 }
180
181 ///////////////////////////////hh.e////////////////////////////////////////
182 #include "LLAddressing.cci"
183 #include "LLAddressing.ct"
184 #include "LLAddressing.cti"
185 //#include "LLAddressing.mpp"
186 #endif
187
188 \f
189 // Local Variables:
190 // mode: c++
191 // c-file-style: "senf"
192 // End: