packet sniffing with pcap segmentation error

136 views Asked by At

** I'm trying to write a packet sniffing program in c and i encountered the problem of segmentation error..this is my first time to code a packet sniffer. In addition I am new to linux and debugging with gdb. So please,I would like you to give me some answers so that I can improve myself. Here is my code:**

#include <stdio.h>
#include <pcap.h>
int main (int argc, char * argv [])
{pcap_t * handle;
struct bpf_program fp;
bpf_u_int32 mask;
bpf_u_int32 net;
struct pcap_pkthdr header;
const u_char * package;
char errbuf [PCAP_ERRBUF_SIZE];
char filter_exp [] = "port 23";
int i = 0;
pcap_if_t * interface = NULL;
char * dev;
if (pcap_findalldevs (& interface, errbuf) <0)
{printf ("\ n Error in pcap alldev");
return 2;
}
printf ("\ n the interfaces present on the system");
pcap_if_t * temp = interface;
while (temp)
{printf ("\ n% d:% s", i, temp-> name);
temp = temp-> next;
i ++;
}
printf ("\ nchoose a device for reniflage: \ n");
scanf ("% s", dev);
if (pcap_lookupnet (dev, & net, & mask, errbuf) == - 1) / * find device properties * /
{fprintf (stderr, "could not get device netmask:% s \ n", dev, errbuf);
net = 0;
mask = 0;
}
handle = pcap_open_live (dev, BUFSIZ, 1,1000, errbuf);
if (handle == NULL)
{fprintf (stderr, "could not open device% s \ n", package, errbuf);
return (2);
}
/ * compile and apply the filter * /
if (pcap_compile (handle, & fp, filter_exp, 0, net) == - 1)
{fprintf (stderr, "cannot install filter% s:% s \ n", filter_exp, pcap_geterr (handle));
return (2);
}
/ * enter the package * /
package = pcap_next (handle, & header);
printf ("its length is: [% d] \ n", header.len);
pcap_close (handle);
return (0);
}
  • when i run my code, it stops just after the scanf. and when i use gdb i get this:*

          Program received signal SIGSEGV, Segmentation fault.
      __vfscanf_internal (s=<optimized out>, format=<optimized out>, 
          argptr=argptr@entry=0x7fffffffdf20, mode_flags=mode_flags@entry=2)
          at vfscanf-internal.c:1100
      1100    vfscanf-internal.c: Aucun fichier ou dossier de ce type.
      (gdb) where
      #0  __vfscanf_internal (s=<optimized out>, format=<optimized out>, 
          argptr=argptr@entry=0x7fffffffdf20, mode_flags=mode_flags@entry=2)
          at vfscanf-internal.c:1100
      #1  0x00007ffff7dfe18e in __isoc99_scanf (format=<optimized out>)
          at isoc99_scanf.c:30
      #2  0x00005555555552ce in main (argc=1, 
          argv=0x7fffffffe278 "J\345\377\377\377\177") at analyser.c:27
    
1

There are 1 answers

0
user16139739 On

when i run my code, it stops just after the scanf

It stops inside scanf(). Apparently, on the platform on which you're running this, calls to scanf() are compiled into calls to a routine named __isoc99_scanf(), which presumably means it's a version of scanf() that conforms to the ISO C99 standard.

So this isn't a problem with libpcap; it's a problem with the way you're using scanf().

C makes it easy to get confused about pointer arguments to functions. If you say

char * dev;

and do not assign a value to dev, dev doesn't point to anything.

This means that if you do

scanf ("% s", dev);

then you are not passing a pointer to a buffer as the second argument to scanf().

In this case, scanf() expects you to pass it a pointer a buffer into which it will put the string matched by % s. You have not done so, but the code assumes you have done so, so it might try to put the string into a random location in the address space of your program - or into a location that's not in the address space of your program, causing a segmentation fault.

A pointer to a buffer isn't necessarily a variable of the type char *. If, for example, you do

char dev[2048+1]; /* "+1" for the terminating '\0' */

and then do

scanf("% s", dev);

then you are passing an expression of the type char * as the second argument to scanf(); in most places in C, a reference to an array is converted to a pointer to the first element of the array.

Your format is also incorrect. First of all, there should not be a space between the "%" and "s" - it should be more like "%s".

Second of all, you want to make sure that, if the user types a very long string, they don't overflow the buffer you've provided, so you should do something such as "%2048s".