[本篇论文由上帝论文网为您收集整理,上帝论文网http://paper.5var.com将为您整理更多优秀的免费论文,谢谢您的支持] 摘 要:本文介绍一个用C语言和网络数据包分析开发工具实现的简易网络Sniffer。 关 键 词:网络;数据包;Sniffer 1 引言 目前,已经有不少的Sniff工具软件,如Windows环境下,最富盛名的工具是Netxray和Sniffer pro,用它们在 Windows环境下抓包来分析,非常方便。在UNIX环境下如Sniffit,Snoop,Tcpdump,Dsniff 等都是比较常见的。这里介绍一个用C语言和网络数据包和分析开发工具libpcap及winpcap实现的简易网络Sniffer。 2网络嗅探器程序实现 在c环境下编程,源码如下: /* June 2nd,2002 * Project for graduation qualification By Bby Team 19 */ #include <stdio.h> #include <conio.h> //必须加路径,必须把头文件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<AdapterNum;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<AdapterNum;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-P [1] [2] 下一页
Tags:
|