Ⅰ 怎么用vc++实现一个网络嗅探器 怎样把这嗅探器这个软件做出来呢
1.网络一下“嗅探原理”;了解计算机基本通信原理,数据封装,以太网传输协议(如OSI七层模型,RAW协议),广播帧····
2.学习怎么设置网卡工作模式为:混杂模式,最后开始设计软件:
===========以下为转载内容,解析不错,直接复制粘贴,呵呵~·====================
代码(转载):
       /************************Tcp_sniff_2.c********************/    
1.#include     
2.#include     
3.#include    
4.#include    
5.#include    
6.#include    
7.#include     
8.#include    
9.#include "headers.h"    
   
#define INTERFACE "eth0"    
   
/*Prototype area*/    
   
10.int Open_Raw_Socket(void);    
11.int Set_Promisc(char *interface, int sock);    
12.int main() {     
13.int sock, bytes_recieved, fromlen;    
14.char buffer[65535];    
15.struct sockaddr_in from;    
16.struct ip *ip;    
17.struct tcp *tcp;     
18.sock = Open_Raw_Socket();    
19. Set_Promisc(INTERFACE, sock);    
   
20. while(1)    
22. {    
23. fromlen = sizeof from;    
24. bytes_recieved = recvfrom(sock, buffer, sizeof buffer, 0, (struct sockaddr *)&from, &fromlen);    
25. printf("\nBytes received ::: %5d\n",bytes_recieved);    
26. printf("Source address ::: %s\n",inet_ntoa(from.sin_addr));    
27. ip = (struct ip *)buffer;    
/*See if this is a TCP packet*/    
28. if(ip->;ip_protocol == 6) {    
29. printf("IP header length ::: %d\n",ip->;ip_length);    
30. printf("rotocol ::: %d\n",ip->;ip_protocol);    
31. tcp = (struct tcp *)(buffer + (4*ip->;ip_length));    
32. printf("Source port ::: %d\n",ntohs(tcp->;tcp_source_port));    
33. printf("Dest port ::: %d\n",ntohs(tcp->;tcp_dest_port));    
34. }    
   
35. }    
36.}    
37.int Open_Raw_Socket() {    
38. int sock;    
39. if((sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) < 0) {  
/*Then the socket was not created properly and must die*/  
40. perror("The raw socket was not created";  
41. exit(0);  
42. };  
43. return(sock);  
44. }  
 
45.int Set_Promisc(char *interface, int sock ) {   
46. struct ifreq ifr;    
47. strncpy(ifr.ifr_name, interface,strnlen(interface)+1);  
48. if((ioctl(sock, SIOCGIFFLAGS, &ifr) == -1)) {  
/*Could not retrieve flags for the interface*/  
49. perror("Could not retrive flags for the interface";  
50. exit(0);  
51. }  
52. printf("The interface is ::: %s\n", interface);  
53. perror("Retrieved flags from interface successfully";  
54. ifr.ifr_flags |= IFF_PROMISC;   
55. if (ioctl (sock, SIOCSIFFLAGS, &ifr) == -1 ) {   
/*Could not set the flags on the interface */   
56. perror("Could not set the PROMISC flag:";  
57. exit(0);   
58. }  
59. printf("Setting interface ::: %s ::: to promisc", interface);  
60. return(0);  
61. }  
 
/***********************EOF**********************************/  
 
  
 
上面这段程序中有很详细的注解,不过我想还是有必要说一说,首先 
第10行--int Open_Raw_Socket(void);是我们的自定义函数,具体内容如下:  
37.int Open_Raw_Socket() {  
38. int sock;  
39. if((sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) < 0) {  
/*Then the socket was not created properly and must die*/  
40. perror("The raw socket was not created";  
41. exit(0);  
42. };  
43. return(sock);  
44. }  
      
 
第39行 if((sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) < 0) {  
 
这里我们调用了socket函数,使创建了了一个原始套接口,使之收到TCP/IP信息包。  
 
接下来第11行-int Set_Promisc(char *interface, int sock),这也是我们的自定义函数, 
目的是把网卡置于混杂模式,具体内容如下:  
45.int Set_Promisc(char *interface, int sock ) {   
46. struct ifreq ifr;    
47. strncpy(ifr.ifr_name, interface,strnlen(interface)+1);  
48. if((ioctl(sock, SIOCGIFFLAGS, &ifr) == -1)) {  
/*Could not retrieve flags for the interface*/  
49. perror("Could not retrive flags for the interface";  
50. exit(0);  
51. }  
52. printf("The interface is ::: %s\n", interface);  
53. perror("Retrieved flags from interface successfully";  
54. ifr.ifr_flags |= IFF_PROMISC;   
55. if (ioctl (sock, SIOCSIFFLAGS, &ifr) == -1 ) {   
/*Could not set the flags on the interface */   
56. perror("Could not set the PROMISC flag:";  
57. exit(0);   
58. }  
59. printf("Setting interface ::: %s ::: to promisc", interface);  
60. return(0);  
61. }  
 
首先 struct ifreq ifr; 定一了一个ifrreg的结构ifr,接下来 
strncpy(ifr.ifr_name, interface,strnlen(interface)+1);,就是把我们网络设备的名字填 
充到ifr结构中,在这里 #define INTERFACE "eth0" ,让我们再往下看, 
ioctl(sock, SIOCGIFFLAGS, &ifr),SIOCGIFFLAGS请求表示需要获取接口标志,现在到了 
第54行,在我们成功的获取接口标志后把他设置成混杂模式, 
ifr.ifr_flags |= IFF_PROMISC;ioctl (sock, SIOCSIFFLAGS, &ifr)。OK,现在我们所说的 
第一步已经完成--------把网卡置于混杂模式。  
 
现在进入第二步,捕获数据包。从第20行开始,我们进入了一个死循环,while(1),在 
第24行,recvfrom(sock, buffer, sizeof buffer, 0, (struct sockaddr *)&from, &fromlen), 
这个函数要做的就是接收数据,冰把接收到的数据放入buffer中。就是这么简单,已经完成了我 
们要捕获数据包的任务。  
 
到了第三步,分析数据包。27行,ip = (struct ip *)buffer,使我们在头文件中的IP结 
构对应于所接收到的数据,接下来判断在网络层中是否使用的是TCP协议, 
if(ip->;ip_protocol == 6) ,如果答案是,tcp信息包从整个IP/TCP包 buffer + (4*ip->;ip_length) 
地址处开始,所以31行 tcp = (struct tcp *)(buffer + (4*ip->;ip_length)),然后对应 
结构把你所需要的信息输出。    
/*************************headers.h**************************/    
/*structure of an ip header*/    
struct ip {     
unsigned int ip_length:4; /*little-endian*/    
unsigned int ip_version:4;    
unsigned char ip_tos;    
unsigned short ip_total_length;     
unsigned short ip_id;     
unsigned short ip_flags;    
unsigned char ip_ttl;    
unsigned char ip_protocol;    
unsigned short ip_cksum;    
unsigned int ip_source; unsigned int ip_dest;     
};    
   
/* Structure of a TCP header */    
struct tcp {    
unsigned short tcp_source_port;    
unsigned short tcp_dest_port;    
unsigned int tcp_seqno;     
unsigned int tcp_ackno;    
unsigned int tcp_res1:4, /*little-endian*/    
tcp_hlen:4,    
tcp_fin:1,    
tcp_syn:1,    
tcp_rst:1,    
tcp_psh:1,    
tcp_ack:1,    
tcp_urg:1,    
tcp_res2:2;    
unsigned short tcp_winsize;    
unsigned short tcp_cksum;    
unsigned short tcp_urgent;    
};    
/*********************EOF***********************************/    
============================
其他的自己追加,这只是原理! ===
============================ 
从上面的分析我们可以清楚的认识到,认识一个SNIFF需要对TCP/IP协议有着详细的了解, 
否则你根本无法找到你需要的信息。有了上面的基础,你可以自己来做一个你需要的SNIFF了。
Ⅱ 网络嗅探器的设计与实现 全代码 最简单的就行 最好用java 可以用的加分
主要原理是利用网卡的混杂模式,和以太网自身的特点进行的。
java写的话用 JPACAP
Jpcap是一个能够抓取与发送网络数据包的Java组件。可以使用Jpcap从一个网络接口获取数据包,然后在Java中对它们进行分析和显示。同样也可以通过一个网络接口发送任意数据包。Jpcap当前能够 捕获以太网,IPv4,IPv6,ARP/RARP,TCP,UDP和ICMPv4数据包。
    Jpcap实际上并非一个真正去实现对数据链路层的控制,而是一个中间件,Jpcap调用wincap/libcap,而给Java语言提供一个公共的接口,从而实现了平台无关性。在官方网站上声明,Jpcap支持FreeBSD3.x,Linux RedHat6.1, Fedora Core4,Solaris,and Microsoft Windows 2000/XP等系统。
   Jpcap的整个结构大体上跟wincap/libpcap是很相像的,例如NetworkInterface类对应wincap的 typedef struct_ADAPTER ADAPTER,getDeviceList()对应pcap_findalldevs()等等。
    Jpcap主要的类有如下几个:
1.NetworkInterface
该类的每一个实例代表一个网络设备,一般就是网卡。这个类只有一些数据成员,除了继承自java.lang.Object的基本方法以外,没有定义其它方法。
2.JpcapCaptor
该类提供了一系列静态方法实现一些基本的功能。该类一个实例代表建立了一个与指定设备的链接,可以通过该类的实例来控制设备,例如设定网卡模式、设定过滤关键字等等。
3.JpcapSender
该类专门用于控制数据包的发送。
4.Packet
这个是所有其它数据包类的父类。Jpcap所支持的数据包有:
ARPPacket、DatalinkPacket、EthernetPacket、ICMPPacket、IPPacket、TCPPacket、UDPPacket。
Ⅲ 网络嗅探器有哪些 常用网络嗅探器推荐介绍
一、影音神探
网络嗅探器(影音神探)使用WinPcap开发包,嗅探流过网卡的数据并智能分析过滤,快速找到所需要的网络信息(音乐、视频、图片、文件等)。软件智能化程度高,使用方便快捷。 
请先安装 WinPcap_4_1_1.exe,再运行本软件。
☆,彻底支持WINPCAP的各个版本,不再挑食。
☆,彻底支持所有操作系统,WIN9X/WIN2K/WINXP,适应能力加强。
☆,增加支持无线网卡的嗅探能力,软件使用更广泛。
☆,软件用Ddlphi 7编写,彻底解决了VB特有的错误,如"运行时错误",软件更加稳定。
☆,不再使用PACKETB.DLL连接文件,软件“绿色环保”。
☆,使用多线程编程技术,内存和CPU占用大幅度减少。
☆,集成超强HTTP下载软件,突破HTTP下载难题。
二、SRSniffer
监听网卡数据包,分析出http数据。
数据包列表使用两种颜色区分发送和接收,更直观
软件背景色使用草绿色,用久了不那么刺眼
可以根据选择监听指定进程。
特殊标注出程序、影音、文档等特殊文件,视频、音乐类的网站资源都可以轻松下载了。
三、乌龙寺网络嗅探器
乌龙寺网络嗅探器是一款功能强大、兼容性好的网络抓包工具,而且绿色安全绝无病毒广告,有了它从此网络管理变得简单高效。
Ⅳ 用VC编写网络嗅探工具
目前,已经有不少的Sniff工具软件,如Windows环境下,最富盛名的工具是Netxray和Sniffer pro,用它们在 Windows环境下抓包来分析,非常方便。在UNIX环境下如Sniffit,Snoop,Tcpmp,Dsniff 等都是比较常见的。这里介绍一个用C语言和网络数据包和分析开发工具libpcap及winpcap实现的简易网络Sniffer。
2网络嗅探器程序实现
在c环境下编程,源码如下:
/* June 2nd,2002
* Project for graation qualification By Bby Team 19 */
#include 
#include 
//必须加路径,必须把头文件packet32.h包含进去
#include "..\..\Include\packet32.h"
#include "..\..\Include\ntddndis.h"
#define Max_Num_Adapter 10
// Prototypes原形
//发包
void PrintPackets(LPPACKET lpPacket);
//设备列表
char AdapterList[Max_Num_Adapter][1024];
// 主程序开始
int main()
{
//define a pointer to an ADAPTER structure设备指针
LPADAPTER lpAdapter = 0;
//define a pointer to a PACKET structure包指针
LPPACKET lpPacket;
int i;
DWORD dwErrorCode;
DWORD dwVersion;
DWORD dwWindowsMajorVersion;
//Unicode strings (WinNT)
WCHAR AdapterName[8192]; //网络适配器设备列表
WCHAR *temp,*temp1;
//ASCII strings (Win9x)
char AdapterNamea[8192]; //网络适配器设备列表
char *tempa,*temp1a;
int AdapterNum=0,Open;
ULONG AdapterLength;
char buffer[256000]; // 容纳来自驱动器的数据的缓冲区
struct bpf_stat stat;
// 获得本机网卡名
AdapterLength=4096;
printf("Packet.dll test application. Library version:%s\n", PacketGetVersion());
printf("Adapters installed:\n");
i=0; 
下面这段代码是用来在不同版本下得到网络适配器名:
Win9x 和WinNT中的网卡名称是分别用ASCII和UNICODE实现的,所以首先要得到本地操作系统的版本号.:
dwVersion=GetVersion();
dwWindowsMajorVersion= (DWORD)(LOBYTE(LOWORD(dwVersion)));
这里首先用到的Packet.dll函数是PacketGetAdapterNames(PTSTR pStr,PULONG BufferSize,通常它是与驱动程序通信并被调用的第一个函数,它将返回的用户本地系统中安装的网络适配器的名字放在缓冲区pStr中;BufferSize是缓冲区的长度:
if (!(dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4))
{ //是Windows NT
// 找不到设备列表
if(PacketGetAdapterNames(AdapterName,&AdapterLength)==FALSE){
printf("Unable to retrieve the list of the adapters!\n");
return -1;
一个简易网络嗅探器的实现 来自: 书签论文网  
}
// 找到设备列表
temp=AdapterName;
temp1=AdapterName;
while ((*temp!='\0')||(*(temp-1)!='\0'))
{
if (*temp=='\0') 
{
memcpy(AdapterList,temp1,(temp-temp1)*2);
temp1=temp+1;
i++;
}
temp++;
}
// 显示适配器列表
AdapterNum=i;
for (i=0;i wprintf(L"\n%d- %s\n",i+1,AdapterList);
printf("\n");
}
else //否则就是windows 9x,获取适配器名的方法同WinNT下
{
if(PacketGetAdapterNames(AdapterNamea,&AdapterLength)==FALSE){
printf("Unable to retrieve the list of the adapters!\n");
论文一个简易网络嗅探器的实现来自 
return -1;
}
tempa=AdapterNamea;
temp1a=AdapterNamea;
while ((*tempa!='\0')||(*(tempa-1)!='\0'))
{
if (*tempa=='\0') 
{
memcpy(AdapterList,temp1a,tempa-temp1a);
temp1a=tempa+1;
i++;
}
tempa++;
}
AdapterNum=i;
for (i=0;i printf("\n%d- %s\n",i+1,AdapterList);
printf("\n");
}
下面这段代码就是让用户选择监听的网络适配器号:
// 选择设备
do 
{
printf("Select the number of the adapter to open : ");
scanf("%d",&Open);
if (Open>AdapterNum) 
printf("\nThe number must be smaller than %d",AdapterNum); 
} while (Open>AdapterNum);
然后,将所选择的设备打开,这里可以设置为“混杂”模式打开,也可以是“直接”模式打开。代码如下:
// 打开设备
lpAdapter = PacketOpenAdapter(AdapterList[Open-1]);
// 当设备无法打开时,出示错误信息:
if (!lpAdapter || (lpAdapter->hFile == INVALID_HANDLE_VALUE))
{
dwErrorCode=GetLastError();
printf("Unable to open the adapter, Error Code : %lx\n",dwErrorCode); 
return -1;
} 
将网卡设置为“混杂”模式,代码如下:
这里用到函数PacketSetHwFilter(LPADAPTER AdapterObject,ULONG Filter),它在到来的包上设置了一个硬件过滤器,如操作成功,返回TRUE。AdapterObject是过滤器所在的网卡设备指针;过滤器的常量Filter定义在头文件ntddndis.h 中,包括有:
•NDIS-PACKET-TYPE-PROMISCUOUS:设置混杂模式,每个到来的包都会被网卡接受;
•NDIS-PACKET-TYPE-DIRECTED:只有直接到主机网卡的包才会被接受;
•NDIS-PACKET-TYPE-BROADCAST:只接受广播包;
•NDIS-PACKET-TYPE-MULTICAST:只接受到主机所在的组的多播包;
•NDIS-PACKET-TYPE-ALL-MULTICAS:接受每个多播的包。
// set the network adapter in promiscuous mode
// 如果混杂模式设置失败,提示错误:
if(PacketSetHwFilter(lpAdapter,NDIS_PACKET_TYPE_PROMISCUOUS)==FALSE){
一个简易网络嗅探器的实现 来自: 书签论文网  
printf("Warning: unable to set promiscuous mode!\n");
}
然后在driver中置512K的缓冲:
这里用到函数PacketSetBuff(LPADAPTER AdapterObject,int dim),它被用于设置AdapterObject指向的网卡的驱动程序的缓冲区,成功则返回TRUE。Dim是新的缓冲区的大小,当它被设定时,旧缓冲区中的数据将被丢弃,其中存储的包也会失去。
需要注意的地方:驱动器缓冲区的大小设置是否恰当,将影响截包进程的性能,设置应能保证运行快且不会丢包。这里设置的是512000Byte。
// set a 512K buffer in the driver
// 当无法设置缓冲区时,提示错误:
if(PacketSetBuff(lpAdapter,512000)==FALSE){
printf("Unable to set the kernel buffer!\n");
return -1;
}
PacketSetReadTimeout(LPADAPTER AdapterObject,int timeout)函数的功能是,设置与AdapterObject指定网卡绑定的读操作超时的值,timeout以毫秒为单位,0表示没有超时,当没有包到时,read就不返回。
// set a 1 second read timeout
// 设置1秒的读取操作超时
if(PacketSetReadTimeout(lpAdapter,1000)==FALSE){
printf("Warning: unable to set the read tiemout!\n");
}
接下来,定位设备,代码如下:
这里用到函数PacketAllocatePacket(Void)将在内存中分配一个PACKET结构并返回一个指向它的指针,但这个结构的Buffer字段还没有设定,所以应再调用PacketInitPacket函数来对其进行初始化。
//allocate and initialize a packet structure that will be used to
//receive the packets.
// 当定位失败时,提示错误:
if((lpPacket = PacketAllocatePacket())==NULL){
printf("\nError: failed to allocate the LPPACKET structure.");
return (-1);
}
然后,就可以初始化设备,开始接受网络包了:
用函数PacketInitPacket(LPPACKET lpPacket,PVOID Buffer,UINT Length)来初始化PACKET结构。lpPacket是要被初始化的指针;Buffer为指向用户分配的包含包的数据的缓冲区的指针;Length为缓冲区长度。
需要注意的地方:PACKET结构关联的缓冲区存储由packet capture driver 截获的包,包的数量被缓冲区大小所限制,最大缓冲区的大小就是应用程序从驱动器中一次能读到的数据的多少。所以设置大的缓冲区可减少系统调用的次数,提高截获效率。这里设置的是256K。
PacketInitPacket(lpPacket,(char*)buffer,256000);
接下来,是截包主循环:
//main capture loop
这里又用到函数PacketReceivePacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync),它将接受(截获)一个包的集合。参数包括一个指向用来指定截包的网卡的ADAPTER结构指针、一个指向用来容纳包的PACKET结构、一个指出是同步还是异步方式操作的标记。当操作同步时,函数锁定程序;当操作异步时,函数不锁定程序,必须调用PacketWaitPacket过程来检查是否正确完成。一般采用同步模式。
// 直到有键盘键入:
while(!kbhit())
{
// capture the packets 捕获包
// 捕获包失败时,提示错误:
if(PacketReceivePacket(lpAdapter,lpPacket,TRUE)==FALSE){
printf("Error: PacketReceivePacket failed");
一个简易网络嗅探器的实现 来自: 书签论文网  
return (-1);
}
// 打印包中的数据,调用自定义函数PrintPackets()
PrintPackets(lpPacket);
}
最后将得到的统计数据打印出来,代码如下:
这里用到函数PacketGetStats(LPADAPTER AdapterObject,struct bpf_star*s)可以得到两个驱动程序的内部变量的值:从调用PacketOpenAdapter开始,已经被指定网卡接收的包数目;以及已经被网卡接收但被内核丢弃的包数目。这两个值被驱动程序拷贝到应用提供的bpf_stat结构中。
//print the capture statistics
// 得到统计值
// 当无法从内核读取状态时,提示错误:
if(PacketGetStats(lpAdapter,&stat)==FALSE){
printf("Warning: unable to get stats from the kernel!\n");
}
// 打印“XX包被截取;XX包被丢弃”:
else
printf("\n\n%d packets received.\n%d Packets lost",stat.bs_recv,stat.bs_drop);
这里用函数PacketFreePacket(LPPACKET lpPacket)来释放由lpPacket指向的结构:
// 释放空间
PacketFreePacket(lpPacket);
用函数PacketCloseAdapter(LPADAPTER lpAdapter)来释放ADAPTER结构lpAdapter,并关闭网卡指针:
// close the adapter and exit
// 关闭设备退出
PacketCloseAdapter(lpAdapter);
return (0);
} // 主程序结束
其中用来打印数据报的自定义的函数PrintPackets()的代码在这里就不详细说明了。
3结束语
通过对网络嗅探器的编写,目的使大家知道网络管理的重要性,时刻注意网络信息安全问题,做好信息的加密和解密工作。