c/c++写的Mini Sniffer(嗅探工具)
来源:互联网 发布:iot js 机 编辑:程序博客网 时间:2024/05/21 14:01
c/c++写的Mini Sniffer
前两天写了一个mini sniffer 原理很简单,就是利用原始套接字将网卡设置成混杂模式,然后利用套接字监听经过本主机的所有网络IP封包,但是由于本人现在能力有限,还不能很好的对数据包进行解码分析,就只能将它们的十六进制ASCL码输出..以下是源代码.编译器是vs2005 //头文件 DataStruct.h
#ifndef _DATASTRUCT_H_
#define _DATASTRUCT_H_
char szText[1024];
typedef struct _IP_HDR
...{
UCHAR ipVersion;//IP版本号和头长度
UCHAR ipTos;//服务类型
USHORT ipLength;//总长度
USHORT ipID;//封包标识,用于将分片重新组装成封包
USHORT ipFlag;//标志,目前只有前两位有意义,|DF|MF|...DF是不能分片,MF是有更多的分片
UCHAR ipTTL;//封包生存时间,也就是经过的路由个数
UCHAR ipProtocol;//指定数据包携带的数据是使用的是那种协议:TCP,UDP,ICMP??
USHORT ipCheckSum;//首部校验和
ULONG ipSourceAdd;//数据报源地址
ULONG ipDestination;//数据报目的地址
}IPHEADER, *PIPHEADER;
typedef struct _UDP_HDR
...{
USHORT sourcePort;//源端口号
USHORT destinationPort;//目的端口号
USHORT len;//封包长度
USHORT chekSum;//校验和
}UDPHEADER, *PUDPHEADER;
/**//*该程序没有ICMP数据包的解析
typedef struct _ICMP_HDR
{
USHORT icmp_type;
USHORT icmp_code;
USHORT icmp_chekSum;
USHORT icmp_id;
USHORT icmp_sequuence;
ULONG icmp_timestamp;
}ICMP_HDR, *PICMP_HDR;
*/
typedef struct _TCP_HDR
...{
USHORT sourcePort;//16位源端口号
USHORT destPort;//目的端口号
ULONG sequenceNumber;// 序列号
ULONG ACK;//确认号
UCHAR dataOffset;//4位首部长度/6位保留字
UCHAR flags;//6位标志位
USHORT windowLen;//窗口大小
USHORT checkSum;//校验和
USHORT urgentPointer;//紧急指针|紧急数据偏移量
}TCPHEADER, *PTCPHEADER;
#endif //_DATASTRUCT_H_
//头文件 InitSocket.h
/**//* winsock应用程序必须加载Winsock Dll
* 加载该Dll的函数就是::WSAStartup()
* 使用结束后还得释放Dll 用::WSACleanup()函数可以实现
*/
#ifndef _INITSOCKET_H_
#define _INITSOCKET_H_
#include <winsock2.h>
#include <Mswsock.h>
#include <Ws2tcpip.h>
#pragma comment(lib, "WS2_32")
class CInitSocket
...{
public:
CInitSocket(BYTE minorVer = 2, BYTE majorVer = 2)
...{
WSADATA wsaData;
WORD sockVersion = MAKEWORD(minorVer, majorVer);
if (::WSAStartup(sockVersion, &wsaData) != 0)
...{
return;
}
}
~CInitSocket()
...{
::WSACleanup();
}
};
#endif _INITSOCKET_H_
//头文件HdFuns.h
#ifndef _HDFUNS_H_
#define _HDFUNS_H_
extern int nRet;
void AnalyzeIpPackets(char *buff);//分析IP数据包
void AnalyzeTcpPackets(char *buff);//分析TCP数据包
void AnalyzeUdpPackets(char *buff);//分析UDP数据包
#endif //_HDFUNS_H_
该头文件的实现文件HdFuns.cpp如下:
#include "HdFuns.h"
#include <stdio.h>
#include <winsock2.h>
#include "DataStruct.h"
void AnalyzeIpPackets(char *buff)
...{
PIPHEADER pIphdr = (PIPHEADER)buff;
in_addr source, dest;//源地址和目的地址
char szSourceIp[32], szDestIp[32];
printf(" ----------------------------------- ");
source.S_un.S_addr = pIphdr->ipSourceAdd;//源IP
dest.S_un.S_addr = pIphdr->ipDestination;//目的IP
::strcpy(szSourceIp, ::inet_ntoa(source));
::strcpy(szDestIp, ::inet_ntoa(dest));
printf("%s -> %s ", szSourceIp, szDestIp);
//IP头长度
int nIpHeaderLen = (pIphdr->ipVersion & 0xf) * sizeof(ULONG);
switch(pIphdr->ipProtocol)
...{
case IPPROTO_TCP://TCP
AnalyzeTcpPackets(buff + nIpHeaderLen);
break;
case IPPROTO_UDP://UDP
AnalyzeUdpPackets(buff + nIpHeaderLen);
break;
case IPPROTO_ICMP:
break;
}
}
void AnalyzeTcpPackets(char *buff)
...{
PTCPHEADER pTcpHdr = (PTCPHEADER)buff;
printf("This is a Tcp packet!! ");
//输出端口号
printf("Port : %d -> %d ", ::ntohs(pTcpHdr->sourcePort), ::ntohs(pTcpHdr->destPort));
::memset(szText, ' ', nRet);
int dataLen = nRet - sizeof(IPHEADER) - sizeof(TCPHEADER);//计算数据的长度
::memcpy(szText, &buff[sizeof(TCPHEADER)], dataLen);//将数据包中的数据拷贝到缓冲区中
for (int i = 0; i < dataLen; i++)
...{
//按字节分析数据
if (szText[i] < 0 )
...{
szText[i] = -szText[i];
}
printf("%X ", szText[i]);
}
switch(::ntohs(pTcpHdr->destPort))
...{
case 21:
break;
case 80:
case 8080:
break;
}
}
void AnalyzeUdpPackets(char *buff)
...{
printf("This is a Udp packet!! ");
PUDPHEADER pUdpHdr = (PUDPHEADER)buff;
printf("%d--->%d ", ::ntohs(pUdpHdr->sourcePort), ::ntohs(pUdpHdr->destinationPort));
::memset(szText, ' ' , nRet);//清空缓冲区
int dataLen =nRet - sizeof(UDPHEADER) - sizeof(IPHEADER);
::memcpy(szText, buff + sizeof(UDPHEADER), dataLen);
for (int i = 0; i < dataLen; i++)
...{
if (szText[i] < 0 )
...{
szText[i] = -szText[i];
}
printf("%X ", szText[i]);
}
}
//主函数内容
#include "InitSocket.h"
#include <iostream>
#include "HdFuns.h"
#include <mstcpip.h>
using namespace std;
CInitSocket initSock;
int nRet;
int main(void)
...{
SOCKET sRaw = ::socket(AF_INET, SOCK_RAW, IPPROTO_IP);//原始套接字
char szHostName[56];//主机名
SOCKADDR_IN localAddr;//本地地址
struct hostent *pHost;
::gethostname(szHostName, 56);//获取主机名
if ((pHost = ::gethostbyname((char*)szHostName)) == NULL)
...{
return 0;
}
localAddr.sin_family = AF_INET;
localAddr.sin_port = ::htons(0);
::memcpy(&localAddr.sin_addr.S_un.S_addr, pHost->h_addr_list[0], pHost->h_length);
cout<<"Bind to interface :"<<::inet_ntoa(localAddr.sin_addr)<<endl;
if (::bind(sRaw, (PSOCKADDR)&localAddr, sizeof(localAddr)) == SOCKET_ERROR)
...{
return 0;
}
DWORD dwValue = 1;
if (::ioctlsocket(sRaw, SIO_RCVALL, &dwValue) != 0)//设置网卡为混杂模式
...{
return 0;
}
char buff[1024];
while(true)
...{
nRet = ::recv(sRaw, buff, 1024, 0);//接受网络中数据包
if (nRet > 0)
...{
buff[nRet] = '';
AnalyzeIpPackets(buff);//分析IP数据包
}
}
::closesocket(sRaw);//关闭套接字
return 0;
}
#ifndef _DATASTRUCT_H_
#define _DATASTRUCT_H_
char szText[1024];
typedef struct _IP_HDR
...{
UCHAR ipVersion;//IP版本号和头长度
UCHAR ipTos;//服务类型
USHORT ipLength;//总长度
USHORT ipID;//封包标识,用于将分片重新组装成封包
USHORT ipFlag;//标志,目前只有前两位有意义,|DF|MF|...DF是不能分片,MF是有更多的分片
UCHAR ipTTL;//封包生存时间,也就是经过的路由个数
UCHAR ipProtocol;//指定数据包携带的数据是使用的是那种协议:TCP,UDP,ICMP??
USHORT ipCheckSum;//首部校验和
ULONG ipSourceAdd;//数据报源地址
ULONG ipDestination;//数据报目的地址
}IPHEADER, *PIPHEADER;
typedef struct _UDP_HDR
...{
USHORT sourcePort;//源端口号
USHORT destinationPort;//目的端口号
USHORT len;//封包长度
USHORT chekSum;//校验和
}UDPHEADER, *PUDPHEADER;
/**//*该程序没有ICMP数据包的解析
typedef struct _ICMP_HDR
{
USHORT icmp_type;
USHORT icmp_code;
USHORT icmp_chekSum;
USHORT icmp_id;
USHORT icmp_sequuence;
ULONG icmp_timestamp;
}ICMP_HDR, *PICMP_HDR;
*/
typedef struct _TCP_HDR
...{
USHORT sourcePort;//16位源端口号
USHORT destPort;//目的端口号
ULONG sequenceNumber;// 序列号
ULONG ACK;//确认号
UCHAR dataOffset;//4位首部长度/6位保留字
UCHAR flags;//6位标志位
USHORT windowLen;//窗口大小
USHORT checkSum;//校验和
USHORT urgentPointer;//紧急指针|紧急数据偏移量
}TCPHEADER, *PTCPHEADER;
#endif //_DATASTRUCT_H_
//头文件 InitSocket.h
/**//* winsock应用程序必须加载Winsock Dll
* 加载该Dll的函数就是::WSAStartup()
* 使用结束后还得释放Dll 用::WSACleanup()函数可以实现
*/
#ifndef _INITSOCKET_H_
#define _INITSOCKET_H_
#include <winsock2.h>
#include <Mswsock.h>
#include <Ws2tcpip.h>
#pragma comment(lib, "WS2_32")
class CInitSocket
...{
public:
CInitSocket(BYTE minorVer = 2, BYTE majorVer = 2)
...{
WSADATA wsaData;
WORD sockVersion = MAKEWORD(minorVer, majorVer);
if (::WSAStartup(sockVersion, &wsaData) != 0)
...{
return;
}
}
~CInitSocket()
...{
::WSACleanup();
}
};
#endif _INITSOCKET_H_
//头文件HdFuns.h
#ifndef _HDFUNS_H_
#define _HDFUNS_H_
extern int nRet;
void AnalyzeIpPackets(char *buff);//分析IP数据包
void AnalyzeTcpPackets(char *buff);//分析TCP数据包
void AnalyzeUdpPackets(char *buff);//分析UDP数据包
#endif //_HDFUNS_H_
该头文件的实现文件HdFuns.cpp如下:
#include "HdFuns.h"
#include <stdio.h>
#include <winsock2.h>
#include "DataStruct.h"
void AnalyzeIpPackets(char *buff)
...{
PIPHEADER pIphdr = (PIPHEADER)buff;
in_addr source, dest;//源地址和目的地址
char szSourceIp[32], szDestIp[32];
printf(" ----------------------------------- ");
source.S_un.S_addr = pIphdr->ipSourceAdd;//源IP
dest.S_un.S_addr = pIphdr->ipDestination;//目的IP
::strcpy(szSourceIp, ::inet_ntoa(source));
::strcpy(szDestIp, ::inet_ntoa(dest));
printf("%s -> %s ", szSourceIp, szDestIp);
//IP头长度
int nIpHeaderLen = (pIphdr->ipVersion & 0xf) * sizeof(ULONG);
switch(pIphdr->ipProtocol)
...{
case IPPROTO_TCP://TCP
AnalyzeTcpPackets(buff + nIpHeaderLen);
break;
case IPPROTO_UDP://UDP
AnalyzeUdpPackets(buff + nIpHeaderLen);
break;
case IPPROTO_ICMP:
break;
}
}
void AnalyzeTcpPackets(char *buff)
...{
PTCPHEADER pTcpHdr = (PTCPHEADER)buff;
printf("This is a Tcp packet!! ");
//输出端口号
printf("Port : %d -> %d ", ::ntohs(pTcpHdr->sourcePort), ::ntohs(pTcpHdr->destPort));
::memset(szText, ' ', nRet);
int dataLen = nRet - sizeof(IPHEADER) - sizeof(TCPHEADER);//计算数据的长度
::memcpy(szText, &buff[sizeof(TCPHEADER)], dataLen);//将数据包中的数据拷贝到缓冲区中
for (int i = 0; i < dataLen; i++)
...{
//按字节分析数据
if (szText[i] < 0 )
...{
szText[i] = -szText[i];
}
printf("%X ", szText[i]);
}
switch(::ntohs(pTcpHdr->destPort))
...{
case 21:
break;
case 80:
case 8080:
break;
}
}
void AnalyzeUdpPackets(char *buff)
...{
printf("This is a Udp packet!! ");
PUDPHEADER pUdpHdr = (PUDPHEADER)buff;
printf("%d--->%d ", ::ntohs(pUdpHdr->sourcePort), ::ntohs(pUdpHdr->destinationPort));
::memset(szText, ' ' , nRet);//清空缓冲区
int dataLen =nRet - sizeof(UDPHEADER) - sizeof(IPHEADER);
::memcpy(szText, buff + sizeof(UDPHEADER), dataLen);
for (int i = 0; i < dataLen; i++)
...{
if (szText[i] < 0 )
...{
szText[i] = -szText[i];
}
printf("%X ", szText[i]);
}
}
//主函数内容
#include "InitSocket.h"
#include <iostream>
#include "HdFuns.h"
#include <mstcpip.h>
using namespace std;
CInitSocket initSock;
int nRet;
int main(void)
...{
SOCKET sRaw = ::socket(AF_INET, SOCK_RAW, IPPROTO_IP);//原始套接字
char szHostName[56];//主机名
SOCKADDR_IN localAddr;//本地地址
struct hostent *pHost;
::gethostname(szHostName, 56);//获取主机名
if ((pHost = ::gethostbyname((char*)szHostName)) == NULL)
...{
return 0;
}
localAddr.sin_family = AF_INET;
localAddr.sin_port = ::htons(0);
::memcpy(&localAddr.sin_addr.S_un.S_addr, pHost->h_addr_list[0], pHost->h_length);
cout<<"Bind to interface :"<<::inet_ntoa(localAddr.sin_addr)<<endl;
if (::bind(sRaw, (PSOCKADDR)&localAddr, sizeof(localAddr)) == SOCKET_ERROR)
...{
return 0;
}
DWORD dwValue = 1;
if (::ioctlsocket(sRaw, SIO_RCVALL, &dwValue) != 0)//设置网卡为混杂模式
...{
return 0;
}
char buff[1024];
while(true)
...{
nRet = ::recv(sRaw, buff, 1024, 0);//接受网络中数据包
if (nRet > 0)
...{
buff[nRet] = '';
AnalyzeIpPackets(buff);//分析IP数据包
}
}
::closesocket(sRaw);//关闭套接字
return 0;
}
执行结果如下(部分截图,一直处于滚屏状态):
- c/c++写的Mini Sniffer(嗅探工具)
- sniffer.c
- 网络嗅探工具的原理 sniffer&wireshark
- C语言写的DDOS工具
- C-mini 程序设计语言的设计与实现
- sniffer系统:C+LAMP 实现
- Linux下 Mini-shell的实现(C/C++)
- C#做的配套C做的SNIFFER(C#)--C#简单而实用
- Packet Sniffer Code in C using sockets
- Xray@NET,业余写的SNIFFER
- Xray@NET,业余写的SNIFFER
- c写的迷宫
- Mini-XML入门基础 Getting Started with Mini-XML c
- C语言写魔兽显血条工具
- 写C,先安装好工具
- 使用Objective-C的文档生成工具:appledoc【很好的工具 没写过文档 就先留着】
- mini webserver on linux with c
- mini 2440TEST 之MMU.C解读
- asp.net C# url重写
- MSDN:Webcast 系列课程
- #pragma
- 软件项目版本号的命名规则及格式
- PHP字符串处理函数
- c/c++写的Mini Sniffer(嗅探工具)
- eMule电驴eDonkey从死到生
- PowerShell取得局域网中SQL Server数据库实例以及其他
- 又是一年离别时
- 迷茫
- Eclipse3.2.1中利用XDoclet Enterprise JavaBean创建Container Managed Entity Bean
- 开始→运行→输入的命令集锦
- 一个文件批处理程序代码发布
- #pragma pack() 和sizeof