Skip to content

Instantly share code, notes, and snippets.

@LazyZhu
Last active October 30, 2020 03:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save LazyZhu/3f15cf7ab3777b54d21c to your computer and use it in GitHub Desktop.
Save LazyZhu/3f15cf7ab3777b54d21c to your computer and use it in GitHub Desktop.
cidr_complement.sh
#!/bin/sh
cidr_complement() {
awk -f - $* <<EOF
function ip2int(ip) {
ret=0
n=split(ip,a,".")
for (x=1;x<=n;x++) {
ret=or(lshift(ret,8),a[x])
}
return ret
}
function int2ip(ip,ret,x) {
ret=and(ip,255)
ip=rshift(ip,8)
for(;x<3;x++) {
ret=and(ip,255)"."ret
ip=rshift(ip,8)
}
return ret
}
function compl32(v) {
ret=xor(v, 0xffffffff)
return ret
}
function range2cidr(ipStart, ipEnd, bits, mask, newip) {
bits = 1
mask = 1
result = ""
while (bits < 32) {
newip = or(ipStart, mask)
if ((newip>ipEnd) || ((lshift(rshift(ipStart,bits),bits)) != ipStart)) {
bits--
mask = rshift(mask,1)
break
}
bits++
mask = lshift(mask,1)+1
}
newip = or(ipStart, mask)
bits = 32 - bits
result = result int2ip(ipStart) "/" bits
if (newip < ipEnd) result = result "\n" range2cidr(newip + 1, ipEnd)
return result
}
BEGIN {
start=0
while ((getline cidr<"/tmp/test.list")>0) {
slpos=index(cidr,"/")
ipaddr=ip2int(substr(cidr,0,slpos-1))
netmask=compl32(2**(32-int(substr(cidr,slpos+1)))-1)
num=compl32(netmask)+1
end=ipaddr - 1
if (end>=start) {
print range2cidr(start, end)
}
start=ipaddr + num
}
if (start<=4294967295) {
print range2cidr(start, 4294967295)
}
}
EOF
}
cat /path/to/yourcidr.list | sort -n -t . -k 1,1 -k 2,2 -k 3,3 -k 4,4 >/tmp/test.list
cidr_complement
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment