Skip to content

Commit e47aaa1

Browse files
authored
Merge pull request #2 from DefensiveOrigins/rfc1918
Rfc1918
2 parents 99ec17f + 23e6df3 commit e47aaa1

File tree

1 file changed

+49
-12
lines changed

1 file changed

+49
-12
lines changed

HostCount.py

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,20 @@
33
import os
44
from collections import defaultdict
55

6+
# RFC1918 networks
7+
RFC1918_NETWORKS = [
8+
ipaddress.ip_network("10.0.0.0/8"),
9+
ipaddress.ip_network("172.16.0.0/12"),
10+
ipaddress.ip_network("192.168.0.0/16"),
11+
]
12+
13+
def is_rfc1918(ip_str):
14+
try:
15+
ip = ipaddress.ip_address(ip_str)
16+
return any(ip in net for net in RFC1918_NETWORKS)
17+
except ValueError:
18+
return False
19+
620
def extract_unique_hosts_from_file(file_path):
721
unique_hosts = set()
822

@@ -37,6 +51,8 @@ def main():
3751
parser.add_argument("-d", "--directory", help="Directory of files to process.")
3852
parser.add_argument("-D", "--duplicates", action="store_true",
3953
help="When processing a directory, list hosts that appear in more than one file and which files they appear in.")
54+
parser.add_argument("-r", "--rfc1918", action="store_true",
55+
help="Optionally show how many hosts are in RFC1918 space vs not (per-file and totals).")
4056
args = parser.parse_args()
4157

4258
if args.directory:
@@ -52,28 +68,49 @@ def main():
5268
grand_total_hosts.update(file_hosts)
5369
print(f"\nTotal unique hosts across all files: {len(grand_total_hosts)}")
5470

55-
if args.duplicates:
56-
# Build host -> set(files) mapping
57-
host_to_files = defaultdict(set)
58-
for fname, hosts in file_hosts_map.items():
59-
for h in hosts:
60-
host_to_files[h].add(fname)
71+
# Build host -> set(files) mapping once for both -D output and the duplicate note
72+
host_to_files = defaultdict(set)
73+
for fname, hosts in file_hosts_map.items():
74+
for h in hosts:
75+
host_to_files[h].add(fname)
76+
duplicates_map = {host: sorted(list(files)) for host, files in host_to_files.items() if len(files) > 1}
77+
duplicate_count = len(duplicates_map)
6178

62-
# Find hosts present in more than one file
63-
duplicates = {host: sorted(list(files)) for host, files in host_to_files.items() if len(files) > 1}
79+
# If -D not used, but duplicates exist, print a concise note that duplicates were found and are only counted once
80+
if not args.duplicates and duplicate_count > 0:
81+
print(f"\nNote: {duplicate_count} host(s) were found in more than one file but are only counted once in the total unique host count. Use -D to list them.")
6482

65-
if not duplicates:
83+
if args.rfc1918:
84+
print("\nRFC1918 breakdown per file:")
85+
for fname in sorted(file_hosts_map.keys()):
86+
hosts = file_hosts_map[fname]
87+
rfc_count = sum(1 for h in hosts if is_rfc1918(h))
88+
non_rfc = len(hosts) - rfc_count
89+
print(f"{fname}: {rfc_count} RFC1918, {non_rfc} non-RFC1918")
90+
91+
total_rfc = sum(1 for h in grand_total_hosts if is_rfc1918(h))
92+
total_non_rfc = len(grand_total_hosts) - total_rfc
93+
print(f"\nTotals across all files: {total_rfc} RFC1918, {total_non_rfc} non-RFC1918")
94+
95+
if args.duplicates:
96+
# Use the mapping we already built to list duplicates
97+
if not duplicates_map:
6698
print("\nNo duplicate hosts found between files.")
6799
else:
68-
print(f"\nDuplicate hosts found between files: {len(duplicates)} hosts\n")
69-
for host in sorted(duplicates.keys(), key=lambda x: tuple(int(p) for p in x.split('.'))):
70-
files_list = ", ".join(duplicates[host])
100+
print(f"\nDuplicate hosts found between files: {len(duplicates_map)} hosts\n")
101+
for host in sorted(duplicates_map.keys(), key=lambda x: tuple(int(p) for p in x.split('.'))):
102+
files_list = ", ".join(duplicates_map[host])
71103
print(f"{host}: {files_list}")
72104

73105
elif args.file:
74106
unique_hosts = extract_unique_hosts_from_file(args.file)
75107
print(f"\nTotal unique hosts in {args.file} (excluding network and broadcast): {len(unique_hosts)}")
76108

109+
if args.rfc1918:
110+
rfc_count = sum(1 for h in unique_hosts if is_rfc1918(h))
111+
non_rfc = len(unique_hosts) - rfc_count
112+
print(f"{args.file}: {rfc_count} RFC1918, {non_rfc} non-RFC1918")
113+
77114
else:
78115
print("ERROR: Either a file or a directory must be specified.")
79116
parser.print_help()

0 commit comments

Comments
 (0)