2017-06-14 8 views
0

Nous portons openwrt sur notre appareil qui est une plate-forme Mips. Mais nous avons trouvé le service "Dnsmasq" ne peut pas être démarré correctement sur notre appareil. Ensuite, nous avons trouvé la cause première, "/etc/init.d/dnsmasq" utilisant le script "/bin/ipcalc.sh" générant la mauvaise configuration pour "dnsmasq" et "dnsmasq" n'a pas réussi à analyser la configuration.Pourquoi xor() ne fonctionne pas sur openwrt

Voici le lien vers le code original de "/bin/ipcalc.sh" dans github https://github.com/respeaker/openwrt/blob/master/package/base-files/files/bin/ipcalc.sh

Ensuite, nous remplaçons tous les Invoke de compl32() avec compl(), il fonctionne. Comme nous étudions le script, et trouvons compl32() est une fonction très simple, qui invoque simplement xor(). Mais on dirait que xor() ne peut pas produire ce que nous attendions.

Voici le code de /bin/ipcalc.sh que nous utilisons, et j'ajouter un peu de débogage dans ce:

#!/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 

Voici le résultat courant:

[email protected]:/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 
[email protected]:/tmp# 

C'est très étrange. Pourquoi xor() ne fonctionne pas?

Répondre

0

Votre expression dans BEGIN pour var3 produit var3 = 4294967040 sur mon système (GNU Awk 4.1.4). On dirait que vous utilisez un Awk cassé, essayez une version différente.

0

$ man awk

NORMES L'utilitaire awk est conforme à la spécification IEEE Std 1003,1 à 2008 ('' de POSIX.1 '') , sauf awk ne supporte pas {n, m} correspondance de motif.

Les drapeaux [-dV] et [-safe], ainsi que les commandes fflush, compl, et, ou, xor, lshift, rshift, sont extensions de cette spécification

D'après mon expérience, certaines implémentations comme FreeBSD n'implémentent pas complètement ces extensions.