diff options
author | Jeff Sharkey <jsharkey@android.com> | 2014-10-30 14:51:59 -0700 |
---|---|---|
committer | Jeff Sharkey <jsharkey@android.com> | 2015-01-15 12:50:59 -0800 |
commit | 9a20e67fa62c1e0e0080910deec4be82ebecc922 (patch) | |
tree | 6d8c268d95a26bfecc3e574c9df1eb9dea0f5336 /libsysutils | |
parent | 4503a1450ce9b2ed86fd9bd3eb3c34c845e8ed08 (diff) | |
download | system_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.mk | 7 | ||||
-rw-r--r-- | libsysutils/src/NetlinkEvent.cpp | 59 | ||||
-rw-r--r-- | libsysutils/src/NetlinkListener.cpp | 9 |
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); |