姓名:张梦 学号:11054106
一、嗅探器的设计原理
嗅探器作为一种网络通讯程序,也是通过对网卡的编程来实现网络通讯的,对网卡的编程也是使用通常的套接字(socket)方式来进行。但是,通常的套接字程序只能响应与自己硬件地址相匹配的或是以广播形式发出的数据帧,对于其他形式的数据帧比如已到达网络接口但却不是发给此地址的数据帧,网络接口在验证投递地址并非自身地址之后将不引起响应,也就是说应用程序无法收取到达的数据包。而网络嗅探器的目的恰恰在于从网卡接收所有经过它的数据包,这些数据包即可以是发给它的也可以是发往别处的。显然,要达到此目的就不能再让网卡按通常的正常模式工作,而必须将其设置为混杂模式。 二、嗅探器的开发基础
1、嗅探器的实现目标
(1)实现网络嗅探器的界面。
(2)实现抓取数据包的功能。
(3)实现暂停抓取数据包功能。
(4)实现清空列表功能。
2、嗅探器的技术支持简介
(1)TCP/IP协议分析
TCP/IP 是供已连接因特网的计算机进行通信的通信协议。
TCP/IP 定义了电子设备(比如计算机)如何连入因特网,以及数据如何在它们之间传输的标准。
TCP/IP是一个四层的分层体系结构。高层为传输控制协议,它负责聚集信息或把文件拆分成更小的包。这些包通过网络传送到接收端的TCP层,接收端的TCP层把包还原为原始文
件。低层是网际协议,它处理每个包的地址部分,使这些包正确的到达目的地。网络上的网关计算机根据信息的地址来进行路由选择。即使来自同一文件的分包路由也有可能不同,但最后会在目的地汇合。直流放大器 TCP/IP使用客户端/服务器模式进行通信。TCP/IP通信是点对点的,意思是通信是网络中的一台主机与另一台主机之间的。TCP/IP与上层应用程序之间可以说是“没有国籍的”,因为每个客户请求都被看做是与上一个请求无关的。正是它们之间的“无国籍的”释放了网络路径,才是每个人都可以连续不断的使用网络。 许多用户熟悉使用TCP/IP协议的高层应用协议。
(2)数据包简介双极电凝镊
包是TCP/IP协议通信中的基本的数据单位之一,一般也叫数据包。
必须把内装产品的包装盒放到一个邮局指定的专用纸箱里,这样才能够邮寄。这里,产品包装盒相当于数据包,里面放着的产品相当于可用的数据,而专用纸箱就相当于帧,且一个帧中只有一个数据包。 “包”听起来非常抽象,那么是不是不可见的呢?通过一定技术手段,是可以感知到数据包的存在的。
通过数据包捕获软件,也可以将数据包捕获并加以分析。 ewt就是用网络嗅探器捕获数据包,可以查看捕获到的数据包的 MAC 地址、IP 地址、协议类型端口号等细节。通过分析这些数据,网管员就可以知道网络中到底有什么样的数据包在活动了。数据包的结构非常复杂,不是三言两语能够说清的,在这里主要了解一下它的关键构成就可以了,这对于理解TCP/IP 协议的通信原理是非常重要的。数据包主要由“目的IP 地址”、“源IP 地址”、“净载数据” 等部分构成。 数据包的结构与我们平常写信非常类似,目的IP 地址是说明这个数据包是要发给谁的,相当于收信人地址;源IP 地址是说明这个数据包是发自哪里的,相当于发信人地址;而净载数据相当于信件的内容。 正是因为数据包具有这样的结构,安装了 TCP/IP 协议的计算机之间才能相互通信。我们在使用基于TCP/IP 协议的网络时,网络中其实传递的就是数据包。比如说当你上网打开网页,这个简单的动作,就是你先发送数据包给网站,它接收到了之后,根据你发送的数据包的 IP 地址,返回给你网页的数据包,也就是说,网页的浏览,实际上就是数据包的交换。理解数据包,对于网络管理的网络安全具有至关重要的意义。
(3)C++语言
C++是一种编程语言,可用于编辑可执行程序,支持内嵌汇编,有C++/CLI(托管代码)和C++ISO/IEC(本机代码)两种标准。
三、嗅探器开发的意义
本次设计只是对抓取到的本机在网络中的通信数据,比如说协议类型、源、目的地址和端口、数据包的大小等加以分析!作为从事网络技术方面的人员来说,需要有效的利用、防范嗅探器,就要深入的学习、分析嗅探技术。最为重要的是,对嗅探器的学习使我们对网络通信、数据传输和网络信息安全等有了更深的认识!
四、网络嗅探器源代码
1、网络嗅探器源代码及其说明
#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);