Chinaunix首页 | 论坛 | 博客
  • 博客访问: 561083
  • 博文数量: 375
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 15
  • 用 户 组: 普通用户
  • 注册时间: 2013-09-20 10:21
文章分类

全部博文(375)

文章存档

2015年(1)

2014年(374)

分类: LINUX

2014-08-18 14:01:12


  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <arpa/inet.h>

  5. static void ip_mask(char *net, int *netmask) {
  6.     char *p;

  7.     /* 找出第一个'/'所在字符串中的位置,截断,
  8.      前面的字符串作为点分十进制的IP地址,
  9.      后面的子网掩码转换为整形 */
  10.     if ((p = strchr(net, '/')) != NULL)
  11.         *p = '\0';
  12.     *netmask = atoi(p+1);
  13. }

  14. static u_int32_t dton(u_int32_t mask) {
  15.     u_int32_t i, c;
  16.     int bits = sizeof(u_int32_t) * 8;

  17.     i = ~0;
  18.     bits -= mask;
  19.     /* 让32位全是1的无符号数与左移bits位(右移位用0填充)得出子网掩码 */
  20.     i <<= bits;

  21.     return htonl(i);
  22. }

  23. int main(int argc, char **argv) {
  24.     int err = 0;
  25.     char ip[32];
  26.     char filename[128] = {0};
  27.     char line[128] = {0};
  28.     u_int32_t mask, netmask;
  29.     struct in_addr ipadd, subnet, broadcast;
  30.     FILE *in, *out;
  31.     int len = 0;

  32.     if (argc >= 2) {
  33.         strncpy(filename, argv[1], sizeof(filename)-1);
  34.     } else {
  35.         fprintf(stderr, "Usage: %s \n", argv[0]);
  36.         exit(1);
  37.     }
  38.     
  39.     if((in = fopen(filename, "r")) == NULL)
  40.         printf("%s open failure!\n", filename), exit(-1);

  41.     if((out = fopen("ip_out.txt", "w")) == NULL)
  42.         printf("%s open failure!\n", filename), exit(-1);
  43.     

  44.     while((fgets(ip, 32, in)) != NULL) {

  45.         ip_mask(ip, &mask);

  46.         if (!(err = inet_aton(ip, &ipadd))) {
  47.             fprintf(stderr, "IP type error!\n");
  48.             exit(2);
  49.         }

  50.         if (mask > 32 || mask < 1) {
  51.             fprintf(stderr, "Mask is out of range!\n");
  52.             exit(3);
  53.         }

  54.         netmask = dton(mask);

  55.         /* 网络地址=主机地址和掩码的与运算 */
  56.         subnet.s_addr = ipadd.s_addr & netmask;
  57.         /* 广播地址=网络地址和掩码的同或运算(C语言中没有同或运算, 用异或取反)*/
  58.         broadcast.s_addr = ~(subnet.s_addr ^ netmask);

  59.         /* 因为inet_ntoa函数不可重入,需要两次构建这个字符串
  60.          len为第一次构建的偏移位,第二次构建字符串时跳过这个偏移位
  61.          相应写入长度也减少这个偏移位长度 */
  62.         len = snprintf (line, sizeof(line), "%s - ", inet_ntoa(subnet));
  63.         snprintf (line + len, sizeof(line) - len, "%s\n", inet_ntoa(broadcast));
  64.         fputs(line, out);
  65.     
  66.     }
  67.     fclose(in);
  68.     fclose(out);
  69.     return 0;
  70. }




阅读(999) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~