258 lines
7.7 KiB
C++
258 lines
7.7 KiB
C++
//
|
|
// 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,
|
|
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 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 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 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 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_
|