当前位置:首页 » 安全设置 » 网络安全嗅探器的设计与实现
扩展阅读
光猫有信号无法连接网络 2025-06-30 23:18:52
网站上怎么登录疯狂标签 2025-06-30 23:18:04

网络安全嗅探器的设计与实现

发布时间: 2022-06-08 06:52:03

㈠ 求个网络嗅探器的设计 相关的 外文翻译

随着网络技术的发展和网络应用的普及,越来越多的信息资源放在了互联网上,网络的安全性和可靠性显得越发重要。因此,对于能够分析、诊断网络,测试网络性能与安全性的工具软件的需求也越来越迫切。网络嗅探器具有两面性,攻击者可以用它来监听网络中数据,达到非法获得信息的目的,网络管理者可以通过使用嗅探器捕获网络中传输的数据包并对其进行分析,分析结果可供网络安全分析之用。
本文对网络嗅探技术进行了简要分析,研究了网络数据包的捕获机制,如winpcap、原始套接字。文中首先分析了嗅探的原理和危害,并介绍了几种常见的嗅探器,然后研究了入侵检测系统中使用的包捕获技术。本文利用原始套接字在windows平台下实现了一个网络嗅探器程序,完成了对数据包进行解包、分析数据包的功能。
关键词:网络嗅探器;数据包捕获;数据包分析;原始套接字

目 录
1 引言 1
1.1 网络安全的现状 1
1.1.1 计算机网络安全的问题 1
1.1.2 网络安全机制及技术措施 1
1.2本课题的研究意义 2
1.3本文研究的内容 3
2 网络嗅探器的基本原理 3
2.1网络嗅探器概述 3
2.2 嗅探器实现基础 3
2.3 常见的sniffer 4
2.4 数据包捕获机制的研究 4
2.4.1 WinPcap包捕获机制 5
2.4.2 套接字包捕获机制 6
2.5 嗅探器的两面性 8
2.5.1 sinffer的危害 8
2.5.2 通过网络嗅探进行网络管理 9
3 入侵检测系统与嗅探器 9
3.1 入侵检测概念 9
3.2 入侵检测的实现与嗅探器 10
3.2.1 入侵检测的实现与嗅探器的关系 11
3.2.2 数据包嗅探技术在入侵检测系统中的应用 11
4 嗅探器的实现与测试 12
4.1利用套接字开发网络嗅探程序的步骤 12
4.2 嗅探器的具体实现原理 13
4.3 数据包捕获程序设计 15
4.4 数据包的解析 15
4.5 数据的显示 19
4.6 嗅探器的测试 22

㈡ 【c++ 课程设计】 简单的网络嗅探器 目的与要求:实现网络层抓包,并对获得包的源和目的地址、端口、协议等

#include <winsock2.h> /*windows socket的头文件,系统定义的*/
#include <windows.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <stdlib.h>
#pragma comment(lib,"ws2_32.lib") /*链接API相关连的Ws2_32.lib静态库*/
#define MAX_HOSTNAME_LAN 255
#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
#define MAX_ADDR_LEN 16

struct ipheader {
unsigned char ip_hl:4; /*header length(报头长度)*/
unsigned char ip_v:4; /*version(版本)*/
unsigned char ip_tos; /*type os service服务类型*/
unsigned short int ip_len; /*total length (总长度)*/
unsigned short int ip_id; /*identification (标识符)*/
unsigned short int ip_off; /*fragment offset field(段移位域)*/
unsigned char ip_ttl; /*time to live (生存时间)*/
unsigned char ip_p; /*protocol(协议)*/
unsigned short int ip_sum; /*checksum(校验和)*/
unsigned int ip_src; /*source address(源地址)*/
unsigned int ip_dst; /*destination address(目的地址)*/
}; /* total ip header length: 20 bytes (=160 bits) */

typedef struct tcpheader {
unsigned short int sport; /*source port (源端口号)*/
unsigned short int dport; /*destination port(目的端口号)*/
unsigned int th_seq; /*sequence number(包的序列号)*/
unsigned int th_ack; /*acknowledgement number(确认应答号)*/
unsigned char th_x:4; /*unused(未使用)*/
unsigned char th_off:4; /*data offset(数据偏移量)*/
unsigned char Flags; /*标志全*/
unsigned short int th_win; /*windows(窗口)*/
unsigned short int th_sum; /*checksum(校验和)*/
unsigned short int th_urp; /*urgent pointer(紧急指针)*/
}TCP_HDR;

