tcpdump mailing list archives

a problem with some code


From: "Tyler Littlefield" <tyler () tysdomain com>
Date: Thu, 5 Feb 2009 10:03:05 -0700

Good morning listers,
I've got a quick question, and hope it won't be to much of a problem.
I'm in a college course, which is using a program that is not working with my screen reader. I am blind, and am using a 
reader that takes the text on the screen and reads it in synthasized speech. There are some programs that don't work 
with this however, and this is one of them. I was told that rather than playing with the program to trace packets, I 
could write my own program and get the credit for the lab. I've done well thus far, but I'm having some issues, which I 
hope you will be able to help with.
Everything seems to be working until I try to get the offset of my IP header.
This works, partially, but the ports are invalid--I'm seeing ports in the range of 44000ish when I know there isn't 
data going back and forth on those ports.
I've been playing with this for a couple hours, and would really appriciate it if someone would be able to help me out.
I automatically jump from the ethernet header to the IP header, and after that I'm trying to go to the tcp header so i 
can show destination and source port, etc etc.
The problem is in getting the size of the IP header, I believe. I'm not able to get the correct offset from the top of 
the IP header to the TCP header so I can adjust my pointer.
Again, thanks for your help.
The code is below. I'll provide both files, one is packet.h which I got from the libpcap tutorial and made minor 
adjustments. The second is called pc.cpp, and is all my code.
The function that acts as my loop callback is at the bottom.
//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
//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++;
ip_hdr* recv;
recv=(ip_hdr*)(packet+sizeof(ether_hdr));
cout << "From: " << inet_ntoa(recv->ip_src) << "\t\t" << "to: " << inet_ntoa(recv->ip_dst) << ".\n" <<endl;
cout << "Id: " << recv->ip_id << endl;
//now we determine the protocol:
switch(recv->ip_p)
{
case IPPROTO_TCP:
cout << "Protocol: TCP." << endl;
break;
default:
cout << "Protocol: unknown." << endl;
return;
break;
}
int packsize=0;
int ipsize=sizeof(*recv);
packsize=sizeof(tcp_hdr)+ipsize;
cout << packsize << endl;
tcp_hdr *tcp=(tcp_hdr*)(packet+packsize);
cout << "Source port: " << tcp->th_sport << "\t\tDestination port: " << tcp->th_dport << "." << endl;
}
//end code

Thanks again,
Tyler Littlefield-
This is the tcpdump-workers list.
Visit https://cod.sandelman.ca/ to unsubscribe.


Current thread: