rtnl_message.cc revision cba0f7f604b28b1fe85a16b16b0731860dfff753
1dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart// Copyright (c) 2011 The Chromium OS Authors. All rights reserved. 2dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart// Use of this source code is governed by a BSD-style license that can be 3dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart// found in the LICENSE file. 4dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 5dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart#include "shill/rtnl_message.h" 6dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 7dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart#include <base/logging.h> 8dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 9dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart#include <sys/socket.h> 10dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart#include <linux/netlink.h> 11dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart#include <linux/rtnetlink.h> 12dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 13dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewartnamespace shill { 14dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 15dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewartstruct RTNLHeader { 16dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart RTNLHeader() { 17dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart memset(this, 0, sizeof(*this)); 18dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart } 19dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart struct nlmsghdr hdr; 20dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart union { 21dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart struct ifinfomsg ifi; 22dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart struct ifaddrmsg ifa; 23dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart struct rtmsg rtm; 24dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart struct rtgenmsg gen; 25dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart }; 26dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart}; 27dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 28dd7df792d2401741183a954f3f6e97d4c6de1e22Paul StewartRTNLMessage::RTNLMessage() 299a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart : type_(kTypeUnknown), 309a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart mode_(kModeUnknown), 31dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart flags_(0), 32dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart interface_index_(0), 337355ce1937c504d836a303ac809bd436272212b3Paul Stewart family_(IPAddress::kFamilyUnknown) {} 34dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 359a908080fc2a72dbf06f995b878fc8a3693b725aPaul StewartRTNLMessage::RTNLMessage(Type type, 369a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart Mode mode, 37dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart unsigned int flags, 38dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart uint32 seq, 39dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart uint32 pid, 40dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart int interface_index, 41dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart IPAddress::Family family) 42dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart : type_(type), 43dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart mode_(mode), 44dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart flags_(flags), 45dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart seq_(seq), 46dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart pid_(pid), 47dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart interface_index_(interface_index), 48dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart family_(family) {} 49dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 50dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewartbool RTNLMessage::Decode(const ByteString &msg) { 51dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart bool ret = DecodeInternal(msg); 52dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart if (!ret) { 539a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart mode_ = kModeUnknown; 549a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart type_ = kTypeUnknown; 55dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart } 56dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart return ret; 57dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart} 58dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 59dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewartbool RTNLMessage::DecodeInternal(const ByteString &msg) { 60dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart const RTNLHeader *hdr = 61dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart reinterpret_cast<const RTNLHeader *>(msg.GetConstData()); 62dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 63dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart if (msg.GetLength() < sizeof(hdr->hdr) || 64dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart msg.GetLength() < hdr->hdr.nlmsg_len) 65dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart return false; 66dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 679a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart Mode mode = kModeUnknown; 68dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart switch (hdr->hdr.nlmsg_type) { 69dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart case RTM_NEWLINK: 70dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart case RTM_NEWADDR: 71dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart case RTM_NEWROUTE: 729a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart mode = kModeAdd; 73dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart break; 74dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 75dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart case RTM_DELLINK: 76dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart case RTM_DELADDR: 77dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart case RTM_DELROUTE: 789a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart mode = kModeDelete; 79dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart break; 80dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 81dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart default: 82dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart return false; 83dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart } 84dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 85dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart rtattr *attr_data = NULL; 86dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart int attr_length = 0; 87dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 88dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart switch (hdr->hdr.nlmsg_type) { 89dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart case RTM_NEWLINK: 90dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart case RTM_DELLINK: 91dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart if (!DecodeLink(hdr, mode, &attr_data, &attr_length)) 92dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart return false; 93dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart break; 94dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 95dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart case RTM_NEWADDR: 96dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart case RTM_DELADDR: 97dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart if (!DecodeAddress(hdr, mode, &attr_data, &attr_length)) 98dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart return false; 99dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart break; 100dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 101dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart case RTM_NEWROUTE: 102dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart case RTM_DELROUTE: 103dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart if (!DecodeRoute(hdr, mode, &attr_data, &attr_length)) 104dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart return false; 105dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart break; 106dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 107dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart default: 108dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart NOTREACHED(); 109dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart } 110dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 111dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart flags_ = hdr->hdr.nlmsg_flags; 112dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart seq_ = hdr->hdr.nlmsg_seq; 113dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart pid_ = hdr->hdr.nlmsg_pid; 114dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 115dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart while (attr_data && RTA_OK(attr_data, attr_length)) { 116dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart SetAttribute( 117dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart attr_data->rta_type, 118dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart ByteString(reinterpret_cast<unsigned char *>(RTA_DATA(attr_data)), 119dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart RTA_PAYLOAD(attr_data))); 120dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart attr_data = RTA_NEXT(attr_data, attr_length); 121dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart } 122dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 123dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart if (attr_length) { 124dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart // We hit a parse error while going through the attributes 125dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart attributes_.clear(); 126dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart return false; 127dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart } 128dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 129dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart return true; 130dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart} 131dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 132dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewartbool RTNLMessage::DecodeLink(const RTNLHeader *hdr, 1339a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart Mode mode, 134dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart rtattr **attr_data, 135dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart int *attr_length) { 136dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart if (hdr->hdr.nlmsg_len < NLMSG_LENGTH(sizeof(hdr->ifi))) { 137dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart return false; 138dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart } 139dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 140dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart mode_ = mode; 141dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart *attr_data = IFLA_RTA(NLMSG_DATA(&hdr->hdr)); 142dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart *attr_length = IFLA_PAYLOAD(&hdr->hdr); 143dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 1449a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart type_ = kTypeLink; 145dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart family_ = hdr->ifi.ifi_family; 146dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart interface_index_ = hdr->ifi.ifi_index; 147dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart set_link_status(LinkStatus(hdr->ifi.ifi_type, 148dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->ifi.ifi_flags, 149dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->ifi.ifi_change)); 150dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart return true; 151dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart} 152dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 153dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewartbool RTNLMessage::DecodeAddress(const RTNLHeader *hdr, 1549a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart Mode mode, 155dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart rtattr **attr_data, 156dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart int *attr_length) { 157dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart if (hdr->hdr.nlmsg_len < NLMSG_LENGTH(sizeof(hdr->ifa))) { 158dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart return false; 159dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart } 160dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart mode_ = mode; 161dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart *attr_data = IFA_RTA(NLMSG_DATA(&hdr->hdr)); 162dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart *attr_length = IFA_PAYLOAD(&hdr->hdr); 163dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 1649a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart type_ = kTypeAddress; 165dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart family_ = hdr->ifa.ifa_family; 166dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart interface_index_ = hdr->ifa.ifa_index; 167dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart set_address_status(AddressStatus(hdr->ifa.ifa_prefixlen, 168dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->ifa.ifa_flags, 169dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->ifa.ifa_scope)); 170dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart return true; 171dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart} 172dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 173dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewartbool RTNLMessage::DecodeRoute(const RTNLHeader *hdr, 1749a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart Mode mode, 175dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart rtattr **attr_data, 176dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart int *attr_length) { 177dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart if (hdr->hdr.nlmsg_len < NLMSG_LENGTH(sizeof(hdr->rtm))) { 178dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart return false; 179dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart } 180dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart mode_ = mode; 181dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart *attr_data = RTM_RTA(NLMSG_DATA(&hdr->hdr)); 182dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart *attr_length = RTM_PAYLOAD(&hdr->hdr); 183dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 1849a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart type_ = kTypeRoute; 185dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart family_ = hdr->rtm.rtm_family; 186dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart set_route_status(RouteStatus(hdr->rtm.rtm_dst_len, 187dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->rtm.rtm_src_len, 188dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->rtm.rtm_table, 189dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->rtm.rtm_protocol, 190dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->rtm.rtm_scope, 191dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->rtm.rtm_type, 192dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->rtm.rtm_flags)); 193dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart return true; 194dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart} 195dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 196dd7df792d2401741183a954f3f6e97d4c6de1e22Paul StewartByteString RTNLMessage::Encode() { 1979a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart if (type_ != kTypeLink && 1989a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart type_ != kTypeAddress && 1999a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart type_ != kTypeRoute) { 200dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart return ByteString(); 201dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart } 202dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 203dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart RTNLHeader hdr; 204dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr.hdr.nlmsg_flags = flags_; 205dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr.hdr.nlmsg_seq = seq_; 206dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr.hdr.nlmsg_pid = pid_; 207dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr.hdr.nlmsg_seq = 0; 208dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 2099a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart if (mode_ == kModeGet) { 2109a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart if (type_ == kTypeLink) { 211dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr.hdr.nlmsg_type = RTM_GETLINK; 2129a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart } else if (type_ == kTypeAddress) { 213dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr.hdr.nlmsg_type = RTM_GETADDR; 2149a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart } else if (type_ == kTypeRoute) { 215dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr.hdr.nlmsg_type = RTM_GETROUTE; 216dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart } 217dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(hdr.gen)); 2189a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart hdr.hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP; 219dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr.gen.rtgen_family = family_; 220dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart } else { 221dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart switch (type_) { 2229a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart case kTypeLink: 223dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart EncodeLink(&hdr); 224dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart break; 225dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 2269a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart case kTypeAddress: 227dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart EncodeAddress(&hdr); 228dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart break; 229dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 2309a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart case kTypeRoute: 231dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart EncodeRoute(&hdr); 232dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart break; 233dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 234dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart default: 235dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart NOTREACHED(); 236dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart } 237dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart } 238dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 239dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart size_t header_length = hdr.hdr.nlmsg_len; 240dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart ByteString attributes; 241dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 242dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart base::hash_map<uint16, ByteString>::iterator attr; 243dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart for (attr = attributes_.begin(); attr != attributes_.end(); ++attr) { 244dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart size_t len = RTA_LENGTH(attr->second.GetLength()); 245dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr.hdr.nlmsg_len = NLMSG_ALIGN(hdr.hdr.nlmsg_len) + RTA_ALIGN(len); 246dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 247dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart struct rtattr rt_attr = { len, attr->first }; 248dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart ByteString attr_header(reinterpret_cast<unsigned char *>(&rt_attr), 249dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart sizeof(rt_attr)); 250dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart attr_header.Resize(RTA_ALIGN(attr_header.GetLength())); 251dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart attributes.Append(attr_header); 252dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 253dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart ByteString attr_data(attr->second); 254dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart attr_data.Resize(RTA_ALIGN(attr_data.GetLength())); 255dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart attributes.Append(attr_data); 256dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart } 257dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 258dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart ByteString packet(reinterpret_cast<unsigned char *>(&hdr), header_length); 259dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart packet.Append(attributes); 260dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 261dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart return packet; 262dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart} 263dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 264dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewartvoid RTNLMessage::EncodeLink(RTNLHeader *hdr) { 2659a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart hdr->hdr.nlmsg_type = (mode_ == kModeAdd) ? RTM_NEWLINK : RTM_DELLINK; 266dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->hdr.nlmsg_len = NLMSG_LENGTH(sizeof(hdr->ifi)); 267dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->ifi.ifi_family = family_; 268cba0f7f604b28b1fe85a16b16b0731860dfff753Paul Stewart hdr->ifi.ifi_index = interface_index_; 269dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->ifi.ifi_type = link_status_.type; 270dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->ifi.ifi_flags = link_status_.flags; 271dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->ifi.ifi_change = link_status_.change; 272dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart} 273dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 274dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewartvoid RTNLMessage::EncodeAddress(RTNLHeader *hdr) { 2759a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart hdr->hdr.nlmsg_type = (mode_ == kModeAdd) ? RTM_NEWADDR : RTM_DELADDR; 276dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->hdr.nlmsg_len = NLMSG_LENGTH(sizeof(hdr->ifa)); 277dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->ifa.ifa_family = family_; 278dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->ifa.ifa_prefixlen = address_status_.prefix_len; 279dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->ifa.ifa_flags = address_status_.flags; 280dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->ifa.ifa_scope = address_status_.scope; 281dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->ifa.ifa_index = interface_index_; 282dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart} 283dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 284dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewartvoid RTNLMessage::EncodeRoute(RTNLHeader *hdr) { 2859a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart hdr->hdr.nlmsg_type = (mode_ == kModeAdd) ? RTM_NEWROUTE : RTM_DELROUTE; 286dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->hdr.nlmsg_len = NLMSG_LENGTH(sizeof(hdr->rtm)); 287dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->rtm.rtm_family = family_; 288dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->rtm.rtm_dst_len = route_status_.dst_prefix; 289dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->rtm.rtm_src_len = route_status_.src_prefix; 290dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->rtm.rtm_table = route_status_.table; 291dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->rtm.rtm_protocol = route_status_.protocol; 292dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->rtm.rtm_scope = route_status_.scope; 293dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->rtm.rtm_type = route_status_.type; 294dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->rtm.rtm_flags = route_status_.flags; 295dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart} 296dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 297dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart} // namespace shill 298