typedef struct udphdr {
unsigned short sport; /*source port(源端口号)*/
unsigned short dport; /*destination port(目的端口号)*/
unsigned short len; /*udp length(udp长度)*/
unsigned short cksum; /*udp checksum(udp校验和)*/
}UDP_HDR;

void main(){

SOCKET sock;
WSADATA wsd;
DWORD dwBytesRet;
unsigned int optval = 1;
unsigned char *dataudp,*datatcp;
int i,pCount=0,lentcp, lenudp;
SOCKADDR_IN sa,saSource, saDest;
struct hostent FAR * pHostent;
char FAR name[MAX_HOSTNAME_LAN];
char szSourceIP[MAX_ADDR_LEN], szDestIP[MAX_ADDR_LEN],RecvBuf[65535] = {0};
struct udphdr *pUdpheader;
struct ipheader *pIpheader;
struct tcpheader *pTcpheader;
WSAStartup(MAKEWORD(2,1),&wsd);
if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP))==SOCKET_ERROR)
exit(1);
gethostname(name, MAX_HOSTNAME_LAN);
pHostent = gethostbyname(name);
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)); /*bind()设定自己主机的IP地址和端口号*/
if ((WSAGetLastError())==10013)
exit(1);
WSAIoctl(sock, SIO_RCVALL, &optval, sizeof(optval), NULL, 0, &dwBytesRet, NULL, NULL);
pIpheader = (struct ipheader *)RecvBuf;
pTcpheader = (struct tcpheader *)(RecvBuf+ sizeof(struct ipheader ));
pUdpheader = (struct udphdr *) (RecvBuf+ sizeof(struct ipheader ));

while (1){
memset(RecvBuf, 0, sizeof(RecvBuf));
recv(sock, RecvBuf, sizeof(RecvBuf), 0);
saSource.sin_addr.s_addr = pIpheader->ip_src;
strncpy(szSourceIP, inet_ntoa(saSource.sin_addr), MAX_ADDR_LEN);
saDest.sin_addr.s_addr = pIpheader->ip_dst;
strncpy(szDestIP, inet_ntoa(saDest.sin_addr), MAX_ADDR_LEN);
lentcp =(ntohs(pIpheader->ip_len)-(sizeof(struct ipheader)+sizeof(struct tcpheader)));
lenudp =(ntohs(pIpheader->ip_len)-(sizeof(struct ipheader)+sizeof(struct udphdr)));

if((pIpheader->ip_p)==IPPROTO_TCP&&lentcp!=0){
printf("*******************************************\n");
pCount++;
datatcp=(unsigned char *) RecvBuf+sizeof(struct ipheader)+sizeof(struct tcpheader);
printf("-TCP-\n");
printf("\n目的IP地址:%s\n",szDestIP);
printf("\n目的端口:%i\n",ntohs(pTcpheader->dport));
printf("datatcp address->%x\n",datatcp);
printf("size of ipheader->%i\n",sizeof(struct ipheader));
printf("size of tcpheader->%i\n",sizeof(struct tcpheader));
printf("size of the hole packet->%i\n",ntohs(pIpheader->ip_len));
printf("\nchar Packet%i [%i]=\"",pCount,lentcp-1);

for (i=0;i<lentcp;i++){
printf("\\x%.2x",*(datatcp+i));
if (i%10==0)
printf("\"\n\"");
}
printf("\";\n\n\n");

for (i=0;i<lentcp;i++){
if( *(datatcp+i)<=127&&*(datatcp+i)>=20)
printf("%c",*(datatcp+i));
else
printf(".");
}
printf("\n\n*******************************************\n");
}

if((pIpheader->ip_p)==IPPROTO_UDP&&lentcp!=0){
pCount++;
dataudp=(unsigned char *) RecvBuf+sizeof(struct ipheader)+sizeof(struct udphdr);
printf("-UDP-\n");
printf("\n目的IP地址:%s\n",szDestIP);
printf("\n目的端口:%d\n",ntohs(pTcpheader->dport));
printf("UDP数据地址:%x\n",dataudp);
printf("IP头部长度:%i\n",sizeof(struct ipheader));
printf("UDP头部长度:%i\n",sizeof(struct udphdr));
printf("包的大小:%i\n",ntohs(pIpheader->ip_len));
printf("\nchar Packet%i [%i]=\"",pCount,lenudp-1);
for (i=0;i<lenudp;i++){
printf("\\x%.2x",*(dataudp+i));
if (i%10==0)
printf("\"\n\"");
}
printf("\";\n\n\n");
for (i=0;i<lenudp;i++){
if( *(dataudp+i)<=127&&*(dataudp+i)>=20)
printf("%c",*(dataudp+i));
else
printf(".");
}
printf("\n\n*******************************************\n");
}
}
}

㈢ 计算机网络课程设计

我给你发

㈣ 嗅探器是做什么用的电脑

嗅探器是一种监视网络数据运行的软件设备,协议分析器既能用于合法网络管理也能用于窃取网络信息。网络运作和维护都可以采用协议分析器:如监视网络流量、分析数据包、监视网络资源利用、执行网络安全操作规则、鉴定分析网络数据以及诊断并修复网络问题等等。非法嗅探器严重威胁网络安全性,这是因为它实质上不能进行探测行为且容易随处插入,所以网络黑客常将它作为攻击武器。
嗅探器最初由 Network General 推出,由 Network Associates 所有。最近,Network Associates 决定另开辟一个嗅探器产品单元,该单元组成一家私有企业并重新命名为 Network General,如今嗅探器已成为 Network General 公司的一种特征产品商标,由于专业人士的普遍使用,嗅探器广泛应用于所有能够捕获和分析网络流量的产品。
嗅探器设计原理
嗅探器作为一种网络通讯程序,也是通过对网卡的编程来实现网络通讯的,对网卡的编程也是使用通常的套接字(socket)方式来进行。但是,通常的套接字程序只能响应与自己硬件地址相匹配的或是以广播形式发出的数据帧,对于其他形式的数据帧比如已到达网络接口但却不是发给此地址的数据帧,网络接口在验证投递地址并非自身地址之后将不引起响应,也就是说应用程序无法收取到达的数据包。而网络嗅探器的目的恰恰在于从网卡接收所有经过它的数据包,这些数据包即可以是发给它的也可以是发往别处的。显然,要达到此目的就不能再让网卡按通常的正常模式工作,而必须将其设置为混杂模式。

㈤ 嗅探器 干什么啊

嗅探器
嗅探器是一种监视网络数据运行的软件设备,协议分析器既能用于合法网络管理也能用于窃取网络信息。网络运作和维护都可以采用协议分析器:如监视网络流量、分析数据包、监视网络资源利用、执行网络安全操作规则、鉴定分析网络数据以及诊断并修复网络问题等等。非法嗅探器严重威胁网络安全性,这是因为它实质上不能进行探测行为且容易随处插入,所以网络黑客常将它作为攻击武器。
嗅探器最初由 Network General 推出,由 Network Associates 所有。最近,Network Associates 决定另开辟一个嗅探器产品单元,该单元组成一家私有企业并重新命名为 Network General,如今嗅探器已成为 Network General 公司的一种特征产品商标,由于专业人士的普遍使用,嗅探器广泛应用于所有能够捕获和分析网络流量的产品。
嗅探器设计原理
嗅探器作为一种网络通讯程序,也是通过对网卡的编程来实现网络通讯的,对网卡的编程也是使用通常的套接字(socket)方式来进行。但是,通常的套接字程序只能响应与自己硬件地址相匹配的或是以广播形式发出的数据帧,对于其他形式的数据帧比如已到达网络接口但却不是发给此地址的数据帧,网络接口在验证投递地址并非自身地址之后将不引起响应,也就是说应用程序无法收取到达的数据包。而网络嗅探器的目的恰恰在于从网卡接收所有经过它的数据包,这些数据包即可以是发给它的也可以是发往别处的。显然,要达到此目的就不能再让网卡按通常的正常模式工作,而必须将其设置为混杂模式。

㈥ 用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结束语
通过对网络嗅探器的编写,目的使大家知道网络管理的重要性,时刻注意网络信息安全问题,做好信息的加密和解密工作。

㈦ FTP嗅探器的设计与实现

FTP嗅探器的设计与实
这样好理解,分析结果的

㈧ (网络嗅探器-sniffer)谁能帮我找关于网络嗅探器的综述文章。

