WinSniffer
2012-03-16 08:58
543 查看
在以太网中,所有的通信都是广播的,也就是说通常在同一个网段的所有网络接口都可以访问在物理媒体上传输的所有数据,而每一个网络接口对哦有一个唯一的硬件地址,这个硬件地址也就是网卡的MAC地址。在硬件地址和IP地址间使用ARP和RARP协议进行相互转换。
在正常情况下,一个网络接口只响应这样两种数据帧:与自己硬件地址相匹配的数据帧;向所有计算机的广播数据帧。
在一个系统中,数据的收发是由网卡来完成的,网卡接收到传输来的数据,网卡内的程序接收数据帧的目的MAC地址,根据计算机上的网卡驱动程序设置的接收模式判断该不该接收。
网卡一般有4种接收模式:
广播方式:该模式下的网卡能接收网络中的广播信息
组播方式:该模式下的网卡能够接收组播数据
直接方式: 该模式下,只有目的网卡才能接收数据
混杂谋杀:该模式下的网卡能够接收一切通过它的数据,而不管该数据是否是传给它的
Sniff的工作原理:让网卡接收一切所能接收的数据。
要实现一个Snaiff程序,需要把网卡设置为混杂模式;捕获数据包;分析数据包。
WinSniffer:
附件:http://down.51cto.com/data/2360064
在正常情况下,一个网络接口只响应这样两种数据帧:与自己硬件地址相匹配的数据帧;向所有计算机的广播数据帧。
在一个系统中,数据的收发是由网卡来完成的,网卡接收到传输来的数据,网卡内的程序接收数据帧的目的MAC地址,根据计算机上的网卡驱动程序设置的接收模式判断该不该接收。
网卡一般有4种接收模式:
广播方式:该模式下的网卡能接收网络中的广播信息
组播方式:该模式下的网卡能够接收组播数据
直接方式: 该模式下,只有目的网卡才能接收数据
混杂谋杀:该模式下的网卡能够接收一切通过它的数据,而不管该数据是否是传给它的
Sniff的工作原理:让网卡接收一切所能接收的数据。
要实现一个Snaiff程序,需要把网卡设置为混杂模式;捕获数据包;分析数据包。
WinSniffer:
#include<stdio.h> #include<winsock2.h> #include<mstcpip.h> #pragma comment(lib,"ws2_32.lib") typedef struct iphdr { unsigned char ver_hlen;//4位IPv4版本的4位头长度(用32位字表示) unsigned char tos;//服务的IP类型 unsigned short total_len;//总长 unsigned short ident;//唯一标识符 unsigned short frag_and_flags;//片段偏移字段 unsigned char ttl;//生存时间 unsigned char proto;//协议 unsigned short checksum;//IP校验和 unsigned int sourceIP;//源地址 unsigned int destIP;//目的地址 }IPHeader; #define PACKAGE_SIZE sizeof(IPHeader) #define xmalloc(s) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(s)) #define xfree(p) HeapFree(GetProcessHeap(),0,(p)) BOOL WINAPI CtrlHandler(DWORD dwEvent); void HandleError(char *); BOOL g_bExit = FALSE; int main() { if(!SetConsoleCtrlHandler(CtrlHandler,TRUE)) { printf("SetConsoleCtrlHandler:%d\n",GetLastError()); return -1; } WSADATA wsaData; WSAStartup(MAKEWORD(2,2), &wsaData); SOCKET sock = socket(AF_INET,SOCK_RAW,IPPROTO_IP); if(INVALID_SOCKET==sock) { HandleError("socket"); closesocket(sock); WSACleanup(); return -1; } SOCKADDR_IN addr; memset(&addr,0,sizeof(SOCKADDR_IN)); addr.sin_family=AF_INET; addr.sin_addr.s_addr=inet_addr("192.168.1.222"); if(SOCKET_ERROR==bind(sock,(SOCKADDR*)&addr,sizeof(addr))) { HandleError("bind"); closesocket(sock); WSACleanup(); return -1; } int on = RCVALL_ON; DWORD num; if(SOCKET_ERROR==WSAIoctl(sock,SIO_RCVALL,&on,sizeof(on),NULL,0,&num,NULL,NULL)) { HandleError("WSAIoctl"); closesocket(sock); WSACleanup(); return -1; } char *buf = (char*)xmalloc(PACKAGE_SIZE); SOCKADDR_IN from; int fromlen; while(!g_bExit) { memset(buf,0,PACKAGE_SIZE); memset(&from,0,sizeof(from)); fromlen=sizeof(from); if(SOCKET_ERROR==recvfrom(sock,buf,PACKAGE_SIZE,0,(SOCKADDR*)&from,&fromlen)) { if(WSAEMSGSIZE!=WSAGetLastError()) { HandleError("recvfrom"); break; } } switch(((IPHeader*)buf)->proto) { case IPPROTO_ICMP: printf("ICMP From %s\n",inet_ntoa(from.sin_addr)); break; case IPPROTO_IGMP: printf("IGMP From %s\n",inet_ntoa(from.sin_addr)); break; case IPPROTO_TCP: printf("TCP From %s\n",inet_ntoa(from.sin_addr)); break; case IPPROTO_UDP: printf("UPD From %s\n",inet_ntoa(from.sin_addr)); break; default: printf("Unknown datagram From %s\n",inet_ntoa(from.sin_addr)); } } xfree(buf); closesocket(sock); WSACleanup(); printf("Stopped!\n"); system("pause"); return 0; } BOOL WINAPI CtrlHandler(DWORD dwEvent) { switch(dwEvent) { case CTRL_C_EVENT: case CTRL_LOGOFF_EVENT: case CTRL_SHUTDOWN_EVENT: case CTRL_CLOSE_EVENT: printf("Stopping......\n"); break; default: return FALSE; } return TRUE; } void HandleError(char * func) { int error = WSAGetLastError(); char info[65] = {0}; _snprintf(info, 64, "%s: %d\n",func,error); printf(info); }
附件:http://down.51cto.com/data/2360064
相关文章推荐
- DNS的工作原理图解说明
- 可以获取客户端的IP地址的sql语句
- jQuery源码分析-04 选择器-Sizzle-工作原理分析
- 腾讯与新浪的通过IP地址获取当前地理位置(省份)的接口
- javascript将ip地址第四段用星号代替的两种方法
- asp.net 通过指定IP地址得到当前的网络上的主机的域名
- 使用CDN之后APACHE日志记录中IP地址不正确的解决方案
- 交换机的工作原理
- 协议寻址
- Red Hat Linux 253 实验部分
- 常用以太网帧结构详解
- 快速批量绑定MAC与IP地址
- C#实现的一个内存Ini类
- 局域网IP地址非法使用问题的解决方法
- h3c 3600 交换机配置Telnet登录
- 【引用】IP地址已经分配给另一个适配器问题的解决方法
- linux配置网卡IP地址命令详细介绍及一些常用网络配置命令
- 以太网帧格式及例子
- 什么是TX,FX,SX,LX,CX?
- ip subnet zero