简易的sniffer程序

时间:2023-03-09 14:46:21
简易的sniffer程序

真的非常简易,这个程序不过抓一些发送到本机的数据包,然后显示出来它们的一些信息罢了。

     程序很easy!

     

#include <WinSock2.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#pragma comment(lib, "ws2_32.lib") /*链接ws2_32.lib动态链接库*/
#define SIO_RCVALL _WSAIOW(IOC_VENDOR, 1)
const int MAX_ADDR_LEN = 16; /*ip地址长度*/
const int MAX_HOSTNAME_LEN = 255; /*主机名称*/ /*WORD 16位 DWORD 32位*/
struct IPHeader {
BYTE HeaderLength : 4; //首部长度
BYTE Version : 4; //版本号
BYTE DS; //区分服务
WORD TotalLength; //总长度
WORD ID; //标识
BYTE FragmentOffset0 : 5; //片偏移
BYTE MF : 1; //MF标识
BYTE DF : 1; //DF标识
BYTE Reserved : 1; //保留标识
BYTE FragmentOffset1; //片偏移
BYTE TTL; //生存时间
BYTE Protocol; //协议
WORD Checksum; //检验和
DWORD SourceAddress; //源地址
DWORD DestinationAddress; //目的地址
}; struct TCPHeader {
WORD SourcePort; //源port
WORD DestinationPort; //目的port
DWORD SequenceNumber; //序号
DWORD AcknowledgmentNumber; //确认号
BYTE Reserved0 : 4; //保留字段第一部分
BYTE DataOffset : 4; //数据偏移
BYTE FIN : 1; //FIN标识
BYTE SYN : 1; //SYN标识
BYTE RST : 1; //RST标识
BYTE PSH : 1; //PSH标识
BYTE ACK : 1; //ACK标识
BYTE URG : 1; //URG标识
BYTE Reserved1 : 2; //保留字段第二部分
WORD Window; //窗体
WORD Checksum; //检验和
WORD UrgentPointer; //紧急指针
}; struct UDPHeader {
WORD SourcePort; //源port
WORD DestinationPort; //目的port
WORD Length; //长度
WORD Checksum; //检验和
}; void main()
{
SOCKET sock;
WSADATA wsd;
DWORD dwBytesRet;
unsigned int optval = 1;
int pCount = 0; sockaddr_in source, dest; char hostName[MAX_HOSTNAME_LEN]; char sourceIP[MAX_ADDR_LEN]; /*记录源ip地址*/
char destIP[MAX_ADDR_LEN]; /*记录目的ip地址*/
char recvBuff[65535] = { 0 }; WSAStartup(MAKEWORD(2, 1), &wsd); /*初始化*/
hostent *pHostent;
UDPHeader *pUdpheader; /*UDP头部*/
IPHeader *pIpheader; /*IP头部*/
TCPHeader *pTcpheader; /*TCP头部*/ if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP)) == SOCKET_ERROR)/*创建原始套接字*/
{
exit(-1);
} gethostname(hostName, MAX_HOSTNAME_LEN); //获取主机名称
pHostent = gethostbyname(hostName); //获取有关于本机信息的一个hostent结构体 sockaddr_in sa;
sa.sin_family = AF_INET;
sa.sin_port = htons(6000);
memcpy(&sa.sin_addr.S_un.S_addr, pHostent->h_addr_list[0], pHostent->h_length); bind(sock, (SOCKADDR *)&sa, sizeof(sa)); /*绑定套接字*/ if (WSAGetLastError() == 10013)
{
exit(1);
}
/************************************************************************/
/* The WSAIoctl function controls the mode of a socket.
*/
/************************************************************************/
/*这个函数主要用来设定一些參数,这里设定接收全部的数据包*/
WSAIoctl(sock, SIO_RCVALL, &optval, sizeof(optval), NULL, 0, &dwBytesRet, NULL, NULL); pIpheader = (IPHeader *)recvBuff; while (pCount < 1000)
{
memset(recvBuff, 0, sizeof(recvBuff));
recv(sock, recvBuff, sizeof(recvBuff), 0); /*接收数据包*/ source.sin_addr.S_un.S_addr = pIpheader->SourceAddress; /*数据包源地址*/
strncpy_s(sourceIP, inet_ntoa(source.sin_addr), MAX_ADDR_LEN); dest.sin_addr.S_un.S_addr = pIpheader->DestinationAddress; /*目的地址*/
strncpy_s(destIP, inet_ntoa(dest.sin_addr), MAX_ADDR_LEN); if (pIpheader->Protocol == IPPROTO_TCP) /*使用的是TCP协议*/
{
int dataLen;
pTcpheader = (TCPHeader *)(recvBuff + sizeof(IPHeader));
dataLen = (pIpheader->TotalLength -
(pIpheader->HeaderLength * 4 + pTcpheader->DataOffset * 4));//tcp可能存在扩展 if (dataLen == 0) break;
printf("---------------------TCP---------------------\n");
printf("数据包序号 : %d\n", pCount);
printf("数据包大小 : %d\n", dataLen);
printf("源IP地址 :%s\n", sourceIP);
/*ntohs(s表示short)即将16位的数从网络(network)字节序转换为主机(host)字节序*/
/*同理,ntohl(l表示long)即将32位的数从网络(network)字节序转换为主机(host)字节序*/
printf("源port :%d\n", ntohs(pTcpheader->SourcePort));
printf("目地ip地址 :%s\n", destIP);
printf("目的port :%d\n", ntohs(pTcpheader->DestinationPort));
printf(" IP头部大小:%d\n", pIpheader->HeaderLength * 4);
printf("TCP头部大小:%d\n", (pTcpheader->DataOffset) * 4);
Sleep(1000);/*假设不休眠一下的话,速度会很的快!*/
pCount++;
} if (pIpheader->Protocol == IPPROTO_UDP) //数据包使用UDP
{
pUdpheader = (UDPHeader *)(recvBuff + sizeof(IPHeader));
int dataLen;
dataLen = (pIpheader->TotalLength -
(pIpheader->HeaderLength * 4 + sizeof(UDPHeader)));//udp首部并没有扩展
if (dataLen == 0) break;
printf("---------------------UDP--------------------\n");
printf("数据包序号 : %d\n", pCount);
printf("数据包大小 : %d\n", dataLen); printf("源IP地址 :%s\n", sourceIP);
printf("源port :%d\n", ntohs(pUdpheader->SourcePort));
printf("目的IP地址 :%s\n", destIP);
printf("目的port :%d\n", ntohs(pUdpheader->DestinationPort));
printf("IP头部大小 :%d\n", (pIpheader->HeaderLength)* 4);
printf("UDP头部大小:%d\n", sizeof(UDPHeader));
Sleep(1000);//假设不休眠一下的话,速度会很的快!
pCount++;
} }/*while*/
system("pause");
}