linux网络编程之:获取指定网卡网络数据包并分析(附C语言源码)

C Program 同时被 2 个专栏收录
43 篇文章 0 订阅
15 篇文章 0 订阅
#include <stdio.h>
#include <pcap.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main(){
	char *net_dev;
	char *ip_addr;
	char *net_mask;
	char errbuf[PCAP_ERRBUF_SIZE];

	bpf_u_int32 netp;
	bpf_u_int32 mask;
	struct in_addr addr;

	net_dev = pcap_lookupdev(errbuf);
	if(net_dev == NULL){
		printf("cannot get  the network device info: %s\n", errbuf);
		return 1;
	}
	
	printf("the network device is : %s\n", net_dev);
	if(pcap_lookupnet("any", &netp, &mask, errbuf) == -1){
		printf("error\n");
		return 1;
	}	
	
	addr.s_addr = netp;
	ip_addr = inet_ntoa(addr);

	if(ip_addr == NULL){
		printf("inet_ntoa()\n");
		return 1;
	}

	printf("ip is %s\n", ip_addr);

	addr.s_addr = mask;
	net_mask = inet_ntoa(addr);
	if(net_mask == NULL){
		perror("inet_ntoa();\n");
		return 1;
	}
	
	printf("mask is %s\n", net_mask);

	return 0;
}

本程序可以自动获取电脑上面的网卡名称,然后可以得到所获取网卡的ip地址以及mask掩码。

#include <stdio.h>
#include <pcap.h>
#include <netinet/if_ether.h>

int main(){
	pcap_t *sniffer_des;
	char errbuf[PCAP_ERRBUF_SIZE];
	char *net_dev;
	bpf_u_int32 net, mask;
	struct bpf_program fp;
	const u_char *packet;
	struct pcap_pkthdr hdr;
	struct ether_header *eth_header;
	u_char *ptr;

	char filter[] = "port 80";

	net_dev = pcap_lookupdev(errbuf);
	if(net_dev == NULL){
		printf("get device error:%s\n", errbuf);
		return 1;
	}
	net_dev = "p3p1";
	if(pcap_lookupnet(net_dev, &net, &mask, errbuf) == -1){
		printf("get net error:%s\n", errbuf);
		return 1;
	}

	sniffer_des = pcap_open_live(net_dev, 65535, 1, 5000, errbuf);
	if(sniffer_des == NULL){
		printf("pcap_open_live%s\n", errbuf);
		return 1;
	}

	if(pcap_compile(sniffer_des, &fp, filter, 0, mask) == -1){
		printf("pcap_compile error\n");
		return 1;
	}

	if(pcap_setfilter(sniffer_des, &fp) == -1){
		printf("pcap_setfilter() error\n");
		return 1;
	}

	packet = pcap_next(sniffer_des, &hdr);
	if(packet == NULL){
		printf("pacap_next() failed\n");
		return 1;
	}

	printf("Packet length %d\n", hdr.len);
	printf("Sniffer time: %s\n", ctime((const time_t*)&hdr.ts.tv_sec));
	printf("length of portion present: %d\n", hdr.caplen);

	eth_header = (struct ether_header*)packet;
	if(ntohs(eth_header->ether_type) != ETHERTYPE_IP){
		printf("not ethernet packet\n");
		return 1;
	}

	ptr = eth_header->ether_dhost;
	int i = 0;
	printf("destination address(MAC):");
	while(i < ETHER_ADDR_LEN){
		printf(" %x", *ptr++);
		i++;
	}

	printf("\nsource address(MAC):");
	ptr = eth_header->ether_shost;
	i = 0;
	while(i < ETHER_ADDR_LEN){
		printf(" %x", *ptr++);
		i++;
	}

	printf("\n");
	return 0;

}

这个程序可以获取指定网卡的MAC地址,并获取指定端口的数据包,可以用于程序的分析。我电脑上面运行的结果。


上面的获取是一个一个的获取,效率很低,下面的程序可以指定获取数据包的个数

#include <stdio.h>
#include <pcap.h>
#include <netinet/if_ether.h>

void deal(u_char *user, const struct pcap_pkthdr *hdr, const u_char *packet){
    static int count = 0;
    struct ether_header *eth_header;
	u_char *ptr;
    
	printf("Packet length %d\n", hdr->len);
	printf("length of portion present: %d\n", hdr->caplen);

	eth_header = (struct ether_header*)packet;
	if(ntohs(eth_header->ether_type) != ETHERTYPE_IP){
		printf("not ethernet packet\n");
		return;
	}

	ptr = eth_header->ether_dhost;
	int i = 0;
	printf("destination address(MAC):");
	while(i < ETHER_ADDR_LEN){
		printf(" %x", *ptr++);
		i++;
	}

	printf("\nsource address(MAC):");
	ptr = eth_header->ether_shost;
	i = 0;
	while(i < ETHER_ADDR_LEN){
		printf(" %x", *ptr++);
		i++;
	}

	printf("\nfinish deal with %d packet\n", count);
    count++;
}
int main(){
	pcap_t *sniffer_des;
	char errbuf[PCAP_ERRBUF_SIZE];
	char *net_dev;
	bpf_u_int32 net, mask;
	struct bpf_program fp;
	const u_char *packet;
	struct pcap_pkthdr hdr;
	
    int ret;

	char filter[] = "port 80";

	net_dev = pcap_lookupdev(errbuf);
	if(net_dev == NULL){
		printf("get device error:%s\n", errbuf);
		return 1;
	}
	net_dev = "p3p1";
	if(pcap_lookupnet(net_dev, &net, &mask, errbuf) == -1){
		printf("get net error:%s\n", errbuf);
		return 1;
	}

	sniffer_des = pcap_open_live(net_dev, 65535, 1, 5000, errbuf);
	if(sniffer_des == NULL){
		printf("pcap_open_live%s\n", errbuf);
		return 1;
	}

	if(pcap_compile(sniffer_des, &fp, filter, 0, mask) == -1){
		printf("pcap_compile error\n");
		return 1;
	}

	if(pcap_setfilter(sniffer_des, &fp) == -1){
		printf("pcap_setfilter() error\n");
		return 1;
	}

	ret = pcap_loop(sniffer_des, 3, deal, NULL);
    if(ret == -1 || ret == -2){
        printf("cannot get the pcaket\n");
        return 1;
    }
	return 0;

}

我电脑上面运行的结果(抓取http协议的数据报)




  • 2
    点赞
  • 1
    评论
  • 8
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: Age of Ai 设计师:meimeiellie 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值