Home | History | Annotate | Download | only in net
      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 {
     57     LinkStatus()
     58         : type(0),
     59           flags(0),
     60           change(0) {}
     61     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 {
     73     AddressStatus()
     74         : prefix_len(0),
     75           flags(0),
     76           scope(0) {}
     77     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 {
     89     RouteStatus()
     90         : dst_prefix(0),
     91           src_prefix(0),
     92           table(0),
     93           protocol(0),
     94           scope(0),
     95           type(0),
     96           flags(0) {}
     97     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 {
    121     NeighborStatus()
    122         : state(0),
    123           flags(0),
    124           type(0) {}
    125     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 {
    137     RdnssOption()
    138         : lifetime(0) {}
    139     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
    166   Type type() const { return type_; }
    167   Mode mode() const { return mode_; }
    168   uint16_t flags() const { return flags_; }
    169   uint32_t seq() const { return seq_; }
    170   void set_seq(uint32_t seq) { seq_ = seq; }
    171   uint32_t pid() const { return pid_; }
    172   uint32_t interface_index() const { return interface_index_; }
    173   IPAddress::Family family() const { return family_; }
    174 
    175   const LinkStatus& link_status() const { return link_status_; }
    176   void set_link_status(const LinkStatus& link_status) {
    177     link_status_ = link_status;
    178   }
    179   const AddressStatus& address_status() const { return address_status_; }
    180   void set_address_status(const AddressStatus& address_status) {
    181     address_status_ = address_status;
    182   }
    183   const RouteStatus& route_status() const { return route_status_; }
    184   void set_route_status(const RouteStatus& route_status) {
    185     route_status_ = route_status;
    186   }
    187   const RdnssOption& rdnss_option() const { return rdnss_option_; }
    188   void set_rdnss_option(const RdnssOption& rdnss_option) {
    189     rdnss_option_ = rdnss_option;
    190   }
    191   const NeighborStatus& neighbor_status() const { return 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.
    198   bool HasAttribute(uint16_t attr) const {
    199     return ContainsKey(attributes_, attr);
    200   }
    201   const ByteString GetAttribute(uint16_t attr) const {
    202     return HasAttribute(attr) ?
    203         attributes_.find(attr)->second : ByteString(0);
    204   }
    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