/*
*Author:zhonghaohua@gmail.com
*/
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "execinfo.h"
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/ip.h>
//#include
#include "tcp.h"
#include <netinet/in_systm.h>
#include <netinet/if_ether.h>
#include "pcap.h"
#define SNAPLEN 65536
#define PCAP_ERRBUFi_SIZE 256
#include "ppacket.h"
//存储数据包从链路层到TCP层信息
typedef struct
{
u_int32_t src;
u_int32_t dst;
u_int16_t sport;
u_int16_t dport;
u_int8_t ether_smac[ETHER_ADDR_LEN];
u_int8_t ether_dmac[ETHER_ADDR_LEN];
u_int32_t seq;
u_int32_t ack;
u_int8_t isfin;
}flow_t;
int main(int argc, char *argv[])
{
//for argument
extern int optind;
extern int opterr;
extern int optopt;
extern char *optarg;
char arg = 0x0;
//for libpcap
int promisc = 1; //混杂模式
int dlt = 0;
char *device = NULL; //eht0 or other device
char expression[] = "tcp";
pcap_t *pd = NULL;
pcap_handler handler;
struct bpf_program fcode;
char error[PCAP_ERRBUFi_SIZE];
//init argument
while((arg = getopt(argc, argv, "i:vc")) != EOF)
{
switch(arg)
{
case 'i':
device = optarg;
break;
default:
break;
}
}
//当未指定device时,自动选择可用的device.
if(device == NULL)
{
if( (device = pcap_lookupdev(error)) == NULL)
{
printf("%s", error);
return 1;
}
}
//make sure the device. and set capture mode.
if((pd = pcap_open_live(device, SNAPLEN, promisc, 1000, error)) == NULL)
{
printf("%s", error);
return 1;
}
//get kind of packets
dlt = pcap_datalink(pd);
handler = find_handler(dlt, device); //根据链路层协议,选择相应的处理函数
//set expression
if(pcap_compile(pd, &fcode, expression, 1, 0) < 0)
{
printf("%s", pcap_geterr(pd));
return 1;
}
if(pcap_setfilter(pd, &fcode) < 0)
{
printf("%s", pcap_geterr(pd));
return 1;
}
//Begin to capture packet.
if(pcap_loop(pd, -1, handler, NULL) < 0)
{
printf("%s", pcap_geterr(pd));
return 1;
}
return 0;
}
pcap_handler find_handler(int datalink_type, char *device)
{
struct {
pcap_handler handler;
int type;
} handlers[] = {
{ dl_ethernet, DLT_EN10MB },
{ dl_ethernet, DLT_IEEE802 },
{ dl_ppp, DLT_PPP },
{ NULL, 0 },
};
int i = 0;
for (i = 0; handlers[i].handler != NULL; i++)
if (handlers[i].type == datalink_type)
return handlers[i].handler;
return NULL;
}
|