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