我已经编写了一个程序来从我的网络接口卡(ralink 2870(USB),atheros(PCI)等)捕获无线网络数据包。现在我无法捕获我需要的正确格式的数据包,即使没有捕获数据包。 1,我试着把我的卡调到监控模式或者为它添加一个接口mon0。但是它输出“不支持那个接口”。2,这个程序只能通过pcap_datalink()澄清“这是以太网链路类型”,为什么?我的 wlan0 接口是那种链接类型?这是我的代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<signal.h>
#include<unistd.h>
#include<net/if.h>
#include<netinet/if_ether.h>
#include<pcap.h>
/*ugly shortcuts - Defining our header types*/
#define ETH_HEADER_SIZE 14
#define AVS_HEADER_SIZE 64 /*AVS capture header size*/
#define DATA_80211_FRAME_SIZE 24 /*header for 802.11 data packet*/
#define LLC_HEADER_SIZE 8 /*LLC frame for encapsulation*/
#define MAC_MASK (0XFF)
/*
#define uint8 unsigned char;
#define int8 char;
#define uint16 int;
#define int16 int;
#define u_int32_t unsigned int;
#define int32 signed int;
*/
/*for the sake of clarity we'll use globals for a few things*/
char *device; /*device to sniff on*/
int verbose = 0; /*verbose output about the device*/
int wired = 0; /*flag for the opened pcap session*/
pcap_t *handle; /*handle for the opened pcap session*/
/*8 bytes SNAP LLC header format*/
struct snap_header_t{
u_int8_t dsap;
u_int8_t ssap;
u_int8_t ctl;
u_int16_t org;
u_int8_t org2;
u_int16_t ether_type; /* ethernet type */
}__attribute__((__PACKED__));
//24 bytes 80211 header
struct wireless_80211_header_t{
u_int16_t fc; /*2 bytes */
u_int16_t dur; /*2 bytes duration*/
u_int8_t da[6]; /*6 bytes destination*/
u_int8_t sa[6]; /*6 bytes source*/
u_int8_t bssid[6]; /*6 bytes bssid*/
u_int16_t seq_ctrl; /*2 bytes sequence control*/
};
//64 bytes AVS header
struct AVS_header_t
{
u_int32_t version;
u_int32_t length;
u_int64_t mactime;
u_int64_t hosttime;
u_int32_t phytype;
u_int32_t channel;
u_int32_t datarate;
u_int32_t antenna;
u_int32_t priority;
u_int32_t ssi_type;
int32_t ssi_signal;
int32_t ssi_noise;
u_int32_t preamble;
u_int32_t encoding;
};
/*========defined but not used=========*/
/*prism value */
struct prism_value{
u_int32_t did;
u_int16_t status;
u_int16_t len;
u_int32_t data;
};
/*prism header for traditional wireless card*/
struct prism_header{
u_int32_t msgcode;
u_int32_t msglen;
struct prism_value hosttime;
struct prism_value mactime;
struct prism_value channel;
struct prism_value rssi;
struct prism_value sq;
struct prism_value signal;
struct prism_value noise;
struct prism_value rate;
struct prism_value istx;
struct prism_value frmlen;
};
/*===============================*/
/*gracefully handle a Control + C action*/
void
ctrl_c()
{
printf("\nExiting\n");
pcap_breakloop(handle); /*tell pcap_loop or pcap_dispatch to stop capturing*/
pcap_close(handle);
exit(0);
}
/*Usage of this program*/
void
usage (char *name)
{
printf("\n%s - simple ARP sniffer\n",name);
printf("Usage: %s [-i interface] [-l] [-v]\n",name);
printf("\t-i\tinterface to sniff on\n");
printf("\t-l\tlist available interfaces\n");
printf("\t-v\tprint verbose info\n");
exit(1);
}
/*callback function to process a packet when captured*/
void
process_packet(u_char *args, const struct pcap_pkthdr *header,\
const u_char *packet)
{
struct ether_header *eth_header; /*in ethernet.h included by if_eth.h*/
struct wireless_80211_header_t *wireless_header; /*80211 header*/
struct snap_header_t *llc_header; /*RFC 1042 encapsulation header*/
struct ether_arp *arp_packet; /*from if_eth.h*/
if(wired) /*global flag - wired or wireless*/
{
eth_header = (struct ether_header *) packet;
arp_packet = (struct ether_arp *) (packet + ETH_HEADER_SIZE);
if(ntohs(eth_header->ether_type) != ETHERTYPE_ARP)return;
}
else
{
/*wireless*/
wireless_header = (struct wireless_80211_header_t *)
(packet + AVS_HEADER_SIZE);
llc_header = (struct snap_header_t *)
(packet + AVS_HEADER_SIZE + DATA_80211_FRAME_SIZE);
arp_packet = (struct ether_arp *)
(packet + AVS_HEADER_SIZE + DATA_80211_FRAME_SIZE + LLC_HEADER_SIZE);
if(ntohs(llc_header->ether_type) != ETHERTYPE_ARP)return;
}
printf("SRC: %.2X.%.2X.%.2X.%.2X.%.2X.%.2X--> DES:"
"%.2X.%.2X.%.2X.%.2X.%.2X.%.2X\n",
wireless_header->sa[0]&MAC_MASK,
wireless_header->sa[1]&MAC_MASK,
wireless_header->sa[2]&MAC_MASK,
wireless_header->sa[3]&MAC_MASK,
wireless_header->sa[4]&MAC_MASK,
wireless_header->sa[5]&MAC_MASK,
wireless_header->da[0]&MAC_MASK,
wireless_header->da[1]&MAC_MASK,
wireless_header->da[2]&MAC_MASK,
wireless_header->da[3]&MAC_MASK,
wireless_header->da[4]&MAC_MASK,
wireless_header->da[5]&MAC_MASK);
printf("Src: %d.%d.%d.%d--> Des: %d.%d.%d.%d\n",
arp_packet->arp_spa[0],
arp_packet->arp_spa[1],
arp_packet->arp_spa[2],
arp_packet->arp_spa[3],
arp_packet->arp_tpa[0],
arp_packet->arp_tpa[1],
arp_packet->arp_tpa[2],
arp_packet->arp_tpa[3]);
}/*end of process_packet*/
/*the main function*/
int
main(int argc,char *argv[])
{
char opt; /*for option processing*/
char errbuf[PCAP_ERRBUF_SIZE]; /*pcap error messages buffer*/
struct pcap_pkthdr header; /*packet header from pcap*/
const u_char *packet; /*packet*/
bpf_u_int32 netp; /*ip address of interface*/
bpf_u_int32 maskp; /*subnet mask of interface*/
char *filter = "arp"; /*filter for BPF (human readable)*/
struct bpf_program fp; /*compiled BPF filter*/
int ret; /*gegeric return value*/
pcap_if_t *alldevsp; /*list of interfaces*/
while((opt = getopt(argc, argv, "i:vl")) > 0)
{
switch(opt)
{
case 'i':
device = optarg;
break;
case 'l':
if(pcap_findalldevs (&alldevsp,errbuf) < 0)
{
fprintf(stderr,"erros in find all devs: %s\n",errbuf);
exit(1);
}
while(alldevsp != NULL)
{
printf("%s\n",alldevsp->name);
alldevsp = alldevsp->next;
}
exit(0);
case 'v':
verbose = 1;
break;
default:
usage(argv[0]);
break;
}//end of switch
}//end of while
/*setup signal handler to Control+C will graceful*/
signal(SIGINT,ctrl_c);
/*find device for sniffing if needed*/
if(device == NULL)/*if user hasn't specified a device*/
{
device = pcap_lookupdev(errbuf);/*let pcap find a compatible device*/
if(device == NULL)//there was an error
{
fprintf(stderr,"%s\n",errbuf);
exit(1);
}
}
/*set errbuf to 0 length string to check for warnings*/
//memset(errbuf,PCAP_ERRBUF_SIZE,0);
errbuf[0] = 0;
/*open device for sniffing*/
handle = pcap_open_live(device, /*device to sniff on*/
BUFSIZ, /*maximum number of bytes to capture per packet*/
1, /*set 1 for promisc mode,0 to not*/
0, /*0,snigg until an error occurs*/
errbuf);
if(handle == NULL)
{
fprintf(stderr,"%s\n",errbuf);
exit(1);
}
if(strlen(errbuf) > 0)
{
fprintf(stderr,"warning: %s\n",errbuf);
errbuf[0] = 0;
}
if(verbose)
{
printf("Using device: %s\n",device);
printf("libpcap version: %s\n",(char *)pcap_lib_version);
}
/*find out the datalink type of the connection*/
if(pcap_datalink (handle) == DLT_EN10MB)
{
wired = 1;/*ethernet link*/
printf("this is a ethernet link\n");
}
else if((pcap_datalink (handle) == DLT_IEEE802_11_RADIO_AVS)\
||(pcap_datalink (handle) == DLT_IEEE802_11_RADIO)\
||(pcap_datalink (handle) == DLT_IEEE802_11)\
||(pcap_datalink (handle) == DLT_PRISM_HEADER))
{
wired = 0;
printf("this is a wireless link\n");
}
else
{
fprintf(stderr,"do not support this interface type!\n");
exit(1);
}
/*get the IP subnet mask of the device,so we set a filter on it*/
if(pcap_lookupnet(device,&netp,&maskp,errbuf) == -1)
{
fprintf(stderr,"%s\n",errbuf);
exit(1);
}
/*compile the filter,so we can capture only stuff we are interested in*/
if(pcap_compile(handle,&fp,filter,0,maskp) == -1)
{
fprintf(stderr,"%s\n",pcap_geterr(handle));
exit(1);
}
/*set the filter for the device we have opened*/
if(pcap_setfilter(handle,&fp) == -1)
{
fprintf(stderr,"%s\n",pcap_geterr(handle));
exit(1);
}
/*it will be nice and free the memory used for the compiled filter*/
pcap_freecode(&fp);
/*the 'main loop' of capturing packet with our callback function*/
if((ret = pcap_loop(handle, /*our session created previous*/
-1, /*(count) a negative number means sniff until error*/
process_packet, /*callback function*/
NULL)) < 0)/*arg can be transfer to callback function*/
{
if(ret == -1)
{ fprintf(stderr,"%s\n",pcap_geterr(handle));
exit(1);
}/*otherwise return should be -2,meaning pcap_breakloop has been called*/
}
/*close our session*/
pcap_close(handle);
return 0;
}