Hello list,
I'm still working on this for college.
I rewrote my callback function to work a bit differently, but it's still giving
me weird sizes.
If someone would check this out, I'd really really appriciate it.
I don't want you to tell me exactly how to fix it, just where I'm going wrong.
Thanks,
Tyler Littlefield
//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[]="port 22"; //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)
{
if (packet==NULL)
{
cout << "NULL packet" << endl;
}
static int count=1;
cout << count << endl;
count++;
int ip_size;
int tcp_size;
int size_payload;
ether_hdr* eth=(ether_hdr*)packet;
ip_hdr* ip=(ip_hdr*)(packet+sizeof(ether_hdr));
cout << "From: " << inet_ntoa(ip->ip_src) << "\t\t" << "to: " <<
inet_ntoa(ip->ip_dst) << ".\n" <<endl;
cout << "Id: " << ip->ip_id << endl;
//now we determine the protocol:
switch(ip->ip_p)
{
case IPPROTO_TCP:
cout << "Protocol: TCP." << endl;
break;
default:
cout << "Protocol: unknown." << endl;
return;
break;
}
tcp_hdr *tcp;
ip_size=IP_HL(ip)*4;
tcp=(tcp_hdr*)((packet+sizeof(ether_hdr))+ip_size);
cout << "Source port: " << tcp->th_sport << "\t\tDestination port: " <<
tcp->th_dport << "." << endl;
}
//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 */
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 */
};
#endif
//end code
Thanks again,
[Non-text portions of this message have been removed]