blob: 6dcca9862138d9aeef3eb989c40ada1722f7cb29 [file] [log] [blame]
// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SHILL_RTNL_MESSAGE_H_
#define SHILL_RTNL_MESSAGE_H_
#include <unordered_map>
#include <vector>
#include <base/basictypes.h>
#include <base/stl_util.h>
#include "shill/byte_string.h"
#include "shill/ip_address.h"
struct rtattr;
namespace shill {
struct RTNLHeader;
class RTNLMessage {
public:
enum Type {
kTypeUnknown,
kTypeLink,
kTypeAddress,
kTypeRoute,
kTypeRdnss,
kTypeDnssl
};
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 char 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 char flags;
};
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;
}
// 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 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:
bool DecodeInternal(const ByteString &msg);
bool DecodeLink(const RTNLHeader *hdr,
Mode mode,
rtattr **attr_data,
int *attr_length);
bool DecodeAddress(const RTNLHeader *hdr,
Mode mode,
rtattr **attr_data,
int *attr_length);
bool DecodeRoute(const RTNLHeader *hdr,
Mode mode,
rtattr **attr_data,
int *attr_length);
bool DecodeNdUserOption(const RTNLHeader *hdr,
Mode mode,
rtattr **attr_data,
int *attr_length);
bool ParseRdnssOption(const uint8_t *data,
int length,
uint32_t lifetime);
bool EncodeLink(RTNLHeader *hdr) const;
bool EncodeAddress(RTNLHeader *hdr) const;
bool EncodeRoute(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_;
RdnssOption rdnss_option_;
std::unordered_map<uint16_t, ByteString> attributes_;
DISALLOW_COPY_AND_ASSIGN(RTNLMessage);
};
} // namespace shill
#endif // SHILL_RTNL_MESSAGE_H_