#pac_ana.h
#ifndef _PAC_ANA_H
#define _PAC_ANA_H
#ifdef _MSC_VER
/*
?* we do not want the warnings about the old deprecated and unsecure CRT functions
?* since these examples can be compiled under *nix as well
?*/
#define _CRT_SECURE_NO_WARNINGS
#endif
?/*set the environment head files*/
#define WIN32
#pragma comment (lib, "ws2_32.lib") ?//load ws2_32.dll
/*set the C++ head files*/
#include <iostream>
#include <stdio.h>
#include <map>
#include <string>
#include <iomanip>
#include <sstream>
/*set the wpcap head files*/
#include <pcap.h>
#include <WinSock2.h>
#define DIVISION "--------------------"
#define B_DIVISION "==================="
?/* 4 bytes IP address */
typedef struct ip_v4_address ip_v4_address;
/* 16 bytes IP address */
typedef struct ip_v6_address ip_v6_address;
/*8 bytes MAC addresss*/
typedef struct mac_address mac_address;
/*ethernet header*/
typedef struct ethernet_header ethernet_header;
/* IPv4 header */
typedef struct ip_v4_header ip_v4_header;
/*IPv6 header*/
typedef struct ip_v6_header ip_v6_header;
/*arp header*/
typedef struct arp_header arp_header;
/*TCP header*/
typedef struct tcp_header tcp_header;
/* UDP header*/
typedef struct udp_header udp_header;
/*ICMP header*/
typedef struct icmp_header icmp_header;
/* prototype of the packet handler */
// 回调函数
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);
/*analysis the ethernet packet*/
//void packet_handler(u_char* packets,const struct pcap_pkthdr *header,const u_char *data)
void ethernet_package_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);
/*analysis the IPv4 packet*/
void ip_v4_package_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);
/*analysis the IPv6 packet*/
void ip_v6_package_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);
/*analysis the arp packet*/
void arp_package_handler(u_char* param, const struct pcap_pkthdr *header, const u_char *pkt_data);
/*analysis the udp packet*/
void udp_package_handler(u_char* param, const struct pcap_pkthdr *header, const u_char *pkt_data);
/*analysis the tcp packet*/
void tcp_package_handler(u_char* param, const struct pcap_pkthdr *header, const u_char *pkt_data);
/*analysis the icmp packet*/
void icmp_package_handler(u_char* param, const struct pcap_pkthdr *header, const u_char *pkt_data);
/*count the package with c++ std::map*/
void add_to_map(std::map<std::string, int> &counter, ip_v4_address ip);
void add_to_map(std::map<std::string, int> &counter, ip_v6_address ip);
/*print the map info*/
void print_map(std::map<std::string, int> counter);
class ethernet_package_handler;
class packet_handler;
class ip_v4_package_handler;
class tcp_package_handler;
#endif // !_PAC_ANA_H
#winpcap.cpp
#include "pac_ana.h"
#pragma comment(lib,"wpcap.lib")
#pragma comment(lib,"packet.lib")
#pragma comment(lib,"ws2_32.lib")
using namespace std;
/*ip counter*/
map<string, int> counter;
/*header structure*/
struct ip_v4_address
{
?? ?u_char byte1;
?? ?u_char byte2;
?? ?u_char byte3;
?? ?u_char byte4;
};
struct ip_v6_address
{
?? ?u_short part1;
?? ?u_short part2;
?? ?u_short part3;
?? ?u_short part4;
?? ?u_short part5;
?? ?u_short part6;
?? ?u_short part7;
?? ?u_short part8;
};
struct mac_address
{
?? ?u_char byte1;
?? ?u_char byte2;
?? ?u_char byte3;
?? ?u_char byte4;
?? ?u_char byte5;
?? ?u_char byte6;
};
struct ethernet_header
{
?? ?mac_address des_mac_addr;
?? ?mac_address src_mac_addr;
?? ?u_short type;
};
struct ip_v4_header
{
?? ?u_char?? ?ver_ihl;?? ??? ?// Version (4 bits) + Internet header length (4 bits)
?? ?u_char?? ?tos;?? ??? ??? ?// Type of service?
?? ?u_short tlen;?? ??? ??? ?// Total length?
?? ?u_short identification; // Identification
?? ?u_short flags_fo;?? ??? ?// Flags (3 bits) + Fragment offset (13 bits)
?? ?u_char?? ?ttl;?? ??? ??? ?// Time to live
?? ?u_char?? ?proto;?? ??? ??? ?// Protocol
?? ?u_short checksum;?? ??? ??? ?// Header checksum
?? ?ip_v4_address?? ?src_ip_addr;?? ??? ?// Source address
?? ?ip_v4_address?? ?des_ip_addr;?? ??? ?// Destination address
?? ?u_int?? ?op_pad;?? ??? ??? ?// Option + Padding
};
struct ip_v6_header
{
?? ?u_int32_t ver_trafficclass_flowlabel;
?? ?u_short payload_len;
?? ?u_char next_head;
?? ?u_char ttl;
?? ?ip_v6_address src_ip_addr;
?? ?ip_v6_address dst_ip_addr;
};
struct arp_header
{
?? ?u_short hardware_type;
?? ?u_short protocol_type;
?? ?u_char hardware_length;
?? ?u_char protocol_length;
?? ?u_short operation_code;
?? ?mac_address source_mac_addr;
?? ?ip_v4_address source_ip_addr;
?? ?mac_address des_mac_addr;
?? ?ip_v4_address des_ip_addr;
};
struct tcp_header
{
?? ?u_short sport;
?? ?u_short dport;
?? ?u_int sequence;
?? ?u_int acknowledgement;
?? ?u_char offset;
?? ?u_char flags;
?? ?u_short windows;
?? ?u_short checksum;
?? ?u_short urgent_pointer;
};
struct udp_header
{
?? ?u_short sport;?? ??? ??? ?// Source port
?? ?u_short dport;?? ??? ??? ?// Destination port
?? ?u_short len;?? ??? ??? ?// Datagram length
?? ?u_short checksum;?? ??? ??? ?// Checksum
};
struct icmp_header
{
?? ?u_char type;
?? ?u_char code;
?? ?u_short checksum;
?? ?u_short id;
?? ?u_short sequence;
};
class ethernet_package_handler {
public:
?? ?
?? ?void ip_v4_package_handler(string &data);
};
void ethernet_package_handler::ip_v4_package_handler(string &data) {
}
int main()
{
?? ?pcap_if_t *alldevs;
?? ?pcap_if_t *d;
?? ?int inum = 3;
?? ?int i = 0;
?? ?int pktnum = 0;
?? ?pcap_t *adhandle;
?? ?char errbuf[PCAP_ERRBUF_SIZE];
?? ?/*u_int表示无符号整形,意味着该变量的值不会出现负数;
?? ?int表示有符号整形,意味着该变量可以是正、负数;
?? ?如果接口没有地址,那么我们假设一个C类的掩码*/
?? ?u_int netmask = 0xffffff;
?? ?struct bpf_program fcode;
?? ?if (pcap_findalldevs(&alldevs, errbuf) == -1)
?? ?{
?? ??? ?fprintf(stderr, "Error in pcap_findalldevs: %s\n", errbuf);
?? ??? ?exit(1);
?? ?}
?? ?/*你获得的设备信息在alldevs里,把它赋给同类型的d,
?? ?第二个为d自己,然后枚举下一个设备信息.d = d->next.*/
?? ?for (d = alldevs; d; d = d->next)
?? ?{
?? ??? ?cout << ++i << "." << d->name;
?? ??? ?if (d->description)
?? ??? ??? ?cout << "\t" << d->description << endl;
?? ??? ?else
?? ??? ??? ?cout << " (No description available)" << endl;
?? ?}
?? ?if (i == 0)
?? ?{
?? ??? ?cout << "\nNo interfaces found! Make sure WinPcap is installed." << endl;
?? ??? ?return -1;
?? ?}
?? ?cout << "Enter the interface number (1-" << i << "): ";
?? ?//int inum = 3;
?? ?//cin >> inum;
?? ?cout << inum << endl;
?? ?while (inum < 1 || inum > i)
?? ?{
?? ??? ?cout << "\n输入有误请重新输入." << endl;
?? ??? ?//pcap_freealldevs(alldevs);
?? ??? ?cin >> inum;
?? ?}
?? ?for (d = alldevs, i = 0; i < inum - 1; d = d->next, i++);
?? ?/*pcap_open_live()用于获取数据包捕获描述符以查看网络上的数据包。device是指定要打开的网络设备的字符串; 在具有2.2或更高版本内核的Linux系统上,
?? ?可以使用“any”或NULL的设备参数来捕获来自所有接口的数据包。snaplen指定要捕获的最大字节数。如果该值小于捕获的数据包的大小,
?? ?则该数据包的第一个snaplen字节将被捕获并作为数据包数据提供。在大多数(如果不是全部)网络中,值65535应该足以捕获数据包中可用的所有数据。
?? ?promisc指定是否将接口置于混杂模式。(注意,即使这个参数是假的,接口也可能在混杂模式下出于某些其他原因。)现在,这不适用于“任何”设备;
?? ?如果提供了“any”或NULL的参数,则将忽略promisc标志。to_ms指定读取超时(以毫秒为单位)。读取超时用于安排在看到数据包时读取不一定立即返回,
?? ?但是在一次操作中,等待一段时间才能允许更多数据包到达并从操作系统内核读取多个数据包。*/
?? ?if ((adhandle = pcap_open_live(d->name,?? ?// name of the device
?? ??? ?128,?? ??? ??? ?// portion of the packet to capture.?
?? ??? ??? ??? ??? ??? ?// 65536 grants that the whole packet will be captured on all the MACs.
?? ??? ?1,?? ??? ??? ??? ?// promiscuous mode (nonzero means promiscuous)
?? ??? ?1000,?? ??? ??? ?// read timeout
?? ??? ?errbuf?? ??? ??? ?// error buffer
?? ?)) == NULL)
?? ?{
?? ??? ?fprintf(stderr, "\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);
?? ??? ?pcap_freealldevs(alldevs);
?? ??? ?return -1;
?? ?}
?? ?cout << "listening on " << d->description << "...." << endl;
?? ?pcap_freealldevs(alldevs); //释放一个接口列表,这个列表将被 pcap_findalldevs()返回
?? ?//过滤器
?? ?if (pcap_compile(adhandle, &fcode, "src net 10.2.15.78 && dst net 10.2.100.252 && tcp", 1, netmask) < 0)
?? ?{
?? ??? ?fprintf(stderr, "\nUnable to compile the packet filter. Check the syntax.\n");
?? ??? ?pcap_close(adhandle);
?? ??? ?return -1;
?? ?}
?? ?if (pcap_setfilter(adhandle, &fcode) < 0)
?? ?{
?? ??? ?fprintf(stderr, "\nError setting the filter.\n");
?? ??? ?pcap_close(adhandle);
?? ??? ?return -1;
?? ?}
?? ?cout << "请输入要捕获的数据包数(0用于保持捕获): ";
?? ?//int pktnum = 2;
?? ?//cin >> pktnum;
?? ?cout << pktnum << endl;
?? ?/*pcap_loop原型是pcap_loop(pcap_t *p,int cnt,pcap_handler callback,u_char *user)
?? ?其中第一个参数是pcap的句柄, 第二个是指定捕获的数据包个数, 如果为 - 1则无限循环捕获。第四个参数user是留给用户使用的。*/
?? ?
?? ?pcap_loop(adhandle, pktnum, packet_handler, NULL);
?? ?pcap_close(adhandle);
?? ?/*当程序调用getchar时,程序就等着用户按键。用户输入的字符被存放在键盘缓冲区中。直到用户按回车为止。当用户键入回车之后,getchar才开始从stdin流中每次读入一个字符。*/
?? ?getchar();
?? ?return 0;
}
/* Callback function invoked by libpcap for every incoming packet
这里pcap_loop的作用是抓包,每抓到一个包之后就调用callback函数来处理之,callback需要你自己编写,callback的类似于这种:
void PacketCallback(u_char *user, const struct pcap_pkthdr *h,const u_char *p);
你给出的代码是定义了一个函数指针grinder_t的类型,就可以用grinder_t来声明函数指针了
grinder应该就是作为一个回调函数来处理pcap抓到的包
pcap_loop和callback之间参数存在联系,pcap_loop的最后一个参数user是留给用户使用的,当callback被调用的时候这 个值会传递给callback的第一个参数(也叫user),callback的最后一个参数p指向一块内存空间,这个空间中存放的就是 pcap_loop抓到的数据包。callback的第二个参数是一个结构体指针,该结构体定义如下:
struct pcap_pkthdr {
struct timeval ts;
bpf_u_int32 caplen;
bpf_u_int32 len;
};
这个结构体是由pcap_loop自己填充的,用来取得一些关于数据包的信息
所以,在callback函数当中只有第一个user指针是可以留给用户使用的,如果你想给callback传递自己参数,那就只能通过pcap_loop的最后一个参数user来实现了*/
/*u_char *param:数据包存储的文件指针
struct pcap_pkthdr * header: 并非是数据包的指针,只是与数据包捕获驱动有关的一个header ,是堆文件包的结构体首部指针。可以得到时间值,数据包长度
const_char * pkt_data:指向数据包内容的指针,包括了协议头,可以经过计算获得IP数据包头部的位置, UDP首部的位置。*/
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
?? ?//typedef unsigned int == uin32_t
?? ?static uint32_t pkt_num = 0;
?? ?struct tm *ltime;
?? ?char timestr[16];
?? ?time_t local_tv_sec;
?? ?/* 将时间戳转换成可识别的格式 */
?? ?/* convert the timestamp to readable format */
?? ?local_tv_sec = header->ts.tv_sec;
?? ?//localtime获取当前时间和日期并转换为本地时间
?? ?ltime = localtime(&local_tv_sec);
?? ?strftime(timestr, sizeof timestr, "%H:%M:%S", ltime);
?? ?// ts.tv_sec 和 ts.tv_usec B_DIVISION ??
?? ?/*cout << B_DIVISION << "time:" << timestr << ","
?? ??? ?<< header->ts.tv_usec << " ?len:" << header->len << B_DIVISION << endl;*/
?? ?std::cout << "pkt num : " << pkt_num++ << std::endl;
?? ?ethernet_package_handler(param, header, pkt_data);
}
void ethernet_package_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
?? ?ethernet_header* eh = (ethernet_header*)pkt_data;
?? ?//cout << DIVISION << "以太网协议分析结构" << DIVISION << endl;
?? ?//ntohs() 将一个16位数由网络字节顺序转换为主机字节顺序
?? ?u_short type = ntohs(eh->type);
?? ?switch (type)
?? ?{
?? ?case 0x0800:
?? ??? ?ip_v4_package_handler(param, header, pkt_data);
?? ??? ?break;
?? ?case 0x0806:
?? ??? ?arp_package_handler(param, header, pkt_data);
?? ??? ?break;
?? ?case 0x86DD:
?? ??? ?ip_v6_package_handler(param, header, pkt_data);
?? ??? ?break;
?? ?default:
?? ??? ?break;
?? ?}
?? ?cout << endl << endl;
}
void arp_package_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
?? ?arp_header* ah;
?? ?ah = (arp_header*)(pkt_data + 14);
?? ?//cout << DIVISION << "ARP协议分析结构" << DIVISION << endl;
?? ?u_short operation_code = ntohs(ah->operation_code);
?? ?cout << "硬件类型:" << ntohs(ah->hardware_type) << endl;
?? ?cout << "协议类型:0x" << hex << ntohs(ah->protocol_type) << endl;
?? ?cout << setbase(10);
?? ?cout << "硬件地址长度:" << int(ah->hardware_length) << endl;
?? ?cout << "协议地址长度:" << int(ah->protocol_length) << endl;
?? ?switch (operation_code)
?? ?{
?? ?case 1:
?? ??? ?cout << "ARP请求协议" << endl;
?? ??? ?break;
?? ?case 2:
?? ??? ?cout << "ARP应答协议" << endl;
?? ??? ?break;
?? ?case 3:
?? ??? ?cout << "ARP请求协议" << endl;
?? ??? ?break;
?? ?case 4:
?? ??? ?cout << "RARP应答协议" << endl;
?? ??? ?break;
?? ?default:
?? ??? ?break;
?? ?}
?? ?cout << "源IP地址:"
?? ??? ?<< int(ah->source_ip_addr.byte1) << "."
?? ??? ?<< int(ah->source_ip_addr.byte2) << "."
?? ??? ?<< int(ah->source_ip_addr.byte3) << "."
?? ??? ?<< int(ah->source_ip_addr.byte4) << endl;
?? ?cout << "目的IP地址:"
?? ??? ?<< int(ah->des_ip_addr.byte1) << "."
?? ??? ?<< int(ah->des_ip_addr.byte2) << "."
?? ??? ?<< int(ah->des_ip_addr.byte3) << "."
?? ??? ?<< int(ah->des_ip_addr.byte4) << endl;
?? ?add_to_map(counter, ah->source_ip_addr);
?? ?print_map(counter);
}
void ip_v4_package_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
?? ?ip_v4_header *ih;
?? ?// 14是以太网mac帧的帧头长度,14 = 6个字节的目的地址+6个字节的源地址+2个字节的类型说明
?? ?ih = (ip_v4_header *)(pkt_data + 14); //14 measn the length of ethernet header
?? ?switch (ih->proto)
?? ?{
?? ?case 6:
?? ??? ?tcp_package_handler(param, header, pkt_data);
?? ??? ?break;
?? ?case 17:
?? ??? ?udp_package_handler(param, header, pkt_data);
?? ??? ?break;
?? ?case 1:
?? ??? ?icmp_package_handler(param, header, pkt_data);
?? ??? ?break;
?? ?default:
?? ??? ?break;
?? ?}
?? ?add_to_map(counter, ih->src_ip_addr);
?? ?print_map(counter);
}
void ip_v6_package_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
?? ?ip_v6_header *ih;
?? ?ih = (ip_v6_header *)(pkt_data + 14); //14 measn the length of ethernet header
?? ?int version = (ih->ver_trafficclass_flowlabel & 0xf0000000) >> 28;
?? ?int traffic_class = ntohs((ih->ver_trafficclass_flowlabel & 0x0ff00000) >> 20);
?? ?int flow_label = ih->ver_trafficclass_flowlabel & 0x000fffff;
?? ?cout << "版本号:" << version << endl;
?? ?cout << "通信量类:" << traffic_class << endl;
?? ?cout << "流标号:" << flow_label << endl;
?? ?cout << "有效载荷:" << ntohs(ih->payload_len) << endl;
?? ?cout << "下一个首部:" << int(ih->next_head) << endl;
?? ?cout << "跳数限制:" << int(ih->ttl) << endl;
?? ?cout << "源IP地址:"
?? ??? ?<< int(ih->src_ip_addr.part1) << ":"
?? ??? ?<< int(ih->src_ip_addr.part2) << ":"
?? ??? ?<< int(ih->src_ip_addr.part3) << ":"
?? ??? ?<< int(ih->src_ip_addr.part4) << ":"
?? ??? ?<< int(ih->src_ip_addr.part5) << ":"
?? ??? ?<< int(ih->src_ip_addr.part6) << ":"
?? ??? ?<< int(ih->src_ip_addr.part7) << ":"
?? ??? ?<< int(ih->src_ip_addr.part8) << endl;
?? ?cout << "目的IP地址:"
?? ??? ?<< int(ih->dst_ip_addr.part1) << ":"
?? ??? ?<< int(ih->dst_ip_addr.part2) << ":"
?? ??? ?<< int(ih->dst_ip_addr.part3) << ":"
?? ??? ?<< int(ih->dst_ip_addr.part4) << ":"
?? ??? ?<< int(ih->dst_ip_addr.part5) << ":"
?? ??? ?<< int(ih->dst_ip_addr.part6) << ":"
?? ??? ?<< int(ih->dst_ip_addr.part7) << ":"
?? ??? ?<< int(ih->dst_ip_addr.part8) << endl;
?? ?switch (ih->next_head)
?? ?{
?? ?case 6:
?? ??? ?tcp_package_handler(param, header, pkt_data);
?? ??? ?break;
?? ?case 17:
?? ??? ?udp_package_handler(param, header, pkt_data);
?? ??? ?break;
?? ?case 58:
?? ??? ?icmp_package_handler(param, header, pkt_data);
?? ??? ?break;
?? ?default:
?? ??? ?break;
?? ?}
?? ?add_to_map(counter, ih->src_ip_addr);
?? ?//print_map(counter);
}
void udp_package_handler(u_char* param, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
?? ?udp_header *uh;
?? ?uh = (udp_header *)(pkt_data + 20 + 14);
?? ?//cout << DIVISION << "UDP协议分析结构" << DIVISION << endl;
?? ?cout << "源端口:" << ntohs(uh->sport) << endl;
?? ?cout << "目的端口:" << ntohs(uh->dport) << endl;
?? ?cout << "长度:" << ntohs(uh->len) << endl;
?? ?cout << "检验和:" << ntohs(uh->checksum) << endl;
}
void tcp_package_handler(u_char* param, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
?? ?const uint16_t ether_header_len = 14;
?? ?const uint16_t ip_header_len = 20;
?? ?tcp_header* th;
?? ?th = (tcp_header*)(pkt_data + ether_header_len + ip_header_len);
?? ?uint16_t tcp_header_len = th->offset * 4;
?? ?uint32_t payload_len = (header->caplen - ether_header_len - ip_header_len - tcp_header_len) > 0 ? (header->caplen - ether_header_len - ip_header_len - tcp_header_len) : 0;
?? ?if (payload_len == 0)
?? ??? ?return;
?? ?string mes = ((const char*)(pkt_data + ether_header_len + ip_header_len + tcp_header_len));
?? ?int x = mes.find("name=\"name\"");
?? ?if (x == -1)
?? ??? ?return;
?? ?string mes1 = ((const char*)(pkt_data + ether_header_len + ip_header_len + tcp_header_len + x + 15));
?? ?cout << mes1.substr(0, 7) << endl;
?? ?int y = mes.find("name=\"pass\"");
?? ?if (y == -1)
?? ??? ?return;
?? ?string mes2 = ((const char*)(pkt_data + ether_header_len + ip_header_len + tcp_header_len + y + 15)); //15是name="pass"和换行
?? ?int z = mes.find("Content-Disposition: form-data; name=\"ukey\"");
?? ?string mes3 = ((const char*)(pkt_data + ether_header_len + ip_header_len + tcp_header_len + z - 46));
?? ?//cout << mes2.size() << "\n" << mes3.size() << endl;
?? ?cout << mes2.substr(0, mes2.size() - mes3.size()) << endl;
?? ?//std::string mes2 - std::string mes3;
}
void icmp_package_handler(u_char* param, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
?? ?icmp_header* ih;
?? ?ih = (icmp_header*)(pkt_data + 14 + 20);
?? ?//cout << DIVISION << "ICMP协议分析结构" << DIVISION << endl;
?? ?cout << "ICMP类型:" << ih->type;
?? ?switch (ih->type)
?? ?{
?? ?case 8:
?? ??? ?cout << "ICMP回显请求协议" << endl;
?? ??? ?break;
?? ?case 0:
?? ??? ?cout << "ICMP回显应答协议" << endl;
?? ??? ?break;
?? ?default:
?? ??? ?break;
?? ?}
?? ?cout << "ICMP代码:" << ih->code << endl;
?? ?cout << "标识符:" << ih->id << endl;
?? ?cout << "序列码:" << ih->sequence << endl;
?? ?cout << "ICMP校验和:" << ntohs(ih->checksum) << endl;
}
void add_to_map(map<string, int> &counter, ip_v4_address ip)
{
?? ?string ip_string;
?? ?int amount = 0;
?? ?map<string, int>::iterator iter;
?? ?ip_string = to_string(ip.byte1) + "."
?? ??? ?+ to_string(ip.byte2) + "."
?? ??? ?+ to_string(ip.byte3) + "."
?? ??? ?+ to_string(ip.byte4);
?? ?iter = counter.find(ip_string);
?? ?if (iter != counter.end())
?? ?{
?? ??? ?amount = iter->second;
?? ?}
?? ?counter.insert_or_assign(ip_string, ++amount);
}
void add_to_map(map<string, int> &counter, ip_v6_address ip)
{
?? ?string ip_string;
?? ?int amount = 0;
?? ?map<string, int>::iterator iter;
?? ?ip_string = to_string(ip.part1) + ":"
?? ??? ?+ to_string(ip.part2) + ":"
?? ??? ?+ to_string(ip.part3) + ":"
?? ??? ?+ to_string(ip.part4) + ":"
?? ??? ?+ to_string(ip.part5) + ":"
?? ??? ?+ to_string(ip.part6) + ":"
?? ??? ?+ to_string(ip.part7) + ":"
?? ??? ?+ to_string(ip.part8);
?? ?iter = counter.find(ip_string);
?? ?if (iter != counter.end())
?? ?{
?? ??? ?amount = iter->second;
?? ?}
?? ?counter.insert_or_assign(ip_string, ++amount);
}
void print_map(map<string, int> counter)
{
?? ?map<string, int>::iterator iter;
?? ?//cout << DIVISION << "流量统计" << DIVISION << endl;
?? ?//setw(int n)是c++中在输出操作中使用的字段宽度设置,设置输出的域宽,n表示字段宽度。只对紧接着的输出有效,紧接着的输出结束后又变回默认的域宽。
?? ?//cout << "IP" << setfill(' ') << setw(45) << "流量" << endl;
?? ?for (iter = counter.begin(); iter != counter.end(); iter++)
?? ?{
?? ??? ?//cout << iter->first << setfill('.') << setw(45 - iter->first.length()) << iter->second << endl;
?? ?}
}
//欢迎讨论,我也有很多不会,我是缝合怪
//我的账号密码在tcp层下可以用wireshark组合查看.
|