#include <stdio.h>
#include <iostream>
#include<winsock2.h>
#include <thread>
#define HAVE_REMOTE
#include "pcap.h"
using namespace std;
extern u_int8_t* packPacket(u_int8_t*data, u_int16_t len, u_int8_t proto=IPPROTO_UDP);
//char bpf_filter_string[]="udp port 18080 and dst host 172.16.2.121 and src host 172.16.2.35";
char bpf_filter_string[]="udp port 18080 and dst host 172.16.2.121";
u_int8_t* myMac = new u_int8_t[6]();
u_int8_t* remoteMac = new u_int8_t[6]();
string myIP ="172.16.2.121";
string remoteIP = "172.16.2.35";
u_int16_t srcPort = 18080;
u_int16_t dstPort = 18080;
bpf_u_int32 net_mask=0; //掩码地址
pcap_t * adapterHandle;//适配器句柄
void ethernet_protocol_packet_callback(u_char *argument,const struct pcap_pkthdr* packet_header,const u_char* packet_content);
void ip_protool_packet_callback(u_char *argument,const struct pcap_pkthdr* packet_header,const u_char* packet_content);
void tcp_protool_packet_callback(u_char *argument,const struct pcap_pkthdr* packet_header,const u_char* packet_content);
void udp_protool_packet_callback(u_char *argument,const struct pcap_pkthdr* packet_header,const u_char* packet_content);
//以太网协议头
struct ether_header
{
u_int8_t ether_dhost[6]; //目的Mac地址
u_int8_t ether_shost[6]; //源Mac地址
u_int16_t ether_type; //协议类型
};
//IPv4协议头
struct ip_header
{
#if defined(WORDS_BIENDIAN)
u_int8_t ip_version:4,ip_header_length:4;
#else
u_int8_t ip_header_length:4,ip_version:4;
#endif
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;
};
//UDP协议头
struct udphdr
{
u_int16_t source_port; /*源地址端口*/
u_int16_t dest_port; /*目的地址端口*/
u_int16_t len; /*UDP长度*/
u_int16_t check; /*UDP校验和*/
};
//TCP协议头
#define __LITTLE_ENDIAN_BITFIELD
struct tcphdr
{
u_int16_t source_port; /*源地址端口*/
u_int16_t dest_port; /*目的地址端口*/
u_int32_t seq; /*序列号*/
u_int32_t ack_seq; /*确认序列号*/
#if defined(__LITTLE_ENDIAN_BITFIELD)
u_int16_t res1:4, /*保留*/
doff:4, /*偏移*/
fin:1, /*关闭连接标志*/
syn:1, /*请求连接标志*/
rst:1, /*重置连接标志*/
psh:1, /*接收方尽快将数据放到应用层标志*/
ack:1, /*确认序号标志*/
urg:1, /*紧急指针标志*/
ece:1, /*拥塞标志位*/
cwr:1; /*拥塞标志位*/
#elif defined(__BIG_ENDIAN_BITFIELD)
u_int16_t doff:4, /*偏移*/
res1:4, /*保留*/
cwr:1, /*拥塞标志位*/
ece:1, /*拥塞标志位*/
urg:1, /*紧急指针标志*/
ack:1, /*确认序号标志*/
psh:1, /*接收方尽快将数据放到应用层标志*/
rst:1, /*重置连接标志*/
syn:1, /*请求连接标志*/
fin:1; /*关闭连接标志*/
#else
u_int16_t flag;
#endif
u_int16_t window; /*滑动窗口大小*/
u_int16_t check; /*校验和*/
u_int16_t urg_ptr; /*紧急字段指针*/
};
// u_int16_t in_cksum (u_int16_t * addr, int len)
// {
// int nleft = len;
// u_int32_t sum = 0;
// u_int16_t *w = addr;
// u_int16_t answer = 0;
// while (nleft > 1) {
// sum += *w++;
// nleft -= 2;
// }
// /* mop up an odd byte, if necessary */
// if (nleft == 1) {
// * (unsigned char *) (&answer) = * (unsigned char *) w;
// sum += answer;
// }
// /* add back carry outs from top 16 bits to low 16 bits */
// sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
// sum += (sum >> 16); /* add carry */
// answer = ~sum; /* truncate to 16 bits */
// return (answer);
// }
u_int16_t in_cksum(u_int16_t *addr, int count) {
register u_int32_t sum=0;
while (count > 1) {
sum += *addr++;
if (sum & 0x80000000) /* if high-orderbit set, fold */
sum = (sum & 0xFFFF) + (sum>> 16);
count -= 2;
}
if(count>0) {
sum += *(u_int8_t*)addr;
}
while(sum>>16){
sum = (sum & 0xffff) + (sum >>16);
}
return (u_int16_t)(~sum);
}
//以太网协议分析
void ethernet_protocol_packet_callback(u_char *argument,const struct pcap_pkthdr* packet_header,const u_char* packet_content)
{
u_short ethernet_type;
struct ether_header *ethernet_protocol;
u_char *mac_string;
static int packet_number = 1;
printf("-----------------eth-----------------------------\n");fflush(stdout);
printf("packet index %d\n",packet_number);
printf("captime:%d\n",packet_header->ts.tv_sec);
printf("packet len:%d\n",packet_header->len);
ethernet_protocol=(struct ether_header*)packet_content;//获得数据包内容
ethernet_type=ntohs(ethernet_protocol->ether_type);//获得以太网类型
printf("eth type:%04x\n",ethernet_type);
switch (ethernet_type)
{
case 0x0800: printf("IPv4\n");break;
case 0x0806: printf("ARP\n");break;
case 0x8035: printf("RARP\n");break;
case 0x814C: printf("SNMP\n");break;
case 0x8137: printf("(IPX:Internet Packet Exchange)\n");break;
case 0x86DD: printf("IPv6\n");break;
case 0x880B: printf("(PPP:Point-to-Point Protocol)\n");break;
default:break;
}
//--------------------------------------------------------//
for(int i=0; i<6; ++i){
remoteMac[i] = ethernet_prot