rtnl_message.cc revision dd7df792d2401741183a954f3f6e97d4c6de1e22
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() 29dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart : type_(kMessageTypeUnknown), 30dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart mode_(kMessageModeUnknown), 31dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart flags_(0), 32dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart interface_index_(0), 33dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart family_(IPAddress::kAddressFamilyUnknown) {} 34dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 35dd7df792d2401741183a954f3f6e97d4c6de1e22Paul StewartRTNLMessage::RTNLMessage(MessageType type, 36dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart MessageMode 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) { 53dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart mode_ = kMessageModeUnknown; 54dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart type_ = kMessageTypeUnknown; 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 67dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart MessageMode mode = kMessageModeUnknown; 68dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart switch (hdr->hdr.nlmsg_type) { 69dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart case RTM_NEWLINK: 70dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart case RTM_NEWADDR: 71dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart case RTM_NEWROUTE: 72dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart mode = kMessageModeAdd; 73dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart break; 74dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 75dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart case RTM_DELLINK: 76dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart case RTM_DELADDR: 77dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart case RTM_DELROUTE: 78dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart mode = kMessageModeDelete; 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, 133dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart MessageMode 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 144dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart type_ = kMessageTypeLink; 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, 154dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart MessageMode 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 164dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart type_ = kMessageTypeAddress; 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, 174dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart MessageMode 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 184dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart type_ = kMessageTypeRoute; 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() { 197dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart if (type_ != kMessageTypeLink && 198dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart type_ != kMessageTypeAddress && 199dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart type_ != kMessageTypeRoute) { 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 209dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart if (mode_ == kMessageModeGet) { 210dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart if (type_ == kMessageTypeLink) { 211dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr.hdr.nlmsg_type = RTM_GETLINK; 212dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart } else if (type_ == kMessageTypeAddress) { 213dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr.hdr.nlmsg_type = RTM_GETADDR; 214dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart } else if (type_ == kMessageTypeRoute) { 215dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr.hdr.nlmsg_type = RTM_GETROUTE; 216dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart } 217dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(hdr.gen)); 218dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr.gen.rtgen_family = family_; 219dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart } else { 220dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart switch (type_) { 221dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart case kMessageTypeLink: 222dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart EncodeLink(&hdr); 223dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart break; 224dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 225dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart case kMessageTypeAddress: 226dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart EncodeAddress(&hdr); 227dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart break; 228dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 229dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart case kMessageTypeRoute: 230dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart EncodeRoute(&hdr); 231dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart break; 232dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 233dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart default: 234dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart NOTREACHED(); 235dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart } 236dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart } 237dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 238dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart size_t header_length = hdr.hdr.nlmsg_len; 239dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart ByteString attributes; 240dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 241dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart base::hash_map<uint16, ByteString>::iterator attr; 242dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart for (attr = attributes_.begin(); attr != attributes_.end(); ++attr) { 243dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart size_t len = RTA_LENGTH(attr->second.GetLength()); 244dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr.hdr.nlmsg_len = NLMSG_ALIGN(hdr.hdr.nlmsg_len) + RTA_ALIGN(len); 245dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 246dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart struct rtattr rt_attr = { len, attr->first }; 247dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart ByteString attr_header(reinterpret_cast<unsigned char *>(&rt_attr), 248dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart sizeof(rt_attr)); 249dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart attr_header.Resize(RTA_ALIGN(attr_header.GetLength())); 250dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart attributes.Append(attr_header); 251dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 252dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart ByteString attr_data(attr->second); 253dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart attr_data.Resize(RTA_ALIGN(attr_data.GetLength())); 254dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart attributes.Append(attr_data); 255dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart } 256dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 257dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart ByteString packet(reinterpret_cast<unsigned char *>(&hdr), header_length); 258dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart packet.Append(attributes); 259dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 260dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart return packet; 261dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart} 262dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 263dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewartvoid RTNLMessage::EncodeLink(RTNLHeader *hdr) { 264dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->hdr.nlmsg_type = (mode_ == kMessageModeAdd) ? RTM_NEWLINK : RTM_DELLINK; 265dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->hdr.nlmsg_len = NLMSG_LENGTH(sizeof(hdr->ifi)); 266dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->ifi.ifi_family = family_; 267dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->ifi.ifi_type = link_status_.type; 268dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->ifi.ifi_flags = link_status_.flags; 269dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->ifi.ifi_change = link_status_.change; 270dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart} 271dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 272dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewartvoid RTNLMessage::EncodeAddress(RTNLHeader *hdr) { 273dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->hdr.nlmsg_type = (mode_ == kMessageModeAdd) ? RTM_NEWADDR : RTM_DELADDR; 274dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->hdr.nlmsg_len = NLMSG_LENGTH(sizeof(hdr->ifa)); 275dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->ifa.ifa_family = family_; 276dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->ifa.ifa_prefixlen = address_status_.prefix_len; 277dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->ifa.ifa_flags = address_status_.flags; 278dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->ifa.ifa_scope = address_status_.scope; 279dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->ifa.ifa_index = interface_index_; 280dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart} 281dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 282dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewartvoid RTNLMessage::EncodeRoute(RTNLHeader *hdr) { 283dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->hdr.nlmsg_type = 284dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart (mode_ == kMessageModeAdd) ? RTM_NEWROUTE : RTM_DELROUTE; 285dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->hdr.nlmsg_len = NLMSG_LENGTH(sizeof(hdr->rtm)); 286dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->rtm.rtm_family = family_; 287dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->rtm.rtm_dst_len = route_status_.dst_prefix; 288dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->rtm.rtm_src_len = route_status_.src_prefix; 289dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->rtm.rtm_table = route_status_.table; 290dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->rtm.rtm_protocol = route_status_.protocol; 291dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->rtm.rtm_scope = route_status_.scope; 292dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->rtm.rtm_type = route_status_.type; 293dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart hdr->rtm.rtm_flags = route_status_.flags; 294dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart} 295dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart 296dd7df792d2401741183a954f3f6e97d4c6de1e22Paul Stewart} // namespace shill 297