1*5b8af90fSJose Luis Duranimport pytest 2*5b8af90fSJose Luis Duran 3*5b8af90fSJose Luis Duranimport logging 4*5b8af90fSJose Luis Duranimport os 5*5b8af90fSJose Luis Duranimport re 6*5b8af90fSJose Luis Duranimport subprocess 7*5b8af90fSJose Luis Duran 8*5b8af90fSJose Luis Duranfrom atf_python.sys.net.vnet import IfaceFactory 9*5b8af90fSJose Luis Duranfrom atf_python.sys.net.vnet import SingleVnetTestTemplate 10*5b8af90fSJose Luis Duranfrom atf_python.sys.net.tools import ToolsHelper 11*5b8af90fSJose Luis Duranfrom typing import List 12*5b8af90fSJose Luis Duranfrom typing import Optional 13*5b8af90fSJose Luis Duran 14*5b8af90fSJose Luis Duranlogging.getLogger("scapy").setLevel(logging.CRITICAL) 15*5b8af90fSJose Luis Duranimport scapy.all as sc 16*5b8af90fSJose Luis Duran 17*5b8af90fSJose Luis Duran 18*5b8af90fSJose Luis Durandef build_response_packet(echo, ip, icmp, oip_ihl, special): 19*5b8af90fSJose Luis Duran icmp_id_seq_types = [0, 8, 13, 14, 15, 16, 17, 18, 37, 38] 20*5b8af90fSJose Luis Duran oip = echo[sc.IP] 21*5b8af90fSJose Luis Duran oicmp = echo[sc.ICMP] 22*5b8af90fSJose Luis Duran load = echo[sc.ICMP].payload 23*5b8af90fSJose Luis Duran oip[sc.IP].remove_payload() 24*5b8af90fSJose Luis Duran oicmp[sc.ICMP].remove_payload() 25*5b8af90fSJose Luis Duran oicmp.type = 8 26*5b8af90fSJose Luis Duran 27*5b8af90fSJose Luis Duran # As if the original IP packet had these set 28*5b8af90fSJose Luis Duran oip.ihl = None 29*5b8af90fSJose Luis Duran oip.len = None 30*5b8af90fSJose Luis Duran oip.id = 1 31*5b8af90fSJose Luis Duran oip.flags = ip.flags 32*5b8af90fSJose Luis Duran oip.chksum = None 33*5b8af90fSJose Luis Duran oip.options = ip.options 34*5b8af90fSJose Luis Duran 35*5b8af90fSJose Luis Duran # Inner packet (oip) options 36*5b8af90fSJose Luis Duran if oip_ihl: 37*5b8af90fSJose Luis Duran oip.ihl = oip_ihl 38*5b8af90fSJose Luis Duran 39*5b8af90fSJose Luis Duran # Special options 40*5b8af90fSJose Luis Duran if special == "no-payload": 41*5b8af90fSJose Luis Duran load = "" 42*5b8af90fSJose Luis Duran if special == "tcp": 43*5b8af90fSJose Luis Duran oip.proto = "tcp" 44*5b8af90fSJose Luis Duran tcp = sc.TCP(sport=1234, dport=5678) 45*5b8af90fSJose Luis Duran return ip / icmp / oip / tcp 46*5b8af90fSJose Luis Duran if special == "udp": 47*5b8af90fSJose Luis Duran oip.proto = "udp" 48*5b8af90fSJose Luis Duran udp = sc.UDP(sport=1234, dport=5678) 49*5b8af90fSJose Luis Duran return ip / icmp / oip / udp 50*5b8af90fSJose Luis Duran if special == "warp": 51*5b8af90fSJose Luis Duran # Build a package with a timestamp of INT_MAX 52*5b8af90fSJose Luis Duran # (time-warped package) 53*5b8af90fSJose Luis Duran payload_no_timestamp = sc.bytes_hex(load)[16:] 54*5b8af90fSJose Luis Duran load = (b"\xff" * 8) + sc.hex_bytes(payload_no_timestamp) 55*5b8af90fSJose Luis Duran if special == "wrong": 56*5b8af90fSJose Luis Duran # Build a package with a wrong last byte 57*5b8af90fSJose Luis Duran payload_no_last_byte = sc.bytes_hex(load)[:-2] 58*5b8af90fSJose Luis Duran load = (sc.hex_bytes(payload_no_last_byte)) + b"\x00" 59*5b8af90fSJose Luis Duran 60*5b8af90fSJose Luis Duran if icmp.type in icmp_id_seq_types: 61*5b8af90fSJose Luis Duran pkt = ip / icmp / load 62*5b8af90fSJose Luis Duran else: 63*5b8af90fSJose Luis Duran ip.options = "" 64*5b8af90fSJose Luis Duran pkt = ip / icmp / oip / oicmp / load 65*5b8af90fSJose Luis Duran return pkt 66*5b8af90fSJose Luis Duran 67*5b8af90fSJose Luis Duran 68*5b8af90fSJose Luis Durandef generate_ip_options(opts): 69*5b8af90fSJose Luis Duran if not opts: 70*5b8af90fSJose Luis Duran return "" 71*5b8af90fSJose Luis Duran 72*5b8af90fSJose Luis Duran routers = [ 73*5b8af90fSJose Luis Duran "192.0.2.10", 74*5b8af90fSJose Luis Duran "192.0.2.20", 75*5b8af90fSJose Luis Duran "192.0.2.30", 76*5b8af90fSJose Luis Duran "192.0.2.40", 77*5b8af90fSJose Luis Duran "192.0.2.50", 78*5b8af90fSJose Luis Duran "192.0.2.60", 79*5b8af90fSJose Luis Duran "192.0.2.70", 80*5b8af90fSJose Luis Duran "192.0.2.80", 81*5b8af90fSJose Luis Duran "192.0.2.90", 82*5b8af90fSJose Luis Duran ] 83*5b8af90fSJose Luis Duran routers_zero = [0, 0, 0, 0, 0, 0, 0, 0, 0] 84*5b8af90fSJose Luis Duran if opts == "EOL": 85*5b8af90fSJose Luis Duran options = sc.IPOption(b"\x00") 86*5b8af90fSJose Luis Duran elif opts == "NOP": 87*5b8af90fSJose Luis Duran options = sc.IPOption(b"\x01") 88*5b8af90fSJose Luis Duran elif opts == "NOP-40": 89*5b8af90fSJose Luis Duran options = sc.IPOption(b"\x01" * 40) 90*5b8af90fSJose Luis Duran elif opts == "RR": 91*5b8af90fSJose Luis Duran ToolsHelper.set_sysctl("net.inet.ip.process_options", 0) 92*5b8af90fSJose Luis Duran options = sc.IPOption_RR(pointer=40, routers=routers) 93*5b8af90fSJose Luis Duran elif opts == "RR-same": 94*5b8af90fSJose Luis Duran ToolsHelper.set_sysctl("net.inet.ip.process_options", 0) 95*5b8af90fSJose Luis Duran options = sc.IPOption_RR(pointer=3, routers=routers_zero) 96*5b8af90fSJose Luis Duran elif opts == "RR-trunc": 97*5b8af90fSJose Luis Duran ToolsHelper.set_sysctl("net.inet.ip.process_options", 0) 98*5b8af90fSJose Luis Duran options = sc.IPOption_RR(length=7, routers=routers_zero) 99*5b8af90fSJose Luis Duran elif opts == "LSRR": 100*5b8af90fSJose Luis Duran ToolsHelper.set_sysctl("net.inet.ip.process_options", 0) 101*5b8af90fSJose Luis Duran options = sc.IPOption_LSRR(routers=routers) 102*5b8af90fSJose Luis Duran elif opts == "LSRR-trunc": 103*5b8af90fSJose Luis Duran ToolsHelper.set_sysctl("net.inet.ip.process_options", 0) 104*5b8af90fSJose Luis Duran options = sc.IPOption_LSRR(length=3, routers=routers_zero) 105*5b8af90fSJose Luis Duran elif opts == "SSRR": 106*5b8af90fSJose Luis Duran ToolsHelper.set_sysctl("net.inet.ip.process_options", 0) 107*5b8af90fSJose Luis Duran options = sc.IPOption_SSRR(routers=routers) 108*5b8af90fSJose Luis Duran elif opts == "SSRR-trunc": 109*5b8af90fSJose Luis Duran ToolsHelper.set_sysctl("net.inet.ip.process_options", 0) 110*5b8af90fSJose Luis Duran options = sc.IPOption_SSRR(length=3, routers=routers_zero) 111*5b8af90fSJose Luis Duran elif opts == "unk": 112*5b8af90fSJose Luis Duran ToolsHelper.set_sysctl("net.inet.ip.process_options", 0) 113*5b8af90fSJose Luis Duran options = sc.IPOption(b"\x9f") 114*5b8af90fSJose Luis Duran elif opts == "unk-40": 115*5b8af90fSJose Luis Duran ToolsHelper.set_sysctl("net.inet.ip.process_options", 0) 116*5b8af90fSJose Luis Duran options = sc.IPOption(b"\x9f" * 40) 117*5b8af90fSJose Luis Duran else: 118*5b8af90fSJose Luis Duran options = "" 119*5b8af90fSJose Luis Duran return options 120*5b8af90fSJose Luis Duran 121*5b8af90fSJose Luis Duran 122*5b8af90fSJose Luis Durandef pinger( 123*5b8af90fSJose Luis Duran # Required arguments 124*5b8af90fSJose Luis Duran # Avoid setting defaults on these arguments, 125*5b8af90fSJose Luis Duran # as we want to set them explicitly in the tests 126*5b8af90fSJose Luis Duran iface: str, 127*5b8af90fSJose Luis Duran /, 128*5b8af90fSJose Luis Duran src: sc.scapy.fields.SourceIPField, 129*5b8af90fSJose Luis Duran dst: sc.scapy.layers.inet.DestIPField, 130*5b8af90fSJose Luis Duran icmp_type: sc.scapy.fields.ByteEnumField, 131*5b8af90fSJose Luis Duran icmp_code: sc.scapy.fields.MultiEnumField, 132*5b8af90fSJose Luis Duran # IP arguments 133*5b8af90fSJose Luis Duran ihl: Optional[sc.scapy.fields.BitField] = None, 134*5b8af90fSJose Luis Duran flags: Optional[sc.scapy.fields.FlagsField] = None, 135*5b8af90fSJose Luis Duran opts: Optional[str] = None, 136*5b8af90fSJose Luis Duran oip_ihl: Optional[sc.scapy.fields.BitField] = None, 137*5b8af90fSJose Luis Duran special: Optional[str] = None, 138*5b8af90fSJose Luis Duran # ICMP arguments 139*5b8af90fSJose Luis Duran # Match names with <netinet/ip_icmp.h> 140*5b8af90fSJose Luis Duran icmp_pptr: sc.scapy.fields.ByteField = 0, 141*5b8af90fSJose Luis Duran icmp_gwaddr: sc.scapy.fields.IPField = "0.0.0.0", 142*5b8af90fSJose Luis Duran icmp_nextmtu: sc.scapy.fields.ShortField = 0, 143*5b8af90fSJose Luis Duran icmp_otime: sc.scapy.layers.inet.ICMPTimeStampField = 0, 144*5b8af90fSJose Luis Duran icmp_rtime: sc.scapy.layers.inet.ICMPTimeStampField = 0, 145*5b8af90fSJose Luis Duran icmp_ttime: sc.scapy.layers.inet.ICMPTimeStampField = 0, 146*5b8af90fSJose Luis Duran icmp_mask: sc.scapy.fields.IPField = "0.0.0.0", 147*5b8af90fSJose Luis Duran request: Optional[str] = None, 148*5b8af90fSJose Luis Duran # Miscellaneous arguments 149*5b8af90fSJose Luis Duran count: int = 1, 150*5b8af90fSJose Luis Duran dup: bool = False, 151*5b8af90fSJose Luis Duran) -> subprocess.CompletedProcess: 152*5b8af90fSJose Luis Duran """P I N G E R 153*5b8af90fSJose Luis Duran 154*5b8af90fSJose Luis Duran Echo reply faker 155*5b8af90fSJose Luis Duran 156*5b8af90fSJose Luis Duran :param str iface: Interface to send packet to 157*5b8af90fSJose Luis Duran :keyword src: Source packet IP 158*5b8af90fSJose Luis Duran :type src: class:`scapy.fields.SourceIPField` 159*5b8af90fSJose Luis Duran :keyword dst: Destination packet IP 160*5b8af90fSJose Luis Duran :type dst: class:`scapy.layers.inet.DestIPField` 161*5b8af90fSJose Luis Duran :keyword icmp_type: ICMP type 162*5b8af90fSJose Luis Duran :type icmp_type: class:`scapy.fields.ByteEnumField` 163*5b8af90fSJose Luis Duran :keyword icmp_code: ICMP code 164*5b8af90fSJose Luis Duran :type icmp_code: class:`scapy.fields.MultiEnumField` 165*5b8af90fSJose Luis Duran 166*5b8af90fSJose Luis Duran :keyword ihl: Internet Header Length, defaults to None 167*5b8af90fSJose Luis Duran :type ihl: class:`scapy.fields.BitField`, optional 168*5b8af90fSJose Luis Duran :keyword flags: IP flags - one of `DF`, `MF` or `evil`, defaults to None 169*5b8af90fSJose Luis Duran :type flags: class:`scapy.fields.FlagsField`, optional 170*5b8af90fSJose Luis Duran :keyword opts: Include IP options - one of `EOL`, `NOP`, `NOP-40`, `unk`, 171*5b8af90fSJose Luis Duran `unk-40`, `RR`, `RR-same`, `RR-trunc`, `LSRR`, `LSRR-trunc`, `SSRR` or 172*5b8af90fSJose Luis Duran `SSRR-trunc`, defaults to None 173*5b8af90fSJose Luis Duran :type opts: str, optional 174*5b8af90fSJose Luis Duran :keyword oip_ihl: Inner packet's Internet Header Length, defaults to None 175*5b8af90fSJose Luis Duran :type oip_ihl: class:`scapy.fields.BitField`, optional 176*5b8af90fSJose Luis Duran :keyword special: Send a special packet - one of `no-payload`, `tcp`, 177*5b8af90fSJose Luis Duran `udp`, `wrong` or `warp`, defaults to None 178*5b8af90fSJose Luis Duran :type special: str, optional 179*5b8af90fSJose Luis Duran :keyword icmp_pptr: ICMP pointer, defaults to 0 180*5b8af90fSJose Luis Duran :type icmp_pptr: class:`scapy.fields.ByteField` 181*5b8af90fSJose Luis Duran :keyword icmp_gwaddr: ICMP gateway IP address, defaults to "0.0.0.0" 182*5b8af90fSJose Luis Duran :type icmp_gwaddr: class:`scapy.fields.IPField` 183*5b8af90fSJose Luis Duran :keyword icmp_nextmtu: ICMP next MTU, defaults to 0 184*5b8af90fSJose Luis Duran :type icmp_nextmtu: class:`scapy.fields.ShortField` 185*5b8af90fSJose Luis Duran :keyword icmp_otime: ICMP originate timestamp, defaults to 0 186*5b8af90fSJose Luis Duran :type icmp_otime: class:`scapy.layers.inet.ICMPTimeStampField` 187*5b8af90fSJose Luis Duran :keyword icmp_rtime: ICMP receive timestamp, defaults to 0 188*5b8af90fSJose Luis Duran :type icmp_rtime: class:`scapy.layers.inet.ICMPTimeStampField` 189*5b8af90fSJose Luis Duran :keyword icmp_ttime: ICMP transmit timestamp, defaults to 0 190*5b8af90fSJose Luis Duran :type icmp_ttime: class:`scapy.layers.inet.ICMPTimeStampField` 191*5b8af90fSJose Luis Duran :keyword icmp_mask: ICMP address mask, defaults to "0.0.0.0" 192*5b8af90fSJose Luis Duran :type icmp_mask: class:`scapy.fields.IPField` 193*5b8af90fSJose Luis Duran :keyword request: Request type - one of `mask` or `timestamp`, 194*5b8af90fSJose Luis Duran defaults to None 195*5b8af90fSJose Luis Duran :type request: str, optional 196*5b8af90fSJose Luis Duran :keyword count: Number of packets to send, defaults to 1 197*5b8af90fSJose Luis Duran :type count: int 198*5b8af90fSJose Luis Duran :keyword dup: Duplicate packets, defaults to `False` 199*5b8af90fSJose Luis Duran :type dup: bool 200*5b8af90fSJose Luis Duran 201*5b8af90fSJose Luis Duran :return: A class:`subprocess.CompletedProcess` with the output from the 202*5b8af90fSJose Luis Duran ping utility 203*5b8af90fSJose Luis Duran :rtype: class:`subprocess.CompletedProcess` 204*5b8af90fSJose Luis Duran """ 205*5b8af90fSJose Luis Duran tun = sc.TunTapInterface(iface) 206*5b8af90fSJose Luis Duran subprocess.run(["ifconfig", tun.iface, "up"], check=True) 207*5b8af90fSJose Luis Duran subprocess.run(["ifconfig", tun.iface, src, dst], check=True) 208*5b8af90fSJose Luis Duran ip_opts = generate_ip_options(opts) 209*5b8af90fSJose Luis Duran ip = sc.IP(ihl=ihl, flags=flags, src=dst, dst=src, options=ip_opts) 210*5b8af90fSJose Luis Duran command = [ 211*5b8af90fSJose Luis Duran "/sbin/ping", 212*5b8af90fSJose Luis Duran "-c", 213*5b8af90fSJose Luis Duran str(count), 214*5b8af90fSJose Luis Duran "-t", 215*5b8af90fSJose Luis Duran str(count), 216*5b8af90fSJose Luis Duran "-v", 217*5b8af90fSJose Luis Duran ] 218*5b8af90fSJose Luis Duran if request == "mask": 219*5b8af90fSJose Luis Duran command += ["-Mm"] 220*5b8af90fSJose Luis Duran if request == "timestamp": 221*5b8af90fSJose Luis Duran command += ["-Mt"] 222*5b8af90fSJose Luis Duran if special: 223*5b8af90fSJose Luis Duran command += ["-p1"] 224*5b8af90fSJose Luis Duran if opts in [ 225*5b8af90fSJose Luis Duran "RR", 226*5b8af90fSJose Luis Duran "RR-same", 227*5b8af90fSJose Luis Duran "RR-trunc", 228*5b8af90fSJose Luis Duran "LSRR", 229*5b8af90fSJose Luis Duran "LSRR-trunc", 230*5b8af90fSJose Luis Duran "SSRR", 231*5b8af90fSJose Luis Duran "SSRR-trunc", 232*5b8af90fSJose Luis Duran ]: 233*5b8af90fSJose Luis Duran command += ["-R"] 234*5b8af90fSJose Luis Duran command += [dst] 235*5b8af90fSJose Luis Duran with subprocess.Popen( 236*5b8af90fSJose Luis Duran args=command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True 237*5b8af90fSJose Luis Duran ) as ping: 238*5b8af90fSJose Luis Duran for dummy in range(count): 239*5b8af90fSJose Luis Duran echo = tun.recv() 240*5b8af90fSJose Luis Duran icmp = sc.ICMP( 241*5b8af90fSJose Luis Duran type=icmp_type, 242*5b8af90fSJose Luis Duran code=icmp_code, 243*5b8af90fSJose Luis Duran id=echo[sc.ICMP].id, 244*5b8af90fSJose Luis Duran seq=echo[sc.ICMP].seq, 245*5b8af90fSJose Luis Duran ts_ori=icmp_otime, 246*5b8af90fSJose Luis Duran ts_rx=icmp_rtime, 247*5b8af90fSJose Luis Duran ts_tx=icmp_ttime, 248*5b8af90fSJose Luis Duran gw=icmp_gwaddr, 249*5b8af90fSJose Luis Duran ptr=icmp_pptr, 250*5b8af90fSJose Luis Duran addr_mask=icmp_mask, 251*5b8af90fSJose Luis Duran nexthopmtu=icmp_nextmtu, 252*5b8af90fSJose Luis Duran ) 253*5b8af90fSJose Luis Duran pkt = build_response_packet(echo, ip, icmp, oip_ihl, special) 254*5b8af90fSJose Luis Duran tun.send(pkt) 255*5b8af90fSJose Luis Duran if dup is True: 256*5b8af90fSJose Luis Duran tun.send(pkt) 257*5b8af90fSJose Luis Duran stdout, stderr = ping.communicate() 258*5b8af90fSJose Luis Duran return subprocess.CompletedProcess( 259*5b8af90fSJose Luis Duran ping.args, ping.returncode, stdout, stderr 260*5b8af90fSJose Luis Duran ) 261*5b8af90fSJose Luis Duran 262*5b8af90fSJose Luis Duran 263*5b8af90fSJose Luis Durandef redact(output): 264*5b8af90fSJose Luis Duran """Redact some elements of ping's output""" 265*5b8af90fSJose Luis Duran pattern_replacements = [ 266*5b8af90fSJose Luis Duran ("localhost \([0-9]{1,3}(\.[0-9]{1,3}){3}\)", "localhost"), 267*5b8af90fSJose Luis Duran ("from [0-9]{1,3}(\.[0-9]{1,3}){3}", "from"), 268*5b8af90fSJose Luis Duran ("hlim=[0-9]*", "hlim="), 269*5b8af90fSJose Luis Duran ("ttl=[0-9]*", "ttl="), 270*5b8af90fSJose Luis Duran ("time=[0-9.-]*", "time="), 271*5b8af90fSJose Luis Duran ("[0-9\.]+/[0-9.]+", "/"), 272*5b8af90fSJose Luis Duran ] 273*5b8af90fSJose Luis Duran for pattern, repl in pattern_replacements: 274*5b8af90fSJose Luis Duran output = re.sub(pattern, repl, output) 275*5b8af90fSJose Luis Duran return output 276*5b8af90fSJose Luis Duran 277*5b8af90fSJose Luis Duran 278*5b8af90fSJose Luis Duranclass TestPing(SingleVnetTestTemplate): 279*5b8af90fSJose Luis Duran IPV6_PREFIXES: List[str] = ["2001:db8::1/64"] 280*5b8af90fSJose Luis Duran IPV4_PREFIXES: List[str] = ["192.0.2.1/24"] 281*5b8af90fSJose Luis Duran 282*5b8af90fSJose Luis Duran # Each param in testdata contains a dictionary with the command, 283*5b8af90fSJose Luis Duran # and the expected outcome (returncode, redacted stdout, and stderr) 284*5b8af90fSJose Luis Duran testdata = [ 285*5b8af90fSJose Luis Duran pytest.param( 286*5b8af90fSJose Luis Duran { 287*5b8af90fSJose Luis Duran "args": "ping -4 -c1 -s56 -t1 localhost", 288*5b8af90fSJose Luis Duran "returncode": 0, 289*5b8af90fSJose Luis Duran "stdout": """\ 290*5b8af90fSJose Luis DuranPING localhost: 56 data bytes 291*5b8af90fSJose Luis Duran64 bytes from: icmp_seq=0 ttl= time= ms 292*5b8af90fSJose Luis Duran 293*5b8af90fSJose Luis Duran--- localhost ping statistics --- 294*5b8af90fSJose Luis Duran1 packets transmitted, 1 packets received, 0.0% packet loss 295*5b8af90fSJose Luis Duranround-trip min/avg/max/stddev = /// ms 296*5b8af90fSJose Luis Duran""", 297*5b8af90fSJose Luis Duran "stderr": "", 298*5b8af90fSJose Luis Duran }, 299*5b8af90fSJose Luis Duran id="_4_c1_s56_t1_localhost", 300*5b8af90fSJose Luis Duran ), 301*5b8af90fSJose Luis Duran pytest.param( 302*5b8af90fSJose Luis Duran { 303*5b8af90fSJose Luis Duran "args": "ping -6 -c1 -s8 -t1 localhost", 304*5b8af90fSJose Luis Duran "returncode": 0, 305*5b8af90fSJose Luis Duran "stdout": """\ 306*5b8af90fSJose Luis DuranPING6(56=40+8+8 bytes) ::1 --> ::1 307*5b8af90fSJose Luis Duran16 bytes from ::1, icmp_seq=0 hlim= time= ms 308*5b8af90fSJose Luis Duran 309*5b8af90fSJose Luis Duran--- localhost ping6 statistics --- 310*5b8af90fSJose Luis Duran1 packets transmitted, 1 packets received, 0.0% packet loss 311*5b8af90fSJose Luis Duranround-trip min/avg/max/std-dev = /// ms 312*5b8af90fSJose Luis Duran""", 313*5b8af90fSJose Luis Duran "stderr": "", 314*5b8af90fSJose Luis Duran }, 315*5b8af90fSJose Luis Duran id="_6_c1_s8_t1_localhost", 316*5b8af90fSJose Luis Duran ), 317*5b8af90fSJose Luis Duran pytest.param( 318*5b8af90fSJose Luis Duran { 319*5b8af90fSJose Luis Duran "args": "ping -A -c1 192.0.2.1", 320*5b8af90fSJose Luis Duran "returncode": 0, 321*5b8af90fSJose Luis Duran "stdout": """\ 322*5b8af90fSJose Luis DuranPING 192.0.2.1 (192.0.2.1): 56 data bytes 323*5b8af90fSJose Luis Duran64 bytes from: icmp_seq=0 ttl= time= ms 324*5b8af90fSJose Luis Duran 325*5b8af90fSJose Luis Duran--- 192.0.2.1 ping statistics --- 326*5b8af90fSJose Luis Duran1 packets transmitted, 1 packets received, 0.0% packet loss 327*5b8af90fSJose Luis Duranround-trip min/avg/max/stddev = /// ms 328*5b8af90fSJose Luis Duran""", 329*5b8af90fSJose Luis Duran "stderr": "", 330*5b8af90fSJose Luis Duran }, 331*5b8af90fSJose Luis Duran id="_A_c1_192_0_2_1", 332*5b8af90fSJose Luis Duran ), 333*5b8af90fSJose Luis Duran pytest.param( 334*5b8af90fSJose Luis Duran { 335*5b8af90fSJose Luis Duran "args": "ping -A -c1 192.0.2.2", 336*5b8af90fSJose Luis Duran "returncode": 2, 337*5b8af90fSJose Luis Duran "stdout": """\ 338*5b8af90fSJose Luis DuranPING 192.0.2.2 (192.0.2.2): 56 data bytes 339*5b8af90fSJose Luis Duran 340*5b8af90fSJose Luis Duran--- 192.0.2.2 ping statistics --- 341*5b8af90fSJose Luis Duran1 packets transmitted, 0 packets received, 100.0% packet loss 342*5b8af90fSJose Luis Duran""", 343*5b8af90fSJose Luis Duran "stderr": "", 344*5b8af90fSJose Luis Duran }, 345*5b8af90fSJose Luis Duran id="_A_c1_192_0_2_2", 346*5b8af90fSJose Luis Duran ), 347*5b8af90fSJose Luis Duran pytest.param( 348*5b8af90fSJose Luis Duran { 349*5b8af90fSJose Luis Duran "args": "ping -A -c1 2001:db8::1", 350*5b8af90fSJose Luis Duran "returncode": 0, 351*5b8af90fSJose Luis Duran "stdout": """\ 352*5b8af90fSJose Luis DuranPING6(56=40+8+8 bytes) 2001:db8::1 --> 2001:db8::1 353*5b8af90fSJose Luis Duran16 bytes from 2001:db8::1, icmp_seq=0 hlim= time= ms 354*5b8af90fSJose Luis Duran 355*5b8af90fSJose Luis Duran--- 2001:db8::1 ping6 statistics --- 356*5b8af90fSJose Luis Duran1 packets transmitted, 1 packets received, 0.0% packet loss 357*5b8af90fSJose Luis Duranround-trip min/avg/max/std-dev = /// ms 358*5b8af90fSJose Luis Duran""", 359*5b8af90fSJose Luis Duran "stderr": "", 360*5b8af90fSJose Luis Duran }, 361*5b8af90fSJose Luis Duran id="_A_c1_2001_db8__1", 362*5b8af90fSJose Luis Duran ), 363*5b8af90fSJose Luis Duran pytest.param( 364*5b8af90fSJose Luis Duran { 365*5b8af90fSJose Luis Duran "args": "ping -A -c1 2001:db8::2", 366*5b8af90fSJose Luis Duran "returncode": 2, 367*5b8af90fSJose Luis Duran "stdout": """\ 368*5b8af90fSJose Luis DuranPING6(56=40+8+8 bytes) 2001:db8::1 --> 2001:db8::2 369*5b8af90fSJose Luis Duran 370*5b8af90fSJose Luis Duran--- 2001:db8::2 ping6 statistics --- 371*5b8af90fSJose Luis Duran1 packets transmitted, 0 packets received, 100.0% packet loss 372*5b8af90fSJose Luis Duran""", 373*5b8af90fSJose Luis Duran "stderr": "", 374*5b8af90fSJose Luis Duran }, 375*5b8af90fSJose Luis Duran id="_A_c1_2001_db8__2", 376*5b8af90fSJose Luis Duran ), 377*5b8af90fSJose Luis Duran pytest.param( 378*5b8af90fSJose Luis Duran { 379*5b8af90fSJose Luis Duran "args": "ping -A -c3 192.0.2.1", 380*5b8af90fSJose Luis Duran "returncode": 0, 381*5b8af90fSJose Luis Duran "stdout": """\ 382*5b8af90fSJose Luis DuranPING 192.0.2.1 (192.0.2.1): 56 data bytes 383*5b8af90fSJose Luis Duran64 bytes from: icmp_seq=0 ttl= time= ms 384*5b8af90fSJose Luis Duran64 bytes from: icmp_seq=1 ttl= time= ms 385*5b8af90fSJose Luis Duran64 bytes from: icmp_seq=2 ttl= time= ms 386*5b8af90fSJose Luis Duran 387*5b8af90fSJose Luis Duran--- 192.0.2.1 ping statistics --- 388*5b8af90fSJose Luis Duran3 packets transmitted, 3 packets received, 0.0% packet loss 389*5b8af90fSJose Luis Duranround-trip min/avg/max/stddev = /// ms 390*5b8af90fSJose Luis Duran""", 391*5b8af90fSJose Luis Duran "stderr": "", 392*5b8af90fSJose Luis Duran }, 393*5b8af90fSJose Luis Duran id="_A_3_192_0.2.1", 394*5b8af90fSJose Luis Duran ), 395*5b8af90fSJose Luis Duran pytest.param( 396*5b8af90fSJose Luis Duran { 397*5b8af90fSJose Luis Duran "args": "ping -A -c3 192.0.2.2", 398*5b8af90fSJose Luis Duran "returncode": 2, 399*5b8af90fSJose Luis Duran "stdout": """\ 400*5b8af90fSJose Luis Duran\x07\x07PING 192.0.2.2 (192.0.2.2): 56 data bytes 401*5b8af90fSJose Luis Duran 402*5b8af90fSJose Luis Duran--- 192.0.2.2 ping statistics --- 403*5b8af90fSJose Luis Duran3 packets transmitted, 0 packets received, 100.0% packet loss 404*5b8af90fSJose Luis Duran""", 405*5b8af90fSJose Luis Duran "stderr": "", 406*5b8af90fSJose Luis Duran }, 407*5b8af90fSJose Luis Duran id="_A_c3_192_0_2_2", 408*5b8af90fSJose Luis Duran ), 409*5b8af90fSJose Luis Duran pytest.param( 410*5b8af90fSJose Luis Duran { 411*5b8af90fSJose Luis Duran "args": "ping -A -c3 2001:db8::1", 412*5b8af90fSJose Luis Duran "returncode": 0, 413*5b8af90fSJose Luis Duran "stdout": """\ 414*5b8af90fSJose Luis DuranPING6(56=40+8+8 bytes) 2001:db8::1 --> 2001:db8::1 415*5b8af90fSJose Luis Duran16 bytes from 2001:db8::1, icmp_seq=0 hlim= time= ms 416*5b8af90fSJose Luis Duran16 bytes from 2001:db8::1, icmp_seq=1 hlim= time= ms 417*5b8af90fSJose Luis Duran16 bytes from 2001:db8::1, icmp_seq=2 hlim= time= ms 418*5b8af90fSJose Luis Duran 419*5b8af90fSJose Luis Duran--- 2001:db8::1 ping6 statistics --- 420*5b8af90fSJose Luis Duran3 packets transmitted, 3 packets received, 0.0% packet loss 421*5b8af90fSJose Luis Duranround-trip min/avg/max/std-dev = /// ms 422*5b8af90fSJose Luis Duran""", 423*5b8af90fSJose Luis Duran "stderr": "", 424*5b8af90fSJose Luis Duran }, 425*5b8af90fSJose Luis Duran id="_A_c3_2001_db8__1", 426*5b8af90fSJose Luis Duran ), 427*5b8af90fSJose Luis Duran pytest.param( 428*5b8af90fSJose Luis Duran { 429*5b8af90fSJose Luis Duran "args": "ping -A -c3 2001:db8::2", 430*5b8af90fSJose Luis Duran "returncode": 2, 431*5b8af90fSJose Luis Duran "stdout": """\ 432*5b8af90fSJose Luis Duran\x07\x07PING6(56=40+8+8 bytes) 2001:db8::1 --> 2001:db8::2 433*5b8af90fSJose Luis Duran 434*5b8af90fSJose Luis Duran--- 2001:db8::2 ping6 statistics --- 435*5b8af90fSJose Luis Duran3 packets transmitted, 0 packets received, 100.0% packet loss 436*5b8af90fSJose Luis Duran""", 437*5b8af90fSJose Luis Duran "stderr": "", 438*5b8af90fSJose Luis Duran }, 439*5b8af90fSJose Luis Duran id="_A_c3_2001_db8__2", 440*5b8af90fSJose Luis Duran ), 441*5b8af90fSJose Luis Duran pytest.param( 442*5b8af90fSJose Luis Duran { 443*5b8af90fSJose Luis Duran "args": "ping -c1 192.0.2.1", 444*5b8af90fSJose Luis Duran "returncode": 0, 445*5b8af90fSJose Luis Duran "stdout": """\ 446*5b8af90fSJose Luis DuranPING 192.0.2.1 (192.0.2.1): 56 data bytes 447*5b8af90fSJose Luis Duran64 bytes from: icmp_seq=0 ttl= time= ms 448*5b8af90fSJose Luis Duran 449*5b8af90fSJose Luis Duran--- 192.0.2.1 ping statistics --- 450*5b8af90fSJose Luis Duran1 packets transmitted, 1 packets received, 0.0% packet loss 451*5b8af90fSJose Luis Duranround-trip min/avg/max/stddev = /// ms 452*5b8af90fSJose Luis Duran""", 453*5b8af90fSJose Luis Duran "stderr": "", 454*5b8af90fSJose Luis Duran }, 455*5b8af90fSJose Luis Duran id="_c1_192_0_2_1", 456*5b8af90fSJose Luis Duran ), 457*5b8af90fSJose Luis Duran pytest.param( 458*5b8af90fSJose Luis Duran { 459*5b8af90fSJose Luis Duran "args": "ping -c1 192.0.2.2", 460*5b8af90fSJose Luis Duran "returncode": 2, 461*5b8af90fSJose Luis Duran "stdout": """\ 462*5b8af90fSJose Luis DuranPING 192.0.2.2 (192.0.2.2): 56 data bytes 463*5b8af90fSJose Luis Duran 464*5b8af90fSJose Luis Duran--- 192.0.2.2 ping statistics --- 465*5b8af90fSJose Luis Duran1 packets transmitted, 0 packets received, 100.0% packet loss 466*5b8af90fSJose Luis Duran""", 467*5b8af90fSJose Luis Duran "stderr": "", 468*5b8af90fSJose Luis Duran }, 469*5b8af90fSJose Luis Duran id="_c1_192_0_2_2", 470*5b8af90fSJose Luis Duran ), 471*5b8af90fSJose Luis Duran pytest.param( 472*5b8af90fSJose Luis Duran { 473*5b8af90fSJose Luis Duran "args": "ping -c1 2001:db8::1", 474*5b8af90fSJose Luis Duran "returncode": 0, 475*5b8af90fSJose Luis Duran "stdout": """\ 476*5b8af90fSJose Luis DuranPING6(56=40+8+8 bytes) 2001:db8::1 --> 2001:db8::1 477*5b8af90fSJose Luis Duran16 bytes from 2001:db8::1, icmp_seq=0 hlim= time= ms 478*5b8af90fSJose Luis Duran 479*5b8af90fSJose Luis Duran--- 2001:db8::1 ping6 statistics --- 480*5b8af90fSJose Luis Duran1 packets transmitted, 1 packets received, 0.0% packet loss 481*5b8af90fSJose Luis Duranround-trip min/avg/max/std-dev = /// ms 482*5b8af90fSJose Luis Duran""", 483*5b8af90fSJose Luis Duran "stderr": "", 484*5b8af90fSJose Luis Duran }, 485*5b8af90fSJose Luis Duran id="_c1_2001_db8__1", 486*5b8af90fSJose Luis Duran ), 487*5b8af90fSJose Luis Duran pytest.param( 488*5b8af90fSJose Luis Duran { 489*5b8af90fSJose Luis Duran "args": "ping -c1 2001:db8::2", 490*5b8af90fSJose Luis Duran "returncode": 2, 491*5b8af90fSJose Luis Duran "stdout": """\ 492*5b8af90fSJose Luis DuranPING6(56=40+8+8 bytes) 2001:db8::1 --> 2001:db8::2 493*5b8af90fSJose Luis Duran 494*5b8af90fSJose Luis Duran--- 2001:db8::2 ping6 statistics --- 495*5b8af90fSJose Luis Duran1 packets transmitted, 0 packets received, 100.0% packet loss 496*5b8af90fSJose Luis Duran""", 497*5b8af90fSJose Luis Duran "stderr": "", 498*5b8af90fSJose Luis Duran }, 499*5b8af90fSJose Luis Duran id="_c1_2001_db8__2", 500*5b8af90fSJose Luis Duran ), 501*5b8af90fSJose Luis Duran pytest.param( 502*5b8af90fSJose Luis Duran { 503*5b8af90fSJose Luis Duran "args": "ping -c1 -S127.0.0.1 -s56 -t1 localhost", 504*5b8af90fSJose Luis Duran "returncode": 0, 505*5b8af90fSJose Luis Duran "stdout": """\ 506*5b8af90fSJose Luis DuranPING localhost from: 56 data bytes 507*5b8af90fSJose Luis Duran64 bytes from: icmp_seq=0 ttl= time= ms 508*5b8af90fSJose Luis Duran 509*5b8af90fSJose Luis Duran--- localhost ping statistics --- 510*5b8af90fSJose Luis Duran1 packets transmitted, 1 packets received, 0.0% packet loss 511*5b8af90fSJose Luis Duranround-trip min/avg/max/stddev = /// ms 512*5b8af90fSJose Luis Duran""", 513*5b8af90fSJose Luis Duran "stderr": "", 514*5b8af90fSJose Luis Duran }, 515*5b8af90fSJose Luis Duran id="_c1_S127_0_0_1_s56_t1_localhost", 516*5b8af90fSJose Luis Duran ), 517*5b8af90fSJose Luis Duran pytest.param( 518*5b8af90fSJose Luis Duran { 519*5b8af90fSJose Luis Duran "args": "ping -c1 -S::1 -s8 -t1 localhost", 520*5b8af90fSJose Luis Duran "returncode": 0, 521*5b8af90fSJose Luis Duran "stdout": """\ 522*5b8af90fSJose Luis DuranPING6(56=40+8+8 bytes) ::1 --> ::1 523*5b8af90fSJose Luis Duran16 bytes from ::1, icmp_seq=0 hlim= time= ms 524*5b8af90fSJose Luis Duran 525*5b8af90fSJose Luis Duran--- localhost ping6 statistics --- 526*5b8af90fSJose Luis Duran1 packets transmitted, 1 packets received, 0.0% packet loss 527*5b8af90fSJose Luis Duranround-trip min/avg/max/std-dev = /// ms 528*5b8af90fSJose Luis Duran""", 529*5b8af90fSJose Luis Duran "stderr": "", 530*5b8af90fSJose Luis Duran }, 531*5b8af90fSJose Luis Duran id="_c1_S__1_s8_t1_localhost", 532*5b8af90fSJose Luis Duran ), 533*5b8af90fSJose Luis Duran pytest.param( 534*5b8af90fSJose Luis Duran { 535*5b8af90fSJose Luis Duran "args": "ping -c3 192.0.2.1", 536*5b8af90fSJose Luis Duran "returncode": 0, 537*5b8af90fSJose Luis Duran "stdout": """\ 538*5b8af90fSJose Luis DuranPING 192.0.2.1 (192.0.2.1): 56 data bytes 539*5b8af90fSJose Luis Duran64 bytes from: icmp_seq=0 ttl= time= ms 540*5b8af90fSJose Luis Duran64 bytes from: icmp_seq=1 ttl= time= ms 541*5b8af90fSJose Luis Duran64 bytes from: icmp_seq=2 ttl= time= ms 542*5b8af90fSJose Luis Duran 543*5b8af90fSJose Luis Duran--- 192.0.2.1 ping statistics --- 544*5b8af90fSJose Luis Duran3 packets transmitted, 3 packets received, 0.0% packet loss 545*5b8af90fSJose Luis Duranround-trip min/avg/max/stddev = /// ms 546*5b8af90fSJose Luis Duran""", 547*5b8af90fSJose Luis Duran "stderr": "", 548*5b8af90fSJose Luis Duran }, 549*5b8af90fSJose Luis Duran id="_c3_192_0_2_1", 550*5b8af90fSJose Luis Duran ), 551*5b8af90fSJose Luis Duran pytest.param( 552*5b8af90fSJose Luis Duran { 553*5b8af90fSJose Luis Duran "args": "ping -c3 192.0.2.2", 554*5b8af90fSJose Luis Duran "returncode": 2, 555*5b8af90fSJose Luis Duran "stdout": """\ 556*5b8af90fSJose Luis DuranPING 192.0.2.2 (192.0.2.2): 56 data bytes 557*5b8af90fSJose Luis Duran 558*5b8af90fSJose Luis Duran--- 192.0.2.2 ping statistics --- 559*5b8af90fSJose Luis Duran3 packets transmitted, 0 packets received, 100.0% packet loss 560*5b8af90fSJose Luis Duran""", 561*5b8af90fSJose Luis Duran "stderr": "", 562*5b8af90fSJose Luis Duran }, 563*5b8af90fSJose Luis Duran id="_c3_192_0_2_2", 564*5b8af90fSJose Luis Duran ), 565*5b8af90fSJose Luis Duran pytest.param( 566*5b8af90fSJose Luis Duran { 567*5b8af90fSJose Luis Duran "args": "ping -c3 2001:db8::1", 568*5b8af90fSJose Luis Duran "returncode": 0, 569*5b8af90fSJose Luis Duran "stdout": """\ 570*5b8af90fSJose Luis DuranPING6(56=40+8+8 bytes) 2001:db8::1 --> 2001:db8::1 571*5b8af90fSJose Luis Duran16 bytes from 2001:db8::1, icmp_seq=0 hlim= time= ms 572*5b8af90fSJose Luis Duran16 bytes from 2001:db8::1, icmp_seq=1 hlim= time= ms 573*5b8af90fSJose Luis Duran16 bytes from 2001:db8::1, icmp_seq=2 hlim= time= ms 574*5b8af90fSJose Luis Duran 575*5b8af90fSJose Luis Duran--- 2001:db8::1 ping6 statistics --- 576*5b8af90fSJose Luis Duran3 packets transmitted, 3 packets received, 0.0% packet loss 577*5b8af90fSJose Luis Duranround-trip min/avg/max/std-dev = /// ms 578*5b8af90fSJose Luis Duran""", 579*5b8af90fSJose Luis Duran "stderr": "", 580*5b8af90fSJose Luis Duran }, 581*5b8af90fSJose Luis Duran id="_c3_2001_db8__1", 582*5b8af90fSJose Luis Duran ), 583*5b8af90fSJose Luis Duran pytest.param( 584*5b8af90fSJose Luis Duran { 585*5b8af90fSJose Luis Duran "args": "ping -c3 2001:db8::2", 586*5b8af90fSJose Luis Duran "returncode": 2, 587*5b8af90fSJose Luis Duran "stdout": """\ 588*5b8af90fSJose Luis DuranPING6(56=40+8+8 bytes) 2001:db8::1 --> 2001:db8::2 589*5b8af90fSJose Luis Duran 590*5b8af90fSJose Luis Duran--- 2001:db8::2 ping6 statistics --- 591*5b8af90fSJose Luis Duran3 packets transmitted, 0 packets received, 100.0% packet loss 592*5b8af90fSJose Luis Duran""", 593*5b8af90fSJose Luis Duran "stderr": "", 594*5b8af90fSJose Luis Duran }, 595*5b8af90fSJose Luis Duran id="_c3_2001_db8__2", 596*5b8af90fSJose Luis Duran ), 597*5b8af90fSJose Luis Duran pytest.param( 598*5b8af90fSJose Luis Duran { 599*5b8af90fSJose Luis Duran "args": "ping -q -c1 192.0.2.1", 600*5b8af90fSJose Luis Duran "returncode": 0, 601*5b8af90fSJose Luis Duran "stdout": """\ 602*5b8af90fSJose Luis DuranPING 192.0.2.1 (192.0.2.1): 56 data bytes 603*5b8af90fSJose Luis Duran 604*5b8af90fSJose Luis Duran--- 192.0.2.1 ping statistics --- 605*5b8af90fSJose Luis Duran1 packets transmitted, 1 packets received, 0.0% packet loss 606*5b8af90fSJose Luis Duranround-trip min/avg/max/stddev = /// ms 607*5b8af90fSJose Luis Duran""", 608*5b8af90fSJose Luis Duran "stderr": "", 609*5b8af90fSJose Luis Duran }, 610*5b8af90fSJose Luis Duran id="_q_c1_192_0_2_1", 611*5b8af90fSJose Luis Duran ), 612*5b8af90fSJose Luis Duran pytest.param( 613*5b8af90fSJose Luis Duran { 614*5b8af90fSJose Luis Duran "args": "ping -q -c1 192.0.2.2", 615*5b8af90fSJose Luis Duran "returncode": 2, 616*5b8af90fSJose Luis Duran "stdout": """\ 617*5b8af90fSJose Luis DuranPING 192.0.2.2 (192.0.2.2): 56 data bytes 618*5b8af90fSJose Luis Duran 619*5b8af90fSJose Luis Duran--- 192.0.2.2 ping statistics --- 620*5b8af90fSJose Luis Duran1 packets transmitted, 0 packets received, 100.0% packet loss 621*5b8af90fSJose Luis Duran""", 622*5b8af90fSJose Luis Duran "stderr": "", 623*5b8af90fSJose Luis Duran }, 624*5b8af90fSJose Luis Duran id="_q_c1_192_0_2_2", 625*5b8af90fSJose Luis Duran ), 626*5b8af90fSJose Luis Duran pytest.param( 627*5b8af90fSJose Luis Duran { 628*5b8af90fSJose Luis Duran "args": "ping -q -c1 2001:db8::1", 629*5b8af90fSJose Luis Duran "returncode": 0, 630*5b8af90fSJose Luis Duran "stdout": """\ 631*5b8af90fSJose Luis DuranPING6(56=40+8+8 bytes) 2001:db8::1 --> 2001:db8::1 632*5b8af90fSJose Luis Duran 633*5b8af90fSJose Luis Duran--- 2001:db8::1 ping6 statistics --- 634*5b8af90fSJose Luis Duran1 packets transmitted, 1 packets received, 0.0% packet loss 635*5b8af90fSJose Luis Duranround-trip min/avg/max/std-dev = /// ms 636*5b8af90fSJose Luis Duran""", 637*5b8af90fSJose Luis Duran "stderr": "", 638*5b8af90fSJose Luis Duran }, 639*5b8af90fSJose Luis Duran id="_q_c1_2001_db8__1", 640*5b8af90fSJose Luis Duran ), 641*5b8af90fSJose Luis Duran pytest.param( 642*5b8af90fSJose Luis Duran { 643*5b8af90fSJose Luis Duran "args": "ping -q -c1 2001:db8::2", 644*5b8af90fSJose Luis Duran "returncode": 2, 645*5b8af90fSJose Luis Duran "stdout": """\ 646*5b8af90fSJose Luis DuranPING6(56=40+8+8 bytes) 2001:db8::1 --> 2001:db8::2 647*5b8af90fSJose Luis Duran 648*5b8af90fSJose Luis Duran--- 2001:db8::2 ping6 statistics --- 649*5b8af90fSJose Luis Duran1 packets transmitted, 0 packets received, 100.0% packet loss 650*5b8af90fSJose Luis Duran""", 651*5b8af90fSJose Luis Duran "stderr": "", 652*5b8af90fSJose Luis Duran }, 653*5b8af90fSJose Luis Duran id="_q_c1_2001_db8__2", 654*5b8af90fSJose Luis Duran ), 655*5b8af90fSJose Luis Duran pytest.param( 656*5b8af90fSJose Luis Duran { 657*5b8af90fSJose Luis Duran "args": "ping -q -c3 192.0.2.1", 658*5b8af90fSJose Luis Duran "returncode": 0, 659*5b8af90fSJose Luis Duran "stdout": """\ 660*5b8af90fSJose Luis DuranPING 192.0.2.1 (192.0.2.1): 56 data bytes 661*5b8af90fSJose Luis Duran 662*5b8af90fSJose Luis Duran--- 192.0.2.1 ping statistics --- 663*5b8af90fSJose Luis Duran3 packets transmitted, 3 packets received, 0.0% packet loss 664*5b8af90fSJose Luis Duranround-trip min/avg/max/stddev = /// ms 665*5b8af90fSJose Luis Duran""", 666*5b8af90fSJose Luis Duran "stderr": "", 667*5b8af90fSJose Luis Duran }, 668*5b8af90fSJose Luis Duran id="_q_c3_192_0_2_1", 669*5b8af90fSJose Luis Duran ), 670*5b8af90fSJose Luis Duran pytest.param( 671*5b8af90fSJose Luis Duran { 672*5b8af90fSJose Luis Duran "args": "ping -q -c3 192.0.2.2", 673*5b8af90fSJose Luis Duran "returncode": 2, 674*5b8af90fSJose Luis Duran "stdout": """\ 675*5b8af90fSJose Luis DuranPING 192.0.2.2 (192.0.2.2): 56 data bytes 676*5b8af90fSJose Luis Duran 677*5b8af90fSJose Luis Duran--- 192.0.2.2 ping statistics --- 678*5b8af90fSJose Luis Duran3 packets transmitted, 0 packets received, 100.0% packet loss 679*5b8af90fSJose Luis Duran""", 680*5b8af90fSJose Luis Duran "stderr": "", 681*5b8af90fSJose Luis Duran }, 682*5b8af90fSJose Luis Duran id="_q_c3_192_0_2_2", 683*5b8af90fSJose Luis Duran ), 684*5b8af90fSJose Luis Duran pytest.param( 685*5b8af90fSJose Luis Duran { 686*5b8af90fSJose Luis Duran "args": "ping -q -c3 2001:db8::1", 687*5b8af90fSJose Luis Duran "returncode": 0, 688*5b8af90fSJose Luis Duran "stdout": """\ 689*5b8af90fSJose Luis DuranPING6(56=40+8+8 bytes) 2001:db8::1 --> 2001:db8::1 690*5b8af90fSJose Luis Duran 691*5b8af90fSJose Luis Duran--- 2001:db8::1 ping6 statistics --- 692*5b8af90fSJose Luis Duran3 packets transmitted, 3 packets received, 0.0% packet loss 693*5b8af90fSJose Luis Duranround-trip min/avg/max/std-dev = /// ms 694*5b8af90fSJose Luis Duran""", 695*5b8af90fSJose Luis Duran "stderr": "", 696*5b8af90fSJose Luis Duran }, 697*5b8af90fSJose Luis Duran id="_q_c3_2001_db8__1", 698*5b8af90fSJose Luis Duran ), 699*5b8af90fSJose Luis Duran pytest.param( 700*5b8af90fSJose Luis Duran { 701*5b8af90fSJose Luis Duran "args": "ping -q -c3 2001:db8::2", 702*5b8af90fSJose Luis Duran "returncode": 2, 703*5b8af90fSJose Luis Duran "stdout": """\ 704*5b8af90fSJose Luis DuranPING6(56=40+8+8 bytes) 2001:db8::1 --> 2001:db8::2 705*5b8af90fSJose Luis Duran 706*5b8af90fSJose Luis Duran--- 2001:db8::2 ping6 statistics --- 707*5b8af90fSJose Luis Duran3 packets transmitted, 0 packets received, 100.0% packet loss 708*5b8af90fSJose Luis Duran""", 709*5b8af90fSJose Luis Duran "stderr": "", 710*5b8af90fSJose Luis Duran }, 711*5b8af90fSJose Luis Duran id="_q_c3_2001_db8__2", 712*5b8af90fSJose Luis Duran ), 713*5b8af90fSJose Luis Duran ] 714*5b8af90fSJose Luis Duran 715*5b8af90fSJose Luis Duran @pytest.mark.parametrize("expected", testdata) 716*5b8af90fSJose Luis Duran def test_ping(self, expected): 717*5b8af90fSJose Luis Duran """Test ping""" 718*5b8af90fSJose Luis Duran ping = subprocess.run( 719*5b8af90fSJose Luis Duran expected["args"].split(), 720*5b8af90fSJose Luis Duran capture_output=True, 721*5b8af90fSJose Luis Duran timeout=15, 722*5b8af90fSJose Luis Duran text=True, 723*5b8af90fSJose Luis Duran ) 724*5b8af90fSJose Luis Duran assert ping.returncode == expected["returncode"] 725*5b8af90fSJose Luis Duran assert redact(ping.stdout) == expected["stdout"] 726*5b8af90fSJose Luis Duran assert ping.stderr == expected["stderr"] 727*5b8af90fSJose Luis Duran 728*5b8af90fSJose Luis Duran # Each param in ping46_testdata contains a dictionary with the arguments 729*5b8af90fSJose Luis Duran # and the expected outcome (returncode, redacted stdout, and stderr) 730*5b8af90fSJose Luis Duran # common to `ping -4` and `ping -6` 731*5b8af90fSJose Luis Duran ping46_testdata = [ 732*5b8af90fSJose Luis Duran pytest.param( 733*5b8af90fSJose Luis Duran { 734*5b8af90fSJose Luis Duran "args": "-Wx localhost", 735*5b8af90fSJose Luis Duran "returncode": os.EX_USAGE, 736*5b8af90fSJose Luis Duran "stdout": "", 737*5b8af90fSJose Luis Duran "stderr": "ping: invalid timing interval: `x'\n", 738*5b8af90fSJose Luis Duran }, 739*5b8af90fSJose Luis Duran marks=pytest.mark.skip("XXX currently failing"), 740*5b8af90fSJose Luis Duran id="_Wx_localhost", 741*5b8af90fSJose Luis Duran ), 742*5b8af90fSJose Luis Duran ] 743*5b8af90fSJose Luis Duran 744*5b8af90fSJose Luis Duran @pytest.mark.parametrize("expected", ping46_testdata) 745*5b8af90fSJose Luis Duran def test_ping_46(self, expected): 746*5b8af90fSJose Luis Duran """Test ping -4/ping -6""" 747*5b8af90fSJose Luis Duran for version in [4, 6]: 748*5b8af90fSJose Luis Duran ping = subprocess.run( 749*5b8af90fSJose Luis Duran ["ping", f"-{version}"] + expected["args"].split(), 750*5b8af90fSJose Luis Duran capture_output=True, 751*5b8af90fSJose Luis Duran timeout=15, 752*5b8af90fSJose Luis Duran text=True, 753*5b8af90fSJose Luis Duran ) 754*5b8af90fSJose Luis Duran assert ping.returncode == expected["returncode"] 755*5b8af90fSJose Luis Duran assert redact(ping.stdout) == expected["stdout"] 756*5b8af90fSJose Luis Duran assert ping.stderr == expected["stderr"] 757*5b8af90fSJose Luis Duran 758*5b8af90fSJose Luis Duran # Each param in pinger_testdata contains a dictionary with the keywords to 759*5b8af90fSJose Luis Duran # `pinger()` and a dictionary with the expected outcome (returncode, 760*5b8af90fSJose Luis Duran # stdout, stderr, and if ping's output is redacted) 761*5b8af90fSJose Luis Duran pinger_testdata = [ 762*5b8af90fSJose Luis Duran pytest.param( 763*5b8af90fSJose Luis Duran { 764*5b8af90fSJose Luis Duran "src": "192.0.2.1", 765*5b8af90fSJose Luis Duran "dst": "192.0.2.2", 766*5b8af90fSJose Luis Duran "icmp_type": 0, 767*5b8af90fSJose Luis Duran "icmp_code": 0, 768*5b8af90fSJose Luis Duran }, 769*5b8af90fSJose Luis Duran { 770*5b8af90fSJose Luis Duran "returncode": 0, 771*5b8af90fSJose Luis Duran "stdout": """\ 772*5b8af90fSJose Luis DuranPING 192.0.2.2 (192.0.2.2): 56 data bytes 773*5b8af90fSJose Luis Duran64 bytes from: icmp_seq=0 ttl= time= ms 774*5b8af90fSJose Luis Duran 775*5b8af90fSJose Luis Duran--- 192.0.2.2 ping statistics --- 776*5b8af90fSJose Luis Duran1 packets transmitted, 1 packets received, 0.0% packet loss 777*5b8af90fSJose Luis Duranround-trip min/avg/max/stddev = /// ms 778*5b8af90fSJose Luis Duran""", 779*5b8af90fSJose Luis Duran "stderr": "", 780*5b8af90fSJose Luis Duran "redacted": True, 781*5b8af90fSJose Luis Duran }, 782*5b8af90fSJose Luis Duran id="_0_0", 783*5b8af90fSJose Luis Duran ), 784*5b8af90fSJose Luis Duran pytest.param( 785*5b8af90fSJose Luis Duran { 786*5b8af90fSJose Luis Duran "src": "192.0.2.1", 787*5b8af90fSJose Luis Duran "dst": "192.0.2.2", 788*5b8af90fSJose Luis Duran "icmp_type": 0, 789*5b8af90fSJose Luis Duran "icmp_code": 0, 790*5b8af90fSJose Luis Duran "opts": "NOP-40", 791*5b8af90fSJose Luis Duran }, 792*5b8af90fSJose Luis Duran { 793*5b8af90fSJose Luis Duran "returncode": 0, 794*5b8af90fSJose Luis Duran "stdout": """\ 795*5b8af90fSJose Luis DuranPING 192.0.2.2 (192.0.2.2): 56 data bytes 796*5b8af90fSJose Luis Duran64 bytes from: icmp_seq=0 ttl= time= ms 797*5b8af90fSJose Luis Duranwrong total length 124 instead of 84 798*5b8af90fSJose Luis DuranNOP 799*5b8af90fSJose Luis DuranNOP 800*5b8af90fSJose Luis DuranNOP 801*5b8af90fSJose Luis DuranNOP 802*5b8af90fSJose Luis DuranNOP 803*5b8af90fSJose Luis DuranNOP 804*5b8af90fSJose Luis DuranNOP 805*5b8af90fSJose Luis DuranNOP 806*5b8af90fSJose Luis DuranNOP 807*5b8af90fSJose Luis DuranNOP 808*5b8af90fSJose Luis DuranNOP 809*5b8af90fSJose Luis DuranNOP 810*5b8af90fSJose Luis DuranNOP 811*5b8af90fSJose Luis DuranNOP 812*5b8af90fSJose Luis DuranNOP 813*5b8af90fSJose Luis DuranNOP 814*5b8af90fSJose Luis DuranNOP 815*5b8af90fSJose Luis DuranNOP 816*5b8af90fSJose Luis DuranNOP 817*5b8af90fSJose Luis DuranNOP 818*5b8af90fSJose Luis DuranNOP 819*5b8af90fSJose Luis DuranNOP 820*5b8af90fSJose Luis DuranNOP 821*5b8af90fSJose Luis DuranNOP 822*5b8af90fSJose Luis DuranNOP 823*5b8af90fSJose Luis DuranNOP 824*5b8af90fSJose Luis DuranNOP 825*5b8af90fSJose Luis DuranNOP 826*5b8af90fSJose Luis DuranNOP 827*5b8af90fSJose Luis DuranNOP 828*5b8af90fSJose Luis DuranNOP 829*5b8af90fSJose Luis DuranNOP 830*5b8af90fSJose Luis DuranNOP 831*5b8af90fSJose Luis DuranNOP 832*5b8af90fSJose Luis DuranNOP 833*5b8af90fSJose Luis DuranNOP 834*5b8af90fSJose Luis DuranNOP 835*5b8af90fSJose Luis DuranNOP 836*5b8af90fSJose Luis DuranNOP 837*5b8af90fSJose Luis DuranNOP 838*5b8af90fSJose Luis Duran 839*5b8af90fSJose Luis Duran--- 192.0.2.2 ping statistics --- 840*5b8af90fSJose Luis Duran1 packets transmitted, 1 packets received, 0.0% packet loss 841*5b8af90fSJose Luis Duranround-trip min/avg/max/stddev = /// ms 842*5b8af90fSJose Luis Duran""", 843*5b8af90fSJose Luis Duran "stderr": "", 844*5b8af90fSJose Luis Duran "redacted": True, 845*5b8af90fSJose Luis Duran }, 846*5b8af90fSJose Luis Duran id="_0_0_opts_NOP_40", 847*5b8af90fSJose Luis Duran ), 848*5b8af90fSJose Luis Duran pytest.param( 849*5b8af90fSJose Luis Duran { 850*5b8af90fSJose Luis Duran "src": "192.0.2.1", 851*5b8af90fSJose Luis Duran "dst": "192.0.2.2", 852*5b8af90fSJose Luis Duran "icmp_type": 0, 853*5b8af90fSJose Luis Duran "icmp_code": 0, 854*5b8af90fSJose Luis Duran "opts": "unk", 855*5b8af90fSJose Luis Duran }, 856*5b8af90fSJose Luis Duran { 857*5b8af90fSJose Luis Duran "returncode": 0, 858*5b8af90fSJose Luis Duran "stdout": """\ 859*5b8af90fSJose Luis DuranPING 192.0.2.2 (192.0.2.2): 56 data bytes 860*5b8af90fSJose Luis Duran64 bytes from: icmp_seq=0 ttl= time= ms 861*5b8af90fSJose Luis Duranwrong total length 88 instead of 84 862*5b8af90fSJose Luis Duranunknown option 9f 863*5b8af90fSJose Luis Duran 864*5b8af90fSJose Luis Duran--- 192.0.2.2 ping statistics --- 865*5b8af90fSJose Luis Duran1 packets transmitted, 1 packets received, 0.0% packet loss 866*5b8af90fSJose Luis Duranround-trip min/avg/max/stddev = /// ms 867*5b8af90fSJose Luis Duran""", 868*5b8af90fSJose Luis Duran "stderr": "", 869*5b8af90fSJose Luis Duran "redacted": True, 870*5b8af90fSJose Luis Duran }, 871*5b8af90fSJose Luis Duran marks=pytest.mark.skip("XXX currently failing"), 872*5b8af90fSJose Luis Duran id="_0_0_opts_unk", 873*5b8af90fSJose Luis Duran ), 874*5b8af90fSJose Luis Duran pytest.param( 875*5b8af90fSJose Luis Duran { 876*5b8af90fSJose Luis Duran "src": "192.0.2.1", 877*5b8af90fSJose Luis Duran "dst": "192.0.2.2", 878*5b8af90fSJose Luis Duran "icmp_type": 3, 879*5b8af90fSJose Luis Duran "icmp_code": 1, 880*5b8af90fSJose Luis Duran "opts": "NOP-40", 881*5b8af90fSJose Luis Duran }, 882*5b8af90fSJose Luis Duran { 883*5b8af90fSJose Luis Duran "returncode": 2, 884*5b8af90fSJose Luis Duran "stdout": """\ 885*5b8af90fSJose Luis DuranPING 192.0.2.2 (192.0.2.2): 56 data bytes 886*5b8af90fSJose Luis Duran132 bytes from 192.0.2.2: Destination Host Unreachable 887*5b8af90fSJose Luis DuranVr HL TOS Len ID Flg off TTL Pro cks Src Dst 888*5b8af90fSJose Luis Duran 4 f 00 007c 0001 0 0000 40 01 d868 192.0.2.1 192.0.2.2 01010101010101010101010101010101010101010101010101010101010101010101010101010101 889*5b8af90fSJose Luis Duran 890*5b8af90fSJose Luis Duran 891*5b8af90fSJose Luis Duran--- 192.0.2.2 ping statistics --- 892*5b8af90fSJose Luis Duran1 packets transmitted, 0 packets received, 100.0% packet loss 893*5b8af90fSJose Luis Duran""", 894*5b8af90fSJose Luis Duran "stderr": "", 895*5b8af90fSJose Luis Duran "redacted": False, 896*5b8af90fSJose Luis Duran }, 897*5b8af90fSJose Luis Duran marks=pytest.mark.skip("XXX currently failing"), 898*5b8af90fSJose Luis Duran id="_3_1_opts_NOP_40", 899*5b8af90fSJose Luis Duran ), 900*5b8af90fSJose Luis Duran pytest.param( 901*5b8af90fSJose Luis Duran { 902*5b8af90fSJose Luis Duran "src": "192.0.2.1", 903*5b8af90fSJose Luis Duran "dst": "192.0.2.2", 904*5b8af90fSJose Luis Duran "icmp_type": 3, 905*5b8af90fSJose Luis Duran "icmp_code": 1, 906*5b8af90fSJose Luis Duran "flags": "DF", 907*5b8af90fSJose Luis Duran }, 908*5b8af90fSJose Luis Duran { 909*5b8af90fSJose Luis Duran "returncode": 2, 910*5b8af90fSJose Luis Duran "stdout": """\ 911*5b8af90fSJose Luis DuranPING 192.0.2.2 (192.0.2.2): 56 data bytes 912*5b8af90fSJose Luis Duran92 bytes from 192.0.2.2: Destination Host Unreachable 913*5b8af90fSJose Luis DuranVr HL TOS Len ID Flg off TTL Pro cks Src Dst 914*5b8af90fSJose Luis Duran 4 5 00 0054 0001 2 0000 40 01 b6a4 192.0.2.1 192.0.2.2 915*5b8af90fSJose Luis Duran 916*5b8af90fSJose Luis Duran 917*5b8af90fSJose Luis Duran--- 192.0.2.2 ping statistics --- 918*5b8af90fSJose Luis Duran1 packets transmitted, 0 packets received, 100.0% packet loss 919*5b8af90fSJose Luis Duran""", 920*5b8af90fSJose Luis Duran "stderr": "", 921*5b8af90fSJose Luis Duran "redacted": False, 922*5b8af90fSJose Luis Duran }, 923*5b8af90fSJose Luis Duran marks=pytest.mark.skip("XXX currently failing"), 924*5b8af90fSJose Luis Duran id="_3_1_flags_DF", 925*5b8af90fSJose Luis Duran ), 926*5b8af90fSJose Luis Duran ] 927*5b8af90fSJose Luis Duran 928*5b8af90fSJose Luis Duran @pytest.mark.parametrize("pinger_kargs, expected", pinger_testdata) 929*5b8af90fSJose Luis Duran @pytest.mark.require_progs(["scapy"]) 930*5b8af90fSJose Luis Duran @pytest.mark.require_user("root") 931*5b8af90fSJose Luis Duran def test_pinger(self, pinger_kargs, expected): 932*5b8af90fSJose Luis Duran """Test ping using pinger(), a reply faker""" 933*5b8af90fSJose Luis Duran iface = IfaceFactory().create_iface("", "tun")[0].name 934*5b8af90fSJose Luis Duran ping = pinger(iface, **pinger_kargs) 935*5b8af90fSJose Luis Duran assert ping.returncode == expected["returncode"] 936*5b8af90fSJose Luis Duran if expected["redacted"]: 937*5b8af90fSJose Luis Duran assert redact(ping.stdout) == expected["stdout"] 938*5b8af90fSJose Luis Duran else: 939*5b8af90fSJose Luis Duran assert ping.stdout == expected["stdout"] 940*5b8af90fSJose Luis Duran assert ping.stderr == expected["stderr"] 941