1. 程式人生 > >winPcap庫函式介紹

winPcap庫函式介紹

最近在看WINPCAP,將其庫函式總結如下1. int pcap_findalldevs(pcap_if_t **, char *)    說明:用來獲得網絡卡的列表    引數: 指向pcap_if_t**型別的列表的指標的指標; char型指標,當開啟列表錯誤時返回錯誤資訊    返回值: 為int型,當顯示列表失敗時返回-1pcap_if_t 是pcap_if 重新命名而來:typedef struct pcap_if pcap_if_t;pcap_if結構體如下:struct pcap_if{        struct pcap_if *next;               /*多個網絡卡時使用來顯示各個網絡卡的資訊*/        char *name;                /* name to hand to "pcap_open_live()" */
        char *description;        /* textual description of interface, or NULL 就是網絡卡的型號、名字等*/        struct pcap_addr *addresses;    //pcap_addr 結構體        bpf_u_int32 flags;        /* PCAP_IF_ interface flags 介面標誌*/};pcap_addr 結構體如下:struct pcap_addr{         struct pcap_addr *next;         struct sockaddr *addr;                /* address */
         struct sockaddr *netmask;        /* netmask for that address  子網掩碼*/        struct sockaddr *broadaddr;        /* broadcast address for that address  廣播地址*/        struct sockaddr *dstaddr;        /* P2P destination address for that address  P2P目的地址 */};舉例:    pcap_if_t *alldevs;    pcap_if_t *d;
    char errbuf[64];    if (pcap_findalldevs(&alldevs, errbuf) == -1)/* 這個API用來獲得網絡卡 的列表 */    {      fprintf(stderr,"Error in pcap_findalldevs: %s/n", errbuf);      exit(1);   }  for(d=alldevs;d;d=d->next)/* 顯示列表的響應欄位的內容 */  {    printf("%d. %s", ++i, d->name);    if (d->description)       printf(" (%s)/n", d->description);   else      printf(" (No description available)/n"); }用pcap_findalldevs不能獲得網絡卡的MAC,有兩種方法可以實現,一、向自己傳送arp包,二、使用IPHelp的API可以獲得。2. void   pcap_freealldevs(pcap_if_t *)  說明:與int pcap_findalldevs(pcap_if_t **, char *)配套使用,當不再需要網絡卡列表時,用此函式free釋放空間  引數:開啟網絡卡列表時申請的pcap_if_t型的指標  舉例:pcap_freealldevs(alldevs);3. pcap_t    *pcap_open_live(const char * device, int snaplen, int promisc, int to_ms, char ebuf *)說明:被用來得到一個包抓取得描述符引數:      device是一個指出要抓取的網路裝置的字串。      snaplen指明最大可抓取的位元組長度。      promisc置位表明該介面要被設定成混雜模式。      to_ms以毫秒為單位設定超時時間。當在超時時間內網絡卡上沒有資料到來時對網絡卡的讀操作將返回 (如   pcap_dispatch() or pcap_next_ex()等函式)。     ebuf被用來存放當pcap_open_live()呼叫失敗時,返回的錯誤字串。    返回值: pcap_t型的指標,供pcap_dispatch() or pcap_next_ex()等函式呼叫。pcap_t的結構體:struct pcap {     #ifdef WIN32        ADAPTER *adapter;        LPPACKET Packet;        int timeout;        int nonblock;     #else        int fd;#endif                   int snapshot;        int linktype;        int tzoff;                /* timezone offset */        int offset;                /* offset for proper alignment */        struct pcap_sf sf;        struct pcap_md md;  int bufsize;               /* Read buffer. */        u_char *buffer;        u_char *bp;        int cc;           //Place holder for pcap_next(). u_char *pkt;               //Placeholder for filter code if bpf not in kernel. struct bpf_program fcode;        char errbuf[PCAP_ERRBUF_SIZE + 1];        int dlt_count;        int *dlt_list;   #ifdef REMOTE       /*! /brief '1' if we're the network client; needed by several functions (like pcap_setfilter() ) to know if        they have to use the socket or they have to open the local adapter. */        int rmt_clientside;           SOCKET rmt_sockctrl;                //!< socket ID of the socket used for the control connection        SOCKET rmt_sockdata;                //!< socket ID of the socket used for the data connection        pthread_t rmt_threaddata;       //!< handle to the receiving thread, we need to kill it in case of 'pcap_clos()'        int rmt_flags;                             //!< we have to save flags, since they are passed by the pcap_open_live(),  but they are used by the pcap_start capture()        int rmt_capstarted;                        //!< 'true' if the capture is already started (needed to knoe if we have to call the pcap_startcapture()        struct pcap_pkthdr pcap_header;        //!< In Linux, you have to copy the packet headers another time  before giving them to the user   #endif               }; 舉例:    /* Open the adapter */    if ( (adhandle= pcap_open_live(d->name, // name of the device           65536, // portion of the packet to capture. 65536 grants that the whole packet will be captured on all the MACs.          1,         // 混雜模式                1000,      // 設定超時時間,亳秒為單位                errbuf     // 發生錯誤時存放錯誤內容的緩衝區                ) ) == NULL)    {        fprintf(stderr,"/nUnable to open the adapter. %s is not supported by WinPcap/n");  pcap_freealldevs(alldevs);        return -1;4. int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user);說明:捕獲資料包;不會響應pcap_open_live()中設定的超時時間引數:        p是由pcap_open_live()返回的所開啟網絡卡的指標        cnt用於設定所捕獲資料包的個數        packet_handler是與void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)配合使用的一個引數。回撥函式。         user值一般為NULL舉例:pcap_loop(adhandle, 0, packet_handler, NULL);void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data){ struct tm *ltime; char timestr[16];  ltime=localtime(&header->ts.tv_sec);    /* 將時間戳轉變為易讀的標準格式*/ strftime( timestr, sizeof timestr, "%H:%M:%S", ltime); printf("%s,%.6d len:%d/n", timestr, header->ts.tv_usec, header->len);}5. int pcap_dispatch(pcap_t * p, int cnt, pcap_handler, u_char *user)說明:捕獲資料包。可以不被阻塞 引數:與pcap_loop()相同pcap_dispatch(...)和pcap_loop(...)的比較:一旦網絡卡被開啟,舊可以呼叫pcap_dispatch() 或pcap_loop()進行資料的捕獲,這兩個函式的功能十分相似,不同的是pcap_ dispatch()可以不被阻塞,而pcap_loop()在沒有資料流到達時將阻塞。在這個簡單的例子裡用pcap_loop()就足夠了,而在一些複雜的程式裡往往用pcap_dispatch()。這兩個函式都有返回的引數,一個指向某個函式(該函式用來接受資料如該程式中的packet_handler)的指標,libpcap呼叫該函式對每個從網上到來的資料包進行處理和接收資料包。另一個引數是帶有時間戳和包長等資訊的頭部,最後一個是含有所有協議頭部資料報的實際資料。注意MAC的冗餘校驗碼一般不出現,因為當一個楨到達並被確認後網絡卡就把它刪除了,同樣需要注意的是大多數網絡卡會丟掉冗餘碼出錯的資料包,所以WinPcap一般不能夠捕獲這些出錯的資料報。6. int pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header, u_char **pkt_data);說明:捕獲資料包,與pcap_ dispatch()   pcap_loop()很相似。pcap_next_ex()允許直接呼叫來接收包,它的引數和pcap_loop()相同:有一個網絡卡描述副,和兩個指標,這兩個指標會被初始化並返回給使用者,一個是pcap_pkthdr結構,另一個是接收資料的緩衝區。引數:       p是由pcap_open_live()返回的所開啟網絡卡的指標       pcap_pkthdr型的結構體,儲存時間,包的長度        pkt_data儲存資料包的內容,為一個char型陣列struct pcap_pkthdr{        struct timeval ts;        /* time stamp */        bpf_u_int32 caplen;        /* length of portion present */        bpf_u_int32 len;        /* length this packet (off wire) */}; 返回值: 當等於1時成功;等於0時超時;等於-1時說明發生錯誤,錯誤資訊用pcap_geterr(adhandle)獲得舉例:(最重要的一段程式碼)#define LINE_LEN 16main(int argc, char **argv){        pcap_if_t *alldevs, *d;        pcap_t *fp;        u_int inum, i=0;        char errbuf[PCAP_ERRBUF_SIZE];        int res;        struct pcap_pkthdr *header;        u_char *pkt_data;        printf("pktdump_ex: prints the packets of the network using WinPcap./n");        printf("/t Usage: pktdump_ex [-n adapter] | [-f file_name]/n/n");        if(argc < 3)        {                if (pcap_findalldevs(&alldevs, errbuf) == -1)                {                        fprintf(stderr,"Error in pcap_findalldevs: %s/n", errbuf);                        exit(1);                }   for(d=alldevs; d; d=d->next)                {                        printf("%d. %s", ++i, d->name);                        if (d->description)                                printf(" (%s)/n", d->description);                        else                                printf(" (No description available)/n");                }                if(i==0)                {                        printf("/nNo interfaces found! Make sure WinPcap is installed./n");                        return -1;                }                printf("Enter the interface number (1-%d):",i);                scanf("%d", &inum);                if(inum < 1 || inum > i)    //選擇網絡卡                {                        printf("/nInterface number out of range./n");                        /* Free the device list */                        pcap_freealldevs(alldevs);                        return -1;                } for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);   //跳轉到指定的網絡卡 if ( (fp= pcap_open_live(d->name, 100, 1, 20, errbuf) ) == NULL)                {                        fprintf(stderr,"/nError opening adapter/n");                        return -1;                }        }        else       { switch (argv[1] [1])   /* The user provided a packet source: open it */                {                      case 'n':                        {                                if ( (fp= pcap_open_live(argv[2], 100, 1, 20, errbuf) ) == NULL)     //Open a physical device                                {                                        fprintf(stderr,"/nError opening adapter/n");                                        return -1;                                }         break;                        }                     case 'f':                        { if ( (fp = pcap_open_offline(argv[2], errbuf) ) == NULL)    /* Open a capture file */                                {                                        fprintf(stderr,"/nError opening dump file/n");                                        return -1;                                }                                break;                        }                }        } while((res = pcap_next_ex( fp, &header, &pkt_data)) >= 0)        {                if(res == 0) continue;                printf("%ld:%ld (%ld)/n", header->ts.tv_sec, header->ts.tv_usec, header->len);               for (i=1; (i < header->caplen + 1 ) ; i++)                {                        printf("%.2x ", pkt_data[i-1]);                        if ( (i % LINE_LEN) == 0) printf("/n");                }                 printf("/n/n");                       }        if(res == -1)  {                printf("Error reading the packets: %s/n", pcap_geterr(fp));                return -1;        }        return 0;}7. int pcap_compile(pcap_t *p, struct bpf_program *fp, char *str, int optimize,bpf_u_int32 netmask)說明:編譯一個過濾裝置,它通過一個高層的boolean型變數和字串產生一系列的能夠被底層驅動所解釋的二進位制編碼。boolean表示語法能夠在這個檔案的過濾表示語法中找到。與pcap_setfilter()配合使用。引數:        p是開啟網絡卡時返回的網絡卡指標        fp用於與pcap_setfilter()傳遞過濾資訊。        str是一個字串。        optimize指明是否需要優化編譯結果。       netmask子網掩碼返回值:       發生錯誤是返回-1舉例: if(d->addresses != NULL) /* 獲得第一個介面地址的掩碼 */      netmask=((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_addr;  else      netmask=0xffffff;  /* 如果這個介面沒有地址那麼我們假設他為C類地址 */   if(pcap_compile(adhandle, &fcode, "ip and tcp", 1, netmask) <0 ) {       fprintf(stderr,"/nUnable to compile the packet filter. Check the syntax./n");      pcap_freealldevs(alldevs);       return -1;  }   if(pcap_setfilter(adhandle, &fcode)<0) {       fprintf(stderr,"/nError setting the filter./n");     pcap_freealldevs(alldevs);       return -1; }8. int pcap_setfilter ( pcap_t *p, struct bpf_program * fp )  說明:pcap_setfilter() 用來聯絡一個在核心驅動上過濾的過濾器,這時所有網路資料包都將流經過濾器,並拷貝到應用程式中。引數:        p是開啟網絡卡時返回的網絡卡指標        fp是pcap_compile()傳遞過來的引數返回值:       錯誤時返回-19. int pcap_sendpacket(pcap_t *p, u_char *buf, int size)Ø         說明:手工傳送一個數據包了。這個函式需要的引數:一個裝有要傳送資料的緩衝區,要傳送的長度,和一個介面卡。注意緩衝區中的資料將不被核心協議處理,只是作為最原始的資料流被髮送,所以我門必須填充好正確的協議頭以便正確的將資料傳送。引數:        p是開啟網絡卡時返回的網絡卡指標        buf是傳送資料包的內容緩衝區首地址       size是傳送資料包的大小舉例:void usage();void main(int argc, char **argv){ pcap_t *fp; char error[PCAP_ERRBUF_SIZE]; u_char packet[100]; int i;  if (argc != 2)  {    printf("usage: %s inerface", argv[0]);    return; } if((fp = pcap_open_live(argv[1], 100, 1, 1000, error) ) == NULL) {    fprintf(stderr,"/nError opening adapter: %s/n", error);    return; } /* 假設網路環境為ethernet,我門把目的MAC設為1:1:1:1:1:1*/ packet[0]=1; packet[1]=1; packet[2]=1; packet[3]=1; packet[4]=1; packet[5]=1; /* 假設源MAC為 2:2:2:2:2:2 */ packet[6]=2; packet[7]=2; packet[8]=2; packet[9]=2; packet[10]=2; packet[11]=2; /* 填充發送包的剩餘部分 */ for(i=12;i<100;i++){    packet[i]=i%256; } /* 傳送包 */ pcap_sendpacket(fp, packet, 100); //傳送原始的資料包 return;}10.傳送資料包有關的幾個函式 pcap_send_queue* pcap_sendqueue_alloc(u_int memsize);說明:給資料包佇列分配空間引數:        memsize佇列緩衝區的大小返回值:       pcap_send_queue指標struct pcap_send_queue{        u_int maxlen;        u_int len;                        //< Current size of the queue, in bytes.        char *buffer;                //< Buffer containing the packets to be sent.};舉例:squeue = pcap_sendqueue_alloc(caplen); int pcap_sendqueue_queue(pcap_send_queue* queue, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data)說明:填充佇列引數:        queue 是由pcap_sendqueue_alloc()返回的指標         pkt_header是資料包頭        pkt_data是資料包內容緩衝區指標返回值:錯誤是返回-1 舉例:    if(pcap_sendqueue_queue(squeue, pktheader, pktdata) == -1) {        printf("Warning: packet buffer too small, not all the packets will be sent./n");        break; }u_int pcap_sendqueue_transmit(pcap_t *p, pcap_send_queue* queue, int sync)說明:傳送佇列資料引數:         pcap_t是        pcap_open_live()函式開啟的網絡卡指標        queue 是由pcap_sendqueue_alloc()返回的指標         sync是同步設定。如果非零,那麼傳送將是同步的,這將站用很大的CPU資源,因為發生在核心驅動的同步傳送是通過"brute force" loops的,但是一般情況下能夠精確到微秒。返回值:錯誤是返回-1舉例:    if((res = pcap_sendqueue_transmit(outdesc, squeue, sync)) < squeue->len)    {       printf("An error occurred sending the packets: %s. Only %d bytes were sent/n", error,res); } void pcap_sendqueue_destroy(pcap_send_queue* queue);說明:釋放佇列引數:       queue 是由pcap_sendqueue_alloc()返回的指標

相關推薦

winPcap函式介紹

最近在看WINPCAP,將其庫函式總結如下1. int pcap_findalldevs(pcap_if_t **, char *)    說明:用來獲得網絡卡的列表    引數: 指向pcap_if_t**型別的列表的指標的指標; char型指標,當開啟列表錯誤時返回錯誤資

SDL音訊 播放 函式介紹

Dir: 參考了各種文章,先儲存,隨需隨查。目前包含以下內容: SDL_OpenAudio SDL_PauseAudio PCM SDL_mixAudio SDL_CreateThread 1.SDL

ffmpeg函式介紹

av_register_all() 呼叫了avcodec_register_all()。avcodec_register_all()註冊了和編解碼器有關的元件:硬體加速器,解碼器,編碼器,Parser,Bitstream Filter。av_register_all()除了呼叫avcodec_re

STM32-自學筆記(9.SysTick定時器控制LED燈閃爍,程式用到的函式介紹

1.SysTick_CLKSourceConfig 函式原型:viod SysTick_CLKSourceConfig (u32 SysTick_CLKSource) 功能:選擇SysTick的時鐘源 引數:SysTick_CLKSource:SysTick時鐘源 引數:S

STM32-自學筆記(7.用GPIO點亮LED,程式用到的函式介紹

1.RCC_DeInit 函式原型:void RCC_DeInit (void) 功能:將外設RCC暫存器重設為預設值。 引數:無 例子:RCC_DeInit ();      //將外設RCC暫存器重設為預設值   2.RCC_HSE

libpcap函式介紹(附原始碼)

libpcap的資料型別定義:struct pcap_addr:網絡卡地址描述{    pcap_addr * next;    sockaddr * addr;    sockaddr * netmask;    sockaddr *broadaddr;    sockaddr *dstaddr;};pca

STM32之RTC實時時鐘函式介紹(1)

本章主要是介紹RTC的響應庫函式使用方法。 1.RTC_ITConfig函式的功能是使能或者失能指定的RTC中斷,其中輸入引數是32位的待使能或失能的RTC中斷源。但是在使用該函式之前,必須先呼叫函式RTC_WaitForLastTask(),等待標誌位RTOFF被設定。

STM32USART串列埠函式介紹之USART_Init

本文將介紹USART串列埠的庫函式,總的來說有以下函式體: ※ USART_Init函式:初始化所使用的串列埠外設 ※ USART_Cmd函式:使能或者失能USART外設 ※ USART_ITConf

Numpy函式基礎介紹

寫在最前面:機器學習的本質是數學,是數學在資料上的應用,python的Numpy函式庫對於線性代數的處理有著很好的效果 構建一個5x5的隨機陣列 a = random.rand(5,5) print(type(a)) print(a) <class 'numpy.ndarray

MATLAB函式radarvcd介紹

形式: [vcp,vcpangles] = radarvcd(freq,rfs,anht) [vcp,vcpangles] = radarvcd(____,name,value) radarvcd(__) vcp:vertical coverage pattern

Linux:基礎IO(cIO函式詳細介紹)(IO系統呼叫介面詳細介紹)(兩者關係:檔案描述符和檔案指標)

目錄 c系統中的庫函式: fopen:開啟檔案 fclose:關閉檔案 fwrite:向檔案寫入一個數據塊 fread:讀寫 fprintf:格式化輸出到一個流/檔案中 fseek:移動/跳轉 到當前 讀取/寫入位置 fgets:獲取字串 fput:把字串寫入到指

[C++] STL函式之字串string::npos的介紹,以及string中的find函式

npos經常和find一起用~它們兩個都在標頭檔案<string>裡面~先看用法: #include <iostream> #include <string> us

URLLIB函式介紹-爬蟲

URLLIB庫的urlretrieve函式用法 urlretrievel函式: 這個面數可以方便的將網頁上的一個檔案儲存到本地。以下程式碼可少非常方便的將百度的首頁下載到本地: from urllib import request request.urlretrdeve("http://www.

STM32之ADC函式介紹

ADC的基本概念希望各位網友查閱相應的手冊,上面對ADC有比較詳盡的介紹,包括誤差的分析和消除。這裡主要介紹ADC的基本庫函式的定義和使用。 1.ADC_DeInit函式的功能是將外設ADCx的全部暫存器重設為預設值。 ADC_DeInit(ADC2); 2.ADC_Ini

核心態與使用者態、系統呼叫與函式、檔案IO與標準IO、緩衝區等概念介紹

概述 Linux提供了兩套可以用於檔案的IO介面: 檔案IO: open、create、close、lseek、read、write、fcntl、ioctl等 標準IO: FILE、fopen、fwrite、fread、等 為了理解檔案IO和標準I

MYSQL數據事務介紹

mysql 數據庫 介紹 一、數據庫事務介紹 簡單地說,事務就是指邏輯上的一組SQL語句操作,組成這組操作的各個SQL語句, 執行時要麽全成功要麽全失敗。 列如:小明給小紅轉賬5塊錢,流程如下: 1.從小明銀行卡取出5元,計算式money-5 2.把上面5塊錢打入小紅的賬號上,小紅收到5塊,

轉---CentOS安裝Oracle數據詳細介紹及常見問題匯總

cati res export 硬件 image centos 6 bin pre 數據庫安裝 一、安裝前準備 1.軟件硬件要求 操作系統:CentOS 6.4(32bit)Oracle數據庫版本:Oracle 10g(10201_database_linux32.zi

Robot Framework(AutoItLibrary關鍵字介紹

花括號 body 按鈕 導致 library mage img 括號 cti AutoItLibrary庫關鍵字 AutoItLibrary 的對象操作大體上有幾大主要部分,Window 操作、Control 操作、Mouse 操作、Process操作、Run 操作、Re

professional cuda c programming--CUDA簡單介紹

傅裏葉變換 gac device 行為 tst vid .com 地址 ott CUDA Libraries簡單介紹 ? 上圖是CUDA 庫的位置。本文簡要介