Add more packet info to nflog packet wakeup events
This patch completes the onWakeupEvent() binder interface of
INetdEventListener with some L2, L3, L4 packet information:
- ethertype
- destination hardware address
- destination ip address if any
- ip protocol if any
- src and dst ports if any
Also for consistency applying globally the transformation:
be16toh -> ntohs
be32toh -> ntohl
htobe16toh -> htons
htobe32toh -> htonl
Bug: 66869042
Test: runtest -x system/netd/server/netd_unit_test.cpp
+ manual testing by monitoring $ dumpsys connmetrics list
Change-Id: I33ef54d5af2e5e667006d853f56f3fe2e82b6a0b
diff --git a/server/WakeupControllerTest.cpp b/server/WakeupControllerTest.cpp
index 05e899c..f7812e5 100644
--- a/server/WakeupControllerTest.cpp
+++ b/server/WakeupControllerTest.cpp
@@ -16,6 +16,12 @@
#include <linux/netfilter/nfnetlink_log.h>
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+
#include <gmock/gmock.h>
#include <gtest/gtest.h>
@@ -32,12 +38,16 @@
namespace android {
namespace net {
+const uint32_t kDefaultPacketCopyRange = WakeupController::kDefaultPacketCopyRange;
+
using netdutils::status::ok;
class MockNetdEventListener {
public:
- MOCK_METHOD4(onWakeupEvent,
- void(const std::string& prefix, uid_t uid, gid_t gid, uint64_t timestampNs));
+ MOCK_METHOD10(onWakeupEvent, void(
+ const std::string& prefix, int uid, int ether, int ipNextHeader,
+ std::vector<uint8_t> dstHw, const std::string& srcIp, const std::string& dstIp,
+ int srcPort, int dstPort, uint64_t timestampNs));
};
class MockIptablesRestore : public IptablesRestoreInterface {
@@ -51,15 +61,19 @@
public:
~MockNFLogListener() override = default;
MOCK_METHOD2(subscribe, netdutils::Status(uint16_t nfLogGroup, const DispatchFn& fn));
+ MOCK_METHOD3(subscribe,
+ netdutils::Status(uint16_t nfLogGroup, uint32_t copyRange, const DispatchFn& fn));
MOCK_METHOD1(unsubscribe, netdutils::Status(uint16_t nfLogGroup));
};
class WakeupControllerTest : public Test {
protected:
WakeupControllerTest() {
- EXPECT_CALL(mListener, subscribe(NetlinkManager::NFLOG_WAKEUP_GROUP, _))
- .WillOnce(DoAll(SaveArg<1>(&mMessageHandler), Return(ok)));
- EXPECT_CALL(mListener, unsubscribe(NetlinkManager::NFLOG_WAKEUP_GROUP)).WillOnce(Return(ok));
+ EXPECT_CALL(mListener,
+ subscribe(NetlinkManager::NFLOG_WAKEUP_GROUP, kDefaultPacketCopyRange, _))
+ .WillOnce(DoAll(SaveArg<2>(&mMessageHandler), Return(ok)));
+ EXPECT_CALL(mListener,
+ unsubscribe(NetlinkManager::NFLOG_WAKEUP_GROUP)).WillOnce(Return(ok));
mController.init(&mListener);
}
@@ -67,14 +81,16 @@
StrictMock<MockIptablesRestore> mIptables;
StrictMock<MockNFLogListener> mListener;
WakeupController mController{
- [this](const std::string& prefix, uid_t uid, gid_t gid, uint64_t timestampNs) {
- mEventListener.onWakeupEvent(prefix, uid, gid, timestampNs);
+ [this](const WakeupController::ReportArgs& args) {
+ mEventListener.onWakeupEvent(args.prefix, args.uid, args.ethertype, args.ipNextHeader,
+ args.dstHw, args.srcIp, args.dstIp, args.srcPort,
+ args.dstPort, args.timestampNs);
},
&mIptables};
NFLogListenerInterface::DispatchFn mMessageHandler;
};
-TEST_F(WakeupControllerTest, msgHandler) {
+TEST_F(WakeupControllerTest, msgHandlerWithPartialAttributes) {
const char kPrefix[] = "test:prefix";
const uid_t kUid = 8734;
const gid_t kGid = 2222;
@@ -96,23 +112,100 @@
msg.uidAttr.nla_type = NFULA_UID;
msg.uidAttr.nla_len = sizeof(msg.uidAttr) + sizeof(msg.uid);
- msg.uid = htobe32(kUid);
+ msg.uid = htonl(kUid);
msg.gidAttr.nla_type = NFULA_GID;
msg.gidAttr.nla_len = sizeof(msg.gidAttr) + sizeof(msg.gid);
- msg.gid = htobe32(kGid);
+ msg.gid = htonl(kGid);
msg.tsAttr.nla_type = NFULA_TIMESTAMP;
msg.tsAttr.nla_len = sizeof(msg.tsAttr) + sizeof(msg.ts);
- msg.ts.tv_sec = htobe32(kTsNs / kNsPerS);
- msg.ts.tv_nsec = htobe32(kTsNs % kNsPerS);
+ msg.ts.tv_sec = htonl(kTsNs / kNsPerS);
+ msg.ts.tv_nsec = htonl(kTsNs % kNsPerS);
msg.prefixAttr.nla_type = NFULA_PREFIX;
msg.prefixAttr.nla_len = sizeof(msg.prefixAttr) + sizeof(msg.prefix);
memcpy(msg.prefix, kPrefix, sizeof(kPrefix));
auto payload = drop(netdutils::makeSlice(msg), offsetof(Msg, uidAttr));
- EXPECT_CALL(mEventListener, onWakeupEvent(kPrefix, kUid, kGid, kTsNs));
+ EXPECT_CALL(mEventListener,
+ onWakeupEvent(kPrefix, kUid, -1, -1, std::vector<uint8_t>(), "", "", -1, -1, kTsNs));
+ mMessageHandler(msg.nlmsg, msg.nfmsg, payload);
+}
+
+TEST_F(WakeupControllerTest, msgHandler) {
+ const char kPrefix[] = "test:prefix";
+ const uid_t kUid = 8734;
+ const gid_t kGid = 2222;
+ const std::vector<uint8_t> kMacAddr = {11, 22, 33, 44, 55, 66};
+ const char* kSrcIpAddr = "192.168.2.1";
+ const char* kDstIpAddr = "192.168.2.23";
+ const uint16_t kEthertype = 0x800;
+ const uint8_t kIpNextHeader = 6;
+ const uint16_t kSrcPort = 1238;
+ const uint16_t kDstPort = 4567;
+ const uint64_t kNsPerS = 1000000000ULL;
+ const uint64_t kTsNs = 9999 + (34 * kNsPerS);
+
+ struct Msg {
+ nlmsghdr nlmsg;
+ nfgenmsg nfmsg;
+ nlattr uidAttr;
+ uid_t uid;
+ nlattr gidAttr;
+ gid_t gid;
+ nlattr tsAttr;
+ timespec ts;
+ nlattr prefixAttr;
+ char prefix[sizeof(kPrefix)];
+ nlattr packetHeaderAttr;
+ struct nfulnl_msg_packet_hdr packetHeader;
+ nlattr hardwareAddrAttr;
+ struct nfulnl_msg_packet_hw hardwareAddr;
+ nlattr packetPayloadAttr;
+ struct iphdr ipHeader;
+ struct tcphdr tcpHeader;
+ } msg = {};
+
+ msg.prefixAttr.nla_type = NFULA_PREFIX;
+ msg.prefixAttr.nla_len = sizeof(msg.prefixAttr) + sizeof(msg.prefix);
+ memcpy(msg.prefix, kPrefix, sizeof(kPrefix));
+
+ msg.uidAttr.nla_type = NFULA_UID;
+ msg.uidAttr.nla_len = sizeof(msg.uidAttr) + sizeof(msg.uid);
+ msg.uid = htonl(kUid);
+
+ msg.gidAttr.nla_type = NFULA_GID;
+ msg.gidAttr.nla_len = sizeof(msg.gidAttr) + sizeof(msg.gid);
+ msg.gid = htonl(kGid);
+
+ msg.tsAttr.nla_type = NFULA_TIMESTAMP;
+ msg.tsAttr.nla_len = sizeof(msg.tsAttr) + sizeof(msg.ts);
+ msg.ts.tv_sec = htonl(kTsNs / kNsPerS);
+ msg.ts.tv_nsec = htonl(kTsNs % kNsPerS);
+
+ msg.packetHeaderAttr.nla_type = NFULA_PACKET_HDR;
+ msg.packetHeaderAttr.nla_len = sizeof(msg.packetHeaderAttr) + sizeof(msg.packetHeader);
+ msg.packetHeader.hw_protocol = htons(kEthertype);
+
+ msg.hardwareAddrAttr.nla_type = NFULA_HWADDR;
+ msg.hardwareAddrAttr.nla_len = sizeof(msg.hardwareAddrAttr) + sizeof(msg.hardwareAddr);
+ msg.hardwareAddr.hw_addrlen = htons(kMacAddr.size());
+ std::copy(kMacAddr.begin(), kMacAddr.end(), msg.hardwareAddr.hw_addr);
+
+ msg.packetPayloadAttr.nla_type = NFULA_PAYLOAD;
+ msg.packetPayloadAttr.nla_len =
+ sizeof(msg.packetPayloadAttr) + sizeof(msg.ipHeader) + sizeof(msg.tcpHeader);
+ msg.ipHeader.protocol = IPPROTO_TCP;
+ msg.ipHeader.ihl = sizeof(msg.ipHeader) / 4; // ipv4 IHL counts 32 bit words.
+ inet_pton(AF_INET, kSrcIpAddr, &msg.ipHeader.saddr);
+ inet_pton(AF_INET, kDstIpAddr, &msg.ipHeader.daddr);
+ msg.tcpHeader.th_sport = htons(kSrcPort);
+ msg.tcpHeader.th_dport = htons(kDstPort);
+
+ auto payload = drop(netdutils::makeSlice(msg), offsetof(Msg, uidAttr));
+ EXPECT_CALL(mEventListener, onWakeupEvent(kPrefix, kUid, kEthertype, kIpNextHeader, kMacAddr,
+ kSrcIpAddr, kDstIpAddr, kSrcPort, kDstPort, kTsNs));
mMessageHandler(msg.nlmsg, msg.nfmsg, payload);
}
@@ -140,7 +233,7 @@
msg.uidAttr.nla_type = 999;
msg.uidAttr.nla_len = sizeof(msg.uidAttr) + sizeof(msg.uid);
- msg.uid = htobe32(kUid);
+ msg.uid = htonl(kUid);
msg.invalid0.nla_type = 0;
msg.invalid0.nla_len = 0;
@@ -149,19 +242,20 @@
msg.gidAttr.nla_type = NFULA_GID;
msg.gidAttr.nla_len = sizeof(msg.gidAttr) + sizeof(msg.gid);
- msg.gid = htobe32(kGid);
+ msg.gid = htonl(kGid);
msg.tsAttr.nla_type = NFULA_TIMESTAMP;
msg.tsAttr.nla_len = sizeof(msg.tsAttr) - 2;
- msg.ts.tv_sec = htobe32(kTsNs / kNsPerS);
- msg.ts.tv_nsec = htobe32(kTsNs % kNsPerS);
+ msg.ts.tv_sec = htonl(kTsNs / kNsPerS);
+ msg.ts.tv_nsec = htonl(kTsNs % kNsPerS);
msg.prefixAttr.nla_type = NFULA_UID;
msg.prefixAttr.nla_len = sizeof(msg.prefixAttr) + sizeof(msg.prefix);
memcpy(msg.prefix, kPrefix, sizeof(kPrefix));
auto payload = drop(netdutils::makeSlice(msg), offsetof(Msg, uidAttr));
- EXPECT_CALL(mEventListener, onWakeupEvent("", 1952805748, kGid, 0));
+ EXPECT_CALL(mEventListener,
+ onWakeupEvent("", 1952805748, -1, -1, std::vector<uint8_t>(), "", "", -1, -1, 0));
mMessageHandler(msg.nlmsg, msg.nfmsg, payload);
}
@@ -182,7 +276,8 @@
const auto expected = std::string(ones, sizeof(ones) - 1);
auto payload = drop(netdutils::makeSlice(msg), offsetof(Msg, prefixAttr));
- EXPECT_CALL(mEventListener, onWakeupEvent(expected, -1, -1, -1));
+ EXPECT_CALL(mEventListener,
+ onWakeupEvent(expected, -1, -1, -1, std::vector<uint8_t>(), "", "", -1, -1, 0));
mMessageHandler(msg.nlmsg, msg.nfmsg, payload);
}
@@ -194,7 +289,7 @@
const char kExpected[] =
"*mangle\n-A wakeupctrl_mangle_INPUT -i test:prefix"
" -j NFLOG --nflog-prefix wlan8 --nflog-group 3 --nflog-threshold 8"
- " -m mark --mark 0x12345678/0x0f0f0f0f -m limit --limit 10/s\nCOMMIT\n";
+ " --nflog-range 60 -m mark --mark 0x12345678/0x0f0f0f0f -m limit --limit 10/s\nCOMMIT\n";
EXPECT_CALL(mIptables, execute(V4V6, kExpected, _)).WillOnce(Return(0));
mController.addInterface(kPrefix, kIfName, kMark, kMask);
}
@@ -207,7 +302,7 @@
const char kExpected[] =
"*mangle\n-D wakeupctrl_mangle_INPUT -i test:prefix"
" -j NFLOG --nflog-prefix wlan8 --nflog-group 3 --nflog-threshold 8"
- " -m mark --mark 0x12345678/0xf0f0f0f0 -m limit --limit 10/s\nCOMMIT\n";
+ " --nflog-range 60 -m mark --mark 0x12345678/0xf0f0f0f0 -m limit --limit 10/s\nCOMMIT\n";
EXPECT_CALL(mIptables, execute(V4V6, kExpected, _)).WillOnce(Return(0));
mController.delInterface(kPrefix, kIfName, kMark, kMask);
}