基于WINPCAP的瞎抓一些比较简单的数据包(应付作业了事)

VS2017 winpcap下载和环境配置省略(懒,百度了好久)

#define  have_remote
#include "stdafx.h"
  
#include "pcap.h"  
#include<winsock2.h>  
#include<stdio.h>
#include<time.h>
//#include<iostream>
//using namespace std;
//#pragma comment(lib,"wpcap.lib")  
#pragma comment(lib, "wpcap.lib") 
#pragma comment(lib,"packet.lib") 
#pragma comment(lib,"ws2_32.lib")  
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pcap_data);
#define IPTOSBUFFERS 12  
void ifprint(pcap_if_t *d);
char * iptos(u_long in);
int i = 0;
u_char *data;
#include "pcap.h"
struct ether_header
{
	u_int8_t ether_dhost[6]; 
	u_int8_t ether_shost[6];
	u_int16_t ether_type;     
};
typedef struct ip_address {
	u_char byte1;
	u_char byte2;
	u_char byte3;
	u_char byte4;
}ip_address;

struct ip_header
{
	u_int8_t    ip_header_length;
	u_int8_t    ip_tos;
	u_int16_t   ip_length;
	u_int16_t   ip_id;
	u_int16_t   ip_off;
	u_int8_t    ip_ttl;
	u_int8_t    ip_protocol;
	u_int16_t   ip_checksum;
	struct in_addr ip_souce_address;
	struct in_addr ip_destination_address;
};

typedef struct udp_header {
	u_short sport;          
	u_short dport;          
	u_short len;           
	u_short crc;           
}udp_header;

/* tcp 首部 */
typedef struct tcp_header {
	u_short sport;          
	u_short dport;          
	u_int th_seq;             
	u_int th_ack;             
	u_short doff; 
	u_short th_window;       
	u_short th_sum;         
	u_short th_urp;         
}tcp_header;




typedef struct icmp_header {
	u_int8_t  icmp_type;
	u_int8_t  icmp_code;
	u_int16_t icmp_check_sum;
	u_int16_t icmp_flag;
	u_int16_t icmp_id;
}icmp_header;



typedef struct igmp_header {    //时间紧迫 希望V2还在用 0_0
	u_int8_t  igmp_type;
	u_int8_t  igmp_max_resp;
	u_int16_t igmp_check_sum;
	u_int32_t igmp_group_add;
}igmp_header;

typedef struct arp_header {    
	u_int16_t  mac_type;
	u_int16_t  protocol_type;
	u_int8_t mac_add_len;
	u_int8_t protocol_add_len;
	u_int16_t op;
	u_int16_t src1;
	u_int32_t src2;
	u_int32_t src_ip;
	u_int16_t des1;
	u_int32_t des2;
	u_int32_t des_ip;
}arp_header;


void arp_protool(pcap_pkthdr *header, const u_char *pkt_data, int eth_len) {
	struct arp_header *arp_protocol;
	arp_protocol = (struct arp_header*)(pkt_data + eth_len);
	u_int16_t  mac_type = ntohs(arp_protocol->mac_type);
	u_int16_t  protocol_type = ntohs(arp_protocol->protocol_type);
	u_int8_t mac_add_len = ntohs(arp_protocol->mac_add_len);
	u_int8_t protocol_add_len = ntohs(arp_protocol->protocol_add_len);
	u_int16_t op = ntohs(arp_protocol->op);
	u_int16_t src1 = ntohs(arp_protocol->src1);
	u_int32_t src2 = ntohs(arp_protocol->src2);
	u_int32_t src_ip = ntohs(arp_protocol->src_ip);
	u_int16_t des1 = ntohs(arp_protocol->des1);
	u_int32_t des2 = ntohs(arp_protocol->des2);
	u_int32_t des_ip = ntohs(arp_protocol->des_ip);
	if (protocol_type == 0x0800) {
		printf("*********ARP协议*********\n");
	}
	else printf("*********RARP协议*********\n");
	printf("eth_len:%d\n", eth_len);
	printf("硬件类型:%d\n", mac_type);
	printf("协议类型:%d\n", protocol_type);
	printf("硬件地址长度:%d\n", mac_add_len);
	printf("协议地址长度:%d\n", protocol_add_len);
	printf("操作:%d\n", op);
	/*u_char* mac_string;
	mac_string = src1;
	printf("%02x:%02x:%02x:%02x:%02x:%02x\n", *mac_string, *(mac_string + 1), *(mac_string + 2), *(mac_string + 3), *(mac_string + 4), *(mac_string + 5));
	printf("MAC帧目的地址:\n");
	mac_string = ethernet_protocol->ether_dhost;
	printf("%02x:%02x:%02x:%02x:%02x:%02x\n", *mac_string, *(mac_string + 1), *(mac_string + 2), *(mac_string + 3), *(mac_string + 4), *(mac_string + 5));
	*/
	printf("发送者硬件地址:");
	
	printf("%02x:%02x:%02x:%02x:%02x:%02x\n",*(pkt_data+20+0+2), *(pkt_data + 20 + 1+2), *(pkt_data + 20 + 2+2), *(pkt_data + 20 + 3+2), *(pkt_data + 20 + 4+2), *(pkt_data + 20 + 5+2));
	printf("发送者ip:%d.%d.%d.%d\n", *(pkt_data + 20 + 6+2),*(pkt_data + 20 + 7+2),*(pkt_data + 20 + 8+2),*(pkt_data + 20 + 9+2));
	printf("目标硬件地址:");
	printf("%02x:%02x:%02x:%02x:%02x:%02x\n", *(pkt_data + 30 + 0+2), *(pkt_data + 30 + 1+2), *(pkt_data + 30 + 2+2), *(pkt_data + 30 + 3+2), *(pkt_data + 30 + 4+2), *(pkt_data + 30 + 5+2));
	printf("目标ip:%d.%d.%d.%d\n", *(pkt_data + 30 + 6+2), *(pkt_data + 30 + 7+2), *(pkt_data + 30 + 8+2), *(pkt_data + 30 + 9+2));
	if (op == 1) {
		printf("ARP请求\n");
	}
	if (op == 2) {
		printf("ARP应答\n");
	}
	if (op == 3) {
		printf("RARP请求\n");
	}
	if (op == 4) {
		printf("RARP应答\n");
	}
}






void igmp_protool(pcap_pkthdr *header, const u_char *pkt_data, int ip_len) {
	struct igmp_header *igmp_protocol;
	igmp_protocol = (struct igmp_header *)(pkt_data + ip_len);
	u_int8_t type = ntohs(igmp_protocol->igmp_type);
	u_int8_t resp = ntohs(igmp_protocol->igmp_max_resp);
	u_int16_t check_sum = ntohs(igmp_protocol->igmp_check_sum);
	u_int32_t add = ntohs(igmp_protocol->igmp_group_add);
	printf("*********IGMP协议*********\n");
	printf("ip_len:%d\n", ip_len);
	printf("类型:%d\n", type);
	printf("最大响应时间:%d\n", resp);
	printf("校验和:%d\n", check_sum);
	printf("组地址:%d\n", add);
	if (type == 0x11) {
		printf("成员查询");
	}
	if (type == 0x12) {
		printf("版本1成员报告");
	}
	if (type == 0x16) {
		printf("版本2成员报告");
	}
	if (type == 0x17) {
		printf("离开组");
	}
}






void icmp_protool(pcap_pkthdr *header, const u_char *pkt_data, int ip_len) {
	struct icmp_header *icmp_protocol;
	icmp_protocol = (struct icmp_header *)(pkt_data + ip_len);
	u_int8_t type = ntohs(icmp_protocol->icmp_type );
	u_int8_t code = ntohs(icmp_protocol->icmp_code );
	u_int16_t sum = ntohs(icmp_protocol->icmp_check_sum );
	u_int16_t flag = ntohs(icmp_protocol->icmp_flag );
	u_int16_t id = ntohs(icmp_protocol->icmp_id );
	printf("*********ICMP协议*********\n");
	printf("ip_len:%d\n", ip_len);
	printf("类型:%d\n", type );
	printf("代码:%d\n", code );
	printf("校验和:%d\n", sum );
	printf("标识符:%d\n", flag );
	printf("序列号:%d\n", id );
	if (type == 0 && code == 0) {
		printf("Echo Reply——回显应答(Ping应答\n");
	}
	if (type == 3) {
		if (code == 0)printf("Network Unreachable——网络不可达\n");
		if (code == 1)printf("Host Unreachable——主机不可达\n");
		if (code == 2)printf("Protocol Unreachable——协议不可达\n");
		if (code == 3)printf("Port Unreachable——端口不可达\n");
		if (code == 4)printf("Fragmentation needed but no frag. bit set——需要进行分片但强制不分片\n");
		if (code == 5)printf("Source routing failed——源站选路失败\n");
		if (code == 6)printf("Destination network unknown——目的网络未知\n");
		if (code == 7)printf("Destination host unknown——目的主机未知\n");
		if (code == 8)printf("Source host isolated (obsolete)——源主机被隔离(作废)\n");
		if (code == 9)printf("Destination network administratively prohibited——目的网络被强制禁止\n");
		if (code == 10)printf("Destination host administratively prohibited——目的主机被强制禁止\n");
		if (code == 11)printf("Network unreachable for TOS——由于服务类型TOS,网络不可达\n");
		if (code == 12)printf("Host unreachable for TOS——由于服务类型TOS,主机不可达\n");
		if (code == 13)printf("Communication administratively prohibited by filtering——由于过滤,通信被强制禁止\n");
		if (code == 14)printf("Host precedence violation——主机越权\n");
		if (code == 15)printf("Precedence cutoff in effect——优先终止生效\n");
	}
	if (type == 4 && code == 0)printf("Source quench——源站被关闭\n");
	if (type == 5) {
		if (code == 0)printf("Redirect for network——对网络重定向\n");
		if (code == 1)printf("Redirect for host——对主机重定向\n");
		if (code == 2)printf("Redirect for TOS and network——对服务类型和网络重定向\n");
		if (code == 3)printf("Redirect for TOS and host——对服务类型和主机重定向\n");
	}
	if (type == 8 && code == 0) {
		printf("Echo request——回显请求(ping请求)\n");
	}
	if (type == 9 && code == 0) {
		printf("Router advertisement——路由器通告\n");
	}
	if (type == 10 && code == 0) {
		printf("Route solicitation——路由器请求\n");
	}
	if (type == 11) {
		if (code == 0) printf("TTL equals 0 during transit——传输期间生存时间为0\n");
		if (code == 1) printf("TTL equals 0 during reassembly——在数据报组装期间生存时间为0\n");
	}
	if (type == 12) {
		if (code == 0)printf("IP header bad (catchall error)——坏的IP首部(包括各种差错)\n");
		if (code == 1)printf("Required options missing——缺少必需的选项\n");
	}
	if (type == 13 && code == 0)printf("Timestamp request (obsolete)——时间戳请求(作废不用)\n");
	if (type == 14)printf("Timestamp reply (obsolete)——时间戳应答(作废不用)\n");
	if (type == 15 && code == 0)printf("Information request (obsolete)——信息请求(作废不用)\n");
	if (type == 16 && code == 0)printf("Information reply (obsolete)——信息应答(作废不用)\n");
	if (type == 17 && code == 0)printf("Address mask request——地址掩码请求\n");
	if (type == 18 && code == 0)printf("Address mask reply——地址掩码应答\n");
}





void tcp_protool(pcap_pkthdr *header, const u_char *pkt_data, int ip_len) {
	
	struct tcp_header *tcp_protocol;
	u_int header_length = 0;
	u_int16_t checksum;
	tcp_protocol = (struct tcp_header *)(pkt_data + ip_len);
	u_short src = ntohs(tcp_protocol->sport);
	u_short des = ntohs(tcp_protocol->dport);
	u_int th_seq = ntohs(tcp_protocol->th_seq);
	u_int th_ack = ntohs(tcp_protocol->th_ack);
	u_short th_window = ntohs(tcp_protocol->th_window);
	u_short th_sum = ntohs(tcp_protocol->th_sum);
	u_short th_urg = ntohs(tcp_protocol->th_urp);
	u_short doff = ntohs(tcp_protocol->doff);
	printf("*********TCP协议*********\n");
	printf("ip_len:%d\n", ip_len);
	printf("源端口号:%d\n", src );
	printf("目的端口号:%d\n", des );
	printf("序号:%d\n", th_seq );
	printf("确认序号:%d\n", th_ack );
	printf("首部长度:%d\n", doff >> 12 * 4 );
	int len = doff >> 12 * 4;
	doff = doff & 63;
	printf("标志位(urg):%d\n", (doff & 32) & 1 );
	printf("标志位(ack):%d\n", (doff & 16) & 1 );
	printf("标志位(psh):%d\n", (doff & 8) & 1 );
	printf("标志位(rst):%d\n", (doff & 4) & 1 );
	printf("标志位(syn):%d\n", (doff & 2) & 1 );
	printf("标志位(fin):%d\n", doff & 1 );
	printf("窗口大小:%d\n", th_window);
	printf("校验和:%d\n", th_sum);
	printf("紧急指针:%d\n", th_urg);
	if (len > 20) {
		printf("TCP选项:\n");
	}
}




void udp_protool(pcap_pkthdr *header, const u_char *pkt_data, int ip_len) {
	struct udp_header *udp_protocol;
	udp_protocol = (struct udp_header *)(pkt_data + ip_len);
	u_short src = ntohs(udp_protocol->sport);
	u_short des = ntohs(udp_protocol->dport);
	u_short len = ntohs(udp_protocol->len);
	u_short sum = ntohs(udp_protocol->crc);
	printf("*********UDP协议*********\n");
	printf("ip_len:%d\n", ip_len);
	printf("源端口号:%d\n", src);
	printf("目的端口号:%d\n", des);
	printf("UDP长度:%d\n", len);
	printf("校验和:%d\n", sum);
}




void ip_protool(pcap_pkthdr *header,const u_char *pkt_data) {
		struct ip_header *ip_protocol;
		u_int header_length = 0;
		u_int offset;
		u_char tos;
		u_int16_t checksum;
		//MAC首部是14位的,加上14位得到IP协议首部  
		ip_protocol = (struct ip_header *) (pkt_data+ 14);
		checksum = ntohs(ip_protocol->ip_checksum);
		tos = ip_protocol->ip_tos;
		offset = ntohs(ip_protocol->ip_off);
		printf("*********IP协议*********\n");
		printf("版本号:%d\n", ip_protocol->ip_header_length >> 4);
		printf("首部长度:%d\n",(int)(ip_protocol->ip_header_length & 15)*4);
		printf("服务质量:%d\n", tos);
		printf("总长度:%d\n", ntohs(ip_protocol->ip_length));
		printf("16位标识:%d\n", (int)(ntohs(ip_protocol->ip_id)));
		printf("3位标志:%d\n", (offset >> 13));
		printf("偏移:%d\n", (offset & 0x1fff) * 8);
		printf("生存时间:%d\n", ip_protocol->ip_ttl);
		printf("协议类型:%d\n", ip_protocol->ip_protocol);
		printf("检验和:%d\n", checksum);
		printf("源IP地址:%s\n", inet_ntoa(ip_protocol->ip_souce_address));
		printf("目的地址:%s\n", inet_ntoa(ip_protocol->ip_destination_address));
		switch (ip_protocol->ip_protocol)
		{
			case 1: printf("上层协议是ICMP协议\n"); break;
			case 2: printf("上层协议是IGMP协议\n"); break;
			case 6: printf("上层协议是TCP协议\n"); break;
			case 17: printf("上层协议是UDP协议\n"); break;
			default:break;
		}
		int next = ip_protocol->ip_protocol;
		int ip_len = (int)(ip_protocol->ip_header_length & 15)*4;
		//printf("***************************%d\n", ip_len);
		if (next == 1) {
			icmp_protool(header, pkt_data, ip_len + 14);
		}
		else if (next == 2) {
			igmp_protool(header, pkt_data, ip_len + 14);
		}
		else if (next == 6) {
			tcp_protool(header, pkt_data, ip_len + 14);
		}
		else if (next == 17) {
			udp_protool(header, pkt_data, ip_len + 14);
		}
}



int main()
{
	pcap_if_t *alldevs;
	pcap_if_t *d;
	int inum;
	int i = 0;
	pcap_t *adhandle;
	int res;
	char errbuf[PCAP_ERRBUF_SIZE];
	struct tm *ltime;
	char timestr[16];
	struct pcap_pkthdr *header;
	const u_char *pkt_data;
	time_t local_tv_sec;



	if (pcap_findalldevs_ex((char *)PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1)
	{
		fprintf(stderr, "Error in pcap_findalldevs: %s\n", errbuf);
		exit(1);
	}

	for (d = alldevs; d; d = d->next)
	{
		printf("%d. %s", ++i, d->name);
		if (d->description)
			printf(" (%s)\n", d->description);
		else
			printf(" (No description available)\n");
	}

	if (i == 0)
	{
		printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
		return -1;
	}

	printf("Enter the interface number (1-%d):", i);
	scanf("%d", &inum);
	//inum = 4;
	if (inum < 1 || inum > i)
	{
		printf("\nInterface number out of range.\n");

		pcap_freealldevs(alldevs);
		return -1;
	}


	for (d = alldevs, i = 0; i< inum * 1; d = d->next, i++);


	if ((adhandle = pcap_open(d->name,  65536,    PCAP_OPENFLAG_PROMISCUOUS,  1000,    NULL, errbuf            
	)) == NULL)
	{
		fprintf(stderr, "\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);

		pcap_freealldevs(alldevs);
		return -1;
	}

	printf("\nlistening on %s...\n", d->description);


	pcap_freealldevs(alldevs);

	while ((res = pcap_next_ex(adhandle, &header, &pkt_data)) >= 0) {

		if (res == 0)

			continue;

		/* 将时间戳转换成可识别的格式 */
		local_tv_sec = header->ts.tv_sec;
		ltime = localtime(&local_tv_sec);
		puts("");
		puts("****************************************************************");
		puts("****************************************************************");
		strftime(timestr, sizeof timestr, "%H:%M:%S", ltime);

		printf("%s,%.6d len:%d\n", timestr, header->ts.tv_usec, header->len);
		puts("****************************************************************");

		for (i = 0; (i < header->caplen + 1); i++)
		{
			printf("%.2x ", pkt_data[i * 1]);
			if ((i % 16/*LINE_LEN*/) == 0 && i!=0) printf("\n");
			//buff[i] = pkt_data[i*1];
		}
		puts("");
		//ntohs
		u_short ethernet_type;
		struct ether_header *ethernet_protocol;			
		u_char *mac_string;
		printf("数据包长度:\n");
		printf("%d\n", header->len);
		printf("*********以太网协议*********\n");
		ethernet_protocol = (struct ether_header*)pkt_data;
		printf("以太网类型:\n");
		ethernet_type = ntohs(ethernet_protocol->ether_type);
		printf("%04x\n", ethernet_type);
		switch (ethernet_type)
		{
			case 0x0800: printf("上层协议是IP协议\n"); break;
			case 0x0806: printf("上层协议是ARP协议\n"); break;
			case 0x8035: printf("上层协议是RARP协议\n"); break;
			default:break;
		}
		printf("MAC帧源地址:\n");
		mac_string = ethernet_protocol->ether_shost;
		printf("%02x:%02x:%02x:%02x:%02x:%02x\n", *mac_string, *(mac_string + 1), *(mac_string + 2), *(mac_string + 3), *(mac_string + 4), *(mac_string + 5));
		printf("MAC帧目的地址:\n");
		mac_string = ethernet_protocol->ether_dhost;
		printf("%02x:%02x:%02x:%02x:%02x:%02x\n", *mac_string, *(mac_string + 1), *(mac_string + 2), *(mac_string + 3), *(mac_string + 4), *(mac_string + 5));
		if (ethernet_type == 0x0800)//继续分析IP协议  
		{
			/*ip_protool_packet_callback(argument, packet_header, packet_content);*/
			ip_protool(header, pkt_data);
		}
		else if (ethernet_type == 0x0806)//继续分析ARP协议
		{
			arp_protool(header, pkt_data, 14);
		}
		else if (ethernet_type == 0x0835)//继续分析RARP协议
		{
			arp_protool(header, pkt_data, 14);
		}
		puts("****************************************************************");
		puts("****************************************************************");
		puts("");
	}

	if (res == -1) {
		printf("Error reading the packets: %s\n", pcap_geterr(adhandle));
		return -1;
	}

	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值