modules/up/src/Core/network/Pcap.cc
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- pcapReadHandler
- pcapProcessHandler
- Pcap
- Pcap
- issueRead
//
// $Id: Pcap.cc,v 1.1.1.1 2000/03/10 16:32:19 engin Exp $
//
// Author(s): Cengiz Alaettinoglu
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#if defined(HAVE_PCAP_H)
#include "util/Types.hh"
#include "util/Trail.hh"
#include "util/Handler.hh"
#include "util/Buffer.hh"
#include "sys/File.hh"
#include "sys/Pipe.hh"
#include "sys/Time.hh"
#include "sched/Timer.hh"
#include "sched/Dispatcher.hh"
#include "network/Pcap.hh"
#include "network/Headers.hh"
#include "network/Network.hh"
extern "C" {
#include <sys/socket.h>
#include <net/if.h>
//#include <net/if_arp.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <netinet/in_systm.h>
//#include <netinet/ip.h>
#include <pcap.h>
int pcap_read(pcap_t *, int cnt, pcap_handler, u_char *);
}
static int tuba=0, idrp=0; //some pcaps want these flags declared
// Locals
static TraceCode tracePcap("network");
const int DefaultSnapLen = 68;
static void pcapReadHandler(void* pcap, void*) {
/* [<][>][^][v][top][bottom][index][help] */
((Pcap *) pcap)->issueRead();
}
static void pcapProcessHandler(u_char *pcap,
/* [<][>][^][v][top][bottom][index][help] */
const struct pcap_pkthdr *h,
const u_char *p) {
u_int caplen = h->caplen;
u_int length = h->len;
u_short pay_type;
switch (((Pcap*)pcap)->datalink_) {
case DLT_EN10MB :
case DLT_IEEE802 :
if (h->caplen < sizeof(struct ether_header)) {
TRACE(tracePcap, "ethernet header not found\n");
return;
}
length-= sizeof(struct ether_header);
caplen-= sizeof(struct ether_header);
pay_type = ntohs(((struct ether_header *)p)->ether_type);
p += sizeof(struct ether_header);
break;
case DLT_ATM_RFC1483 :
if (h->caplen < 8) {
TRACE(tracePcap, "ATM header not found\n");
return;
}
if (p[4] == 0xaa || p[5] == 0xaa || p[6] == 0x03) {
/* if first 4 bytes are cookie/vpci */
p+= 4;
length-= 4;
caplen-= 4;
} else if (p[0] != 0xaa || p[1] != 0xaa || p[2] != 0x03) {
/*XXX assume 802.6 MAC header from fore driver */
p+= 20;
length-= 20;
caplen-= 20;
}
pay_type = p[6] << 8 | p[7];
length-= 8;
caplen-= 8;
p+= 8;
break;
case DLT_SLIP :
//case DLT_SLIP_BSDOS :
case DLT_PPP :
//case DLT_PPP_BSDOS :
case DLT_FDDI :
case DLT_NULL :
//case DLT_RAW :
ERROR("unsupported link layer %d\n", ((Pcap*)pcap)->datalink_);
return;
}
if (pay_type != ETHERTYPE_IP)
return;
if (caplen < sizeof(IP)) {
TRACE(tracePcap, "ip header not found\n");
return;
}
IP *ip= (IP*)p;
ip->ntoh();
Address src(ip->source);
Address dst(ip->destination);
((Pcap*) pcap)->receive(src, dst, ip->protocol);
}
Pcap::Pcap(char *filter, char *device) : ListNode() {
/* [<][>][^][v][top][bottom][index][help] */
int snaplen = DefaultSnapLen;
int promiscuous = 1;
char ebuf[PCAP_ERRBUF_SIZE];
bpf_u_int32 localnet, netmask;
struct bpf_program fcode;
int Oflag = 1; /* run filter code optimizer */
int i;
if (device == NULL) {
device = pcap_lookupdev(ebuf);
if (device == NULL)
FATAL("%s\n", ebuf);
}
pcap_descriptor = pcap_open_live(device, snaplen, promiscuous, 1000, ebuf);
if (pcap_descriptor == NULL)
FATAL("%s\n", ebuf);
datalink_= pcap_datalink(pcap_descriptor);
i = pcap_snapshot(pcap_descriptor);
if (snaplen < i) {
ERROR("snaplen raised from %d to %d", snaplen, i);
snaplen = i;
}
if (pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0) {
localnet = 0;
netmask = 0;
ERROR("%s\n", ebuf);
}
if (pcap_compile(pcap_descriptor, &fcode, filter, Oflag, netmask) < 0)
FATAL("%s\n", pcap_geterr(pcap_descriptor));
if (pcap_setfilter(pcap_descriptor, &fcode) < 0)
FATAL("%s\n", pcap_geterr(pcap_descriptor));
Handler rH(pcapReadHandler, this);
Handler nH((CallBackFunc)NULL, (void *)NULL);
// the pcap_t points to memory where the first word is the file descriptor
file = new File(* (int *) pcap_descriptor, FileModeReadOnly, rH, nH);
}
Pcap::~Pcap() {
/* [<][>][^][v][top][bottom][index][help] */
pcap_close(pcap_descriptor);
delete file;
}
void Pcap::issueRead() {
/* [<][>][^][v][top][bottom][index][help] */
if (pcap_read(pcap_descriptor,
1,
pcapProcessHandler,
(u_char *) this) < 0)
TRACE(tracePcap, "pcap: %s\n", pcap_geterr(pcap_descriptor));
}
// Copyright (c) 1994 by the University of Southern California.
// All rights reserved.
//
// Permission to use, copy, modify, and distribute this software and
// its documentation in source and binary forms for lawful
// non-commercial purposes and without fee is hereby granted, provided
// that the above copyright notice appear in all copies and that both
// the copyright notice and this permission notice appear in supporting
// documentation, and that any documentation, advertising materials,
// and other materials related to such distribution and use acknowledge
// that the software was developed by the University of Southern
// California and/or Information Sciences Institute.
// The name of the University of Southern California may not
// be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THE UNIVERSITY OF SOUTHERN CALIFORNIA DOES NOT MAKE ANY REPRESENTATIONS
// ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. THIS SOFTWARE IS
// PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
// NON-INFRINGEMENT.
//
// IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
// SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT,
// TORT, OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH,
// THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
// Questions concerning this software should be directed to
// scan@isi.edu.
//
#endif HAVE_PCAP