简体   繁体   English

编写 bash 脚本将给定的 su.net 细分为预定义数量的较小 su.net

[英]Write a bash script to subdivide an given subnet into a pre-defined number of smaller subnets

This question was recently asked in an interview.这个问题最近在一次采访中被问到。

Question: Write a bash script to subdivide an given su.net into a pre-defined number of smaller su.nets.问题:编写一个 bash 脚本将给定的 su.net 细分为预定义数量的较小 su.net。

After division IP addresses shouldn't be wasted, ie accumulation of your subdivisions should make up the divided su.net.分割后 IP 地址不应该被浪费,即你的细分的积累应该弥补分割的 su.net。

Every su.net has 3 IP addresses reserved and not usable by hosts:.network, broadcast, gateway.每个 su.net 都有 3 个 IP 地址保留,主机不能使用:.network、broadcast、gateway。

Show.network/broadcast address, number of hosts and assign gateway.显示网络/广播地址、主机数量和分配网关。 Gateway should be first IP available in divided su.net.网关应该是第一个IP 在划分su.net 中可用。 Examples:例子:

INPUT: ./su.netter.sh 192.168.0.0/24 3输入: ./su.netter.sh 192.168.0.0/24 3

OUTPUT: OUTPUT:

subnet=192.168.0.0/25   network=192.168.0.0   broadcast=192.168.0.127 gateway=192.168.0.1   hosts=125 
subnet=192.168.0.128/26 network=192.168.0.128 broadcast=192.168.0.191 gateway=192.168.0.129 hosts=61 
subnet=192.168.0.192/26 network=192.168.0.192 broadcast=192.168.0.255 gateway=192.168.0.193 hosts=61

INPUT: ./su.netter.sh 192.168.0.0/24 4输入: ./su.netter.sh 192.168.0.0/24 4

OUTPUT: OUTPUT:

subnet=192.168.0.0/26   network=192.168.0.0   broadcast=192.168.0.63  gateway=192.168.0.1   hosts=61 
subnet=192.168.0.64/26  network=192.168.0.64  broadcast=192.168.0.127 gateway=192.168.0.65  hosts=61 
subnet=192.168.0.128/26 network=192.168.0.128 broadcast=192.168.0.191 gateway=192.168.0.129 hosts=61 
subnet=192.168.0.192/26 network=192.168.0.192 broadcast=192.168.0.255 gateway=192.168.0.193 hosts=61

INPUT: ./su.netter.sh 10.55.10.64/28 2输入: ./su.netter.sh 10.55.10.64/28 2

OUTPUT: OUTPUT:

subnet=10.55.10.64/29   network=10.55.10.64   broadcast=10.55.10.71   gateway=10.55.10.65   hosts=5
subnet=10.55.10.72/29   network=10.55.10.72   broadcast=10.55.10.79   gateway=10.55.10.73   hosts=5

First of all, I am trying to analyse what logic is used to divide the su.nets.首先,我想分析一下su.net是用什么逻辑来划分的。 Secondly, I am trying to use the ipcalc command to get outputs but no luck.其次,我正在尝试使用ipcalc命令获取输出但没有成功。

Thanks谢谢

Here is the bash script, I have tried my hands on: Should work fine.这是 bash 脚本,我已经尝试过:应该可以正常工作。 The script takes 2 arguments, CIDR block and number of su.nets to divide into.该脚本需要 2 arguments,CIDR 块和 su.net 的数量来划分。

      #!/bin/bash

      cidr=$1
      total_subnet=$2
      nw_addr=`echo $cidr | awk -F'/' '{ print $1 }'` # retrieving network IP from input 1
      nw_mask=`echo $cidr | awk -F'/' '{ print $2 }'` # retrieving network mask from input 1
      dbit=`echo $nw_addr | awk -F'.' '{ print $4 }'` # retrieving the D-bit from network ( A.B.C.D )
      significant_bit=`echo $nw_addr | awk -F'.' 'BEGIN {OFS = ""}{print $1,".",$2,".",$3 }'` # retrieving A.B.C bits from n/w address

      change_bit=$(( 32 - $nw_mask)) 
      max_addr=$(( 2 ** $change_bit)) # calculating maximum addresses available in the network that can be subdivided
      dbit_max=$dbit 

      # A Funtion to calculate the least power of 2 that is equal or greater than the argument
      least_greater_power_of_two()
      {
      next_power=2
      power=1
      subnet_range=$1
      while [ $next_power -lt $subnet_range  ]; do

       power=$(($power+1))
       next_power=$(( 2 ** $power))
      done

      }

      #initialising Loop Variables
      remaining_addr=$max_addr
      max_subnet_dbit=$dbit
      total_subnet_addr=0
      starting_dbit=$dbit
      i=$total_subnet


      while [ $i -gt 0 ]; do
        starting_dbit=$(( $starting_dbit + $total_subnet_addr )) #Finding the starting D bit of the subnet

        #finding the total number of addresses in the subnet 
        subnet_range=$(( $remaining_addr /  $i )) 
        least_greater_power_of_two $subnet_range 
        total_subnet_addr=$(( 2 ** $power ))

        max_subnet_dbit=$(( $max_subnet_dbit + $total_subnet_addr ))
        remaining_addr=$(( $remaining_addr - $total_subnet_addr ))  # Remaining addresses left to be assigned to the other subnets

        last_dbit=$(( $max_subnet_dbit - 1)) #calculating last D bit in the subnet range
        subnet_mask=$(( $change_bit - $power + $nw_mask )) #calculating the subnet mask
        gateway_dbit=$(( $starting_dbit + 1 )) # calculating the Gateway D bit
        total_hosts=$(( $total_subnet_addr - 3 )) # calculating the Total-hosts in the network
        echo "Subnet= $significant_bit.$starting_dbit/$subnet_mask Network=$significant_bit.$starting_dbit Broadcast=$significant_bit.$last_dbit Gateway= $significant_bit.$gateway_dbit Hosts=$total_hosts"
        i=$(($i-1)) # updating loop variable

      done

