可以从Windows Sockets 2开始,

虽然微软提供了官方工具, Microsoft Network Monitor 3.4, 不过我们如果能够通过相关的代码和api的调用来深入研究的话,那就大大提升了我们的学习水平。

主要用到socket, bind 和 recvfrom函数。

代码样本:

#include "stdio.h"
#include "winsock2.h" #pragma comment(lib,"ws2_32.lib") //For winsock
#pragma warning(disable:4996) #define SIO_RCVALL _WSAIOW(IOC_VENDOR,1) //this removes the need of mstcpip.h void StartSniffing(SOCKET Sock); //This will sniff here and there void ProcessPacket(char*, int); //This will decide how to digest
void PrintIpHeader(char*);
void PrintUdpPacket(char*, int);
void PrintTcpPacket(char*, int);
void PrintData(char*, int); typedef struct ip_hdr
{
unsigned char ip_header_len : 4; // 4-bit header length (in 32-bit words) normally=5 (Means 20 Bytes may be 24 also)
unsigned char ip_version : 4; // 4-bit IPv4 version
unsigned char ip_tos; // IP type of service
unsigned short ip_total_length; // Total length
unsigned short ip_id; // Unique identifier unsigned char ip_frag_offset : 5; // Fragment offset field unsigned char ip_more_fragment : 1;
unsigned char ip_dont_fragment : 1;
unsigned char ip_reserved_zero : 1; unsigned char ip_frag_offset1; //fragment offset unsigned char ip_ttl; // Time to live
unsigned char ip_protocol; // Protocol(TCP,UDP etc)
unsigned short ip_checksum; // IP checksum
unsigned int ip_srcaddr; // Source address
unsigned int ip_destaddr; // Source address
} IPV4_HDR; typedef struct udp_hdr
{
unsigned short source_port; // Source port no.
unsigned short dest_port; // Dest. port no.
unsigned short udp_length; // Udp packet length
unsigned short udp_checksum; // Udp checksum (optional)
} UDP_HDR; // TCP header
typedef struct tcp_header
{
unsigned short source_port; // source port
unsigned short dest_port; // destination port
unsigned int sequence; // sequence number - 32 bits
unsigned int acknowledge; // acknowledgement number - 32 bits unsigned char ns : 1; //Nonce Sum Flag Added in RFC 3540.
unsigned char reserved_part1 : 3; //according to rfc
unsigned char data_offset : 4; /*The number of 32-bit words in the TCP header.
This indicates where the data begins.
The length of the TCP header is always a multiple
of 32 bits.*/ unsigned char fin : 1; //Finish Flag
unsigned char syn : 1; //Synchronise Flag
unsigned char rst : 1; //Reset Flag
unsigned char psh : 1; //Push Flag
unsigned char ack : 1; //Acknowledgement Flag
unsigned char urg : 1; //Urgent Flag unsigned char ecn : 1; //ECN-Echo Flag
unsigned char cwr : 1; //Congestion Window Reduced Flag //////////////////////////////// unsigned short window; // window
unsigned short checksum; // checksum
unsigned short urgent_pointer; // urgent pointer
} TCP_HDR; FILE* logfile;
int tcp = 0, udp = 0, icmp = 0, others = 0, igmp = 0, total = 0, i, j;
struct sockaddr_in source, dest;
char hex[2]; //Its free!
IPV4_HDR* iphdr;
TCP_HDR* tcpheader;
UDP_HDR* udpheader; int main()
{
SOCKET sniffer;
struct in_addr addr;
int in; char hostname[100];
struct hostent* local;
WSADATA wsa; logfile = fopen("log.txt", "w");
if (logfile == NULL)
{
printf("Unable to create file.");
} //Initialise Winsock
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
printf("WSAStartup() failed.\n");
return 1;
}
printf("Initialised"); //Create a RAW Socket
printf("\nCreating RAW Socket...");
sniffer = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
if (sniffer == INVALID_SOCKET)
{
printf("Failed to create raw socket.\n");
return 1;
}
printf("Created."); //Retrive the local hostname
if (gethostname(hostname, sizeof(hostname)) == SOCKET_ERROR)
{
printf("Error : %d", WSAGetLastError());
return 1;
}
printf("\nHost name : %s \n", hostname); //Retrive the available IPs of the local host
local = gethostbyname(hostname);
printf("\nAvailable Network Interfaces : \n");
if (local == NULL)
{
printf("Error : %d.\n", WSAGetLastError());
return 1;
} for (i = 0; local->h_addr_list[i] != 0; ++i)
{
memcpy(&addr, local->h_addr_list[i], sizeof(struct in_addr));
printf("Interface Number : %d Address : %s\n", i, inet_ntoa(addr));
} printf("Enter the interface number you would like to sniff : ");
scanf("%d", &in); memset(&dest, 0, sizeof(dest));
memcpy(&dest.sin_addr.s_addr, local->h_addr_list[in], sizeof(dest.sin_addr.s_addr));
dest.sin_family = AF_INET;
dest.sin_port = 0; printf("\nBinding socket to local system and port 0 ...");
if (bind(sniffer, (struct sockaddr*) & dest, sizeof(dest)) == SOCKET_ERROR)
{
printf("bind(%s) failed.\n", inet_ntoa(addr));
return 1;
}
printf("Binding successful"); //Enable this socket with the power to sniff : SIO_RCVALL is the key Receive ALL ;) j = 1;
printf("\nSetting socket to sniff...");
if (WSAIoctl(sniffer, SIO_RCVALL, &j, sizeof(j), 0, 0, (LPDWORD)&in, 0, 0) == SOCKET_ERROR)
{
printf("WSAIoctl() failed.\n");
return 1;
}
printf("Socket set."); //Begin
printf("\nStarted Sniffing\n");
printf("Packet Capture Statistics...\n");
StartSniffing(sniffer); //Happy Sniffing //End
closesocket(sniffer);
WSACleanup(); return 0;
} void StartSniffing(SOCKET sniffer)
{
char* Buffer = (char*)malloc(65536); //Its Big!
int mangobyte; if (Buffer == NULL)
{
printf("malloc() failed.\n");
return;
} do
{
mangobyte = recvfrom(sniffer, Buffer, 65536, 0, 0, 0); //Eat as much as u can if (mangobyte > 0)
{
ProcessPacket(Buffer, mangobyte);
}
else
{
printf("recvfrom() failed.\n");
}
} while (mangobyte > 0); free(Buffer);
} void ProcessPacket(char* Buffer, int Size)
{
iphdr = (IPV4_HDR*)Buffer;
++total; switch (iphdr->ip_protocol) //Check the Protocol and do accordingly...
{ case 6: //TCP Protocol
++tcp;
PrintTcpPacket(Buffer, Size);
break; case 17: //UDP Protocol
++udp;
PrintUdpPacket(Buffer, Size);
break; default: //Some Other Protocol like ARP etc.
++others;
break;
}
printf("TCP : %d UDP : %d ICMP : %d IGMP : %d Others : %d Total : %d\r", tcp, udp, icmp, igmp, others, total);
} void PrintIpHeader(char* Buffer)
{
unsigned short iphdrlen; iphdr = (IPV4_HDR*)Buffer;
iphdrlen = iphdr->ip_header_len * 4; memset(&source, 0, sizeof(source));
source.sin_addr.s_addr = iphdr->ip_srcaddr; memset(&dest, 0, sizeof(dest));
dest.sin_addr.s_addr = iphdr->ip_destaddr; fprintf(logfile, "\n");
fprintf(logfile, "IP Header\n");
fprintf(logfile, " |-IP Version : %d\n", (unsigned int)iphdr->ip_version);
fprintf(logfile, " |-IP Header Length : %d DWORDS or %d Bytes\n", (unsigned int)iphdr->ip_header_len, ((unsigned int)(iphdr->ip_header_len)) * 4);
fprintf(logfile, " |-Type Of Service : %d\n", (unsigned int)iphdr->ip_tos);
fprintf(logfile, " |-IP Total Length : %d Bytes(Size of Packet)\n", ntohs(iphdr->ip_total_length));
fprintf(logfile, " |-Identification : %d\n", ntohs(iphdr->ip_id));
fprintf(logfile, " |-Reserved ZERO Field : %d\n", (unsigned int)iphdr->ip_reserved_zero);
fprintf(logfile, " |-Dont Fragment Field : %d\n", (unsigned int)iphdr->ip_dont_fragment);
fprintf(logfile, " |-More Fragment Field : %d\n", (unsigned int)iphdr->ip_more_fragment);
fprintf(logfile, " |-TTL : %d\n", (unsigned int)iphdr->ip_ttl);
fprintf(logfile, " |-Protocol : %d\n", (unsigned int)iphdr->ip_protocol);
fprintf(logfile, " |-Checksum : %d\n", ntohs(iphdr->ip_checksum));
fprintf(logfile, " |-Source IP : %s\n", inet_ntoa(source.sin_addr));
fprintf(logfile, " |-Destination IP : %s\n", inet_ntoa(dest.sin_addr));
} void PrintTcpPacket(char* Buffer, int Size)
{
unsigned short iphdrlen; iphdr = (IPV4_HDR*)Buffer;
iphdrlen = iphdr->ip_header_len * 4; tcpheader = (TCP_HDR*)(Buffer + iphdrlen); fprintf(logfile, "\n\n***********************TCP Packet*************************\n"); PrintIpHeader(Buffer); fprintf(logfile, "\n");
fprintf(logfile, "TCP Header\n");
fprintf(logfile, " |-Source Port : %u\n", ntohs(tcpheader->source_port));
fprintf(logfile, " |-Destination Port : %u\n", ntohs(tcpheader->dest_port));
fprintf(logfile, " |-Sequence Number : %u\n", ntohl(tcpheader->sequence));
fprintf(logfile, " |-Acknowledge Number : %u\n", ntohl(tcpheader->acknowledge));
fprintf(logfile, " |-Header Length : %d DWORDS or %d BYTES\n"
, (unsigned int)tcpheader->data_offset, (unsigned int)tcpheader->data_offset * 4);
fprintf(logfile, " |-CWR Flag : %d\n", (unsigned int)tcpheader->cwr);
fprintf(logfile, " |-ECN Flag : %d\n", (unsigned int)tcpheader->ecn);
fprintf(logfile, " |-Urgent Flag : %d\n", (unsigned int)tcpheader->urg);
fprintf(logfile, " |-Acknowledgement Flag : %d\n", (unsigned int)tcpheader->ack);
fprintf(logfile, " |-Push Flag : %d\n", (unsigned int)tcpheader->psh);
fprintf(logfile, " |-Reset Flag : %d\n", (unsigned int)tcpheader->rst);
fprintf(logfile, " |-Synchronise Flag : %d\n", (unsigned int)tcpheader->syn);
fprintf(logfile, " |-Finish Flag : %d\n", (unsigned int)tcpheader->fin);
fprintf(logfile, " |-Window : %d\n", ntohs(tcpheader->window));
fprintf(logfile, " |-Checksum : %d\n", ntohs(tcpheader->checksum));
fprintf(logfile, " |-Urgent Pointer : %d\n", tcpheader->urgent_pointer);
fprintf(logfile, "\n");
fprintf(logfile, " DATA Dump ");
fprintf(logfile, "\n"); fprintf(logfile, "IP Header\n");
PrintData(Buffer, iphdrlen); fprintf(logfile, "TCP Header\n");
PrintData(Buffer + iphdrlen, tcpheader->data_offset * 4); fprintf(logfile, "Data Payload\n");
PrintData(Buffer + iphdrlen + tcpheader->data_offset * 4
, (Size - tcpheader->data_offset * 4 - iphdr->ip_header_len * 4)); fprintf(logfile, "\n###########################################################");
} void PrintUdpPacket(char* Buffer, int Size)
{
unsigned short iphdrlen; iphdr = (IPV4_HDR*)Buffer;
iphdrlen = iphdr->ip_header_len * 4; udpheader = (UDP_HDR*)(Buffer + iphdrlen); fprintf(logfile, "\n\n***********************UDP Packet*************************\n"); PrintIpHeader(Buffer); fprintf(logfile, "\nUDP Header\n");
fprintf(logfile, " |-Source Port : %d\n", ntohs(udpheader->source_port));
fprintf(logfile, " |-Destination Port : %d\n", ntohs(udpheader->dest_port));
fprintf(logfile, " |-UDP Length : %d\n", ntohs(udpheader->udp_length));
fprintf(logfile, " |-UDP Checksum : %d\n", ntohs(udpheader->udp_checksum)); fprintf(logfile, "\n");
fprintf(logfile, "IP Header\n"); PrintData(Buffer, iphdrlen); fprintf(logfile, "UDP Header\n"); PrintData(Buffer + iphdrlen, sizeof(UDP_HDR)); fprintf(logfile, "Data Payload\n"); PrintData(Buffer + iphdrlen + sizeof(UDP_HDR), (Size - sizeof(UDP_HDR) - iphdr->ip_header_len * 4)); fprintf(logfile, "\n###########################################################");
} /*
Print the hex values of the data
*/
void PrintData(char* data, int Size)
{
char a, line[17], c;
int j; //loop over each character and print
for (i = 0; i < Size; i++)
{
c = data[i]; //Print the hex value for every character , with a space. Important to make unsigned
fprintf(logfile, " %.2x", (unsigned char)c); //Add the character to data line. Important to make unsigned
a = (c >= 32 && c <= 128) ? (unsigned char)c : '.'; line[i % 16] = a; //if last character of a line , then print the line - 16 characters in 1 line
if ((i != 0 && (i + 1) % 16 == 0) || i == Size - 1)
{
line[i % 16 + 1] = '\0'; //print a big gap of 10 characters between hex and characters
fprintf(logfile, " "); //Print additional spaces for last lines which might be less than 16 characters in length
for (j = strlen(line); j < 16; j++)
{
fprintf(logfile, " ");
} fprintf(logfile, "%s \n", line);
}
} fprintf(logfile, "\n");
}

github链接

win32 - 监视网络流量的更多相关文章

  1. windows下使用C#获取特定进程网络流量

    最近老板接了一个中船重工的项目,需要做一个有关海军软件系统的组件评估项目,项目中有一个子项目需要获取特定进程的各种系统参数,项目使用.NET平台.在获取特定进程各种系统参数时,其它诸如进程ID,进程名 ...

  2. linux网络流量实时监控工具之iptraf

    这个工具还是很强大 linux网络流量实时监控工具之iptraf [我的Linux,让Linux更易用]IPTraf是一个网络监控工具,功能比nload更强大,可以监控所有的流量,IP流量,按协议分的 ...

  3. 运用Ntop监控网络流量(视频Demo)

    运用Ntop监控网络流量 ____网络流量反映了网络的运行状态,是判别网络运行是否正常的关键数据,在实际的网络中,如果对网络流量控制得不好或发生网络拥塞,将会导致网络吞吐量下降.网络性能降低.通过流量 ...

  4. Ntop监控网络流量

    运用Ntop监控网络流量 ____ 网络流量反映了网络的运行状态,是判别网络运行是否正常的关键数据,在实际的网络中,如果对网络流量控制得不好或发生网络拥塞,将会导致网络吞吐量下降. 网络性能降低.通过 ...

  5. Linux 网络流量实时监控工具之ntopng详解

    大纲一.前言二.ntopng 简介三.ntopng 功能说明 四.ntopng 安装详解五.ntopng 配置详解 六.ntopng 使用详解注,操作系统 CentOS 5.5 X86_64,软件版本 ...

  6. linux网络流量实时监控工具之iptraf 【个人比较喜欢用的流量监控软件】

    linux网络流量实时监控工具之iptraf IPTraf是一个网络监控工具,功能比nload更强大,可以监控所有的流量,IP流量,按协议分的流量,还可以设置过滤器等,如下图 对监控网络来说,这个更适 ...

  7. CentOS下使用Iptraf进行网络流量的分析笔记

    CentOS下使用Iptraf进行网络流量的分析笔记 一.概述 Iptraf是一款linux环境下,监控网络流量的一款绝佳的免费小软件. 本博客其他随笔参考: Centos安装流量监控工具iftop笔 ...

  8. Linux服务器上监控网络带宽的18个常用命令nload, iftop,iptraf-ng, nethogs, vnstat. nagios,运用Ntop监控网络流量

    Linux服务器上监控网络带宽的18个常用命令 本文介绍了一些可以用来监控网络使用情况的Linux命令行工具.这些工具可以监控通过网络接口传输的数据,并测量目前哪些数据所传输的速度.入站流量和出站流量 ...

  9. linux 网络数据收发网络流量监控

    网卡流量 1.iftop命令 iftop可以用来监控网卡的实时流量(可以指定网段).反向解析IP.显示端口信息.TCP/IP连接等官网:http://www.ex-parrot.com/~pdw/if ...

  10. 全网最详细的Linux命令系列-iptrad-ng网络流量监测命令

    观察网络流量的工具:IPTRAF 想知道你的Linux系统上网络流量有多大吗?想知道是哪一块网卡承载着网络流量吗?想知道哪一个进程产生了网络流量吗?iptraf可以帮你做到.在最新的Linux rel ...

