局域网截包程序设计

3.1 课程设计目的
目前的局域网基本上都采用以广播为技术基础的以太网,任何两个节点之间的通信数据包,不仅为这两个节点的网卡所接收,也同时为处在同一以太网上的任何一个节点的网卡所截取。因此,黑客只要接入以太网上的任一节点进行侦听,就可以捕获发生在这个以太网上的所有数据包,对其进行解包分析,从而窃取关键信息,这就是以太网所固有的安全隐患。网上主要的免费黑客攻击工具如SATAN、ISS、NETCAT等均将以太网侦听作为基本的手段。
本实验实现一个局域网截包程序,目的在于使学生能更好地理解网络的工作机制(包括封包机制、协议分析等),该实验是对《计算机网络》课程一个有益的补充。
3.2 课程设计要求
在一个局域网环境中,用C 语言实现下面的基本功能:
1、 确定截包方法:包括RAW 模式SOCKET、PACKET32及直接作为驱动程序挂在NDIS上;
2、 要求截获以下包的类型并分析:以太网帧格式、IP包、ICMP包、TCP报文段、UDP报文等相关字段进行描述。
3.3 实验步骤和注意事项
1、 熟悉RAW模式的SOCKET编程;
2、 熟悉PACKET32的工作机制;
3、 熟悉WINDOWS 2000环境下NDIS驱动程序的编写方法;
4、 编写基于上述某一机制的局域网截包的实现程序;
5、 在模拟实现环境下调试并运行自己编写的协议实现程序;
6、 如出现异常情况,在实验报告中记录并分析可能的原因。

谁帮帮我,帮我编下

#define RCVALL_ON 1
#define MAX_ADDR_LEN 16 //点分十进制地址的最大长度
#define MAX_PROTO_TEXT_LEN 16 //子协议名称(如"TCP")最大长度
#define WINSOCK_VERSION MAKEWORD(2, 2)
#pragma comment(lib, "Ws2_32.lib")
#include <stdio.h>
#include <winsock2.h>
#include <mstcpip.h>
#include <conio.h>
typedef struct iphdr //定义IP首部
{
unsigned char h_lenver; //4位首部长度+4位IP版本号
unsigned char tos; //8位服务类型TOS
unsigned short total_len; //16位总长度(字节)
unsigned short ident; //16位标识
unsigned short frag_and_flags; //3位标志位
unsigned char ttl; //8位生存时间 TTL
unsigned char proto; //8位协议 (TCP, UDP 或其他)
unsigned short checksum; //16位IP首部校验和
unsigned int sourceIP; //32位源IP地址
unsigned int destIP; //32位目的IP地址
}IPHeader;
typedef struct _tcphdr //定义TCP首部
{
USHORT th_sport; //16位源端口
USHORT th_dport; //16位目的端口
unsigned int th_seq; //32位序列号
unsigned int th_ack; //32位确认号
unsigned char th_lenres; //4位首部长度/6位保留字
unsigned char th_flag; //6位标志位
USHORT th_win; //16位窗口大小
USHORT th_sum; //16位校验和
USHORT th_urp; //16位紧急数据偏移量
}TCP_HEADER;
typedef struct _udphdr //定义UDP首部
{
unsigned short uh_sport; //16位源端口
unsigned short uh_dport; //16位目的端口
unsigned short uh_len; //16位长度
unsigned short uh_sum; //16位校验和
}UDP_HEADER;
typedef struct _icmphdr //定义ICMP首部
{
BYTE i_type; //8位类型
BYTE i_code; //8位代码
USHORT i_cksum; //16位校验和
USHORT i_id; //识别号(一般用进程号作为识别号)
USHORT i_seq; //报文序列号
ULONG timestamp; //时间戳
}ICMP_HEADER;

