#include <stdio.h>
#include <stdlib.h>
#include <pcap.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#define MAX_TCP_SESSIONS 10000
#define MAX_UDP_SESSIONS 10000
// 存储会话信息
struct Session {
struct in_addr src_ip;
struct in_addr dst_ip;
u_int16_t src_port;
u_int16_t dst_port;
int tx_packets; // 上行包数
int rx_packets; // 下行包数
};
struct Session tcp_sessions[MAX_TCP_SESSIONS];
struct Session udp_sessions[MAX_UDP_SESSIONS];
int tcp_count = 0;
int udp_count = 0;
void process_packet(u_char *user, const struct pcap_pkthdr *pkthdr, const u_char *packet) {
struct ip *ip_header = (struct ip *)(packet + 14); // 假设以太网帧头部长度为14字节
// 判断协议类型
if (ip_header->ip_p == IPPROTO_TCP) {
struct tcphdr *tcp_header = (struct tcphdr *)(packet + 14 + (ip_header->ip_hl << 2));
// 获取源和目的IP地址
struct in_addr src_ip = ip_header->ip_src;
struct in_addr dst_ip = ip_header->ip_dst;
// 获取源和目的端口号
u_int16_t src_port = ntohs(tcp_header->source);
u_int16_t dst_port = ntohs(tcp_header->dest);
// 查找或创建会话
int i;
for (i = 0; i < tcp_count; i++) {
if (tcp_sessions[i].src_ip.s_addr == src_ip.s_addr &&
tcp_sessions[i].dst_ip.s_addr == dst_ip.s_addr &&
tcp_sessions[i].src_port == src_port &&
tcp_sessions[i].dst_port == dst_port) {
break;
}
}
// 如果找不到对应的会话,则创建新会话
if (i == tcp_count) {
tcp_sessions[tcp_count].src_ip = src_ip;
tcp_sessions[tcp_count].dst_ip = dst_ip;
tcp_sessions[tcp_count].src_port = src_port;
tcp_sessions[tcp_count].dst_port = dst_port;
tcp_sessions[tcp_count].tx_packets = 0;
tcp_sessions[tcp_count].rx_packets = 0;
tcp_count++;
}
// 根据方向增加包数
if (src_ip.s_addr == tcp_sessions[i].src_ip.s_addr &&
dst_ip.s_addr == tcp_sessions[i].dst_ip.s_addr &&
src_port == tcp_sessions[i].src_port &&
dst_port == tcp_sessions[i].dst_port)
{
tcp_sessions[i].tx_packets++;
}
else if(dst_ip.s_addr == tcp_sessions[i].src_ip.s_addr &&
src_ip.s_addr == tcp_sessions[i].dst_ip.s_addr &&
dst_port == tcp_sessions[i].src_port &&
src_port == tcp_sessions[i].dst_port)
{
tcp_sessions[i].rx_packets++;
}
} else if (ip_header->ip_p == IPPROTO_UDP) {
struct udphdr *udp_header = (struct udphdr *)(packet + 14 + (ip_header->ip_hl << 2));
// 获取源和目的IP地址
struct in_addr src_ip = ip_header->ip_src;
struct in_addr dst_ip = ip_header->ip_dst;
// 获取源和目的端口号
u_int16_t src_port = ntohs(udp_header->source);
u_int16_t dst_port = ntohs(udp_header->dest);
// 查找或创建会话
int i;
for (i = 0; i < udp_count; i++) {
if (udp_sessions[i].src_ip.s_addr == src_ip.s_addr &&
udp_sessions[i].dst_ip.s_addr == dst_ip.s_addr &&
udp_sessions[i].src_port == src_port &&
udp_sessions[i].dst_port == dst_port)
{
break;
}
}
// 如果找不到对应的会话,则创建新会话
if (i == udp_count) {
udp_sessions[udp_count].src_ip = src_ip;
udp_sessions[udp_count].dst_ip = dst_ip;
udp_sessions[udp_count].src_port = src_port;
udp_sessions[udp_count].dst_port = dst_port;
udp_sessions[udp_count].tx_packets = 0;
udp_sessions[udp_count].rx_packets = 0;
udp_count++;
}
// 根据方向增加包数
if (src_ip.s_addr == udp_sessions[i].src_ip.s_addr &&
dst_ip.s_addr == udp_sessions[i].dst_ip.s_addr &&
src_port == udp_sessions[i].src_port &&
dst_port == udp_sessions[i].dst_port)
{
udp_sessions[i].tx_packets++;
}
else if(src_ip.s_addr == udp_sessions[i].src_ip.s_addr &&
dst_ip.s_addr == udp_sessions[i].dst_ip.s_addr &&
src_port == udp_sessions[i].src_port &&
dst_port == udp_sessions[i].dst_port)
{
udp_sessions[i].rx_packets++;
}
}
}
int main(int argc, char *argv[]) {
int i = 0;
char src_ip_str[INET_ADDRSTRLEN];
char dst_ip_str[INET_ADDRSTRLEN];
char errbuf[PCAP_ERRBUF_SIZE];
if (argc != 2) {
fprintf(stderr, "Usage: %s <pcap_file>\n", argv[0]);
return 1;
}
pcap_t *handle = pcap_open_offline(argv[1], errbuf);
if (handle == NULL) {
fprintf(stderr, "Error opening pcap file: %s\n", errbuf);
return 1;
}
pcap_loop(handle, 0, process_packet, NULL);
printf("TCP Sessions:%d\n",tcp_count);
for (i = 0; i < tcp_count; i++) {
inet_ntop(AF_INET, &(tcp_sessions[i].src_ip), src_ip_str, INET_ADDRSTRLEN);
inet_ntop(AF_INET, &(tcp_sessions[i].dst_ip), dst_ip_str, INET_ADDRSTRLEN);
//printf("Session %d: %s:%d -> %s:%d\n", i + 1, src_ip_str, ntohs(tcp_sessions[i].src_port), dst_ip_str, ntohs(tcp_sessions[i].dst_port));
//printf(" Tx Packets: %d\n", tcp_sessions[i].tx_packets);
//printf(" Rx Packets: %d\n", tcp_sessions[i].rx_packets);
}
printf("\nUDP Sessions:%d\n",udp_count);
for(i = 0; i < udp_count; i++) {
inet_ntop(AF_INET, &(udp_sessions[i].src_ip), src_ip_str, INET_ADDRSTRLEN);
inet_ntop(AF_INET, &(udp_sessions[i].dst_ip), dst_ip_str, INET_ADDRSTRLEN);
// printf("Session %d: %s:%d -> %s:%d\n", i + 1, src_ip_str, ntohs(udp_sessions[i].src_port), dst_ip_str, ntohs(udp_sessions[i].dst_port));
// printf(" Tx Packets: %d\n", udp_sessions[i].tx_packets);
// printf(" Rx Packets: %d\n", udp_sessions[i].rx_packets);
}
pcap_close(handle);
return 0;
}