blob: 937aa8e2db60ea9f315720f34b0f582e154bbc97 [file] [log] [blame]
//
// Copyright (C) 2012 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef SHILL_NET_RTNL_MESSAGE_H_
#define SHILL_NET_RTNL_MESSAGE_H_
#include <unordered_map>
#include <vector>
#include <base/macros.h>
#include <base/stl_util.h>
#include "shill/net/byte_string.h"
#include "shill/net/ip_address.h"
#include "shill/net/shill_export.h"
struct rtattr;
namespace shill {
struct RTNLHeader;
class SHILL_EXPORT RTNLMessage {
public:
enum Type {
kTypeUnknown,
kTypeLink,
kTypeAddress,
kTypeRoute,
kTypeRule,
kTypeRdnss,
kTypeDnssl,
kTypeNeighbor,
};
enum Mode {
kModeUnknown,
kModeGet,
kModeAdd,
kModeDelete,
kModeQuery
};
struct LinkStatus {
LinkStatus()
: type(0),
flags(0),
change(0) {}
LinkStatus(unsigned int in_type,
unsigned int in_flags,
unsigned int in_change)
: type(in_type),
flags(in_flags),
change(in_change) {}
unsigned int type;
unsigned int flags;
unsigned int change;
};
struct AddressStatus {
AddressStatus()
: prefix_len(0),
flags(0),
scope(0) {}
AddressStatus(unsigned char prefix_len_in,
unsigned char flags_in,
unsigned char scope_in)
: prefix_len(prefix_len_in),
flags(flags_in),
scope(scope_in) {}
unsigned char prefix_len;
unsigned char flags;
unsigned char scope;
};
struct RouteStatus {
RouteStatus()
: dst_prefix(0),
src_prefix(0),
table(0),
protocol(0),
scope(0),
type(0),
flags(0) {}
RouteStatus(unsigned char dst_prefix_in,
unsigned char src_prefix_in,
unsigned char table_in,
unsigned char protocol_in,
unsigned char scope_in,
unsigned char type_in,
unsigned flags_in)
: dst_prefix(dst_prefix_in),
src_prefix(src_prefix_in),
table(table_in),
protocol(protocol_in),
scope(scope_in),
type(type_in),
flags(flags_in) {}
unsigned char dst_prefix;
unsigned char src_prefix;
unsigned char table;
unsigned char protocol;
unsigned char scope;
unsigned char type;
unsigned flags;
};
struct NeighborStatus {
NeighborStatus()
: state(0),
flags(0),
type(0) {}
NeighborStatus(uint16_t state_in,
uint8_t flags_in,
uint8_t type_in)
: state(state_in),
flags(flags_in),
type(type_in) {}
uint16_t state;
uint8_t flags;
uint8_t type;
};
struct RdnssOption {
RdnssOption()
: lifetime(0) {}
RdnssOption(uint32_t lifetime_in,
std::vector<IPAddress> addresses_in)
: lifetime(lifetime_in),
addresses(addresses_in) {}
uint32_t lifetime;
std::vector<IPAddress> addresses;
};
// Empty constructor
RTNLMessage();
// Build an RTNL message from arguments
RTNLMessage(Type type,
Mode mode,
unsigned int flags,
uint32_t seq,
uint32_t pid,
int interface_index,
IPAddress::Family family);
// Parse an RTNL message. Returns true on success.
bool Decode(const ByteString& data);
// Encode an RTNL message. Returns empty ByteString on failure.
ByteString Encode() const;
// Reset all fields.
void Reset();
// Getters and setters
Type type() const { return type_; }
Mode mode() const { return mode_; }
uint16_t flags() const { return flags_; }
uint32_t seq() const { return seq_; }
void set_seq(uint32_t seq) { seq_ = seq; }
uint32_t pid() const { return pid_; }
uint32_t interface_index() const { return interface_index_; }
IPAddress::Family family() const { return family_; }
const LinkStatus& link_status() const { return link_status_; }
void set_link_status(const LinkStatus& link_status) {
link_status_ = link_status;
}
const AddressStatus& address_status() const { return address_status_; }
void set_address_status(const AddressStatus& address_status) {
address_status_ = address_status;
}
const RouteStatus& route_status() const { return route_status_; }
void set_route_status(const RouteStatus& route_status) {
route_status_ = route_status;
}
const RdnssOption& rdnss_option() const { return rdnss_option_; }
void set_rdnss_option(const RdnssOption& rdnss_option) {
rdnss_option_ = rdnss_option;
}
const NeighborStatus& neighbor_status() const { return neighbor_status_; }
void set_neighbor_status(const NeighborStatus& neighbor_status) {
neighbor_status_ = neighbor_status;
}
// GLint hates "unsigned short", and I don't blame it, but that's the
// type that's used in the system headers. Use uint16_t instead and hope
// that the conversion never ends up truncating on some strange platform.
bool HasAttribute(uint16_t attr) const {
return base::ContainsKey(attributes_, attr);
}
const ByteString GetAttribute(uint16_t attr) const {
return HasAttribute(attr) ?
attributes_.find(attr)->second : ByteString(0);
}
void SetAttribute(uint16_t attr, const ByteString& val) {
attributes_[attr] = val;
}
private:
SHILL_PRIVATE bool DecodeInternal(const ByteString& msg);
SHILL_PRIVATE bool DecodeLink(const RTNLHeader* hdr,
Mode mode,
rtattr** attr_data,
int* attr_length);
SHILL_PRIVATE bool DecodeAddress(const RTNLHeader* hdr,
Mode mode,
rtattr** attr_data,
int* attr_length);
SHILL_PRIVATE bool DecodeRoute(const RTNLHeader* hdr,
Mode mode,
rtattr** attr_data,
int* attr_length);
SHILL_PRIVATE bool DecodeRule(const RTNLHeader* hdr,
Mode mode,
rtattr** attr_data,
int* attr_length);
SHILL_PRIVATE bool DecodeNdUserOption(const RTNLHeader* hdr,
Mode mode,
rtattr** attr_data,
int* attr_length);
SHILL_PRIVATE bool ParseRdnssOption(const uint8_t* data,
int length,
uint32_t lifetime);
SHILL_PRIVATE bool DecodeNeighbor(const RTNLHeader* hdr,
Mode mode,
rtattr** attr_data,
int* attr_length);
SHILL_PRIVATE bool EncodeLink(RTNLHeader* hdr) const;
SHILL_PRIVATE bool EncodeAddress(RTNLHeader* hdr) const;
SHILL_PRIVATE bool EncodeRoute(RTNLHeader* hdr) const;
SHILL_PRIVATE bool EncodeNeighbor(RTNLHeader* hdr) const;
Type type_;
Mode mode_;
uint16_t flags_;
uint32_t seq_;
uint32_t pid_;
unsigned int interface_index_;
IPAddress::Family family_;
LinkStatus link_status_;
AddressStatus address_status_;
RouteStatus route_status_;
NeighborStatus neighbor_status_;
RdnssOption rdnss_option_;
std::unordered_map<uint16_t, ByteString> attributes_;
DISALLOW_COPY_AND_ASSIGN(RTNLMessage);
};
} // namespace shill
#endif // SHILL_NET_RTNL_MESSAGE_H_