一、需求

在写某个脚本时,需要用到使用该网段的任一地址,加上掩码位就可以计算出该网段所有的地址。再结合fping可以获取该网段内所有未被使用的地址。该需求实现时会涉及到各种计算,比较麻烦。所以先放G网上检索下有没有可以直接“拿来的”代码。找了几个代码,必须都是先给出第一个IP ,再加上掩码位才能计算出所有的IP,如果取中间的IP就不灵了。后来找了一段大牛写的C代码,发现比较好用,刚好符合要求。

二、代码及需求实现

代码如下:

 1#include <stdio.h>
 2#include <string.h>
 3#include <stdlib.h>
 4#include <arpa/inet.h>
 5static void ip_mask(char *net, int *netmask) {
 6        char *p;
 7        if ((p = strchr(net, '/')) != NULL)
 8                *p = '\0';
 9        *netmask = atoi(p+1);
10}
11static void dton(u_int32_t mask, u_int32_t *netmask) {
12        u_int32_t i, c;
13        int bits = sizeof(u_int32_t) * 8;
14        i = ~0;
15        bits -= mask;
16        i = i << bits;
17        *netmask = htonl(i);
18}
19int main(int argc, char **argv) {
20        int err = 0;
21        char ip[32] = {0};
22        u_int32_t mask, netmask;
23        struct in_addr ipadd, subnet, broadcast;
24        if (argc >= 2) {
25                strncpy(ip, argv[1], sizeof(ip)-1);
26        } else {
27                fprintf(stderr, "Usage: %s <ip/mask>\n", argv[0]);
28                exit(1);
29        }
30        ip_mask(ip, &mask);
31        if (!(err = inet_aton(ip, &ipadd))) {
32                fprintf(stderr, "IP type error!\n");
33                exit(2);
34        }
35        if (mask > 32 || mask < 1) {
36                fprintf(stderr, "Mask is out of range!\n");
37                exit(3);
38        }
39        dton(mask, &netmask);
40        subnet.s_addr = ipadd.s_addr & netmask;
41        broadcast.s_addr = ~ (subnet.s_addr ^ netmask);
42        printf ("%s - ", inet_ntoa(subnet));
43        printf ("%s\n", inet_ntoa(broadcast));
44        return 0;
45}

代码保存为net2ip.c ,编译运行,结果如下:

1[root@361way ~]# gcc net2ip.c -o net2ip
2[root@361way ~]# ./net2ip 192.168.1.100/24
3192.168.1.0 - 192.168.1.25

使用fping -g可以对一个网段进行ping并获取到未被使用的地址,不过fping使用的网段不要中间的“-” ,C代码略作作改,再编译下。最络实现的结果如下:

1[root@361way ~]# fping -g $(echo `./netip  10.211.89.229/26`)|grep 'unreachable'
210.211.89.196 is unreachable
310.211.89.197 is unreachable
410.211.89.198 is unreachable
510.211.89.201 is unreachable
610.211.89.202 is unreachable
710.211.89.205 is unreachable