base-files: ipcalc.sh: trim for statement
[openwrt/openwrt.git] / package / base-files / files / bin / ipcalc.sh
index 9057e859289b8dd5f0ba66d2c2d50c842a9a7e76..99269fff066f99176ad5802d7005eb53e6e29fca 100755 (executable)
@@ -1,6 +1,5 @@
-#!/bin/sh
+#!/usr/bin/awk -f
 
-awk -f - $* <<EOF
 function bitcount(c) {
        c=and(rshift(c, 1),0x55555555)+and(c,0x55555555)
        c=and(rshift(c, 2),0x33333333)+and(c,0x33333333)
@@ -11,43 +10,80 @@ function bitcount(c) {
 }
 
 function ip2int(ip) {
-       for (ret=0,n=split(ip,a,"\."),x=1;x<=n;x++) ret=or(lshift(ret,8),a[x]) 
+       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;ret=and(ip,255)"."ret,ip=rshift(ip,8),x++);
+       for(;x<3;x++) {
+               ret=and(ip,255)"."ret
+               ip=rshift(ip,8)
+       }
+       return ret
+}
+
+function compl32(v) {
+       ret=xor(v, 0xffffffff)
        return ret
 }
 
 BEGIN {
-       ipaddr=ip2int(ARGV[1])
-       netmask=ip2int(ARGV[2])
+       slpos=index(ARGV[1],"/")
+       if (slpos == 0) {
+               ipaddr=ip2int(ARGV[1])
+               dotpos=index(ARGV[2],".")
+               if (dotpos == 0)
+                       netmask=compl32(2**(32-int(ARGV[2]))-1)
+               else
+                       netmask=ip2int(ARGV[2])
+       } else {
+               ipaddr=ip2int(substr(ARGV[1],0,slpos-1))
+               netmask=compl32(2**(32-int(substr(ARGV[1],slpos+1)))-1)
+               ARGV[4]=ARGV[3]
+               ARGV[3]=ARGV[2]
+       }
+
        network=and(ipaddr,netmask)
-       broadcast=or(network,compl(netmask))
-       
-       start=or(network,and(ip2int(ARGV[3]),compl(netmask)))
-       limit=network+1
-       if (start<limit) start=limit
-       
-       end=start+ARGV[4]
-       limit=or(network,compl(netmask))-1
-       if (end>limit) end=limit
+       prefix=32-bitcount(compl32(netmask))
+       broadcast=or(network,compl32(netmask))
 
        print "IP="int2ip(ipaddr)
        print "NETMASK="int2ip(netmask)
        print "BROADCAST="int2ip(broadcast)
        print "NETWORK="int2ip(network)
-       print "PREFIX="32-bitcount(compl(netmask))
-       
+       print "PREFIX="prefix
+
        # range calculations:
        # ipcalc <ip> <netmask> <start> <num>
-       
-       if (ARGC > 3) {
-               print "START="int2ip(start)
-               print "END="int2ip(end)
+
+       if (ARGC <= 3)
+               exit(0)
+
+       start=or(network,and(ip2int(ARGV[3]),compl32(netmask)))
+       limit=network+1
+       if (start<limit) start=limit
+       if (start==ipaddr) start=ipaddr+1
+
+       end=start+ARGV[4]
+       limit=or(network,compl32(netmask))-1
+       if (end>limit) end=limit
+       if (end==ipaddr) end=ipaddr-1
+
+       if (start>end) {
+               print "network ("int2ip(network)"/"prefix") too small" > "/dev/stderr"
+               exit(1)
        }
+
+       if (ipaddr > start && ipaddr < end) {
+               print "ipaddr inside range" > "/dev/stderr"
+               exit(1)
+       }
+
+       print "START="int2ip(start)
+       print "END="int2ip(end)
 }
-EOF