嗅探器是一种利用计算机网络接口截获网络数据(目的地为其他计算机)的工具。可用于网络管理、网络协议分析以及网络安全等众多方面。在网络攻防技术中,嗅探技术是最为基础的一种技术。从攻击的角度,黑客可以利用嗅探器程序非法获取网络中传输的大量敏感信息,如帐号和口令等。而且由于嗅探器完全被动安静的工作方式以及几乎可以被安装在任何地方,对网络安全极具威胁。从防守的角度,嗅探技术是基于网络的入侵检测系统的最底层环节,是整个系统的数据来源。(通过设计并实现基于Windows环境下的网络嗅探器,掌握网络环境下的多线程编程,熟悉TCP,UDP等常用协议,全面认识网络嗅探技术,深入探讨WinPcap包截获系统和传统的BSD包截获之间的区别)。按照软件工程的思想进行设计、实现和测试。对于该嗅探器的总体架构设计,我分了5个部分,分别是最底层的数据缓存和数据访问、中间层的数据捕获、协议分析、数据过滤和最顶层的图形化用户界面。实现达到界面将会显示网络流量的去向,以及是什么网络协议,显示各字段的具体含义是什么,源IP地址和目标IP地址及端口号,传送文件的具体类型等信息。使得该程序能够较全面的分析出信息以供用户参考决策。

㈨ 网络嗅探器的设计与实现 全代码 最简单的就行 最好用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。

㈩ 求一个C++或C编写网络嗅探器的设计思路和代码

Windows下面的
#include <vector>
#include <iostream>
#include <winsock2.h>
#include <mstcpip.h>

#pragma comment( lib, "ws2_32.lib" )

using namespace std;

struct IPHeader
{
unsigned char mHeaderLengthAndVersion;
unsigned char mTypeOfService;
unsigned short mTotalLength;
unsigned short mIdentifier;
unsigned short mFragment;
unsigned char mTTL;
unsigned char mProtocolType;
unsigned short mCheckSum;
unsigned int mSourceIP;
unsigned int mDestIP;

int getHeaderLength() const
{
return mHeaderLengthAndVersion & 0xf;
}
};

struct TCPHeader
{
unsigned short mSourcePort;
unsigned short mDestPort;
unsigned int mSequence;
unsigned int mAck;
unsigned char mLengthAndReserve;
unsigned char mFlags;
unsigned short mWindow;
unsigned short mCheckSum;
unsigned short mUrgent;
};

struct UDPHeader
{
unsigned short mSourcePort;
unsigned short mDestPort;
unsigned short mLength;
unsigned short mCheckSum;
};

struct ICMPHeader
{
unsigned char mType;
unsigned char mCode;
unsigned short mCheckSum;
unsigned short mID;
unsigned short mSequence;
unsigned long mTimeStamp;
};

void ProcessIPPacket( char*, int );
void ProcessTCPPacket( char*, int );
void ProcessUDPPacket( char*, int );

void main( )
{
WSADATA data;
WSAStartup( MAKEWORD( 2, 0 ), &data );

SOCKET rawSock = socket( AF_INET, SOCK_RAW, IPPROTO_IP );

char name[ 1024 ];
gethostname( name, sizeof( name ) );

hostent* ent = gethostbyname( name );

SOCKADDR_IN addr;
addr.sin_family = AF_INET;
addr.sin_port = htons( 8888 );
memcpy( &addr.sin_addr.S_un.S_addr, ent->h_addr_list[ 0 ], ent->h_length );

bind( rawSock, (PSOCKADDR)&addr, sizeof( addr ) );

DWORD mmy;
WSAIoctl( rawSock, SIO_RCVALL, &mmy, sizeof( mmy ), &mmy, sizeof( mmy ), &mmy, NULL , NULL );

for(;;)
{
vector<char> vc( 128 * 1024 );
ProcessIPPacket( &vc[0], recv( rawSock, &vc[0], (int)vc.size(), 0) );
}
}

void ProcessIPPacket( char* packet, int size )
{
IPHeader* header = (IPHeader*)packet;

if( header->mProtocolType == IPPROTO_TCP )
ProcessTCPPacket( packet + header->getHeaderLength(), size - header->getHeaderLength() );
else if( header->mProtocolType == IPPROTO_UDP )
ProcessUDPPacket( packet + header->getHeaderLength(), size - header->getHeaderLength() );
}

void ProcessTCPPacket( char* packet, int size )
{
TCPHeader* header = (TCPHeader*)packet;
cout<<"got tcp packet"<<endl;
}

void ProcessUDPPacket( char* packet, int size )
{
UDPHeader* header = (UDPHeader*)packet;
cout<<"got udp packet"<<endl;
}
应该不用写其他的了吧,可以再加写捕捉QQ聊天的信息的东西,自己加了挖:)