赞
踩
最近在进行的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、由子网掩码算出前缀长度
- int ipv4_str2prefixlen(const char* ip_str)
- {
- int ret = 0;
- unsigned int ip_num = 0;
- unsigned char c1,c2,c3,c4;
- int cnt = 0;
-
- ret = sscanf(ip_str, "%hhu.%hhu.%hhu.%hhu", &c1, &c2, &c3, &c4);
- ip_num = c1<<24 | c2<<16 | c3<<8 | c4;
-
- // fast...
- if (ip_num == 0xffffffff) return 32;
- if (ip_num == 0xffffff00) return 24;
- if (ip_num == 0xffff0000) return 16;
- if (ip_num == 0xff000000) return 6;
-
- // just in case
- for (int i = 0; i < 32; i++)
- {
- //unsigned int tmp = (ip_num<<i);
- //printf("%d tmp: %x\n", i+1, tmp);
- if ((ip_num<<i) & 0x80000000)
- cnt++;
- else
- break;
- }
-
- //printf("cnt: %d\n", cnt);
- return cnt;
- }
2、由前缀长度算出子网掩码
- int ipv4_prefixlen2str(int prefixlen, char* ip_str)
- {
- char tmp[16] = {0};
- char* p = tmp;
- unsigned int ip_num = 0;
-
-
- if (ip_str == NULL) return -1;
- if (prefixlen > 32) return -1;
-
-
- // fast...
- if (prefixlen == 8) strcpy(ip_str, "255.0.0.0");
- if (prefixlen == 16) strcpy(ip_str, "255.255.0.0");
- if (prefixlen == 24) strcpy(ip_str, "255.255.255.0");
- if (prefixlen == 32) strcpy(ip_str, "255.255.255.255");
-
-
- // just in case
- for (int i = prefixlen, j = 31; i > 0; i--, j--)
- {
- //unsigned int tmp = (1<<j);
- //printf("%d tmp: %08x\n", i, tmp);
- ip_num += (1<<j);
- }
- //printf("ip_num: %08x\n", ip_num);
- sprintf(ip_str, "%hhu.%hhu.%hhu.%hhu", (ip_num>>24)&0xff, (ip_num>>16)&0xff, (ip_num>>8)&0xff, ip_num&0xff);
-
-
- return 0;
- }
几点说明如下:
1、内部功能函数一般不作严格、详细的参数验证,比如IP的合法性没作检查。
2、一些常用的、已知的常识,应该优先使用,比如,我们知道“255.255.0.0”的前缀长度是16,则可以直接写出来,不再做转换。
3、最近搞ONVIF,真正认识到存储空间和运行时效率。在嵌入式中,flash有限,所以存储空间也要注意,用gsoap生成的ONVIF代码比较大,即使使用-O3优化并strip,也有10MB,真的很占空间。另外,有些功能模块可以统一在一处作参数合法性判断而不用每个函数都做。比如上面的示例代码就不用IP合法性判断,因此我调用之前已经做了,这样可以节省一些运行时的指令代码。不过,我们公司架构因为分层级关系,基本上经过review后的代码,每一层都有参数的检查。从效率上看,我依然坚持能省即省的原则。
李迟 2016.01.24 于加班回来晚饭前 (听说南宁青秀山下雪了,今天去加班的我的世界也开始下雪)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。