tcpdump mailing list archives

Re: a problem with some code


From: "Tyler Littlefield" <tyler () tysdomain com>
Date: Fri, 6 Feb 2009 08:15:18 -0700

Hello,
I've updated my code to do IP_HL, and am still getting around 7k in ports.
I also fixed my size, so I'm getting an overall size of 34 or so.
Ideas would be welcomed.
//code:
#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=((IP_HL(recv))*4);
packsize=sizeof(ether_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;
}

----- Original Message ----- From: "Guy Harris" <guy () alum mit edu>
To: <tcpdump-workers () lists tcpdump org>
Sent: Thursday, February 05, 2009 12:18 PM
Subject: Re: [tcpdump-workers] a problem with some code



On Feb 5, 2009, at 9:03 AM, Tyler Littlefield wrote:

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.

When you say "There are some programs that don't work with this however, and this is one of them.", do you mean that tcpdump doesn't work with the screen reader?

If so, what doesn't work? Is the problem that the output has a lot of abbreviations and other "non-words" and the screen reader doesn't translate them well? Or is the problem that command-line programs such as tcpdump/WinDump don't work with the screen reader?

The problem is in getting the size of the IP header, I believe.

You are correct.  Your code is doing

int ipsize=sizeof(*recv);

where "recv" is a pointer to a structure that defines the fixed-length portion of the IP header. As you might infer from my saying "fixed- length portion", the IP header is variable in length; it can include options.

RFC 791 describes how that works; you'll need to look at the "header length" field from the IP header, and use that as the length of the IP header (as RFC 791 indicates, that field is in units of 4-byte words, so you'll need to multiply it by 4 to get the length in bytes).

-
This is the tcpdump-workers list.
Visit https://cod.sandelman.ca/ to unsubscribe.

-
This is the tcpdump-workers list.
Visit https://cod.sandelman.ca/ to unsubscribe.


Current thread: