我有一个文件存储了我为 VPN 客户端设置的上次使用的本地 IP 地址。我正在自动执行添加新客户端的过程,因此我想读取用于上一个客户端的 IP,并增加用于下一个客户端的地址。
然而,这对于所使用的子网来说必须是敏感的。我将 /8 子网用于 10.0.0.0 RFC 1918 专用网络。
因此,假设最后一个客户端的 IP 是 10.0.0.5。增加后,我应该得到 10.0.0.6。
当最后一个客户端 IP 达到 10.0.0.254 时,我们不应增加到 10.0.0.255,而是应该获取 10.0.1.1,依此类推。由于子网提供了除前导字节 (10.) 之外的所有八位字节供客户端使用,因此我们应该对整个范围采用这种方式,例如:
10.0.1.254 之后 -> 10.0.2.1
10.0.254.254 之后 -> 10.1.0.1
我正在寻找最简单的方法来做到这一点。这可以用一个衬垫来完成吗?
答案1
如果您允许有效的 IP 地址,例如 ,10.0.1.0/8
那么10.0.255.255/8
您可以使用单调递增的 32 位整数,如下所示
# Seed with 10.0.0.0 = 167772160
echo $(( (10<<24) + (0<<16) + (0<<8) + 0 )) >counter
# Read the counter, increment, and produce IP address
read ip <counter
echo $((++ip)) >counter
printf "%d.%d.%d.%d\n" $(( (ip>>24)&255 )) $(( (ip>>16)&255 )) $(( (ip>>8)&255 )) $((ip&255))
答案2
我看不出一种方法可以在一个行中完成它,但这可以通过if
子句和模算术来完成。
类似这样的事情:
a = 2nd octet
b = 3rd octet
c = 4th octet
if ( mod(c+1, 255) == 0)
if (mod(b+1, 255) == 0)
if (mod(a+1, 255) == 0)
print "sorry, out of IP numbers"
end
b = 0
a = a+1
continue
c = 0
b = b+1
else
c = c+1
print 10.a.b.c
未经测试,持保留态度。
答案3
我喜欢使用 read 来分隔八位字节:
IFS='.' read -r a b c d <<< 10.0.0.0
ip=$(((a<<24)+(b<<16)+(c<<8)+d))
((ip++))
printf "%d.%d.%d.%d\n" $(((ip>>24)&255)) $(((ip>>16)&255)) $(((ip>>8)&255)) $((ip&255))