summaryrefslogtreecommitdiffstats
path: root/libsysutils
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2014-10-30 14:51:59 -0700
committerJeff Sharkey <jsharkey@android.com>2015-01-15 12:50:59 -0800
commit9a20e67fa62c1e0e0080910deec4be82ebecc922 (patch)
tree6d8c268d95a26bfecc3e574c9df1eb9dea0f5336 /libsysutils
parent4503a1450ce9b2ed86fd9bd3eb3c34c845e8ed08 (diff)
downloadsystem_core-9a20e67fa62c1e0e0080910deec4be82ebecc922.tar.gz
system_core-9a20e67fa62c1e0e0080910deec4be82ebecc922.tar.bz2
system_core-9a20e67fa62c1e0e0080910deec4be82ebecc922.zip
Extend to receive NFLOG packets.
Packets captured and logged by the NFLOG target are unicast, so extend to catch and decode them. To avoid escaping issues, the raw contents are passed around as hex strings. Bug: 18335678 Change-Id: Ib7299500baa00080a1f000f9da843eb527363353
Diffstat (limited to 'libsysutils')
-rw-r--r--libsysutils/Android.mk7
-rw-r--r--libsysutils/src/NetlinkEvent.cpp59
-rw-r--r--libsysutils/src/NetlinkListener.cpp9
3 files changed, 65 insertions, 10 deletions
diff --git a/libsysutils/Android.mk b/libsysutils/Android.mk
index 246f954cb..b902a8191 100644
--- a/libsysutils/Android.mk
+++ b/libsysutils/Android.mk
@@ -16,11 +16,12 @@ LOCAL_SRC_FILES:= \
LOCAL_MODULE:= libsysutils
-LOCAL_C_INCLUDES :=
-
LOCAL_CFLAGS := -Werror
-LOCAL_SHARED_LIBRARIES := libcutils liblog
+LOCAL_SHARED_LIBRARIES := \
+ libcutils \
+ liblog \
+ libnl
include $(BUILD_SHARED_LIBRARY)
diff --git a/libsysutils/src/NetlinkEvent.cpp b/libsysutils/src/NetlinkEvent.cpp
index 9d596ef55..909df8647 100644
--- a/libsysutils/src/NetlinkEvent.cpp
+++ b/libsysutils/src/NetlinkEvent.cpp
@@ -32,13 +32,21 @@
#include <linux/if_addr.h>
#include <linux/if_link.h>
#include <linux/netfilter/nfnetlink.h>
+#include <linux/netfilter/nfnetlink_log.h>
#include <linux/netfilter_ipv4/ipt_ULOG.h>
+
/* From kernel's net/netfilter/xt_quota2.c */
-const int QLOG_NL_EVENT = 112;
+const int LOCAL_QLOG_NL_EVENT = 112;
+const int LOCAL_NFLOG_PACKET = NFNL_SUBSYS_ULOG << 8 | NFULNL_MSG_PACKET;
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
+#include <netlink/attr.h>
+#include <netlink/genl/genl.h>
+#include <netlink/handlers.h>
+#include <netlink/msg.h>
+
const int NetlinkEvent::NlActionUnknown = 0;
const int NetlinkEvent::NlActionAdd = 1;
const int NetlinkEvent::NlActionRemove = 2;
@@ -95,7 +103,8 @@ static const char *rtMessageName(int type) {
NL_EVENT_RTM_NAME(RTM_NEWROUTE);
NL_EVENT_RTM_NAME(RTM_DELROUTE);
NL_EVENT_RTM_NAME(RTM_NEWNDUSEROPT);
- NL_EVENT_RTM_NAME(QLOG_NL_EVENT);
+ NL_EVENT_RTM_NAME(LOCAL_QLOG_NL_EVENT);
+ NL_EVENT_RTM_NAME(LOCAL_NFLOG_PACKET);
default:
return NULL;
}
@@ -272,6 +281,41 @@ bool NetlinkEvent::parseUlogPacketMessage(const struct nlmsghdr *nh) {
}
/*
+ * Parse a LOCAL_NFLOG_PACKET message.
+ */
+bool NetlinkEvent::parseNfPacketMessage(struct nlmsghdr *nh) {
+ int uid = -1;
+ int len = 0;
+ char* raw = NULL;
+
+ struct nlattr *uid_attr = nlmsg_find_attr(nh, sizeof(struct genlmsghdr), NFULA_UID);
+ if (uid_attr) {
+ uid = ntohl(nla_get_u32(uid_attr));
+ }
+
+ struct nlattr *payload = nlmsg_find_attr(nh, sizeof(struct genlmsghdr), NFULA_PAYLOAD);
+ if (payload) {
+ /* First 256 bytes is plenty */
+ len = nla_len(payload);
+ if (len > 256) len = 256;
+ raw = (char*) nla_data(payload);
+ }
+
+ char* hex = (char*) calloc(1, 5 + (len * 2));
+ strcpy(hex, "HEX=");
+ for (int i = 0; i < len; i++) {
+ hex[4 + (i * 2)] = "0123456789abcdef"[(raw[i] >> 4) & 0xf];
+ hex[5 + (i * 2)] = "0123456789abcdef"[raw[i] & 0xf];
+ }
+
+ asprintf(&mParams[0], "UID=%d", uid);
+ mParams[1] = hex;
+ mSubsystem = strdup("strict");
+ mAction = NlActionChange;
+ return true;
+}
+
+/*
* Parse a RTM_NEWROUTE or RTM_DELROUTE message.
*/
bool NetlinkEvent::parseRtMessage(const struct nlmsghdr *nh) {
@@ -478,7 +522,7 @@ bool NetlinkEvent::parseNdUserOptMessage(const struct nlmsghdr *nh) {
* TODO: consider only ever looking at the first message.
*/
bool NetlinkEvent::parseBinaryNetlinkMessage(char *buffer, int size) {
- const struct nlmsghdr *nh;
+ struct nlmsghdr *nh;
for (nh = (struct nlmsghdr *) buffer;
NLMSG_OK(nh, (unsigned) size) && (nh->nlmsg_type != NLMSG_DONE);
@@ -493,7 +537,7 @@ bool NetlinkEvent::parseBinaryNetlinkMessage(char *buffer, int size) {
if (parseIfInfoMessage(nh))
return true;
- } else if (nh->nlmsg_type == QLOG_NL_EVENT) {
+ } else if (nh->nlmsg_type == LOCAL_QLOG_NL_EVENT) {
if (parseUlogPacketMessage(nh))
return true;
@@ -511,6 +555,10 @@ bool NetlinkEvent::parseBinaryNetlinkMessage(char *buffer, int size) {
if (parseNdUserOptMessage(nh))
return true;
+ } else if (nh->nlmsg_type == LOCAL_NFLOG_PACKET) {
+ if (parseNfPacketMessage(nh))
+ return true;
+
}
}
@@ -588,7 +636,8 @@ bool NetlinkEvent::parseAsciiNetlinkMessage(char *buffer, int size) {
}
bool NetlinkEvent::decode(char *buffer, int size, int format) {
- if (format == NetlinkListener::NETLINK_FORMAT_BINARY) {
+ if (format == NetlinkListener::NETLINK_FORMAT_BINARY
+ || format == NetlinkListener::NETLINK_FORMAT_BINARY_UNICAST) {
return parseBinaryNetlinkMessage(buffer, size);
} else {
return parseAsciiNetlinkMessage(buffer, size);
diff --git a/libsysutils/src/NetlinkListener.cpp b/libsysutils/src/NetlinkListener.cpp
index 81c5cc239..637aa1ea3 100644
--- a/libsysutils/src/NetlinkListener.cpp
+++ b/libsysutils/src/NetlinkListener.cpp
@@ -47,8 +47,13 @@ bool NetlinkListener::onDataAvailable(SocketClient *cli)
ssize_t count;
uid_t uid = -1;
- count = TEMP_FAILURE_RETRY(uevent_kernel_multicast_uid_recv(
- socket, mBuffer, sizeof(mBuffer), &uid));
+ bool require_group = true;
+ if (mFormat == NETLINK_FORMAT_BINARY_UNICAST) {
+ require_group = false;
+ }
+
+ count = TEMP_FAILURE_RETRY(uevent_kernel_recv(socket,
+ mBuffer, sizeof(mBuffer), require_group, &uid));
if (count < 0) {
if (uid > 0)
LOG_EVENT_INT(65537, uid);