网络抓包与流量在线分析系统的设计与实现-基于libpcap在MacOS上实现 记录这愉快(DT)的一周

要求:

基于LINUX系统设计并实现一个网络流量的分析系统。该系统具有以下功能:(1)实时抓取网络数据。(2)网络协议分析与显示。(3)将网络数据包聚合成数据流,以源IP、目的IP、源端口、目的端口及协议等五元组的形式存储。(4)计算并显示固定时间间隔内网络连接(双向流)的统计量(如上行与下行的数据包数目,上行与下行的数据量大小等)。在这些统计数据的基础上分析不同网络应用的流量特征。

关键词:linux,libpcap,流量分析,网络抓包,协议分析,哈希链表,文件操作,C语言

功能

(1)能够实时抓取网络中的数据包。并实时显示在程序界面上。用户可自定义过滤条件以抓取所需要的数据包。
(2)分析各个网络协议格式,能够显示各协议字段的实际意义。例如,能够通过该程序反映TCP三次握手的实现过程。
(3)采用Hash链表的形式将网络数据以连接(双向流)的形式存储。
(4)计算并显示固定时间间隔内网络连接(双向流)的统计量(如上行与下行的数据包数目,上行与下行的数据量大小等)。例如,抓取一段时间(如30分钟)的网络流量,将该段时间以固定时长(如1分钟)为单位分成若干个时间片,计算网络连接在每一个时间片内的相关统计量。并在上述统计数据的基础上分析不同应用如WEB、DNS、在线视频等服务的流量特征。注意,可根据实际的流量分析需要自己定义相关的统计量。

实验环境

硬件设备:
(1)MAC笔记本
软件设备:
(2)MACOS(UNIX内核)
(3)网络数据包捕获函数包,Linux平台下为libpcap
(4)编程语言选用C,IDE使用Xcode
实验环境的配置:
Lipcap 下载地址为:http://www.tcpdump.org/release/libpcap-1.7.3.tar.gz
libpcap(Packet Capture library)即数据包捕获函数库。该库提供的C函数接口可用于需要捕获经过网络接口(只要经过该接口,目标地址不一定为本机)数据包的系统开发上。由 Berkeley大学Lawrence Berkeley National Laboratory研究院的Van Jacobson、Craig Leres和Steven McCanne编写。该函数库支持Linux、Solaris和*BSD系统平台。libpcap主要由两部份组成:网络分接头(Network Tap)和数据过滤器(Packet Filter)。
lipcap的安装过程:
1)tar zxvf libpcap-1.7.3.tar.gz 解压文件,并将其放入自定义的安装目录。
2)打开网址:flex.sourceforge.net/ 下载 flex-2.5.35.tar.gz (1.40MB) 软件包,通过 tar zxvf flex-2.5.35.tar.gz 解压文件,并将其放入上述自定义的安装目录中。
注:如果没有编译安装此文件,在编译安装libpcap时,可能会出现 “configure: error: Your operating system’s lex is insufficient to compile libpcap.”的错误提示。
3)打开网址:ftp.gnu.org/gnu/bison/ 下载 bison-2.4.1.tar.gz (1.9MB) 软件包,通过 tar zxvf bison-2.4.1.tar.gz 解压文件,并将其放入上述自定义的安装目录中。
如果没有编译安装此文件,在编译安装libpcap时,可能会出现 “configure: WARNING: don’t have both flex and bison; reverting to lex/yacc checking for capable lex… insufficient” 的错误提示。
4)打开网址:ftp.gnu.org/gnu/m4/ 下载 m4-1.4.13.tar.gz (1.2MB)软件包,通过 tar zxvf m4-1.4.13.tar.gz 解压文件,并将其放入上述自定义的安装目录中。
注:如果没有编译安装此文件,在编译安装bison-2.4.1时,就会出现 “configure: error: GNU M4 1.4 is required”的错误提示。
5)依次进入目录m4-1.4.13,bison-2.4.1,flex-2.5.35,libpcap-1.0.0 并执行以下命令:
./configure
make
make instal
(备注:使用linux或unix系统的需要进入终端用shell指令安装,Xcode中使用libpcap将其当作第三方函数库使用时,需要手动点击蓝色的工程文件,在右边的BuildPhase中LinkBinaryWithLibraries中手动添加libpcap的函数库,并且c中支持的一些基于win平台的函数和头文件在MACOS中有所差异,如#include <malloc.h>需改成#include <mm_malloc.h>,还有一些细节需要自己发现)

源代码

(分为头文件与主c文件两部分)
/main.h 包括网络抓包与流量分析/
#include <stdio.h>
#include <mm_malloc.h>
#include <sys/malloc.h>
#include <time.h>
#include <string.h>
#include <pcap.h>
#include “protocol.h”
#include<netinet/in.h>
#include<arpa/inet.h>
#include<errno.h>
#include<unistd.h>

typedef struct _argument
{
pcap_t *handle;
int timeLen;
}argument;

void *thread_clock(void argv)
{
pcap_t handle = ((argument)argv)->handle;
int timeLen = ((argument
)argv)->timeLen; // set time
sleep(timeLen);
pcap_breakloop(handle);
return 2;
}

void cb_getPacket(u_char *dumpfile, const struct pcap_pkthdr *pkthdr, const u_char *packet)
{
// ip_header seg_ip = (ip_header)(package + ETHER_LEN);
pcap_dump(dumpfile, pkthdr, packet);

static int id = 0;
printf(".  ");
if(++id % 30 == 0)
{printf("\n");
}

}

//timeval结构
typedef struct _shh_timeval{
int tv_sec; /* seconds 1900之后的秒数 /
int tv_usec; /
and microseconds */
}shh_timeval;

// pcap_next()方法执行后,pcap_pkthdr类型的指针指向抓包的信息
typedef struct _shh_pkthdr {
shh_timeval ts; /* time stamp 时间 /
bpf_u_int32 caplen; /
length of portion present 包的数据长度?? /
bpf_u_int32 len; /
length this packet (off wire) 包的实际长度 */
}shh_pkthdr;

typedef struct _net5set
{
u_int sip;
u_short sport;
u_int dip;
u_short dport;
u_char protocol;
}net5set;

typedef struct _net_link_node
{
net5set nln_5set;
int nln_upl_size;
int nln_downl_size;
int nln_upl_pkt;
int nln_downl_pkt;
u_char nln_status;
#define CLOSED 0x00
#define SYN_SENT 0x01 // client sent SYN
#define SYN_RECVD 0x02 // recieve SYN, and send SYN ACK
#define ESTABLISHED 0x03 // client get SYN & ACK, server get ACK

#define FIN_WAIT_1 0x04 // client send FIN
#define CLOSE_WAIT 0x05 // server recv FIN, and send ACK
#define FIN_WAIT_2 0x06 // client recv ACK
#define LAST_ACK 0x07 // server send FIN
#define TIME_WAIT 0x08 // client recv FIN
// CLOSED: client send ACK, server recv ACK
#define UNDEFINED 0xff
struct _net_link_node *next;
}net_link_node, *p_net_link;

typedef struct _net_link_header
{
int count_conn;
int count_upl_pkt;
int count_downl_pkt;
int count_upl;
int count_downl;
p_net_link link;
}net_link_header;

#define IPTOSBUFFERS 12
static char iptos(bpf_u_int32 in)
{
static char output[IPTOSBUFFERS][3
4+3+1];
static short which;
u_char *p;

p = (u_char *)&in;
which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1);
sprintf(output[which], "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
return output[which];

}

char *long2time(long ltime)
{
time_t t;
struct tm *p;
static char s[100];

t = ltime;
p = gmtime(&t);strftime(s, sizeof(s), "%Y-%m-%d %H:%M:%S", p);
return s;

}

// 需要三个链表,一个哈希链表,保存处于连接状态的包
// 另两个链表分别保存tcp和udp的流量
net_link_header *FLowLink_TCP;
net_link_header *FLowLink_UDP;

/* ========== hash table ============= */
#define HASH_TABLE_SIZE 0xffff
p_net_link HashTable[HASH_TABLE_SIZE];

void init_flowLink(net_link_header *head)
{
head->count_conn = 0;
head->count_upl_pkt = 0;
head->count_downl_pkt = 0;
head->count_upl = 0;
head->count_downl = 0;
head->link = NULL;
}

void add_to_flowLink(net_link_header *head, const net_link_node *theNode)
{
net_link_node *newNode = (net_link_node *)malloc(sizeof(net_link_node));
memcpy(newNode, theNode, sizeof(net_link_node));

head->count_conn ++;
head->count_upl_pkt     += newNode->nln_upl_pkt;
head->count_downl_pkt   += newNode->nln_downl_pkt;
head->count_upl         += newNode->nln_upl_size;
head->count_downl       += newNode->nln_downl_size;newNode->next = head->link;
head->link = newNode;

}

void clear_flowLink(net_link_header *head)
{
if( head->link == NULL ){ return;}

net_link_node *pTemp1 = NULL;
net_link_node *pTemp2 = NULL;pTemp1 = head->link;
pTemp2 = pTemp1->next;
while( pTemp2 != NULL )
{free(pTemp1);pTemp1 = pTemp2;pTemp2 = pTemp1->next;
}
free(pTemp1);head->link = NULL;

}

void parse_flowLink_TCP(FILE *fOutput)
{
fprintf(fOutput, “TCP连接个数:\t%d\n”, FLowLink_TCP->count_conn);
fprintf(fOutput, “TCP数据包个数:\t%d\n”, FLowLink_TCP->count_upl_pkt + FLowLink_TCP->count_upl_pkt);
fprintf(fOutput, “TCP数据总流量:\t%d bytes\n”, FLowLink_TCP->count_upl + FLowLink_TCP->count_downl);
fprintf(fOutput, “TCP数据上传量:\t%d bytes\n”, FLowLink_TCP->count_upl);
fprintf(fOutput, “TCP数据下载量:\t%d bytes\n”, FLowLink_TCP->count_downl);
fprintf(fOutput, “-----------------------\n”);

net_link_node *pTemp = NULL;
pTemp = FLowLink_TCP->link;
while( pTemp != NULL )
{fprintf(fOutput, "%s\t%u\t", iptos(pTemp->nln_5set.sip), pTemp->nln_5set.sport);fprintf(fOutput, "==>\t%s\t%u\t", iptos(pTemp->nln_5set.dip), pTemp->nln_5set.dport);fprintf(fOutput, "上传包数量:%d\t", pTemp->nln_upl_pkt);fprintf(fOutput, "下载包数量:%d\t", pTemp->nln_downl_pkt);fprintf(fOutput, "upload:%d bytes\t", pTemp->nln_upl_size);fprintf(fOutput, "download:%d bytes\t", pTemp->nln_downl_size);fprintf(fOutput, "\n");pTemp = pTemp->next;
}clear_flowLink(FLowLink_TCP);

}

void parse_flowLink_UDP(FILE *fOutput)
{
fprintf(fOutput, “UDP数据包个数:\t%d\n”, FLowLink_UDP->count_upl_pkt + FLowLink_UDP->count_upl_pkt);
fprintf(fOutput, “UDP数据流量:\t%d bytes\n”, FLowLink_UDP->count_upl + FLowLink_UDP->count_downl);
clear_flowLink(FLowLink_UDP);
}

u_short get_ushort_net(u_short virtu)
{
return (u_short)(virtu >> 8 | virtu << 8);
}

u_short get_hash(const net5set *theSet)
{
u_int srcIP = theSet->sip;
u_int desIP = theSet->dip;
u_int port = (u_int)(theSet->sport * theSet->dport);
u_int res = (srcIPdesIP)port;
u_short hash= (u_short)((res & 0x00ff)^(res >> 16));
return hash;
}

void add_to_hashTable(u_short hash, const net_link_node *theNode, u_char flags)
{
net_link_node *HashNode = (net_link_node *)malloc(sizeof(net_link_node));
memcpy(HashNode, theNode, sizeof(net_link_node));

if(HashTable[hash] == NULL)
{HashTable[hash] = HashNode;return;
}
net_link_node *pTemp = HashTable[hash];
net_link_node *pBack = NULL;
int isSame_up = 0;
int isSame_down = 0;
while(pTemp != NULL)
{isSame_up = (pTemp->nln_5set.sip == HashNode->nln_5set.sip)&& (pTemp->nln_5set.dip == HashNode->nln_5set.dip)&& (pTemp->nln_5set.sport == HashNode->nln_5set.sport)&& (pTemp->nln_5set.dport == HashNode->nln_5set.dport);isSame_down = (pTemp->nln_5set.dip == HashNode->nln_5set.sip)&& (pTemp->nln_5set.sip == HashNode->nln_5set.dip)&& (pTemp->nln_5set.dport == HashNode->nln_5set.sport)&& (pTemp->nln_5set.sport == HashNode->nln_5set.dport);if( isSame_up ){pTemp->nln_upl_size += HashNode->nln_upl_size;pTemp->nln_upl_pkt ++;if(pTemp->nln_status == ESTABLISHED && (flags & TH_FIN) ){pTemp->nln_status = FIN_WAIT_1;}else if (pTemp->nln_status == TIME_WAIT && (flags & TH_ACK)){pTemp->nln_status = CLOSED;if(pBack == NULL){HashTable[hash] = NULL;}else{pBack->next = pTemp->next;}add_to_flowLink(FLowLink_TCP, pTemp);free(pTemp);}else if(pTemp->nln_status == CLOSE_WAIT && (flags & TH_FIN)){pTemp->nln_status = LAST_ACK;}free(HashNode);break;}else if( isSame_down ){pTemp->nln_downl_size += HashNode->nln_upl_size;pTemp->nln_downl_pkt ++;if(pTemp->nln_status == ESTABLISHED && (flags & TH_FIN)){pTemp->nln_status = CLOSE_WAIT;}else if(pTemp->nln_status == LAST_ACK && (flags & TH_ACK)){pTemp->nln_status = CLOSED;if(pBack == NULL){HashTable[hash] = NULL;}else{pBack->next = pTemp->next;}add_to_flowLink(FLowLink_TCP, pTemp);free(pTemp);}else if(pTemp->nln_status == FIN_WAIT_1 && (flags & TH_ACK)){pTemp->nln_status = FIN_WAIT_2;}else if(pTemp->nln_status == FIN_WAIT_2 && (flags & TH_FIN)){pTemp->nln_status = TIME_WAIT;}free(HashNode);break;}pBack = pTemp;pTemp = pTemp->next;
}
if(pTemp == NULL)
{pBack->next = HashNode;
}

}

void clear_hashTable()
{
int i = 0;
net_link_node *pTemp1 = NULL;
net_link_node *pTemp2 = NULL;
for(i = 0; i < HASH_TABLE_SIZE; i++)
{
if(HashTable[i] == NULL){ continue;}

    pTemp1 = HashTable[i];while(pTemp1 != NULL){pTemp2 = pTemp1->next;add_to_flowLink(FLowLink_TCP, pTemp1);free(pTemp1);pTemp1 = pTemp2;}HashTable[i] = NULL;
}

}

/*
在以太网中,规定最小的数据包为64个字节,如果数据包不足64字节,则会由网卡填充。
*/

int main(int argc, char const *argv[])
{
char *dev, errbuf[PCAP_ERRBUF_SIZE];
pcap_t *dev_handle;
bpf_u_int32 net, mask;
char packet_filter[] = “ip”;
struct bpf_program fcode;

dev = pcap_lookupdev(errbuf);
if(dev == NULL){printf("No Device:%s\n", errbuf);return 0;
} // */
/*char *wlan_dev = "wlan0";dev = wlan_dev; // */
printf("开始抓取数据,设备:%s\n", dev);dev_handle = pcap_open_live(dev, BUFSIZ, 1, 0, errbuf);
if(dev_handle == NULL){printf("pcap_open_live:%s\n", errbuf);return 0;
}
//args->handle = dev_handle;pcap_lookupnet(dev, &net, &mask, errbuf);//compile the filter
if (pcap_compile(dev_handle, &fcode, packet_filter, 1, mask) <0 )
{printf("\nUnable to compile the packet filter. Check the syntax.\n");return 0;
}
//set the filter
if (pcap_setfilter(dev_handle, &fcode) < 0)
{printf("\nError setting the filter.\n");return 0;
}// open file to save pcap
pcap_dumper_t *dumpfile;
dumpfile = pcap_dump_open(dev_handle, "traffic.data");
if(dumpfile == NULL){printf("\nError opening output file\n");return 0;
}// build a new thread
pthread_t ptClock;
argument args;
args.handle = dev_handle;
int argv_time = 30;
args.timeLen = (argv_time > 0) ? argv_time : 60;
printf("抓取时长:%d s\n", argv_time);
if(pthread_create(&ptClock, NULL, thread_clock, &args))
{printf("pthread_create(): Error!\n");return -1;
}
pcap_loop(dev_handle, -1, cb_getPacket, (u_char*)dumpfile);// close all handle
pcap_dump_close(dumpfile);
pcap_close(dev_handle);
printf("\nDone!\n");
//以上为抓包char *file_output = "/Users/ganyu/Desktop/result.data";
FILE *fOutput = fopen(file_output, "w");
fclose(fOutput);        // clear file
fOutput = fopen(file_output, "a+");char *filename = "traffic.data";
fprintf(fOutput, "数据文件:%s\n", filename);printf("载入文件...\n");
FILE *fp = fopen(filename, "r");shh_pkthdr      *pkthdr     = (shh_pkthdr *)malloc(sizeof(shh_pkthdr));
ether_header    *segEther   = (ether_header*)malloc(sizeof(ether_header));
ip_header       *segIP      = (ip_header*)malloc(sizeof(ip_header));
tcp_header      *segTCP     = (tcp_header*)malloc(sizeof(tcp_header));
udp_header      *segUDP     = (udp_header*)malloc(sizeof(udp_header));
net5set         *Cur5Set    = (net5set *)malloc(sizeof(net5set));
net_link_node   *LinkNode   = (net_link_node *)malloc(sizeof(net_link_node));FLowLink_TCP = (net_link_header *)malloc(sizeof(net_link_header));
init_flowLink(FLowLink_TCP);
FLowLink_UDP = (net_link_header *)malloc(sizeof(net_link_header));
init_flowLink(FLowLink_UDP);long    fileLen     = 0;
int     pktLen      = 0;    // pktLen = Ether + IP
int     trailerLen  = 0;
u_short ipLen_real  = 0;
u_short ipLen_total = 0;
u_short tcpLen_real = 0;
u_short dataLen     = 0;// get length of file
fseek(fp, 0, SEEK_END);
fileLen = ftell(fp);
fseek(fp, PCAP_HEADER_LEN, SEEK_SET);
// 移动文件位置指针。
// If successful, the function returns zero.
// Otherwise, it returns non-zero value.
// SEEK_SET:文件开头;SEEK_CUR:当前位置;SEEK_END:文件结尾fread(pkthdr, PACKET_HEADER_LEN, 1, fp);
fseek(fp, - PACKET_HEADER_LEN, SEEK_CUR);
int tstamp_start    = pkthdr->ts.tv_sec;
int tstamp_offset   = tstamp_start;
int tstamp_now      = tstamp_start;
int cycle           = 5;
cycle = (cycle > 0) ? cycle : 10;
fprintf(fOutput, "分析周期:%d s\n", cycle);//  int i = 0;
while( ftell(fp) > 0 &&  ftell(fp) < fileLen )
{fread(pkthdr, PACKET_HEADER_LEN, 1, fp);pktLen = pkthdr->caplen;tstamp_now = pkthdr->ts.tv_sec;if(tstamp_now - tstamp_offset >= cycle){fprintf(fOutput, "\n\n>>>>> 时间段:%s", long2time(tstamp_offset));fprintf(fOutput, " --> %s\n", long2time(tstamp_offset + cycle));fprintf(fOutput, "----------------------\n");clear_hashTable();parse_flowLink_UDP(fOutput);init_flowLink(FLowLink_UDP);fprintf(fOutput, "----------------------\n");parse_flowLink_TCP(fOutput);init_flowLink(FLowLink_TCP);tstamp_offset = tstamp_now;}//printf("%d\t", pktLen);//printf("\n%d\t", ++i);fread(segEther, ETHER_LEN, 1, fp);if( get_ushort_net(segEther->type) != ETHER_TYPE_IP ){//printf("------\t");fseek(fp, pktLen - ETHER_LEN, SEEK_CUR);continue;}fread(segIP, IP_LEN_MIN, 1, fp);ipLen_real = (segIP->ver_ihl & 0x0f)*4;ipLen_total = get_ushort_net(segIP->tlen);trailerLen = pktLen - ETHER_LEN - ipLen_total;fseek(fp, ipLen_real - IP_LEN_MIN, SEEK_CUR);if( segIP->proto != IP_TCP && segIP->proto != IP_UDP ){//printf("------\t");fseek(fp, ipLen_total - ipLen_real + trailerLen, SEEK_CUR);continue;}Cur5Set->sip = segIP->saddr;Cur5Set->dip = segIP->daddr;Cur5Set->protocol = segIP->proto;//printf("src:%s\t", iptos(Cur5Set->sip));//printf("des:%s\t", iptos(Cur5Set->dip));if(segIP->proto == IP_TCP){//printf("TCP\t");fread(segTCP, TCP_LEN_MIN, 1, fp);tcpLen_real = (((segTCP->th_len)>>4) & 0x0f) * 4;dataLen = ipLen_total - ipLen_real - tcpLen_real;Cur5Set->sport = get_ushort_net(segTCP->th_sport);Cur5Set->dport = get_ushort_net(segTCP->th_dport);fseek(fp, (tcpLen_real - TCP_LEN_MIN) + dataLen + trailerLen, SEEK_CUR);}else if(segIP->proto == IP_UDP){//printf("UDP\t");fread(segUDP, UDP_LEN, 1, fp);dataLen = ipLen_total - ipLen_real - UDP_LEN;Cur5Set->sport = get_ushort_net(segUDP->uh_sport);Cur5Set->dport = get_ushort_net(segUDP->uh_dport);fseek(fp, dataLen + trailerLen, SEEK_CUR);}LinkNode->nln_5set      = *Cur5Set;LinkNode->nln_upl_size  = dataLen;LinkNode->nln_downl_size= 0;LinkNode->nln_upl_pkt   = 1;LinkNode->nln_downl_pkt = 0;LinkNode->nln_status    = ESTABLISHED;LinkNode->next          = NULL;if(segIP->proto == IP_TCP){add_to_hashTable(get_hash(Cur5Set), LinkNode, segTCP->th_flags);}else{add_to_flowLink(FLowLink_UDP, LinkNode);}
}
fprintf(fOutput, "\nover\n");free(pkthdr);
free(segEther);
free(segIP);
free(segTCP);
free(segUDP);
free(Cur5Set);
free(LinkNode);
free(FLowLink_TCP);
free(FLowLink_UDP);
fclose(fOutput);printf("Done!\n");
return 0;

}

/** protocol.h
structs of ethernet, ip, tcp, udp
*/

#define PCAP_HEADER_LEN 24
#define PACKET_HEADER_LEN 16

/* ============= Ethernet ============ */
#define ETHER_LEN 14
#define ETHER_ADDR_LEN 6
#define ETHER_TYPE_LEN 2

#define ETHER_DEST_OFFSET (0 * ETHER_ADDR_LEN)
#define ETHER_SRC_OFFSET (1 * ETHER_ADDR_LEN)
#define ETHER_TYPE_OFFSET (2 * ETHER_ADDR_LEN)

typedef struct _ether_header{
u_char host_dest[ETHER_ADDR_LEN];
u_char host_src[ETHER_ADDR_LEN];
u_short type;
#define ETHER_TYPE_MIN 0x0600
#define ETHER_TYPE_IP 0x0800
#define ETHER_TYPE_ARP 0x0806
#define ETHER_TYPE_8021Q 0x8100
#define ETHER_TYPE_BRCM 0x886c
#define ETHER_TYPE_802_1X 0x888e
#define ETHER_TYPE_802_1X_PREAUTH 0x88c7
}ether_header;

/============== IP ================/
#define IP_LEN_MIN 20

/* IPv4 header */
typedef struct _ip_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 ident; // Identification
u_short flags_fo; // Flags (3 bits) + Fragment offset (13 bits)
u_char ttl; // Time to live
u_char proto; // Protocol
#define IP_ICMP 1
#define IP_IGMP 2
#define IP_TCP 6
#define IP_UDP 17
#define IP_IGRP 88
#define IP_OSPF 89
u_short crc; // Header checksum
u_int saddr; // Source address
u_int daddr; // Destination address
}ip_header;

