最近在从ip 数据包中获取源IP时,由于源IP是一个unsigned int的32位整数,而且内核中无法调用inet_aton函数,所以需要自己编程,将ip字符串转换成32位的整数。
初步想想,写出一个原型:
unsigned int ip_str_to_num(const char *buf)
{
unsigned int tmpip[4] = {0};
unsigned int tmpip32 = 0;
unsigned char *uip = (unsigned char*)&tmpip32;
sscanf(buf, "%d.%d.%d.%d", &uip[0], &uip[1], &uip[2], &uip[3]);
return tmpip32;
}
上面的代码在用户态编译运行完全正确,但是在内核态编译时,遇到一个报警,sscanf对应%d要求输入一个(int *)的参数,但是却得到一个(unsigned char*)的参数,所以编译器警告。将代码经过改进如下:
unsigned int ip_str_to_num(const char *buf)
{
unsigned int tmpip[4] = {0};
unsigned int tmpip32 = 0;
sscanf(buf, "%d.%d.%d.%d", &tmpip[0], &tmpip[1], &tmpip[2], &tmpip[3]);
tmpip32 = (tmpip[3]<<24) | (tmpip[2]<<16) | (tmpip[1]<<8) | tmpip[0];
return tmpip32;
}
改进过的代码效率要低些,但是消除了告警。
反之,将整数转换为字符串,则要简单许多,代码如下:
#define IP_LEN 17
static inline void ip_num_to_str(unsigned int ip_num, char *ip_str)
{
unsigned char * uip = (unsigned char *)&ip_num;
snprintf(ip_str, IP_LEN , "%d.%d.%d.%d", uip[0], uip[1], uip[2], uip[3]);
}