Coverage for src / local_deep_research / security / network_utils.py: 100%

11 statements  

« prev     ^ index     » next       coverage.py v7.12.0, created at 2026-01-11 00:51 +0000

1"""Network utility functions for IP address classification. 

2 

3This module provides utilities for classifying IP addresses and hostnames 

4as private/local vs public. Used for URL normalization and security validation. 

5""" 

6 

7import ipaddress 

8 

9 

10def is_private_ip(hostname: str) -> bool: 

11 """Check if hostname is a private/local IP address. 

12 

13 Recognizes: 

14 - Localhost values (127.0.0.1, localhost, [::1], 0.0.0.0) 

15 - RFC 1918 private IPv4 ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) 

16 - IPv6 private addresses (fc00::/7, fe80::/10) 

17 - mDNS .local domains 

18 

19 Args: 

20 hostname: The hostname or IP address to check 

21 

22 Returns: 

23 True if the hostname is a private/local address, False otherwise 

24 

25 Examples: 

26 >>> is_private_ip("192.168.1.100") 

27 True 

28 >>> is_private_ip("172.16.0.50") 

29 True 

30 >>> is_private_ip("10.0.0.1") 

31 True 

32 >>> is_private_ip("8.8.8.8") 

33 False 

34 >>> is_private_ip("api.openai.com") 

35 False 

36 """ 

37 # Known localhost values 

38 if hostname in ("localhost", "127.0.0.1", "[::1]", "0.0.0.0"): 

39 return True 

40 

41 # Handle bracketed IPv6 

42 if hostname.startswith("[") and hostname.endswith("]"): 

43 hostname = hostname[1:-1] 

44 

45 try: 

46 ip = ipaddress.ip_address(hostname) 

47 # Check if private (includes 10.x, 172.16-31.x, 192.168.x, fc00::/7, etc.) 

48 # Also check loopback and link-local 

49 return ip.is_private or ip.is_loopback or ip.is_link_local 

50 except ValueError: 

51 # Not a valid IP address, check for .local domain (mDNS) 

52 return hostname.endswith(".local")