0

I am required to compare two IPs. One IP is stored in u8 format where I managed to convert it to char * which i stored in the variable arp_tbuf. However, the second IP to be compared is in u32 format (from ip.h). But every time I try to convert the IP in u32 format to char * as follows,

    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]);

I get a kernel panic error.

I am aware of the functionality memcmp to compare to characters.

It would be a great help if you experts would help me in converting this IP to char * and to compare the two IP's like memcmp(arp_tbuf, pkt_tbuf).

Thank you very much :)

EDIT

As @BobJarvis suggested, I ran the code again in my kernel. IT worked fine for converting the IPs in the LAN. However, When I loaded the web page, the kernel panic error occured. I there a cleaner way to perform this IP conversion from unsigned int into char * (dotted IP format) ?

Hasitha Shan
  • 2,900
  • 6
  • 42
  • 83

2 Answers2

2

I believe you are running into problems with values (any 2 byte part of the IP) exceeding 127. The >> operator is an arithmetic shift (sign preserving) shift and not a logical shift. (see Shift operator in C ). You can see this in your code with simple tests of pkt_da = 0x7f7f7f7f and pkt_da = 0x80808080. Printing the values with:

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

Gives:

./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'

The right-shift behavior is compiler dependent. So what works on one box, may not on another system.

Community
  • 1
  • 1
David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
0

With the explanation give by @DavidC.Rankin I was able to narrow down and look for more solution. Thus, I found a similar post which solved the question of Converting the int IP to dotted IP, Convert source IP address from struct iphdr* to string equivalent using Linux netfilter

Then I just performed a memcmp()

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

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

Thank you experts for the assistance in helping me understand the issue. :)

Community
  • 1
  • 1
Hasitha Shan
  • 2,900
  • 6
  • 42
  • 83