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 26337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan WangNL80211Packet::NL80211Packet(const vector<uint8_t>& data) 27337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang : data_(data) { 28337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang data_ = data; 29337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 30337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 31703601782dc0dcf952b16b8c906e623f276b6098Ningyuan WangNL80211Packet::NL80211Packet(const NL80211Packet& packet) { 32703601782dc0dcf952b16b8c906e623f276b6098Ningyuan Wang data_ = packet.data_; 3321ff4c7ad0b0ec8da8392c00eedbae022d6e21e5Ningyuan Wang LOG(WARNING) << "Copy constructor is only used for unit tests"; 34703601782dc0dcf952b16b8c906e623f276b6098Ningyuan Wang} 35703601782dc0dcf952b16b8c906e623f276b6098Ningyuan Wang 367397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan WangNL80211Packet::NL80211Packet(uint16_t type, 377397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang uint8_t command, 387397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang uint32_t sequence, 397397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang uint32_t pid) { 40337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang // Initialize the netlink header and generic netlink header. 41337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang // NLMSG_HDRLEN and GENL_HDRLEN already include the padding size. 42337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang data_.resize(NLMSG_HDRLEN + GENL_HDRLEN, 0); 43337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang // Initialize length field. 44337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang nlmsghdr* nl_header = reinterpret_cast<nlmsghdr*>(data_.data()); 45337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang nl_header->nlmsg_len = data_.size(); 46337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang // Add NLM_F_REQUEST flag. 47337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang nl_header->nlmsg_flags = nl_header->nlmsg_flags | NLM_F_REQUEST; 487397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang nl_header->nlmsg_type = type; 497397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang nl_header->nlmsg_seq = sequence; 507397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang nl_header->nlmsg_pid = pid; 51337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 52337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang genlmsghdr* genl_header = 53337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang reinterpret_cast<genlmsghdr*>(data_.data() + NLMSG_HDRLEN); 54337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang genl_header->version = 1; 557397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang genl_header->cmd = command; 56337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang // genl_header->reserved is aready 0. 57337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 58337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 59337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wangbool NL80211Packet::IsValid() const { 60337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang // Verify the size of packet. 61337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang if (data_.size() < NLMSG_HDRLEN) { 62337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang LOG(ERROR) << "Cannot retrieve netlink header."; 63337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang return false; 64337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang } 65337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 6639f581c0a6e2d9f6943b9b7069b6f096e0e5e858Ningyuan Wang const nlmsghdr* nl_header = reinterpret_cast<const nlmsghdr*>(data_.data()); 6739f581c0a6e2d9f6943b9b7069b6f096e0e5e858Ningyuan Wang 68337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang // If type < NLMSG_MIN_TYPE, this should be a reserved control message, 69337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang // which doesn't carry a generic netlink header. 70337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang if (GetMessageType() >= NLMSG_MIN_TYPE) { 7139f581c0a6e2d9f6943b9b7069b6f096e0e5e858Ningyuan Wang if (data_.size() < NLMSG_HDRLEN + GENL_HDRLEN || 7239f581c0a6e2d9f6943b9b7069b6f096e0e5e858Ningyuan Wang nl_header->nlmsg_len < NLMSG_HDRLEN + GENL_HDRLEN) { 73337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang LOG(ERROR) << "Cannot retrieve generic netlink header."; 74337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang return false; 75337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang } 76337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang } 7739f581c0a6e2d9f6943b9b7069b6f096e0e5e858Ningyuan Wang // If it is an ERROR message, it should be long enough to carry an extra error 7839f581c0a6e2d9f6943b9b7069b6f096e0e5e858Ningyuan Wang // code field. 7939f581c0a6e2d9f6943b9b7069b6f096e0e5e858Ningyuan Wang // Kernel uses int for this field. 8039f581c0a6e2d9f6943b9b7069b6f096e0e5e858Ningyuan Wang if (GetMessageType() == NLMSG_ERROR) { 8139f581c0a6e2d9f6943b9b7069b6f096e0e5e858Ningyuan Wang if (data_.size() < NLMSG_HDRLEN + sizeof(int) || 8239f581c0a6e2d9f6943b9b7069b6f096e0e5e858Ningyuan Wang nl_header->nlmsg_len < NLMSG_HDRLEN + sizeof(int)) { 8339f581c0a6e2d9f6943b9b7069b6f096e0e5e858Ningyuan Wang LOG(ERROR) << "Broken error message."; 8439f581c0a6e2d9f6943b9b7069b6f096e0e5e858Ningyuan Wang return false; 8539f581c0a6e2d9f6943b9b7069b6f096e0e5e858Ningyuan Wang } 8639f581c0a6e2d9f6943b9b7069b6f096e0e5e858Ningyuan Wang } 8739f581c0a6e2d9f6943b9b7069b6f096e0e5e858Ningyuan Wang 88337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang // Verify the netlink header. 89337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang if (data_.size() < nl_header->nlmsg_len || 90337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang nl_header->nlmsg_len < sizeof(nlmsghdr)) { 91337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang LOG(ERROR) << "Discarding incomplete / invalid message."; 92337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang return false; 93337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang } 94337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang return true; 95337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 96337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 97337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wangbool NL80211Packet::IsDump() const { 98337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang return GetFlags() & NLM_F_DUMP; 99337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 100337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 101337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wangbool NL80211Packet::IsMulti() const { 102337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang return GetFlags() & NLM_F_MULTI; 103337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 104337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 105337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wanguint8_t NL80211Packet::GetCommand() const { 106337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang const genlmsghdr* genl_header = reinterpret_cast<const genlmsghdr*>( 107337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang data_.data() + NLMSG_HDRLEN); 108337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang return genl_header->cmd; 109337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 110337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 111337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wanguint16_t NL80211Packet::GetFlags() const { 112337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang const nlmsghdr* nl_header = reinterpret_cast<const nlmsghdr*>(data_.data()); 113337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang return nl_header->nlmsg_flags; 114337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 115337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 116337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wanguint16_t NL80211Packet::GetMessageType() const { 117337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang const nlmsghdr* nl_header = reinterpret_cast<const nlmsghdr*>(data_.data()); 118337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang return nl_header->nlmsg_type; 119337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 120337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 121337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wanguint32_t NL80211Packet::GetMessageSequence() const { 122337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang const nlmsghdr* nl_header = reinterpret_cast<const nlmsghdr*>(data_.data()); 123337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang return nl_header->nlmsg_seq; 124337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 125337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 126337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wanguint32_t NL80211Packet::GetPortId() const { 127337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang const nlmsghdr* nl_header = reinterpret_cast<const nlmsghdr*>(data_.data()); 128337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang return nl_header->nlmsg_pid; 129337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 130337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 13139f581c0a6e2d9f6943b9b7069b6f096e0e5e858Ningyuan Wangint NL80211Packet::GetErrorCode() const { 132c2ec52ae9f449880901d50a45eae070aefba2f36Ningyuan Wang return -*reinterpret_cast<const int*>(data_.data() + NLMSG_HDRLEN); 13339f581c0a6e2d9f6943b9b7069b6f096e0e5e858Ningyuan Wang} 13439f581c0a6e2d9f6943b9b7069b6f096e0e5e858Ningyuan Wang 1357397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wangconst vector<uint8_t>& NL80211Packet::GetConstData() const { 1367397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang return data_; 1377397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang} 1387397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang 139337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wangvoid NL80211Packet::SetCommand(uint8_t command) { 140337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang genlmsghdr* genl_header = reinterpret_cast<genlmsghdr*>( 141337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang data_.data() + NLMSG_HDRLEN); 142337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang genl_header->cmd = command; 143337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 144337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 145e6dce59eaa5f1fcbdfb4b3fc6a60d5cd3b522b06Ningyuan Wangvoid NL80211Packet::AddFlag(uint16_t flag) { 146e6dce59eaa5f1fcbdfb4b3fc6a60d5cd3b522b06Ningyuan Wang nlmsghdr* nl_header = reinterpret_cast<nlmsghdr*>(data_.data()); 147e6dce59eaa5f1fcbdfb4b3fc6a60d5cd3b522b06Ningyuan Wang nl_header->nlmsg_flags |= flag; 148e6dce59eaa5f1fcbdfb4b3fc6a60d5cd3b522b06Ningyuan Wang} 149e6dce59eaa5f1fcbdfb4b3fc6a60d5cd3b522b06Ningyuan Wang 150337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wangvoid NL80211Packet::SetFlags(uint16_t flags) { 151337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang nlmsghdr* nl_header = reinterpret_cast<nlmsghdr*>(data_.data()); 152337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang nl_header->nlmsg_flags = flags; 153337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 154337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 155337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wangvoid NL80211Packet::SetMessageType(uint16_t message_type) { 156337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang nlmsghdr* nl_header = reinterpret_cast<nlmsghdr*>(data_.data()); 157337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang nl_header->nlmsg_type = message_type; 158337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 159337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 160337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wangvoid NL80211Packet::SetMessageSequence(uint32_t message_sequence) { 161337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang nlmsghdr* nl_header = reinterpret_cast<nlmsghdr*>(data_.data()); 162337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang nl_header->nlmsg_seq = message_sequence; 163337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 164337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 165337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wangvoid NL80211Packet::SetPortId(uint32_t pid) { 166337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang nlmsghdr* nl_header = reinterpret_cast<nlmsghdr*>(data_.data()); 167337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang nl_header->nlmsg_pid = pid; 168337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 169337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 170337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wangvoid NL80211Packet::AddAttribute(const BaseNL80211Attr& attribute) { 171337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang const vector<uint8_t>& append_data = attribute.GetConstData(); 172337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang // Append the data of |attribute| to |this|. 173337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang data_.insert(data_.end(), append_data.begin(), append_data.end()); 174337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang nlmsghdr* nl_header = reinterpret_cast<nlmsghdr*>(data_.data()); 175337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang // We don't need to worry about padding for a nl80211 packet. 176337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang // Because as long as all sub attributes have padding, the payload is aligned. 177337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang nl_header->nlmsg_len += append_data.size(); 178337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 179337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 180337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wangvoid NL80211Packet::AddFlagAttribute(int attribute_id) { 181337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang // We only need to append a header for flag attribute. 182337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang // Make space for the new attribute. 183337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang data_.resize(data_.size() + NLA_HDRLEN, 0); 184337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang nlattr* flag_header = 185337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang reinterpret_cast<nlattr*>(data_.data() + data_.size() - NLA_HDRLEN); 186337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang flag_header->nla_type = attribute_id; 187337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang flag_header->nla_len = NLA_HDRLEN; 188337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang nlmsghdr* nl_header = reinterpret_cast<nlmsghdr*>(data_.data()); 189337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang nl_header->nlmsg_len += NLA_HDRLEN; 190337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 191337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 192337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wangbool NL80211Packet::HasAttribute(int id) const { 193337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang return BaseNL80211Attr::GetAttributeImpl( 194337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang data_.data() + NLMSG_HDRLEN + GENL_HDRLEN, 195337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang data_.size() - NLMSG_HDRLEN - GENL_HDRLEN, 196337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang id, nullptr, nullptr); 197337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 198337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 199337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wangbool NL80211Packet::GetAttribute(int id, 200337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang NL80211NestedAttr* attribute) const { 201337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang uint8_t* start = nullptr; 202337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang uint8_t* end = nullptr; 203337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang if (!BaseNL80211Attr::GetAttributeImpl( 204337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang data_.data() + NLMSG_HDRLEN + GENL_HDRLEN, 205337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang data_.size() - NLMSG_HDRLEN - GENL_HDRLEN, 206337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang id, &start, &end) || 207337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang start == nullptr || 208337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang end == nullptr) { 209337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang return false; 210337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang } 211337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang *attribute = NL80211NestedAttr(vector<uint8_t>(start, end)); 212337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang if (!attribute->IsValid()) { 213337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang return false; 214337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang } 215337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang return true; 216337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} 217337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang 2188c8faa2a8999e5ecbe5b05605946ad66a7a202a4Christopher Wileyvoid NL80211Packet::DebugLog() const { 2198c8faa2a8999e5ecbe5b05605946ad66a7a202a4Christopher Wiley const uint8_t* ptr = data_.data() + NLMSG_HDRLEN + GENL_HDRLEN; 2208c8faa2a8999e5ecbe5b05605946ad66a7a202a4Christopher Wiley const uint8_t* end_ptr = data_.data() + data_.size(); 2218c8faa2a8999e5ecbe5b05605946ad66a7a202a4Christopher Wiley while (ptr + NLA_HDRLEN <= end_ptr) { 2228c8faa2a8999e5ecbe5b05605946ad66a7a202a4Christopher Wiley const nlattr* header = reinterpret_cast<const nlattr*>(ptr); 2238c8faa2a8999e5ecbe5b05605946ad66a7a202a4Christopher Wiley if (ptr + NLA_ALIGN(header->nla_len) > end_ptr) { 2248c8faa2a8999e5ecbe5b05605946ad66a7a202a4Christopher Wiley LOG(ERROR) << "broken nl80211 atrribute."; 22517acda64ab273929b2d07b3a57501724242af875Ningyuan Wang return; 2268c8faa2a8999e5ecbe5b05605946ad66a7a202a4Christopher Wiley } 2278c8faa2a8999e5ecbe5b05605946ad66a7a202a4Christopher Wiley LOG(INFO) << "Have attribute with nla_type=" << header->nla_type 2288c8faa2a8999e5ecbe5b05605946ad66a7a202a4Christopher Wiley << " and nla_len=" << header->nla_len; 2296fc05a9b0f0f0c86a4cfb281802d8a66ed1f9948Ningyuan Wang if (header->nla_len == 0) { 2306fc05a9b0f0f0c86a4cfb281802d8a66ed1f9948Ningyuan Wang LOG(ERROR) << "0 is a bad nla_len"; 2316fc05a9b0f0f0c86a4cfb281802d8a66ed1f9948Ningyuan Wang return; 2326fc05a9b0f0f0c86a4cfb281802d8a66ed1f9948Ningyuan Wang } 2338c8faa2a8999e5ecbe5b05605946ad66a7a202a4Christopher Wiley ptr += NLA_ALIGN(header->nla_len); 2348c8faa2a8999e5ecbe5b05605946ad66a7a202a4Christopher Wiley } 2358c8faa2a8999e5ecbe5b05605946ad66a7a202a4Christopher Wiley} 2368c8faa2a8999e5ecbe5b05605946ad66a7a202a4Christopher Wiley 237337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} // namespace wificond 238337a336edb8fc48848883a4c0d7a91e63f445f6fNingyuan Wang} // namespace android 239