随机推荐

  1. [转帖]mysql-connect-java驱动从5.x升级到8.x的CST时区问题

    https://juejin.cn/post/7029291622537887774   前言 旧项目MySQL Java升级驱动,本来一切都好好的,但是升级到8.x的驱动后,发现入库的时间比实际时间 ...

  2. [转帖]新一代垃圾回收器ZGC的探索与实践

    1. 引入 1.1 GC之痛 很多低延迟高可用Java服务的系统可用性经常受GC停顿的困扰. GC停顿指垃圾回收期间STW(Stop The World),当STW时,所有应用线程停止活动,等待GC停 ...

  3. redis-shake

    https://github.com/alibaba/RedisShake/wiki/%E8%BF%90%E8%A1%8C%E7%9B%91%E6%8E%A7 redis-shake is a too ...

  4. SQL 训练题目

    title: SQL 训练题目 date: 2023-7-15 01:45:50 tags: - SQL 训练 一. 查询 "01" 课程比 "02" 课程成绩 ...

  5. 金融时间序列预测方法合集:CNN、LSTM、随机森林、ARMA预测股票价格(适用于时序问题)、相似度计算、各类评判指标绘图(数学建模科研适用)

    金融时间序列预测方法合集:CNN.LSTM.随机森林.ARMA预测股票价格(适用于时序问题).相似度计算.各类评判指标绘图(数学建模科研适用) 1.使用CNN模型预测未来一天的股价涨跌-CNN(卷积神 ...

  6. Markdown-CSDN自带帮助语法

    这里写自定义目录标题 欢迎使用Markdown编辑器 新的改变 功能快捷键 合理的创建标题,有助于目录的生成 如何改变文本的样式 插入链接与图片 如何插入一段漂亮的代码片 生成一个适合你的列表 创建一 ...

  7. 强化学习基础篇[2]:SARSA、Q-learning算法简介、应用举例、优缺点分析

    强化学习基础篇[2]:SARSA.Q-learning算法简介.应用举例.优缺点分析 1.SARSA SARSA(State-Action-Reward-State-Action)是一个学习马尔可夫决 ...

  8. 5.1 内存CRC32完整性检测

    CRC校验技术是用于检测数据传输或存储过程中是否出现了错误的一种方法,校验算法可以通过计算应用与数据的循环冗余校验(CRC)检验值来检测任何数据损坏.通过运用本校验技术我们可以实现对特定内存区域以及磁 ...

  9. Linux 统计Web服务日志命令

    本人在Linux运维中收集的一些通用的统计,Apache/Nginx服务器日志的命令组合. Apache日志统计 # 列出当天访问次数最多的IP命令 [root@lyshark.cnblogs.com ...

  10. svg图片引入方式

    第一种直接引入: <svg t="1684280784467" class="icon" viewBox="0 0 1024 1024" ...