Welcome to the MacNN Forums.

If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below.

You are here: MacNN Forums > Software - Troubleshooting and Discussion > Developer Center > Creating a sniffer app (Using libpcap)

Creating a sniffer app (Using libpcap)
Thread Tools
Syphor
Junior Member
Join Date: Jul 2002
Location: Australia
Status: Offline
Reply With Quote
Nov 14, 2004, 12:50 AM
 
Hey all,
I'm having trouble with the following program. I want to be able to spy on my net-device (ppp0) and see all incoming and outgoing connection... just the IPs for now. Technically its working though its printing the same destination and source IPs.

Here is the code:

Code:
#include <pcap.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netinet/ip.h> int main() { pcap_t *handle; /* Session handle */ char *dev; /* The device to sniff on */ char errbuf[PCAP_ERRBUF_SIZE]; /* Error string */ struct pcap_pkthdr header; /* The header that pcap gives us */ const u_char *packet; /* The actual packet */ const struct ip *ip; /* The IP header */ int x; /* Loop Counter */ /* Define the device */ dev = "ppp0"; /* Open the session in promiscuous mode */ handle = pcap_open_live(dev, BUFSIZ, 1, 0, errbuf); for (x=0; x<10; x++) { /* Grab a packet */ packet = pcap_next(handle, &header); /* Set variables from packet data */ ip = (struct ip*)(packet); /* Print the packet's info */ printf("------------------------------------------------\n"); printf("Recieved a packet with length of [%d]\n", header.len); printf("Source IP:\t%s\nDestination IP:\t%s\n", inet_ntoa(ip->ip_src), inet_ntoa(ip->ip_dst) ); } /* And close the session */ pcap_close(handle); return(0); }
I'm running Mac OS 10.3.6 ( Darwin Kernel Version 7.6.0: root:xnu/xnu-517.9.4.obj~1/RELEASE_PPC )

You need to be the root user to run this program.

I'm compiling this the following way:
Code:
cc <filename> -o <program name> -l pcap
     
Syphor  (op)
Junior Member
Join Date: Jul 2002
Location: Australia
Status: Offline
Reply With Quote
Oct 25, 2005, 12:35 PM
 
just under a year later and I still haven't figured out the prob... any help would be appreciated
     
Syphor  (op)
Junior Member
Join Date: Jul 2002
Location: Australia
Status: Offline
Reply With Quote
Jul 29, 2006, 09:55 PM
 
Now nearly 2 years and no luck :P

Here's my re-write:

