报告成绩
《计算机网络》
课程设计报告
项目名称 编程实现简单的 IP 协议分析器
学
院
专业班级
学
姓
号
名
指导教师
2011 年 1 月 10 日
一、课程设计要求
1.利用原始套接字实现简单的 IP 协议分析器。
2.系统功能包括:
2.1 原始套接字与网卡绑定,并接收流经网卡的所有数据包;
2.2 对 IP 数据包进行分析以获得源 IP 地址和目的 IP 地址;
2.3 对 IP 数据报进行分析以获得其首部详细信息;
2.4 显示分析结果
3 建议使用 VC++
二、课程设计步骤与内容
首先,把这个程序的功能实现分为两部分,一部分是建立 socket,截取 IP 数据包,另
一部分是对 IP 数据进行分析,显示结果。对两个主要功能的实现详细的说明一下:
1、接收流经网卡的所有数据包
从创建 socket 开始到接收数据包的基本步骤与过程如下:
(1)// 检查 Winsock 版本号,WSAData 为 WSADATA 结构对象
WSAStartup(wVersion,&wsadata);
(2)// 创建原始套接字
ServerSock=socket(AF_INET,SOCK_RAW,IPPROTO_IP);
(3)// 设置 IP 头操作选项,其中 flag 设置为 ture,亲自对 IP 头进行处理
setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char*)&flag, sizeof(flag));
(4)// 获取本机名
gethostbyname((char*)mname);
(5)// 获取本地 IP 地址
pHost = gethostbyname((char*)LocalName));
(6)// 填充 SOCKADDR_IN 结构
myaddr.sin_addr = *(in_addr *)pHostent->h_addr_list[0];
myaddr.sin_family = AF_INET;
myaddr.sin_port = htons(8888);
(7)// 把原始套接字 ServerSock 绑定到本地网卡地址上
bind(ServerSock,(struct sockaddr *)&myaddr,sizeof(myaddr));
(8)// dwValue 为输入输出参数,为 1 时执行,0 时取消
DWORD dwValue = 1;
(9)// 设置 SOCK_RAW 为 SIO_RCVALL,以便接收所有的 IP 包。其中 SIO_RCVALL
// 的定义为: #define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
WSAIoctl(ServerSock,SIO_RCVALL,&sioarg,sizeof(sioarg),NULL,0,&dwValue,NULL,NULL);
这就是使套接字与网卡绑定,产接收流经网卡的所有数据包的 9 个基本步骤,按照这
9 个步骤可以很轻松地写绑定原始套接字和网卡,并接收数据包的功能块。
2、分析数据包
先定义 IP,TCP 的结构体:
//定义 TCP 首部结构
typedef struct _TCP{
WORD SrcPort; // 源端口
WORD DstPort; // 目的端口
DWORD SeqNum; // 顺序号
DWORD AckNum; // 确认号
BYTE DataOff; // TCP 头长
BYTE Flags; // 标志(URG、ACK 等)
WORD Window; // 窗口大小
WORD Chksum; // 校验和
WORD UrgPtr; // 紧急指针
} TCP;
//定义 ICMP 首部结构
typedef struct _ICMP{
BYTE Type;
BYTE Code;
WORD ChkSum;
// 类型
// 代码
// 检验和
} ICMP;
//定义 UDP 首部结构
typedef struct _UDP {
WORD SrcPort;
WORD DstPort;
WORD Len;
WORD ChkSum;
} UDP;
// 源端口
// 目的端口
// 长度
// 检验和
//定义 IP 首部结构
typedef struct _IP{
union{ BYTE Version; // 版本
BYTE HdrLen; // IHL
};
BYTE ServiceType; // 服务类型
WORD TotalLen; // 总长
WORD ID; // 标识
union{ WORD Flags; // 标志
WORD FragOff; // 分段偏移
};
BYTE TimeToLive; // 生命期
BYTE Protocol; // 协议
WORD HdrChksum; // 头校验和
DWORD SrcAddr; // 源地址
DWORD DstAddr; // 目的地址
BYTE Options; // 选项
} IP;
以上就是对这个 IP 数据包分析器所要分析的 IP、TCP、UDP、ICMP 协议的结构定义。接
下来,我们就可以通过相应的结构来取得数据包中相应的信息和内容。在程序中实现这些分
析功能的代码段如下:
//相关变量的声明
CString strProtocol,strSrcAddr,strSrcPort,strDstAddr,strDstPort,strSize,strData;//分别为
要输出的要素
TCP* pTCPhead;
IP *pIPhead;
ICMP *pICMPhead;
UDP *pUDPhead;
int HdrLen, totallen;
BYTE *pdata=NULL;
IP ip;
TCP tcp;
//分析处理
ip=*(IP*)buf;
//TCP 结构的指针
//IP 结构的指针
//ICMP 结构的指针
//UDP 结构的指针
//IP 结构对象
//TCP 结构对象
tcp=*(TCP*)(buf+ip.HdrLen);
//协议
strProtocol=pDlg->GetProtocolTxt(ip.Protocol);
pIPhead=(IP *)buf;
HdrLen = pIPhead->HdrLen;
HdrLen *= 4;
totallen= pIPhead->TotalLen;
//源地址
strSrcAddr=inet_ntoa(*(in_addr*)&ip.SrcAddr);
//目的地址
strDstAddr=inet_ntoa(*(in_addr*)&ip.DstAddr);
// 以下分析源端口、目的端口和长度
if (!strcmp(strProtocol,"TCP")){
//若协议为 TCP
pTCPhead=(TCP *)(buf+HdrLen);
strSrcPort.Format("%d",ntohs(pTCPhead->SrcPort));
strDstPort.Format("%d",ntohs(pTCPhead->DstPort));
HdrLen = (pTCPhead->DataOff)>>4;
HdrLen *= 4;
pdata=((BYTE *)pTCPhead)+HdrLen;
totallen -= HdrLen;
strData.Format("%s",pdata);
}
else if (!strcmp(strProtocol,"UDP")){
//若协议为 UDP
pUDPhead=(UDP *)(buf+HdrLen);
strSrcPort.Format("%d",ntohs(pTCPhead->SrcPort));
strDstPort.Format("%d",ntohs(pTCPhead->DstPort));
pdata=((BYTE *)pUDPhead)+UDP_HEAD_LEN;
totallen -= UDP_HEAD_LEN;
strData.Format("%s",pdata);
}
else if (!strcmp(strProtocol,"ICMP")){
//若协议为 ICMP
pICMPhead=(ICMP *)(buf+HdrLen);
strSrcPort = "-";
strDstPort = "-";
pdata=((BYTE *)pICMPhead)+ICMP_HEAD_LEN;
totallen -= ICMP_HEAD_LEN;
strData.Format("type:%d code:%d data:%s",pICMPhead->Type,pICMPhead->Code,pdata);
}
else{
}
strSrcPort="-";
strDstPort="-";
strData="-";
//若为其它协议
if(!strcmp(strProtocol,"TCP")||!strcmp(strProtocol,"UDP")||!strcmp(strProtocol,"ICMP"))
strSize.Format("%d",totallen);
else strSize="-";
pDlg->DisplayData(strProtocol,strSrcAddr,strSrcPort ,strDstAddr ,strDstPort ,strSize ,strData);
//DisplayData 为相应的列表框输出函数
从上述代码中可以看到,简单的分析 IP 数据包的过程也就是分析协议类别、源地址、
源端口、目的地址、目的端口、长度、数据等这些基本的要素。然后用特定的方法把这些要
素转换为相应的字符串形式,输出到列表框中。
三、软件说明
本软件的功能主要是用来接收所有经过网卡的 IP 数据包并且作简单的分析,显示出协
议类别、源地址、源端口、目的地址、目的端口、数据长度和数据等,而且仅对 TCP、UDP、
ICMP 协议有效,对于其它协议,只显示协议为?,源地址和目的地址三个要素,其余均为
-。
四、操作界面与操作演示:
本 IP 数据包分析器的操作非常简单,只有三个按钮可以点击,分别为 “开始/停止”按
钮、 ”清空”按钮和”退出”按钮。当点击开始按钮时,按钮的显示变为“停止”,分析器开始
接收所有的 IP 数据包进行分析输出;当点击清空按钮时,列表框里面显示的所有内容将全
部清空;当点击停止按钮时,分析器停止接收数据包,等待响应。点击”退出”按钮可安全退
出软件。另外,对于列表框里某些项目没有显示完整,可拖拉项目的边栏增加长度。操作演
示如下图所示:
图 1
初始界面
初始的界面如图 1 所示,当点击“开始”按钮时,如果绑定成功,并且连接上网络,接
收到数据报时,界面会显示所接收到的所有 IP 数据包的分析后的要素信息。若获取主机名
失败,或绑定网卡失败,或接收数据包失败,则会显示相应的失败提示,如图 2 所示,是
在断开网络连接的情况下得到的失败提示。若按停止,则列表框里所有的内容将不再刷新,
如图 3 所示。此时若按清空按钮,则所有内容会清除,回到图 1 的显示界面。
图 2
接收数据失败
图 3
接收数据并分析输出