Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/scapy/arch/common.py: 33%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

61 statements  

1# SPDX-License-Identifier: GPL-2.0-only 

2# This file is part of Scapy 

3# See https://scapy.net/ for more information 

4# Copyright (C) Philippe Biondi <phil@secdev.org> 

5 

6""" 

7Functions common to different architectures 

8""" 

9 

10import ctypes 

11import re 

12import socket 

13 

14from scapy.config import conf 

15from scapy.data import MTU, ARPHRD_TO_DLT, DLT_RAW_ALT, DLT_RAW 

16from scapy.error import Scapy_Exception, warning 

17from scapy.interfaces import network_name, resolve_iface, NetworkInterface 

18from scapy.libs.structures import bpf_program 

19from scapy.pton_ntop import inet_pton 

20from scapy.utils import decode_locale_str 

21 

22# Type imports 

23import scapy 

24from typing import ( 

25 List, 

26 Optional, 

27 Union, 

28) 

29 

30# From if.h 

31_iff_flags = [ 

32 "UP", 

33 "BROADCAST", 

34 "DEBUG", 

35 "LOOPBACK", 

36 "POINTTOPOINT", 

37 "NOTRAILERS", 

38 "RUNNING", 

39 "NOARP", 

40 "PROMISC", 

41 "ALLMULTI", 

42 "MASTER", 

43 "SLAVE", 

44 "MULTICAST", 

45 "PORTSEL", 

46 "AUTOMEDIA", 

47 "DYNAMIC", 

48 "LOWER_UP", 

49 "DORMANT", 

50 "ECHO" 

51] 

52 

53 

54def get_if_raw_addr(iff): 

55 # type: (Union[NetworkInterface, str]) -> bytes 

56 """Return the raw IPv4 address of interface""" 

57 iff = resolve_iface(iff) 

58 if not iff.ip: 

59 return b"\x00" * 4 

60 return inet_pton(socket.AF_INET, iff.ip) 

61 

62 

63# BPF HANDLERS 

64 

65 

66def compile_filter(filter_exp, # type: str 

67 iface=None, # type: Optional[Union[str, 'scapy.interfaces.NetworkInterface']] # noqa: E501 

68 linktype=None, # type: Optional[int] 

69 promisc=False # type: bool 

70 ): 

71 # type: (...) -> bpf_program 

72 """Asks libpcap to parse the filter, then build the matching 

73 BPF bytecode. 

74 

75 :param iface: if provided, use the interface to compile 

76 :param linktype: if provided, use the linktype to compile 

77 """ 

78 try: 

79 from scapy.libs.winpcapy import ( 

80 PCAP_ERRBUF_SIZE, 

81 pcap_open_live, 

82 pcap_compile, 

83 pcap_compile_nopcap, 

84 pcap_close 

85 ) 

86 except OSError: 

87 raise ImportError( 

88 "libpcap is not available. Cannot compile filter !" 

89 ) 

90 from ctypes import create_string_buffer 

91 bpf = bpf_program() 

92 bpf_filter = create_string_buffer(filter_exp.encode("utf8")) 

93 if not linktype: 

94 # Try to guess linktype to avoid root 

95 if not iface: 

96 if not conf.iface: 

97 raise Scapy_Exception( 

98 "Please provide an interface or linktype!" 

99 ) 

100 iface = conf.iface 

101 # Try to guess linktype to avoid requiring root 

102 try: 

103 arphd = resolve_iface(iface).type 

104 linktype = ARPHRD_TO_DLT.get(arphd) 

105 except Exception: 

106 # Failed to use linktype: use the interface 

107 pass 

108 if linktype is not None: 

109 # Some conversion aliases (e.g. linktype_to_dlt in libpcap) 

110 if linktype == DLT_RAW_ALT: 

111 linktype = DLT_RAW 

112 ret = pcap_compile_nopcap( 

113 MTU, linktype, ctypes.byref(bpf), bpf_filter, 1, -1 

114 ) 

115 elif iface: 

116 err = create_string_buffer(PCAP_ERRBUF_SIZE) 

117 iface_b = create_string_buffer(network_name(iface).encode("utf8")) 

118 pcap = pcap_open_live( 

119 iface_b, MTU, promisc, 0, err 

120 ) 

121 error = decode_locale_str(bytearray(err).strip(b"\x00")) 

122 if error: 

123 raise OSError(error) 

124 ret = pcap_compile( 

125 pcap, ctypes.byref(bpf), bpf_filter, 1, -1 

126 ) 

127 pcap_close(pcap) 

128 if ret == -1: 

129 raise Scapy_Exception( 

130 "Failed to compile filter expression %s (%s)" % (filter_exp, ret) 

131 ) 

132 return bpf 

133 

134 

135####### 

136# DNS # 

137####### 

138 

139def read_nameservers() -> List[str]: 

140 """Return the nameservers configured by the OS 

141 """ 

142 try: 

143 with open('/etc/resolv.conf', 'r') as fd: 

144 return re.findall(r"nameserver\s+([^\s]+)", fd.read()) 

145 except FileNotFoundError: 

146 warning("Could not retrieve the OS's nameserver !") 

147 return []