0

ネットワーク インターフェイス カード (ralink 2870(USB)、atheros(PCI) など) からワイヤレス ネットワーク パケットをキャプチャするプログラムを作成しました。 1 つ目は、カードを監視モードにするか、インターフェース mon0 を追加しようとしましたが、「そのインターフェースをサポートしていません」という出力が表示されました。なぜ?私の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;
}
4

0 に答える 0