X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=server%2FNetlinkManager.cpp;h=76af46f64a3ff4e4538c76658e16846cfa27cb76;hb=397fbc056c1ae1478f0311feab3a8a44cc6a4685;hp=32578a1d6ec6d11e461f83ad1dddc17a57467f2c;hpb=a0817988748a4643041495751997ba9249b8c5ea;p=android-x86%2Fsystem-netd.git diff --git a/server/NetlinkManager.cpp b/server/NetlinkManager.cpp index 32578a1..76af46f 100644 --- a/server/NetlinkManager.cpp +++ b/server/NetlinkManager.cpp @@ -30,10 +30,24 @@ #include +#include +#include +#include +#include + +#include +#include +#include + +#include + #include "NetlinkManager.h" #include "NetlinkHandler.h" +#include "pcap-netfilter-linux-android.h" + const int NetlinkManager::NFLOG_QUOTA_GROUP = 1; +const int NetlinkManager::NETFILTER_STRICT_GROUP = 2; NetlinkManager *NetlinkManager::sInstance = NULL; @@ -51,7 +65,7 @@ NetlinkManager::~NetlinkManager() { } NetlinkHandler *NetlinkManager::setupSocket(int *sock, int netlinkFamily, - int groups, int format) { + int groups, int format, bool configNflog) { struct sockaddr_nl nladdr; int sz = 64 * 1024; @@ -62,7 +76,7 @@ NetlinkHandler *NetlinkManager::setupSocket(int *sock, int netlinkFamily, nladdr.nl_pid = getpid(); nladdr.nl_groups = groups; - if ((*sock = socket(PF_NETLINK, SOCK_DGRAM, netlinkFamily)) < 0) { + if ((*sock = socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, netlinkFamily)) < 0) { ALOGE("Unable to create netlink socket: %s", strerror(errno)); return NULL; } @@ -85,6 +99,21 @@ NetlinkHandler *NetlinkManager::setupSocket(int *sock, int netlinkFamily, return NULL; } + if (configNflog) { + if (android_nflog_send_config_cmd(*sock, 0, NFULNL_CFG_CMD_PF_UNBIND, AF_INET) < 0) { + ALOGE("Failed NFULNL_CFG_CMD_PF_UNBIND: %s", strerror(errno)); + return NULL; + } + if (android_nflog_send_config_cmd(*sock, 0, NFULNL_CFG_CMD_PF_BIND, AF_INET) < 0) { + ALOGE("Failed NFULNL_CFG_CMD_PF_BIND: %s", strerror(errno)); + return NULL; + } + if (android_nflog_send_config_cmd(*sock, 0, NFULNL_CFG_CMD_BIND, AF_UNSPEC) < 0) { + ALOGE("Failed NFULNL_CFG_CMD_BIND: %s", strerror(errno)); + return NULL; + } + } + NetlinkHandler *handler = new NetlinkHandler(this, *sock, format); if (handler->start()) { ALOGE("Unable to start NetlinkHandler: %s", strerror(errno)); @@ -97,7 +126,7 @@ NetlinkHandler *NetlinkManager::setupSocket(int *sock, int netlinkFamily, int NetlinkManager::start() { if ((mUeventHandler = setupSocket(&mUeventSock, NETLINK_KOBJECT_UEVENT, - 0xffffffff, NetlinkListener::NETLINK_FORMAT_ASCII)) == NULL) { + 0xffffffff, NetlinkListener::NETLINK_FORMAT_ASCII, false)) == NULL) { return -1; } @@ -105,14 +134,21 @@ int NetlinkManager::start() { RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR | + RTMGRP_IPV6_ROUTE | (1 << (RTNLGRP_ND_USEROPT - 1)), - NetlinkListener::NETLINK_FORMAT_BINARY)) == NULL) { + NetlinkListener::NETLINK_FORMAT_BINARY, false)) == NULL) { return -1; } if ((mQuotaHandler = setupSocket(&mQuotaSock, NETLINK_NFLOG, - NFLOG_QUOTA_GROUP, NetlinkListener::NETLINK_FORMAT_BINARY)) == NULL) { - ALOGE("Unable to open quota2 logging socket"); + NFLOG_QUOTA_GROUP, NetlinkListener::NETLINK_FORMAT_BINARY, false)) == NULL) { + ALOGE("Unable to open quota socket"); + // TODO: return -1 once the emulator gets a new kernel. + } + + if ((mStrictHandler = setupSocket(&mStrictSock, NETLINK_NETFILTER, + 0, NetlinkListener::NETLINK_FORMAT_BINARY_UNICAST, true)) == NULL) { + ALOGE("Unable to open strict socket"); // TODO: return -1 once the emulator gets a new kernel. } @@ -157,5 +193,18 @@ int NetlinkManager::stop() { mQuotaSock = -1; } + if (mStrictHandler) { + if (mStrictHandler->stop()) { + ALOGE("Unable to stop strict NetlinkHandler: %s", strerror(errno)); + status = -1; + } + + delete mStrictHandler; + mStrictHandler = NULL; + + close(mStrictSock); + mStrictSock = -1; + } + return status; }