I believe I have done 70% of the stuff that you require off the script.我相信我已经根据脚本完成了您需要的 70%。 Since you were using ipcalc, dediced to use a similar binary.由于您使用的是 ipcalc,因此致力于使用类似的二进制文件。 To start off, do the following:要开始,请执行以下操作:

yum install sipcalc if you have a RPM based OS or apt-get install sipcalc depending on the distro of your Linux OS. yum install sipcalc 如果您有基于 RPM 的操作系统或 apt-get install sipcalc 取决于您的 Linux 操作系统的发行版。

Then write the following script and save it as su.netter.sh and give it 'x' permissions so that it can be executed.然后编写如下脚本,保存为su.netter.sh,赋予'x'权限,使其可以执行。

#!/bin/bash

if [ $# == 0 ]; then
echo "Usage: ./subnetter.sh  IP/SUBNET RANGE"
exit
fi

subnet=$1
network=`echo $subnet | cut -d / -f1`
broadcast=`/usr/bin/sipcalc $1 | grep -i broadcast | cut -d '-' -f2`
gateway=`/usr/bin/sipcalc $1 | grep -i usable | awk '{print $4}'`
hosts=`/usr/bin/sipcalc $1 |  grep -i addresses | cut -d '-' -f2`

echo "subnet =" $subnet "network =" $network "broadcast =" $broadcast "gateway =" $gateway "hosts =" $hosts

Output of my script:我的脚本的 Output:

[root@puppet ~]# ./subnetter.sh  192.168.0.0/24
subnet = 192.168.0.0/24 network = 192.168.0.0 broadcast = 192.168.0.255 gateway = 192.168.0.1 hosts = 256

Please note that the requirement of the third argument is very simple and can be simply done using a for loop.请注意,第三个参数的要求非常简单,可以使用 for 循环简单地完成。 I expect you to do that.我希望你这样做。

You can use the following tool to make sure that your output is correct: http://www.su.net-calculator.com/su.net.php.net_class=C您可以使用以下工具来确保您的 output 是正确的: http://www.su.net-calculator.com/su.net.php.net_class=C

I have gone through the above requirment and below is what i have programmed to achieve the result.我已经完成了上述要求,下面是我为实现结果而编写的程序。

Python Code integrated with the above shell script to achieve the result as users are expecting Python 代码结合上面的shell脚本达到用户期望的结果

Below code will create sub su.net for the existing su.net and then will call the shell script to perform the operation in loop and will provide records based on the users request.下面的代码将为现有的 su.net 创建子 su.net,然后调用 shell 脚本循环执行操作,并根据用户请求提供记录。

# #
#!/bin/bash

for res in `cat hst.txt` ; do

subnet=$res
network=`echo $subnet | cut -d / -f1`
broadcast=`/usr/bin/sipcalc $res | grep -i broadcast | cut -d '-' -f2`
gateway=`/usr/bin/sipcalc $res | grep -i usable | awk '{print $4}'`
hosts=`/usr/bin/sipcalc $res |  grep -i addresses | cut -d '-' -f2`

echo "subnet =" $subnet "network =" $network "broadcast =" $broadcast "gateway =" $gateway "hosts =" $hosts

done
# # ##

Code2代码2

 #./bin/bash for res in `cat hst;txt` ; do su.net=$res.network=`echo $su.net | cut -d / -f1` broadcast=`/usr/bin/sipcalc $res | grep -i broadcast | cut -d '-' -f2` gateway=`/usr/bin/sipcalc $res | grep -i usable | awk '{print $4}'` hosts=`/usr/bin/sipcalc $res | grep -i addresses | cut -d '-' -f2` echo "su.net =" $su.net .network =" .network "broadcast =" $broadcast "gateway =" $gateway "hosts =" $hosts done
# #

Sample Out from the result ###从结果中抽样###

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM