Given the IP and netmask, how can I calculate the network address using bash?

后端 未结 6 899
耶瑟儿~
耶瑟儿~ 2020-12-24 03:20

In a bash script I have an IP address like 192.168.1.15 and a netmask like 255.255.0.0. I now want to calculate the start address of this network, that means using the &

相关标签:
6条回答
  • 2020-12-24 03:41

    Just adding an alternative if you have only network prefix available (no netmask):

    IP=10.20.30.240
    PREFIX=26
    IFS=. read -r i1 i2 i3 i4 <<< $IP
    IFS=. read -r xx m1 m2 m3 m4 <<< $(for a in $(seq 1 32); do if [ $(((a - 1) % 8)) -eq 0 ]; then echo -n .; fi; if [ $a -le $PREFIX ]; then echo -n 1; else echo -n 0; fi; done)
    printf "%d.%d.%d.%d\n" "$((i1 & (2#$m1)))" "$((i2 & (2#$m2)))" "$((i3 & (2#$m3)))" "$((i4 & (2#$m4)))"
    
    0 讨论(0)
  • 2020-12-24 03:41

    In addition to @Janci answer

    IP=10.20.30.240
    PREFIX=26
    IFS=. read -r i1 i2 i3 i4 <<< $IP
    D2B=({0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1})
    binIP=${D2B[$i1]}${D2B[$i2]}${D2B[$i3]}${D2B[$i4]}
    binIP0=${binIP::$PREFIX}$(printf '0%.0s' $(seq 1 $((32-$PREFIX))))
    # binIP1=${binIP::$PREFIX}$(printf '0%.0s' $(seq 1 $((31-$PREFIX))))1
    echo $((2#${binIP0::8})).$((2#${binIP0:8:8})).$((2#${binIP0:16:8})).$((2#${binIP0:24:8}))
    
    0 讨论(0)
  • 2020-12-24 03:43

    For people who hit this while googling and need an answer that works in ash, the sh that's included in BusyBox and therefore on many routers, here's something for that case:

    IP=10.20.30.240
    MASK=255.255.252.0
    IFS=. read -r i1 i2 i3 i4 << EOF
    $IP
    EOF
    IFS=. read -r m1 m2 m3 m4 << EOF
    $MASK
    EOF
    read masked << EOF
    $(( $i1 & $m1 )).$(( $i2 & $m2 )).$(( $i3 & $m3 )).$(( $i4 & $m4 ))
    EOF
    echo $masked
    

    And here's what to do if you only have the prefix length:

    IP=10.20.30.240
    PREFIX=22
    IFS=. read -r i1 i2 i3 i4 << EOF
    $IP
    EOF
    mask=$(( ((1<<32)-1) & (((1<<32)-1) << (32 - $PREFIX)) ))
    read masked << EOF
    $(( $i1 & ($mask>>24) )).$(( $i2 & ($mask>>16) )).$(( $i3 & ($mask>>8) )).$(( $i4 & $mask ))
    EOF
    echo $masked
    
    0 讨论(0)
  • 2020-12-24 03:47

    Some Bash functions summarizing all other answers.

    ip2int()
    {
        local a b c d
        { IFS=. read a b c d; } <<< $1
        echo $(((((((a << 8) | b) << 8) | c) << 8) | d))
    }
    
    int2ip()
    {
        local ui32=$1; shift
        local ip n
        for n in 1 2 3 4; do
            ip=$((ui32 & 0xff))${ip:+.}$ip
            ui32=$((ui32 >> 8))
        done
        echo $ip
    }
    
    netmask()
    # Example: netmask 24 => 255.255.255.0
    {
        local mask=$((0xffffffff << (32 - $1))); shift
        int2ip $mask
    }
    
    
    broadcast()
    # Example: broadcast 192.0.2.0 24 => 192.0.2.255
    {
        local addr=$(ip2int $1); shift
        local mask=$((0xffffffff << (32 -$1))); shift
        int2ip $((addr | ~mask))
    }
    
    network()
    # Example: network 192.0.2.0 24 => 192.0.2.0
    {
        local addr=$(ip2int $1); shift
        local mask=$((0xffffffff << (32 -$1))); shift
        int2ip $((addr & mask))
    }
    
    0 讨论(0)
  • 2020-12-24 03:48

    Great answer, though minor typo in answer above.

    $ printf "%d.%d.%d.%d\n" "$((i1 & m1))" "$(($i2  <-- $i2 should be i2
    

    If anyone knows how to calculate the broadcast address (XOR the network), then calculate the usable nodes between network and broadcast I'd be interested in those next steps. I have to find addresses in a list within a /23.

    0 讨论(0)
  • 2020-12-24 04:07

    Use bitwise & (AND) operator:

    $ IFS=. read -r i1 i2 i3 i4 <<< "192.168.1.15"
    $ IFS=. read -r m1 m2 m3 m4 <<< "255.255.0.0"
    $ printf "%d.%d.%d.%d\n" "$((i1 & m1))" "$((i2 & m2))" "$((i3 & m3))" "$((i4 & m4))"
    192.168.0.0
    

    Example with another IP and mask:

    $ IFS=. read -r i1 i2 i3 i4 <<< "10.0.14.97"
    $ IFS=. read -r m1 m2 m3 m4 <<< "255.255.255.248"
    $ printf "%d.%d.%d.%d\n" "$((i1 & m1))" "$((i2 & m2))" "$((i3 & m3))" "$((i4 & m4))"
    10.0.14.96
    
    0 讨论(0)
提交回复
热议问题