使用socket和pcap我可以捕获第3层和上层数据包 . 所以我可以捕获TCP,IP,UDP,ARP或任何其他数据包但我想捕获第2层数据包 . 因此在802.11n以太网头中包含源,目标和AP(接入点)MAC地址每个6字节和2字节帧控制 . 现在在帧控制中有一个类型和子类型每2位提交,所以我们可以知道RTS(请求发送),CTS(清除发送),概率请求 . 所以我想捕获这个rts,cts和probe所以有没有办法使用任何编程语言捕获?我使用c中的pcap.h来捕获网络层数据包802.11n ethernet header当前代码:

#include"pcap.h" #include"stdio.h" #include"stdlib.h" #include"string.h" #include"sys/socket.h" #include"arpa/inet.h" #include"net/ethernet.h" #include"netinet/ip_icmp.h" #include"netinet/udp.h"
#include"netinet/tcp.h"
#include"netinet/ip.h"

int main(){

pcap_if_t *alldevsp , *device;
pcap_t *handle;

char errbuf[100] , *devname , devs[100][100];
int count = 1 , n;

//First get the list of available devices
printf("Finding available devices ... ");
if( pcap_findalldevs( &alldevsp , errbuf) )
{
    printf("Error finding devices : %s" , errbuf);
    exit(1);
}
printf("Done");

//Print the available devices
printf("\nAvailable Devices are :\n");
for(device = alldevsp ; device != NULL ; device = device->next)
{
    printf("%d. %s - %s\n" , count , device->name , device->description);
    if(device->name != NULL)
    {
        strcpy(devs[count] , device->name);
    }
    count++;
}

//Ask user which device to sniff
printf("Enter the number of the device you want to sniff : ");
scanf("%d" , &n);
devname = devs[n];

//Open the device for sniffing
printf("Opening device %s for sniffing ... " , devname);
handle = pcap_open_live(devname , 65536 , 1 , 0 , errbuf);

if (handle == NULL)
{
    fprintf(stderr, "Couldn't open device %s : %s\n" , devname , errbuf);
    exit(1);
}
printf("Done\n");

logfile=fopen("log.txt","w");
if(logfile==NULL)
{
    printf("Unable to create file.");
}

//Put the device in sniff loop
pcap_loop(handle , -1 , process_packet , NULL);

return 0;}

void process_packet(u_char * args,const struct pcap_pkthdr * header,const u_char * buffer){int size = header-> len;

//Get the IP Header part of this packet , excluding the ethernet header
struct iphdr *iph = (struct iphdr*)(buffer + sizeof(struct ethhdr));
++total;
switch (iph->protocol) //Check the Protocol and do accordingly...
{
    case 1:  //ICMP Protocol
        ++icmp;
        print_icmp_packet( buffer , size);
        break;

    case 2:  //IGMP Protocol
        ++igmp;
        break;

    case 6:  //TCP Protocol
        ++tcp;
        print_tcp_packet(buffer , size);
        break;

    case 17: //UDP Protocol
        ++udp;
        print_udp_packet(buffer , size);
        break;

    default: //Some Other Protocol like ARP etc.
        ++others;
        break;
}
printf("TCP : %d   UDP : %d   ICMP : %d   IGMP : %d   Others : %d   Total : %d\r", tcp , udp , icmp , igmp , others , total);

}

void print_ethernet_header(const u_char * Buffer,int Size){struct ethhdr * eth =(struct ethhdr *)Buffer;

fprintf(logfile , "\n");
fprintf(logfile , "Ethernet Header\n");
fprintf(logfile , "   |-Destination Address : %.2X-%.2X-%.2X-%.2X-%.2X-%.2X \n", eth->h_dest[0] , eth->h_dest[1] , eth->h_dest[2] , eth->h_dest[3] , eth->h_dest[4] , eth->h_dest[5] );
fprintf(logfile , "   |-Source Address      : %.2X-%.2X-%.2X-%.2X-%.2X-%.2X \n", eth->h_source[0] , eth->h_source[1] , eth->h_source[2] , eth->h_source[3] , eth->h_source[4] , eth->h_source[5] );
fprintf(logfile , "   |-Protocol            : %u \n",(unsigned short)eth->h_proto);

}`

void print_ip_header(const u_char * Buffer, int Size)

{

print_ethernet_header(Buffer , Size);
unsigned short iphdrlen;
struct iphdr *iph = (struct iphdr *)(Buffer  + sizeof(struct ethhdr) );
iphdrlen =iph->ihl*4;

memset(&source, 0, sizeof(source));
source.sin_addr.s_addr = iph->saddr;

memset(&dest, 0, sizeof(dest));
dest.sin_addr.s_addr = iph->daddr;

fprintf(logfile , "\n");
fprintf(logfile , "IP Header\n");
fprintf(logfile , "   |-IP Version        : %d\n",(unsigned int)iph->version);
fprintf(logfile , "   |-IP Header Length  : %d DWORDS or %d Bytes\n",(unsigned int)iph->ihl,((unsigned int)(iph->ihl))*4);
fprintf(logfile , "   |-Type Of Service   : %d\n",(unsigned int)iph->tos);
fprintf(logfile , "   |-IP Total Length   : %d  Bytes(Size of Packet)\n",ntohs(iph->tot_len));
fprintf(logfile , "   |-Identification    : %d\n",ntohs(iph->id));
//fprintf(logfile , "   |-Reserved ZERO Field   : %d\n",(unsigned int)iphdr->ip_reserved_zero);
//fprintf(logfile , "   |-Dont Fragment Field   : %d\n",(unsigned int)iphdr->ip_dont_fragment);
//fprintf(logfile , "   |-More Fragment Field   : %d\n",(unsigned int)iphdr->ip_more_fragment);
fprintf(logfile , "   |-TTL      : %d\n",(unsigned int)iph->ttl);
fprintf(logfile , "   |-Protocol : %d\n",(unsigned int)iph->protocol);
fprintf(logfile , "   |-Checksum : %d\n",ntohs(iph->check));
fprintf(logfile , "   |-Source IP        : %s\n" , inet_ntoa(source.sin_addr) );
fprintf(logfile , "   |-Destination IP   : %s\n" , inet_ntoa(dest.sin_addr) );

}

所以tcp,udp,icmp标头与IP标头相同