Hello list,
I've got the following code I'm using as a packet sniffer.
Could anyone point me in the right direction? the sniffex.c works from the
tutorial I was utilizing, which is where I got the headers from, but I'm not
seeing any data.
When I memcpy, I'm getting a segmentation fault--I was origenally trying to
memcpy 6 bytes off the packet pointer in my callback function to provide that
to the user as just a bit of a start to show that I was using packets and that
it was working.
Here's the main code:
//main.cpp
#include <stdlib.h>
#include <cstring>
#include <ctime>
#include <iostream>
#include <string>
#include <pcap.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/ethernet.h>
#include <unistd.h>
#include "packet.h"
using namespace std;
//function prototypes:
void PrintErr(const char* message);
void PrintErr(const string message);
void help(const char* progname);
void version(const char* progname);
void capt_h(u_char *args, const struct pcap_pkthdr *header, const u_char
*packet);
int main(int argc, char** argv)
{
//check arg length:
if (argc <=1)
{
PrintErr("You must provide an argument.");
help(argv[0]);
exit(EXIT_FAILURE);
}
//initialize our variables:
char* dev=NULL; //the device pointer
char ebuff[PCAP_ERRBUF_SIZE]; //the error buffer
bpf_u_int32 net_addr; //the network address
bpf_u_int32 mask_addr; //network mask.
in_addr addr; //used for translating addresses.
char *buff=NULL; //a simple buffer.
int i=0; //used for loops.
string temp; //our temporary string.
int loop=0; //how many times will we loop?
int wait=1; //how long should we wait?
pcap_t* handle;
int stop=0; //should we continue after the argument parsing?
char filter[]="ip"; //our default filter
bpf_program prog; //used for applying the filter.
//get the device name:
dev=pcap_lookupdev(ebuff);
if (dev==NULL)
{
PrintErr(ebuff);
exit(EXIT_FAILURE);
}
//get the subnet mask and network mask:
if ((pcap_lookupnet(dev,&net_addr,&mask_addr,ebuff))==-1)
{
PrintErr(ebuff);
exit(EXIT_FAILURE);
}
//loop through args:
for (i=1;i<argc;i++)
{
temp=argv[i];
if (temp=="-i")
{
cout << "Interface: " << dev << endl; //print the interface name
addr.s_addr=mask_addr;
cout << "Network mask: " << inet_ntoa(addr) << endl;
addr.s_addr=net_addr;
cout << "Network address: " << inet_ntoa(addr) << endl;
}
else if (temp=="-v")
{
version(argv[0]);
}
else if (temp=="-c") //the number of packets to capture:
{
if (argc==i)
{
PrintErr("-c takes an argument.");
help(argv[0]);
exit(EXIT_FAILURE);
}
else
{
loop=atoi(argv[i+1]);
stop=1;
}
}
}
//make sure we're not needlessly continuing.
if (stop==0)
{
exit(EXIT_SUCCESS);
}
//here we open the device.
//we'll set promisc to 0 so that this can be ran on non-root systems.
handle=pcap_open_live(dev,BUFSIZ,0,wait,ebuff);
if (handle==NULL)
{
PrintErr(ebuff);
exit(EXIT_FAILURE);
}
cout << "compiling" <<endl;
//now we "compile" our filter:
if (pcap_compile(handle,&prog,filter,1,net_addr)==-1)
{
PrintErr("Filter compilation error!");
exit(EXIT_FAILURE);
}
cout << "applying" <<endl;
//now we apply the filter:
if (pcap_setfilter(handle,&prog)==-1)
{
PrintErr("Error in applying filter!");
exit(EXIT_FAILURE);
}
cout << "creating loop" << endl;
pcap_loop(handle,loop,capt_h,NULL);
pcap_close(handle);
return 0;
}
void PrintErr(const char* message)
{
cerr << "***ERROR***! " << message << "\n" << endl;
return;
}
void PrintErr(const string message)
{
cerr << message << endl;
return;
}
void help(const char* progname)
{
cout << progname << " help:\n\n" << endl;
cout << "-i: print default interface information.\n" << endl;
return;
}
void version(const char* progname)
{
cout << progname << "Version: 0.5.\n" << endl;
cout << "Library versions:\n" << endl;
cout << pcap_lib_version() << "\n" << endl;
return;
}
void capt_h(u_char *args, const struct pcap_pkthdr *header, const u_char
*packet)
{
static int count=1;
cout << count << endl;
count++;
ether_hdr* recv;
recv=(ether_hdr*)packet;
cout << recv->ether_dhost << endl;
}
//and now the packet definitions:
//packet.h
#ifndef PACKET_H
#define PACKET_H
//ethernet header:
//needed if the code includes ethernet.h.
#ifndef ETHER_ADDR_LEN
#define ETHER_ADDR_LEN 6
#endif
//tcp flags:
#define TH_FIN 0x01
#define TH_SYN 0x02
#define TH_RST 0x04
#define TH_PUSH 0x08
#define TH_ACK 0x10
#define TH_URG 0x20
#define TH_ECE 0x40
#define TH_CWR 0x80
#define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
struct ether_hdr {
u_char ether_dhost[ETHER_ADDR_LEN]; /* Destination host address */
u_char ether_shost[ETHER_ADDR_LEN]; /* Source host address */
u_short ether_type; /* IP? ARP? RARP? etc */
};
struct ip_hdr {
u_char ip_vhl; /* version << 4 | header length >> 2 */
u_char ip_tos; /* type of service */
u_short ip_len; /* total length */
u_short ip_id; /* identification */
u_short ip_off; /* fragment offset field */
#define IP_RF 0x8000 /* reserved fragment flag */
#define IP_DF 0x4000 /* dont fragment flag */
#define IP_MF 0x2000 /* more fragments flag */
#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
u_char ip_ttl; /* time to live */
u_char ip_p; /* protocol */
u_short ip_sum; /* checksum */
struct in_addr ip_src,ip_dst; /* source and dest address */
};
#define IP_HL(ip) (((ip)->ip_vhl) & 0x0f)
#define IP_V(ip) (((ip)->ip_vhl) >> 4)
struct tcp_hdr {
u_short th_sport;
u_short th_dport;
int th_seq; /* sequence number */
u_char offset; //the first four bits are used.
#define TH_OFF(th) (((th)->th_offx2 & 0xf0) >> 4)
u_char th_flags;
u_short th_win; /* window */
u_short th_sum; /* checksum */
u_short th_urp; /* urgent pointer */
};
typedef struct {
ether_hdr eth;
ip_hdr ip;
tcp_hdr tcp;
void* payload;
} pack;
#endif
Thanks,
[Non-text portions of this message have been removed]