當(dāng)前位置:首頁 > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 講師博文 > libpcap初試
libpcap初試
時(shí)間:2018-09-29 來源:未知
1. Libpcap的安裝:
下載壓縮包,解壓
./configure
make
sudo make install
2. Libpcap的使用
注意兩點(diǎn):
-lpcap
使用root權(quán)限
自動(dòng)獲取網(wǎng)絡(luò)接口:
char * pcap_lookupdev(char * errbuf)
參數(shù):如果出錯(cuò),則errbuf存放出錯(cuò)信息字符串,errbuf至少應(yīng)該是PCAP_ERRBUF_SIZE個(gè)字節(jié)長度的
返回值:返回第一個(gè)合適的網(wǎng)絡(luò)接口的字符串指針
打開網(wǎng)絡(luò)接口:
pcap_t * pcap_open_live(const char * device, int snaplen, int promisc, int to_ms, char * errbuf)
返回值:指定接口的pcap_t類型指針,后面的所有操作都要使用這個(gè)指針。
第一個(gè)參數(shù):自動(dòng)獲取的網(wǎng)絡(luò)接口字符串,可以直接使用硬編碼。
第二個(gè)參數(shù):對(duì)于每個(gè)數(shù)據(jù)包,從開頭要抓多少個(gè)字節(jié),我們可以設(shè)置這個(gè)值來只抓每個(gè)數(shù)據(jù)包的頭部,而不關(guān)心具體的內(nèi)容。典型的以太網(wǎng)幀長度是1518字節(jié),但其他的某些協(xié)議的數(shù)據(jù)包會(huì)更長一點(diǎn),但任何一個(gè)協(xié)議的一個(gè)數(shù)據(jù)包長度都必然小于65535個(gè)字節(jié)。
第三個(gè)參數(shù):指定是否打開混雜模式(Promiscuous Mode),0表示非混雜模式,任何其他值表示混合模式。如果要打開混雜模式,那么網(wǎng)卡必須也要打開混雜模式,可以使用如下的命令打開eth0混雜模式:
ifconfig eth0 promisc
第四個(gè)參數(shù):指定需要等待的毫秒數(shù),超過這個(gè)數(shù)值后,第3步獲取數(shù)據(jù)包的這幾個(gè)函數(shù)就會(huì)立即返回。0表示一直等待直到有數(shù)據(jù)包到來。
第五個(gè)參數(shù):存放出錯(cuò)信息的數(shù)組。
釋放網(wǎng)絡(luò)接口:
void pcap_close(pcap_t * p)
獲取數(shù)據(jù)包:
int pcap_loop(pcap_t * p, int cnt, pcap_handler callback, u_char * user)
第一個(gè)參數(shù):返回的pcap_t類型的指針
第二個(gè)參數(shù):需要抓的數(shù)據(jù)包的個(gè)數(shù),一旦抓到了cnt個(gè)數(shù)據(jù)包,pcap_loop立即返回。負(fù)數(shù)的cnt表示pcap_loop永遠(yuǎn)循環(huán)抓包,直到出現(xiàn)錯(cuò)誤。
第三個(gè)參數(shù):一個(gè)回調(diào)函數(shù)指針,它必須是如下的形式:
void callback(u_char * userarg, const struct pcap_pkthdr * pkthdr, const u_char * packet)
第一個(gè)參數(shù):pcap_loop的后一個(gè)參數(shù),當(dāng)收到足夠數(shù)量的包后pcap_loop會(huì)調(diào)用callback回調(diào)函數(shù),同時(shí)將pcap_loop()的user參數(shù)傳遞給它
第二個(gè)參數(shù):收到的數(shù)據(jù)包的pcap_pkthdr類型的指針
第三個(gè)參數(shù):收到的數(shù)據(jù)包數(shù)據(jù)
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#define PORT 8888
#define SERVER_IP "192.168.1.153"
int main()
{
int server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
server_addr.sin_port = htons(PORT);
bind(server_sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
listen(server_sockfd, 5);
char ch;
int client_sockfd;
struct sockaddr_in client_addr;
socklen_t len = sizeof(client_addr);
while(1)
{
printf("server waiting:\n");
/* accept a connection */
client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_addr, &len);
/* exchange data */
read(client_sockfd, &ch, 1);
printf("get char from client: %c\n", ch);
++ch;
write(client_sockfd, &ch, 1);
close(client_sockfd);
}
return 0;
}
根據(jù)以上代碼編寫客戶端,運(yùn)行后可查看接收到的具體數(shù)據(jù)包。
int pcap_lookupnet(const char * device, bpf_u_int32 * netp, bpf_u_int32 * maskp, char * errbuf)
可以獲取指定設(shè)備的ip地址,子網(wǎng)掩碼等信息
netp:傳出參數(shù),指定網(wǎng)絡(luò)接口的ip地址
maskp:傳出參數(shù),指定網(wǎng)絡(luò)接口的子網(wǎng)掩碼
pcap_lookupnet()失敗返回-1