/=============== TCP ================/
#define TCP_LEN_MIN 20
typedef struct _tcp_header
{
u_short th_sport; // source port
u_short th_dport; // destination port
u_int th_seq; // sequence number field
u_int th_ack; // acknowledgement number field
u_char th_len:4; // header length
u_char th_x2:4; // unused
u_char th_flags;
#define TH_FIN 0x01
#define TH_SYN 0x02
#define TH_RST 0x04
#define TH_PSH 0x08
#define TH_ACK 0x10
#define TH_URG 0x20
u_short th_win; /* window /
u_short th_sum; /
checksum /
u_short th_urp; /
urgent pointer /
}tcp_header; //
/

/================ UDP ==================/
#define UDP_LEN 8
typedef struct _udp_header{
u_short uh_sport; // Source port
u_short uh_dport; // Destination port
u_short uh_len; // Datagram length
u_short uh_sum; // Checksum
}udp_header;

结果截图

程序会先抓包,存在traffic.data文件中,也可以自定义,建议不要动,容易出错,然后对包的内容进行分析,输出结果到result.data中,这个建议自定义文件目录,方便查看。抓取时长和分析周期可以自定义。


网络抓包与流量在线分析系统的设计与实现-基于libpcap在MacOS上实现 记录这愉快(DT)的一周相关推荐

  1. 网络流量在线分析系统的设计与实现+winpcap+vscode+mingw

    21.2.17更新:替换未渲染的plantuml流程图 前言 文章源地址:https://blog.csdn.net/pi31415926535x/article/details/107230805 ...

  2. 局域网抓包分析工具_[源码和文档分享]基于Libpcap实现的局域网嗅探抓包发包解析工具...

    第一章 需求分析 1.1 设计目的 1.1.1 基本要求 完成一个基于Libpcap的网络数据包解析软件,具有易用.美观的界面. 1.1.2 具体要求 能够解析本地或局域网的数据包,例如TCP包,UD ...

  3. Microsoft Message Analyzer (微软消息分析器,“网络抓包工具 - Network Monitor”的替代品)官方正式版现已发布...

    来自官方日志的喜悦 被誉为全新开始的消息分析器时代,由MMA为您开启,博客原文写的很激动,大家可以点击这里浏览:http://blogs.technet.com/b/messageanalyzer/a ...

  4. 跨平台网络抓包工具-Microsoft Message Analyzer

    Microsoft Message Analyzer (MMA 2013)是微软最受欢迎的Netmon的最新版本. 在Netmon网络跟踪和排除故障功能的基础上提供了更强大的跨平台网络分析追踪能力.园 ...

  5. esxi vsphere的端口_硬干货!一张图弄清楚在ESXi下如何进行网络抓包

    对于网络问题,抓包一直是一个比较简单方便的"大招".由于在esxi环境下可以在不同的层面下抓包,因此在什么地方抓包,怎么抓包一直让我觉得很复杂,于是每次操作之前我都要再检查一次手册 ...

  6. iOS系统网络抓包方法

    转自:http://www.cnblogs.com/ydhliphonedev/archive/2011/10/27/2226935.html 在进行iOS开发过程中,经常会遇到各种各样的网络访问问题 ...

  7. Linux系统无线网络抓包程序(分析手机WIFI MAC地址)

    前面讲述了使用tcpdump和wireshark抓WIFI包,但这只是使用工具的层面,再深一层则是自己写代码实现这个功能.本文在前面文章<Linux系统有线网络抓包程序>的基础上添加实现无 ...

  8. Linux系统有线网络抓包程序

    今天心血来潮,玩一玩linux抓包.思路如下: 1.使用raw socket接收网络数据: 2.先解析以太帧头,得到是IP还是ARP包: 3.再解析IP头,知道是UDP还是TCP: 4.再解析UDP. ...

  9. (转载)网络抓包原理及常用抓包工具

    感谢和转载于: https://blog.csdn.net/l61052319940708/article/details/80624900 本文以App作为例子,实际应用不限于App范围. 前言:本 ...

最新文章

  1. 2019年上半年收集到的人工智能开源框架介绍文章
  2. 查看tcp各个连接状态的数量
  3. pycharm配置git版本管理
  4. 微信小程序中阻止事件冒泡
  5. 华为如何拍火烧云_华为手机拍照功能介绍-设置通用功能
  6. java中什么是类型_什么是Java中基本数据类型?
  7. python 基础 -- python 模块
  8. hadoop27---netty中handler的执行顺序
  9. JavaScript基础学习(七)—BOM
  10. NLP中的词向量总结与实战:从one-hot到bert
  11. 如何在苹果Mac上右键点击?
  12. 关于日期单双日,星期判断
  13. 连通性1 求无向图的low值
  14. 10的n次方换算关系 10^N 计算机存储单位的换算关系
  15. #10064. 「一本通 3.1 例 1」黑暗城堡
  16. Python 通过 Tushare Pro 获取财经数据接口
  17. C语言 三个数字比较大小
  18. s5k4ba摄像头驱动分析
  19. 怎么查找计算机里的金蝶账套,金蝶帐套数据如何拷贝到另一台电脑上
  20. martin fowler_Martin Kleppmann的大型访谈:“弄清楚分布式数据系统的未来”

热门文章

  1. linux如何彻底删除mysql_CentOS下如何完全干净卸载MySQL
  2. 大数据Hadoop:杀鸡用的宰牛刀
  3. 转载:flash加密解密的相关知识
  4. 去南宁市图书馆泡了一晚上~编写文件粉碎机之惑
  5. 【技术综述】人脸关键点检测的数据集与核心算法
  6. flash的各种特效实现
  7. spring boot网上商品定制系统 毕业设计-附源码180915
  8. 贵州新华计算机学校图片,贵州新华电脑学院:第十届“新华杯”校园篮球联赛总决赛图片展...
  9. K-均值聚类算法的原理与实现
  10. Java为啥比PHP快?