libpcap
libpcap使用
make
sudo make install
- #include
- #include
- #include
- #include
- int main()
- {
- char errBuf[PCAP_ERRBUF_SIZE], * devStr;
- /* get a device */
- devStr = pcap_lookupdev(errBuf);
- if(devStr)
- {
- printf("success: device: %s\n", devStr);
- }
- else
- {
- printf("error: %s\n", errBuf);
- exit(1);
- }
- /* open a device, wait until a packet arrives */
- pcap_t * device = pcap_open_live(devStr, 65535, 1, 0, errBuf);
- if(!device)
- {
- printf("error: pcap_open_live(): %s\n", errBuf);
- exit(1);
- }
- /* wait a packet to arrive */
- struct pcap_pkthdr packet;
- const u_char * pktStr = pcap_next(device, &packet);
- if(!pktStr)
- {
- printf("did not capture a packet!\n");
- exit(1);
- }
- printf("Packet length: %d\n", packet.len);
- printf("Number of bytes: %d\n", packet.caplen);
- printf("Recieved time: %s\n", ctime((const time_t *)&packet.ts.tv_sec));
- pcap_close(device);
- return 0;
- }
打开两个终端,先ping 192.168.1.10,由于我们的ip是192.168.1.1,因此我们可以收到广播的数据包,另一个终端运行test,就会抓到这个包。
- #include
- #include
- #include
- #include
- void getPacket(u_char * arg, const struct pcap_pkthdr * pkthdr, const u_char * packet)
- {
- int * id = (int *)arg;
- printf("id: %d\n", ++(*id));
- printf("Packet length: %d\n", pkthdr->len);
- printf("Number of bytes: %d\n", pkthdr->caplen);
- printf("Recieved time: %s", ctime((const time_t *)&pkthdr->ts.tv_sec));
- int i;
- for(i=0; i
len; ++i) - {
- printf(" %02x", packet[i]);
- if( (i + 1) % 16 == 0 )
- {
- printf("\n");
- }
- }
- printf("\n\n");
- }
- int main()
- {
- char errBuf[PCAP_ERRBUF_SIZE], * devStr;
- /* get a device */
- devStr = pcap_lookupdev(errBuf);
- if(devStr)
- {
- printf("success: device: %s\n", devStr);
- }
- else
- {
- printf("error: %s\n", errBuf);
- exit(1);
- }
- /* open a device, wait until a packet arrives */
- pcap_t * device = pcap_open_live(devStr, 65535, 1, 0, errBuf);
- if(!device)
- {
- printf("error: pcap_open_live(): %s\n", errBuf);
- exit(1);
- }
- /* wait loop forever */
- int id = 0;
- pcap_loop(device, -1, getPacket, (u_char*)&id);
- pcap_close(device);
- return 0;
- }
过滤数据包需要完成3件事:
a) 构造一个过滤表达式
b) 编译这个表达式
c) 应用这个过滤器
a)
test4.c
[cpp] view plain copy
- #include
- #include
- #include
- #include
- void getPacket(u_char * arg, const struct pcap_pkthdr * pkthdr, const u_char * packet)
- {
- int * id = (int *)arg;
- printf("id: %d\n", ++(*id));
- printf("Packet length: %d\n", pkthdr->len);
- printf("Number of bytes: %d\n", pkthdr->caplen);
- printf("Recieved time: %s", ctime((const time_t *)&pkthdr->ts.tv_sec));
- int i;
- for(i=0; i
len; ++i) - {
- printf(" %02x", packet[i]);
- if( (i + 1) % 16 == 0 )
- {
- printf("\n");
- }
- }
- printf("\n\n");
- }
- int main()
- {
- char errBuf[PCAP_ERRBUF_SIZE], * devStr;
- /* get a device */
- devStr = pcap_lookupdev(errBuf);
- if(devStr)
- {
- printf("success: device: %s\n", devStr);
- }
- else
- {
- printf("error: %s\n", errBuf);
- exit(1);
- }
- /* open a device, wait until a packet arrives */
- pcap_t * device = pcap_open_live(devStr, 65535, 1, 0, errBuf);
- if(!device)
- {
- printf("error: pcap_open_live(): %s\n", errBuf);
- exit(1);
- }
- /* construct a filter */
- struct bpf_program filter;
- pcap_compile(device, &filter, "dst port 80", 1, 0);
- pcap_setfilter(device, &filter);
- /* wait loop forever */
- int id = 0;
- pcap_loop(device, -1, getPacket, (u_char*)&id);
- pcap_close(device);
- return 0;
- }
在下面的这一个例子中,客户机通过tcp的9732端口连接服务器,发送字符'A',之后服务器将'A'+1即'B'返回给客户机,具体实现可以参考:http://blog.csdn.net/htttw/article/details/7519964
服务器的ip是192.168.56.101,客户机的ip是192.168.56.1
服务器:

