nl80211_packet.cpp revision 703601782dc0dcf952b16b8c906e623f276b6098
1337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang/* 2337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang * Copyright (C) 2016 The Android Open Source Project 3337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang * 4337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang * Licensed under the Apache License, Version 2.0 (the "License"); 5337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang * you may not use this file except in compliance with the License. 6337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang * You may obtain a copy of the License at 7337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang * 8337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang * http://www.apache.org/licenses/LICENSE-2.0 9337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang * 10337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang * Unless required by applicable law or agreed to in writing, software 11337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang * distributed under the License is distributed on an "AS IS" BASIS, 12337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang * See the License for the specific language governing permissions and 14337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang * limitations under the License. 15337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang */ 16337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 17808c670699b218f8cc16f83e81be408ae441d44aNingyuan Wang#include "wificond/net/nl80211_packet.h" 18337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 19337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang#include <android-base/logging.h> 20337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 21337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wangusing std::vector; 22337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 23337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wangnamespace android { 24337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wangnamespace wificond { 25337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 26703601782dc0dcf952b16b8c906e623f276b6098Ningyuan Wangint NL80211Packet::copy_counter_ = 0; 27703601782dc0dcf952b16b8c906e623f276b6098Ningyuan Wanglong NL80211Packet::packet_bytes_copied_ = 0; 28703601782dc0dcf952b16b8c906e623f276b6098Ningyuan Wang 29337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan WangNL80211Packet::NL80211Packet(const vector<uint8_t>& data) 30337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang : data_(data) { 31337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang data_ = data; 32337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 33337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 34703601782dc0dcf952b16b8c906e623f276b6098Ningyuan WangNL80211Packet::NL80211Packet(const NL80211Packet& packet) { 35703601782dc0dcf952b16b8c906e623f276b6098Ningyuan Wang data_ = packet.data_; 36703601782dc0dcf952b16b8c906e623f276b6098Ningyuan Wang copy_counter_++; 37703601782dc0dcf952b16b8c906e623f276b6098Ningyuan Wang packet_bytes_copied_+= packet.data_.size(); 38703601782dc0dcf952b16b8c906e623f276b6098Ningyuan Wang LOG(DEBUG) << "Packet copy operations: " << copy_counter_; 39703601782dc0dcf952b16b8c906e623f276b6098Ningyuan Wang LOG(DEBUG) << "Packet bytes copied: " << packet_bytes_copied_; 40703601782dc0dcf952b16b8c906e623f276b6098Ningyuan Wang} 41703601782dc0dcf952b16b8c906e623f276b6098Ningyuan Wang 427397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan WangNL80211Packet::NL80211Packet(uint16_t type, 437397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang uint8_t command, 447397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang uint32_t sequence, 457397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang uint32_t pid) { 46337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang // Initialize the netlink header and generic netlink header. 47337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang // NLMSG_HDRLEN and GENL_HDRLEN already include the padding size. 48337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang data_.resize(NLMSG_HDRLEN + GENL_HDRLEN, 0); 49337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang // Initialize length field. 50337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang nlmsghdr* nl_header = reinterpret_cast<nlmsghdr*>(data_.data()); 51337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang nl_header->nlmsg_len = data_.size(); 52337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang // Add NLM_F_REQUEST flag. 53337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang nl_header->nlmsg_flags = nl_header->nlmsg_flags | NLM_F_REQUEST; 547397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang nl_header->nlmsg_type = type; 557397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang nl_header->nlmsg_seq = sequence; 567397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang nl_header->nlmsg_pid = pid; 57337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 58337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang genlmsghdr* genl_header = 59337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang reinterpret_cast<genlmsghdr*>(data_.data() + NLMSG_HDRLEN); 60337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang genl_header->version = 1; 617397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang genl_header->cmd = command; 62337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang // genl_header->reserved is aready 0. 63337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 64337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 65337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wangbool NL80211Packet::IsValid() const { 66337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang // Verify the size of packet. 67337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang if (data_.size() < NLMSG_HDRLEN) { 68337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang LOG(ERROR) << "Cannot retrieve netlink header."; 69337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang return false; 70337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang } 71337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 7239f581c0a6e2d9f6943b9b7069b6f096e0e5e858Ningyuan Wang const nlmsghdr* nl_header = reinterpret_cast<const nlmsghdr*>(data_.data()); 7339f581c0a6e2d9f6943b9b7069b6f096e0e5e858Ningyuan Wang 74337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang // If type < NLMSG_MIN_TYPE, this should be a reserved control message, 75337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang // which doesn't carry a generic netlink header. 76337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang if (GetMessageType() >= NLMSG_MIN_TYPE) { 7739f581c0a6e2d9f6943b9b7069b6f096e0e5e858Ningyuan Wang if (data_.size() < NLMSG_HDRLEN + GENL_HDRLEN || 7839f581c0a6e2d9f6943b9b7069b6f096e0e5e858Ningyuan Wang nl_header->nlmsg_len < NLMSG_HDRLEN + GENL_HDRLEN) { 79337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang LOG(ERROR) << "Cannot retrieve generic netlink header."; 80337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang return false; 81337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang } 82337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang } 8339f581c0a6e2d9f6943b9b7069b6f096e0e5e858Ningyuan Wang // If it is an ERROR message, it should be long enough to carry an extra error 8439f581c0a6e2d9f6943b9b7069b6f096e0e5e858Ningyuan Wang // code field. 8539f581c0a6e2d9f6943b9b7069b6f096e0e5e858Ningyuan Wang // Kernel uses int for this field. 8639f581c0a6e2d9f6943b9b7069b6f096e0e5e858Ningyuan Wang if (GetMessageType() == NLMSG_ERROR) { 8739f581c0a6e2d9f6943b9b7069b6f096e0e5e858Ningyuan Wang if (data_.size() < NLMSG_HDRLEN + sizeof(int) || 8839f581c0a6e2d9f6943b9b7069b6f096e0e5e858Ningyuan Wang nl_header->nlmsg_len < NLMSG_HDRLEN + sizeof(int)) { 8939f581c0a6e2d9f6943b9b7069b6f096e0e5e858Ningyuan Wang LOG(ERROR) << "Broken error message."; 9039f581c0a6e2d9f6943b9b7069b6f096e0e5e858Ningyuan Wang return false; 9139f581c0a6e2d9f6943b9b7069b6f096e0e5e858Ningyuan Wang } 9239f581c0a6e2d9f6943b9b7069b6f096e0e5e858Ningyuan Wang } 9339f581c0a6e2d9f6943b9b7069b6f096e0e5e858Ningyuan Wang 94337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang // Verify the netlink header. 95337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang if (data_.size() < nl_header->nlmsg_len || 96337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang nl_header->nlmsg_len < sizeof(nlmsghdr)) { 97337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang LOG(ERROR) << "Discarding incomplete / invalid message."; 98337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang return false; 99337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang } 100337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang return true; 101337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 102337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 103337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wangbool NL80211Packet::IsDump() const { 104337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang return GetFlags() & NLM_F_DUMP; 105337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 106337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 107337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wangbool NL80211Packet::IsMulti() const { 108337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang return GetFlags() & NLM_F_MULTI; 109337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 110337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 111337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wanguint8_t NL80211Packet::GetCommand() const { 112337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang const genlmsghdr* genl_header = reinterpret_cast<const genlmsghdr*>( 113337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang data_.data() + NLMSG_HDRLEN); 114337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang return genl_header->cmd; 115337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 116337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 117337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wanguint16_t NL80211Packet::GetFlags() const { 118337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang const nlmsghdr* nl_header = reinterpret_cast<const nlmsghdr*>(data_.data()); 119337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang return nl_header->nlmsg_flags; 120337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 121337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 122337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wanguint16_t NL80211Packet::GetMessageType() const { 123337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang const nlmsghdr* nl_header = reinterpret_cast<const nlmsghdr*>(data_.data()); 124337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang return nl_header->nlmsg_type; 125337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 126337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 127337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wanguint32_t NL80211Packet::GetMessageSequence() const { 128337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang const nlmsghdr* nl_header = reinterpret_cast<const nlmsghdr*>(data_.data()); 129337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang return nl_header->nlmsg_seq; 130337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 131337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 132337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wanguint32_t NL80211Packet::GetPortId() const { 133337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang const nlmsghdr* nl_header = reinterpret_cast<const nlmsghdr*>(data_.data()); 134337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang return nl_header->nlmsg_pid; 135337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 136337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 13739f581c0a6e2d9f6943b9b7069b6f096e0e5e858Ningyuan Wangint NL80211Packet::GetErrorCode() const { 138c2ec52ae9f449880901d50a45eae070aefba2f36Ningyuan Wang return -*reinterpret_cast<const int*>(data_.data() + NLMSG_HDRLEN); 13939f581c0a6e2d9f6943b9b7069b6f096e0e5e858Ningyuan Wang} 14039f581c0a6e2d9f6943b9b7069b6f096e0e5e858Ningyuan Wang 1417397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wangconst vector<uint8_t>& NL80211Packet::GetConstData() const { 1427397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang return data_; 1437397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang} 1447397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang 145337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wangvoid NL80211Packet::SetCommand(uint8_t command) { 146337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang genlmsghdr* genl_header = reinterpret_cast<genlmsghdr*>( 147337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang data_.data() + NLMSG_HDRLEN); 148337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang genl_header->cmd = command; 149337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 150337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 151e6dce59eaa5f1fcbdfb4b3fc6a60d5cd3b522b06Ningyuan Wangvoid NL80211Packet::AddFlag(uint16_t flag) { 152e6dce59eaa5f1fcbdfb4b3fc6a60d5cd3b522b06Ningyuan Wang nlmsghdr* nl_header = reinterpret_cast<nlmsghdr*>(data_.data()); 153e6dce59eaa5f1fcbdfb4b3fc6a60d5cd3b522b06Ningyuan Wang nl_header->nlmsg_flags |= flag; 154e6dce59eaa5f1fcbdfb4b3fc6a60d5cd3b522b06Ningyuan Wang} 155e6dce59eaa5f1fcbdfb4b3fc6a60d5cd3b522b06Ningyuan Wang 156337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wangvoid NL80211Packet::SetFlags(uint16_t flags) { 157337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang nlmsghdr* nl_header = reinterpret_cast<nlmsghdr*>(data_.data()); 158337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang nl_header->nlmsg_flags = flags; 159337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 160337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 161337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wangvoid NL80211Packet::SetMessageType(uint16_t message_type) { 162337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang nlmsghdr* nl_header = reinterpret_cast<nlmsghdr*>(data_.data()); 163337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang nl_header->nlmsg_type = message_type; 164337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 165337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 166337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wangvoid NL80211Packet::SetMessageSequence(uint32_t message_sequence) { 167337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang nlmsghdr* nl_header = reinterpret_cast<nlmsghdr*>(data_.data()); 168337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang nl_header->nlmsg_seq = message_sequence; 169337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 170337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 171337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wangvoid NL80211Packet::SetPortId(uint32_t pid) { 172337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang nlmsghdr* nl_header = reinterpret_cast<nlmsghdr*>(data_.data()); 173337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang nl_header->nlmsg_pid = pid; 174337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 175337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 176337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wangvoid NL80211Packet::AddAttribute(const BaseNL80211Attr& attribute) { 177337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang const vector<uint8_t>& append_data = attribute.GetConstData(); 178337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang // Append the data of |attribute| to |this|. 179337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang data_.insert(data_.end(), append_data.begin(), append_data.end()); 180337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang nlmsghdr* nl_header = reinterpret_cast<nlmsghdr*>(data_.data()); 181337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang // We don't need to worry about padding for a nl80211 packet. 182337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang // Because as long as all sub attributes have padding, the payload is aligned. 183337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang nl_header->nlmsg_len += append_data.size(); 184337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 185337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 186337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wangvoid NL80211Packet::AddFlagAttribute(int attribute_id) { 187337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang // We only need to append a header for flag attribute. 188337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang // Make space for the new attribute. 189337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang data_.resize(data_.size() + NLA_HDRLEN, 0); 190337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang nlattr* flag_header = 191337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang reinterpret_cast<nlattr*>(data_.data() + data_.size() - NLA_HDRLEN); 192337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang flag_header->nla_type = attribute_id; 193337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang flag_header->nla_len = NLA_HDRLEN; 194337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang nlmsghdr* nl_header = reinterpret_cast<nlmsghdr*>(data_.data()); 195337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang nl_header->nlmsg_len += NLA_HDRLEN; 196337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 197337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 198337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wangbool NL80211Packet::HasAttribute(int id) const { 199337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang return BaseNL80211Attr::GetAttributeImpl( 200337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang data_.data() + NLMSG_HDRLEN + GENL_HDRLEN, 201337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang data_.size() - NLMSG_HDRLEN - GENL_HDRLEN, 202337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang id, nullptr, nullptr); 203337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 204337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 205337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wangbool NL80211Packet::GetAttribute(int id, 206337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang NL80211NestedAttr* attribute) const { 207337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang uint8_t* start = nullptr; 208337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang uint8_t* end = nullptr; 209337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang if (!BaseNL80211Attr::GetAttributeImpl( 210337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang data_.data() + NLMSG_HDRLEN + GENL_HDRLEN, 211337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang data_.size() - NLMSG_HDRLEN - GENL_HDRLEN, 212337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang id, &start, &end) || 213337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang start == nullptr || 214337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang end == nullptr) { 215337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang return false; 216337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang } 217337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang *attribute = NL80211NestedAttr(vector<uint8_t>(start, end)); 218337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang if (!attribute->IsValid()) { 219337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang return false; 220337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang } 221337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang return true; 222337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 223337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 2248c8faa2a8999e5ecbe5b05605946ad66a7a202a4Christopher Wileyvoid NL80211Packet::DebugLog() const { 2258c8faa2a8999e5ecbe5b05605946ad66a7a202a4Christopher Wiley const uint8_t* ptr = data_.data() + NLMSG_HDRLEN + GENL_HDRLEN; 2268c8faa2a8999e5ecbe5b05605946ad66a7a202a4Christopher Wiley const uint8_t* end_ptr = data_.data() + data_.size(); 2278c8faa2a8999e5ecbe5b05605946ad66a7a202a4Christopher Wiley while (ptr + NLA_HDRLEN <= end_ptr) { 2288c8faa2a8999e5ecbe5b05605946ad66a7a202a4Christopher Wiley const nlattr* header = reinterpret_cast<const nlattr*>(ptr); 2298c8faa2a8999e5ecbe5b05605946ad66a7a202a4Christopher Wiley if (ptr + NLA_ALIGN(header->nla_len) > end_ptr) { 2308c8faa2a8999e5ecbe5b05605946ad66a7a202a4Christopher Wiley LOG(ERROR) << "broken nl80211 atrribute."; 2318c8faa2a8999e5ecbe5b05605946ad66a7a202a4Christopher Wiley continue; 2328c8faa2a8999e5ecbe5b05605946ad66a7a202a4Christopher Wiley } 2338c8faa2a8999e5ecbe5b05605946ad66a7a202a4Christopher Wiley LOG(INFO) << "Have attribute with nla_type=" << header->nla_type 2348c8faa2a8999e5ecbe5b05605946ad66a7a202a4Christopher Wiley << " and nla_len=" << header->nla_len; 2358c8faa2a8999e5ecbe5b05605946ad66a7a202a4Christopher Wiley ptr += NLA_ALIGN(header->nla_len); 2368c8faa2a8999e5ecbe5b05605946ad66a7a202a4Christopher Wiley } 2378c8faa2a8999e5ecbe5b05605946ad66a7a202a4Christopher Wiley} 2388c8faa2a8999e5ecbe5b05605946ad66a7a202a4Christopher Wiley 239337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} // namespace wificond 240337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} // namespace android 241