summaryrefslogtreecommitdiffstats
path: root/libsysutils
diff options
context:
space:
mode:
Diffstat (limited to 'libsysutils')
-rw-r--r--libsysutils/Android.mk10
-rw-r--r--libsysutils/src/NetlinkEvent.cpp59
-rw-r--r--libsysutils/src/NetlinkListener.cpp9
-rw-r--r--libsysutils/src/SocketClient.cpp5
4 files changed, 69 insertions, 14 deletions
diff --git a/libsysutils/Android.mk b/libsysutils/Android.mk
index 246f954..7bf53e3 100644
--- a/libsysutils/Android.mk
+++ b/libsysutils/Android.mk
@@ -1,5 +1,3 @@
-ifneq ($(BUILD_TINY_ANDROID),true)
-
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
@@ -16,12 +14,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)
-endif
diff --git a/libsysutils/src/NetlinkEvent.cpp b/libsysutils/src/NetlinkEvent.cpp
index 9d596ef..909df86 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 81c5cc2..637aa1e 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);
diff --git a/libsysutils/src/SocketClient.cpp b/libsysutils/src/SocketClient.cpp
index d3ce8f5..bb9b6a1 100644
--- a/libsysutils/src/SocketClient.cpp
+++ b/libsysutils/src/SocketClient.cpp
@@ -1,5 +1,6 @@
#include <alloca.h>
#include <errno.h>
+#include <malloc.h>
#include <pthread.h>
#include <signal.h>
#include <string.h>
@@ -220,7 +221,9 @@ int SocketClient::sendDataLockedv(struct iovec *iov, int iovcnt) {
sigaction(SIGPIPE, &old_action, &new_action);
- errno = e;
+ if (e != 0) {
+ errno = e;
+ }
return ret;
}