试着用libpcap的API抓包玩,代码如下,在打印IP header中的源地址和目标地址时(加粗语句),
不同的输出方式打印出来不同的结果,十分不解,求指教。
为什么用两个printf分别打印源地址和目标地址时,源和目标是不同的(期望值)?而在一个printf中打印输出的源和目标却是相同的?
(CentOS 6.4 x64, gcc 4.4.7)
输出结果为:
SRC: 192.168.122.13
DST: 192.168.122.1
src: 192.168.122.13
dst: 192.168.122.13
SRC: 192.168.122.13
DST: 192.168.122.1
src: 192.168.122.13
dst: 192.168.122.13
SRC: 192.168.122.1
DST: 192.168.122.13
src: 192.168.122.1
dst: 192.168.122.1
源码:
#include <stdio.h>
#include <stdlib.h>
#include <pcap.h>
#include <pcap-bpf.h>
#include <net/ethernet.h>
#include <netinet/ip.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define SNAP_LEN 1518
void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet)
{
const struct ether_header *ethernet;
const struct ip *ip;
ethernet = (struct ether_header *)packet;
ip = (struct ip*)(packet + ETHER_HDR_LEN);
if ( ip->ip_hl * 4 < 20) {
fprintf(stderr, "Invalid IP header length\n");
return;
}
printf("SRC: %s\n", inet_ntoa(ip->ip_src));
printf("DST: %s\n", inet_ntoa(ip->ip_dst));
printf("src: %s\ndst: %s\n\n",
inet_ntoa(ip->ip_src), inet_ntoa(ip->ip_dst)
);
}
int main(int argc, char **argv)
{
char *dev, err_buff[PCAP_ERRBUF_SIZE];
// 1. find the active interface for capturing data
if ((dev = pcap_lookupdev(err_buff)) == NULL) {
fprintf(stderr, "Couldn't find default device: %s\n", err_buff);
return 1;
}
printf("%s\n", dev);
// 2. open the interface
pcap_t *handle = NULL;
bpf_u_int32 net, mask;
if ((handle = pcap_open_live(dev, SNAP_LEN, 0, 1000, err_buff)) == NULL) {
fprintf(stderr, "Failed to open the device %s\n", dev);
return 2;
}
if (pcap_lookupnet(dev, &net, &mask, err_buff) == -1) {
fprintf(stderr, "Failed to get net.\n");
return 3;
}
// 3. complie and set filter
char filter[] = "ip";
struct bpf_program fp;
if (pcap_compile(handle, &fp, filter, 0, net) == -1) {
fprintf(stderr, "failed to compile the filter %s: %s\n",
filter, pcap_geterr(handle));
return 4;
}
if (pcap_setfilter(handle, &fp) == -1) {
fprintf(stderr, "failed to set filter %s: %s\n", filter,
pcap_geterr(handle));
return 4;
}
// 4. capture the packet
int num_packets = 10;
pcap_loop(handle, num_packets, got_packet, NULL);
// 5. stop capturing packets and free memory.
pcap_freecode(&fp);
pcap_close(handle);
return 0;
}