编写一个bash脚本,将给定的子网细分为预定义数量的较小子网

时间:2017-06-08 05:40:36

标签: bash shell networking sh

最近在一次采访中提出了这个问题。

问题:编写一个bash脚本,将给定的子网细分为预定义数量的较小子网。

分割后IP地址不应该被浪费,即你的细分的累积应该构成划分的子网。

每个子网都有3个IP地址保留,主机无法使用:网络,广播,网关。

显示网络/广播地址,主机数量和分配网关。网关应该是划分子网中的第一个IP可用。示例:

INPUT:./subnetter.sh 192.168.0.0/24 3

输出:

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:./subnetter.sh 192.168.0.0/24 4

输出:

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:./subnetter.sh 10.55.10.64/28 2

输出:

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

首先,我试图分析用于划分子网的逻辑。 其次,我试图使用ipcalc命令获取输出但没有运气。

由于

3 个答案:

答案 0 :(得分:0)

我相信我已经完成了70%的脚本需要的东西。由于您使用的是ipcalc,因此专门使用类似的二进制文件。首先,请执行以下操作:

yum install sipcalc如果您有基于RPM的操作系统或apt-get install sipcalc,具体取决于Linux操作系统的发行版。

然后编写以下脚本并将其保存为subnetter.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




我的剧本输出:



[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




请注意,第三个参数的要求非常简单,可以使用for循环简单地完成。我希望你这样做。

您可以使用以下工具确保输出正确:http://www.subnet-calculator.com/subnet.php?net_class=C

此致

Rohan Dsouza

答案 1 :(得分:0)

我已经完成了上述要求,下面是我编程实现的结果。

Python代码与上面的shell脚本集成,以实现用户期望的结果

下面的代码将为现有子网创建子子网,然后调用shell脚本来执行循环操作,并根据用户请求提供记录。

from netaddr import *
import ipaddress
import csv
import subprocess
import os
import shlex
import sys
import numpy as np
from itertools import islice


if os.path.exists('hst.txt'):
    os.remove('hst.txt')
else:
    print("Sorry, I can not remove " )

if os.path.exists('hst_refined.txt'):
    os.remove('hst_refined.txt')
else:
    print("Sorry, I can not remove " )




fd = open('store_subnet',"w")
enter_subnet = raw_input('Enter subnet please: ')
fd.write(enter_subnet)


fd = open('store_sub_subnet',"w")
sub_subnet = raw_input('Enter nested_subet_count: ')
fd.write(sub_subnet)





ip=ipaddress.ip_network(unicode(enter_subnet))


list_demo = list(ip.subnets(int(sub_subnet)))

for i in  list_demo:
    hs = open("hst.txt","a")
    hs.write(str(i))
    hs.write("\n")
    hs.close()



p =  subprocess.Popen([ "/home/ramkumar5/network_cal/report_demo.sh" ], stdout=subprocess.PIPE).communicate()[0]
for i in p:
    hs =  open("hst_refined.txt","a")
    hs.write(i)
    hs.close()



print(sub_subnet)




records_req = raw_input('Enter Number of Records needed: ')
f=open("hst_refined.txt")
for i in xrange(int(records_req)):
    line=f.next().strip()
    print line
f.close()
# #

代码2

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

Sample Out from the result ###

答案 2 :(得分:0)

这是bash脚本,我已经尝试过: 应该工作正常。该脚本有两个参数,CIDR块和要划分的子网数。

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