Stop depending on libnl.

We only use it for trivial functions. Replace them and drop the
dependency.

Bug: 67345547
Test: bullhead builds, boots
Test: CtsOsTestCases android.os.cts.StrictModeTest passes
Change-Id: I36254962284babdd1a55a32a76dd0dc92d85420c
This commit is contained in:
Lorenzo Colitti 2017-10-03 18:44:11 +09:00
parent 7229576bfe
commit e439ffc762
3 changed files with 44 additions and 11 deletions

View file

@ -23,7 +23,6 @@ cc_library_shared {
"libbase",
"libcutils",
"liblog",
"libnl",
],
export_include_dirs: ["include"],

View file

@ -64,6 +64,7 @@ public:
bool parseNfPacketMessage(struct nlmsghdr *nh);
bool parseRtMessage(const struct nlmsghdr *nh);
bool parseNdUserOptMessage(const struct nlmsghdr *nh);
struct nlattr* findNlAttr(const nlmsghdr* nl, size_t hdrlen, uint16_t attr);
};
#endif

View file

@ -17,6 +17,8 @@
#define LOG_TAG "NetlinkEvent"
#include <arpa/inet.h>
#include <limits.h>
#include <linux/genetlink.h>
#include <linux/if.h>
#include <linux/if_addr.h>
#include <linux/if_link.h>
@ -26,12 +28,8 @@
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/icmp6.h>
#include <netlink/attr.h>
#include <netlink/genl/genl.h>
#include <netlink/handlers.h>
#include <netlink/msg.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
@ -263,6 +261,18 @@ bool NetlinkEvent::parseUlogPacketMessage(const struct nlmsghdr *nh) {
return true;
}
static size_t nlAttrLen(const nlattr* nla) {
return nla->nla_len - NLA_HDRLEN;
}
static const uint8_t* nlAttrData(const nlattr* nla) {
return reinterpret_cast<const uint8_t*>(nla) + NLA_HDRLEN;
}
static uint32_t nlAttrU32(const nlattr* nla) {
return *reinterpret_cast<const uint32_t*>(nlAttrData(nla));
}
/*
* Parse a LOCAL_NFLOG_PACKET message.
*/
@ -271,17 +281,17 @@ bool NetlinkEvent::parseNfPacketMessage(struct nlmsghdr *nh) {
int len = 0;
char* raw = NULL;
struct nlattr *uid_attr = nlmsg_find_attr(nh, sizeof(struct genlmsghdr), NFULA_UID);
struct nlattr* uid_attr = findNlAttr(nh, sizeof(struct genlmsghdr), NFULA_UID);
if (uid_attr) {
uid = ntohl(nla_get_u32(uid_attr));
uid = ntohl(nlAttrU32(uid_attr));
}
struct nlattr *payload = nlmsg_find_attr(nh, sizeof(struct genlmsghdr), NFULA_PAYLOAD);
struct nlattr* payload = findNlAttr(nh, sizeof(struct genlmsghdr), NFULA_PAYLOAD);
if (payload) {
/* First 256 bytes is plenty */
len = nla_len(payload);
len = nlAttrLen(payload);
if (len > 256) len = 256;
raw = (char*) nla_data(payload);
raw = (char*)nlAttrData(payload);
}
char* hex = (char*) calloc(1, 5 + (len * 2));
@ -646,3 +656,26 @@ const char *NetlinkEvent::findParam(const char *paramName) {
SLOGE("NetlinkEvent::FindParam(): Parameter '%s' not found", paramName);
return NULL;
}
nlattr* NetlinkEvent::findNlAttr(const nlmsghdr* nh, size_t hdrlen, uint16_t attr) {
if (nh == nullptr || NLMSG_HDRLEN + NLMSG_ALIGN(hdrlen) > SSIZE_MAX) {
return nullptr;
}
// Skip header, padding, and family header.
const ssize_t NLA_START = NLMSG_HDRLEN + NLMSG_ALIGN(hdrlen);
ssize_t left = nh->nlmsg_len - NLA_START;
uint8_t* hdr = ((uint8_t*)nh) + NLA_START;
while (left >= NLA_HDRLEN) {
nlattr* nla = (nlattr*)hdr;
if (nla->nla_type == attr) {
return nla;
}
hdr += NLA_ALIGN(nla->nla_len);
left -= NLA_ALIGN(nla->nla_len);
}
return nullptr;
}