We are porting openwrt to our device which is a mips platform. But we found the service "dnsmasq" can't be started correctly on our device.
Then we found the root cause, "/etc/init.d/dnsmasq" used the script "/bin/ipcalc.sh" generating the wrong configuration for "dnsmasq" and "dnsmasq" failed to parse the configuration.
Here is the link to the original code of "/bin/ipcalc.sh" in github https://github.com/respeaker/openwrt/blob/master/package/base-files/files/bin/ipcalc.sh
Then we replace all the invoke of compl32() with compl(), then it works. As we investigate the script, and find compl32() is a very simple function, which just invoke xor(). But looks like xor() can't produce what we were expecting.
Here is the code of /bin/ipcalc.sh that we are using, and I add some debug in it:
#!/bin/sh
awk -f - $* <<EOF
function bitcount(c) {
c=and(rshift(c, 1),0x55555555)+and(c,0x55555555)
c=and(rshift(c, 2),0x33333333)+and(c,0x33333333)
c=and(rshift(c, 4),0x0f0f0f0f)+and(c,0x0f0f0f0f)
c=and(rshift(c, 8),0x00ff00ff)+and(c,0x00ff00ff)
c=and(rshift(c,16),0x0000ffff)+and(c,0x0000ffff)
return c
}
function ip2int(ip) {
for (ret=0,n=split(ip,a,"\."),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++);
return ret
}
function compl32(v) {
ret=xor(v, 0xffffffff)
return ret
}
BEGIN {
print "var1="compl32(255)
print "var2="compl(0xff)
print "var3="xor(0xff,0xffffffff)
print "var4="xor(255,0xffffffff)
slpos=index(ARGV[1],"/")
if (slpos == 0) {
ipaddr=ip2int(ARGV[1])
dotpos=index(ARGV[2],".")
if (dotpos == 0)
netmask=compl(2**(32-int(ARGV[2]))-1)
else
netmask=ip2int(ARGV[2])
} else {
ipaddr=ip2int(substr(ARGV[1],0,slpos-1))
netmask=compl(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
print "IP="int2ip(ipaddr)
print "NETMASK="int2ip(netmask)
print "BROADCAST="int2ip(broadcast)
print "NETWORK="int2ip(network)
print "PREFIX="32-bitcount(compl(netmask))
# range calculations:
# ipcalc <ip> <netmask> <start> <num>
if (ARGC > 3) {
print "START="int2ip(start)
print "END="int2ip(end)
}
}
EOF
Here is the running result:
root@OpenWrt:/tmp# ipcalc.sh 192.168.1.1/24 100 50
var1=255
var2=4294967295
var3=0
var4=255
IP=192.168.1.1
NETMASK=255.255.255.0
BROADCAST=192.168.1.255
NETWORK=192.168.1.0
PREFIX=32
START=192.168.1.100
END=192.168.1.150
root@OpenWrt:/tmp#
This is very strange. Why xor() does not work?
Your expression in BEGIN for var3 produces var3=4294967040 on my system (GNU Awk 4.1.4). Looks like you are using an broken Awk- please try a different version.
$ man awk
STANDARDS The awk utility is compliant with the IEEE Std 1003.1-2008 (''POSIX.1'') specification, except awk does not support {n,m} pattern matching.
The flags [-dV] and [-safe], as well as the commands fflush,compl, and,or, xor, lshift, rshift, are extensions to that specification
In my experience some implementations like in FreeBSD do not fully implement those extensions.
User contributions licensed under CC BY-SA 3.0