Retrieves the network information including the default gateway and subnet.
(self)
| 912 | self.logger.error(f"Error in display_csv: {e}") |
| 913 | |
| 914 | def get_network(self): |
| 915 | """ |
| 916 | Retrieves the network information including the default gateway and subnet. |
| 917 | """ |
| 918 | try: |
| 919 | if self._active_scan_network: |
| 920 | network = ipaddress.ip_network(self._active_scan_network, strict=False) |
| 921 | self.logger.info(f"Network (override): {network}") |
| 922 | return network |
| 923 | if netifaces is None: |
| 924 | # Fallback: detect network from ip commands |
| 925 | try: |
| 926 | result = subprocess.run( |
| 927 | ['ip', '-o', '-4', 'addr', 'show', self.arp_scan_interface], |
| 928 | capture_output=True, text=True, timeout=5 |
| 929 | ) |
| 930 | for line in result.stdout.strip().splitlines(): |
| 931 | # Format: 3: br-lan inet 172.16.52.1/24 brd ... |
| 932 | parts = line.split() |
| 933 | for i, p in enumerate(parts): |
| 934 | if p == 'inet' and i + 1 < len(parts): |
| 935 | cidr = parts[i + 1] # e.g. 172.16.52.1/24 |
| 936 | network = ipaddress.IPv4Network(cidr, strict=False) |
| 937 | self.logger.info(f"Network (from {self.arp_scan_interface}): {network}") |
| 938 | return network |
| 939 | except Exception as e: |
| 940 | self.logger.warning(f"Failed to detect network from ip command: {e}") |
| 941 | # Last resort: try any non-loopback interface |
| 942 | try: |
| 943 | result = subprocess.run( |
| 944 | ['ip', '-o', '-4', 'addr', 'show'], |
| 945 | capture_output=True, text=True, timeout=5 |
| 946 | ) |
| 947 | for line in result.stdout.strip().splitlines(): |
| 948 | if '127.0.0.1' in line: |
| 949 | continue |
| 950 | parts = line.split() |
| 951 | for i, p in enumerate(parts): |
| 952 | if p == 'inet' and i + 1 < len(parts): |
| 953 | cidr = parts[i + 1] |
| 954 | network = ipaddress.IPv4Network(cidr, strict=False) |
| 955 | self.logger.info(f"Network (detected): {network}") |
| 956 | return network |
| 957 | except Exception as e: |
| 958 | self.logger.warning(f"Failed to detect any network: {e}") |
| 959 | self.logger.error( |
| 960 | "Unable to detect local network — netifaces missing and " |
| 961 | "'ip' command output could not be parsed. Caller must " |
| 962 | "supply an explicit CIDR.") |
| 963 | return None |
| 964 | |
| 965 | gws = netifaces.gateways() |
| 966 | default_gateway = gws['default'][netifaces.AF_INET][1] |
| 967 | iface = netifaces.ifaddresses(default_gateway)[netifaces.AF_INET][0] |
| 968 | ip_address = iface['addr'] |
| 969 | netmask = iface['netmask'] |
| 970 | cidr = sum([bin(int(x)).count('1') for x in netmask.split('.')]) |
| 971 | network = ipaddress.IPv4Network(f"{ip_address}/{cidr}", strict=False) |
no test coverage detected