4

I'm working on a packet sniffer. The big problem is that my code works perfectly only under Backtrack 5 R3, but it doesn't work under other distributions! In fact, on Ubuntu 12.10 and ArchLinux, when the sniffer gets the first packet, I experience a segmentation fault (I get "segmentation fault core dumped"). At first, I thought the fault lay with the libraries or the compiler, but after some tests, I think I can exclude them! This is the situation:

  • Backtrack 5 R3 uses gcc 4.4.3 and libpcap 1.0.0
  • Ubuntu 12.10 uses Gcc 4.7.2 and Libpcap 1.3.0
  • ArchLinux the same as Ubuntu

So I tried to downgrade on Arch to gcc 4.4.3 e libpcap 1.0.0, but I get the same error. I have some warnings while compiling the code, but nothing really important, and however it works perfectly under backtrack! That's the big mystery.

Here's the code which cause the problem:

void packet_dump(unsigned char *arguments, const struct pcap_pkthdr *pcap_data, const unsigned char *packet) {
    int packet_data_len, tcp_header_size=0, total_header_size;
    unsigned char *packet_data;
    const unsigned char *ip_src_dest;
    const struct header_ip *ip_header; 

    //Calculate the value of variables
    ip_src_dest = (packet+LUNGHEZZA_INTESTAZIONE_ETH); 
    ip_header = (const struct header_ip *)ip_src_dest; 
    total_header_size = LUNGHEZZA_INTESTAZIONE_ETH+sizeof(struct header_ip)+tcp_header_size;
    packet_data = (unsigned char *)packet + total_header_size;  
    packet_data_len = pcap_data->len - total_header_size;

    //THIS CAUSE THE PROBLEM (Solved removing inet_ntoa and converting it manually)
    printf("[ %s ] ============> ", inet_ntoa(ip_header->source_addr_ip));
    printf("[ %s ]  \n", inet_ntoa(ip_header->destination_addr_ip));


}
Arbok
  • 63
  • 1
  • 8
  • 4
    Did you debug the segmentation fault? GDB is your friend. – Mark Nov 28 '12 at 17:15
  • 9
    *I have some warning while compiling the code but nothing really important* -- are you *sure* about that ? – Paul R Nov 28 '12 at 17:15
  • 1
    As @Mark said do a gdb to see where the segfault occured – 1-----1 Nov 28 '12 at 17:15
  • 1
    Did you run it as root on Ubuntu or Arch? I know Backtrack uses root login per default. – eminor Nov 28 '12 at 17:20
  • Yes i tried to use GDB and i understood that the program fails in packet_dump() function! In fact when i try to use it under Ubuntu and Arch it crash when it gets the first packet, so when the packet_dump function is called. However i think the warnings aren't important just because it works really fine under Backtrack... – Arbok Nov 28 '12 at 17:24
  • 9
    @Saitek: your logic is flawed when you assume that compiler warnings "aren't important" just because your code *happens to work in one particular environment* - read the warnings, understand them, and fix them! – Paul R Nov 28 '12 at 17:28
  • @Saitek Which line? As the function is nontrivial, it is hard to see where it could fail. – 1-----1 Nov 28 '12 at 17:33
  • @PaulR: I've fixed quite all warnings. The only warnings remaining are about printf formatting, and i doubt that they can cause segfault! – Arbok Nov 28 '12 at 17:39
  • @ks6g10: wait, i'll tell you – Arbok Nov 28 '12 at 17:39
  • @Saitek: mismatched printf format strings and arguments can very commonly cause segfaults and other problems - you should fix these warnings too. – Paul R Nov 28 '12 at 17:40
  • 3
    Warnings aren't just advice; they're generally trying to tell you something is potentially *very* wrong. Compile with `-Wall -Werror` at least, if not even more pedantic than that. – WhozCraig Nov 28 '12 at 17:41
  • @PaulR: ok wait...i'll try to do it for all warnings! – Arbok Nov 28 '12 at 17:43
  • 1
    printf can cause a segfault. you can just run `strace your_program args` and find out the last thing it does before the segfault – technosaurus Nov 28 '12 at 17:52
  • 1
    Don't forget to fix line 12 – eminor Nov 28 '12 at 17:55
  • 1
    Wait, i have some updates. I fixed quite everything, an i understood the problem is in inet_ntoa() function because fixing the other warnings, the programm works until it calls inet_ntoa, and there it crashes! I tried to comment the lines where i use inet_ntoa and it works even under arch and ubuntu...but i don't know how to solve this problem. I use %s and it gives me a warning, i tried to cast it, but it doesn't work, i tried to use %d but it doesn't print the right thing, but only numbers and not the ip address... @PaulR: thanks, and sorry. You were right about warnings. – Arbok Nov 28 '12 at 18:09
  • `inet_ntoa` returns a `char *`, so your format string needs a `%s` for this. – Paul R Nov 28 '12 at 18:14
  • I'm using %s...but there is a deeper problem. I'm not including the library of inet_ntoa() because, by default, it expects a in_addr struct. But in my code i'm using a different structure, created by me, written in sniffer-Protocols.h. It was a trick that seemed to work! But it create this big problem. In fact including the library of inet_ntoa(), which is arpa/inet.h, it gives an error because it expects a in_addr struct! – Arbok Nov 28 '12 at 18:19
  • Actually it seems i have solved it throught a walkaround...i have deleted inet_ntoa, and i print the content of the structure with %u. Obviously i don't get the ip address in a correct format, so now i'm trying to understand how to convert it in a correct format withouth using inet_ntoa :) – Arbok Nov 28 '12 at 18:26
  • Thanks to everybody guys! For who will come: I've solved the problem removing inet_ntoa, because it can't work with a structure different from in_addr. Instead of it i use a simple function, manually written, wich convert the string in ip address. – Arbok Nov 28 '12 at 18:39
  • 1
    @SaiT could you post your solution as an answer? – nairboon Dec 25 '12 at 17:41
  • Tip: Calculate the packet ip header size using the length indicator of the IP header, and not by sizeof() (sometimes there are ip options) – Guy L Jan 24 '13 at 07:57
  • @SaiT Always check your input pointers for NULL. Given that your dumping this whole packet, better safe than sorry. – Steve Lazaridis Jan 25 '13 at 16:07

1 Answers1

0

I suspect your program is crashing because ip_header->source_addr_ip points to memory that you're not allowed to access. You should be able to use GDB to determine whether this is the case.

splicer
  • 5,344
  • 4
  • 42
  • 47