- all: tcp_client.c tcp_server.c
- gcc -g -Wall -o tcp_client tcp_client.c
- gcc -g -Wall -o tcp_server tcp_server.c
- clean:
- rm -rf *.o tcp_client tcp_server
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #define PORT 9832
- #define SERVER_IP "192.168.56.101"
- int main()
- {
- /* create a socket */
- 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 with the local file */
- bind(server_sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
- /* listen */
- 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 the socket */
- close(client_sockfd);
- }
- return 0;
- }
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #define PORT 9832
- #define SERVER_IP "192.168.56.101"
- int main()
- {
- /* create a socket */
- int sockfd = socket(AF_INET, SOCK_STREAM, 0);
- struct sockaddr_in address;
- address.sin_family = AF_INET;
- address.sin_addr.s_addr = inet_addr(SERVER_IP);
- address.sin_port = htons(PORT);
- /* connect to the server */
- int result = connect(sockfd, (struct sockaddr *)&address, sizeof(address));
- if(result == -1)
- {
- perror("connect failed: ");
- exit(1);
- }
- /* exchange data */
- char ch = 'A';
- write(sockfd, &ch, 1);
- read(sockfd, &ch, 1);
- printf("get char from server: %c\n", ch);
- /* close the socket */
- close(sockfd);
- return 0;
- }
在客户机上运行下列命令来清空记录服务器的arp缓存:
sudo arp -d 192.168.56.101
arp -a后发现已经删除了记录服务器的arp缓存
抓包的结果如下所示,由于包太多了,无法全部截图,因此我把所有内容保存在下面的文本中了:

- hutao@hutao-VirtualBox:~/test3$ sudo ./test
- success: device: eth0
- id: 1
- Packet length: 60
- Number of bytes: 60
- Recieved time: Sat Apr 28 19:57:50 2012
- ff ff ff ff ff ff 0a 00 27 00 00 00 08 06 00 01
- 08 00 06 04 00 01 0a 00 27 00 00 00 c0 a8 38 01
- 00 00 00 00 00 00 c0 a8 38 65 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00
- id: 2
- Packet length: 42
- Number of bytes: 42
- Recieved time: Sat Apr 28 19:57:50 2012
- 0a 00 27 00 00 00 08 00 27 9c ff b1 08 06 00 01
- 08 00 06 04 00 02 08 00 27 9c ff b1 c0 a8 38 65
- 0a 00 27 00 00 00 c0 a8 38 01
- id: 3
- Packet length: 74
- Number of bytes: 74
- Recieved time: Sat Apr 28 19:57:50 2012
- 08 00 27 9c ff b1 0a 00 27 00 00 00 08 00 45 00
- 00 3c d4 af 40 00 40 06 74 55 c0 a8 38 01 c0 a8
- 38 65 8e 20 26 68 79 e1 63 8c 00 00 00 00 a0 02
- 39 08 d4 13 00 00 02 04 05 b4 04 02 08 0a 00 14
- b7 23 00 00 00 00 01 03 03 06
- id: 4
- Packet length: 74
- Number of bytes: 74
- Recieved time: Sat Apr 28 19:57:50 2012
- 0a 00 27 00 00 00 08 00 27 9c ff b1 08 00 45 00
- 00 3c 00 00 40 00 40 06 49 05 c0 a8 38 65 c0 a8
- 38 01 26 68 8e 20 b6 c4 e6 e5 79 e1 63 8d a0 12
- 38 90 f1 e5 00 00 02 04 05 b4 04 02 08 0a 00 57
- a1 2c 00 14 b7 23 01 03 03 05
- id: 5
- Packet length: 66
- Number of bytes: 66
- Recieved time: Sat Apr 28 19:57:50 2012
- 08 00 27 9c ff b1 0a 00 27 00 00 00 08 00 45 00
- 00 34 d4 b0 40 00 40 06 74 5c c0 a8 38 01 c0 a8
- 38 65 8e 20 26 68 79 e1 63 8d b6 c4 e6 e6 80 10
- 00 e5 fb c1 00 00 01 01 08 0a 00 14 b7 24 00 57
- a1 2c
- id: 6
- Packet length: 67
- Number of bytes: 67
- Recieved time: Sat Apr 28 19:57:50 2012
- 08 00 27 9c ff b1 0a 00 27 00 00 00 08 00 45 00
- 00 35 d4 b1 40 00 40 06 74 5a c0 a8 38 01 c0 a8
- 38 65 8e 20 26 68 79 e1 63 8d b6 c4 e6 e6 80 18
- 00 e5 ba b7 00 00 01 01 08 0a 00 14 b7 25 00 57
- a1 2c 41
- id: 7
- Packet length: 66
- Number of bytes: 66
- Recieved time: Sat Apr 28 19:57:50 2012
- 0a 00 27 00 00 00 08 00 27 9c ff b1 08 00 45 00
- 00 34 47 cb 40 00 40 06 01 42 c0 a8 38 65 c0 a8
- 38 01 26 68 8e 20 b6 c4 e6 e6 79 e1 63 8e 80 10
- 01 c5 f1 dd 00 00 01 01 08 0a 00 57 a1 2e 00 14
- b7 25
- id: 8
- Packet length: 67
- Number of bytes: 67
- Recieved time: Sat Apr 28 19:57:50 2012
- 0a 00 27 00 00 00 08 00 27 9c ff b1 08 00 45 00
- 00 35 47 cc 40 00 40 06 01 40 c0 a8 38 65 c0 a8
- 38 01 26 68 8e 20 b6 c4 e6 e6 79 e1 63 8e 80 18
- 01 c5 f1 de 00 00 01 01 08 0a 00 57 a1 2e 00 14
- b7 25 42
- id: 9
- Packet length: 66
- Number of bytes: 66
- Recieved time: Sat Apr 28 19:57:50 2012
- 0a 00 27 00 00 00 08 00 27 9c ff b1 08 00 45 00
- 00 34 47 cd 40 00 40 06 01 40 c0 a8 38 65 c0 a8
- 38 01 26 68 8e 20 b6 c4 e6 e7 79 e1 63 8e 80 11
- 01 c5 f1 dd 00 00 01 01 08 0a 00 57 a1 2e 00 14
- b7 25
- id: 10
- Packet length: 66
- Number of bytes: 66
- Recieved time: Sat Apr 28 19:57:50 2012
- 08 00 27 9c ff b1 0a 00 27 00 00 00 08 00 45 00
- 00 34 d4 b2 40 00 40 06 74 5a c0 a8 38 01 c0 a8
- 38 65 8e 20 26 68 79 e1 63 8e b6 c4 e6 e7 80 10
- 00 e5 fb bc 00 00 01 01 08 0a 00 14 b7 25 00 57
- a1 2e
- id: 11
- Packet length: 66
- Number of bytes: 66
- Recieved time: Sat Apr 28 19:57:50 2012
- 08 00 27 9c ff b1 0a 00 27 00 00 00 08 00 45 00
- 00 34 d4 b3 40 00 40 06 74 59 c0 a8 38 01 c0 a8
- 38 65 8e 20 26 68 79 e1 63 8e b6 c4 e6 e7 80 11
- 00 e5 fb bb 00 00 01 01 08 0a 00 14 b7 25 00 57
- a1 2e
- id: 12
- Packet length: 66
- Number of bytes: 66
- Recieved time: Sat Apr 28 19:57:50 2012
- 0a 00 27 00 00 00 08 00 27 9c ff b1 08 00 45 00
- 00 34 47 ce 40 00 40 06 01 3f c0 a8 38 65 c0 a8
- 38 01 26 68 8e 20 b6 c4 e6 e8 79 e1 63 8f 80 10
- 01 c5 f1 dd 00 00 01 01 08 0a 00 57 a1 2e 00 14
- b7 25
- id: 13
- Packet length: 66
- Number of bytes: 66
- Recieved time: Sat Apr 28 19:57:50 2012
- 08 00 27 9c ff b1 0a 00 27 00 00 00 08 00 45 00
- 00 34 d4 b4 40 00 40 06 74 58 c0 a8 38 01 c0 a8
- 38 65 8e 20 26 68 79 e1 63 8f b6 c4 e6 e8 80 10
- 00 e5 fb b9 00 00 01 01 08 0a 00 14 b7 26 00 57
- a1 2e
仔细研究即可发现服务器与客户机是如何通过tcp通信的。
- #include
- #include
- #include
- #include
- #include
- #include
- int main()
- {
- /* ask pcap to find a valid device for use to sniff on */
- char * dev; /* name of the device */
- char errbuf[PCAP_ERRBUF_SIZE];
- dev = pcap_lookupdev(errbuf);
- /* error checking */
- if(!dev)
- {
- printf("pcap_lookupdev() error: %s\n", errbuf);
- exit(1);
- }
- /* print out device name */
- printf("dev name: %s\n", dev);
- /* ask pcap for the network address and mask of the device */
- bpf_u_int32 netp; /* ip */
- bpf_u_int32 maskp; /* subnet mask */
- int ret; /* return code */
- ret = pcap_lookupnet(dev, &netp, &maskp, errbuf);
- if(ret == -1)
- {
- printf("pcap_lookupnet() error: %s\n", errbuf);
- exit(1);
- }
- /* get the network address in a human readable form */
- char * net; /* dot notation of the network address */
- char * mask; /* dot notation of the network mask */
- struct in_addr addr;
- addr.s_addr = netp;
- net = inet_ntoa(addr);
- if(!net)
- {
- perror("inet_ntoa() ip error: ");
- exit(1);
- }
- printf("ip: %s\n", net);
- /* do the same as above for the device's mask */
- addr.s_addr = maskp;
- mask = inet_ntoa(addr);
- if(!mask)
- {
- perror("inet_ntoa() sub mask error: ");
- exit(1);
- }
- printf("sub mask: %s\n", mask);
- return 0;
- }
int pcap_lookupnet(const char * device, bpf_u_int32 * netp, bpf_u_int32 * maskp, char * errbuf)
可以获取指定设备的ip地址,子网掩码等信息
我们使用inet_ntoa()将其转换为可读的点分十进制形式的字符串
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
