两个IP的比较

时间:2014-05-24 17:08:27

标签: c linux comparison ip-address kernel-module

我需要比较两个IP。一个IP以u8格式存储,我设法将其转换为char *,我将其存储在变量arp_tbuf中。但是,要比较的第二个IP是u32格式(来自ip.h)。但每当我尝试将u32格式的IP转换为char *时,如下所示,

    unsigned int pkt_da = (unsigned int)ip_header->daddr;   
    char pkt_tbuf[16];
    char pkt_tbuf_tmp[4];

    pkt_tbuf_tmp[0] = pkt_da & 0x000000FF;
    pkt_tbuf_tmp[1] = (pkt_da & 0x0000FF00) >> 8;
    pkt_tbuf_tmp[2] = (pkt_da & 0x00FF0000) >> 16;
    pkt_tbuf_tmp[3] = (pkt_da & 0xFF000000) >> 24;  
    sprintf(pkt_tbuf, "%d.%d.%d.%d\n", pkt_tbuf_tmp[0], pkt_tbuf_tmp[1], pkt_tbuf_tmp[2], pkt_tbuf_tmp[3]);

我收到kernel panic错误。

我知道要与字符进行比较的功能memcmp

如果您的专家帮助我将此IP转换为char *来比较两个IP ,例如memcmp(arp_tbuf, pkt_tbuf),那将是一个很好的帮助。

非常感谢:)

修改

正如@BobJarvis建议的那样,我在我的内核中再次运行代码。 IT在转换局域网中的IP方面运行良好。但是,当我加载网页时,发生了kernel panic错误。我有一种更简洁的方法来执行从unsigned intchar *(点分IP格式)的IP转换吗?

2 个答案:

答案 0 :(得分:2)

我相信你遇到的问题是值(IP的任何2字节部分)超过127. >>运算符是算术移位(符号保留)移位而不是逻辑转变。 (见 Shift operator in C )。您可以使用pkt_da = 0x7f7f7f7fpkt_da = 0x80808080的简单测试在代码中看到这一点。使用以下方法打印值:

for (it = 0; it < 4; it++)
    printf ("  pkt_tbuf_tmp[%2d]: %u\n", it, pkt_tbuf_tmp[it]);

给出:

./bin/pktb 2139062143
pkt_tbuf_tmp[ 0]: 127
pkt_tbuf_tmp[ 1]: 127
pkt_tbuf_tmp[ 2]: 127
pkt_tbuf_tmp[ 3]: 127
Done - pkt_tbuf='127.127.127.127'

./bin/pktb 2155905152
pkt_tbuf_tmp[ 0]: 4294967168
pkt_tbuf_tmp[ 1]: 4294967168
pkt_tbuf_tmp[ 2]: 4294967168
pkt_tbuf_tmp[ 3]: 4294967168
Done - pkt_tbuf='-128.-128.-128.-128'

右移行为取决于编译器。那么什么在一个盒子上工作,可能不在另一个系统上。

答案 1 :(得分:0)

根据@ DavidC.Rankin给出的解释,我能够缩小范围并寻找更多解决方案。因此,我发现了一个类似的帖子,它解决了将int IP转换为点IP的问题, Convert source IP address from struct iphdr* to string equivalent using Linux netfilter

然后我刚刚执行了memcmp()

int cmp;
cmp=memcmp ( arp_tbuf, pkt_tbuf, sizeof(arp_tbuf) );

if((cmp > 0) || (cmp < 0)){
    printk(KERN_ALERT "Not matching");              
}

感谢专家帮助我理解这个问题。 :)