2011-07-14 Code Snippets 3000 Turbo: Subnets of Subnets

Juhani Eronen from CERT-FI was doing some Python coding, and he XMPP'd (Jabbered? Asked?) me whether I had something that would give out subnets inside subnets. For example, all /24 subnets contained in 10.10.0.0/16. I didn't, but Jani was concentrating on no doubt something very important instead of guarding my productivity.

   1 import struct
   2 import socket
   3 
   4 def subnets(ip, original_bits, final_bits):
   5     if not 0 <= original_bits <= final_bits <= 32:
   6         return
   7 
   8     ip_num, = struct.unpack("!I", socket.inet_aton(ip))
   9 
  10     ip_start = ip_num & (((1 << 32) - 1) ^ ((1 << (32-original_bits)) - 1))
  11     ip_end = ip_start + (1 << (32 - original_bits))
  12     ip_jump = 1 << (32 - final_bits)
  13     
  14     while ip_start < ip_end:
  15         yield socket.inet_ntoa(struct.pack("!I", ip_start)), final_bits
  16         ip_start += ip_jump

As always, comments and documentation are for fools! And IPv6 support! And probably correctness, too! Juhani didn't ultimately need this code, but there you have it.

Addendum: Turns out Juhani needed something that checks whether an IP address is contained by a subnet. When all you have is a hammer everything becomes a nail:

   1 def check(ip, subnet_ip, subnet_bits):
   2     return (set(subnets(ip, subnet_bits, subnet_bits))
   3             ==
   4             set(subnets(subnet_ip, subnet_bits, subnet_bits)))

Kids, please use something more to the point instead of... this. And stay in school.

-- jviide 2011-07-14 11:16:21


return to the blog ...