• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (C) 2012 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #ifndef SHILL_NET_RTNL_MESSAGE_H_
18 #define SHILL_NET_RTNL_MESSAGE_H_
19 
20 #include <unordered_map>
21 #include <vector>
22 
23 #include <base/macros.h>
24 #include <base/stl_util.h>
25 
26 #include "shill/net/byte_string.h"
27 #include "shill/net/ip_address.h"
28 #include "shill/net/shill_export.h"
29 
30 struct rtattr;
31 
32 namespace shill {
33 
34 struct RTNLHeader;
35 
36 class SHILL_EXPORT RTNLMessage {
37  public:
38   enum Type {
39     kTypeUnknown,
40     kTypeLink,
41     kTypeAddress,
42     kTypeRoute,
43     kTypeRdnss,
44     kTypeDnssl,
45     kTypeNeighbor,
46   };
47 
48   enum Mode {
49     kModeUnknown,
50     kModeGet,
51     kModeAdd,
52     kModeDelete,
53     kModeQuery
54   };
55 
56   struct LinkStatus {
LinkStatusLinkStatus57     LinkStatus()
58         : type(0),
59           flags(0),
60           change(0) {}
LinkStatusLinkStatus61     LinkStatus(unsigned int in_type,
62                unsigned int in_flags,
63                unsigned int in_change)
64         : type(in_type),
65           flags(in_flags),
66           change(in_change) {}
67     unsigned int type;
68     unsigned int flags;
69     unsigned int change;
70   };
71 
72   struct AddressStatus {
AddressStatusAddressStatus73     AddressStatus()
74         : prefix_len(0),
75           flags(0),
76           scope(0) {}
AddressStatusAddressStatus77     AddressStatus(unsigned char prefix_len_in,
78                   unsigned char flags_in,
79                   unsigned char scope_in)
80         : prefix_len(prefix_len_in),
81           flags(flags_in),
82           scope(scope_in) {}
83     unsigned char prefix_len;
84     unsigned char flags;
85     unsigned char scope;
86   };
87 
88   struct RouteStatus {
RouteStatusRouteStatus89     RouteStatus()
90         : dst_prefix(0),
91           src_prefix(0),
92           table(0),
93           protocol(0),
94           scope(0),
95           type(0),
96           flags(0) {}
RouteStatusRouteStatus97     RouteStatus(unsigned char dst_prefix_in,
98                 unsigned char src_prefix_in,
99                 unsigned char table_in,
100                 unsigned char protocol_in,
101                 unsigned char scope_in,
102                 unsigned char type_in,
103                 unsigned char flags_in)
104         : dst_prefix(dst_prefix_in),
105           src_prefix(src_prefix_in),
106           table(table_in),
107           protocol(protocol_in),
108           scope(scope_in),
109           type(type_in),
110           flags(flags_in) {}
111     unsigned char dst_prefix;
112     unsigned char src_prefix;
113     unsigned char table;
114     unsigned char protocol;
115     unsigned char scope;
116     unsigned char type;
117     unsigned char flags;
118   };
119 
120   struct NeighborStatus {
NeighborStatusNeighborStatus121     NeighborStatus()
122         : state(0),
123           flags(0),
124           type(0) {}
NeighborStatusNeighborStatus125     NeighborStatus(uint16_t state_in,
126                    uint8_t flags_in,
127                    uint8_t type_in)
128         : state(state_in),
129           flags(flags_in),
130           type(type_in) {}
131     uint16_t state;
132     uint8_t flags;
133     uint8_t type;
134   };
135 
136   struct RdnssOption {
RdnssOptionRdnssOption137     RdnssOption()
138         : lifetime(0) {}
RdnssOptionRdnssOption139     RdnssOption(uint32_t lifetime_in,
140                 std::vector<IPAddress> addresses_in)
141         : lifetime(lifetime_in),
142           addresses(addresses_in) {}
143     uint32_t lifetime;
144     std::vector<IPAddress> addresses;
145   };
146 
147   // Empty constructor
148   RTNLMessage();
149   // Build an RTNL message from arguments
150   RTNLMessage(Type type,
151               Mode mode,
152               unsigned int flags,
153               uint32_t seq,
154               uint32_t pid,
155               int interface_index,
156               IPAddress::Family family);
157 
158   // Parse an RTNL message.  Returns true on success.
159   bool Decode(const ByteString& data);
160   // Encode an RTNL message.  Returns empty ByteString on failure.
161   ByteString Encode() const;
162   // Reset all fields.
163   void Reset();
164 
165   // Getters and setters
type()166   Type type() const { return type_; }
mode()167   Mode mode() const { return mode_; }
flags()168   uint16_t flags() const { return flags_; }
seq()169   uint32_t seq() const { return seq_; }
set_seq(uint32_t seq)170   void set_seq(uint32_t seq) { seq_ = seq; }
pid()171   uint32_t pid() const { return pid_; }
interface_index()172   uint32_t interface_index() const { return interface_index_; }
family()173   IPAddress::Family family() const { return family_; }
174 
link_status()175   const LinkStatus& link_status() const { return link_status_; }
set_link_status(const LinkStatus & link_status)176   void set_link_status(const LinkStatus& link_status) {
177     link_status_ = link_status;
178   }
address_status()179   const AddressStatus& address_status() const { return address_status_; }
set_address_status(const AddressStatus & address_status)180   void set_address_status(const AddressStatus& address_status) {
181     address_status_ = address_status;
182   }
route_status()183   const RouteStatus& route_status() const { return route_status_; }
set_route_status(const RouteStatus & route_status)184   void set_route_status(const RouteStatus& route_status) {
185     route_status_ = route_status;
186   }
rdnss_option()187   const RdnssOption& rdnss_option() const { return rdnss_option_; }
set_rdnss_option(const RdnssOption & rdnss_option)188   void set_rdnss_option(const RdnssOption& rdnss_option) {
189     rdnss_option_ = rdnss_option;
190   }
neighbor_status()191   const NeighborStatus& neighbor_status() const { return neighbor_status_; }
set_neighbor_status(const NeighborStatus & neighbor_status)192   void set_neighbor_status(const NeighborStatus& neighbor_status) {
193     neighbor_status_ = neighbor_status;
194   }
195   // GLint hates "unsigned short", and I don't blame it, but that's the
196   // type that's used in the system headers.  Use uint16_t instead and hope
197   // that the conversion never ends up truncating on some strange platform.
HasAttribute(uint16_t attr)198   bool HasAttribute(uint16_t attr) const {
199     return ContainsKey(attributes_, attr);
200   }
GetAttribute(uint16_t attr)201   const ByteString GetAttribute(uint16_t attr) const {
202     return HasAttribute(attr) ?
203         attributes_.find(attr)->second : ByteString(0);
204   }
SetAttribute(uint16_t attr,const ByteString & val)205   void SetAttribute(uint16_t attr, const ByteString& val) {
206     attributes_[attr] = val;
207   }
208 
209  private:
210   SHILL_PRIVATE bool DecodeInternal(const ByteString& msg);
211   SHILL_PRIVATE bool DecodeLink(const RTNLHeader* hdr,
212                                 Mode mode,
213                                 rtattr** attr_data,
214                                 int* attr_length);
215   SHILL_PRIVATE bool DecodeAddress(const RTNLHeader* hdr,
216                                    Mode mode,
217                                    rtattr** attr_data,
218                                    int* attr_length);
219   SHILL_PRIVATE bool DecodeRoute(const RTNLHeader* hdr,
220                                  Mode mode,
221                                  rtattr** attr_data,
222                                  int* attr_length);
223   SHILL_PRIVATE bool DecodeNdUserOption(const RTNLHeader* hdr,
224                                         Mode mode,
225                                         rtattr** attr_data,
226                                         int* attr_length);
227   SHILL_PRIVATE bool ParseRdnssOption(const uint8_t* data,
228                                       int length,
229                                       uint32_t lifetime);
230   SHILL_PRIVATE bool DecodeNeighbor(const RTNLHeader* hdr,
231                                     Mode mode,
232                                     rtattr** attr_data,
233                                     int* attr_length);
234   SHILL_PRIVATE bool EncodeLink(RTNLHeader* hdr) const;
235   SHILL_PRIVATE bool EncodeAddress(RTNLHeader* hdr) const;
236   SHILL_PRIVATE bool EncodeRoute(RTNLHeader* hdr) const;
237   SHILL_PRIVATE bool EncodeNeighbor(RTNLHeader* hdr) const;
238 
239   Type type_;
240   Mode mode_;
241   uint16_t flags_;
242   uint32_t seq_;
243   uint32_t pid_;
244   unsigned int interface_index_;
245   IPAddress::Family family_;
246   LinkStatus link_status_;
247   AddressStatus address_status_;
248   RouteStatus route_status_;
249   NeighborStatus neighbor_status_;
250   RdnssOption rdnss_option_;
251   std::unordered_map<uint16_t, ByteString> attributes_;
252 
253   DISALLOW_COPY_AND_ASSIGN(RTNLMessage);
254 };
255 
256 }  // namespace shill
257 
258 #endif  // SHILL_NET_RTNL_MESSAGE_H_
259