fixed small documentation typo
[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 wraps 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 implementations 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 unsigned 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 #       ifndef DOXYGEN
100         template <class ForwardRange>
101         explicit LLSocketAddress(ForwardRange const & address, std::string interface="",
102                                  typename boost::enable_if_c<! boost::is_integral<ForwardRange>::value >::type * = 0);
103 #       else
104         template <class ForwardRange>
105         explicit LLSocketAddress(ForwardRange const & address, std::string interface="");
106 #       endif
107
108         void clear();
109
110         unsigned protocol() const;
111         std::string interface() const;
112         unsigned arptype() const;
113         unsigned pkttype() const;
114         LLAddress address() const;
115
116         // The mutating interface is purposely restricted to allow only
117         // changing those members, which are sensible to be changed.
118
119         template <class ForwardRange>
120         void address(ForwardRange const & address);
121         void interface(std::string interface);
122         void protocol(unsigned protocol);
123
124         struct sockaddr * sockaddr_p();
125         struct sockaddr const * sockaddr_p() const;
126         unsigned sockaddr_len() const;
127
128     private:
129         struct ::sockaddr_ll addr_;
130     };
131
132     /** \brief
133         \related LLSocketAddress
134      */
135     detail::LLAddressFromStringRange llAddress(std::string address);
136
137     // The enable_if condition here allows only for classes as range.
138     // However, excluding zero-terminated strings (which we want to
139     // pass to above) I cannot think of a non-class ForwardRange
140     // except for academic cases
141     // STOP: ... how about std::vector<...>::iterator ?? isn't that a ..pointer ?
142     /** \brief Convert raw link-local address into printable form
143         \related LLSocketAddress
144      */
145     template <class ForwardRange>
146     std::string llAddress(ForwardRange const & address,
147                           typename boost::enable_if< boost::is_class<ForwardRange> >::type * = 0);
148
149     /** \brief Signal invalid link local address syntax
150         \related LLSocketAddress
151      */
152     struct InvalidLLSocketAddressException : public std::exception
153     { char const * what() const throw() { return "invalid ll address"; } };
154
155     /// @}
156
157     /// \addtogroup policy_impl_group
158     /// @{
159
160     /** \brief Addressing policy supporting link-local addressing
161
162         \par Address Type:
163             LLSocketAddress
164
165         This addressing policy implements generic link local
166         addressing. The predominant type of link local addressing is
167         Ethernet addressing.
168
169         Since the link layer does not support the notion of
170         connections, link local addresses do not support the connect()
171         or peer() members.
172      */
173     struct LLAddressingPolicy
174         : public AddressingPolicyBase,
175           private GenericAddressingPolicy<LLSocketAddress>
176     {
177         typedef LLSocketAddress Address;
178
179         using GenericAddressingPolicy<LLSocketAddress>::local;
180         using GenericAddressingPolicy<LLSocketAddress>::bind;
181     };
182
183     /// @}
184 }
185
186 ///////////////////////////////hh.e////////////////////////////////////////
187 #include "LLAddressing.cci"
188 #include "LLAddressing.ct"
189 #include "LLAddressing.cti"
190 //#include "LLAddressing.mpp"
191 #endif
192
193 \f
194 // Local Variables:
195 // mode: c++
196 // fill-column: 100
197 // c-file-style: "senf"
198 // indent-tabs-mode: nil
199 // ispell-local-dictionary: "american"
200 // compile-command: "scons -u test"
201 // comment-column: 40
202 // End: