日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

libpcap讲解与API接口函数讲解

發(fā)布時(shí)間:2023/11/30 编程问答 62 豆豆
生活随笔 收集整理的這篇文章主要介紹了 libpcap讲解与API接口函数讲解 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

ibpcap(Packet Capture Library),即數(shù)據(jù)包捕獲函數(shù)庫(kù),是Unix/Linux平臺(tái)下的網(wǎng)絡(luò)數(shù)據(jù)包捕獲函數(shù)庫(kù)。它是一個(gè)獨(dú)立于系統(tǒng)的用戶層包捕獲的API接口,為底層網(wǎng)絡(luò)監(jiān)測(cè)提供了一個(gè)可移植的框架。

?

一、libpcap工作原理

libpcap主要由兩部份組成:網(wǎng)絡(luò)分接頭(Network Tap)和數(shù)據(jù)過(guò)濾器(Packet Filter)。網(wǎng)絡(luò)分接頭從網(wǎng)絡(luò)設(shè)備驅(qū)動(dòng)程序中收集數(shù)據(jù)拷貝,過(guò)濾器決定是否接收該數(shù)據(jù)包。Libpcap利用BSD Packet Filter(BPF)算法對(duì)網(wǎng)卡接收到的鏈路層數(shù)據(jù)包進(jìn)行過(guò)濾。BPF算法的基本思想是在有BPF監(jiān)聽的網(wǎng)絡(luò)中,網(wǎng)卡驅(qū)動(dòng)將接收到的數(shù)據(jù)包復(fù)制一份交給BPF過(guò)濾器,過(guò)濾器根據(jù)用戶定義的規(guī)則決定是否接收此數(shù)據(jù)包以及需要拷貝該數(shù)據(jù)包的那些內(nèi)容,然后將過(guò)濾后的數(shù)據(jù)給與過(guò)濾器相關(guān)聯(lián)的上層應(yīng)用程序。

libpcap的包捕獲機(jī)制就是在數(shù)據(jù)鏈路層加一個(gè)旁路處理。當(dāng)一個(gè)數(shù)據(jù)包到達(dá)網(wǎng)絡(luò)接口時(shí),libpcap首先利用已經(jīng)創(chuàng)建的Socket從鏈路層驅(qū)動(dòng)程序中獲得該數(shù)據(jù)包的拷貝,再通過(guò)Tap函數(shù)將數(shù)據(jù)包發(fā)給BPF過(guò)濾器。BPF過(guò)濾器根據(jù)用戶已經(jīng)定義好的過(guò)濾規(guī)則對(duì)數(shù)據(jù)包進(jìn)行逐一匹配,匹配成功則放入內(nèi)核緩沖區(qū),并傳遞給用戶緩沖區(qū),匹配失敗則直接丟棄。如果沒有設(shè)置過(guò)濾規(guī)則,所有數(shù)據(jù)包都將放入內(nèi)核緩沖區(qū),并傳遞給用戶層緩沖區(qū)。

?

二、libpcap的抓包框架

pcap_lookupdev()函數(shù)用于查找網(wǎng)絡(luò)設(shè)備,返回可被pcap_open_live()函數(shù)調(diào)用的網(wǎng)絡(luò)設(shè)備名指針。

pcap_open_live()函數(shù)用于打開網(wǎng)絡(luò)設(shè)備,并且返回用于捕獲網(wǎng)絡(luò)數(shù)據(jù)包的數(shù)據(jù)包捕獲描述字。對(duì)于此網(wǎng)絡(luò)設(shè)備的操作都要基于此網(wǎng)絡(luò)設(shè)備描述字。

pcap_lookupnet()函數(shù)獲得指定網(wǎng)絡(luò)設(shè)備的網(wǎng)絡(luò)號(hào)和掩碼。

pcap_compile()函數(shù)用于將用戶制定的過(guò)濾策略編譯到過(guò)濾程序中。

pcap_setfilter()函數(shù)用于設(shè)置過(guò)濾器。

pcap_loop()函數(shù)pcap_dispatch()函數(shù)用于捕獲數(shù)據(jù)包,捕獲后還可以進(jìn)行處理,此外pcap_next()和pcap_next_ex()兩個(gè)函數(shù)也可以用來(lái)捕獲數(shù)據(jù)包。

pcap_close()函數(shù)用于關(guān)閉網(wǎng)絡(luò)設(shè)備,釋放資源。

?

其實(shí)pcap的應(yīng)用程序格式很簡(jiǎn)單,總的來(lái)說(shuō)可以可以分為以下5部分,相信看了以下的5部分,大概能對(duì)pcap的總體布局有個(gè)大概的了解了吧:

1.我們從決定用哪一個(gè)接口進(jìn)行嗅探開始。在Linux中,這可能是eth0,而在BSD系統(tǒng)中則可能是xl1等等。我們也可以用一個(gè)字符串來(lái)定義這個(gè)設(shè)備,或者采用pcap提供的接口名來(lái)工作。

2.初始化pcap。在這里我們要告訴pcap對(duì)什么設(shè)備進(jìn)行嗅探。假如愿意的話,我們還可以嗅探多個(gè)設(shè)備。怎樣區(qū)分它們呢?使用 文件句柄。就像打開一個(gè)文件進(jìn)行讀寫一樣,必須命名我們的嗅探“會(huì)話”,以此使它們各自區(qū)別開來(lái)。

3.假如我們只想嗅探特定的傳輸(如TCP/IP包,發(fā)往端口23的包等等),我們必須創(chuàng)建一個(gè)規(guī)則集合,編譯并且使用它。這個(gè)過(guò)程分為三個(gè)相互緊密關(guān)聯(lián)的階段。規(guī)則集合被置于一個(gè)字符串內(nèi),并且被轉(zhuǎn)換成能被pcap讀的格式(因此編譯它)。編譯實(shí)際上就是在我們的程序里調(diào)用一個(gè)不被外部程序使用的函數(shù)。接下來(lái)我們要告訴 pcap使用它來(lái)過(guò)濾出我們想要的那一個(gè)會(huì)話。

4.最后,我們告訴pcap進(jìn)入它的主體執(zhí)行循環(huán)。在這個(gè)階段內(nèi)pcap一直工作到它接收了所有我們想要的包為止。每當(dāng)它收到一個(gè)包就調(diào)用另一個(gè)已經(jīng)定義好的函數(shù),這個(gè)函數(shù)可以做我們想要的任何工作,它可以剖析所部獲的包并給用戶打印出結(jié)果,它可以將結(jié)果保存為一個(gè)文件,或者什么也不作。

5.在嗅探到所需的數(shù)據(jù)后,我們要關(guān)閉會(huì)話并結(jié)束。

?

三、實(shí)現(xiàn)libpcap的每一個(gè)步驟

(1)設(shè)置設(shè)備

這是很簡(jiǎn)單的。有兩種方法設(shè)置想要嗅探的設(shè)備。

第一種,我們可以簡(jiǎn)單的讓用戶告訴我們。考察下面的程序:

   #include

   #include

   int main(int argc, char *argv[])

   {

   char *dev = argv[1];

   printf("Device: %s", dev);

   return(0);

   }

用戶通過(guò)傳遞給程序的第一個(gè)參數(shù)來(lái)指定設(shè)備。字符串“dev”以pcap能“理解”的格式保存了我們要嗅探的接口的名字(當(dāng)然,用戶必須給了我們一個(gè)真正存在的接口)。

另一種也是同樣的簡(jiǎn)單。來(lái)看這段程序:

   #include

   #include

   int main()

   {

   char *dev, errbuf[PCAP_ERRBUF_SIZE];

   dev = pcap_lookupdev(errbuf);

   printf("Device: %s", dev);

   return(0);

   }

(2)打開設(shè)備進(jìn)行嗅探

創(chuàng)建一個(gè)嗅探會(huì)話的任務(wù)真的非常簡(jiǎn)單。為此,我們使用pcap_open_live()函數(shù)。此函數(shù)的原型(根據(jù)pcap的手冊(cè)頁(yè))如下:

   pcap_t *pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)

其第一個(gè)參數(shù)是我們?cè)谏弦还?jié)中指定的設(shè)備,snaplen是整形的,它定義了將被pcap捕捉的最大字節(jié)數(shù)。當(dāng)promisc設(shè)為true時(shí)將置指定接口為混雜模式(然而,當(dāng)它置為false時(shí)接口仍處于混雜模式的非凡情況也是有可能的)。to_ms是讀取時(shí)的超時(shí)值,單位是毫秒(假如為0則一直嗅探直到錯(cuò)誤發(fā)生,為-1則不確定)。最后,ebuf是一個(gè)我們可以存入任何錯(cuò)誤信息的字符串(就像上面的errbuf)。此函數(shù)返回其會(huì)話句柄。

混雜模式與非混雜模式的區(qū)別:這兩種方式區(qū)別很大。一般來(lái)說(shuō),非混雜模式的嗅探器中,主機(jī)僅嗅探那些跟它直接有關(guān)的通信,如發(fā)向它的,從它發(fā)出的,或經(jīng)它路由的等都會(huì)被嗅探器捕捉。而在混雜模式中則嗅探傳輸線路上的所有通信。在非交換式網(wǎng)絡(luò)中,這將是整個(gè)網(wǎng)絡(luò)的通信。這樣做最明顯的優(yōu)點(diǎn)就是使更多的包被嗅探到,它們因你嗅探網(wǎng)絡(luò)的原因或者對(duì)你有幫助,或者沒有。但是,混雜模式是可被探測(cè)到的。一個(gè)主機(jī)可以通過(guò)高強(qiáng)度的測(cè)試判定另一臺(tái)主機(jī)是否正在進(jìn)行混雜模式的嗅探。其次,它僅在非交換式的網(wǎng)絡(luò)環(huán)境中有效工作(如集線器,或者交換中的ARP層面)。再次,在高負(fù)荷的網(wǎng)絡(luò)中,主機(jī)的系統(tǒng)資源將消耗的非常嚴(yán)重。

(3)過(guò)濾通信

實(shí)現(xiàn)這一過(guò)程由pcap_compile()與pcap_setfilter()這兩個(gè)函數(shù)完成。

在使用我們自己的過(guò)濾器前必須編譯它。過(guò)濾表達(dá)式被保存在一個(gè)字符串中(字符數(shù)組)。其句法在tcpdump的手冊(cè)頁(yè)中被證實(shí)非常好。我建議你親自閱讀它。但是我們將使用簡(jiǎn)單的測(cè)試表達(dá)式,這樣你可能很輕易理解我的例子。

我們調(diào)用pcap_compile()來(lái)編譯它,其原型是這樣定義的:

   int pcap_compile(pcap_t *p, strUCt bpf_program *fp, char *str, int optimize, bpf_u_int32 netmask)

第一個(gè)參數(shù)是會(huì)話句柄。接下來(lái)的是我們存儲(chǔ)被編譯的過(guò)濾器版本的地址的引用。再接下來(lái)的則是表達(dá)式本身,存儲(chǔ)在規(guī)定的字符串格式里。再下邊是一個(gè)定義表達(dá)式是否被優(yōu)化的整形量(0為false,1為true,標(biāo)準(zhǔn)規(guī)定)。最后,我們必須指定應(yīng)用此過(guò)濾器的網(wǎng)絡(luò)掩碼。函數(shù)返回-1為失敗,其他的任何值都表明是成功的。

表達(dá)式被編譯之后就可以使用了。現(xiàn)在進(jìn)入pcap_setfilter()。仿照我們介紹pcap的格式,先來(lái)看一看pcap_setfilter()的原型:

   int pcap_setfilter(pcap_t *p, struct bpf_program *fp)

這非常直觀,第一個(gè)參數(shù)是會(huì)話句柄,第二個(gè)參數(shù)是被編譯表達(dá)式版本的引用(可推測(cè)出它與pcap_compile()的第二個(gè)參數(shù)相同)。

下面的代碼示例可能能使你更好的理解:

   #include

   pcap_t *handle; /* 會(huì)話的句柄 */

   char dev[] = "eth0"; /* 執(zhí)行嗅探的設(shè)備 */

   char errbuf[PCAP_ERRBUF_SIZE]; /* 存儲(chǔ)錯(cuò)誤 信息的字符串 */

   struct bpf_program filter; /*已經(jīng)編譯好的過(guò)濾表達(dá)式*/

   char filter_app[] = "port 23"; /* 過(guò)濾表達(dá)式*/

   bpf_u_int32 mask; /* 執(zhí)行嗅探的設(shè)備的網(wǎng)絡(luò)掩碼 */

   bpf_u_int32 net; /* 執(zhí)行嗅探的設(shè)備的IP地址 */

   pcap_lookupnet(dev, &net, &mask, errbuf);

   handle = pcap_open_live(dev, BUFSIZ, 1, 0, errbuf);

   pcap_compile(handle, &filter, filter_app, 0, net);

   pcap_setfilter(handle, &filter);

這個(gè)程序使嗅探器嗅探經(jīng)由端口23的所有通信,使用混雜模式,設(shè)備是eth0。

(4)實(shí)際的嗅探

有兩種手段捕捉包。我們可以一次只捕捉一個(gè)包,也可以進(jìn)入一個(gè)循環(huán),等捕捉到多個(gè)包再進(jìn)行處理。我們將先看看怎樣去捕捉單個(gè)包,然后再看看使用循環(huán)的方法。為此,我們使用函數(shù)pcap_next()。

pcap_next()的原型及其簡(jiǎn)單:

   u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h)

第一個(gè)參數(shù)是會(huì)話句柄,第二個(gè)參數(shù)是指向一個(gè)包括了當(dāng)前數(shù)據(jù)包總體信息(被捕捉時(shí)的時(shí)間,包的長(zhǎng)度,其被指定的部分長(zhǎng)度)的結(jié)構(gòu)體的指針(在這里只有一個(gè)片斷,只作為一個(gè)示例)。pcap_next()返回一個(gè)u_char指針給被這個(gè)結(jié)構(gòu)體描述的包。我們將稍后討論這種實(shí)際讀取包本身的手段。

   這里有一個(gè)演示怎樣使用pcap_next()來(lái)嗅探一個(gè)包的例子:

   #include

   #include

   int main()

   {

   pcap_t *handle; /* 會(huì)話句柄 */

   char *dev; /* 執(zhí)行嗅探的設(shè)備 */

   char errbuf[PCAP_ERRBUF_SIZE]; /* 存儲(chǔ)錯(cuò)誤信息的字符串 */

  

   struct bpf_program filter; /* 已經(jīng)編譯好的過(guò)濾器 */

   char filter_app[] = "port 23"; /* 過(guò)濾表達(dá)式 */

   bpf_u_int32 mask; /* 所在網(wǎng)絡(luò)的掩碼 */

   bpf_u_int32 net; /* 主機(jī)的IP地址 */

   struct pcap_pkthdr header; /* 由pcap.h定義 */

   const u_char *packet; /* 實(shí)際的包 */

   /* Define the device */

   dev = pcap_lookupdev(errbuf);

   /* 探查設(shè)備屬性 */

   pcap_lookupnet(dev, &net, &mask, errbuf);

   /* 以混雜模式打開會(huì)話 */

   handle = pcap_open_live(dev, BUFSIZ, 1, 0, errbuf);

   /* 編譯并應(yīng)用過(guò)濾器 */

   pcap_compile(handle, &filter, filter_app, 0, net);

   pcap_setfilter(handle, &filter);

   /* 截獲一個(gè)包 */

   packet = pcap_next(handle, &header);

   /* 打印它的長(zhǎng)度 */

   printf("Jacked a packet with length of [%d]

   ", header.len);

   /* 關(guān)閉會(huì)話 */

   pcap_close(handle);

   return(0);

   }

這個(gè)程序嗅探被pcap_lookupdev()返回的設(shè)備并將它置為混雜模式。它發(fā)現(xiàn)第一個(gè)包經(jīng)過(guò)端口23(telnet)并且告訴用戶此包的大小(以字 節(jié)為單位)。這個(gè)程序又包含了一個(gè)新的調(diào)用pcap_close(),我們將在后面討論(盡管它的名字就足夠證實(shí)它自己的作用)。

實(shí)際上很少有嗅探程序會(huì)真正的使用pcap_next()。通常,它們使用pcap_loop()或者 pcap_dispatch()(它就是用了pcap_loop())。

pcap_loop()的原型如下:

   int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)

第一個(gè)參數(shù)是會(huì)話句柄,接下來(lái)是一個(gè)整型,它告訴pcap_loop()在返回前應(yīng)捕捉多少個(gè)數(shù)據(jù)包(若為負(fù)值則表示應(yīng)該一直工作直至錯(cuò)誤發(fā)生)。第三個(gè)參數(shù)是回調(diào)函數(shù)的名稱(正像其標(biāo)識(shí)符所指,無(wú)括號(hào))。最后一個(gè)參數(shù)在有些應(yīng)用里有用,但更多時(shí)候則置為NULL。假設(shè)我們有我們自己的想送往回調(diào)函數(shù)的參數(shù),另外還有pcap_loop()發(fā)送的參數(shù),這就需要用到它。很明顯,必須是一個(gè)u_char類型的指針以確保結(jié)果正確;正像我們稍后見到的,pcap使用了很有意思的方法以u(píng)_char指針的形勢(shì)傳遞信息。pcap_dispatch()的用法幾乎相同。唯一不同的是它們?nèi)绾翁幚沓瑫r(shí)(還記得在調(diào)用pcap_open_live()時(shí)怎樣設(shè)置超時(shí)嗎?這就是它起作用的地方)。Pcap_loop()忽略超時(shí)而pcap_dispatch()則不。關(guān)于它們之間區(qū)別的更深入的討論請(qǐng)參見pcap的手冊(cè)頁(yè)。

回調(diào)函數(shù)的原型:

   void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet);

讓我們更細(xì)致的考察它。首先,你會(huì)注重到該函數(shù)返回void類型,這是符合邏輯的,因?yàn)閜cap_loop()不知道如何去處理一個(gè)回調(diào)返回值。第一個(gè)參數(shù)相應(yīng)于pcap_loop()的最后一個(gè)參數(shù)。每當(dāng)回調(diào)函數(shù)被老婆 調(diào)用時(shí),無(wú)論最后一個(gè)參數(shù)傳給pcap_loop()什么值,這個(gè)值都會(huì)傳給我們回調(diào)函數(shù)的第一個(gè)參數(shù)。第二個(gè)參數(shù)是pcap頭文件定義的,它包括數(shù)據(jù)包被嗅探的時(shí)間、大小等信息。結(jié)構(gòu)體pcap_pkhdr在pcap.h中定義如下:

   struct pcap_pkthdr {

   struct timeval ts; /* 時(shí)間戳 */

   bpf_u_int32 caplen; /* 已捕捉部分的長(zhǎng)度 */

   bpf_u_int32 len; /* 該包的脫機(jī)長(zhǎng)度 */

   };

這些量都相當(dāng)明了。最后一個(gè)參數(shù)在它們中是最有意思的,也最讓pcap程序新手感到迷惑。這又是一個(gè)u_char指針,它包含了被pcap_loop()嗅探到的所有包。

但是你怎樣使用這個(gè)我們?cè)谠屠锓Q為packet的變量呢?一個(gè)數(shù)據(jù)包包含許多屬性,因此你可以想象它不只是一個(gè)字符串,而實(shí)質(zhì)上是一個(gè)結(jié)構(gòu)體的集合(比如,一個(gè)TCP/IP包會(huì)有一個(gè)以太網(wǎng)的頭部,一個(gè)IP頭部,一個(gè)TCP頭部,還有此包的有效載荷)。這個(gè)u_char就是這些結(jié)構(gòu)體的串聯(lián)版本。為了使用它,我們必須作一些有趣的匹配工作。

下面這些是一些數(shù)據(jù)包的結(jié)構(gòu)體:

   /* 以太網(wǎng)幀頭部 */

   struct sniff_ethernet {

   u_char ether_dhost[ETHER_ADDR_LEN]; /* 目的主機(jī)的地址 */

   u_char ether_shost[ETHER_ADDR_LEN]; /* 源主機(jī)的地址 */

   u_short ether_type; /* IP? ARP? RARP? etc */

   };

   /* IP數(shù)據(jù)包的頭部 */

   struct sniff_ip {

   #if BYTE_ORDER == LITTLE_ENDIAN

   u_int ip_hl:4, /* 頭部長(zhǎng)度 */

   ip_v:4; /* 版本號(hào) */

   #if BYTE_ORDER == BIG_ENDIAN

   u_int ip_v:4, /* 版本號(hào) */

   ip_hl:4; /* 頭部長(zhǎng)度 */

   #endif

   #endif /* not _IP_VHL */

   u_char ip_tos; /* 服務(wù)的類型 */

   u_short ip_len; /* 總長(zhǎng)度 */

   u_short ip_id; /*包標(biāo)志號(hào) */

   u_short ip_off; /* 碎片偏移 */

   #define IP_RF 0x8000 /* 保留的碎片標(biāo)志 */

   #define IP_DF 0x4000 /* dont fragment flag */

   #define IP_MF 0x2000 /* 多碎片標(biāo)志*/

   #define IP_OFFMASK 0x1fff /*分段位 */

   u_char ip_ttl; /* 數(shù)據(jù)包的生存時(shí)間 */

   u_char ip_p; /* 所使用的協(xié)議 */

   u_short ip_sum; /* 校驗(yàn)和 */

   struct in_addr ip_src,ip_dst; /* 源地址、目的地址*/

   };

   /* TCP 數(shù)據(jù)包的頭部 */

   struct sniff_tcp {

   u_short th_sport; /* 源端口 */

   u_short th_dport; /* 目的端口 */

   tcp_seq th_seq; /* 包序號(hào) */

   tcp_seq th_ack; /* 確認(rèn)序號(hào) */

   #if BYTE_ORDER == LITTLE_ENDIAN

   u_int th_x2:4, /* 還沒有用到 */

   th_off:4; /* 數(shù)據(jù)偏移 */

   #endif

   #if BYTE_ORDER == BIG_ENDIAN

   u_int th_off:4, /* 數(shù)據(jù)偏移*/

   th_x2:4; /*還沒有用到 */

   #endif

   u_char th_flags;

   #define TH_FIN 0x01

   #define TH_SYN 0x02

   #define TH_RST 0x04

   #define TH_PUSH 0x08

   #define TH_ACK 0x10

   #define TH_URG 0x20

   #define TH_ECE 0x40

   #define TH_CWR 0x80

   #define TH_FLAGS (TH_FINTH_SYNTH_RSTTH_ACKTH_URGTH_ECETH_CWR)

   u_short th_win; /* TCP滑動(dòng)窗口 */

   u_short th_sum; /* 頭部校驗(yàn)和 */

   u_short th_urp; /* 緊急服務(wù)位 */

   };

pcap嗅探數(shù)據(jù)包時(shí)正是使用的這些結(jié)構(gòu)。接下來(lái),它簡(jiǎn)單的創(chuàng)建一個(gè)u_char字符串并且將這些結(jié)構(gòu)體填入。那么我們?cè)鯓硬拍軈^(qū)分它們呢?預(yù)備好見證指針最實(shí)用的好處之一吧。

我們?cè)僖淮渭俣ㄒ獙?duì)以太網(wǎng)上的TCP/IP包進(jìn)行處理。同樣的手段可以應(yīng)用于任何數(shù)據(jù)包,唯一的區(qū)別是你實(shí)際所使用的結(jié)構(gòu)體的類型。讓我們從聲明分解u_char包的變量開始:

   const struct sniff_ethernet *ethernet; /* 以太網(wǎng)幀頭部*/

   const struct sniff_ip *ip; /* IP包頭部 */

   const struct sniff_tcp *tcp; /* TCP包頭部 */

   const char *payload; /* 數(shù)據(jù)包的有效載荷*/

   /*為了讓它的可讀性好,我們計(jì)算每個(gè)結(jié)構(gòu)體中的變量大小*/

   int size_ethernet = sizeof(struct sniff_ethernet);

   int size_ip = sizeof(struct sniff_ip);

   int size_tcp = sizeof(struct sniff_tcp);

   現(xiàn)在我們開始讓人感到有些神秘的匹配:

   ethernet = (struct sniff_ethernet*)(packet);

   ip = (struct sniff_ip*)(packet + size_ethernet);

   tcp = (struct sniff_tcp*)(packet + size_ethernet + size_ip);

   payload = (u_char *)(packet + size_ethernet + size_ip + size_tcp);

  

此處如何工作?考慮u_char在內(nèi)存中的層次。基本的,當(dāng)pcap將這些結(jié)構(gòu)體填入u_char的時(shí)候是將這些數(shù)據(jù)存入一個(gè)字符串中,那個(gè)字符串將被送入我們的回調(diào)函數(shù)中。反向轉(zhuǎn)換是這樣的,不考慮這些結(jié)構(gòu)體制中的值,它們的大小將是一致的。例如在我的平臺(tái)上,一個(gè)sniff_ethernet結(jié)構(gòu)體的大小是14字節(jié)。一個(gè)sniff_ip結(jié)構(gòu)體是20字節(jié),一個(gè)sniff_tcp結(jié)構(gòu)體也是20字節(jié)。 u_char指針正是包含了內(nèi)存地址的一個(gè)變量,這也是指針的實(shí)質(zhì),它指向內(nèi)存的一個(gè)區(qū)域。簡(jiǎn)單而言,我們說(shuō)指針指向的地址為x,假如三個(gè)結(jié)構(gòu)體恰好線性排列,第一個(gè)(sniff_ethernet)被裝載到內(nèi)存地址的x處則我們很輕易的發(fā)現(xiàn)其他結(jié)構(gòu)體的地址,讓我們以表格顯示之:

   Variable Location (in bytes)

   sniff_ethernet X

   sniff_ip X + 14

   sniff_tcp X + 14 + 20

   payload X + 14 + 20 + 20

結(jié)構(gòu)體sniff_ethernet正好在x處,緊接著它的sniff_ip則位于x加上它本身占用的空間(此例為14字節(jié)),依此類推可得全部地址。

注重:你沒有假定你的變量也是同樣大小是很重要的。你應(yīng)該總是使用sizeof()來(lái)確保尺寸的正確。這是因?yàn)檫@些結(jié)構(gòu)體中的每個(gè)成員在不同平臺(tái)下可以有不同的尺寸。

?

下面是主要函數(shù)接口:

pcap_t *pcap_open_live(char *device, int snaplen,

?? int promisc, int to_ms, char *ebuf)

?? 獲得用于捕獲網(wǎng)絡(luò)數(shù)據(jù)包的數(shù)據(jù)包捕獲描述字。device參數(shù)為指定打開

?? 的網(wǎng)絡(luò)設(shè)備名。snaplen參數(shù)定義捕獲數(shù)據(jù)的最大字節(jié)數(shù)。promisc指定

?? 是否將網(wǎng)絡(luò)接口置于混雜模式。to_ms參數(shù)指定超時(shí)時(shí)間(毫秒)。

?? ebuf參數(shù)則僅在pcap_open_live()函數(shù)出錯(cuò)返回NULL時(shí)用于傳遞錯(cuò)誤消

?? 息。

pcap_t *pcap_open_offline(char *fname, char *ebuf)

?? 打開以前保存捕獲數(shù)據(jù)包的文件,用于讀取。fname參數(shù)指定打開的文

?? 件名。該文件中的數(shù)據(jù)格式與tcpdump和tcpslice兼容。"-"為標(biāo)準(zhǔn)輸

?? 入。ebuf參數(shù)則僅在pcap_open_offline()函數(shù)出錯(cuò)返回NULL時(shí)用于傳

?? 遞錯(cuò)誤消息。

pcap_dumper_t *pcap_dump_open(pcap_t *p, char *fname)

?? 打開用于保存捕獲數(shù)據(jù)包的文件,用于寫入。fname參數(shù)為"-"時(shí)表示

?? 標(biāo)準(zhǔn)輸出。出錯(cuò)時(shí)返回NULL。p參數(shù)為調(diào)用pcap_open_offline()或

?? pcap_open_live()函數(shù)后返回的pcap結(jié)構(gòu)指針。fname參數(shù)指定打開

?? 的文件名。如果返回NULL,則可調(diào)用pcap_geterr()函數(shù)獲取錯(cuò)誤消

?? 息。

?

char *pcap_lookupdev(char *errbuf)

?? 用于返回可被pcap_open_live()或pcap_lookupnet()函數(shù)調(diào)用的網(wǎng)絡(luò)

?? 設(shè)備名指針。如果函數(shù)出錯(cuò),則返回NULL,同時(shí)errbuf中存放相關(guān)的

?? 錯(cuò)誤消息。

int pcap_lookupnet(char *device, bpf_u_int32 *netp,

?? bpf_u_int32 *maskp, char *errbuf)

?? 獲得指定網(wǎng)絡(luò)設(shè)備的網(wǎng)絡(luò)號(hào)和掩碼。netp參數(shù)和maskp參數(shù)都是

?? bpf_u_int32指針。如果函數(shù)出錯(cuò),則返回-1,同時(shí)errbuf中存放相

?? 關(guān)的錯(cuò)誤消息。

int pcap_dispatch(pcap_t *p, int cnt,

?? pcap_handler callback, u_char *user)

?? 捕獲并處理數(shù)據(jù)包。cnt參數(shù)指定函數(shù)返回前所處理數(shù)據(jù)包的最大值。

?? cnt=-1表示在一個(gè)緩沖區(qū)中處理所有的數(shù)據(jù)包。cnt=0表示處理所有

?? 數(shù)據(jù)包,直到產(chǎn)生以下錯(cuò)誤之一:讀取到EOF;超時(shí)讀取。callback

?? 參數(shù)指定一個(gè)帶有三個(gè)參數(shù)的回調(diào)函數(shù),這三個(gè)參數(shù)為:一個(gè)從

?? pcap_dispatch()函數(shù)傳遞過(guò)來(lái)的u_char指針,一個(gè)pcap_pkthdr結(jié)構(gòu)

?? 的指針,和一個(gè)數(shù)據(jù)包大小的u_char指針。如果成功則返回讀取到的

?? 字節(jié)數(shù)。讀取到EOF時(shí)則返回零值。出錯(cuò)時(shí)則返回-1,此時(shí)可調(diào)用

?? pcap_perror()或pcap_geterr()函數(shù)獲取錯(cuò)誤消息。

int pcap_loop(pcap_t *p, int cnt,

?? pcap_handler callback, u_char *user)

?? 功能基本與pcap_dispatch()函數(shù)相同,只不過(guò)此函數(shù)在cnt個(gè)數(shù)據(jù)包

?? 被處理或出現(xiàn)錯(cuò)誤時(shí)才返回,但讀取超時(shí)不會(huì)返回。而如果為

?? pcap_open_live()函數(shù)指定了一個(gè)非零值的超時(shí)設(shè)置,然后調(diào)用

?? pcap_dispatch()函數(shù),則當(dāng)超時(shí)發(fā)生時(shí)pcap_dispatch()函數(shù)會(huì)返回。

?? cnt參數(shù)為負(fù)值時(shí)pcap_loop()函數(shù)將始終循環(huán)運(yùn)行,除非出現(xiàn)錯(cuò)誤。

void pcap_dump(u_char *user, struct pcap_pkthdr *h,

?? u_char *sp)

?? 向調(diào)用pcap_dump_open()函數(shù)打開的文件輸出一個(gè)數(shù)據(jù)包。該函數(shù)可

?? 作為pcap_dispatch()函數(shù)的回調(diào)函數(shù)。

int pcap_compile(pcap_t *p, struct bpf_program *fp,

?? char *str, int optimize, bpf_u_int32 netmask)

?? 將str參數(shù)指定的字符串編譯到過(guò)濾程序中。fp是一個(gè)bpf_program結(jié)

?? 構(gòu)的指針,在pcap_compile()函數(shù)中被賦值。optimize參數(shù)控制結(jié)果

?? 代碼的優(yōu)化。netmask參數(shù)指定本地網(wǎng)絡(luò)的網(wǎng)絡(luò)掩碼。

int pcap_setfilter(pcap_t *p, struct bpf_program *fp)

?? 指定一個(gè)過(guò)濾程序。fp參數(shù)是bpf_program結(jié)構(gòu)指針,通常取自

?? pcap_compile()函數(shù)調(diào)用。出錯(cuò)時(shí)返回-1;成功時(shí)返回0。

u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h)

?? 返回指向下一個(gè)數(shù)據(jù)包的u_char指針。

int pcap_datalink(pcap_t *p)

?? 返回?cái)?shù)據(jù)鏈路層類型,例如DLT_EN10MB。

int pcap_snapshot(pcap_t *p)

?? 返回pcap_open_live被調(diào)用后的snapshot參數(shù)值。

int pcap_is_swapped(pcap_t *p)

?? 返回當(dāng)前系統(tǒng)主機(jī)字節(jié)與被打開文件的字節(jié)順序是否不同。

int pcap_major_version(pcap_t *p)

?? 返回寫入被打開文件所使用的pcap函數(shù)的主版本號(hào)。

int pcap_minor_version(pcap_t *p)

?? 返回寫入被打開文件所使用的pcap函數(shù)的輔版本號(hào)。

int pcap_stats(pcap_t *p, struct pcap_stat *ps)

?? 向pcap_stat結(jié)構(gòu)賦值。成功時(shí)返回0。這些數(shù)值包括了從開始

?? 捕獲數(shù)據(jù)以來(lái)至今共捕獲到的數(shù)據(jù)包統(tǒng)計(jì)。如果出錯(cuò)或不支持

?? 數(shù)據(jù)包統(tǒng)計(jì),則返回-1,且可調(diào)用pcap_perror()或

?? pcap_geterr()函數(shù)來(lái)獲取錯(cuò)誤消息。

FILE *pcap_file(pcap_t *p)

?? 返回被打開文件的文件名。

int pcap_fileno(pcap_t *p)

?? 返回被打開文件的文件描述字號(hào)碼。

void pcap_perror(pcap_t *p, char *prefix)

?? 在標(biāo)準(zhǔn)輸出設(shè)備上顯示最后一個(gè)pcap庫(kù)錯(cuò)誤消息。以prefix參

?? 數(shù)指定的字符串為消息頭。

char *pcap_geterr(pcap_t *p)

?? 返回最后一個(gè)pcap庫(kù)錯(cuò)誤消息。

char *pcap_strerror(int error)

?? 如果strerror()函數(shù)不可用,則可調(diào)用pcap_strerror函數(shù)替代。

void pcap_close(pcap_t *p)

?? 關(guān)閉p參數(shù)相應(yīng)的文件,并釋放資源。

libpcap(Packet Capture Library),即數(shù)據(jù)包捕獲函數(shù)庫(kù),是Unix/Linux平臺(tái)下的網(wǎng)絡(luò)數(shù)據(jù)包捕獲函數(shù)庫(kù)。它是一個(gè)獨(dú)立于系統(tǒng)的用戶層包捕獲的API接口,為底層網(wǎng)絡(luò)監(jiān)測(cè)提供了一個(gè)可移植的框架。

?

一、libpcap工作原理

libpcap主要由兩部份組成:網(wǎng)絡(luò)分接頭(Network Tap)和數(shù)據(jù)過(guò)濾器(Packet Filter)。網(wǎng)絡(luò)分接頭從網(wǎng)絡(luò)設(shè)備驅(qū)動(dòng)程序中收集數(shù)據(jù)拷貝,過(guò)濾器決定是否接收該數(shù)據(jù)包。Libpcap利用BSD Packet Filter(BPF)算法對(duì)網(wǎng)卡接收到的鏈路層數(shù)據(jù)包進(jìn)行過(guò)濾。BPF算法的基本思想是在有BPF監(jiān)聽的網(wǎng)絡(luò)中,網(wǎng)卡驅(qū)動(dòng)將接收到的數(shù)據(jù)包復(fù)制一份交給BPF過(guò)濾器,過(guò)濾器根據(jù)用戶定義的規(guī)則決定是否接收此數(shù)據(jù)包以及需要拷貝該數(shù)據(jù)包的那些內(nèi)容,然后將過(guò)濾后的數(shù)據(jù)給與過(guò)濾器相關(guān)聯(lián)的上層應(yīng)用程序。

libpcap的包捕獲機(jī)制就是在數(shù)據(jù)鏈路層加一個(gè)旁路處理。當(dāng)一個(gè)數(shù)據(jù)包到達(dá)網(wǎng)絡(luò)接口時(shí),libpcap首先利用已經(jīng)創(chuàng)建的Socket從鏈路層驅(qū)動(dòng)程序中獲得該數(shù)據(jù)包的拷貝,再通過(guò)Tap函數(shù)將數(shù)據(jù)包發(fā)給BPF過(guò)濾器。BPF過(guò)濾器根據(jù)用戶已經(jīng)定義好的過(guò)濾規(guī)則對(duì)數(shù)據(jù)包進(jìn)行逐一匹配,匹配成功則放入內(nèi)核緩沖區(qū),并傳遞給用戶緩沖區(qū),匹配失敗則直接丟棄。如果沒有設(shè)置過(guò)濾規(guī)則,所有數(shù)據(jù)包都將放入內(nèi)核緩沖區(qū),并傳遞給用戶層緩沖區(qū)。

?

二、libpcap的抓包框架

pcap_lookupdev()函數(shù)用于查找網(wǎng)絡(luò)設(shè)備,返回可被pcap_open_live()函數(shù)調(diào)用的網(wǎng)絡(luò)設(shè)備名指針。

pcap_open_live()函數(shù)用于打開網(wǎng)絡(luò)設(shè)備,并且返回用于捕獲網(wǎng)絡(luò)數(shù)據(jù)包的數(shù)據(jù)包捕獲描述字。對(duì)于此網(wǎng)絡(luò)設(shè)備的操作都要基于此網(wǎng)絡(luò)設(shè)備描述字。

pcap_lookupnet()函數(shù)獲得指定網(wǎng)絡(luò)設(shè)備的網(wǎng)絡(luò)號(hào)和掩碼。

pcap_compile()函數(shù)用于將用戶制定的過(guò)濾策略編譯到過(guò)濾程序中。

pcap_setfilter()函數(shù)用于設(shè)置過(guò)濾器。

pcap_loop()函數(shù)pcap_dispatch()函數(shù)用于捕獲數(shù)據(jù)包,捕獲后還可以進(jìn)行處理,此外pcap_next()和pcap_next_ex()兩個(gè)函數(shù)也可以用來(lái)捕獲數(shù)據(jù)包。

pcap_close()函數(shù)用于關(guān)閉網(wǎng)絡(luò)設(shè)備,釋放資源。

?

其實(shí)pcap的應(yīng)用程序格式很簡(jiǎn)單,總的來(lái)說(shuō)可以可以分為以下5部分,相信看了以下的5部分,大概能對(duì)pcap的總體布局有個(gè)大概的了解了吧:

1.我們從決定用哪一個(gè)接口進(jìn)行嗅探開始。在Linux中,這可能是eth0,而在BSD系統(tǒng)中則可能是xl1等等。我們也可以用一個(gè)字符串來(lái)定義這個(gè)設(shè)備,或者采用pcap提供的接口名來(lái)工作。

2.初始化pcap。在這里我們要告訴pcap對(duì)什么設(shè)備進(jìn)行嗅探。假如愿意的話,我們還可以嗅探多個(gè)設(shè)備。怎樣區(qū)分它們呢?使用 文件句柄。就像打開一個(gè)文件進(jìn)行讀寫一樣,必須命名我們的嗅探“會(huì)話”,以此使它們各自區(qū)別開來(lái)。

3.假如我們只想嗅探特定的傳輸(如TCP/IP包,發(fā)往端口23的包等等),我們必須創(chuàng)建一個(gè)規(guī)則集合,編譯并且使用它。這個(gè)過(guò)程分為三個(gè)相互緊密關(guān)聯(lián)的階段。規(guī)則集合被置于一個(gè)字符串內(nèi),并且被轉(zhuǎn)換成能被pcap讀的格式(因此編譯它)。編譯實(shí)際上就是在我們的程序里調(diào)用一個(gè)不被外部程序使用的函數(shù)。接下來(lái)我們要告訴 pcap使用它來(lái)過(guò)濾出我們想要的那一個(gè)會(huì)話。

4.最后,我們告訴pcap進(jìn)入它的主體執(zhí)行循環(huán)。在這個(gè)階段內(nèi)pcap一直工作到它接收了所有我們想要的包為止。每當(dāng)它收到一個(gè)包就調(diào)用另一個(gè)已經(jīng)定義好的函數(shù),這個(gè)函數(shù)可以做我們想要的任何工作,它可以剖析所部獲的包并給用戶打印出結(jié)果,它可以將結(jié)果保存為一個(gè)文件,或者什么也不作。

5.在嗅探到所需的數(shù)據(jù)后,我們要關(guān)閉會(huì)話并結(jié)束。

?

三、實(shí)現(xiàn)libpcap的每一個(gè)步驟

(1)設(shè)置設(shè)備

這是很簡(jiǎn)單的。有兩種方法設(shè)置想要嗅探的設(shè)備。

第一種,我們可以簡(jiǎn)單的讓用戶告訴我們。考察下面的程序:

   #include

   #include

   int main(int argc, char *argv[])

   {

   char *dev = argv[1];

   printf("Device: %s", dev);

   return(0);

   }

用戶通過(guò)傳遞給程序的第一個(gè)參數(shù)來(lái)指定設(shè)備。字符串“dev”以pcap能“理解”的格式保存了我們要嗅探的接口的名字(當(dāng)然,用戶必須給了我們一個(gè)真正存在的接口)。

另一種也是同樣的簡(jiǎn)單。來(lái)看這段程序:

   #include

   #include

   int main()

   {

   char *dev, errbuf[PCAP_ERRBUF_SIZE];

   dev = pcap_lookupdev(errbuf);

   printf("Device: %s", dev);

   return(0);

   }

(2)打開設(shè)備進(jìn)行嗅探

創(chuàng)建一個(gè)嗅探會(huì)話的任務(wù)真的非常簡(jiǎn)單。為此,我們使用pcap_open_live()函數(shù)。此函數(shù)的原型(根據(jù)pcap的手冊(cè)頁(yè))如下:

   pcap_t *pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)

其第一個(gè)參數(shù)是我們?cè)谏弦还?jié)中指定的設(shè)備,snaplen是整形的,它定義了將被pcap捕捉的最大字節(jié)數(shù)。當(dāng)promisc設(shè)為true時(shí)將置指定接口為混雜模式(然而,當(dāng)它置為false時(shí)接口仍處于混雜模式的非凡情況也是有可能的)。to_ms是讀取時(shí)的超時(shí)值,單位是毫秒(假如為0則一直嗅探直到錯(cuò)誤發(fā)生,為-1則不確定)。最后,ebuf是一個(gè)我們可以存入任何錯(cuò)誤信息的字符串(就像上面的errbuf)。此函數(shù)返回其會(huì)話句柄。

混雜模式與非混雜模式的區(qū)別:這兩種方式區(qū)別很大。一般來(lái)說(shuō),非混雜模式的嗅探器中,主機(jī)僅嗅探那些跟它直接有關(guān)的通信,如發(fā)向它的,從它發(fā)出的,或經(jīng)它路由的等都會(huì)被嗅探器捕捉。而在混雜模式中則嗅探傳輸線路上的所有通信。在非交換式網(wǎng)絡(luò)中,這將是整個(gè)網(wǎng)絡(luò)的通信。這樣做最明顯的優(yōu)點(diǎn)就是使更多的包被嗅探到,它們因你嗅探網(wǎng)絡(luò)的原因或者對(duì)你有幫助,或者沒有。但是,混雜模式是可被探測(cè)到的。一個(gè)主機(jī)可以通過(guò)高強(qiáng)度的測(cè)試判定另一臺(tái)主機(jī)是否正在進(jìn)行混雜模式的嗅探。其次,它僅在非交換式的網(wǎng)絡(luò)環(huán)境中有效工作(如集線器,或者交換中的ARP層面)。再次,在高負(fù)荷的網(wǎng)絡(luò)中,主機(jī)的系統(tǒng)資源將消耗的非常嚴(yán)重。

(3)過(guò)濾通信

實(shí)現(xiàn)這一過(guò)程由pcap_compile()與pcap_setfilter()這兩個(gè)函數(shù)完成。

在使用我們自己的過(guò)濾器前必須編譯它。過(guò)濾表達(dá)式被保存在一個(gè)字符串中(字符數(shù)組)。其句法在tcpdump的手冊(cè)頁(yè)中被證實(shí)非常好。我建議你親自閱讀它。但是我們將使用簡(jiǎn)單的測(cè)試表達(dá)式,這樣你可能很輕易理解我的例子。

我們調(diào)用pcap_compile()來(lái)編譯它,其原型是這樣定義的:

   int pcap_compile(pcap_t *p, strUCt bpf_program *fp, char *str, int optimize, bpf_u_int32 netmask)

第一個(gè)參數(shù)是會(huì)話句柄。接下來(lái)的是我們存儲(chǔ)被編譯的過(guò)濾器版本的地址的引用。再接下來(lái)的則是表達(dá)式本身,存儲(chǔ)在規(guī)定的字符串格式里。再下邊是一個(gè)定義表達(dá)式是否被優(yōu)化的整形量(0為false,1為true,標(biāo)準(zhǔn)規(guī)定)。最后,我們必須指定應(yīng)用此過(guò)濾器的網(wǎng)絡(luò)掩碼。函數(shù)返回-1為失敗,其他的任何值都表明是成功的。

表達(dá)式被編譯之后就可以使用了。現(xiàn)在進(jìn)入pcap_setfilter()。仿照我們介紹pcap的格式,先來(lái)看一看pcap_setfilter()的原型:

   int pcap_setfilter(pcap_t *p, struct bpf_program *fp)

這非常直觀,第一個(gè)參數(shù)是會(huì)話句柄,第二個(gè)參數(shù)是被編譯表達(dá)式版本的引用(可推測(cè)出它與pcap_compile()的第二個(gè)參數(shù)相同)。

下面的代碼示例可能能使你更好的理解:

   #include

   pcap_t *handle; /* 會(huì)話的句柄 */

   char dev[] = "eth0"; /* 執(zhí)行嗅探的設(shè)備 */

   char errbuf[PCAP_ERRBUF_SIZE]; /* 存儲(chǔ)錯(cuò)誤 信息的字符串 */

   struct bpf_program filter; /*已經(jīng)編譯好的過(guò)濾表達(dá)式*/

   char filter_app[] = "port 23"; /* 過(guò)濾表達(dá)式*/

   bpf_u_int32 mask; /* 執(zhí)行嗅探的設(shè)備的網(wǎng)絡(luò)掩碼 */

   bpf_u_int32 net; /* 執(zhí)行嗅探的設(shè)備的IP地址 */

   pcap_lookupnet(dev, &net, &mask, errbuf);

   handle = pcap_open_live(dev, BUFSIZ, 1, 0, errbuf);

   pcap_compile(handle, &filter, filter_app, 0, net);

   pcap_setfilter(handle, &filter);

這個(gè)程序使嗅探器嗅探經(jīng)由端口23的所有通信,使用混雜模式,設(shè)備是eth0。

(4)實(shí)際的嗅探

有兩種手段捕捉包。我們可以一次只捕捉一個(gè)包,也可以進(jìn)入一個(gè)循環(huán),等捕捉到多個(gè)包再進(jìn)行處理。我們將先看看怎樣去捕捉單個(gè)包,然后再看看使用循環(huán)的方法。為此,我們使用函數(shù)pcap_next()。

pcap_next()的原型及其簡(jiǎn)單:

   u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h)

第一個(gè)參數(shù)是會(huì)話句柄,第二個(gè)參數(shù)是指向一個(gè)包括了當(dāng)前數(shù)據(jù)包總體信息(被捕捉時(shí)的時(shí)間,包的長(zhǎng)度,其被指定的部分長(zhǎng)度)的結(jié)構(gòu)體的指針(在這里只有一個(gè)片斷,只作為一個(gè)示例)。pcap_next()返回一個(gè)u_char指針給被這個(gè)結(jié)構(gòu)體描述的包。我們將稍后討論這種實(shí)際讀取包本身的手段。

   這里有一個(gè)演示怎樣使用pcap_next()來(lái)嗅探一個(gè)包的例子:

   #include

   #include

   int main()

   {

   pcap_t *handle; /* 會(huì)話句柄 */

   char *dev; /* 執(zhí)行嗅探的設(shè)備 */

   char errbuf[PCAP_ERRBUF_SIZE]; /* 存儲(chǔ)錯(cuò)誤信息的字符串 */

  

   struct bpf_program filter; /* 已經(jīng)編譯好的過(guò)濾器 */

   char filter_app[] = "port 23"; /* 過(guò)濾表達(dá)式 */

   bpf_u_int32 mask; /* 所在網(wǎng)絡(luò)的掩碼 */

   bpf_u_int32 net; /* 主機(jī)的IP地址 */

   struct pcap_pkthdr header; /* 由pcap.h定義 */

   const u_char *packet; /* 實(shí)際的包 */

   /* Define the device */

   dev = pcap_lookupdev(errbuf);

   /* 探查設(shè)備屬性 */

   pcap_lookupnet(dev, &net, &mask, errbuf);

   /* 以混雜模式打開會(huì)話 */

   handle = pcap_open_live(dev, BUFSIZ, 1, 0, errbuf);

   /* 編譯并應(yīng)用過(guò)濾器 */

   pcap_compile(handle, &filter, filter_app, 0, net);

   pcap_setfilter(handle, &filter);

   /* 截獲一個(gè)包 */

   packet = pcap_next(handle, &header);

   /* 打印它的長(zhǎng)度 */

   printf("Jacked a packet with length of [%d]

   ", header.len);

   /* 關(guān)閉會(huì)話 */

   pcap_close(handle);

   return(0);

   }

這個(gè)程序嗅探被pcap_lookupdev()返回的設(shè)備并將它置為混雜模式。它發(fā)現(xiàn)第一個(gè)包經(jīng)過(guò)端口23(telnet)并且告訴用戶此包的大小(以字 節(jié)為單位)。這個(gè)程序又包含了一個(gè)新的調(diào)用pcap_close(),我們將在后面討論(盡管它的名字就足夠證實(shí)它自己的作用)。

實(shí)際上很少有嗅探程序會(huì)真正的使用pcap_next()。通常,它們使用pcap_loop()或者 pcap_dispatch()(它就是用了pcap_loop())。

pcap_loop()的原型如下:

   int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)

第一個(gè)參數(shù)是會(huì)話句柄,接下來(lái)是一個(gè)整型,它告訴pcap_loop()在返回前應(yīng)捕捉多少個(gè)數(shù)據(jù)包(若為負(fù)值則表示應(yīng)該一直工作直至錯(cuò)誤發(fā)生)。第三個(gè)參數(shù)是回調(diào)函數(shù)的名稱(正像其標(biāo)識(shí)符所指,無(wú)括號(hào))。最后一個(gè)參數(shù)在有些應(yīng)用里有用,但更多時(shí)候則置為NULL。假設(shè)我們有我們自己的想送往回調(diào)函數(shù)的參數(shù),另外還有pcap_loop()發(fā)送的參數(shù),這就需要用到它。很明顯,必須是一個(gè)u_char類型的指針以確保結(jié)果正確;正像我們稍后見到的,pcap使用了很有意思的方法以u(píng)_char指針的形勢(shì)傳遞信息。pcap_dispatch()的用法幾乎相同。唯一不同的是它們?nèi)绾翁幚沓瑫r(shí)(還記得在調(diào)用pcap_open_live()時(shí)怎樣設(shè)置超時(shí)嗎?這就是它起作用的地方)。Pcap_loop()忽略超時(shí)而pcap_dispatch()則不。關(guān)于它們之間區(qū)別的更深入的討論請(qǐng)參見pcap的手冊(cè)頁(yè)。

回調(diào)函數(shù)的原型:

   void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet);

讓我們更細(xì)致的考察它。首先,你會(huì)注重到該函數(shù)返回void類型,這是符合邏輯的,因?yàn)閜cap_loop()不知道如何去處理一個(gè)回調(diào)返回值。第一個(gè)參數(shù)相應(yīng)于pcap_loop()的最后一個(gè)參數(shù)。每當(dāng)回調(diào)函數(shù)被老婆 調(diào)用時(shí),無(wú)論最后一個(gè)參數(shù)傳給pcap_loop()什么值,這個(gè)值都會(huì)傳給我們回調(diào)函數(shù)的第一個(gè)參數(shù)。第二個(gè)參數(shù)是pcap頭文件定義的,它包括數(shù)據(jù)包被嗅探的時(shí)間、大小等信息。結(jié)構(gòu)體pcap_pkhdr在pcap.h中定義如下:

   struct pcap_pkthdr {

   struct timeval ts; /* 時(shí)間戳 */

   bpf_u_int32 caplen; /* 已捕捉部分的長(zhǎng)度 */

   bpf_u_int32 len; /* 該包的脫機(jī)長(zhǎng)度 */

   };

這些量都相當(dāng)明了。最后一個(gè)參數(shù)在它們中是最有意思的,也最讓pcap程序新手感到迷惑。這又是一個(gè)u_char指針,它包含了被pcap_loop()嗅探到的所有包。

但是你怎樣使用這個(gè)我們?cè)谠屠锓Q為packet的變量呢?一個(gè)數(shù)據(jù)包包含許多屬性,因此你可以想象它不只是一個(gè)字符串,而實(shí)質(zhì)上是一個(gè)結(jié)構(gòu)體的集合(比如,一個(gè)TCP/IP包會(huì)有一個(gè)以太網(wǎng)的頭部,一個(gè)IP頭部,一個(gè)TCP頭部,還有此包的有效載荷)。這個(gè)u_char就是這些結(jié)構(gòu)體的串聯(lián)版本。為了使用它,我們必須作一些有趣的匹配工作。

下面這些是一些數(shù)據(jù)包的結(jié)構(gòu)體:

   /* 以太網(wǎng)幀頭部 */

   struct sniff_ethernet {

   u_char ether_dhost[ETHER_ADDR_LEN]; /* 目的主機(jī)的地址 */

   u_char ether_shost[ETHER_ADDR_LEN]; /* 源主機(jī)的地址 */

   u_short ether_type; /* IP? ARP? RARP? etc */

   };

   /* IP數(shù)據(jù)包的頭部 */

   struct sniff_ip {

   #if BYTE_ORDER == LITTLE_ENDIAN

   u_int ip_hl:4, /* 頭部長(zhǎng)度 */

   ip_v:4; /* 版本號(hào) */

   #if BYTE_ORDER == BIG_ENDIAN

   u_int ip_v:4, /* 版本號(hào) */

   ip_hl:4; /* 頭部長(zhǎng)度 */

   #endif

   #endif /* not _IP_VHL */

   u_char ip_tos; /* 服務(wù)的類型 */

   u_short ip_len; /* 總長(zhǎng)度 */

   u_short ip_id; /*包標(biāo)志號(hào) */

   u_short ip_off; /* 碎片偏移 */

   #define IP_RF 0x8000 /* 保留的碎片標(biāo)志 */

   #define IP_DF 0x4000 /* dont fragment flag */

   #define IP_MF 0x2000 /* 多碎片標(biāo)志*/

   #define IP_OFFMASK 0x1fff /*分段位 */

   u_char ip_ttl; /* 數(shù)據(jù)包的生存時(shí)間 */

   u_char ip_p; /* 所使用的協(xié)議 */

   u_short ip_sum; /* 校驗(yàn)和 */

   struct in_addr ip_src,ip_dst; /* 源地址、目的地址*/

   };

   /* TCP 數(shù)據(jù)包的頭部 */

   struct sniff_tcp {

   u_short th_sport; /* 源端口 */

   u_short th_dport; /* 目的端口 */

   tcp_seq th_seq; /* 包序號(hào) */

   tcp_seq th_ack; /* 確認(rèn)序號(hào) */

   #if BYTE_ORDER == LITTLE_ENDIAN

   u_int th_x2:4, /* 還沒有用到 */

   th_off:4; /* 數(shù)據(jù)偏移 */

   #endif

   #if BYTE_ORDER == BIG_ENDIAN

   u_int th_off:4, /* 數(shù)據(jù)偏移*/

   th_x2:4; /*還沒有用到 */

   #endif

   u_char th_flags;

   #define TH_FIN 0x01

   #define TH_SYN 0x02

   #define TH_RST 0x04

   #define TH_PUSH 0x08

   #define TH_ACK 0x10

   #define TH_URG 0x20

   #define TH_ECE 0x40

   #define TH_CWR 0x80

   #define TH_FLAGS (TH_FINTH_SYNTH_RSTTH_ACKTH_URGTH_ECETH_CWR)

   u_short th_win; /* TCP滑動(dòng)窗口 */

   u_short th_sum; /* 頭部校驗(yàn)和 */

   u_short th_urp; /* 緊急服務(wù)位 */

   };

pcap嗅探數(shù)據(jù)包時(shí)正是使用的這些結(jié)構(gòu)。接下來(lái),它簡(jiǎn)單的創(chuàng)建一個(gè)u_char字符串并且將這些結(jié)構(gòu)體填入。那么我們?cè)鯓硬拍軈^(qū)分它們呢?預(yù)備好見證指針最實(shí)用的好處之一吧。

我們?cè)僖淮渭俣ㄒ獙?duì)以太網(wǎng)上的TCP/IP包進(jìn)行處理。同樣的手段可以應(yīng)用于任何數(shù)據(jù)包,唯一的區(qū)別是你實(shí)際所使用的結(jié)構(gòu)體的類型。讓我們從聲明分解u_char包的變量開始:

   const struct sniff_ethernet *ethernet; /* 以太網(wǎng)幀頭部*/

   const struct sniff_ip *ip; /* IP包頭部 */

   const struct sniff_tcp *tcp; /* TCP包頭部 */

   const char *payload; /* 數(shù)據(jù)包的有效載荷*/

   /*為了讓它的可讀性好,我們計(jì)算每個(gè)結(jié)構(gòu)體中的變量大小*/

   int size_ethernet = sizeof(struct sniff_ethernet);

   int size_ip = sizeof(struct sniff_ip);

   int size_tcp = sizeof(struct sniff_tcp);

   現(xiàn)在我們開始讓人感到有些神秘的匹配:

   ethernet = (struct sniff_ethernet*)(packet);

   ip = (struct sniff_ip*)(packet + size_ethernet);

   tcp = (struct sniff_tcp*)(packet + size_ethernet + size_ip);

   payload = (u_char *)(packet + size_ethernet + size_ip + size_tcp);

  

此處如何工作?考慮u_char在內(nèi)存中的層次。基本的,當(dāng)pcap將這些結(jié)構(gòu)體填入u_char的時(shí)候是將這些數(shù)據(jù)存入一個(gè)字符串中,那個(gè)字符串將被送入我們的回調(diào)函數(shù)中。反向轉(zhuǎn)換是這樣的,不考慮這些結(jié)構(gòu)體制中的值,它們的大小將是一致的。例如在我的平臺(tái)上,一個(gè)sniff_ethernet結(jié)構(gòu)體的大小是14字節(jié)。一個(gè)sniff_ip結(jié)構(gòu)體是20字節(jié),一個(gè)sniff_tcp結(jié)構(gòu)體也是20字節(jié)。 u_char指針正是包含了內(nèi)存地址的一個(gè)變量,這也是指針的實(shí)質(zhì),它指向內(nèi)存的一個(gè)區(qū)域。簡(jiǎn)單而言,我們說(shuō)指針指向的地址為x,假如三個(gè)結(jié)構(gòu)體恰好線性排列,第一個(gè)(sniff_ethernet)被裝載到內(nèi)存地址的x處則我們很輕易的發(fā)現(xiàn)其他結(jié)構(gòu)體的地址,讓我們以表格顯示之:

   Variable Location (in bytes)

   sniff_ethernet X

   sniff_ip X + 14

   sniff_tcp X + 14 + 20

   payload X + 14 + 20 + 20

結(jié)構(gòu)體sniff_ethernet正好在x處,緊接著它的sniff_ip則位于x加上它本身占用的空間(此例為14字節(jié)),依此類推可得全部地址。

注重:你沒有假定你的變量也是同樣大小是很重要的。你應(yīng)該總是使用sizeof()來(lái)確保尺寸的正確。這是因?yàn)檫@些結(jié)構(gòu)體中的每個(gè)成員在不同平臺(tái)下可以有不同的尺寸。

?

下面是主要函數(shù)接口:

pcap_t *pcap_open_live(char *device, int snaplen,

?? int promisc, int to_ms, char *ebuf)

?? 獲得用于捕獲網(wǎng)絡(luò)數(shù)據(jù)包的數(shù)據(jù)包捕獲描述字。device參數(shù)為指定打開

?? 的網(wǎng)絡(luò)設(shè)備名。snaplen參數(shù)定義捕獲數(shù)據(jù)的最大字節(jié)數(shù)。promisc指定

?? 是否將網(wǎng)絡(luò)接口置于混雜模式。to_ms參數(shù)指定超時(shí)時(shí)間(毫秒)。

?? ebuf參數(shù)則僅在pcap_open_live()函數(shù)出錯(cuò)返回NULL時(shí)用于傳遞錯(cuò)誤消

?? 息。

pcap_t *pcap_open_offline(char *fname, char *ebuf)

?? 打開以前保存捕獲數(shù)據(jù)包的文件,用于讀取。fname參數(shù)指定打開的文

?? 件名。該文件中的數(shù)據(jù)格式與tcpdump和tcpslice兼容。"-"為標(biāo)準(zhǔn)輸

?? 入。ebuf參數(shù)則僅在pcap_open_offline()函數(shù)出錯(cuò)返回NULL時(shí)用于傳

?? 遞錯(cuò)誤消息。

pcap_dumper_t *pcap_dump_open(pcap_t *p, char *fname)

?? 打開用于保存捕獲數(shù)據(jù)包的文件,用于寫入。fname參數(shù)為"-"時(shí)表示

?? 標(biāo)準(zhǔn)輸出。出錯(cuò)時(shí)返回NULL。p參數(shù)為調(diào)用pcap_open_offline()或

?? pcap_open_live()函數(shù)后返回的pcap結(jié)構(gòu)指針。fname參數(shù)指定打開

?? 的文件名。如果返回NULL,則可調(diào)用pcap_geterr()函數(shù)獲取錯(cuò)誤消

?? 息。

?

char *pcap_lookupdev(char *errbuf)

?? 用于返回可被pcap_open_live()或pcap_lookupnet()函數(shù)調(diào)用的網(wǎng)絡(luò)

?? 設(shè)備名指針。如果函數(shù)出錯(cuò),則返回NULL,同時(shí)errbuf中存放相關(guān)的

?? 錯(cuò)誤消息。

int pcap_lookupnet(char *device, bpf_u_int32 *netp,

?? bpf_u_int32 *maskp, char *errbuf)

?? 獲得指定網(wǎng)絡(luò)設(shè)備的網(wǎng)絡(luò)號(hào)和掩碼。netp參數(shù)和maskp參數(shù)都是

?? bpf_u_int32指針。如果函數(shù)出錯(cuò),則返回-1,同時(shí)errbuf中存放相

?? 關(guān)的錯(cuò)誤消息。

int pcap_dispatch(pcap_t *p, int cnt,

?? pcap_handler callback, u_char *user)

?? 捕獲并處理數(shù)據(jù)包。cnt參數(shù)指定函數(shù)返回前所處理數(shù)據(jù)包的最大值。

?? cnt=-1表示在一個(gè)緩沖區(qū)中處理所有的數(shù)據(jù)包。cnt=0表示處理所有

?? 數(shù)據(jù)包,直到產(chǎn)生以下錯(cuò)誤之一:讀取到EOF;超時(shí)讀取。callback

?? 參數(shù)指定一個(gè)帶有三個(gè)參數(shù)的回調(diào)函數(shù),這三個(gè)參數(shù)為:一個(gè)從

?? pcap_dispatch()函數(shù)傳遞過(guò)來(lái)的u_char指針,一個(gè)pcap_pkthdr結(jié)構(gòu)

?? 的指針,和一個(gè)數(shù)據(jù)包大小的u_char指針。如果成功則返回讀取到的

?? 字節(jié)數(shù)。讀取到EOF時(shí)則返回零值。出錯(cuò)時(shí)則返回-1,此時(shí)可調(diào)用

?? pcap_perror()或pcap_geterr()函數(shù)獲取錯(cuò)誤消息。

int pcap_loop(pcap_t *p, int cnt,

?? pcap_handler callback, u_char *user)

?? 功能基本與pcap_dispatch()函數(shù)相同,只不過(guò)此函數(shù)在cnt個(gè)數(shù)據(jù)包

?? 被處理或出現(xiàn)錯(cuò)誤時(shí)才返回,但讀取超時(shí)不會(huì)返回。而如果為

?? pcap_open_live()函數(shù)指定了一個(gè)非零值的超時(shí)設(shè)置,然后調(diào)用

?? pcap_dispatch()函數(shù),則當(dāng)超時(shí)發(fā)生時(shí)pcap_dispatch()函數(shù)會(huì)返回。

?? cnt參數(shù)為負(fù)值時(shí)pcap_loop()函數(shù)將始終循環(huán)運(yùn)行,除非出現(xiàn)錯(cuò)誤。

void pcap_dump(u_char *user, struct pcap_pkthdr *h,

?? u_char *sp)

?? 向調(diào)用pcap_dump_open()函數(shù)打開的文件輸出一個(gè)數(shù)據(jù)包。該函數(shù)可

?? 作為pcap_dispatch()函數(shù)的回調(diào)函數(shù)。

int pcap_compile(pcap_t *p, struct bpf_program *fp,

?? char *str, int optimize, bpf_u_int32 netmask)

?? 將str參數(shù)指定的字符串編譯到過(guò)濾程序中。fp是一個(gè)bpf_program結(jié)

?? 構(gòu)的指針,在pcap_compile()函數(shù)中被賦值。optimize參數(shù)控制結(jié)果

?? 代碼的優(yōu)化。netmask參數(shù)指定本地網(wǎng)絡(luò)的網(wǎng)絡(luò)掩碼。

int pcap_setfilter(pcap_t *p, struct bpf_program *fp)

?? 指定一個(gè)過(guò)濾程序。fp參數(shù)是bpf_program結(jié)構(gòu)指針,通常取自

?? pcap_compile()函數(shù)調(diào)用。出錯(cuò)時(shí)返回-1;成功時(shí)返回0。

u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h)

?? 返回指向下一個(gè)數(shù)據(jù)包的u_char指針。

int pcap_datalink(pcap_t *p)

?? 返回?cái)?shù)據(jù)鏈路層類型,例如DLT_EN10MB。

int pcap_snapshot(pcap_t *p)

?? 返回pcap_open_live被調(diào)用后的snapshot參數(shù)值。

int pcap_is_swapped(pcap_t *p)

?? 返回當(dāng)前系統(tǒng)主機(jī)字節(jié)與被打開文件的字節(jié)順序是否不同。

int pcap_major_version(pcap_t *p)

?? 返回寫入被打開文件所使用的pcap函數(shù)的主版本號(hào)。

int pcap_minor_version(pcap_t *p)

?? 返回寫入被打開文件所使用的pcap函數(shù)的輔版本號(hào)。

int pcap_stats(pcap_t *p, struct pcap_stat *ps)

?? 向pcap_stat結(jié)構(gòu)賦值。成功時(shí)返回0。這些數(shù)值包括了從開始

?? 捕獲數(shù)據(jù)以來(lái)至今共捕獲到的數(shù)據(jù)包統(tǒng)計(jì)。如果出錯(cuò)或不支持

?? 數(shù)據(jù)包統(tǒng)計(jì),則返回-1,且可調(diào)用pcap_perror()或

?? pcap_geterr()函數(shù)來(lái)獲取錯(cuò)誤消息。

FILE *pcap_file(pcap_t *p)

?? 返回被打開文件的文件名。

int pcap_fileno(pcap_t *p)

?? 返回被打開文件的文件描述字號(hào)碼。

void pcap_perror(pcap_t *p, char *prefix)

?? 在標(biāo)準(zhǔn)輸出設(shè)備上顯示最后一個(gè)pcap庫(kù)錯(cuò)誤消息。以prefix參

?? 數(shù)指定的字符串為消息頭。

char *pcap_geterr(pcap_t *p)

?? 返回最后一個(gè)pcap庫(kù)錯(cuò)誤消息。

char *pcap_strerror(int error)

?? 如果strerror()函數(shù)不可用,則可調(diào)用pcap_strerror函數(shù)替代。

void pcap_close(pcap_t *p)

?? 關(guān)閉p參數(shù)相應(yīng)的文件,并釋放資源。

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的libpcap讲解与API接口函数讲解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

