xref: /aosp_15_r20/kernel/tests/net/test/net_test.py (revision 2f2c4c7ab4226c71756b9c31670392fdd6887c4f)
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