当前位置:   article > 正文

由子网掩码字符串转换成长度前缀的代码示例_子网掩码转换前缀长度

子网掩码转换前缀长度

最近在进行的ONVIF任务,有一个接口是设置IP的,叫SetNetworkInterfaces,可以设置包括网络速率、双工、自动协商等功能,还可以改IP。但里面有子网掩码字段,只有一个叫PrefixLenght的,直译为前缀长度。具体如下:

IPv4 - optional; [IPv4NetworkInterfaceSetConfiguration]
IPv4 network interface configuration.
 Enabled - optional; [boolean]
             Indicates whether or not IPv4 is enabled.
Manual - optional, unbounded; [PrefixedIPv4Address]
             List of manually added IPv4 addresses.
 Address [IPv4Address]
                     IPv4 address
PrefixLength [int]
                     Prefix/submask length

PrefixLength就是子网掩码的长度。比如子网掩码为“255.255.0.0”,则PrefixLength为16。为了做转换,特意写了2个函数。

1、由子网掩码算出前缀长度

  1. int ipv4_str2prefixlen(const char* ip_str)
  2. {
  3. int ret = 0;
  4. unsigned int ip_num = 0;
  5. unsigned char c1,c2,c3,c4;
  6. int cnt = 0;
  7. ret = sscanf(ip_str, "%hhu.%hhu.%hhu.%hhu", &c1, &c2, &c3, &c4);
  8. ip_num = c1<<24 | c2<<16 | c3<<8 | c4;
  9. // fast...
  10. if (ip_num == 0xffffffff) return 32;
  11. if (ip_num == 0xffffff00) return 24;
  12. if (ip_num == 0xffff0000) return 16;
  13. if (ip_num == 0xff000000) return 6;
  14. // just in case
  15. for (int i = 0; i < 32; i++)
  16. {
  17. //unsigned int tmp = (ip_num<<i);
  18. //printf("%d tmp: %x\n", i+1, tmp);
  19. if ((ip_num<<i) & 0x80000000)
  20. cnt++;
  21. else
  22. break;
  23. }
  24. //printf("cnt: %d\n", cnt);
  25. return cnt;
  26. }

2、由前缀长度算出子网掩码

  1. int ipv4_prefixlen2str(int prefixlen, char* ip_str)
  2. {
  3. char tmp[16] = {0};
  4. char* p = tmp;
  5. unsigned int ip_num = 0;
  6. if (ip_str == NULL) return -1;
  7. if (prefixlen > 32) return -1;
  8. // fast...
  9. if (prefixlen == 8) strcpy(ip_str, "255.0.0.0");
  10. if (prefixlen == 16) strcpy(ip_str, "255.255.0.0");
  11. if (prefixlen == 24) strcpy(ip_str, "255.255.255.0");
  12. if (prefixlen == 32) strcpy(ip_str, "255.255.255.255");
  13. // just in case
  14. for (int i = prefixlen, j = 31; i > 0; i--, j--)
  15. {
  16. //unsigned int tmp = (1<<j);
  17. //printf("%d tmp: %08x\n", i, tmp);
  18. ip_num += (1<<j);
  19. }
  20. //printf("ip_num: %08x\n", ip_num);
  21. sprintf(ip_str, "%hhu.%hhu.%hhu.%hhu", (ip_num>>24)&0xff, (ip_num>>16)&0xff, (ip_num>>8)&0xff, ip_num&0xff);
  22. return 0;
  23. }
几点说明如下:

1、内部功能函数一般不作严格、详细的参数验证,比如IP的合法性没作检查。

2、一些常用的、已知的常识,应该优先使用,比如,我们知道“255.255.0.0”的前缀长度是16,则可以直接写出来,不再做转换。

3、最近搞ONVIF,真正认识到存储空间和运行时效率。在嵌入式中,flash有限,所以存储空间也要注意,用gsoap生成的ONVIF代码比较大,即使使用-O3优化并strip,也有10MB,真的很占空间。另外,有些功能模块可以统一在一处作参数合法性判断而不用每个函数都做。比如上面的示例代码就不用IP合法性判断,因此我调用之前已经做了,这样可以节省一些运行时的指令代码。不过,我们公司架构因为分层级关系,基本上经过review后的代码,每一层都有参数的检查。从效率上看,我依然坚持能省即省的原则。


李迟 2016.01.24 于加班回来晚饭前 (听说南宁青秀山下雪了,今天去加班的我的世界也开始下雪)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/518668
推荐阅读
相关标签
  

闽ICP备14008679号