Code:
- (void) awakeFromNib { /* Authenticate */ [self authenticate]; /* Start a new thread */ [NSThread detachNewThreadSelector:@selector(theSniffer) toTarget:self withObject:nil]; } - (void) theSniffer { /* For the thread's auto release pool */ NSAutoreleasePool *apool=[[NSAutoreleasePool alloc] init]; pcap_t *handle; /* Session handle */ char *dev; /* The device to sniff on */ struct pcap_pkthdr header; /* The header that pcap gives us */ const u_char *packet; /* The actual packet */ char errbuf[PCAP_ERRBUF_SIZE]; /* Error string */ struct ip *_ip; /* The IP header */ int x; /* Loop Counter */ NS_DURING /* Define the device */ dev = "en0"; /* Open the session in promiscuous mode */ handle = pcap_open_live(dev, BUFSIZ, 1, 0, errbuf); for (x=0; x<5; x++) { /* Grab a packet */ packet = pcap_next(handle, &header); /* Set variables from packet data */ _ip = (struct ip*)(packet + 14); // The +14 is the size of the ethernet frame /* Print the packet's info */ [sniffOutput insertText:[NSString stringWithString:@"------------------------------------------------\n"]]; [sniffOutput insertText:[NSString stringWithFormat:@"Recieved a packet with length of [%d]\n", header.len]]; [sniffOutput insertText:[NSString stringWithFormat:@"Source IP:\t%s\nDestination IP:\t%s\n", inet_ntoa(ip->ip_src), inet_ntoa(ip->ip_dst)]]; } /* And close the session */ pcap_close(handle); NS_HANDLER NS_ENDHANDLER /* Release the autorelease pool */ [apool release]; } - (void) authenticate { // To Do }
P.S. You'll need to run this program as root or using an Administrator account
     
ptoomey3
Fresh-Faced Recruit
Join Date: Jun 2003
Status: Offline
Reply With Quote
Aug 6, 2006, 11:38 AM
 
So, I have no access to a ppp device and I don't know objective-c, so I started with the code you posted initially. First, I don't know what is returned from a pcap_next with ppp, but with normal devices you receive back the packet starting at the ethernet header, not the IP header. I don't know if ppp would start you at a ppp header or not, but you need to take this into account. The second thing, and perhaps the more important thing, is your problem with the same source and destination addresses. I played around a bit, got the same results, and thought about it for second. I had no experience with libpcap before, but the calls to inet_ntoa both return a char*. The most common way for something like this to be implemented would be a static char array within inet_ntoa. Thus, each successive call to the function will overwrite the value from the prior call. THus, in your print statement you call it for ip_src which returns a char*, then you call it on ip_dst. This will also return a char*, and in fact it will be the same char* as the first call (because of the use of a static array for storge). Anyway, the solution to this is to make use of each call distinct. I modified your code to work with an ethernet card, but minor modifications should fix the ppp case as well. My changes include included:

1. including the <net/ethernet.h> header
2. adding a variable for the ethernet header struct ether_header
3. appropriately setting the ip header to packet + sizeof(struct ether_header)
4. making two separate calls to printf when calling inet_ntoa


Code:
#include <pcap.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netinet/ip.h> #include <net/ethernet.h> int main() { pcap_t *handle; /* Session handle */ char *dev; /* The device to sniff on */ char errbuf[PCAP_ERRBUF_SIZE]; /* Error string */ struct pcap_pkthdr header; /* The header that pcap gives us */ const u_char *packet; /* The actual packet */ const struct ip *ip; /* The IP header */ int x; /* Loop Counter */ const struct ether_header *eth; /* The Ethernet Header */ /* Define the device */ dev = "en1"; /* Open the session in promiscuous mode */ handle = pcap_open_live(dev, BUFSIZ, 1, 0, errbuf); for (x=0; x<10; x++) { /* Grab a packet */ packet = pcap_next(handle, &header); /* Set variable to ethernet header*/ eth = (struct ether_header*)(packet); /* Set variables from packet data */ ip = (struct ip*)(packet + sizeof(struct ether_header)); /* Print the packet's info */ printf("------------------------------------------------\n"); printf("Recieved a packet with length of [%d]\n", header.len); printf("Source IP \t%s\n", inet_ntoa(ip->ip_src)); printf("Dest IP \t%s\n", inet_ntoa(ip->ip_dst)); } /* And close the session */ pcap_close(handle); return(0); }
( Last edited by ptoomey3; Aug 6, 2006 at 11:45 AM. )
Patrick
     
ptoomey3
Fresh-Faced Recruit
Join Date: Jun 2003
Status: Offline
Reply With Quote
Aug 6, 2006, 11:52 AM
 
Ok, so I should have looked at your objective-c version, as it didn't really matter if I knew objetive-c or not to fix the problem. It looks like you already account for the ethernet header with the
Code:
_ip = (struct ip*)(packet + 14); // The +14 is the size of the ethernet frame
I would get rid of the 14 though and use the real struct. Anyway, you can fix your problem with changing

Code:
[sniffOutput insertText:[NSString stringWithFormat:@"Source IP:\t%s\nDestination IP:\t%s\n", inet_ntoa(ip->ip_src), inet_ntoa(ip->ip_dst)]];
to

Code:
[sniffOutput insertText:[NSString stringWithFormat:@"Source IP:\t%s\n", inet_ntoa(ip->ip_src)]]; [sniffOutput insertText:[NSString stringWithFormat:@"Destination IP:\t%s\n, inet_ntoa(ip->ip_dst)]];
Patrick
     
Thinine
Mac Elite
Join Date: Jul 2002
Status: Offline
Reply With Quote
Aug 6, 2006, 01:15 PM
 
I don't think that should be stringWithFormat there but stringWithString.
     
   
 
Forum Links
Forum Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Top
Privacy Policy
All times are GMT -4. The time now is 09:41 PM.
All contents of these forums © 1995-2017 MacNN. All rights reserved.
Branding + Design: www.gesamtbild.com
vBulletin v.3.8.8 © 2000-2017, Jelsoft Enterprises Ltd.,