int iTTL,iLEN,iBYTES;
char szSourceIP[MAX_ADDR_LEN], szDestIP[MAX_ADDR_LEN];
int iSourcePort,iDestPort;
int fflag=0;//file flag
#define PACKAGE_SIZE sizeof(IPHeader)+1000
void HandleError(char *func);
//functions
int DecodeTcpPack(char *, int,FILE *); //TCP解包函数
int DecodeUdpPack(char *, int,FILE *); //UDP解包函数
int DecodeIcmpPack(char *, int,FILE *); //ICMP解包函数
//MAIN
int main(int argc, char *argv[])
{
sockaddr_in saSource,saDest;
WSAData wsaData;
char buf[PACKAGE_SIZE];
WSAStartup(WINSOCK_VERSION, &wsaData);
SOCKET sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
if(sock == SOCKET_ERROR)
{
HandleError("socket");
WSACleanup();
return -1;
}
//获取本机IP地址
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
//addr.sin_addr.S_un.S_addr = inet_addr("192.168.1.101");
char name[256];
PHOSTENT hostinfo;
if( gethostname ( name, sizeof(name)) == 0)
{
if((hostinfo = gethostbyname(name)) != NULL)
{
memcpy(&(addr.sin_addr.S_un.S_addr) , (struct in_addr *)*hostinfo->h_addr_list , sizeof((struct in_addr *)*hostinfo->h_addr_list ));
}
}
addr.sin_family = AF_INET;
if(bind(sock, (struct sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR)//bind
{
HandleError("bind");
}
//设置SOCK_RAW为SIO_RCVALL,以便接收所有的IP包
int on = RCVALL_ON;
DWORD num;
if(WSAIoctl(sock, SIO_RCVALL, &on, sizeof(on), NULL, 0, &num, NULL, NULL) == SOCKET_ERROR)
{
HandleError("wsaIoctl set");
}
struct sockaddr_in from;
int fromlen;
int size;
FILE *fp;
if((fp=fopen("log.txt","w+"))==NULL)
{
printf("open file errer,can't save list to file");
fflag=1;
}
//侦听IP报文
while(!kbhit())
{
memset(buf, 0, sizeof(num));
memset(&from, 0, sizeof(from));
fromlen = sizeof(from);
size=recvfrom(sock, buf, PACKAGE_SIZE, 0, (struct sockaddr*)&from, &fromlen);
if(size == SOCKET_ERROR)
{
if(WSAGetLastError() == WSAEMSGSIZE)
{
HandleError("recvfrom");
continue;
}
}
IPHeader *iph=(IPHeader *)buf;
/**/
//源地址
saSource.sin_addr.s_addr = iph->sourceIP;
strncpy(szSourceIP, inet_ntoa(saSource.sin_addr), MAX_ADDR_LEN);
//目的地址
saDest.sin_addr.s_addr = iph->destIP;
strncpy(szDestIP, inet_ntoa(saDest.sin_addr), MAX_ADDR_LEN);
iTTL = iph->ttl;
//计算IP首部的长度
int IpHeadLen = 4 * (iph->h_lenver & 0xf);
//根据协议类型分别调用相应的函数

switch(iph->proto)
{
case IPPROTO_ICMP:
DecodeIcmpPack(buf+IpHeadLen, size,fp);
break;
case IPPROTO_IGMP:
printf("IGMP ");
printf("%15s: ->%15s: ", szSourceIP, szDestIP);
printf("%d",size);
printf("%s/n", buf);
break;
case IPPROTO_TCP:
DecodeTcpPack((buf+IpHeadLen),size,fp);
break;
case IPPROTO_UDP:
DecodeUdpPack(buf+IpHeadLen, size,fp);
break;
default:
printf("unknown datagram from %s/n", inet_ntoa(from.sin_addr));
printf("%s/n", buf);
break;
}//end switch

Sleep(200);
}//end while
fclose(fp);
closesocket(sock);
WSACleanup();
printf("Stopped!/n");
getch();
return 0;
}//end of main

//TCP解包程序
int DecodeTcpPack(char * TcpBuf, int iBufSize,FILE *fp)
{
unsigned char FlagMask;FlagMask = 1;
int i;
TCP_HEADER *tcph;

tcph = (TCP_HEADER*)TcpBuf;
//计算TCP首部长度
int TcpHeadLen = tcph->th_lenres>>4;
TcpHeadLen *= sizeof(unsigned long);
char *TcpData=TcpBuf+TcpHeadLen;
iSourcePort = ntohs(tcph->th_sport);
iDestPort = ntohs(tcph->th_dport);

//输出
printf("TCP ");
printf("%15s:%5d ->%15s:%5d ", szSourceIP, iSourcePort, szDestIP, iDestPort);
printf("TTL=%3d ", iTTL);
if(fflag==1)

//判断TCP标志位
for( i=0; i<6; i++ )
{
if((tcph->th_flag) & FlagMask)
printf("1");
else printf("0");
FlagMask=FlagMask<<1;
}
printf(" bytes=%4d", iBufSize);
printf("/n");
if(fflag=1)//写入文件
fprintf(fp,"TCP %15s:%5d ->%15s:%5d TTL=%3d ------ bytes=%4d/n"
,szSourceIP, iSourcePort, szDestIP, iDestPort, iTTL,iBufSize);
return 0;
}
//UDP解包程序
int DecodeUdpPack(char * UdpBuf, int iBufSize,FILE *fp)
{
UDP_HEADER *udph;
udph = (UDP_HEADER*)UdpBuf;
iSourcePort = ntohs(udph->uh_sport);
iDestPort = ntohs(udph->uh_dport);
//输出
printf("UDP ");
printf("%15s:%5d ->%15s:%5d ", szSourceIP, iSourcePort, szDestIP, iDestPort);
printf("TTL=%3d ", iTTL);
printf("Len=%4d ", ntohs(udph->uh_len));
printf("bytes=%4d", iBufSize);
printf("/n");
if(fflag=1)//写入文件
fprintf(fp,"UDP %15s:%5d ->%15s:%5d TTL=%3d Len=%4d bytes=%4d/n"
,szSourceIP, iSourcePort, szDestIP, iDestPort, iTTL, ntohs(udph->uh_len), iBufSize);
return 0;
}
//ICMP解包程序
int DecodeIcmpPack(char * IcmpBuf, int iBufSize,FILE *fp)
{
ICMP_HEADER * icmph;
icmph = (ICMP_HEADER * )IcmpBuf;
int iIcmpType = icmph->i_type;
int iIcmpCode = icmph->i_code;
//输出
printf("ICMP ");
printf("%15s ->%15s ", szSourceIP, szDestIP);
printf("TTL=%3d ", iTTL);
printf("Type%2d,%d ",iIcmpType,iIcmpCode);
printf("bytes=%4d", iBufSize);
printf("/n");
if(fflag=1)//写入文件
fprintf(fp,"ICMP %15s ->%15s TTL=%3d Type%2d,%d bytes=%4d"
, szSourceIP, szDestIP, iTTL,iIcmpType,iIcmpCode, iBufSize);
return 0;
}
void HandleError(char *func)
{
char info[65]= {0};
_snprintf(info, 64, "%s: %d/n", func, WSAGetLastError());
printf(info);
}
温馨提示:答案为网友推荐,仅供参考
第1个回答  2008-01-08
这个让人头疼啊,还不如直接去下载个软件实现了。。。
要是非要手动的编写的话,恐怕问题要石沉大海了!本回答被网友采纳
第2个回答  2008-01-08
你才给10分,谁会帮你啊?