高潮久久久久久 | 91精品视屏 | 美女av免费看 | 日本中文在线播放 | av不卡网站 | 成人在线观看资源 | 九九久久视频 | 在线观看国产区 | 亚洲成人av电影在线 | 国产va精品免费观看 | 中文字幕 国产 一区 | 91精品视频一区二区三区 | 中文字幕精品三级久久久 | 国产精品免费一区二区 | 日韩电影一区二区三区在线观看 | 五月综合激情网 | 久久99精品国产麻豆宅宅 | 啪啪资源 | 欧美久久综合 | 在线观看一区视频 | 天天干天天上 | 日本久久久久久 | 国产精品欧美一区二区三区不卡 | 中文字幕国语官网在线视频 | 日韩免| 丝袜护士aⅴ在线白丝护士 天天综合精品 | 精品999| 99热九九这里只有精品10 | 亚洲黄色三级 | 免费黄色看片 | 久久亚洲精品电影 | 久久一本综合 | 日本中文字幕免费观看 | 99r精品视频在线观看 | 91精选在线观看 | 日韩黄色影院 | 精品网站999www | 激情欧美xxxx | 久久亚洲人| 久久一区二区免费视频 | 午夜精品久久久久久久爽 | 国产精品色婷婷视频 | 成人在线网站观看 | 久久国际影院 | www激情com | 缴情综合网五月天 | 91中文字幕在线播放 | 国产精品久久综合 | 中文字幕一区二区三区四区在线视频 | 99日韩精品 | 久久99国产视频 | 婷婷色网站 | 国产伦理一区二区 | 黄色片网站av | 91精品国产一区二区三区 | 在线观看你懂的网址 | 99精品一区二区 | 在线看日韩av | 久久久久国产精品厨房 | 99中文字幕视频 | 日韩三级久久 | 人人搞人人搞 | 天天操天天舔天天爽 | 日韩中文字幕免费视频 | 九九视频精品免费 | 久在线 | 国产精品乱码一区二三区 | 亚州性色 | 天天操天天摸天天射 | 久久精品综合 | 91日韩精品一区 | 久久久久久久久黄色 | 久久国产a | 精品久久久久久亚洲综合网 | 日韩精品一区二区免费视频 | 日韩a在线观看 | 亚洲理论在线观看电影 | 91视频国产免费 | 在线观看韩日电影免费 | 深夜免费福利视频 | 91少妇精拍在线播放 | 最新av网址在线观看 | 日本 在线 视频 中文 有码 | 精品国产一区二区三区四区在线观看 | 高潮毛片无遮挡高清免费 | 探花视频在线版播放免费观看 | 国产成人不卡 | 色综合久久久久综合 | 日韩经典一区二区三区 | 视频国产精品 | 久久女教师 | 中文在线字幕免费观 | 综合铜03 | 日韩在线高清视频 | 丁香婷五月 | 99麻豆视频 | 五月婷婷在线视频 | 国产一二三四在线观看视频 | 久久国产精品系列 | 精品免费| 91精品一区二区三区蜜臀 | 久久综合欧美精品亚洲一区 | 天天射天天做 | 久久99久久99精品中文字幕 | 黄网站免费久久 | 国产精品99久久久久久小说 | 婷婷激情欧美 | 一区二区视频网站 | 国产成人黄色在线 | 狠狠操夜夜操 | 九九精品视频在线观看 | 欧美精品久 | 国产精久久久久久妇女av | 2020天天干夜夜爽 | 国产中文自拍 | 日韩精品在线观看av | 国产精品一区二区三区在线 | 久久久婷 | 毛片网在线观看 | 正在播放亚洲精品 | 二区中文字幕 | 婷婷深爱网 | 国产成人一区在线 | 久久视频免费在线观看 | 久艹在线免费观看 | 久久99国产精品久久 | 成年人三级网站 | 五月天六月婷 | 免费亚洲电影 | 99这里只有精品视频 | 最新国产精品拍自在线播放 | 中文字幕在线观看第一页 | 三级视频片 | 在线免费色 | 精品国产一区二区久久 | 视频在线观看入口黄最新永久免费国产 | 最新av在线网址 | 日本午夜在线亚洲.国产 | 亚洲国产999 | 日韩乱码中文字幕 | 精品视频专区 | 久草免费福利在线观看 | 91精品国自产在线观看 | 成人污视频在线观看 | av成人在线观看 | 久草在线91 | 国产色视频一区二区三区qq号 | 国产精品久久久av | 日韩在线看片 | 波多野结衣久久精品 | 99国产精品一区二区 | 色噜噜日韩精品欧美一区二区 | 久草视频精品 | 国产午夜亚洲精品 | 国产精品激情偷乱一区二区∴ | 亚洲欧美成人在线 | 成人动漫视频在线 | 国产精品毛片一区 | 免费看污片 | 亚洲日本va在线观看 | 国产精品久久久一区二区三区网站 | 国产福利小视频在线 | 午夜精品婷婷 | 精品视频成人 | 色www精品视频在线观看 | 99国产一区 | 天天艹天天干天天 | 亚洲黄网址| 亚洲精品美女在线观看播放 | 91免费在线视频 | 狠狠狠色丁香综合久久天下网 | 香蕉视频91 | 中文资源在线官网 | 在线免费观看国产 | 五月婷视频 | 超碰在线人 | 天天搞夜夜骑 | 国产91在线免费视频 | 国产无限资源在线观看 | www.av在线播放 | 国产精品成人久久久 | 在线观看亚洲国产精品 | 91麻豆精品91久久久久同性 | 久久艹免费 | 婷婷中文字幕在线观看 | 一级一级一片免费 | 国产成人av综合色 | 久久精品欧美一区二区三区麻豆 | 爱情影院aqdy鲁丝片二区 | 成人国产精品久久久春色 | 天堂av免费在线 | 午夜久久久久久久久久久 | 欧美日韩国产精品一区 | 天天干天天射天天插 | 91香蕉视频| 国产精品国产三级国产 | 亚洲欧美精品一区二区 | 久久婷亚洲五月一区天天躁 | 成人天堂网 | 91污在线观看 | 麻豆成人在线观看 | 日韩精品在线一区 | 久久视频在线免费观看 | 99在线观看精品 | 91精品日韩| 国产精品久久人 | 天天爽天天射 | 久草网站 | 四虎5151久久欧美毛片 | 久久66热这里只有精品 | 99视频免费观看 | 国产日韩欧美网站 | 在线视频 区 | 免费a一级 | 国产高清在线a视频大全 | 91视频成人免费 | 97免费中文视频在线观看 | 久久久久国产a免费观看rela | 韩日精品在线 | 2022久久国产露脸精品国产 | 国产精品色视频 | 亚洲国产三级 | 国产免费精彩视频 | 亚洲成a人片在线观看中文 中文字幕在线视频第一页 狠狠色丁香婷婷综合 | 国产精品一区二区免费视频 | 日韩理论视频 | 五月天综合婷婷 | 99热99热| 欧美老人xxxx18 | 超碰官网 | 免费在线观看毛片网站 | 91人人澡人人爽人人精品 | 在线 日韩 av| 日本视频网 | 中文亚洲欧美日韩 | 日本三级不卡视频 | 久久男人影院 | 中文字幕 91 | 丁香六月激情婷婷 | 久久一区二区三区超碰国产精品 | 91香蕉视频色版 | 三级视频国产 | 日韩免费在线一区 | 国产精品久久久久久久av大片 | av资源免费在线观看 | 国产精品久久久久一区二区国产 | 911香蕉视频| 欧美日韩精品在线观看视频 | 激情五月伊人 | 三级在线国产 | 成人四虎 | 色噜噜狠狠狠狠色综合 | 国产精品久久久一区二区三区网站 | www.狠狠 | 狠狠操导航 | 最新国产精品拍自在线播放 | 久草网站 | 99热在线精品观看 | 狠狠狠狠狠色综合 | 天堂视频中文在线 | 色综合久久久久久中文网 | 久久国产精品久久久久 | 午夜久久福利 | 精品电影一区 | 超碰在线亚洲 | 人人爽久久久噜噜噜电影 | 国产黄色视| 在线看国产一区 | 婷婷六月久久 | 亚洲va欧美va国产va黑人 | 91精品欧美一区二区三区 | 一区二区三区视频 | 国产成人精品女人久久久 | 久久国产精品久久国产精品 | 999亚洲国产996395 | 亚洲一区二区精品3399 | 在线观看成人国产 | 日韩国产精品久久久久久亚洲 | 在线观看涩涩 | 蜜臀av网址 | 成人在线一区二区三区 | av亚洲产国偷v产偷v自拍小说 | 国产黄色播放 | 国产精品久久久区三区天天噜 | 在线视频成人 | 青草视频在线 | 欧美久久久一区二区三区 | 91丨精品丨蝌蚪丨白丝jk | 亚洲va综合va国产va中文 | 欧美精品黑人性xxxx | 久久成年人 | 91麻豆国产福利在线观看 | 91看片淫黄大片一级在线观看 | 九九免费精品 | 网站免费黄 | 日本中文字幕在线一区 | 久久国产视屏 | 丁香激情视频 | 99 久久久久 | 最新亚洲视频 | 九九久久久久99精品 | 一级免费看视频 | 中文字幕av有码 | 久热免费| 99热9| 在线日韩 | 国产成人久久77777精品 | 91九色蝌蚪在线 | 中文字幕国产视频 | 国产美女搞久久 | 日日爽夜夜操 | 91精选在线 | 国内一级片在线观看 | 日韩欧美大片免费观看 | 久草视频中文 | 五月天激情视频在线观看 | 日韩欧美综合视频 | 91视频在线免费看 | av丁香 | 999久久国精品免费观看网站 | 亚洲精品麻豆 | 久久综合成人网 | 久久久久久久久久免费视频 | 911久久香蕉国产线看观看 | 久久午夜电影网 | 国产成人av在线 | 色欧美88888久久久久久影院 | 国产精品美女久久久久久久 | 久久久久亚洲精品中文字幕 | 免费激情网| 手机av电影在线观看 | 91日韩免费 | 美女黄频免费 | 色综合天天狠天天透天天伊人 | 色综合天天 | 视频直播国产精品 | 中文字幕有码在线观看 | av大片免费 | 一区二区三区四区精品视频 | 99久久久久国产精品免费 | 久久se视频| 天天爽夜夜爽人人爽一区二区 | 中文字幕在线一二 | 色综合久久88色综合天天人守婷 | 久久婷婷丁香 | 五月激情丁香婷婷 | 日韩视频二区 | 国产成人一区二区三区在线观看 | 国产免费观看高清完整版 | 91麻豆视频| 国产高清黄 | 91亚洲精品国偷拍 | 国产精品尤物视频 | 午夜影视剧场 | 免费精品人在线二线三线 | 久久你懂得 | 香蕉网在线播放 | 91av国产视频 | 日本韩国中文字幕 | 天天天天色射综合 | 婷婷久久综合九色综合 | av在线播放观看 | 不卡的一区二区三区 | 日韩在线观看一区二区三区 | 亚洲精品综合久久 | 久久精品中文字幕免费mv | 国产黄色在线看 | 国产精品麻豆欧美日韩ww | 欧美另类69| 成人cosplay福利网站 | 最新极品jizzhd欧美 | 超碰av在线播放 | 91亚洲精品在线观看 | 在线免费观看黄网站 | 久久99久久99精品中文字幕 | 超碰公开在线 | 免费在线观看视频一区 | 国内精品久久久 | 视频一区二区精品 | 国产原创在线观看 | 在线播放av网址 | 国产一级视频在线观看 | 免费精品视频在线观看 | 久久久久久久久久久久久影院 | 婷婷精品国产欧美精品亚洲人人爽 | 91免费观看视频在线 | 人人添人人 | 久久婷婷国产色一区二区三区 | 国产精品免费观看国产网曝瓜 | 美女视频又黄又免费 | 九九九热 | 一区二区电影网 | 亚洲最新毛片 | 午夜久久电影网 | 很黄很色很污的网站 | 有没有在线观看av | 日韩国产精品久久久久久亚洲 | 激情五月婷婷 | 国产麻豆剧传媒免费观看 | 香蕉精品视频在线观看 | 正在播放五月婷婷狠狠干 | 久久影视中文字幕 | 国产精品av电影 | 久久九九精品 | 国产综合精品久久 | 免费福利影院 | 欧美色图亚洲图片 | 久久久久久国产精品免费 | 久久久激情网 | 成人免费观看视频大全 | 午夜色婷婷 | 色综合天天色 | 国产一级在线免费观看 | 日韩精品不卡在线观看 | 国产九九九视频 | 国产高清无av久久 | 久久精品资源 | 水蜜桃亚洲一二三四在线 | 午夜久久福利影院 | 婷婷网在线| 亚洲国产欧美在线看片xxoo | 超级碰视频 | av资源免费在线观看 | 国产分类视频 | 人人爽网站| 中文字幕日本在线观看 | 亚洲理论在线观看 | 一区在线免费观看 | 免费av试看 | 91久久国产露脸精品国产闺蜜 | 中文字幕二区在线观看 | 中文av影院 | 午夜久久久久久久 | 久久免费看a级毛毛片 | 色综合久久久久 | 中文字幕乱码电影 | 日韩乱码中文字幕 | 久久久久网站 | 69国产在线观看 | 国产字幕av| 91视频免费网址 | 久久99精品久久久久久三级 | 久久人人爽爽人人爽人人片av | 精品国产区 | 日日夜日日干 | av一级免费 | 91精品国产福利 | 国产一区久久 | 日本爽妇网 | 超级碰碰免费视频 | 日韩av一区二区三区在线观看 | 99久久99视频只有精品 | 久久夜色精品国产亚洲aⅴ 91chinesexxx | 成人97视频一区二区 | 天天天操操操 | 国产亚洲精品成人av久久ww | 国产精品久久三 | 成人全视频免费观看在线看 | 一级黄色视屏 | 99精品国产成人一区二区 | 久久成人18免费网站 | 欧美日韩伦理一区 | 操高跟美女 | 狠狠天天| 久久在草 | 日韩性xxxx | 日韩在线免费看 | 成人小视频在线免费观看 | 免费国产在线观看 | 九九热久久免费视频 | 久久久久电影网站 | 欧洲在线免费视频 | 99视频精品免费视频 | 91超在线 | 美女在线免费观看视频 | 91麻豆精品91久久久久同性 | 国产手机在线视频 | av中文在线观看 | 久久精品一区二区三区国产主播 | 亚洲精品乱码白浆高清久久久久久 | 99国产精品一区 | 麻豆视频免费入口 | 精品字幕在线 | 日日干日日 | 国产丝袜网站 | 国产精品麻豆果冻传媒在线播放 | 日韩免费福利 | 久久精品亚洲综合专区 | 国产1区2区3区精品美女 | 91中文字幕在线观看 | 4p变态网欧美系列 | 国产黄色播放 | 欧美精品中文 | 国内精品久久久久久 | 婷婷综合av| 国产在线观看不卡 | 久久男人中文字幕资源站 | 成人免费亚洲 | 成人免费视频a | 夜夜躁狠狠燥 | 成人av免费在线播放 | 国产99在线免费 | 精品久久久久久亚洲综合网站 | 国产在线观看黄 | 人人爽人人爽人人爽人人爽 | 91中文字幕网 | 日韩三级免费观看 | 麻豆精品视频在线 | 午夜精品剧场 | 日韩在线电影一区二区 | 国产精品福利在线播放 | 国产一级性生活 | 在线视频 你懂得 | 黄色网址av | 午夜精品一区二区三区在线观看 | 超级碰99| japanesexxxhd奶水| 色视频网站在线观看一=区 a视频免费在线观看 | 91秒拍国产福利一区 | 国产精品久久99综合免费观看尤物 | 99色免费 | 国产精品久久久一区二区三区网站 | 久久免费视频这里只有精品 | 免费韩国av | 黄色大片入口 | www国产一区 | 激情欧美国产 | 亚洲天堂在线观看完整版 | 国产视频亚洲视频 | 超碰免费久久 | 久久国产精品99久久久久久进口 | 日韩激情视频 | 欧美一区二区伦理片 | 中文字幕专区高清在线观看 | 色婷婷狠 | 97超碰人人模人人人爽人人爱 | 园产精品久久久久久久7电影 | 国产一区精品在线 | 久久99国产精品免费 | 激情欧美在线观看 | 五月花激情| 久久五月精品 | 中文字幕网址 | 91精品久久久久久久91蜜桃 | 国产99久久久欧美黑人 | 中文字幕在线观看免费高清完整版 | 在线视频你懂 | 国内精品久久影院 | 中文字幕在线视频网站 | 亚洲欧美在线观看视频 | 国产精品第二十页 | 婷婷综合五月天 | 久草观看| 香蕉视频一级 | 日日夜夜免费精品视频 | 天天草天天爽 | 99精品在线免费观看 | 激情欧美丁香 | 7777精品伊人久久久大香线蕉 | 91成人短视频在线观看 | 欧美精品在线观看免费 | 亚洲成人999 | 97**国产露脸精品国产 | 一级电影免费在线观看 | 久久99久久精品 | 一区二区三区四区五区在线视频 | 99理论片| 亚洲精品中文字幕视频 | 日韩激情影院 | 色综合久久88色综合天天人守婷 | 色中色亚洲 | 91毛片在线 | 91在线精品秘密一区二区 | 久久经典国产 | 激情开心网站 | 一级电影免费在线观看 | 97色涩| 久草久草在线观看 | 国产精品免费成人 | 久久不卡视频 | 免费看短 | 亚州欧美精品 | 五月天免费网站 | 在线看黄网站 | 精品国产乱码久久久久 | 黄色一级在线免费观看 | 亚洲高清色综合 | 狠狠干激情 | 成年人免费av | 黄色精品在线看 | 在线观看91网站 | jizz999| 91av蜜桃| 日日干影院| 成年人免费观看国产 | 精品国产乱码久久久久久1区2匹 | 久久天堂影院 | 欧美视频18 | 久久爱992xxoo| av在线电影免费观看 | 久久国产欧美日韩 | 精品久久久久久亚洲综合网站 | 免费欧美精品 | 国产综合香蕉五月婷在线 | 亚洲精品国产自产拍在线观看 | 成人久久精品 | 国产精品免费久久久久影院仙踪林 | 天天曰天天| 在线激情影院一区 | 久久影院午夜论 | 亚洲理论在线观看电影 | 色婷婷丁香 | 午夜久久久久久久久 | 91麻豆精品国产91久久久无限制版 | 97av在线| 国产美女在线精品免费观看 | 久久免费国产精品1 | 99视频+国产日韩欧美 | 久热av在线| 一区二区视频电影在线观看 | 激情欧美xxxx | 福利二区视频 | 国产在线精品一区二区三区 | 国产破处视频在线播放 | 97在线播放视频 | 国产综合91 | 国际av在线 | 伊人婷婷综合 | 日韩精品视频免费看 | 亚洲精品久久激情国产片 | 成人一级影视 | 国产在线色站 | 狠狠狠色狠狠色综合 | 久草成人在线 | 国产成人精品一区二区三区网站观看 | 久久久久久97三级 | 亚洲精品乱码久久久久久蜜桃91 | 91成人网在线观看 | 色99视频 | 午夜三级理论 | 91chinese在线 | 亚洲人成在线观看 | 九九热.com| 国内精品久久久久久久影视简单 | 国产成人久久精品77777综合 | 精品视频999 | 亚洲精品久久久久999中文字幕 | 在线精品视频免费观看 | 亚洲高清久久久 | 在线精品视频免费播放 | 中文字幕一区二区三区在线观看 | 97视频在线免费 | 亚洲乱码中文字幕综合 | 99精品视频免费观看 | 国产中文欧美日韩在线 | 久久草网| 国产成人高清在线 | 久久女同性恋中文字幕 | 不卡的一区二区三区 | 亚洲日韩中文字幕在线播放 | 日韩影视大全 | 久久久久亚洲国产 | 九九日韩 | 伊人久久一区 | 色99在线| 欧美成人精品欧美一级乱 | 国产 欧美 日韩 | 伊人黄 | 天天操人人干 | 97视频在线观看免费 | 日韩欧美在线视频一区二区三区 | 伊人五月在线 | 亚洲年轻女教师毛茸茸 | 国产亚洲精品久久久久久 | 亚州av网站| 欧美精品亚州精品 | 99久久国产免费看 | 亚洲欧美日韩一级 | 最新av观看 | 在线观看国产亚洲 | 日本高清免费中文字幕 | 婷婷在线五月 | 成人午夜av电影 | 午夜视频99 | 高清国产在线一区 | 伊人狠狠操 | 国产麻豆精品久久一二三 | 国产96在线观看 | 久久久久久久久久久网站 | 欧美日韩不卡一区二区 | 播五月婷婷 | 国产成人精品一区二区在线观看 | 热九九精品 | 国产色在线观看 | 国产精品成人自产拍在线观看 | 欧美日韩国产一二三区 | 日日干日日| 国产色婷婷在线 | 久色网 | 天天天射| 日韩中文字幕免费视频 | 97免费在线观看视频 | 免费看片网站91 | 国产精品欧美一区二区 | 久久精品综合视频 | 国产成人久久精品亚洲 | 国产亚洲久一区二区 | 四虎伊人| 欧美日韩精品在线免费观看 | 亚洲丁香日韩 | 国产亚洲成人网 | 在线国产91| 亚洲天天摸日日摸天天欢 | 狠狠躁夜夜躁人人爽超碰97香蕉 | 黄色电影网站在线观看 | www.在线看片.com | 日日夜操 | 国产福利一区二区三区在线观看 | 在线免费观看国产视频 | 人人草在线视频 | 色噜噜在线观看 | 在线视频福利 | 亚洲欧美日韩国产精品一区午夜 | av丝袜美腿 | 国产又粗又长又硬免费视频 | 91中文字幕在线播放 | 亚洲污视频 | 亚洲最新av网址 | 婷婷亚洲综合五月天小说 | 国产小视频免费观看 | 国产在线一区二区三区播放 | 精品视频国产 | 噜噜色官网 | 在线观看日韩国产 | 日日婷婷夜日日天干 | 亚洲国产一区二区精品专区 | 成人h动漫精品一区二 | 国产精品免费成人 | 一区二区三区影院 | 网址你懂的在线观看 | 国产人免费人成免费视频 | 黄色一级大片在线观看 | 欧美视频网址 | 色www永久免费 | 亚洲h在线播放在线观看h | 在线视频成人 | 国产精品一区二区三区久久 | 亚洲美女精品视频 | 日韩av电影中文字幕 | 国产xx视频 | 国产精品久久亚洲 | 夜夜操综合网 | 成人午夜免费福利 | 日日爱网址 | 国产在线一区二区三区播放 | 婷婷精品国产一区二区三区日韩 | 亚洲天堂毛片 | 日韩久久激情 | 500部大龄熟乱视频使用方法 | 亚洲精品影视在线观看 | 精品毛片一区二区免费看 | 97视频在线免费 | 国产伦精品一区二区三区在线 | 福利久久久 | 久久最新网址 | 麻豆免费看片 | 久久一区二区免费视频 | 欧美久久久| 国产精品久久婷婷六月丁香 | 91人人爱| 日韩av区| 久久www免费人成看片高清 | 日韩在线免费播放 | www.福利| 91最新在线 | 夜夜夜草| 黄色资源网站 | 欧美精品一区二区性色 | 国产精品初高中精品久久 | 麻豆精品国产传媒 | av一区在线| 五月婷婷在线观看视频 | 天天综合网国产 | 久久久 精品 | 一区二区欧美激情 | 亚洲电影第一页av | 99久久久免费视频 | 久久夜色网| 天天操天天谢 | 日韩欧美网址 | 国产精品久久久久久久久久妇女 | 亚洲专区一二三 | 日韩精品免费在线 | 久草在线免费电影 | 韩日精品在线观看 | 美女久久一区 | 亚洲一级片免费观看 | 色婷婷久久久 | 欧美一级片免费观看 | 成人av动漫在线 | 国产精品麻豆99久久久久久 | 欧美aaa视频 | 国内视频在线 | 激情大尺度视频 | 免费观看国产视频 | 日本不卡视频 | 国产在线一区观看 | 免费看一级黄色大全 | 在线观看91久久久久久 | 五月香视频在线观看 | av资源在线观看 | 国产精品免费久久 | 成人在线电影观看 | 人人草在线视频 | 午夜国产一区 | 91精品一区国产高清在线gif | 久久涩涩网站 | 在线观看视频亚洲 | 亚洲人人精品 | 国产美女在线免费观看 | 人人爽人人看 | 特级毛片网站 | 国产综合精品久久 | 日韩欧美在线综合网 | 四虎国产永久在线精品 | 人人澡人摸人人添学生av | 精品国产一区二区三区久久久 | 国产精品久久久久av | 中文字幕在线免费观看视频 | 成人黄色中文字幕 | 国产精品一区二区三区在线 | 91视频a| 久久精品五月 | 久久久天堂 | 精品国产日本 | 中文字幕在线看视频国产中文版 | 久久免费黄色大片 | 色婷婷狠狠18 | 一区二精品 | 欧美另类69 | 亚洲做受高潮欧美裸体 | 国产福利一区二区三区在线观看 | 成年人三级网站 | 欧美一级性生活片 | 日韩精品一区不卡 | 中文字幕91视频 | 亚洲专区 国产精品 | 欧美高清视频不卡网 | 美女免费网站 | 久久99网 | 欧美在线视频一区二区三区 | av中文字幕网站 | 免费合欢视频成人app | 五月色婷 | 日本大片免费观看在线 | 视频一区二区在线观看 | 日日夜夜天天综合 | 正在播放亚洲精品 | 久久小视频 | 天天射天天操天天 | 黄色日视频 | 五月激情电影 | 国产精品自产拍在线观看中文 | 欧美不卡视频在线 | 91在线播放视频 | 日日夜夜草 | 在线一区电影 | 九九九热视频 | 亚洲精品影院在线观看 | 久久99视频精品 | 中文字幕一区二区三区在线播放 | 欧美日韩国产页 | 六月丁香伊人 | 久久影院中文字幕 | 午夜av剧场| 免费看亚洲毛片 | 国产成人一区二 | 色偷偷88888欧美精品久久 | 国产精品18久久久久久首页狼 | 天天爱天天射天天干天天 | 国产视频午夜 | 欧美在线日韩在线 | 在线视频手机国产 | 欧美日韩国产精品一区二区亚洲 | 国产永久免费高清在线观看视频 | 天天碰天天操 | 欧美一区二区三区免费观看 | 蜜臀久久99精品久久久久久网站 | 亚洲欧洲日韩在线观看 | 国产日韩精品欧美 | 久久免费在线观看视频 | 懂色av一区二区三区蜜臀 | 久久黄色免费观看 | 亚洲三级性片 | 天天操天天干天天综合网 | 成人动漫一区二区三区 | 四虎8848免费高清在线观看 | 亚洲每日更新 | 美女网站在线观看 | 天天撸夜夜操 | 成人在线超碰 | 日韩有码专区 | 黄色大片视频网站 | 午夜a区| www.狠狠干 | 国产精品日韩 | 九月婷婷色 | 视频在线一区二区三区 | 精品久久久久久亚洲 | 九九九九免费视频 | 在线观看免费成人 | 国产精品视频不卡 | 日本中文字幕视频 | 婷婷丁香狠狠爱 | 91亚洲精品国偷拍自产在线观看 | 国产视频99| 在线视频 影院 | 综合网色 | 亚洲乱码精品久久久久 | 日日摸日日添日日躁av | 中文字幕一区二区在线观看 | 亚洲美女免费精品视频在线观看 | 日韩网站中文字幕 | 国产三级av在线 | 九九视频网 | 久久草在线免费 | 精品久久一区二区 | 青春草视频在线播放 | 在线精品视频免费播放 | 又色又爽又黄高潮的免费视频 | 午夜av日韩 | 91精品久久久久久久久久入口 | 精品久久久网 | 国产不卡视频在线 | av先锋影音少妇 | 国产在线观| 在线电影日韩 | 在线观看日韩国产 | 手机在线小视频 | 国产免码va在线观看免费 | 色综合人人| 亚洲精品国久久99热 | 一区二区 不卡 | 久久资源在线 | 国产视频99 | 天天操福利视频 | 91精品国产一区二区三区 | 久久国产片 | 亚洲视频999 | 成年一级片 | 亚洲极色| 久久精品老司机 | 在线观看久久久久久 | 最近中文字幕mv免费高清在线 | 久久久久免费观看 | 中文av在线免费观看 | 高清免费av在线 | 亚洲精品久久久久www | 精品国产一区二区三区日日嗨 | 麻豆极品| 特级黄色片免费看 | 国产在线观看你懂得 | 丰满少妇一级片 | 色婷婷亚洲 | 91九色在线 | 国产无套一区二区三区久久 | 国产激情免费 | 97视频人人澡人人爽 | 久久,天天综合 | 久久久精品国产一区二区 | 成人天堂网| free,性欧美 九九交易行官网 | 色九九视频 | 精品国产乱码久久久久久三级人 | 久久小视频 | 国产精美视频 | 成人免费电影 | 欧美中文字幕久久 | 在线看片91 | 欧美一级免费高清 | 91亚洲夫妻 | 六月色| 在线播放国产一区二区三区 | 国产99久久久国产精品免费看 | 色综合在 | 亚洲小视频在线观看 | 狠狠色噜噜狠狠狠狠2021天天 | 日韩黄色免费电影 | 九9热这里真品2 | 成人av电影免费观看 | 99热最新 | 伊人中文网 | 国产亚洲欧洲 | 91麻豆精品国产91久久久久久久久 | 国产久草在线 | 草久在线| 亚洲精品在线一区二区三区 | 精品视频久久久 |