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 Worker"""Base module for multinetwork tests.""" 18*2f2c4c7aSAndroid Build Coastguard Worker 19*2f2c4c7aSAndroid Build Coastguard Workerimport errno 20*2f2c4c7aSAndroid Build Coastguard Workerimport fcntl 21*2f2c4c7aSAndroid Build Coastguard Workerimport os 22*2f2c4c7aSAndroid Build Coastguard Workerimport posix 23*2f2c4c7aSAndroid Build Coastguard Workerimport random 24*2f2c4c7aSAndroid Build Coastguard Workerimport re 25*2f2c4c7aSAndroid Build Coastguard Workerfrom socket import * # pylint: disable=wildcard-import 26*2f2c4c7aSAndroid Build Coastguard Workerimport struct 27*2f2c4c7aSAndroid Build Coastguard Workerimport time 28*2f2c4c7aSAndroid Build Coastguard Worker 29*2f2c4c7aSAndroid Build Coastguard Workerfrom scapy import all as scapy 30*2f2c4c7aSAndroid Build Coastguard Worker 31*2f2c4c7aSAndroid Build Coastguard Workerimport csocket 32*2f2c4c7aSAndroid Build Coastguard Workerimport iproute 33*2f2c4c7aSAndroid Build Coastguard Workerimport net_test 34*2f2c4c7aSAndroid Build Coastguard Worker 35*2f2c4c7aSAndroid Build Coastguard Worker 36*2f2c4c7aSAndroid Build Coastguard WorkerIFF_TUN = 1 37*2f2c4c7aSAndroid Build Coastguard WorkerIFF_TAP = 2 38*2f2c4c7aSAndroid Build Coastguard WorkerIFF_NO_PI = 0x1000 39*2f2c4c7aSAndroid Build Coastguard WorkerTUNSETIFF = 0x400454ca 40*2f2c4c7aSAndroid Build Coastguard Worker 41*2f2c4c7aSAndroid Build Coastguard WorkerSO_BINDTODEVICE = 25 42*2f2c4c7aSAndroid Build Coastguard Worker 43*2f2c4c7aSAndroid Build Coastguard Worker# Setsockopt values. 44*2f2c4c7aSAndroid Build Coastguard WorkerIP_UNICAST_IF = 50 45*2f2c4c7aSAndroid Build Coastguard WorkerIPV6_MULTICAST_IF = 17 46*2f2c4c7aSAndroid Build Coastguard WorkerIPV6_UNICAST_IF = 76 47*2f2c4c7aSAndroid Build Coastguard Worker 48*2f2c4c7aSAndroid Build Coastguard Worker# Cmsg values. 49*2f2c4c7aSAndroid Build Coastguard WorkerIP_TTL = 2 50*2f2c4c7aSAndroid Build Coastguard WorkerIPV6_2292PKTOPTIONS = 6 51*2f2c4c7aSAndroid Build Coastguard WorkerIPV6_FLOWINFO = 11 52*2f2c4c7aSAndroid Build Coastguard WorkerIPV6_HOPLIMIT = 52 # Different from IPV6_UNICAST_HOPS, this is cmsg only. 53*2f2c4c7aSAndroid Build Coastguard Worker 54*2f2c4c7aSAndroid Build Coastguard Worker 55*2f2c4c7aSAndroid Build Coastguard WorkerACCEPT_RA_MIN_LFT_SYSCTL = "/proc/sys/net/ipv6/conf/default/accept_ra_min_lft" 56*2f2c4c7aSAndroid Build Coastguard WorkerAUTOCONF_TABLE_SYSCTL = "/proc/sys/net/ipv6/conf/default/accept_ra_rt_table" 57*2f2c4c7aSAndroid Build Coastguard WorkerIPV4_MARK_REFLECT_SYSCTL = "/proc/sys/net/ipv4/fwmark_reflect" 58*2f2c4c7aSAndroid Build Coastguard WorkerIPV6_MARK_REFLECT_SYSCTL = "/proc/sys/net/ipv6/fwmark_reflect" 59*2f2c4c7aSAndroid Build Coastguard WorkerRA_HONOR_PIO_LIFE_SYSCTL = "/proc/sys/net/ipv6/conf/default/ra_honor_pio_life" 60*2f2c4c7aSAndroid Build Coastguard WorkerRA_HONOR_PIO_PFLAG = "/proc/sys/net/ipv6/conf/default/ra_honor_pio_pflag" 61*2f2c4c7aSAndroid Build Coastguard Worker 62*2f2c4c7aSAndroid Build Coastguard WorkerHAVE_ACCEPT_RA_MIN_LFT = (os.path.isfile(ACCEPT_RA_MIN_LFT_SYSCTL) or 63*2f2c4c7aSAndroid Build Coastguard Worker net_test.NonGXI(5, 10) or 64*2f2c4c7aSAndroid Build Coastguard Worker net_test.KernelAtLeast([(5, 10, 199), (5, 15, 136), 65*2f2c4c7aSAndroid Build Coastguard Worker (6, 1, 57), (6, 6, 0)])) 66*2f2c4c7aSAndroid Build Coastguard WorkerHAVE_AUTOCONF_TABLE = os.path.isfile(AUTOCONF_TABLE_SYSCTL) 67*2f2c4c7aSAndroid Build Coastguard WorkerHAVE_RA_HONOR_PIO_LIFE = (os.path.isfile(RA_HONOR_PIO_LIFE_SYSCTL) or 68*2f2c4c7aSAndroid Build Coastguard Worker net_test.KernelAtLeast([(6, 7, 0)])) 69*2f2c4c7aSAndroid Build Coastguard WorkerHAVE_RA_HONOR_PIO_PFLAG = (os.path.isfile(RA_HONOR_PIO_PFLAG) or 70*2f2c4c7aSAndroid Build Coastguard Worker net_test.KernelAtLeast([(6, 12, 0)])) 71*2f2c4c7aSAndroid Build Coastguard Worker 72*2f2c4c7aSAndroid Build Coastguard WorkerHAVE_USEROPT_PIO_FIX = net_test.KernelAtLeast([(4, 19, 320), (5, 4, 282), 73*2f2c4c7aSAndroid Build Coastguard Worker (5, 10, 224), (5, 15, 165), 74*2f2c4c7aSAndroid Build Coastguard Worker (6, 1, 104), (6, 6, 45), 75*2f2c4c7aSAndroid Build Coastguard Worker (6, 9, 13), (6, 10, 4), 76*2f2c4c7aSAndroid Build Coastguard Worker (6, 11, 0)]) 77*2f2c4c7aSAndroid Build Coastguard Worker 78*2f2c4c7aSAndroid Build Coastguard Worker 79*2f2c4c7aSAndroid Build Coastguard Workerclass ConfigurationError(AssertionError): 80*2f2c4c7aSAndroid Build Coastguard Worker pass 81*2f2c4c7aSAndroid Build Coastguard Worker 82*2f2c4c7aSAndroid Build Coastguard Worker 83*2f2c4c7aSAndroid Build Coastguard Workerclass UnexpectedPacketError(AssertionError): 84*2f2c4c7aSAndroid Build Coastguard Worker pass 85*2f2c4c7aSAndroid Build Coastguard Worker 86*2f2c4c7aSAndroid Build Coastguard Worker 87*2f2c4c7aSAndroid Build Coastguard Workerdef MakePktInfo(version, addr, ifindex): 88*2f2c4c7aSAndroid Build Coastguard Worker family = {4: AF_INET, 6: AF_INET6}[version] 89*2f2c4c7aSAndroid Build Coastguard Worker if not addr: 90*2f2c4c7aSAndroid Build Coastguard Worker addr = {4: "0.0.0.0", 6: "::"}[version] 91*2f2c4c7aSAndroid Build Coastguard Worker if addr: 92*2f2c4c7aSAndroid Build Coastguard Worker addr = inet_pton(family, addr) 93*2f2c4c7aSAndroid Build Coastguard Worker if version == 6: 94*2f2c4c7aSAndroid Build Coastguard Worker return csocket.In6Pktinfo((addr, ifindex)).Pack() 95*2f2c4c7aSAndroid Build Coastguard Worker else: 96*2f2c4c7aSAndroid Build Coastguard Worker return csocket.InPktinfo((ifindex, addr, b"\x00" * 4)).Pack() 97*2f2c4c7aSAndroid Build Coastguard Worker 98*2f2c4c7aSAndroid Build Coastguard Worker 99*2f2c4c7aSAndroid Build Coastguard Workerclass MultiNetworkBaseTest(net_test.NetworkTest): 100*2f2c4c7aSAndroid Build Coastguard Worker """Base class for all multinetwork tests. 101*2f2c4c7aSAndroid Build Coastguard Worker 102*2f2c4c7aSAndroid Build Coastguard Worker This class does not contain any test code, but contains code to set up and 103*2f2c4c7aSAndroid Build Coastguard Worker tear a multi-network environment using multiple tun interfaces. The 104*2f2c4c7aSAndroid Build Coastguard Worker environment is designed to be similar to a real Android device in terms of 105*2f2c4c7aSAndroid Build Coastguard Worker rules and routes, and supports IPv4 and IPv6. 106*2f2c4c7aSAndroid Build Coastguard Worker 107*2f2c4c7aSAndroid Build Coastguard Worker Tests wishing to use this environment should inherit from this class and 108*2f2c4c7aSAndroid Build Coastguard Worker ensure that any setupClass, tearDownClass, setUp, and tearDown methods they 109*2f2c4c7aSAndroid Build Coastguard Worker implement also call the superclass versions. 110*2f2c4c7aSAndroid Build Coastguard Worker """ 111*2f2c4c7aSAndroid Build Coastguard Worker 112*2f2c4c7aSAndroid Build Coastguard Worker # Must be between 1 and 256, since we put them in MAC addresses and IIDs. 113*2f2c4c7aSAndroid Build Coastguard Worker NETIDS = [100, 150, 200, 250] 114*2f2c4c7aSAndroid Build Coastguard Worker 115*2f2c4c7aSAndroid Build Coastguard Worker # Stores sysctl values to write back when the test completes. 116*2f2c4c7aSAndroid Build Coastguard Worker saved_sysctls = {} 117*2f2c4c7aSAndroid Build Coastguard Worker 118*2f2c4c7aSAndroid Build Coastguard Worker # Wether to output setup commands. 119*2f2c4c7aSAndroid Build Coastguard Worker DEBUG = False 120*2f2c4c7aSAndroid Build Coastguard Worker 121*2f2c4c7aSAndroid Build Coastguard Worker UID_RANGE_START = 2000 122*2f2c4c7aSAndroid Build Coastguard Worker UID_RANGE_END = 9999 123*2f2c4c7aSAndroid Build Coastguard Worker UID_RANGE_SIZE = UID_RANGE_END - UID_RANGE_START + 1 124*2f2c4c7aSAndroid Build Coastguard Worker 125*2f2c4c7aSAndroid Build Coastguard Worker # Rule priorities. 126*2f2c4c7aSAndroid Build Coastguard Worker PRIORITY_UID = 100 127*2f2c4c7aSAndroid Build Coastguard Worker PRIORITY_OIF = 200 128*2f2c4c7aSAndroid Build Coastguard Worker PRIORITY_FWMARK = 300 129*2f2c4c7aSAndroid Build Coastguard Worker PRIORITY_IIF = 400 130*2f2c4c7aSAndroid Build Coastguard Worker PRIORITY_DEFAULT = 999 131*2f2c4c7aSAndroid Build Coastguard Worker PRIORITY_UNREACHABLE = 1000 132*2f2c4c7aSAndroid Build Coastguard Worker 133*2f2c4c7aSAndroid Build Coastguard Worker # Actual device routing is more complicated, involving more than one rule 134*2f2c4c7aSAndroid Build Coastguard Worker # per NetId, but here we make do with just one rule that selects the lower 135*2f2c4c7aSAndroid Build Coastguard Worker # 16 bits. 136*2f2c4c7aSAndroid Build Coastguard Worker NETID_FWMASK = 0xffff 137*2f2c4c7aSAndroid Build Coastguard Worker 138*2f2c4c7aSAndroid Build Coastguard Worker # For convenience. 139*2f2c4c7aSAndroid Build Coastguard Worker IPV4_ADDR = net_test.IPV4_ADDR 140*2f2c4c7aSAndroid Build Coastguard Worker IPV6_ADDR = net_test.IPV6_ADDR 141*2f2c4c7aSAndroid Build Coastguard Worker IPV4_ADDR2 = net_test.IPV4_ADDR2 142*2f2c4c7aSAndroid Build Coastguard Worker IPV6_ADDR2 = net_test.IPV6_ADDR2 143*2f2c4c7aSAndroid Build Coastguard Worker IPV4_PING = net_test.IPV4_PING 144*2f2c4c7aSAndroid Build Coastguard Worker IPV6_PING = net_test.IPV6_PING 145*2f2c4c7aSAndroid Build Coastguard Worker 146*2f2c4c7aSAndroid Build Coastguard Worker RA_VALIDITY = 600 # seconds 147*2f2c4c7aSAndroid Build Coastguard Worker 148*2f2c4c7aSAndroid Build Coastguard Worker @classmethod 149*2f2c4c7aSAndroid Build Coastguard Worker def UidRangeForNetid(cls, netid): 150*2f2c4c7aSAndroid Build Coastguard Worker per_netid_range = int(cls.UID_RANGE_SIZE / len(cls.NETIDS)) 151*2f2c4c7aSAndroid Build Coastguard Worker idx = cls.NETIDS.index(netid) 152*2f2c4c7aSAndroid Build Coastguard Worker return ( 153*2f2c4c7aSAndroid Build Coastguard Worker cls.UID_RANGE_START + per_netid_range * idx, 154*2f2c4c7aSAndroid Build Coastguard Worker cls.UID_RANGE_START + per_netid_range * (idx + 1) - 1 155*2f2c4c7aSAndroid Build Coastguard Worker ) 156*2f2c4c7aSAndroid Build Coastguard Worker 157*2f2c4c7aSAndroid Build Coastguard Worker @classmethod 158*2f2c4c7aSAndroid Build Coastguard Worker def UidForNetid(cls, netid): 159*2f2c4c7aSAndroid Build Coastguard Worker if not netid: 160*2f2c4c7aSAndroid Build Coastguard Worker return 0 161*2f2c4c7aSAndroid Build Coastguard Worker return random.randint(*cls.UidRangeForNetid(netid)) 162*2f2c4c7aSAndroid Build Coastguard Worker 163*2f2c4c7aSAndroid Build Coastguard Worker @classmethod 164*2f2c4c7aSAndroid Build Coastguard Worker def _TableForNetid(cls, netid): 165*2f2c4c7aSAndroid Build Coastguard Worker if cls.AUTOCONF_TABLE_OFFSET and netid in cls.ifindices: 166*2f2c4c7aSAndroid Build Coastguard Worker return cls.ifindices[netid] + (-cls.AUTOCONF_TABLE_OFFSET) 167*2f2c4c7aSAndroid Build Coastguard Worker else: 168*2f2c4c7aSAndroid Build Coastguard Worker return netid 169*2f2c4c7aSAndroid Build Coastguard Worker 170*2f2c4c7aSAndroid Build Coastguard Worker @staticmethod 171*2f2c4c7aSAndroid Build Coastguard Worker def GetInterfaceName(netid): 172*2f2c4c7aSAndroid Build Coastguard Worker return "nettest%d" % netid 173*2f2c4c7aSAndroid Build Coastguard Worker 174*2f2c4c7aSAndroid Build Coastguard Worker @staticmethod 175*2f2c4c7aSAndroid Build Coastguard Worker def RouterMacAddress(netid): 176*2f2c4c7aSAndroid Build Coastguard Worker return "02:00:00:00:%02x:00" % netid 177*2f2c4c7aSAndroid Build Coastguard Worker 178*2f2c4c7aSAndroid Build Coastguard Worker @staticmethod 179*2f2c4c7aSAndroid Build Coastguard Worker def MyMacAddress(netid): 180*2f2c4c7aSAndroid Build Coastguard Worker return "02:00:00:00:%02x:01" % netid 181*2f2c4c7aSAndroid Build Coastguard Worker 182*2f2c4c7aSAndroid Build Coastguard Worker @staticmethod 183*2f2c4c7aSAndroid Build Coastguard Worker def _RouterAddress(netid, version): 184*2f2c4c7aSAndroid Build Coastguard Worker if version == 6: 185*2f2c4c7aSAndroid Build Coastguard Worker return "fe80::%02x00" % netid 186*2f2c4c7aSAndroid Build Coastguard Worker elif version == 4: 187*2f2c4c7aSAndroid Build Coastguard Worker return "10.0.%d.1" % netid 188*2f2c4c7aSAndroid Build Coastguard Worker else: 189*2f2c4c7aSAndroid Build Coastguard Worker raise ValueError("Don't support IPv%s" % version) 190*2f2c4c7aSAndroid Build Coastguard Worker 191*2f2c4c7aSAndroid Build Coastguard Worker @classmethod 192*2f2c4c7aSAndroid Build Coastguard Worker def _MyIPv4Address(cls, netid): 193*2f2c4c7aSAndroid Build Coastguard Worker return "10.0.%d.2" % netid 194*2f2c4c7aSAndroid Build Coastguard Worker 195*2f2c4c7aSAndroid Build Coastguard Worker @classmethod 196*2f2c4c7aSAndroid Build Coastguard Worker def _MyIPv6Address(cls, netid): 197*2f2c4c7aSAndroid Build Coastguard Worker return net_test.GetLinkAddress(cls.GetInterfaceName(netid), False) 198*2f2c4c7aSAndroid Build Coastguard Worker 199*2f2c4c7aSAndroid Build Coastguard Worker @classmethod 200*2f2c4c7aSAndroid Build Coastguard Worker def MyAddress(cls, version, netid): 201*2f2c4c7aSAndroid Build Coastguard Worker return {4: cls._MyIPv4Address(netid), 202*2f2c4c7aSAndroid Build Coastguard Worker 5: cls._MyIPv4Address(netid), 203*2f2c4c7aSAndroid Build Coastguard Worker 6: cls._MyIPv6Address(netid)}[version] 204*2f2c4c7aSAndroid Build Coastguard Worker 205*2f2c4c7aSAndroid Build Coastguard Worker @classmethod 206*2f2c4c7aSAndroid Build Coastguard Worker def MySocketAddress(cls, version, netid): 207*2f2c4c7aSAndroid Build Coastguard Worker addr = cls.MyAddress(version, netid) 208*2f2c4c7aSAndroid Build Coastguard Worker return "::ffff:" + addr if version == 5 else addr 209*2f2c4c7aSAndroid Build Coastguard Worker 210*2f2c4c7aSAndroid Build Coastguard Worker @classmethod 211*2f2c4c7aSAndroid Build Coastguard Worker def MyLinkLocalAddress(cls, netid): 212*2f2c4c7aSAndroid Build Coastguard Worker return net_test.GetLinkAddress(cls.GetInterfaceName(netid), True) 213*2f2c4c7aSAndroid Build Coastguard Worker 214*2f2c4c7aSAndroid Build Coastguard Worker @staticmethod 215*2f2c4c7aSAndroid Build Coastguard Worker def OnlinkPrefixLen(version): 216*2f2c4c7aSAndroid Build Coastguard Worker return {4: 24, 6: 64}[version] 217*2f2c4c7aSAndroid Build Coastguard Worker 218*2f2c4c7aSAndroid Build Coastguard Worker @staticmethod 219*2f2c4c7aSAndroid Build Coastguard Worker def OnlinkPrefix(version, netid): 220*2f2c4c7aSAndroid Build Coastguard Worker return {4: "10.0.%d.0" % netid, 221*2f2c4c7aSAndroid Build Coastguard Worker 6: "2001:db8:%02x::" % netid}[version] 222*2f2c4c7aSAndroid Build Coastguard Worker 223*2f2c4c7aSAndroid Build Coastguard Worker @staticmethod 224*2f2c4c7aSAndroid Build Coastguard Worker def GetRandomDestination(prefix): 225*2f2c4c7aSAndroid Build Coastguard Worker if "." in prefix: 226*2f2c4c7aSAndroid Build Coastguard Worker return prefix + "%d.%d" % (random.randint(0, 255), random.randint(0, 255)) 227*2f2c4c7aSAndroid Build Coastguard Worker else: 228*2f2c4c7aSAndroid Build Coastguard Worker return prefix + "%x:%x" % (random.randint(0, 65535), 229*2f2c4c7aSAndroid Build Coastguard Worker random.randint(0, 65535)) 230*2f2c4c7aSAndroid Build Coastguard Worker 231*2f2c4c7aSAndroid Build Coastguard Worker def GetProtocolFamily(self, version): 232*2f2c4c7aSAndroid Build Coastguard Worker return {4: AF_INET, 6: AF_INET6}[version] 233*2f2c4c7aSAndroid Build Coastguard Worker 234*2f2c4c7aSAndroid Build Coastguard Worker @classmethod 235*2f2c4c7aSAndroid Build Coastguard Worker def CreateTunInterface(cls, netid): 236*2f2c4c7aSAndroid Build Coastguard Worker iface = cls.GetInterfaceName(netid) 237*2f2c4c7aSAndroid Build Coastguard Worker try: 238*2f2c4c7aSAndroid Build Coastguard Worker f = open("/dev/net/tun", "r+b", buffering=0) 239*2f2c4c7aSAndroid Build Coastguard Worker except IOError: 240*2f2c4c7aSAndroid Build Coastguard Worker f = open("/dev/tun", "r+b", buffering=0) 241*2f2c4c7aSAndroid Build Coastguard Worker ifr = struct.pack("16sH", iface.encode(), IFF_TAP | IFF_NO_PI) 242*2f2c4c7aSAndroid Build Coastguard Worker ifr += b"\x00" * (40 - len(ifr)) 243*2f2c4c7aSAndroid Build Coastguard Worker fcntl.ioctl(f, TUNSETIFF, ifr) 244*2f2c4c7aSAndroid Build Coastguard Worker # Give ourselves a predictable MAC address. 245*2f2c4c7aSAndroid Build Coastguard Worker net_test.SetInterfaceHWAddr(iface, cls.MyMacAddress(netid)) 246*2f2c4c7aSAndroid Build Coastguard Worker # Disable DAD so we don't have to wait for it. 247*2f2c4c7aSAndroid Build Coastguard Worker cls.SetSysctl("/proc/sys/net/ipv6/conf/%s/accept_dad" % iface, 0) 248*2f2c4c7aSAndroid Build Coastguard Worker # Set accept_ra to 2, because that's what we use. 249*2f2c4c7aSAndroid Build Coastguard Worker cls.SetSysctl("/proc/sys/net/ipv6/conf/%s/accept_ra" % iface, 2) 250*2f2c4c7aSAndroid Build Coastguard Worker net_test.SetInterfaceUp(iface) 251*2f2c4c7aSAndroid Build Coastguard Worker net_test.SetNonBlocking(f) 252*2f2c4c7aSAndroid Build Coastguard Worker return f 253*2f2c4c7aSAndroid Build Coastguard Worker 254*2f2c4c7aSAndroid Build Coastguard Worker @classmethod 255*2f2c4c7aSAndroid Build Coastguard Worker def SendRA(cls, netid, retranstimer=None, reachabletime=0, routerlft=RA_VALIDITY, 256*2f2c4c7aSAndroid Build Coastguard Worker piolft=RA_VALIDITY, m=0, o=0, piopflag=0, options=()): 257*2f2c4c7aSAndroid Build Coastguard Worker macaddr = cls.RouterMacAddress(netid) 258*2f2c4c7aSAndroid Build Coastguard Worker lladdr = cls._RouterAddress(netid, 6) 259*2f2c4c7aSAndroid Build Coastguard Worker 260*2f2c4c7aSAndroid Build Coastguard Worker if retranstimer is None: 261*2f2c4c7aSAndroid Build Coastguard Worker # If no retrans timer was specified, pick one that's as long as the 262*2f2c4c7aSAndroid Build Coastguard Worker # router lifetime. This ensures that no spurious ND retransmits 263*2f2c4c7aSAndroid Build Coastguard Worker # will interfere with test expectations. 264*2f2c4c7aSAndroid Build Coastguard Worker retranstimer = routerlft * 1000 # Lifetime is in s, retrans timer in ms. 265*2f2c4c7aSAndroid Build Coastguard Worker 266*2f2c4c7aSAndroid Build Coastguard Worker # We don't want any routes in the main table. If the kernel doesn't support 267*2f2c4c7aSAndroid Build Coastguard Worker # putting RA routes into per-interface tables, configure routing manually. 268*2f2c4c7aSAndroid Build Coastguard Worker if not HAVE_AUTOCONF_TABLE: 269*2f2c4c7aSAndroid Build Coastguard Worker routerlft = 0 270*2f2c4c7aSAndroid Build Coastguard Worker 271*2f2c4c7aSAndroid Build Coastguard Worker res1 = 0x10 if piopflag else 0 272*2f2c4c7aSAndroid Build Coastguard Worker 273*2f2c4c7aSAndroid Build Coastguard Worker ra = (scapy.Ether(src=macaddr, dst="33:33:00:00:00:01") / 274*2f2c4c7aSAndroid Build Coastguard Worker scapy.IPv6(src=lladdr, hlim=255) / 275*2f2c4c7aSAndroid Build Coastguard Worker scapy.ICMPv6ND_RA(reachabletime=reachabletime, 276*2f2c4c7aSAndroid Build Coastguard Worker retranstimer=retranstimer, 277*2f2c4c7aSAndroid Build Coastguard Worker routerlifetime=routerlft, 278*2f2c4c7aSAndroid Build Coastguard Worker M=m, O=o) / 279*2f2c4c7aSAndroid Build Coastguard Worker scapy.ICMPv6NDOptSrcLLAddr(lladdr=macaddr) / 280*2f2c4c7aSAndroid Build Coastguard Worker scapy.ICMPv6NDOptPrefixInfo(prefix=cls.OnlinkPrefix(6, netid), 281*2f2c4c7aSAndroid Build Coastguard Worker prefixlen=cls.OnlinkPrefixLen(6), 282*2f2c4c7aSAndroid Build Coastguard Worker L=1, A=1, res1=res1, 283*2f2c4c7aSAndroid Build Coastguard Worker validlifetime=piolft, 284*2f2c4c7aSAndroid Build Coastguard Worker preferredlifetime=piolft)) 285*2f2c4c7aSAndroid Build Coastguard Worker for option in options: 286*2f2c4c7aSAndroid Build Coastguard Worker ra /= option 287*2f2c4c7aSAndroid Build Coastguard Worker posix.write(cls.tuns[netid].fileno(), bytes(ra)) 288*2f2c4c7aSAndroid Build Coastguard Worker 289*2f2c4c7aSAndroid Build Coastguard Worker @classmethod 290*2f2c4c7aSAndroid Build Coastguard Worker def _RunSetupCommands(cls, netid, is_add): 291*2f2c4c7aSAndroid Build Coastguard Worker for version in [4, 6]: 292*2f2c4c7aSAndroid Build Coastguard Worker # Find out how to configure things. 293*2f2c4c7aSAndroid Build Coastguard Worker iface = cls.GetInterfaceName(netid) 294*2f2c4c7aSAndroid Build Coastguard Worker ifindex = cls.ifindices[netid] 295*2f2c4c7aSAndroid Build Coastguard Worker macaddr = cls.RouterMacAddress(netid) 296*2f2c4c7aSAndroid Build Coastguard Worker router = cls._RouterAddress(netid, version) 297*2f2c4c7aSAndroid Build Coastguard Worker table = cls._TableForNetid(netid) 298*2f2c4c7aSAndroid Build Coastguard Worker 299*2f2c4c7aSAndroid Build Coastguard Worker # Set up routing rules. 300*2f2c4c7aSAndroid Build Coastguard Worker start, end = cls.UidRangeForNetid(netid) 301*2f2c4c7aSAndroid Build Coastguard Worker cls.iproute.UidRangeRule(version, is_add, start, end, table, 302*2f2c4c7aSAndroid Build Coastguard Worker cls.PRIORITY_UID) 303*2f2c4c7aSAndroid Build Coastguard Worker cls.iproute.OifRule(version, is_add, iface, table, cls.PRIORITY_OIF) 304*2f2c4c7aSAndroid Build Coastguard Worker cls.iproute.FwmarkRule(version, is_add, netid, cls.NETID_FWMASK, table, 305*2f2c4c7aSAndroid Build Coastguard Worker cls.PRIORITY_FWMARK) 306*2f2c4c7aSAndroid Build Coastguard Worker 307*2f2c4c7aSAndroid Build Coastguard Worker # Configure routing and addressing. 308*2f2c4c7aSAndroid Build Coastguard Worker # 309*2f2c4c7aSAndroid Build Coastguard Worker # IPv6 uses autoconf for everything, except if per-device autoconf routing 310*2f2c4c7aSAndroid Build Coastguard Worker # tables are not supported, in which case the default route (only) is 311*2f2c4c7aSAndroid Build Coastguard Worker # configured manually. For IPv4 we have to manually configure addresses, 312*2f2c4c7aSAndroid Build Coastguard Worker # routes, and neighbour cache entries (since we don't reply to ARP or ND). 313*2f2c4c7aSAndroid Build Coastguard Worker # 314*2f2c4c7aSAndroid Build Coastguard Worker # Since deleting addresses also causes routes to be deleted, we need to 315*2f2c4c7aSAndroid Build Coastguard Worker # be careful with ordering or the delete commands will fail with ENOENT. 316*2f2c4c7aSAndroid Build Coastguard Worker # 317*2f2c4c7aSAndroid Build Coastguard Worker # A real Android system will have both IPv4 and IPv6 routes for 318*2f2c4c7aSAndroid Build Coastguard Worker # directly-connected subnets in the per-interface routing tables. Ensure 319*2f2c4c7aSAndroid Build Coastguard Worker # we create those as well. 320*2f2c4c7aSAndroid Build Coastguard Worker do_routing = (version == 4 or cls.AUTOCONF_TABLE_OFFSET is None) 321*2f2c4c7aSAndroid Build Coastguard Worker if is_add: 322*2f2c4c7aSAndroid Build Coastguard Worker if version == 4: 323*2f2c4c7aSAndroid Build Coastguard Worker cls.iproute.AddAddress(cls._MyIPv4Address(netid), 324*2f2c4c7aSAndroid Build Coastguard Worker cls.OnlinkPrefixLen(4), ifindex) 325*2f2c4c7aSAndroid Build Coastguard Worker cls.iproute.AddNeighbour(version, router, macaddr, ifindex) 326*2f2c4c7aSAndroid Build Coastguard Worker if do_routing: 327*2f2c4c7aSAndroid Build Coastguard Worker cls.iproute.AddRoute(version, table, 328*2f2c4c7aSAndroid Build Coastguard Worker cls.OnlinkPrefix(version, netid), 329*2f2c4c7aSAndroid Build Coastguard Worker cls.OnlinkPrefixLen(version), None, ifindex) 330*2f2c4c7aSAndroid Build Coastguard Worker cls.iproute.AddRoute(version, table, "default", 0, router, ifindex) 331*2f2c4c7aSAndroid Build Coastguard Worker else: 332*2f2c4c7aSAndroid Build Coastguard Worker if do_routing: 333*2f2c4c7aSAndroid Build Coastguard Worker cls.iproute.DelRoute(version, table, "default", 0, router, ifindex) 334*2f2c4c7aSAndroid Build Coastguard Worker cls.iproute.DelRoute(version, table, 335*2f2c4c7aSAndroid Build Coastguard Worker cls.OnlinkPrefix(version, netid), 336*2f2c4c7aSAndroid Build Coastguard Worker cls.OnlinkPrefixLen(version), None, ifindex) 337*2f2c4c7aSAndroid Build Coastguard Worker if version == 4: 338*2f2c4c7aSAndroid Build Coastguard Worker cls.iproute.DelNeighbour(version, router, macaddr, ifindex) 339*2f2c4c7aSAndroid Build Coastguard Worker cls.iproute.DelAddress(cls._MyIPv4Address(netid), 340*2f2c4c7aSAndroid Build Coastguard Worker cls.OnlinkPrefixLen(4), ifindex) 341*2f2c4c7aSAndroid Build Coastguard Worker 342*2f2c4c7aSAndroid Build Coastguard Worker @classmethod 343*2f2c4c7aSAndroid Build Coastguard Worker def SetMarkReflectSysctls(cls, value): 344*2f2c4c7aSAndroid Build Coastguard Worker """Makes kernel-generated replies use the mark of the original packet.""" 345*2f2c4c7aSAndroid Build Coastguard Worker cls.SetSysctl(IPV4_MARK_REFLECT_SYSCTL, value) 346*2f2c4c7aSAndroid Build Coastguard Worker cls.SetSysctl(IPV6_MARK_REFLECT_SYSCTL, value) 347*2f2c4c7aSAndroid Build Coastguard Worker 348*2f2c4c7aSAndroid Build Coastguard Worker @classmethod 349*2f2c4c7aSAndroid Build Coastguard Worker def _SetInboundMarking(cls, netid, iface, is_add): 350*2f2c4c7aSAndroid Build Coastguard Worker for version in [4, 6]: 351*2f2c4c7aSAndroid Build Coastguard Worker # Run iptables to set up incoming packet marking. 352*2f2c4c7aSAndroid Build Coastguard Worker add_del = "-A" if is_add else "-D" 353*2f2c4c7aSAndroid Build Coastguard Worker iptables = {4: "iptables", 6: "ip6tables"}[version] 354*2f2c4c7aSAndroid Build Coastguard Worker args = "%s INPUT -t mangle -i %s -j MARK --set-mark %d" % ( 355*2f2c4c7aSAndroid Build Coastguard Worker add_del, iface, netid) 356*2f2c4c7aSAndroid Build Coastguard Worker if net_test.RunIptablesCommand(version, args): 357*2f2c4c7aSAndroid Build Coastguard Worker raise ConfigurationError("Setup command failed: %s" % args) 358*2f2c4c7aSAndroid Build Coastguard Worker 359*2f2c4c7aSAndroid Build Coastguard Worker @classmethod 360*2f2c4c7aSAndroid Build Coastguard Worker def SetInboundMarks(cls, is_add): 361*2f2c4c7aSAndroid Build Coastguard Worker for netid in cls.tuns: 362*2f2c4c7aSAndroid Build Coastguard Worker cls._SetInboundMarking(netid, cls.GetInterfaceName(netid), is_add) 363*2f2c4c7aSAndroid Build Coastguard Worker 364*2f2c4c7aSAndroid Build Coastguard Worker @classmethod 365*2f2c4c7aSAndroid Build Coastguard Worker def SetDefaultNetwork(cls, netid): 366*2f2c4c7aSAndroid Build Coastguard Worker table = cls._TableForNetid(netid) if netid else None 367*2f2c4c7aSAndroid Build Coastguard Worker for version in [4, 6]: 368*2f2c4c7aSAndroid Build Coastguard Worker is_add = table is not None 369*2f2c4c7aSAndroid Build Coastguard Worker cls.iproute.DefaultRule(version, is_add, table, cls.PRIORITY_DEFAULT) 370*2f2c4c7aSAndroid Build Coastguard Worker 371*2f2c4c7aSAndroid Build Coastguard Worker @classmethod 372*2f2c4c7aSAndroid Build Coastguard Worker def ClearDefaultNetwork(cls): 373*2f2c4c7aSAndroid Build Coastguard Worker cls.SetDefaultNetwork(None) 374*2f2c4c7aSAndroid Build Coastguard Worker 375*2f2c4c7aSAndroid Build Coastguard Worker @classmethod 376*2f2c4c7aSAndroid Build Coastguard Worker def GetSysctl(cls, sysctl): 377*2f2c4c7aSAndroid Build Coastguard Worker with open(sysctl, "r") as sysctl_file: 378*2f2c4c7aSAndroid Build Coastguard Worker return sysctl_file.read() 379*2f2c4c7aSAndroid Build Coastguard Worker 380*2f2c4c7aSAndroid Build Coastguard Worker @classmethod 381*2f2c4c7aSAndroid Build Coastguard Worker def SetSysctl(cls, sysctl, value): 382*2f2c4c7aSAndroid Build Coastguard Worker # Only save each sysctl value the first time we set it. This is so we can 383*2f2c4c7aSAndroid Build Coastguard Worker # set it to arbitrary values multiple times and still write it back 384*2f2c4c7aSAndroid Build Coastguard Worker # correctly at the end. 385*2f2c4c7aSAndroid Build Coastguard Worker if sysctl not in cls.saved_sysctls: 386*2f2c4c7aSAndroid Build Coastguard Worker cls.saved_sysctls[sysctl] = cls.GetSysctl(sysctl) 387*2f2c4c7aSAndroid Build Coastguard Worker with open(sysctl, "w") as sysctl_file: 388*2f2c4c7aSAndroid Build Coastguard Worker sysctl_file.write(str(value) + "\n") 389*2f2c4c7aSAndroid Build Coastguard Worker 390*2f2c4c7aSAndroid Build Coastguard Worker @classmethod 391*2f2c4c7aSAndroid Build Coastguard Worker def SetIPv6SysctlOnAllIfaces(cls, sysctl, value): 392*2f2c4c7aSAndroid Build Coastguard Worker for netid in cls.tuns: 393*2f2c4c7aSAndroid Build Coastguard Worker iface = cls.GetInterfaceName(netid) 394*2f2c4c7aSAndroid Build Coastguard Worker name = "/proc/sys/net/ipv6/conf/%s/%s" % (iface, sysctl) 395*2f2c4c7aSAndroid Build Coastguard Worker cls.SetSysctl(name, value) 396*2f2c4c7aSAndroid Build Coastguard Worker 397*2f2c4c7aSAndroid Build Coastguard Worker @classmethod 398*2f2c4c7aSAndroid Build Coastguard Worker def _RestoreSysctls(cls): 399*2f2c4c7aSAndroid Build Coastguard Worker for sysctl, value in cls.saved_sysctls.items(): 400*2f2c4c7aSAndroid Build Coastguard Worker try: 401*2f2c4c7aSAndroid Build Coastguard Worker with open(sysctl, "w") as sysctl_file: 402*2f2c4c7aSAndroid Build Coastguard Worker sysctl_file.write(value) 403*2f2c4c7aSAndroid Build Coastguard Worker except IOError: 404*2f2c4c7aSAndroid Build Coastguard Worker pass 405*2f2c4c7aSAndroid Build Coastguard Worker 406*2f2c4c7aSAndroid Build Coastguard Worker @classmethod 407*2f2c4c7aSAndroid Build Coastguard Worker def _ICMPRatelimitFilename(cls, version): 408*2f2c4c7aSAndroid Build Coastguard Worker return "/proc/sys/net/" + {4: "ipv4/icmp_ratelimit", 409*2f2c4c7aSAndroid Build Coastguard Worker 6: "ipv6/icmp/ratelimit"}[version] 410*2f2c4c7aSAndroid Build Coastguard Worker 411*2f2c4c7aSAndroid Build Coastguard Worker @classmethod 412*2f2c4c7aSAndroid Build Coastguard Worker def _SetICMPRatelimit(cls, version, limit): 413*2f2c4c7aSAndroid Build Coastguard Worker cls.SetSysctl(cls._ICMPRatelimitFilename(version), limit) 414*2f2c4c7aSAndroid Build Coastguard Worker 415*2f2c4c7aSAndroid Build Coastguard Worker @classmethod 416*2f2c4c7aSAndroid Build Coastguard Worker def setUpClass(cls): 417*2f2c4c7aSAndroid Build Coastguard Worker # This is per-class setup instead of per-testcase setup because shelling out 418*2f2c4c7aSAndroid Build Coastguard Worker # to ip and iptables is slow, and because routing configuration doesn't 419*2f2c4c7aSAndroid Build Coastguard Worker # change during the test. 420*2f2c4c7aSAndroid Build Coastguard Worker cls.iproute = iproute.IPRoute() 421*2f2c4c7aSAndroid Build Coastguard Worker cls.tuns = {} 422*2f2c4c7aSAndroid Build Coastguard Worker cls.ifindices = {} 423*2f2c4c7aSAndroid Build Coastguard Worker if HAVE_AUTOCONF_TABLE: 424*2f2c4c7aSAndroid Build Coastguard Worker cls.SetSysctl(AUTOCONF_TABLE_SYSCTL, -1000) 425*2f2c4c7aSAndroid Build Coastguard Worker cls.AUTOCONF_TABLE_OFFSET = -1000 426*2f2c4c7aSAndroid Build Coastguard Worker else: 427*2f2c4c7aSAndroid Build Coastguard Worker cls.AUTOCONF_TABLE_OFFSET = None 428*2f2c4c7aSAndroid Build Coastguard Worker 429*2f2c4c7aSAndroid Build Coastguard Worker # Disable ICMP rate limits. These will be restored by _RestoreSysctls. 430*2f2c4c7aSAndroid Build Coastguard Worker for version in [4, 6]: 431*2f2c4c7aSAndroid Build Coastguard Worker cls._SetICMPRatelimit(version, 0) 432*2f2c4c7aSAndroid Build Coastguard Worker 433*2f2c4c7aSAndroid Build Coastguard Worker for version in [4, 6]: 434*2f2c4c7aSAndroid Build Coastguard Worker cls.iproute.UnreachableRule(version, True, cls.PRIORITY_UNREACHABLE) 435*2f2c4c7aSAndroid Build Coastguard Worker 436*2f2c4c7aSAndroid Build Coastguard Worker for netid in cls.NETIDS: 437*2f2c4c7aSAndroid Build Coastguard Worker cls.tuns[netid] = cls.CreateTunInterface(netid) 438*2f2c4c7aSAndroid Build Coastguard Worker iface = cls.GetInterfaceName(netid) 439*2f2c4c7aSAndroid Build Coastguard Worker cls.ifindices[netid] = net_test.GetInterfaceIndex(iface) 440*2f2c4c7aSAndroid Build Coastguard Worker 441*2f2c4c7aSAndroid Build Coastguard Worker cls.SendRA(netid) 442*2f2c4c7aSAndroid Build Coastguard Worker cls._RunSetupCommands(netid, True) 443*2f2c4c7aSAndroid Build Coastguard Worker 444*2f2c4c7aSAndroid Build Coastguard Worker # Don't print lots of "device foo entered promiscuous mode" warnings. 445*2f2c4c7aSAndroid Build Coastguard Worker cls.loglevel = cls.GetConsoleLogLevel() 446*2f2c4c7aSAndroid Build Coastguard Worker cls.SetConsoleLogLevel(net_test.KERN_INFO) 447*2f2c4c7aSAndroid Build Coastguard Worker 448*2f2c4c7aSAndroid Build Coastguard Worker # When running on device, don't send connections through FwmarkServer. 449*2f2c4c7aSAndroid Build Coastguard Worker os.environ["ANDROID_NO_USE_FWMARK_CLIENT"] = "1" 450*2f2c4c7aSAndroid Build Coastguard Worker 451*2f2c4c7aSAndroid Build Coastguard Worker # Uncomment to look around at interface and rule configuration while 452*2f2c4c7aSAndroid Build Coastguard Worker # running in the background. (Once the test finishes running, all the 453*2f2c4c7aSAndroid Build Coastguard Worker # interfaces and rules are gone.) 454*2f2c4c7aSAndroid Build Coastguard Worker # time.sleep(30) 455*2f2c4c7aSAndroid Build Coastguard Worker 456*2f2c4c7aSAndroid Build Coastguard Worker @classmethod 457*2f2c4c7aSAndroid Build Coastguard Worker def tearDownClass(cls): 458*2f2c4c7aSAndroid Build Coastguard Worker del os.environ["ANDROID_NO_USE_FWMARK_CLIENT"] 459*2f2c4c7aSAndroid Build Coastguard Worker 460*2f2c4c7aSAndroid Build Coastguard Worker for version in [4, 6]: 461*2f2c4c7aSAndroid Build Coastguard Worker try: 462*2f2c4c7aSAndroid Build Coastguard Worker cls.iproute.UnreachableRule(version, False, cls.PRIORITY_UNREACHABLE) 463*2f2c4c7aSAndroid Build Coastguard Worker except IOError: 464*2f2c4c7aSAndroid Build Coastguard Worker pass 465*2f2c4c7aSAndroid Build Coastguard Worker 466*2f2c4c7aSAndroid Build Coastguard Worker for netid in cls.tuns: 467*2f2c4c7aSAndroid Build Coastguard Worker cls._RunSetupCommands(netid, False) 468*2f2c4c7aSAndroid Build Coastguard Worker cls.tuns[netid].close() 469*2f2c4c7aSAndroid Build Coastguard Worker 470*2f2c4c7aSAndroid Build Coastguard Worker cls.iproute.close() 471*2f2c4c7aSAndroid Build Coastguard Worker cls._RestoreSysctls() 472*2f2c4c7aSAndroid Build Coastguard Worker cls.SetConsoleLogLevel(cls.loglevel) 473*2f2c4c7aSAndroid Build Coastguard Worker 474*2f2c4c7aSAndroid Build Coastguard Worker def setUp(self): 475*2f2c4c7aSAndroid Build Coastguard Worker self.ClearTunQueues() 476*2f2c4c7aSAndroid Build Coastguard Worker 477*2f2c4c7aSAndroid Build Coastguard Worker def SetSocketMark(self, s, netid): 478*2f2c4c7aSAndroid Build Coastguard Worker if netid is None: 479*2f2c4c7aSAndroid Build Coastguard Worker netid = 0 480*2f2c4c7aSAndroid Build Coastguard Worker s.setsockopt(SOL_SOCKET, net_test.SO_MARK, netid) 481*2f2c4c7aSAndroid Build Coastguard Worker 482*2f2c4c7aSAndroid Build Coastguard Worker def GetSocketMark(self, s): 483*2f2c4c7aSAndroid Build Coastguard Worker return s.getsockopt(SOL_SOCKET, net_test.SO_MARK) 484*2f2c4c7aSAndroid Build Coastguard Worker 485*2f2c4c7aSAndroid Build Coastguard Worker def ClearSocketMark(self, s): 486*2f2c4c7aSAndroid Build Coastguard Worker self.SetSocketMark(s, 0) 487*2f2c4c7aSAndroid Build Coastguard Worker 488*2f2c4c7aSAndroid Build Coastguard Worker def BindToDevice(self, s, iface): 489*2f2c4c7aSAndroid Build Coastguard Worker if not iface: 490*2f2c4c7aSAndroid Build Coastguard Worker iface = "" 491*2f2c4c7aSAndroid Build Coastguard Worker s.setsockopt(SOL_SOCKET, SO_BINDTODEVICE, iface.encode()) 492*2f2c4c7aSAndroid Build Coastguard Worker 493*2f2c4c7aSAndroid Build Coastguard Worker def SetUnicastInterface(self, s, ifindex): 494*2f2c4c7aSAndroid Build Coastguard Worker # Otherwise, Python thinks it's a 1-byte option. 495*2f2c4c7aSAndroid Build Coastguard Worker ifindex = struct.pack("!I", ifindex) 496*2f2c4c7aSAndroid Build Coastguard Worker 497*2f2c4c7aSAndroid Build Coastguard Worker # Always set the IPv4 interface, because it will be used even on IPv6 498*2f2c4c7aSAndroid Build Coastguard Worker # sockets if the destination address is a mapped address. 499*2f2c4c7aSAndroid Build Coastguard Worker s.setsockopt(net_test.SOL_IP, IP_UNICAST_IF, ifindex) 500*2f2c4c7aSAndroid Build Coastguard Worker if s.family == AF_INET6: 501*2f2c4c7aSAndroid Build Coastguard Worker s.setsockopt(net_test.SOL_IPV6, IPV6_UNICAST_IF, ifindex) 502*2f2c4c7aSAndroid Build Coastguard Worker 503*2f2c4c7aSAndroid Build Coastguard Worker def GetRemoteAddress(self, version): 504*2f2c4c7aSAndroid Build Coastguard Worker return {4: self.IPV4_ADDR, 505*2f2c4c7aSAndroid Build Coastguard Worker 5: self.IPV4_ADDR, # see GetRemoteSocketAddress() 506*2f2c4c7aSAndroid Build Coastguard Worker 6: self.IPV6_ADDR}[version] 507*2f2c4c7aSAndroid Build Coastguard Worker 508*2f2c4c7aSAndroid Build Coastguard Worker def GetRemoteSocketAddress(self, version): 509*2f2c4c7aSAndroid Build Coastguard Worker addr = self.GetRemoteAddress(version) 510*2f2c4c7aSAndroid Build Coastguard Worker return "::ffff:" + addr if version == 5 else addr 511*2f2c4c7aSAndroid Build Coastguard Worker 512*2f2c4c7aSAndroid Build Coastguard Worker def GetOtherRemoteSocketAddress(self, version): 513*2f2c4c7aSAndroid Build Coastguard Worker return {4: self.IPV4_ADDR2, 514*2f2c4c7aSAndroid Build Coastguard Worker 5: "::ffff:" + self.IPV4_ADDR2, 515*2f2c4c7aSAndroid Build Coastguard Worker 6: self.IPV6_ADDR2}[version] 516*2f2c4c7aSAndroid Build Coastguard Worker 517*2f2c4c7aSAndroid Build Coastguard Worker def SelectInterface(self, s, netid, mode): 518*2f2c4c7aSAndroid Build Coastguard Worker if mode == "uid": 519*2f2c4c7aSAndroid Build Coastguard Worker os.fchown(s.fileno(), self.UidForNetid(netid), -1) 520*2f2c4c7aSAndroid Build Coastguard Worker elif mode == "mark": 521*2f2c4c7aSAndroid Build Coastguard Worker self.SetSocketMark(s, netid) 522*2f2c4c7aSAndroid Build Coastguard Worker elif mode == "oif": 523*2f2c4c7aSAndroid Build Coastguard Worker iface = self.GetInterfaceName(netid) if netid else "" 524*2f2c4c7aSAndroid Build Coastguard Worker self.BindToDevice(s, iface) 525*2f2c4c7aSAndroid Build Coastguard Worker elif mode == "ucast_oif": 526*2f2c4c7aSAndroid Build Coastguard Worker self.SetUnicastInterface(s, self.ifindices.get(netid, 0)) 527*2f2c4c7aSAndroid Build Coastguard Worker else: 528*2f2c4c7aSAndroid Build Coastguard Worker raise ValueError("Unknown interface selection mode %s" % mode) 529*2f2c4c7aSAndroid Build Coastguard Worker 530*2f2c4c7aSAndroid Build Coastguard Worker def BuildSocket(self, version, constructor, netid, routing_mode): 531*2f2c4c7aSAndroid Build Coastguard Worker if version == 5: version = 6 532*2f2c4c7aSAndroid Build Coastguard Worker s = constructor(self.GetProtocolFamily(version)) 533*2f2c4c7aSAndroid Build Coastguard Worker 534*2f2c4c7aSAndroid Build Coastguard Worker if routing_mode not in [None, "uid"]: 535*2f2c4c7aSAndroid Build Coastguard Worker self.SelectInterface(s, netid, routing_mode) 536*2f2c4c7aSAndroid Build Coastguard Worker elif routing_mode == "uid": 537*2f2c4c7aSAndroid Build Coastguard Worker os.fchown(s.fileno(), self.UidForNetid(netid), -1) 538*2f2c4c7aSAndroid Build Coastguard Worker 539*2f2c4c7aSAndroid Build Coastguard Worker return s 540*2f2c4c7aSAndroid Build Coastguard Worker 541*2f2c4c7aSAndroid Build Coastguard Worker def RandomNetid(self, exclude=None): 542*2f2c4c7aSAndroid Build Coastguard Worker """Return a random netid from the list of netids 543*2f2c4c7aSAndroid Build Coastguard Worker 544*2f2c4c7aSAndroid Build Coastguard Worker Args: 545*2f2c4c7aSAndroid Build Coastguard Worker exclude: a netid or list of netids that should not be chosen 546*2f2c4c7aSAndroid Build Coastguard Worker """ 547*2f2c4c7aSAndroid Build Coastguard Worker if exclude is None: 548*2f2c4c7aSAndroid Build Coastguard Worker exclude = [] 549*2f2c4c7aSAndroid Build Coastguard Worker elif isinstance(exclude, int): 550*2f2c4c7aSAndroid Build Coastguard Worker exclude = [exclude] 551*2f2c4c7aSAndroid Build Coastguard Worker diff = [netid for netid in self.NETIDS if netid not in exclude] 552*2f2c4c7aSAndroid Build Coastguard Worker return random.choice(diff) 553*2f2c4c7aSAndroid Build Coastguard Worker 554*2f2c4c7aSAndroid Build Coastguard Worker def SendOnNetid(self, version, s, dstaddr, dstport, netid, payload, cmsgs): 555*2f2c4c7aSAndroid Build Coastguard Worker if netid is not None: 556*2f2c4c7aSAndroid Build Coastguard Worker pktinfo = MakePktInfo(version, None, self.ifindices[netid]) 557*2f2c4c7aSAndroid Build Coastguard Worker cmsg_level, cmsg_name = { 558*2f2c4c7aSAndroid Build Coastguard Worker 4: (net_test.SOL_IP, csocket.IP_PKTINFO), 559*2f2c4c7aSAndroid Build Coastguard Worker 6: (net_test.SOL_IPV6, csocket.IPV6_PKTINFO)}[version] 560*2f2c4c7aSAndroid Build Coastguard Worker cmsgs.append((cmsg_level, cmsg_name, pktinfo)) 561*2f2c4c7aSAndroid Build Coastguard Worker csocket.Sendmsg(s, (dstaddr, dstport), payload, cmsgs, csocket.MSG_CONFIRM) 562*2f2c4c7aSAndroid Build Coastguard Worker 563*2f2c4c7aSAndroid Build Coastguard Worker def ReceiveEtherPacketOn(self, netid, packet): 564*2f2c4c7aSAndroid Build Coastguard Worker posix.write(self.tuns[netid].fileno(), bytes(packet)) 565*2f2c4c7aSAndroid Build Coastguard Worker 566*2f2c4c7aSAndroid Build Coastguard Worker def ReceivePacketOn(self, netid, ip_packet): 567*2f2c4c7aSAndroid Build Coastguard Worker routermac = self.RouterMacAddress(netid) 568*2f2c4c7aSAndroid Build Coastguard Worker mymac = self.MyMacAddress(netid) 569*2f2c4c7aSAndroid Build Coastguard Worker packet = scapy.Ether(src=routermac, dst=mymac) / ip_packet 570*2f2c4c7aSAndroid Build Coastguard Worker self.ReceiveEtherPacketOn(netid, packet) 571*2f2c4c7aSAndroid Build Coastguard Worker 572*2f2c4c7aSAndroid Build Coastguard Worker def ReadAllPacketsOn(self, netid, include_multicast=False): 573*2f2c4c7aSAndroid Build Coastguard Worker """Return all queued packets on a netid as a list. 574*2f2c4c7aSAndroid Build Coastguard Worker 575*2f2c4c7aSAndroid Build Coastguard Worker Args: 576*2f2c4c7aSAndroid Build Coastguard Worker netid: The netid from which to read packets 577*2f2c4c7aSAndroid Build Coastguard Worker include_multicast: A boolean, whether to remove multicast packets 578*2f2c4c7aSAndroid Build Coastguard Worker (default=False) 579*2f2c4c7aSAndroid Build Coastguard Worker """ 580*2f2c4c7aSAndroid Build Coastguard Worker packets = [] 581*2f2c4c7aSAndroid Build Coastguard Worker retries = 0 582*2f2c4c7aSAndroid Build Coastguard Worker max_retries = 1 583*2f2c4c7aSAndroid Build Coastguard Worker while True: 584*2f2c4c7aSAndroid Build Coastguard Worker try: 585*2f2c4c7aSAndroid Build Coastguard Worker packet = posix.read(self.tuns[netid].fileno(), 4096) 586*2f2c4c7aSAndroid Build Coastguard Worker if not packet: 587*2f2c4c7aSAndroid Build Coastguard Worker break 588*2f2c4c7aSAndroid Build Coastguard Worker ether = scapy.Ether(packet) 589*2f2c4c7aSAndroid Build Coastguard Worker # Multicast frames are frames where the first byte of the destination 590*2f2c4c7aSAndroid Build Coastguard Worker # MAC address has 1 in the least-significant bit. 591*2f2c4c7aSAndroid Build Coastguard Worker if include_multicast or not int(ether.dst.split(":")[0], 16) & 0x1: 592*2f2c4c7aSAndroid Build Coastguard Worker packets.append(ether.payload) 593*2f2c4c7aSAndroid Build Coastguard Worker except OSError as e: 594*2f2c4c7aSAndroid Build Coastguard Worker # EAGAIN means there are no more packets waiting. 595*2f2c4c7aSAndroid Build Coastguard Worker if e.errno == errno.EAGAIN: 596*2f2c4c7aSAndroid Build Coastguard Worker # If we didn't see any packets, try again for good luck. 597*2f2c4c7aSAndroid Build Coastguard Worker if not packets and retries < max_retries: 598*2f2c4c7aSAndroid Build Coastguard Worker time.sleep(0.01) 599*2f2c4c7aSAndroid Build Coastguard Worker retries += 1 600*2f2c4c7aSAndroid Build Coastguard Worker continue 601*2f2c4c7aSAndroid Build Coastguard Worker else: 602*2f2c4c7aSAndroid Build Coastguard Worker break 603*2f2c4c7aSAndroid Build Coastguard Worker # Anything else is unexpected. 604*2f2c4c7aSAndroid Build Coastguard Worker else: 605*2f2c4c7aSAndroid Build Coastguard Worker raise e 606*2f2c4c7aSAndroid Build Coastguard Worker return packets 607*2f2c4c7aSAndroid Build Coastguard Worker 608*2f2c4c7aSAndroid Build Coastguard Worker def InvalidateDstCache(self, version, netid): 609*2f2c4c7aSAndroid Build Coastguard Worker """Invalidates destination cache entries of sockets on the specified table. 610*2f2c4c7aSAndroid Build Coastguard Worker 611*2f2c4c7aSAndroid Build Coastguard Worker Creates and then deletes a low-priority throw route in the table for the 612*2f2c4c7aSAndroid Build Coastguard Worker given netid, which invalidates the destination cache entries of any sockets 613*2f2c4c7aSAndroid Build Coastguard Worker that refer to routes in that table. 614*2f2c4c7aSAndroid Build Coastguard Worker 615*2f2c4c7aSAndroid Build Coastguard Worker The fact that this method actually invalidates destination cache entries is 616*2f2c4c7aSAndroid Build Coastguard Worker tested by OutgoingTest#testIPv[46]Remarking, which checks that the kernel 617*2f2c4c7aSAndroid Build Coastguard Worker does not re-route sockets when they are remarked, but does re-route them if 618*2f2c4c7aSAndroid Build Coastguard Worker this method is called. 619*2f2c4c7aSAndroid Build Coastguard Worker 620*2f2c4c7aSAndroid Build Coastguard Worker Args: 621*2f2c4c7aSAndroid Build Coastguard Worker version: The IP version, 4 or 6. 622*2f2c4c7aSAndroid Build Coastguard Worker netid: The netid to invalidate dst caches on. 623*2f2c4c7aSAndroid Build Coastguard Worker """ 624*2f2c4c7aSAndroid Build Coastguard Worker iface = self.GetInterfaceName(netid) 625*2f2c4c7aSAndroid Build Coastguard Worker ifindex = self.ifindices[netid] 626*2f2c4c7aSAndroid Build Coastguard Worker table = self._TableForNetid(netid) 627*2f2c4c7aSAndroid Build Coastguard Worker for action in [iproute.RTM_NEWROUTE, iproute.RTM_DELROUTE]: 628*2f2c4c7aSAndroid Build Coastguard Worker self.iproute._Route(version, iproute.RTPROT_STATIC, action, table, 629*2f2c4c7aSAndroid Build Coastguard Worker "default", 0, nexthop=None, dev=None, mark=None, 630*2f2c4c7aSAndroid Build Coastguard Worker uid=None, route_type=iproute.RTN_THROW, 631*2f2c4c7aSAndroid Build Coastguard Worker priority=100000) 632*2f2c4c7aSAndroid Build Coastguard Worker 633*2f2c4c7aSAndroid Build Coastguard Worker def ClearTunQueues(self): 634*2f2c4c7aSAndroid Build Coastguard Worker # Keep reading packets on all netids until we get no packets on any of them. 635*2f2c4c7aSAndroid Build Coastguard Worker waiting = None 636*2f2c4c7aSAndroid Build Coastguard Worker while waiting != 0: 637*2f2c4c7aSAndroid Build Coastguard Worker waiting = sum(len(self.ReadAllPacketsOn(netid)) for netid in self.NETIDS) 638*2f2c4c7aSAndroid Build Coastguard Worker 639*2f2c4c7aSAndroid Build Coastguard Worker def assertPacketMatches(self, expected, actual): 640*2f2c4c7aSAndroid Build Coastguard Worker # The expected packet is just a rough sketch of the packet we expect to 641*2f2c4c7aSAndroid Build Coastguard Worker # receive. For example, it doesn't contain fields we can't predict, such as 642*2f2c4c7aSAndroid Build Coastguard Worker # initial TCP sequence numbers, or that depend on the host implementation 643*2f2c4c7aSAndroid Build Coastguard Worker # and settings, such as TCP options. To check whether the packet matches 644*2f2c4c7aSAndroid Build Coastguard Worker # what we expect, instead of just checking all the known fields one by one, 645*2f2c4c7aSAndroid Build Coastguard Worker # we blank out fields in the actual packet and then compare the whole 646*2f2c4c7aSAndroid Build Coastguard Worker # packets to each other as strings. Because we modify the actual packet, 647*2f2c4c7aSAndroid Build Coastguard Worker # make a copy here. 648*2f2c4c7aSAndroid Build Coastguard Worker actual = actual.copy() 649*2f2c4c7aSAndroid Build Coastguard Worker 650*2f2c4c7aSAndroid Build Coastguard Worker # Blank out IPv4 fields that we can't predict, like ID and the DF bit. 651*2f2c4c7aSAndroid Build Coastguard Worker actualip = actual.getlayer("IP") 652*2f2c4c7aSAndroid Build Coastguard Worker expectedip = expected.getlayer("IP") 653*2f2c4c7aSAndroid Build Coastguard Worker if actualip and expectedip: 654*2f2c4c7aSAndroid Build Coastguard Worker actualip.id = expectedip.id 655*2f2c4c7aSAndroid Build Coastguard Worker actualip.flags &= 5 656*2f2c4c7aSAndroid Build Coastguard Worker actualip.chksum = None # Change the header, recalculate the checksum. 657*2f2c4c7aSAndroid Build Coastguard Worker 658*2f2c4c7aSAndroid Build Coastguard Worker # Blank out the flow label, since new kernels randomize it by default. 659*2f2c4c7aSAndroid Build Coastguard Worker actualipv6 = actual.getlayer("IPv6") 660*2f2c4c7aSAndroid Build Coastguard Worker expectedipv6 = expected.getlayer("IPv6") 661*2f2c4c7aSAndroid Build Coastguard Worker if actualipv6 and expectedipv6: 662*2f2c4c7aSAndroid Build Coastguard Worker actualipv6.fl = expectedipv6.fl 663*2f2c4c7aSAndroid Build Coastguard Worker 664*2f2c4c7aSAndroid Build Coastguard Worker # Blank out UDP fields that we can't predict (e.g., the source port for 665*2f2c4c7aSAndroid Build Coastguard Worker # kernel-originated packets). 666*2f2c4c7aSAndroid Build Coastguard Worker actualudp = actual.getlayer("UDP") 667*2f2c4c7aSAndroid Build Coastguard Worker expectedudp = expected.getlayer("UDP") 668*2f2c4c7aSAndroid Build Coastguard Worker if actualudp and expectedudp: 669*2f2c4c7aSAndroid Build Coastguard Worker if expectedudp.sport is None: 670*2f2c4c7aSAndroid Build Coastguard Worker actualudp.sport = None 671*2f2c4c7aSAndroid Build Coastguard Worker actualudp.chksum = None 672*2f2c4c7aSAndroid Build Coastguard Worker elif actualudp.chksum == 0xffff and expectedudp.chksum == 0: 673*2f2c4c7aSAndroid Build Coastguard Worker # Scapy does not appear to change 0 to 0xffff as required by RFC 768. 674*2f2c4c7aSAndroid Build Coastguard Worker # It is possible that scapy has been upgraded and this no longer triggers. 675*2f2c4c7aSAndroid Build Coastguard Worker actualudp.chksum = 0 676*2f2c4c7aSAndroid Build Coastguard Worker 677*2f2c4c7aSAndroid Build Coastguard Worker # Since the TCP code below messes with options, recalculate the length. 678*2f2c4c7aSAndroid Build Coastguard Worker if actualip: 679*2f2c4c7aSAndroid Build Coastguard Worker actualip.len = None 680*2f2c4c7aSAndroid Build Coastguard Worker if actualipv6: 681*2f2c4c7aSAndroid Build Coastguard Worker actualipv6.plen = None 682*2f2c4c7aSAndroid Build Coastguard Worker 683*2f2c4c7aSAndroid Build Coastguard Worker # Blank out TCP fields that we can't predict. 684*2f2c4c7aSAndroid Build Coastguard Worker actualtcp = actual.getlayer("TCP") 685*2f2c4c7aSAndroid Build Coastguard Worker expectedtcp = expected.getlayer("TCP") 686*2f2c4c7aSAndroid Build Coastguard Worker if actualtcp and expectedtcp: 687*2f2c4c7aSAndroid Build Coastguard Worker actualtcp.dataofs = expectedtcp.dataofs 688*2f2c4c7aSAndroid Build Coastguard Worker actualtcp.options = expectedtcp.options 689*2f2c4c7aSAndroid Build Coastguard Worker actualtcp.window = expectedtcp.window 690*2f2c4c7aSAndroid Build Coastguard Worker if expectedtcp.sport is None: 691*2f2c4c7aSAndroid Build Coastguard Worker actualtcp.sport = None 692*2f2c4c7aSAndroid Build Coastguard Worker if expectedtcp.seq is None: 693*2f2c4c7aSAndroid Build Coastguard Worker actualtcp.seq = None 694*2f2c4c7aSAndroid Build Coastguard Worker if expectedtcp.ack is None: 695*2f2c4c7aSAndroid Build Coastguard Worker actualtcp.ack = None 696*2f2c4c7aSAndroid Build Coastguard Worker actualtcp.chksum = None 697*2f2c4c7aSAndroid Build Coastguard Worker 698*2f2c4c7aSAndroid Build Coastguard Worker # Serialize the packet so that expected packet fields that are only set when 699*2f2c4c7aSAndroid Build Coastguard Worker # a packet is serialized e.g., the checksum) are filled in. 700*2f2c4c7aSAndroid Build Coastguard Worker expected_real = expected.__class__(bytes(expected)) 701*2f2c4c7aSAndroid Build Coastguard Worker actual_real = actual.__class__(bytes(actual)) 702*2f2c4c7aSAndroid Build Coastguard Worker # repr() can be expensive. Call it only if the test is going to fail and we 703*2f2c4c7aSAndroid Build Coastguard Worker # want to see the error. 704*2f2c4c7aSAndroid Build Coastguard Worker if expected_real != actual_real: 705*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(repr(expected_real), repr(actual_real)) 706*2f2c4c7aSAndroid Build Coastguard Worker 707*2f2c4c7aSAndroid Build Coastguard Worker def PacketMatches(self, expected, actual): 708*2f2c4c7aSAndroid Build Coastguard Worker try: 709*2f2c4c7aSAndroid Build Coastguard Worker self.assertPacketMatches(expected, actual) 710*2f2c4c7aSAndroid Build Coastguard Worker return True 711*2f2c4c7aSAndroid Build Coastguard Worker except AssertionError: 712*2f2c4c7aSAndroid Build Coastguard Worker return False 713*2f2c4c7aSAndroid Build Coastguard Worker 714*2f2c4c7aSAndroid Build Coastguard Worker def ExpectNoPacketsOn(self, netid, msg): 715*2f2c4c7aSAndroid Build Coastguard Worker packets = self.ReadAllPacketsOn(netid) 716*2f2c4c7aSAndroid Build Coastguard Worker if packets: 717*2f2c4c7aSAndroid Build Coastguard Worker firstpacket = repr(packets[0]) 718*2f2c4c7aSAndroid Build Coastguard Worker else: 719*2f2c4c7aSAndroid Build Coastguard Worker firstpacket = "" 720*2f2c4c7aSAndroid Build Coastguard Worker self.assertFalse(packets, msg + ": unexpected packet: " + firstpacket) 721*2f2c4c7aSAndroid Build Coastguard Worker 722*2f2c4c7aSAndroid Build Coastguard Worker def ExpectPacketOn(self, netid, msg, expected): 723*2f2c4c7aSAndroid Build Coastguard Worker # To avoid confusion due to lots of ICMPv6 ND going on all the time, drop 724*2f2c4c7aSAndroid Build Coastguard Worker # multicast packets unless the packet we expect to see is a multicast 725*2f2c4c7aSAndroid Build Coastguard Worker # packet. For now the only tests that use this are IPv6. 726*2f2c4c7aSAndroid Build Coastguard Worker ipv6 = expected.getlayer("IPv6") 727*2f2c4c7aSAndroid Build Coastguard Worker if ipv6 and ipv6.dst.startswith("ff"): 728*2f2c4c7aSAndroid Build Coastguard Worker include_multicast = True 729*2f2c4c7aSAndroid Build Coastguard Worker else: 730*2f2c4c7aSAndroid Build Coastguard Worker include_multicast = False 731*2f2c4c7aSAndroid Build Coastguard Worker 732*2f2c4c7aSAndroid Build Coastguard Worker packets = self.ReadAllPacketsOn(netid, include_multicast=include_multicast) 733*2f2c4c7aSAndroid Build Coastguard Worker self.assertTrue(packets, msg + ": received no packets") 734*2f2c4c7aSAndroid Build Coastguard Worker 735*2f2c4c7aSAndroid Build Coastguard Worker # If we receive a packet that matches what we expected, return it. 736*2f2c4c7aSAndroid Build Coastguard Worker for packet in packets: 737*2f2c4c7aSAndroid Build Coastguard Worker if self.PacketMatches(expected, packet): 738*2f2c4c7aSAndroid Build Coastguard Worker return packet 739*2f2c4c7aSAndroid Build Coastguard Worker 740*2f2c4c7aSAndroid Build Coastguard Worker # None of the packets matched. Call assertPacketMatches to output a diff 741*2f2c4c7aSAndroid Build Coastguard Worker # between the expected packet and the last packet we received. In theory, 742*2f2c4c7aSAndroid Build Coastguard Worker # we'd output a diff to the packet that's the best match for what we 743*2f2c4c7aSAndroid Build Coastguard Worker # expected, but this is good enough for now. 744*2f2c4c7aSAndroid Build Coastguard Worker try: 745*2f2c4c7aSAndroid Build Coastguard Worker self.assertPacketMatches(expected, packets[-1]) 746*2f2c4c7aSAndroid Build Coastguard Worker except Exception as e: 747*2f2c4c7aSAndroid Build Coastguard Worker raise UnexpectedPacketError( 748*2f2c4c7aSAndroid Build Coastguard Worker "%s: diff with last packet:\n%s" % (msg, str(e))) 749*2f2c4c7aSAndroid Build Coastguard Worker 750*2f2c4c7aSAndroid Build Coastguard Worker def Combinations(self, version): 751*2f2c4c7aSAndroid Build Coastguard Worker """Produces a list of combinations to test.""" 752*2f2c4c7aSAndroid Build Coastguard Worker combinations = [] 753*2f2c4c7aSAndroid Build Coastguard Worker 754*2f2c4c7aSAndroid Build Coastguard Worker # Check packets addressed to the IP addresses of all our interfaces... 755*2f2c4c7aSAndroid Build Coastguard Worker for dest_ip_netid in self.tuns: 756*2f2c4c7aSAndroid Build Coastguard Worker ip_if = self.GetInterfaceName(dest_ip_netid) 757*2f2c4c7aSAndroid Build Coastguard Worker myaddr = self.MyAddress(version, dest_ip_netid) 758*2f2c4c7aSAndroid Build Coastguard Worker prefix = {4: "172.22.", 6: "2001:db8:aaaa::"}[version] 759*2f2c4c7aSAndroid Build Coastguard Worker remoteaddr = self.GetRandomDestination(prefix) 760*2f2c4c7aSAndroid Build Coastguard Worker 761*2f2c4c7aSAndroid Build Coastguard Worker # ... coming in on all our interfaces. 762*2f2c4c7aSAndroid Build Coastguard Worker for netid in self.tuns: 763*2f2c4c7aSAndroid Build Coastguard Worker iif = self.GetInterfaceName(netid) 764*2f2c4c7aSAndroid Build Coastguard Worker combinations.append((netid, iif, ip_if, myaddr, remoteaddr)) 765*2f2c4c7aSAndroid Build Coastguard Worker 766*2f2c4c7aSAndroid Build Coastguard Worker return combinations 767*2f2c4c7aSAndroid Build Coastguard Worker 768*2f2c4c7aSAndroid Build Coastguard Worker def _FormatMessage(self, iif, ip_if, extra, desc, reply_desc): 769*2f2c4c7aSAndroid Build Coastguard Worker msg = "Receiving %s on %s to %s IP, %s" % (desc, iif, ip_if, extra) 770*2f2c4c7aSAndroid Build Coastguard Worker if reply_desc: 771*2f2c4c7aSAndroid Build Coastguard Worker msg += ": Expecting %s on %s" % (reply_desc, iif) 772*2f2c4c7aSAndroid Build Coastguard Worker else: 773*2f2c4c7aSAndroid Build Coastguard Worker msg += ": Expecting no packets on %s" % iif 774*2f2c4c7aSAndroid Build Coastguard Worker return msg 775*2f2c4c7aSAndroid Build Coastguard Worker 776*2f2c4c7aSAndroid Build Coastguard Worker def _ReceiveAndExpectResponse(self, netid, packet, reply, msg): 777*2f2c4c7aSAndroid Build Coastguard Worker self.ReceivePacketOn(netid, packet) 778*2f2c4c7aSAndroid Build Coastguard Worker if reply: 779*2f2c4c7aSAndroid Build Coastguard Worker return self.ExpectPacketOn(netid, msg, reply) 780*2f2c4c7aSAndroid Build Coastguard Worker else: 781*2f2c4c7aSAndroid Build Coastguard Worker self.ExpectNoPacketsOn(netid, msg) 782*2f2c4c7aSAndroid Build Coastguard Worker return None 783*2f2c4c7aSAndroid Build Coastguard Worker 784*2f2c4c7aSAndroid Build Coastguard Worker 785*2f2c4c7aSAndroid Build Coastguard Workerclass InboundMarkingTest(MultiNetworkBaseTest): 786*2f2c4c7aSAndroid Build Coastguard Worker """Class that automatically sets up inbound marking.""" 787*2f2c4c7aSAndroid Build Coastguard Worker 788*2f2c4c7aSAndroid Build Coastguard Worker @classmethod 789*2f2c4c7aSAndroid Build Coastguard Worker def setUpClass(cls): 790*2f2c4c7aSAndroid Build Coastguard Worker super(InboundMarkingTest, cls).setUpClass() 791*2f2c4c7aSAndroid Build Coastguard Worker cls.SetInboundMarks(True) 792*2f2c4c7aSAndroid Build Coastguard Worker 793*2f2c4c7aSAndroid Build Coastguard Worker @classmethod 794*2f2c4c7aSAndroid Build Coastguard Worker def tearDownClass(cls): 795*2f2c4c7aSAndroid Build Coastguard Worker cls.SetInboundMarks(False) 796*2f2c4c7aSAndroid Build Coastguard Worker super(InboundMarkingTest, cls).tearDownClass() 797