1*2f2c4c7aSAndroid Build Coastguard Worker#!/usr/bin/python3 2*2f2c4c7aSAndroid Build Coastguard Worker# 3*2f2c4c7aSAndroid Build Coastguard Worker# Copyright 2014 The Android Open Source Project 4*2f2c4c7aSAndroid Build Coastguard Worker# 5*2f2c4c7aSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 6*2f2c4c7aSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 7*2f2c4c7aSAndroid Build Coastguard Worker# You may obtain a copy of the License at 8*2f2c4c7aSAndroid Build Coastguard Worker# 9*2f2c4c7aSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 10*2f2c4c7aSAndroid Build Coastguard Worker# 11*2f2c4c7aSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 12*2f2c4c7aSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 13*2f2c4c7aSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14*2f2c4c7aSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 15*2f2c4c7aSAndroid Build Coastguard Worker# limitations under the License. 16*2f2c4c7aSAndroid Build Coastguard Worker 17*2f2c4c7aSAndroid Build Coastguard Workerimport contextlib 18*2f2c4c7aSAndroid Build Coastguard Workerimport fcntl 19*2f2c4c7aSAndroid Build Coastguard Workerimport os 20*2f2c4c7aSAndroid Build Coastguard Workerimport random 21*2f2c4c7aSAndroid Build Coastguard Workerimport re 22*2f2c4c7aSAndroid Build Coastguard Workerfrom socket import * # pylint: disable=wildcard-import 23*2f2c4c7aSAndroid Build Coastguard Workerimport struct 24*2f2c4c7aSAndroid Build Coastguard Workerimport sys 25*2f2c4c7aSAndroid Build Coastguard Workerimport unittest 26*2f2c4c7aSAndroid Build Coastguard Worker 27*2f2c4c7aSAndroid Build Coastguard Workerfrom scapy import all as scapy 28*2f2c4c7aSAndroid Build Coastguard Worker 29*2f2c4c7aSAndroid Build Coastguard Workerimport binascii 30*2f2c4c7aSAndroid Build Coastguard Workerimport csocket 31*2f2c4c7aSAndroid Build Coastguard Workerimport gki 32*2f2c4c7aSAndroid Build Coastguard Worker 33*2f2c4c7aSAndroid Build Coastguard Worker# TODO: Move these to csocket.py. 34*2f2c4c7aSAndroid Build Coastguard WorkerSOL_IPV6 = 41 35*2f2c4c7aSAndroid Build Coastguard WorkerIP_RECVERR = 11 36*2f2c4c7aSAndroid Build Coastguard WorkerIPV6_RECVERR = 25 37*2f2c4c7aSAndroid Build Coastguard WorkerIP_TRANSPARENT = 19 38*2f2c4c7aSAndroid Build Coastguard WorkerIPV6_TRANSPARENT = 75 39*2f2c4c7aSAndroid Build Coastguard WorkerIPV6_TCLASS = 67 40*2f2c4c7aSAndroid Build Coastguard WorkerIPV6_FLOWLABEL_MGR = 32 41*2f2c4c7aSAndroid Build Coastguard WorkerIPV6_FLOWINFO_SEND = 33 42*2f2c4c7aSAndroid Build Coastguard Worker 43*2f2c4c7aSAndroid Build Coastguard WorkerSO_BINDTODEVICE = 25 44*2f2c4c7aSAndroid Build Coastguard WorkerSO_MARK = 36 45*2f2c4c7aSAndroid Build Coastguard WorkerSO_PROTOCOL = 38 46*2f2c4c7aSAndroid Build Coastguard WorkerSO_DOMAIN = 39 47*2f2c4c7aSAndroid Build Coastguard WorkerSO_COOKIE = 57 48*2f2c4c7aSAndroid Build Coastguard Worker 49*2f2c4c7aSAndroid Build Coastguard WorkerETH_P_IP = 0x0800 50*2f2c4c7aSAndroid Build Coastguard WorkerETH_P_IPV6 = 0x86dd 51*2f2c4c7aSAndroid Build Coastguard Worker 52*2f2c4c7aSAndroid Build Coastguard WorkerIPPROTO_GRE = 47 53*2f2c4c7aSAndroid Build Coastguard Worker 54*2f2c4c7aSAndroid Build Coastguard WorkerSIOCSIFHWADDR = 0x8924 55*2f2c4c7aSAndroid Build Coastguard Worker 56*2f2c4c7aSAndroid Build Coastguard WorkerIPV6_FL_A_GET = 0 57*2f2c4c7aSAndroid Build Coastguard WorkerIPV6_FL_A_PUT = 1 58*2f2c4c7aSAndroid Build Coastguard WorkerIPV6_FL_A_RENEW = 1 59*2f2c4c7aSAndroid Build Coastguard Worker 60*2f2c4c7aSAndroid Build Coastguard WorkerIPV6_FL_F_CREATE = 1 61*2f2c4c7aSAndroid Build Coastguard WorkerIPV6_FL_F_EXCL = 2 62*2f2c4c7aSAndroid Build Coastguard Worker 63*2f2c4c7aSAndroid Build Coastguard WorkerIPV6_FL_S_NONE = 0 64*2f2c4c7aSAndroid Build Coastguard WorkerIPV6_FL_S_EXCL = 1 65*2f2c4c7aSAndroid Build Coastguard WorkerIPV6_FL_S_ANY = 255 66*2f2c4c7aSAndroid Build Coastguard Worker 67*2f2c4c7aSAndroid Build Coastguard WorkerIFNAMSIZ = 16 68*2f2c4c7aSAndroid Build Coastguard Worker 69*2f2c4c7aSAndroid Build Coastguard WorkerIPV4_PING = b"\x08\x00\x00\x00\x0a\xce\x00\x03" 70*2f2c4c7aSAndroid Build Coastguard WorkerIPV6_PING = b"\x80\x00\x00\x00\x0a\xce\x00\x03" 71*2f2c4c7aSAndroid Build Coastguard Worker 72*2f2c4c7aSAndroid Build Coastguard WorkerIPV4_ADDR = "8.8.8.8" 73*2f2c4c7aSAndroid Build Coastguard WorkerIPV4_ADDR2 = "8.8.4.4" 74*2f2c4c7aSAndroid Build Coastguard WorkerIPV6_ADDR = "2001:4860:4860::8888" 75*2f2c4c7aSAndroid Build Coastguard WorkerIPV6_ADDR2 = "2001:4860:4860::8844" 76*2f2c4c7aSAndroid Build Coastguard Worker 77*2f2c4c7aSAndroid Build Coastguard WorkerIPV6_SEQ_DGRAM_HEADER = (" sl " 78*2f2c4c7aSAndroid Build Coastguard Worker "local_address " 79*2f2c4c7aSAndroid Build Coastguard Worker "remote_address " 80*2f2c4c7aSAndroid Build Coastguard Worker "st tx_queue rx_queue tr tm->when retrnsmt" 81*2f2c4c7aSAndroid Build Coastguard Worker " uid timeout inode ref pointer drops\n") 82*2f2c4c7aSAndroid Build Coastguard Worker 83*2f2c4c7aSAndroid Build Coastguard WorkerUDP_HDR_LEN = 8 84*2f2c4c7aSAndroid Build Coastguard Worker 85*2f2c4c7aSAndroid Build Coastguard Worker# Arbitrary packet payload. 86*2f2c4c7aSAndroid Build Coastguard WorkerUDP_PAYLOAD = bytes(scapy.DNS(rd=1, 87*2f2c4c7aSAndroid Build Coastguard Worker id=random.randint(0, 65535), 88*2f2c4c7aSAndroid Build Coastguard Worker qd=scapy.DNSQR(qname="wWW.GoOGle.CoM", 89*2f2c4c7aSAndroid Build Coastguard Worker qtype="AAAA"))) 90*2f2c4c7aSAndroid Build Coastguard Worker 91*2f2c4c7aSAndroid Build Coastguard Worker# Unix group to use if we want to open sockets as non-root. 92*2f2c4c7aSAndroid Build Coastguard WorkerAID_INET = 3003 93*2f2c4c7aSAndroid Build Coastguard Worker 94*2f2c4c7aSAndroid Build Coastguard Worker# Kernel log verbosity levels. 95*2f2c4c7aSAndroid Build Coastguard WorkerKERN_INFO = 6 96*2f2c4c7aSAndroid Build Coastguard Worker 97*2f2c4c7aSAndroid Build Coastguard Worker# The following ends up being (VERSION, PATCHLEVEL, SUBLEVEL) from top of kernel's Makefile 98*2f2c4c7aSAndroid Build Coastguard WorkerLINUX_VERSION = csocket.LinuxVersion() 99*2f2c4c7aSAndroid Build Coastguard Worker 100*2f2c4c7aSAndroid Build Coastguard WorkerLINUX_ANY_VERSION = (0, 0, 0) 101*2f2c4c7aSAndroid Build Coastguard Worker 102*2f2c4c7aSAndroid Build Coastguard Worker# Linus always releases x.y.0-rcZ or x.y.0, any stable (incl. LTS) release will be x.y.1+ 103*2f2c4c7aSAndroid Build Coastguard WorkerIS_STABLE = (LINUX_VERSION[2] > 0) 104*2f2c4c7aSAndroid Build Coastguard Worker 105*2f2c4c7aSAndroid Build Coastguard Worker# From //system/gsid/libgsi.cpp IsGsiRunning() 106*2f2c4c7aSAndroid Build Coastguard WorkerIS_GSI = os.access("/metadata/gsi/dsu/booted", os.F_OK) 107*2f2c4c7aSAndroid Build Coastguard Worker 108*2f2c4c7aSAndroid Build Coastguard Worker# NonGXI() is useful to run tests starting from a specific kernel version, 109*2f2c4c7aSAndroid Build Coastguard Worker# thus allowing one to test for correctly backported fixes, 110*2f2c4c7aSAndroid Build Coastguard Worker# without running the tests on non-updatable kernels (as part of GSI tests). 111*2f2c4c7aSAndroid Build Coastguard Worker# 112*2f2c4c7aSAndroid Build Coastguard Worker# Running vts_net_test on GSI image basically doesn't make sense, since 113*2f2c4c7aSAndroid Build Coastguard Worker# it's not like the unmodified vendor image - including the kernel - can be 114*2f2c4c7aSAndroid Build Coastguard Worker# realistically fixed in such a setup. Particularly problematic is GSI 115*2f2c4c7aSAndroid Build Coastguard Worker# on *older* pixel vendor: newer pixel images will have the fixed kernel, 116*2f2c4c7aSAndroid Build Coastguard Worker# but running newer GSI against ancient vendor will not see those fixes. 117*2f2c4c7aSAndroid Build Coastguard Worker# 118*2f2c4c7aSAndroid Build Coastguard Worker# Normally you'd also want to run on GKI kernels, but older release branches 119*2f2c4c7aSAndroid Build Coastguard Worker# are no longer maintained, so they also need to be excluded. 120*2f2c4c7aSAndroid Build Coastguard Worker# Proper GKI testing will happen on at the tip of the appropriate ACK/GKI branch. 121*2f2c4c7aSAndroid Build Coastguard Workerdef NonGXI(major, minor): 122*2f2c4c7aSAndroid Build Coastguard Worker """Checks the kernel version is >= major.minor, and not GKI or GSI.""" 123*2f2c4c7aSAndroid Build Coastguard Worker 124*2f2c4c7aSAndroid Build Coastguard Worker if IS_GSI or gki.IS_GKI: 125*2f2c4c7aSAndroid Build Coastguard Worker return False 126*2f2c4c7aSAndroid Build Coastguard Worker return LINUX_VERSION >= (major, minor, 0) 127*2f2c4c7aSAndroid Build Coastguard Worker 128*2f2c4c7aSAndroid Build Coastguard Workerdef KernelAtLeast(versions): 129*2f2c4c7aSAndroid Build Coastguard Worker """Checks the kernel version matches the specified versions. 130*2f2c4c7aSAndroid Build Coastguard Worker 131*2f2c4c7aSAndroid Build Coastguard Worker Args: 132*2f2c4c7aSAndroid Build Coastguard Worker versions: a list of versions expressed as tuples, 133*2f2c4c7aSAndroid Build Coastguard Worker e.g., [(5, 10, 108), (5, 15, 31)]. The kernel version matches if it's 134*2f2c4c7aSAndroid Build Coastguard Worker between each specified version and the next minor version with last digit 135*2f2c4c7aSAndroid Build Coastguard Worker set to 0. In this example, the kernel version must match either: 136*2f2c4c7aSAndroid Build Coastguard Worker >= 5.10.108 and < 5.15.0 137*2f2c4c7aSAndroid Build Coastguard Worker >= 5.15.31 138*2f2c4c7aSAndroid Build Coastguard Worker While this is less flexible than matching exact tuples, it allows the caller 139*2f2c4c7aSAndroid Build Coastguard Worker to pass in fewer arguments, because Android only supports certain minor 140*2f2c4c7aSAndroid Build Coastguard Worker versions (4.19, 5.4, 5.10, ...) 141*2f2c4c7aSAndroid Build Coastguard Worker 142*2f2c4c7aSAndroid Build Coastguard Worker Returns: 143*2f2c4c7aSAndroid Build Coastguard Worker True if the kernel version matches, False otherwise 144*2f2c4c7aSAndroid Build Coastguard Worker """ 145*2f2c4c7aSAndroid Build Coastguard Worker maxversion = (1000, 255, 65535) 146*2f2c4c7aSAndroid Build Coastguard Worker for version in sorted(versions, reverse=True): 147*2f2c4c7aSAndroid Build Coastguard Worker if version[:2] == maxversion[:2]: 148*2f2c4c7aSAndroid Build Coastguard Worker raise ValueError("Duplicate minor version: %s %s", (version, maxversion)) 149*2f2c4c7aSAndroid Build Coastguard Worker if LINUX_VERSION >= version and LINUX_VERSION < maxversion: 150*2f2c4c7aSAndroid Build Coastguard Worker return True 151*2f2c4c7aSAndroid Build Coastguard Worker maxversion = (version[0], version[1], 0) 152*2f2c4c7aSAndroid Build Coastguard Worker return False 153*2f2c4c7aSAndroid Build Coastguard Worker 154*2f2c4c7aSAndroid Build Coastguard Workerdef ByteToHex(b): 155*2f2c4c7aSAndroid Build Coastguard Worker return "%02x" % (ord(b) if isinstance(b, str) else b) 156*2f2c4c7aSAndroid Build Coastguard Worker 157*2f2c4c7aSAndroid Build Coastguard Workerdef GetWildcardAddress(version): 158*2f2c4c7aSAndroid Build Coastguard Worker return {4: "0.0.0.0", 6: "::"}[version] 159*2f2c4c7aSAndroid Build Coastguard Worker 160*2f2c4c7aSAndroid Build Coastguard Workerdef GetIpHdrLength(version): 161*2f2c4c7aSAndroid Build Coastguard Worker return {4: 20, 6: 40}[version] 162*2f2c4c7aSAndroid Build Coastguard Worker 163*2f2c4c7aSAndroid Build Coastguard Workerdef GetAddressFamily(version): 164*2f2c4c7aSAndroid Build Coastguard Worker return {4: AF_INET, 5: AF_INET6, 6: AF_INET6}[version] 165*2f2c4c7aSAndroid Build Coastguard Worker 166*2f2c4c7aSAndroid Build Coastguard Worker 167*2f2c4c7aSAndroid Build Coastguard Workerdef AddressLengthBits(version): 168*2f2c4c7aSAndroid Build Coastguard Worker return {4: 32, 6: 128}[version] 169*2f2c4c7aSAndroid Build Coastguard Worker 170*2f2c4c7aSAndroid Build Coastguard Workerdef GetAddressVersion(address): 171*2f2c4c7aSAndroid Build Coastguard Worker if ":" not in address: 172*2f2c4c7aSAndroid Build Coastguard Worker return 4 173*2f2c4c7aSAndroid Build Coastguard Worker if address.startswith("::ffff"): 174*2f2c4c7aSAndroid Build Coastguard Worker return 5 175*2f2c4c7aSAndroid Build Coastguard Worker return 6 176*2f2c4c7aSAndroid Build Coastguard Worker 177*2f2c4c7aSAndroid Build Coastguard Workerdef SetSocketTos(s, tos): 178*2f2c4c7aSAndroid Build Coastguard Worker level = {AF_INET: SOL_IP, AF_INET6: SOL_IPV6}[s.family] 179*2f2c4c7aSAndroid Build Coastguard Worker option = {AF_INET: IP_TOS, AF_INET6: IPV6_TCLASS}[s.family] 180*2f2c4c7aSAndroid Build Coastguard Worker s.setsockopt(level, option, tos) 181*2f2c4c7aSAndroid Build Coastguard Worker 182*2f2c4c7aSAndroid Build Coastguard Worker 183*2f2c4c7aSAndroid Build Coastguard Workerdef SetNonBlocking(fd): 184*2f2c4c7aSAndroid Build Coastguard Worker flags = fcntl.fcntl(fd, fcntl.F_GETFL, 0) 185*2f2c4c7aSAndroid Build Coastguard Worker fcntl.fcntl(fd, fcntl.F_SETFL, flags | os.O_NONBLOCK) 186*2f2c4c7aSAndroid Build Coastguard Worker 187*2f2c4c7aSAndroid Build Coastguard Worker 188*2f2c4c7aSAndroid Build Coastguard Worker# Convenience functions to create sockets. 189*2f2c4c7aSAndroid Build Coastguard Workerdef Socket(family, sock_type, protocol): 190*2f2c4c7aSAndroid Build Coastguard Worker s = socket(family, sock_type, protocol) 191*2f2c4c7aSAndroid Build Coastguard Worker csocket.SetSocketTimeout(s, 5000) 192*2f2c4c7aSAndroid Build Coastguard Worker return s 193*2f2c4c7aSAndroid Build Coastguard Worker 194*2f2c4c7aSAndroid Build Coastguard Worker 195*2f2c4c7aSAndroid Build Coastguard Workerdef PingSocket(family): 196*2f2c4c7aSAndroid Build Coastguard Worker proto = {AF_INET: IPPROTO_ICMP, AF_INET6: IPPROTO_ICMPV6}[family] 197*2f2c4c7aSAndroid Build Coastguard Worker return Socket(family, SOCK_DGRAM, proto) 198*2f2c4c7aSAndroid Build Coastguard Worker 199*2f2c4c7aSAndroid Build Coastguard Worker 200*2f2c4c7aSAndroid Build Coastguard Workerdef IPv4PingSocket(): 201*2f2c4c7aSAndroid Build Coastguard Worker return PingSocket(AF_INET) 202*2f2c4c7aSAndroid Build Coastguard Worker 203*2f2c4c7aSAndroid Build Coastguard Worker 204*2f2c4c7aSAndroid Build Coastguard Workerdef IPv6PingSocket(): 205*2f2c4c7aSAndroid Build Coastguard Worker return PingSocket(AF_INET6) 206*2f2c4c7aSAndroid Build Coastguard Worker 207*2f2c4c7aSAndroid Build Coastguard Worker 208*2f2c4c7aSAndroid Build Coastguard Workerdef TCPSocket(family): 209*2f2c4c7aSAndroid Build Coastguard Worker s = Socket(family, SOCK_STREAM, IPPROTO_TCP) 210*2f2c4c7aSAndroid Build Coastguard Worker SetNonBlocking(s.fileno()) 211*2f2c4c7aSAndroid Build Coastguard Worker return s 212*2f2c4c7aSAndroid Build Coastguard Worker 213*2f2c4c7aSAndroid Build Coastguard Worker 214*2f2c4c7aSAndroid Build Coastguard Workerdef IPv4TCPSocket(): 215*2f2c4c7aSAndroid Build Coastguard Worker return TCPSocket(AF_INET) 216*2f2c4c7aSAndroid Build Coastguard Worker 217*2f2c4c7aSAndroid Build Coastguard Worker 218*2f2c4c7aSAndroid Build Coastguard Workerdef IPv6TCPSocket(): 219*2f2c4c7aSAndroid Build Coastguard Worker return TCPSocket(AF_INET6) 220*2f2c4c7aSAndroid Build Coastguard Worker 221*2f2c4c7aSAndroid Build Coastguard Worker 222*2f2c4c7aSAndroid Build Coastguard Workerdef UDPSocket(family): 223*2f2c4c7aSAndroid Build Coastguard Worker return Socket(family, SOCK_DGRAM, IPPROTO_UDP) 224*2f2c4c7aSAndroid Build Coastguard Worker 225*2f2c4c7aSAndroid Build Coastguard Worker 226*2f2c4c7aSAndroid Build Coastguard Workerdef RawGRESocket(family): 227*2f2c4c7aSAndroid Build Coastguard Worker s = Socket(family, SOCK_RAW, IPPROTO_GRE) 228*2f2c4c7aSAndroid Build Coastguard Worker return s 229*2f2c4c7aSAndroid Build Coastguard Worker 230*2f2c4c7aSAndroid Build Coastguard Worker 231*2f2c4c7aSAndroid Build Coastguard Workerdef BindRandomPort(version, sock): 232*2f2c4c7aSAndroid Build Coastguard Worker addr = {4: "0.0.0.0", 5: "::", 6: "::"}[version] 233*2f2c4c7aSAndroid Build Coastguard Worker sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) 234*2f2c4c7aSAndroid Build Coastguard Worker sock.bind((addr, 0)) 235*2f2c4c7aSAndroid Build Coastguard Worker if sock.getsockopt(SOL_SOCKET, SO_PROTOCOL) == IPPROTO_TCP: 236*2f2c4c7aSAndroid Build Coastguard Worker sock.listen(100) 237*2f2c4c7aSAndroid Build Coastguard Worker port = sock.getsockname()[1] 238*2f2c4c7aSAndroid Build Coastguard Worker return port 239*2f2c4c7aSAndroid Build Coastguard Worker 240*2f2c4c7aSAndroid Build Coastguard Worker 241*2f2c4c7aSAndroid Build Coastguard Workerdef EnableFinWait(sock): 242*2f2c4c7aSAndroid Build Coastguard Worker # Disabling SO_LINGER causes sockets to go into FIN_WAIT on close(). 243*2f2c4c7aSAndroid Build Coastguard Worker sock.setsockopt(SOL_SOCKET, SO_LINGER, struct.pack("ii", 0, 0)) 244*2f2c4c7aSAndroid Build Coastguard Worker 245*2f2c4c7aSAndroid Build Coastguard Worker 246*2f2c4c7aSAndroid Build Coastguard Workerdef DisableFinWait(sock): 247*2f2c4c7aSAndroid Build Coastguard Worker # Enabling SO_LINGER with a timeout of zero causes close() to send RST. 248*2f2c4c7aSAndroid Build Coastguard Worker sock.setsockopt(SOL_SOCKET, SO_LINGER, struct.pack("ii", 1, 0)) 249*2f2c4c7aSAndroid Build Coastguard Worker 250*2f2c4c7aSAndroid Build Coastguard Worker 251*2f2c4c7aSAndroid Build Coastguard Workerdef CreateSocketPair(family, socktype, addr): 252*2f2c4c7aSAndroid Build Coastguard Worker clientsock = socket(family, socktype, 0) 253*2f2c4c7aSAndroid Build Coastguard Worker listensock = socket(family, socktype, 0) 254*2f2c4c7aSAndroid Build Coastguard Worker listensock.bind((addr, 0)) 255*2f2c4c7aSAndroid Build Coastguard Worker addr = listensock.getsockname() 256*2f2c4c7aSAndroid Build Coastguard Worker if socktype == SOCK_STREAM: 257*2f2c4c7aSAndroid Build Coastguard Worker listensock.listen(1) 258*2f2c4c7aSAndroid Build Coastguard Worker clientsock.connect(listensock.getsockname()) 259*2f2c4c7aSAndroid Build Coastguard Worker if socktype == SOCK_STREAM: 260*2f2c4c7aSAndroid Build Coastguard Worker acceptedsock, _ = listensock.accept() 261*2f2c4c7aSAndroid Build Coastguard Worker DisableFinWait(clientsock) 262*2f2c4c7aSAndroid Build Coastguard Worker DisableFinWait(acceptedsock) 263*2f2c4c7aSAndroid Build Coastguard Worker listensock.close() 264*2f2c4c7aSAndroid Build Coastguard Worker else: 265*2f2c4c7aSAndroid Build Coastguard Worker listensock.connect(clientsock.getsockname()) 266*2f2c4c7aSAndroid Build Coastguard Worker acceptedsock = listensock 267*2f2c4c7aSAndroid Build Coastguard Worker return clientsock, acceptedsock 268*2f2c4c7aSAndroid Build Coastguard Worker 269*2f2c4c7aSAndroid Build Coastguard Worker 270*2f2c4c7aSAndroid Build Coastguard Workerdef GetInterfaceIndex(ifname): 271*2f2c4c7aSAndroid Build Coastguard Worker with UDPSocket(AF_INET) as s: 272*2f2c4c7aSAndroid Build Coastguard Worker ifr = struct.pack("%dsi" % IFNAMSIZ, ifname.encode(), 0) 273*2f2c4c7aSAndroid Build Coastguard Worker ifr = fcntl.ioctl(s, scapy.SIOCGIFINDEX, ifr) 274*2f2c4c7aSAndroid Build Coastguard Worker return struct.unpack("%dsi" % IFNAMSIZ, ifr)[1] 275*2f2c4c7aSAndroid Build Coastguard Worker 276*2f2c4c7aSAndroid Build Coastguard Worker 277*2f2c4c7aSAndroid Build Coastguard Workerdef SetInterfaceHWAddr(ifname, hwaddr): 278*2f2c4c7aSAndroid Build Coastguard Worker with UDPSocket(AF_INET) as s: 279*2f2c4c7aSAndroid Build Coastguard Worker hwaddr = hwaddr.replace(":", "") 280*2f2c4c7aSAndroid Build Coastguard Worker hwaddr = binascii.unhexlify(hwaddr) 281*2f2c4c7aSAndroid Build Coastguard Worker if len(hwaddr) != 6: 282*2f2c4c7aSAndroid Build Coastguard Worker raise ValueError("Unknown hardware address length %d" % len(hwaddr)) 283*2f2c4c7aSAndroid Build Coastguard Worker ifr = struct.pack("%dsH6s" % IFNAMSIZ, ifname.encode(), scapy.ARPHDR_ETHER, 284*2f2c4c7aSAndroid Build Coastguard Worker hwaddr) 285*2f2c4c7aSAndroid Build Coastguard Worker fcntl.ioctl(s, SIOCSIFHWADDR, ifr) 286*2f2c4c7aSAndroid Build Coastguard Worker 287*2f2c4c7aSAndroid Build Coastguard Worker 288*2f2c4c7aSAndroid Build Coastguard Workerdef SetInterfaceState(ifname, up): 289*2f2c4c7aSAndroid Build Coastguard Worker ifname_bytes = ifname.encode() 290*2f2c4c7aSAndroid Build Coastguard Worker with UDPSocket(AF_INET) as s: 291*2f2c4c7aSAndroid Build Coastguard Worker ifr = struct.pack("%dsH" % IFNAMSIZ, ifname_bytes, 0) 292*2f2c4c7aSAndroid Build Coastguard Worker ifr = fcntl.ioctl(s, scapy.SIOCGIFFLAGS, ifr) 293*2f2c4c7aSAndroid Build Coastguard Worker _, flags = struct.unpack("%dsH" % IFNAMSIZ, ifr) 294*2f2c4c7aSAndroid Build Coastguard Worker if up: 295*2f2c4c7aSAndroid Build Coastguard Worker flags |= scapy.IFF_UP 296*2f2c4c7aSAndroid Build Coastguard Worker else: 297*2f2c4c7aSAndroid Build Coastguard Worker flags &= ~scapy.IFF_UP 298*2f2c4c7aSAndroid Build Coastguard Worker ifr = struct.pack("%dsH" % IFNAMSIZ, ifname_bytes, flags) 299*2f2c4c7aSAndroid Build Coastguard Worker ifr = fcntl.ioctl(s, scapy.SIOCSIFFLAGS, ifr) 300*2f2c4c7aSAndroid Build Coastguard Worker 301*2f2c4c7aSAndroid Build Coastguard Worker 302*2f2c4c7aSAndroid Build Coastguard Workerdef SetInterfaceUp(ifname): 303*2f2c4c7aSAndroid Build Coastguard Worker return SetInterfaceState(ifname, True) 304*2f2c4c7aSAndroid Build Coastguard Worker 305*2f2c4c7aSAndroid Build Coastguard Worker 306*2f2c4c7aSAndroid Build Coastguard Workerdef SetInterfaceDown(ifname): 307*2f2c4c7aSAndroid Build Coastguard Worker return SetInterfaceState(ifname, False) 308*2f2c4c7aSAndroid Build Coastguard Worker 309*2f2c4c7aSAndroid Build Coastguard Worker 310*2f2c4c7aSAndroid Build Coastguard Workerdef CanonicalizeIPv6Address(addr): 311*2f2c4c7aSAndroid Build Coastguard Worker return inet_ntop(AF_INET6, inet_pton(AF_INET6, addr)) 312*2f2c4c7aSAndroid Build Coastguard Worker 313*2f2c4c7aSAndroid Build Coastguard Worker 314*2f2c4c7aSAndroid Build Coastguard Workerdef FormatProcAddress(unformatted): 315*2f2c4c7aSAndroid Build Coastguard Worker groups = [] 316*2f2c4c7aSAndroid Build Coastguard Worker for i in range(0, len(unformatted), 4): 317*2f2c4c7aSAndroid Build Coastguard Worker groups.append(unformatted[i:i+4]) 318*2f2c4c7aSAndroid Build Coastguard Worker formatted = ":".join(groups) 319*2f2c4c7aSAndroid Build Coastguard Worker # Compress the address. 320*2f2c4c7aSAndroid Build Coastguard Worker address = CanonicalizeIPv6Address(formatted) 321*2f2c4c7aSAndroid Build Coastguard Worker return address 322*2f2c4c7aSAndroid Build Coastguard Worker 323*2f2c4c7aSAndroid Build Coastguard Worker 324*2f2c4c7aSAndroid Build Coastguard Workerdef FormatSockStatAddress(address): 325*2f2c4c7aSAndroid Build Coastguard Worker if ":" in address: 326*2f2c4c7aSAndroid Build Coastguard Worker family = AF_INET6 327*2f2c4c7aSAndroid Build Coastguard Worker else: 328*2f2c4c7aSAndroid Build Coastguard Worker family = AF_INET 329*2f2c4c7aSAndroid Build Coastguard Worker binary = inet_pton(family, address) 330*2f2c4c7aSAndroid Build Coastguard Worker out = "" 331*2f2c4c7aSAndroid Build Coastguard Worker for i in range(0, len(binary), 4): 332*2f2c4c7aSAndroid Build Coastguard Worker out += "%08X" % struct.unpack("=L", binary[i:i+4]) 333*2f2c4c7aSAndroid Build Coastguard Worker return out 334*2f2c4c7aSAndroid Build Coastguard Worker 335*2f2c4c7aSAndroid Build Coastguard Worker 336*2f2c4c7aSAndroid Build Coastguard Workerdef GetLinkAddress(ifname, linklocal): 337*2f2c4c7aSAndroid Build Coastguard Worker with open("/proc/net/if_inet6") as if_inet6: 338*2f2c4c7aSAndroid Build Coastguard Worker addresses = if_inet6.readlines() 339*2f2c4c7aSAndroid Build Coastguard Worker for address in addresses: 340*2f2c4c7aSAndroid Build Coastguard Worker address = [s for s in address.strip().split(" ") if s] 341*2f2c4c7aSAndroid Build Coastguard Worker if address[5] == ifname: 342*2f2c4c7aSAndroid Build Coastguard Worker if (linklocal and address[0].startswith("fe80") 343*2f2c4c7aSAndroid Build Coastguard Worker or not linklocal and not address[0].startswith("fe80")): 344*2f2c4c7aSAndroid Build Coastguard Worker # Convert the address from raw hex to something with colons in it. 345*2f2c4c7aSAndroid Build Coastguard Worker return FormatProcAddress(address[0]) 346*2f2c4c7aSAndroid Build Coastguard Worker return None 347*2f2c4c7aSAndroid Build Coastguard Worker 348*2f2c4c7aSAndroid Build Coastguard Worker 349*2f2c4c7aSAndroid Build Coastguard Workerdef GetDefaultRoute(version=6): 350*2f2c4c7aSAndroid Build Coastguard Worker if version == 6: 351*2f2c4c7aSAndroid Build Coastguard Worker with open("/proc/net/ipv6_route") as ipv6_route: 352*2f2c4c7aSAndroid Build Coastguard Worker routes = ipv6_route.readlines() 353*2f2c4c7aSAndroid Build Coastguard Worker for route in routes: 354*2f2c4c7aSAndroid Build Coastguard Worker route = [s for s in route.strip().split(" ") if s] 355*2f2c4c7aSAndroid Build Coastguard Worker if (route[0] == "00000000000000000000000000000000" and route[1] == "00" 356*2f2c4c7aSAndroid Build Coastguard Worker # Routes in non-default tables end up in /proc/net/ipv6_route!!! 357*2f2c4c7aSAndroid Build Coastguard Worker and route[9] != "lo" and not route[9].startswith("nettest")): 358*2f2c4c7aSAndroid Build Coastguard Worker return FormatProcAddress(route[4]), route[9] 359*2f2c4c7aSAndroid Build Coastguard Worker raise ValueError("No IPv6 default route found") 360*2f2c4c7aSAndroid Build Coastguard Worker elif version == 4: 361*2f2c4c7aSAndroid Build Coastguard Worker with open("/proc/net/route") as ipv4_route: 362*2f2c4c7aSAndroid Build Coastguard Worker routes = ipv4_route.readlines() 363*2f2c4c7aSAndroid Build Coastguard Worker for route in routes: 364*2f2c4c7aSAndroid Build Coastguard Worker route = [s for s in route.strip().split("\t") if s] 365*2f2c4c7aSAndroid Build Coastguard Worker if route[1] == "00000000" and route[7] == "00000000": 366*2f2c4c7aSAndroid Build Coastguard Worker gw, iface = route[2], route[0] 367*2f2c4c7aSAndroid Build Coastguard Worker gw = inet_ntop(AF_INET, binascii.unhexlify(gw)[::-1]) 368*2f2c4c7aSAndroid Build Coastguard Worker return gw, iface 369*2f2c4c7aSAndroid Build Coastguard Worker raise ValueError("No IPv4 default route found") 370*2f2c4c7aSAndroid Build Coastguard Worker else: 371*2f2c4c7aSAndroid Build Coastguard Worker raise ValueError("Don't know about IPv%s" % version) 372*2f2c4c7aSAndroid Build Coastguard Worker 373*2f2c4c7aSAndroid Build Coastguard Worker 374*2f2c4c7aSAndroid Build Coastguard Workerdef GetDefaultRouteInterface(): 375*2f2c4c7aSAndroid Build Coastguard Worker unused_gw, iface = GetDefaultRoute() 376*2f2c4c7aSAndroid Build Coastguard Worker return iface 377*2f2c4c7aSAndroid Build Coastguard Worker 378*2f2c4c7aSAndroid Build Coastguard Worker 379*2f2c4c7aSAndroid Build Coastguard Workerdef MakeFlowLabelOption(addr, label): 380*2f2c4c7aSAndroid Build Coastguard Worker # struct in6_flowlabel_req { 381*2f2c4c7aSAndroid Build Coastguard Worker # struct in6_addr flr_dst; 382*2f2c4c7aSAndroid Build Coastguard Worker # __be32 flr_label; 383*2f2c4c7aSAndroid Build Coastguard Worker # __u8 flr_action; 384*2f2c4c7aSAndroid Build Coastguard Worker # __u8 flr_share; 385*2f2c4c7aSAndroid Build Coastguard Worker # __u16 flr_flags; 386*2f2c4c7aSAndroid Build Coastguard Worker # __u16 flr_expires; 387*2f2c4c7aSAndroid Build Coastguard Worker # __u16 flr_linger; 388*2f2c4c7aSAndroid Build Coastguard Worker # __u32 __flr_pad; 389*2f2c4c7aSAndroid Build Coastguard Worker # /* Options in format of IPV6_PKTOPTIONS */ 390*2f2c4c7aSAndroid Build Coastguard Worker # }; 391*2f2c4c7aSAndroid Build Coastguard Worker fmt = "16sIBBHHH4s" 392*2f2c4c7aSAndroid Build Coastguard Worker assert struct.calcsize(fmt) == 32 393*2f2c4c7aSAndroid Build Coastguard Worker addr = inet_pton(AF_INET6, addr) 394*2f2c4c7aSAndroid Build Coastguard Worker assert len(addr) == 16 395*2f2c4c7aSAndroid Build Coastguard Worker label = htonl(label & 0xfffff) 396*2f2c4c7aSAndroid Build Coastguard Worker action = IPV6_FL_A_GET 397*2f2c4c7aSAndroid Build Coastguard Worker share = IPV6_FL_S_ANY 398*2f2c4c7aSAndroid Build Coastguard Worker flags = IPV6_FL_F_CREATE 399*2f2c4c7aSAndroid Build Coastguard Worker pad = b"\x00" * 4 400*2f2c4c7aSAndroid Build Coastguard Worker return struct.pack(fmt, addr, label, action, share, flags, 0, 0, pad) 401*2f2c4c7aSAndroid Build Coastguard Worker 402*2f2c4c7aSAndroid Build Coastguard Worker 403*2f2c4c7aSAndroid Build Coastguard Workerdef SetFlowLabel(s, addr, label): 404*2f2c4c7aSAndroid Build Coastguard Worker opt = MakeFlowLabelOption(addr, label) 405*2f2c4c7aSAndroid Build Coastguard Worker s.setsockopt(SOL_IPV6, IPV6_FLOWLABEL_MGR, opt) 406*2f2c4c7aSAndroid Build Coastguard Worker # Caller also needs to do s.setsockopt(SOL_IPV6, IPV6_FLOWINFO_SEND, 1). 407*2f2c4c7aSAndroid Build Coastguard Worker 408*2f2c4c7aSAndroid Build Coastguard Worker 409*2f2c4c7aSAndroid Build Coastguard Workerdef GetIptablesBinaryPath(version): 410*2f2c4c7aSAndroid Build Coastguard Worker if version == 4: 411*2f2c4c7aSAndroid Build Coastguard Worker paths = ( 412*2f2c4c7aSAndroid Build Coastguard Worker "/sbin/iptables-legacy", 413*2f2c4c7aSAndroid Build Coastguard Worker "/sbin/iptables", 414*2f2c4c7aSAndroid Build Coastguard Worker "/system/bin/iptables-legacy", 415*2f2c4c7aSAndroid Build Coastguard Worker "/system/bin/iptables", 416*2f2c4c7aSAndroid Build Coastguard Worker ) 417*2f2c4c7aSAndroid Build Coastguard Worker elif version == 6: 418*2f2c4c7aSAndroid Build Coastguard Worker paths = ( 419*2f2c4c7aSAndroid Build Coastguard Worker "/sbin/ip6tables-legacy", 420*2f2c4c7aSAndroid Build Coastguard Worker "/sbin/ip6tables", 421*2f2c4c7aSAndroid Build Coastguard Worker "/system/bin/ip6tables-legacy", 422*2f2c4c7aSAndroid Build Coastguard Worker "/system/bin/ip6tables", 423*2f2c4c7aSAndroid Build Coastguard Worker ) 424*2f2c4c7aSAndroid Build Coastguard Worker for iptables_path in paths: 425*2f2c4c7aSAndroid Build Coastguard Worker if os.access(iptables_path, os.X_OK): 426*2f2c4c7aSAndroid Build Coastguard Worker return iptables_path 427*2f2c4c7aSAndroid Build Coastguard Worker raise FileNotFoundError( 428*2f2c4c7aSAndroid Build Coastguard Worker "iptables binary for IPv{} not found".format(version) + 429*2f2c4c7aSAndroid Build Coastguard Worker ", checked: {}".format(", ".join(paths))) 430*2f2c4c7aSAndroid Build Coastguard Worker 431*2f2c4c7aSAndroid Build Coastguard Worker 432*2f2c4c7aSAndroid Build Coastguard Workerdef RunIptablesCommand(version, args): 433*2f2c4c7aSAndroid Build Coastguard Worker iptables_path = GetIptablesBinaryPath(version) 434*2f2c4c7aSAndroid Build Coastguard Worker return os.spawnvp( 435*2f2c4c7aSAndroid Build Coastguard Worker os.P_WAIT, iptables_path, 436*2f2c4c7aSAndroid Build Coastguard Worker [iptables_path, "-w"] + args.split(" ")) 437*2f2c4c7aSAndroid Build Coastguard Worker 438*2f2c4c7aSAndroid Build Coastguard Worker# Determine network configuration. 439*2f2c4c7aSAndroid Build Coastguard Workertry: 440*2f2c4c7aSAndroid Build Coastguard Worker GetDefaultRoute(version=4) 441*2f2c4c7aSAndroid Build Coastguard Worker HAVE_IPV4 = True 442*2f2c4c7aSAndroid Build Coastguard Workerexcept ValueError: 443*2f2c4c7aSAndroid Build Coastguard Worker HAVE_IPV4 = False 444*2f2c4c7aSAndroid Build Coastguard Worker 445*2f2c4c7aSAndroid Build Coastguard Workertry: 446*2f2c4c7aSAndroid Build Coastguard Worker GetDefaultRoute(version=6) 447*2f2c4c7aSAndroid Build Coastguard Worker HAVE_IPV6 = True 448*2f2c4c7aSAndroid Build Coastguard Workerexcept ValueError: 449*2f2c4c7aSAndroid Build Coastguard Worker HAVE_IPV6 = False 450*2f2c4c7aSAndroid Build Coastguard Worker 451*2f2c4c7aSAndroid Build Coastguard Workerclass RunAsUidGid(object): 452*2f2c4c7aSAndroid Build Coastguard Worker """Context guard to run a code block as a given UID.""" 453*2f2c4c7aSAndroid Build Coastguard Worker 454*2f2c4c7aSAndroid Build Coastguard Worker def __init__(self, uid, gid): 455*2f2c4c7aSAndroid Build Coastguard Worker self.uid = uid 456*2f2c4c7aSAndroid Build Coastguard Worker self.gid = gid 457*2f2c4c7aSAndroid Build Coastguard Worker 458*2f2c4c7aSAndroid Build Coastguard Worker def __enter__(self): 459*2f2c4c7aSAndroid Build Coastguard Worker if self.gid: 460*2f2c4c7aSAndroid Build Coastguard Worker self.saved_gid = os.getgid() 461*2f2c4c7aSAndroid Build Coastguard Worker os.setgid(self.gid) 462*2f2c4c7aSAndroid Build Coastguard Worker if self.uid: 463*2f2c4c7aSAndroid Build Coastguard Worker self.saved_uids = os.getresuid() 464*2f2c4c7aSAndroid Build Coastguard Worker self.saved_groups = os.getgroups() 465*2f2c4c7aSAndroid Build Coastguard Worker os.setgroups(self.saved_groups + [AID_INET]) 466*2f2c4c7aSAndroid Build Coastguard Worker os.setresuid(self.uid, self.uid, self.saved_uids[0]) 467*2f2c4c7aSAndroid Build Coastguard Worker 468*2f2c4c7aSAndroid Build Coastguard Worker def __exit__(self, unused_type, unused_value, unused_traceback): 469*2f2c4c7aSAndroid Build Coastguard Worker if self.uid: 470*2f2c4c7aSAndroid Build Coastguard Worker os.setresuid(*self.saved_uids) 471*2f2c4c7aSAndroid Build Coastguard Worker os.setgroups(self.saved_groups) 472*2f2c4c7aSAndroid Build Coastguard Worker if self.gid: 473*2f2c4c7aSAndroid Build Coastguard Worker os.setgid(self.saved_gid) 474*2f2c4c7aSAndroid Build Coastguard Worker 475*2f2c4c7aSAndroid Build Coastguard Workerclass RunAsUid(RunAsUidGid): 476*2f2c4c7aSAndroid Build Coastguard Worker """Context guard to run a code block as a given GID and UID.""" 477*2f2c4c7aSAndroid Build Coastguard Worker 478*2f2c4c7aSAndroid Build Coastguard Worker def __init__(self, uid): 479*2f2c4c7aSAndroid Build Coastguard Worker RunAsUidGid.__init__(self, uid, 0) 480*2f2c4c7aSAndroid Build Coastguard Worker 481*2f2c4c7aSAndroid Build Coastguard Workerclass NetworkTest(unittest.TestCase): 482*2f2c4c7aSAndroid Build Coastguard Worker 483*2f2c4c7aSAndroid Build Coastguard Worker @contextlib.contextmanager 484*2f2c4c7aSAndroid Build Coastguard Worker def _errnoCheck(self, err_num): 485*2f2c4c7aSAndroid Build Coastguard Worker with self.assertRaises(EnvironmentError) as context: 486*2f2c4c7aSAndroid Build Coastguard Worker yield context 487*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(context.exception.errno, err_num) 488*2f2c4c7aSAndroid Build Coastguard Worker 489*2f2c4c7aSAndroid Build Coastguard Worker def assertRaisesErrno(self, err_num, f=None, *args): 490*2f2c4c7aSAndroid Build Coastguard Worker """Test that the system returns an errno error. 491*2f2c4c7aSAndroid Build Coastguard Worker 492*2f2c4c7aSAndroid Build Coastguard Worker This works similarly to unittest.TestCase.assertRaises. You can call it as 493*2f2c4c7aSAndroid Build Coastguard Worker an assertion, or use it as a context manager. 494*2f2c4c7aSAndroid Build Coastguard Worker e.g. 495*2f2c4c7aSAndroid Build Coastguard Worker self.assertRaisesErrno(errno.ENOENT, do_things, arg1, arg2) 496*2f2c4c7aSAndroid Build Coastguard Worker or 497*2f2c4c7aSAndroid Build Coastguard Worker with self.assertRaisesErrno(errno.ENOENT): 498*2f2c4c7aSAndroid Build Coastguard Worker do_things(arg1, arg2) 499*2f2c4c7aSAndroid Build Coastguard Worker 500*2f2c4c7aSAndroid Build Coastguard Worker Args: 501*2f2c4c7aSAndroid Build Coastguard Worker err_num: an errno constant 502*2f2c4c7aSAndroid Build Coastguard Worker f: (optional) A callable that should result in error 503*2f2c4c7aSAndroid Build Coastguard Worker *args: arguments passed to f 504*2f2c4c7aSAndroid Build Coastguard Worker """ 505*2f2c4c7aSAndroid Build Coastguard Worker if f is None: 506*2f2c4c7aSAndroid Build Coastguard Worker return self._errnoCheck(err_num) 507*2f2c4c7aSAndroid Build Coastguard Worker else: 508*2f2c4c7aSAndroid Build Coastguard Worker with self._errnoCheck(err_num): 509*2f2c4c7aSAndroid Build Coastguard Worker f(*args) 510*2f2c4c7aSAndroid Build Coastguard Worker 511*2f2c4c7aSAndroid Build Coastguard Worker def ReadProcNetSocket(self, protocol): 512*2f2c4c7aSAndroid Build Coastguard Worker # Read file. 513*2f2c4c7aSAndroid Build Coastguard Worker filename = "/proc/net/%s" % protocol 514*2f2c4c7aSAndroid Build Coastguard Worker with open(filename) as f: 515*2f2c4c7aSAndroid Build Coastguard Worker lines = f.readlines() 516*2f2c4c7aSAndroid Build Coastguard Worker 517*2f2c4c7aSAndroid Build Coastguard Worker # Possibly check, and strip, header. 518*2f2c4c7aSAndroid Build Coastguard Worker if protocol in ["icmp6", "raw6", "udp6"]: 519*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(IPV6_SEQ_DGRAM_HEADER, lines[0]) 520*2f2c4c7aSAndroid Build Coastguard Worker lines = lines[1:] 521*2f2c4c7aSAndroid Build Coastguard Worker 522*2f2c4c7aSAndroid Build Coastguard Worker # Check contents. 523*2f2c4c7aSAndroid Build Coastguard Worker if protocol.endswith("6"): 524*2f2c4c7aSAndroid Build Coastguard Worker addrlen = 32 525*2f2c4c7aSAndroid Build Coastguard Worker else: 526*2f2c4c7aSAndroid Build Coastguard Worker addrlen = 8 527*2f2c4c7aSAndroid Build Coastguard Worker 528*2f2c4c7aSAndroid Build Coastguard Worker if protocol.startswith("tcp"): 529*2f2c4c7aSAndroid Build Coastguard Worker # Real sockets have 5 extra numbers, timewait sockets have none. 530*2f2c4c7aSAndroid Build Coastguard Worker end_regexp = "(| +[0-9]+ [0-9]+ [0-9]+ [0-9]+ -?[0-9]+)$" 531*2f2c4c7aSAndroid Build Coastguard Worker elif re.match("icmp|udp|raw", protocol): 532*2f2c4c7aSAndroid Build Coastguard Worker # Drops. 533*2f2c4c7aSAndroid Build Coastguard Worker end_regexp = " +([0-9]+) *$" 534*2f2c4c7aSAndroid Build Coastguard Worker else: 535*2f2c4c7aSAndroid Build Coastguard Worker raise ValueError("Don't know how to parse %s" % filename) 536*2f2c4c7aSAndroid Build Coastguard Worker 537*2f2c4c7aSAndroid Build Coastguard Worker regexp = re.compile(r" *(\d+): " # bucket 538*2f2c4c7aSAndroid Build Coastguard Worker "([0-9A-F]{%d}:[0-9A-F]{4}) " # srcaddr, port 539*2f2c4c7aSAndroid Build Coastguard Worker "([0-9A-F]{%d}:[0-9A-F]{4}) " # dstaddr, port 540*2f2c4c7aSAndroid Build Coastguard Worker "([0-9A-F][0-9A-F]) " # state 541*2f2c4c7aSAndroid Build Coastguard Worker "([0-9A-F]{8}:[0-9A-F]{8}) " # mem 542*2f2c4c7aSAndroid Build Coastguard Worker "([0-9A-F]{2}:[0-9A-F]{8}) " # ? 543*2f2c4c7aSAndroid Build Coastguard Worker "([0-9A-F]{8}) +" # ? 544*2f2c4c7aSAndroid Build Coastguard Worker "([0-9]+) +" # uid 545*2f2c4c7aSAndroid Build Coastguard Worker "([0-9]+) +" # timeout 546*2f2c4c7aSAndroid Build Coastguard Worker "([0-9]+) +" # inode 547*2f2c4c7aSAndroid Build Coastguard Worker "([0-9]+) +" # refcnt 548*2f2c4c7aSAndroid Build Coastguard Worker "([0-9a-f]+)" # sp 549*2f2c4c7aSAndroid Build Coastguard Worker "%s" # icmp has spaces 550*2f2c4c7aSAndroid Build Coastguard Worker % (addrlen, addrlen, end_regexp)) 551*2f2c4c7aSAndroid Build Coastguard Worker # Return a list of lists with only source / dest addresses for now. 552*2f2c4c7aSAndroid Build Coastguard Worker # TODO: consider returning a dict or namedtuple instead. 553*2f2c4c7aSAndroid Build Coastguard Worker out = [] 554*2f2c4c7aSAndroid Build Coastguard Worker for line in lines: 555*2f2c4c7aSAndroid Build Coastguard Worker m = regexp.match(line) 556*2f2c4c7aSAndroid Build Coastguard Worker if m is None: 557*2f2c4c7aSAndroid Build Coastguard Worker raise ValueError("Failed match on [%s]" % line) 558*2f2c4c7aSAndroid Build Coastguard Worker (_, src, dst, state, mem, 559*2f2c4c7aSAndroid Build Coastguard Worker _, _, uid, _, _, refcnt, _, extra) = m.groups() 560*2f2c4c7aSAndroid Build Coastguard Worker out.append([src, dst, state, mem, uid, refcnt, extra]) 561*2f2c4c7aSAndroid Build Coastguard Worker return out 562*2f2c4c7aSAndroid Build Coastguard Worker 563*2f2c4c7aSAndroid Build Coastguard Worker @staticmethod 564*2f2c4c7aSAndroid Build Coastguard Worker def GetConsoleLogLevel(): 565*2f2c4c7aSAndroid Build Coastguard Worker with open("/proc/sys/kernel/printk") as printk: 566*2f2c4c7aSAndroid Build Coastguard Worker return int(printk.readline().split()[0]) 567*2f2c4c7aSAndroid Build Coastguard Worker 568*2f2c4c7aSAndroid Build Coastguard Worker @staticmethod 569*2f2c4c7aSAndroid Build Coastguard Worker def SetConsoleLogLevel(level): 570*2f2c4c7aSAndroid Build Coastguard Worker with open("/proc/sys/kernel/printk", "w") as printk: 571*2f2c4c7aSAndroid Build Coastguard Worker return printk.write("%s\n" % level) 572*2f2c4c7aSAndroid Build Coastguard Worker 573*2f2c4c7aSAndroid Build Coastguard Worker 574*2f2c4c7aSAndroid Build Coastguard Workerif __name__ == "__main__": 575*2f2c4c7aSAndroid Build Coastguard Worker unittest.main() 576