Renamed namespaces satcom::lib and satcom::pkf to senf
[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 #ifndef HH_LLAddressing_
24 #define HH_LLAddressing_ 1
25
26 // Custom includes
27 #include <boost/range/iterator_range.hpp>
28 #include <boost/utility/enable_if.hpp>
29 #include <boost/type_traits.hpp>
30
31 #include <sys/socket.h>
32 #include <netpacket/packet.h>
33
34 #include "SocketPolicy.hh"
35 #include "FileHandle.hh"
36 #include "GenericAddressingPolicy.hh"
37
38 //#include "LLAddressing.mpp"
39 #include "LLAddressing.ih"
40 ///////////////////////////////hh.p////////////////////////////////////////
41
42 namespace senf {
43
44
45     class LLSocketAddress
46     {
47     public:
48         // Right now we use an arbitrary ForwardRange (see Boost.Range)
49         // as the representation for a hardware address. The restrictions
50         // for the range are:
51         // a) the range must never be larger than 8 elements
52         // b) the value_type must be convertible to unsigend char
53         // and really we need only a single-pass range.
54         //
55         // Since a hardware address is so short (a maximum of 8
56         // bytes), in the aftermath I think a simple container holding
57         // a maximum of 8 unsigned chars (e.g. Boost.Array with
58         // additional length parameter) will be much simpler and
59         // probably even more efficient. This should have a conversion
60         // constructor from an arbitrary ForwardRange to make it
61         // compatible e.g. with the Packet library.
62         //
63         // However, since I have implemented it already as it is now,
64         // I'll leave it as it is ...
65
66         typedef boost::iterator_range<unsigned char const *> LLAddress;
67         
68         LLSocketAddress();
69         // And this is for bind
70         explicit LLSocketAddress(unsigned protocol, std::string interface="");
71         explicit LLSocketAddress(std::string interface);
72         // This is for sending packets ..
73         // We must use enable_if here, so this constructor will not hide
74         // above constructor if passed a plain int or short argument
75         template <class ForwardRange>
76         explicit LLSocketAddress(ForwardRange const & address, std::string interface="",
77                                  typename boost::enable_if_c<! boost::is_integral<ForwardRange>::value >::type * = 0);
78
79         void clear();
80
81         unsigned protocol() const;
82         std::string interface() const;
83         unsigned arptype() const;
84         unsigned pkttype() const;
85         LLAddress address() const;
86
87         // The mutating interface is purposely restricted to allow only
88         // changing those members, which are sensible to be changed.
89
90         template <class ForwardRange>
91         void address(ForwardRange const & address);
92         void interface(std::string interface);
93         void protocol(unsigned protocol);
94
95         struct sockaddr * sockaddr_p();
96         struct sockaddr const * sockaddr_p() const;
97         unsigned sockaddr_len() const;
98
99     private:
100         struct ::sockaddr_ll addr_;
101     };
102
103     detail::LLAddressFromStringRange llAddress(std::string address);
104     // The enable_if condition here allows only for classes as range.
105     // However, excluding zero-terminated strings (which we want to
106     // pass to above) I cannot think of a non-class ForwardRange
107     // except for academic cases
108     template <class ForwardRange>
109     std::string llAddress(ForwardRange const & address,
110                           typename boost::enable_if< boost::is_class<ForwardRange> >::type * = 0);
111
112     class LLAddressingPolicy
113         : public AddressingPolicyBase,
114           private GenericAddressingPolicy<LLSocketAddress>
115     {
116     public:
117         typedef LLSocketAddress Address;
118
119         using GenericAddressingPolicy<LLSocketAddress>::local;
120         using GenericAddressingPolicy<LLSocketAddress>::bind;
121     };
122
123     struct InvalidLLSocketAddressException : public std::exception
124     { char const * what() const throw() { return "invalid ll address"; } };
125 }
126
127 ///////////////////////////////hh.e////////////////////////////////////////
128 #include "LLAddressing.cci"
129 #include "LLAddressing.ct"
130 #include "LLAddressing.cti"
131 //#include "LLAddressing.mpp"
132 #endif
133
134 \f
135 // Local Variables:
136 // mode: c++
137 // c-file-style: "senf"
138 // End: