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;
}