blob: a7eb8e8a85aadb0f815e2fc42f613c60519b1f2e [file] [log] [blame]
Paul Stewartf748a362012-03-07 12:01:20 -08001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Paul Stewartdd7df792011-07-15 11:09:50 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef SHILL_RTNL_MESSAGE_
6#define SHILL_RTNL_MESSAGE_
7
8#include <base/basictypes.h>
Ben Chana0ddf462014-02-06 11:32:42 -08009#include <base/containers/hash_tables.h>
Eric Shienbrood3e20a232012-02-16 11:35:56 -050010#include <base/stl_util.h>
Paul Stewartdd7df792011-07-15 11:09:50 -070011
12#include "shill/byte_string.h"
13#include "shill/ip_address.h"
14
15struct rtattr;
16
17namespace shill {
18
19struct RTNLHeader;
20
21class RTNLMessage {
22 public:
Paul Stewart9a908082011-08-31 12:18:48 -070023 enum Type {
24 kTypeUnknown,
25 kTypeLink,
26 kTypeAddress,
27 kTypeRoute
Paul Stewartdd7df792011-07-15 11:09:50 -070028 };
29
Paul Stewart9a908082011-08-31 12:18:48 -070030 enum Mode {
31 kModeUnknown,
32 kModeGet,
33 kModeAdd,
Paul Stewartf748a362012-03-07 12:01:20 -080034 kModeDelete,
35 kModeQuery
Paul Stewartdd7df792011-07-15 11:09:50 -070036 };
37
38 struct LinkStatus {
39 LinkStatus()
40 : type(0),
41 flags(0),
42 change(0) {}
43 LinkStatus(unsigned int in_type,
44 unsigned int in_flags,
45 unsigned int in_change)
46 : type(in_type),
47 flags(in_flags),
48 change(in_change) {}
49 unsigned int type;
50 unsigned int flags;
51 unsigned int change;
52 };
53
54 struct AddressStatus {
55 AddressStatus()
56 : prefix_len(0),
57 flags(0),
58 scope(0) {}
59 AddressStatus(unsigned char prefix_len_in,
60 unsigned char flags_in,
61 unsigned char scope_in)
62 : prefix_len(prefix_len_in),
63 flags(flags_in),
64 scope(scope_in) {}
65 unsigned char prefix_len;
66 unsigned char flags;
67 unsigned char scope;
68 };
69
70 struct RouteStatus {
71 RouteStatus()
72 : dst_prefix(0),
73 src_prefix(0),
74 table(0),
75 protocol(0),
76 scope(0),
77 type(0),
78 flags(0) {}
79 RouteStatus(unsigned char dst_prefix_in,
80 unsigned char src_prefix_in,
81 unsigned char table_in,
82 unsigned char protocol_in,
83 unsigned char scope_in,
84 unsigned char type_in,
85 unsigned char flags_in)
86 : dst_prefix(dst_prefix_in),
87 src_prefix(src_prefix_in),
88 table(table_in),
89 protocol(protocol_in),
90 scope(scope_in),
91 type(type_in),
92 flags(flags_in) {}
93 unsigned char dst_prefix;
94 unsigned char src_prefix;
95 unsigned char table;
96 unsigned char protocol;
97 unsigned char scope;
98 unsigned char type;
99 unsigned char flags;
100 };
101
102 // Empty constructor
103 RTNLMessage();
104 // Build an RTNL message from arguments
Paul Stewart9a908082011-08-31 12:18:48 -0700105 RTNLMessage(Type type,
106 Mode mode,
Paul Stewartdd7df792011-07-15 11:09:50 -0700107 unsigned int flags,
108 uint32 seq,
109 uint32 pid,
110 int interface_index,
111 IPAddress::Family family);
112
113 // Parse an RTNL message. Returns true on success.
114 bool Decode(const ByteString &data);
115 // Encode an RTNL message. Returns empty ByteString on failure.
Paul Stewartf748a362012-03-07 12:01:20 -0800116 ByteString Encode() const;
117 // Reset all fields.
118 void Reset();
Paul Stewartdd7df792011-07-15 11:09:50 -0700119
120 // Getters and setters
Paul Stewart9a908082011-08-31 12:18:48 -0700121 Type type() const { return type_; }
122 Mode mode() const { return mode_; }
Chris Masone2aa97072011-08-09 17:35:08 -0700123 uint16 flags() const { return flags_; }
124 uint32 seq() const { return seq_; }
Paul Stewartdd7df792011-07-15 11:09:50 -0700125 void set_seq(uint32 seq) { seq_ = seq; }
Chris Masone2aa97072011-08-09 17:35:08 -0700126 uint32 pid() const { return pid_; }
127 uint32 interface_index() const { return interface_index_; }
128 IPAddress::Family family() const { return family_; }
Paul Stewartdd7df792011-07-15 11:09:50 -0700129
Chris Masone2aa97072011-08-09 17:35:08 -0700130 const LinkStatus &link_status() const { return link_status_; }
Paul Stewart9a908082011-08-31 12:18:48 -0700131 void set_link_status(const LinkStatus &link_status) {
132 link_status_ = link_status;
133 }
Chris Masone2aa97072011-08-09 17:35:08 -0700134 const AddressStatus &address_status() const { return address_status_; }
Paul Stewart9a908082011-08-31 12:18:48 -0700135 void set_address_status(const AddressStatus &address_status) {
Paul Stewartdd7df792011-07-15 11:09:50 -0700136 address_status_ = address_status;
137 }
Chris Masone2aa97072011-08-09 17:35:08 -0700138 const RouteStatus &route_status() const { return route_status_; }
Paul Stewart9a908082011-08-31 12:18:48 -0700139 void set_route_status(const RouteStatus &route_status) {
Paul Stewartdd7df792011-07-15 11:09:50 -0700140 route_status_ = route_status;
141 }
142 // GLint hates "unsigned short", and I don't blame it, but that's the
143 // type that's used in the system headers. Use uint16 instead and hope
144 // that the conversion never ends up truncating on some strange platform.
Chris Masone2aa97072011-08-09 17:35:08 -0700145 bool HasAttribute(uint16 attr) const {
Paul Stewartdd7df792011-07-15 11:09:50 -0700146 return ContainsKey(attributes_, attr);
147 }
Chris Masone2aa97072011-08-09 17:35:08 -0700148 const ByteString GetAttribute(uint16 attr) const {
149 return HasAttribute(attr) ?
150 attributes_.find(attr)->second : ByteString(0);
Paul Stewartdd7df792011-07-15 11:09:50 -0700151 }
152 void SetAttribute(uint16 attr, const ByteString &val) {
153 attributes_[attr] = val;
154 }
155
156 private:
157 bool DecodeInternal(const ByteString &msg);
158 bool DecodeLink(const RTNLHeader *hdr,
Paul Stewart9a908082011-08-31 12:18:48 -0700159 Mode mode,
Paul Stewartdd7df792011-07-15 11:09:50 -0700160 rtattr **attr_data,
161 int *attr_length);
162 bool DecodeAddress(const RTNLHeader *hdr,
Paul Stewart9a908082011-08-31 12:18:48 -0700163 Mode mode,
Paul Stewartdd7df792011-07-15 11:09:50 -0700164 rtattr **attr_data,
165 int *attr_length);
166 bool DecodeRoute(const RTNLHeader *hdr,
Paul Stewart9a908082011-08-31 12:18:48 -0700167 Mode mode,
Paul Stewartdd7df792011-07-15 11:09:50 -0700168 rtattr **attr_data,
169 int *attr_length);
Paul Stewartf748a362012-03-07 12:01:20 -0800170 bool EncodeLink(RTNLHeader *hdr) const;
171 bool EncodeAddress(RTNLHeader *hdr) const;
172 bool EncodeRoute(RTNLHeader *hdr) const;
Paul Stewartdd7df792011-07-15 11:09:50 -0700173
Paul Stewart9a908082011-08-31 12:18:48 -0700174 Type type_;
175 Mode mode_;
Paul Stewartdd7df792011-07-15 11:09:50 -0700176 uint16 flags_;
177 uint32 seq_;
178 uint32 pid_;
179 unsigned int interface_index_;
180 IPAddress::Family family_;
181 LinkStatus link_status_;
182 AddressStatus address_status_;
183 RouteStatus route_status_;
Hristo Stefanoved2c28c2011-11-29 15:37:30 -0800184 base::hash_map<uint16, ByteString> attributes_; // NOLINT
185 // NOLINT above: hash_map from base, no need to #include <hash_map>
Paul Stewartdd7df792011-07-15 11:09:50 -0700186
187 DISALLOW_COPY_AND_ASSIGN(RTNLMessage);
188};
189
190} // namespace shill
191
192#endif // SHILL_RTNL_MESSAGE_