blob: dff4571eab516428881262d08560c19d9750611b [file] [log] [blame]
Paul Stewartdd7df792011-07-15 11:09:50 -07001// Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
2// 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>
9#include <base/hash_tables.h>
10#include <base/stl_util-inl.h>
11
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:
23 enum MessageType {
24 kMessageTypeUnknown,
25 kMessageTypeLink,
26 kMessageTypeAddress,
27 kMessageTypeRoute
28 };
29
30 enum MessageMode {
31 kMessageModeUnknown,
32 kMessageModeGet,
33 kMessageModeAdd,
34 kMessageModeDelete
35 };
36
37 struct LinkStatus {
38 LinkStatus()
39 : type(0),
40 flags(0),
41 change(0) {}
42 LinkStatus(unsigned int in_type,
43 unsigned int in_flags,
44 unsigned int in_change)
45 : type(in_type),
46 flags(in_flags),
47 change(in_change) {}
48 unsigned int type;
49 unsigned int flags;
50 unsigned int change;
51 };
52
53 struct AddressStatus {
54 AddressStatus()
55 : prefix_len(0),
56 flags(0),
57 scope(0) {}
58 AddressStatus(unsigned char prefix_len_in,
59 unsigned char flags_in,
60 unsigned char scope_in)
61 : prefix_len(prefix_len_in),
62 flags(flags_in),
63 scope(scope_in) {}
64 unsigned char prefix_len;
65 unsigned char flags;
66 unsigned char scope;
67 };
68
69 struct RouteStatus {
70 RouteStatus()
71 : dst_prefix(0),
72 src_prefix(0),
73 table(0),
74 protocol(0),
75 scope(0),
76 type(0),
77 flags(0) {}
78 RouteStatus(unsigned char dst_prefix_in,
79 unsigned char src_prefix_in,
80 unsigned char table_in,
81 unsigned char protocol_in,
82 unsigned char scope_in,
83 unsigned char type_in,
84 unsigned char flags_in)
85 : dst_prefix(dst_prefix_in),
86 src_prefix(src_prefix_in),
87 table(table_in),
88 protocol(protocol_in),
89 scope(scope_in),
90 type(type_in),
91 flags(flags_in) {}
92 unsigned char dst_prefix;
93 unsigned char src_prefix;
94 unsigned char table;
95 unsigned char protocol;
96 unsigned char scope;
97 unsigned char type;
98 unsigned char flags;
99 };
100
101 // Empty constructor
102 RTNLMessage();
103 // Build an RTNL message from arguments
104 RTNLMessage(MessageType type,
105 MessageMode mode,
106 unsigned int flags,
107 uint32 seq,
108 uint32 pid,
109 int interface_index,
110 IPAddress::Family family);
111
112 // Parse an RTNL message. Returns true on success.
113 bool Decode(const ByteString &data);
114 // Encode an RTNL message. Returns empty ByteString on failure.
115 ByteString Encode();
116
117 // Getters and setters
Chris Masone2aa97072011-08-09 17:35:08 -0700118 MessageType type() const { return type_; }
119 MessageMode mode() const { return mode_; }
120 uint16 flags() const { return flags_; }
121 uint32 seq() const { return seq_; }
Paul Stewartdd7df792011-07-15 11:09:50 -0700122 void set_seq(uint32 seq) { seq_ = seq; }
Chris Masone2aa97072011-08-09 17:35:08 -0700123 uint32 pid() const { return pid_; }
124 uint32 interface_index() const { return interface_index_; }
125 IPAddress::Family family() const { return family_; }
Paul Stewartdd7df792011-07-15 11:09:50 -0700126
Chris Masone2aa97072011-08-09 17:35:08 -0700127 const LinkStatus &link_status() const { return link_status_; }
Paul Stewartdd7df792011-07-15 11:09:50 -0700128 void set_link_status(LinkStatus link_status) { link_status_ = link_status; }
Chris Masone2aa97072011-08-09 17:35:08 -0700129 const AddressStatus &address_status() const { return address_status_; }
Paul Stewartdd7df792011-07-15 11:09:50 -0700130 void set_address_status(AddressStatus address_status) {
131 address_status_ = address_status;
132 }
Chris Masone2aa97072011-08-09 17:35:08 -0700133 const RouteStatus &route_status() const { return route_status_; }
Paul Stewartdd7df792011-07-15 11:09:50 -0700134 void set_route_status(RouteStatus route_status) {
135 route_status_ = route_status;
136 }
137 // GLint hates "unsigned short", and I don't blame it, but that's the
138 // type that's used in the system headers. Use uint16 instead and hope
139 // that the conversion never ends up truncating on some strange platform.
Chris Masone2aa97072011-08-09 17:35:08 -0700140 bool HasAttribute(uint16 attr) const {
Paul Stewartdd7df792011-07-15 11:09:50 -0700141 return ContainsKey(attributes_, attr);
142 }
Chris Masone2aa97072011-08-09 17:35:08 -0700143 const ByteString GetAttribute(uint16 attr) const {
144 return HasAttribute(attr) ?
145 attributes_.find(attr)->second : ByteString(0);
Paul Stewartdd7df792011-07-15 11:09:50 -0700146 }
147 void SetAttribute(uint16 attr, const ByteString &val) {
148 attributes_[attr] = val;
149 }
150
151 private:
152 bool DecodeInternal(const ByteString &msg);
153 bool DecodeLink(const RTNLHeader *hdr,
154 MessageMode mode,
155 rtattr **attr_data,
156 int *attr_length);
157 bool DecodeAddress(const RTNLHeader *hdr,
158 MessageMode mode,
159 rtattr **attr_data,
160 int *attr_length);
161 bool DecodeRoute(const RTNLHeader *hdr,
162 MessageMode mode,
163 rtattr **attr_data,
164 int *attr_length);
165 void EncodeLink(RTNLHeader *hdr);
166 void EncodeAddress(RTNLHeader *hdr);
167 void EncodeRoute(RTNLHeader *hdr);
168
169 MessageType type_;
170 MessageMode mode_;
171 uint16 flags_;
172 uint32 seq_;
173 uint32 pid_;
174 unsigned int interface_index_;
175 IPAddress::Family family_;
176 LinkStatus link_status_;
177 AddressStatus address_status_;
178 RouteStatus route_status_;
179 base::hash_map<uint16, ByteString> attributes_;
180
181 DISALLOW_COPY_AND_ASSIGN(RTNLMessage);
182};
183
184} // namespace shill
185
186#endif // SHILL_RTNL_MESSAGE_