基本信息
源码名称:c++ 网络流量统计 示例源码
源码大小:7.54KB
文件格式:.cpp
开发语言:C/C++
更新时间:2017-12-27
友情提示:(无需注册或充值,赞助后即可获取资源下载链接)
嘿,亲!知识可是无价之宝呢,但咱这精心整理的资料也耗费了不少心血呀。小小地破费一下,绝对物超所值哦!如有下载和支付问题,请联系我们QQ(微信同号):813200300
本次赞助数额为: 2 元×
微信扫码支付:2 元
×
请留下您的邮箱,我们将在2小时内将文件发到您的邮箱
源码介绍
网络课程设计流量统计,网络流量统计课设
网络课程设计流量统计,网络流量统计课设
#include "pcap.h"
#include<remote-ext.h>
#ifndef WIN32
#include <sys/socket.h>
#include <netinet/in.h>
#else
#include <winsock.h>
#endif
#include<conio.h>
#include<time.h>
/*全局变量*/
/*=====================================================*/
int num_packet = 0; //统计的数据包个数
pcap_t *adhandle;
//struct pcap_stat pkt_stat;
struct bpf_program fcode;
pcap_if_t *alldevs, *d;
char errbuf[PCAP_ERRBUF_SIZE];
u_int netmask;
/*=====================================================*/
/* 4字节的IP地址 */
typedef struct ip_address{
u_char byte1;
u_char byte2;
u_char byte3;
u_char byte4;
}ip_address;
/*ip链表*/
typedef struct ip_link{
int number=1;
u_char byte1;
u_char byte2;
u_char byte3;
u_char byte4;
struct ip_link *next;
}ip_link;
ip_link *head;
/* IPv4 首部 */
typedef struct ip_header{
u_char ver_ihl; // 版本 (4 bits) 首部长度 (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 crc; // 首部校验和(Header checksum)
ip_address saddr; // 源地址(Source address)
ip_address daddr; // 目的地址(Destination address)
u_int op_pad; // 选项与填充(Option Padding)
}ip_header;
/*设置一个观察变量表示是否暂停抓包*/
bool ispause = false;
/*监听键盘输入*/
DWORD WINAPI ThreadProc1(LPVOID lpParam)
{
while (1)
{
if (_kbhit()) //检查是否有键盘输入
{
ispause = _getch() == 27; //esc键
}
}
}
/*将捕获的数据包的源ip加入链表*/
void add_link_ip(ip_address ip)
{
ip_link *q=head;
while (q->next != NULL)
{
q = q->next;
if (q->byte1 == ip.byte1&&
q->byte2 == ip.byte2&&
q->byte3 == ip.byte3&&
q->byte4 == ip.byte4)
{
q->number ;
return;
}
}
ip_link *p = (ip_link*)malloc(sizeof(ip_link));
p->byte1 = ip.byte1;
p->byte2 = ip.byte2;
p->byte3 = ip.byte3;
p->byte4 = ip.byte4;
p->number = 1;
p->next = head->next;
head->next = p;
//printf("添加一条数据\n");
}
/*获取网卡列表*/
void get_adapter()
{
if (pcap_findalldevs(&alldevs, errbuf) == -1)//无法找到网卡列表
{
fprintf(stderr, "error in pcap_findalldevs: %s\n", errbuf);
exit(1);
}
}
/*输出网卡信息*/
int printf_adapter()
{
u_int32_t net_ip, net_mask;
struct in_addr net_ip_address, net_mask_address;//网卡IP信息,在pcap.h里面有定义
int num=0;
char *net_ip_string, *net_mask_string;
pcap_if_t *d;
/* 打印列表*/
for (d = alldevs; d; d = d->next)
{
printf("%d.\n %s", num, d->name);
printf("\nDescription: %s\n", d->description);
pcap_lookupnet(d->name, &net_ip, &net_mask, errbuf);
net_ip_address.s_addr = net_ip;
net_ip_string = inet_ntoa(net_ip_address);//format
printf("网络地址: %s \n", net_ip_string);
net_mask_address.s_addr = net_mask;
net_mask_string = inet_ntoa(net_mask_address);//format
printf("子网掩码: %s \n", net_mask_string);
printf("\n");
}
return num;
if (num == 0)
{
printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
return -1;
}
}
/*设置网卡模式,获取网络地址和掩码地址*/
int get_address()
{
/* 打开适配器 */
if ((adhandle = pcap_open(d->name, // 设备名
65536, // 要捕捉的数据包的部分
// 65535保证能捕获到不同数据链路层上的每个数据包的全部内容
PCAP_OPENFLAG_PROMISCUOUS, // 混杂模式
1000, // 读取超时时间
NULL, // 远程机器验证
errbuf // 错误缓冲池
)) == NULL)
{
fprintf(stderr, "\nUnable to open the adapter. %s is not supported by WinPcap\n");
/* 释放设备列表 */
pcap_freealldevs(alldevs);
return -1;
}
if (d->addresses != NULL)
/* 获得接口第一个地址的掩码 */
netmask = ((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr;
else
/* 如果接口没有地址,那么我们假设一个C类的掩码 */
netmask = 0xffffff;
}
/*选择网卡,跳转设备*/
int select_adapter(int i)
{
int inum;
printf("Enter the interface number (1-%d):", i);
scanf("%d", &inum);
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 );
}
/*设置过滤器*/
int filter()
{
char packet_filter[1000]; //设置过滤规则
printf("请输入过滤规则\n");
getchar();
gets(packet_filter);
//printf("%s", packet_filter);
//编译过滤器
if (pcap_compile(adhandle, &fcode, packet_filter, 1, netmask) < 0)
{
fprintf(stderr, "\nUnable to compile the packet filter. Check the syntax.\n");
/* 释放设备列表 */
pcap_freealldevs(alldevs);
return -1;
}
//设置过滤器
if (pcap_setfilter(adhandle, &fcode) < 0)
{
fprintf(stderr, "\nError setting the filter.\n");
/* 释放设备列表 */
pcap_freealldevs(alldevs);
return -1;
}
}
/*将统计数据输出*/
void printf_link_ip(ip_link *head)
{
if (head == NULL)
{
// printf("tututu");
return;
}
ip_link *q = head;
printf("========================================\n");
printf("|共接收%d数据包\t\t\t|\n", num_packet);
printf("|\t源地址\t\t\t|数量\n");
while (q->next != NULL)
{
printf("|\t%d.%d.%d.%d\t\t|", q->next->byte1, q->next->byte2, q->next->byte3, q->next->byte4);
printf("%d个\n", q->next->number);
q = q->next;
}
printf("========================================\n");
}
/* 回调函数,当收到每一个数据包时会被libpcap所调用 */
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
struct tm *ltime;
char timestr[16];
ip_header *ih;
u_int ip_len;
time_t local_tv_sec;
if (ispause)
{
pcap_breakloop(adhandle);
printf_link_ip(head);
return;
}
/* 将时间戳转换成可识别的格式 */
local_tv_sec = header->ts.tv_sec;
ltime = localtime(&local_tv_sec);
strftime(timestr, sizeof timestr, "%H:%M:%S", ltime);
/* 打印数据包的时间戳和长度 */
printf("%s.%.6d len:%d ", timestr, header->ts.tv_usec, header->len);
/* 获得IP数据包头部的位置 */
ih = (ip_header *)(pkt_data
14); //以太网头部长度
/* 打印IP地址 */
printf("%d.%d.%d.%d -> %d.%d.%d.%d\n",
ih->saddr.byte1,
ih->saddr.byte2,
ih->saddr.byte3,
ih->saddr.byte4,
ih->daddr.byte1,
ih->daddr.byte2,
ih->daddr.byte3,
ih->daddr.byte4
);
add_link_ip(ih->saddr);
num_packet ;
}
int main()
{
int inum; //输入的网卡序号
int i = 0; //网卡序号
head = (ip_link*)malloc(sizeof(ip_link)); //初始化ip链表
head->next = NULL;
/*创建监听线程*/
CreateThread(
NULL, // default security attributes
0, // use default stack size
ThreadProc1, // thread function
NULL, // argument to thread function
0, // use default creation flags
NULL); // returns the thread identifier
/*获取网卡列表*/
get_adapter();
/*输出网卡列表,返回网卡数量*/
i = printf_adapter();
/*选择网卡*/
select_adapter(i);
/*设置网卡模式,获取网络地址和掩码地址*/
get_address();
/*设置过滤器*/
filter();
printf("\nlistening on %s...\n", d->description);
/* 释放设备列表 */
pcap_freealldevs(alldevs);
/* 开始捕捉 */
printf("\t时间\t 长度\t 源ip\t\t目的ip\n");
pcap_loop(adhandle, 0, packet_handler, NULL); //数字表示抓几回包停止,0表示无限制
//暂停函数
rewind(stdin); getchar();
return 0;
}