18464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti/* 28464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti * Copyright (C) 2016 The Android Open Source Project 38464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti * 48464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti * Licensed under the Apache License, Version 2.0 (the "License"); 58464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti * you may not use this file except in compliance with the License. 68464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti * You may obtain a copy of the License at 78464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti * 88464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti * http://www.apache.org/licenses/LICENSE-2.0 98464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti * 108464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti * Unless required by applicable law or agreed to in writing, software 118464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti * distributed under the License is distributed on an "AS IS" BASIS, 128464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti * See the License for the specific language governing permissions and 148464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti * limitations under the License. 158464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti */ 168464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 178464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti#include <errno.h> 188464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti#include <netdb.h> 198464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti#include <string.h> 208464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti#include <netinet/in.h> 218464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti#include <netinet/tcp.h> 228464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti#include <sys/socket.h> 238464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti#include <sys/uio.h> 248464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 258464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti#include <linux/netlink.h> 268464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti#include <linux/sock_diag.h> 278464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti#include <linux/inet_diag.h> 288464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 298464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti#define LOG_TAG "Netd" 308464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 31fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti#include <android-base/strings.h> 328464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti#include <cutils/log.h> 338464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 348464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti#include "NetdConstants.h" 358464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti#include "SockDiag.h" 368464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 37f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti#include <chrono> 38f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti 398464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti#ifndef SOCK_DESTROY 408464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti#define SOCK_DESTROY 21 418464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti#endif 428464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 438464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colittinamespace { 448464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 458464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colittistruct AddrinfoDeleter { 468464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti void operator()(addrinfo *a) { if (a) freeaddrinfo(a); } 478464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti}; 488464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 498464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colittitypedef std::unique_ptr<addrinfo, AddrinfoDeleter> ScopedAddrinfo; 508464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 518464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colittiint checkError(int fd) { 528464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti struct { 538464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti nlmsghdr h; 548464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti nlmsgerr err; 558464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti } __attribute__((__packed__)) ack; 568464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti ssize_t bytesread = recv(fd, &ack, sizeof(ack), MSG_DONTWAIT | MSG_PEEK); 578464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti if (bytesread == -1) { 588464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti // Read failed (error), or nothing to read (good). 598464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti return (errno == EAGAIN) ? 0 : -errno; 608464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti } else if (bytesread == (ssize_t) sizeof(ack) && ack.h.nlmsg_type == NLMSG_ERROR) { 618464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti // We got an error. Consume it. 628464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti recv(fd, &ack, sizeof(ack), 0); 638464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti return ack.err.error; 648464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti } else { 658464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti // The kernel replied with something. Leave it to the caller. 668464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti return 0; 678464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti } 688464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti} 698464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 708464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti} // namespace 718464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 728464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colittibool SockDiag::open() { 738464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti if (hasSocks()) { 748464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti return false; 758464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti } 768464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 778464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti mSock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_INET_DIAG); 788464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti mWriteSock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_INET_DIAG); 798464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti if (!hasSocks()) { 808464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti closeSocks(); 818464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti return false; 828464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti } 838464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 848464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti sockaddr_nl nl = { .nl_family = AF_NETLINK }; 858464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti if ((connect(mSock, reinterpret_cast<sockaddr *>(&nl), sizeof(nl)) == -1) || 868464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti (connect(mWriteSock, reinterpret_cast<sockaddr *>(&nl), sizeof(nl)) == -1)) { 878464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti closeSocks(); 888464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti return false; 898464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti } 908464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 918464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti return true; 928464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti} 938464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 9494a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colittiint SockDiag::sendDumpRequest(uint8_t proto, uint8_t family, uint32_t states, 9594a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti iovec *iov, int iovcnt) { 9694a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti struct { 9794a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti nlmsghdr nlh; 9894a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti inet_diag_req_v2 req; 9994a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti } __attribute__((__packed__)) request = { 10094a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti .nlh = { 10194a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti .nlmsg_type = SOCK_DIAG_BY_FAMILY, 10294a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti .nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP, 10394a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti }, 10494a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti .req = { 10594a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti .sdiag_family = family, 10694a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti .sdiag_protocol = proto, 10794a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti .idiag_states = states, 10894a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti }, 10994a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti }; 11094a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti 11194a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti size_t len = 0; 11294a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti iov[0].iov_base = &request; 11394a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti iov[0].iov_len = sizeof(request); 11494a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti for (int i = 0; i < iovcnt; i++) { 11594a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti len += iov[i].iov_len; 11694a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti } 11794a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti request.nlh.nlmsg_len = len; 11894a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti 11994a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti if (writev(mSock, iov, iovcnt) != (ssize_t) len) { 12094a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti return -errno; 12194a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti } 12294a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti 12394a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti return checkError(mSock); 12494a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti} 12594a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti 12694a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colittiint SockDiag::sendDumpRequest(uint8_t proto, uint8_t family, uint32_t states) { 12794a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti iovec iov[] = { 12894a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti { nullptr, 0 }, 12994a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti }; 13094a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti return sendDumpRequest(proto, family, states, iov, ARRAY_SIZE(iov)); 13194a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti} 13294a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti 1338464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colittiint SockDiag::sendDumpRequest(uint8_t proto, uint8_t family, const char *addrstr) { 1348464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti addrinfo hints = { .ai_flags = AI_NUMERICHOST }; 1358464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti addrinfo *res; 1368464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti in6_addr mapped = { .s6_addr32 = { 0, 0, htonl(0xffff), 0 } }; 1378464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti int ret; 1388464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 1398464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti // TODO: refactor the netlink parsing code out of system/core, bring it into netd, and stop 1408464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti // doing string conversions when they're not necessary. 1418464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti if ((ret = getaddrinfo(addrstr, nullptr, &hints, &res)) != 0) { 1428464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti return -EINVAL; 1438464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti } 1448464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 1458464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti // So we don't have to call freeaddrinfo on every failure path. 1468464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti ScopedAddrinfo resP(res); 1478464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 1488464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti void *addr; 1498464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti uint8_t addrlen; 1508464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti if (res->ai_family == AF_INET && family == AF_INET) { 1518464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti in_addr& ina = reinterpret_cast<sockaddr_in*>(res->ai_addr)->sin_addr; 1528464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti addr = &ina; 1538464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti addrlen = sizeof(ina); 1548464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti } else if (res->ai_family == AF_INET && family == AF_INET6) { 1558464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti in_addr& ina = reinterpret_cast<sockaddr_in*>(res->ai_addr)->sin_addr; 1568464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti mapped.s6_addr32[3] = ina.s_addr; 1578464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti addr = &mapped; 1588464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti addrlen = sizeof(mapped); 1598464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti } else if (res->ai_family == AF_INET6 && family == AF_INET6) { 1608464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti in6_addr& in6a = reinterpret_cast<sockaddr_in6*>(res->ai_addr)->sin6_addr; 1618464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti addr = &in6a; 1628464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti addrlen = sizeof(in6a); 1638464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti } else { 1648464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti return -EAFNOSUPPORT; 1658464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti } 1668464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 1678464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti uint8_t prefixlen = addrlen * 8; 1688464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti uint8_t yesjump = sizeof(inet_diag_bc_op) + sizeof(inet_diag_hostcond) + addrlen; 1698464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti uint8_t nojump = yesjump + 4; 1708464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 1718464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti struct { 1728464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti nlattr nla; 1738464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti inet_diag_bc_op op; 1748464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti inet_diag_hostcond cond; 17594a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti } __attribute__((__packed__)) attrs = { 1768464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti .nla = { 1778464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti .nla_type = INET_DIAG_REQ_BYTECODE, 1788464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti }, 1798464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti .op = { 1808464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti INET_DIAG_BC_S_COND, 1818464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti yesjump, 1828464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti nojump, 1838464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti }, 1848464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti .cond = { 1858464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti family, 1868464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti prefixlen, 1878464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti -1, 1888464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti {} 1898464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti }, 1908464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti }; 1918464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 19294a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti attrs.nla.nla_len = sizeof(attrs) + addrlen; 1938464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 19494a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti iovec iov[] = { 19594a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti { nullptr, 0 }, 19694a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti { &attrs, sizeof(attrs) }, 1978464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti { addr, addrlen }, 1988464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti }; 1998464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 20094a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti uint32_t states = ~(1 << TCP_TIME_WAIT); 20194a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti return sendDumpRequest(proto, family, states, iov, ARRAY_SIZE(iov)); 2028464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti} 2038464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 2048464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colittiint SockDiag::readDiagMsg(uint8_t proto, SockDiag::DumpCallback callback) { 2058464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti char buf[kBufferSize]; 2068464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 2078464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti ssize_t bytesread; 2088464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti do { 2098464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti bytesread = read(mSock, buf, sizeof(buf)); 2108464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 2118464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti if (bytesread < 0) { 2128464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti return -errno; 2138464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti } 2148464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 2158464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti uint32_t len = bytesread; 2168464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti for (nlmsghdr *nlh = reinterpret_cast<nlmsghdr *>(buf); 2178464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti NLMSG_OK(nlh, len); 2188464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti nlh = NLMSG_NEXT(nlh, len)) { 2198464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti switch (nlh->nlmsg_type) { 2208464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti case NLMSG_DONE: 2218464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti callback(proto, NULL); 2228464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti return 0; 2238464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti case NLMSG_ERROR: { 2248464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti nlmsgerr *err = reinterpret_cast<nlmsgerr *>(NLMSG_DATA(nlh)); 2258464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti return err->error; 2268464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti } 2278464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti default: 2288464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti inet_diag_msg *msg = reinterpret_cast<inet_diag_msg *>(NLMSG_DATA(nlh)); 229fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti if (callback(proto, msg)) { 230fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti sockDestroy(proto, msg); 231fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti } 2328464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti } 2338464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti } 2348464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti } while (bytesread > 0); 2358464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 2368464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti return 0; 2378464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti} 2388464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 2398464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colittiint SockDiag::sockDestroy(uint8_t proto, const inet_diag_msg *msg) { 240f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti if (msg == nullptr) { 241f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti return 0; 242f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti } 243f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti 2448464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti DestroyRequest request = { 2458464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti .nlh = { 2468464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti .nlmsg_type = SOCK_DESTROY, 2478464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti .nlmsg_flags = NLM_F_REQUEST, 2488464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti }, 2498464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti .req = { 2508464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti .sdiag_family = msg->idiag_family, 2518464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti .sdiag_protocol = proto, 2528464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti .idiag_states = (uint32_t) (1 << msg->idiag_state), 2538464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti .id = msg->id, 2548464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti }, 2558464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti }; 2568464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti request.nlh.nlmsg_len = sizeof(request); 2578464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 2588464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti if (write(mWriteSock, &request, sizeof(request)) < (ssize_t) sizeof(request)) { 2598464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti return -errno; 2608464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti } 2618464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 262f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti int ret = checkError(mWriteSock); 263f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti if (!ret) mSocketsDestroyed++; 264f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti return ret; 265f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti} 266f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti 267f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colittiint SockDiag::destroySockets(uint8_t proto, int family, const char *addrstr) { 268f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti if (!hasSocks()) { 269f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti return -EBADFD; 270f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti } 271f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti 272f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti if (int ret = sendDumpRequest(proto, family, addrstr)) { 273f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti return ret; 274f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti } 275f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti 276fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti auto destroyAll = [] (uint8_t, const inet_diag_msg*) { return true; }; 277f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti 278fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti return readDiagMsg(proto, destroyAll); 279f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti} 280f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti 281f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colittiint SockDiag::destroySockets(const char *addrstr) { 28294a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti Stopwatch s; 283f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti mSocketsDestroyed = 0; 28494a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti 285f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti if (!strchr(addrstr, ':')) { 286f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti if (int ret = destroySockets(IPPROTO_TCP, AF_INET, addrstr)) { 287f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti ALOGE("Failed to destroy IPv4 sockets on %s: %s", addrstr, strerror(-ret)); 288f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti return ret; 289f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti } 290f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti } 291f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti if (int ret = destroySockets(IPPROTO_TCP, AF_INET6, addrstr)) { 292f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti ALOGE("Failed to destroy IPv6 sockets on %s: %s", addrstr, strerror(-ret)); 293f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti return ret; 294f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti } 295f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti 296f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti if (mSocketsDestroyed > 0) { 29794a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti ALOGI("Destroyed %d sockets on %s in %.1f ms", mSocketsDestroyed, addrstr, s.timeTaken()); 298f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti } 299f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti 300f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti return mSocketsDestroyed; 3018464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti} 30294a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti 303fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colittiint SockDiag::destroyLiveSockets(DumpCallback destroyFilter) { 304fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti int proto = IPPROTO_TCP; 305fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti 306fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti for (const int family : {AF_INET, AF_INET6}) { 307fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti const char *familyName = (family == AF_INET) ? "IPv4" : "IPv6"; 308fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti uint32_t states = (1 << TCP_ESTABLISHED) | (1 << TCP_SYN_SENT) | (1 << TCP_SYN_RECV); 309fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti if (int ret = sendDumpRequest(proto, family, states)) { 310fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti ALOGE("Failed to dump %s sockets for UID: %s", familyName, strerror(-ret)); 311fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti return ret; 312fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti } 313fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti if (int ret = readDiagMsg(proto, destroyFilter)) { 314fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti ALOGE("Failed to destroy %s sockets for UID: %s", familyName, strerror(-ret)); 315fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti return ret; 316fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti } 317fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti } 318fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti 319fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti return 0; 320fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti} 321fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti 32294a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colittiint SockDiag::destroySockets(uint8_t proto, const uid_t uid) { 32394a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti mSocketsDestroyed = 0; 32494a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti Stopwatch s; 32594a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti 326fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti auto shouldDestroy = [uid] (uint8_t, const inet_diag_msg *msg) { 327fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti return (msg != nullptr && msg->idiag_uid == uid); 32894a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti }; 32994a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti 33094a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti for (const int family : {AF_INET, AF_INET6}) { 33194a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti const char *familyName = family == AF_INET ? "IPv4" : "IPv6"; 33294a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti uint32_t states = (1 << TCP_ESTABLISHED) | (1 << TCP_SYN_SENT) | (1 << TCP_SYN_RECV); 33394a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti if (int ret = sendDumpRequest(proto, family, states)) { 33494a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti ALOGE("Failed to dump %s sockets for UID: %s", familyName, strerror(-ret)); 33594a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti return ret; 33694a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti } 337fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti if (int ret = readDiagMsg(proto, shouldDestroy)) { 33894a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti ALOGE("Failed to destroy %s sockets for UID: %s", familyName, strerror(-ret)); 33994a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti return ret; 34094a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti } 34194a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti } 34294a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti 34394a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti if (mSocketsDestroyed > 0) { 34494a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti ALOGI("Destroyed %d sockets for UID in %.1f ms", mSocketsDestroyed, s.timeTaken()); 34594a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti } 34694a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti 34794a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti return 0; 34894a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti} 349fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti 350fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colittiint SockDiag::destroySockets(const UidRanges& uidRanges, const std::set<uid_t>& skipUids) { 351fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti mSocketsDestroyed = 0; 352fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti Stopwatch s; 353fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti 354fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti auto shouldDestroy = [&] (uint8_t, const inet_diag_msg *msg) { 355fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti return msg != nullptr && 356fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti uidRanges.hasUid(msg->idiag_uid) && 357fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti skipUids.find(msg->idiag_uid) == skipUids.end(); 358fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti }; 359fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti 360fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti if (int ret = destroyLiveSockets(shouldDestroy)) { 361fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti return ret; 362fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti } 363fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti 364fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti std::vector<uid_t> skipUidStrings; 365fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti for (uid_t uid : skipUids) { 366fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti skipUidStrings.push_back(uid); 367fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti } 368fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti std::sort(skipUidStrings.begin(), skipUidStrings.end()); 369fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti 370fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti if (mSocketsDestroyed > 0) { 371fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti ALOGI("Destroyed %d sockets for %s skip={%s} in %.1f ms", 372fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti mSocketsDestroyed, uidRanges.toString().c_str(), 373fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti android::base::Join(skipUidStrings, " ").c_str(), s.timeTaken()); 374fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti } 375fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti 376fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti return 0; 377fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti} 378