计算机科学与技术学院课程设计成绩单优秀:90分~100分良好:80 分~89分中等:70~79分及格:60~69分不及格0分~59分武汉科技大学计算机科学与技术学院制表计算机科学与技术学院课程设计报告课程名称:网络编程与协议分析专班学姓业:级:号:名:指导老师:《网络编程与协议分析》课程设计报告一、课设题目:网络数据包抓取与分析软件二、课设要求:1)能抓取本地主机所在局域网子网内的所有数据包2)分析并显示所抓取数据包的IP 头部各字段的信息3)分析并显示所抓取数据包的封装在IP 数据包内的协议头部字段信息(TCP、UDP、ICMP 等)4)生成日志信息,以文本文档形式保存5)分析并显示所抓取数据包应用层协议头部字段信息(HTTP、FTP、DNS、Telnet、SMTP、POP等各种应用层协议中至少取三种)三、用到的基本概念及原理(3)Winpcap的组成和结构(4)Winpcap基本原理(5)NPF 在windows 系统中的位置(6)系统构架四、部分代码1)初始化套接字BOOL CTestDlg::SockInit(){WSADATA wsa;if(WSAStartup(MAKEWORD(2,2),&wsa)!=0){AfxMessageBox("WSAStartup fail!");}m_sock=socket(AF_INET,SOCK_RAW,0);if(m_sock==INVALID_SOCKET){AfxMessageBox("socket fail!");}SOCKADDR_IN addr;addr.sin_family=AF_INET;addr.sin_port=htons(5000);struct hostent FAR *pHostent;char FAR name[25];gethostname(name,25);pHostent = gethostbyname(name);memcpy(&addr.sin_addr.S_un.S_addr,pHostent->h_addr_list[0],pHostent->h_len);if(bind(m_sock,(SOCKADDR*)&addr,sizeof(addr))!=0){AfxMessageBox("bind fail!");}DWORD dwBytesRet;unsigned int optval = 1;int pCount=0;if(INVALID_SOCKET==(WSAIoctl(m_sock,SIO_RCVALL,&optval,sizeof(optval),NULL,0,&dwBytesRet,NULL, NULL))){AfxMessageBox("WSAIoctl Fail!");return false;}return true;}2)初始化表格BOOL CTestDlg::ListInit(){DWORD dwStyle= GetWindowLong(m_List.m_hWnd, GWL_STYLE);SetWindowLong(m_List.m_hWnd,GWL_STYLE,dwStyle|LVS_REPO);DWORD dwStyles= m_List.GetExStyle();dwStyles&=~LVS_EX_CHECKBOXES;m_List.SetExtendedStyle(dwStyles|LVS_EX_FULLROWSELECT|LVXGRIDLINES);m_List.InsertColumn(1,"版本",LVCFMT_CENTER,40,0);m_List.InsertColumn(2,"头部长度",LVCFMT_CENTER,60,1);m_List.InsertColumn(3,"服务类型",LVCFMT_CENTER,60,2);m_List.InsertColumn(4,"总长度",LVCFMT_CENTER,50,3);m_List.InsertColumn(5,"标识符",LVCFMT_CENTER,50,4);m_List.InsertColumn(6,"标志位",LVCFMT_CENTER,50,5);m_List.InsertColumn(7,"片偏移",LVCFMT_CENTER,50,6);m_List.InsertColumn(8,"生存周期",LVCFMT_CENTER,60,7);m_List.InsertColumn(9,"协议",LVCFMT_CENTER,40,8);m_List.InsertColumn(10,"首部校验和",LVCFMT_CENTER,80,9);m_List.InsertColumn(11,"源地址",LVCFMT_CENTER,100,10);m_List.InsertColumn(12,"目的IP地址",LVCFMT_CENTER,100,11);return true;}3)ip,tcp,udp,icmp头部定义struct iphead{unsigned char ip_EdiAndLen;//版本&首部长度unsigned char ip_Serve; //服务类型unsigned short int ip_Len; //总长度unsigned short int ip_Sign; //标识unsigned short int ip_MarkAndMove;//标识&片偏移unsigned char ip_Ttl; //生存时间unsigned char ip_Protocol; //上层协议unsigned short int ip_Sum;//首部校验和unsigned int ip_SoIp; //源ipunsigned int ip_DeIp; //目的ip};struct tcphead{unsigned short tcp_SoPort; //16 位的源端口unsigned short tcp_DePort; //16 位的目的端口unsigned int tcp_Seq; //32 位的序列号unsigned int tcp_Ack; //32 位的确认号unsigned char tcp_LenAndRes;//4位的首部长度和4位的保留字unsigned char tcp_Flag; //2位的保留字和6 位的标志位unsigned short tcp_Win; //16 位的窗口大小unsigned short tcp_Wum;//16 位校验和unsigned short tcp_Mov; //16 位的紧急数据偏移量};struct udphead{unsigned short udp_SoPort; //源端口unsigned short udp_DePort; //目的端口unsigned short udp_Len; //总长度unsigned short udp_Sum; //校验和};struct icmphead{unsigned char icmp_Type;//类型unsigned char icmp_Code;//代码unsigned short icmp_Sum;//16 位检验和};4)“开始”按钮事件void CTestDlg::OnStart(){//TODO:Add your control notification handler code hereDWORD code;if(!GetExitCodeThread(m_thr,&code)|| (code!= STILL_ACTIVE)){alldata*recvdata=new alldata;recvdata->lis=&m_List;recvdata->sock=m_sock;m_thr=CreateThread(NULL,0,RecvProc,(LPVOID)recvdata,0,NULL);CloseHandle(m_thr);}else{m_List.DeleteAllItems();ResumeThread(m_thr);}GetDlgItem(IDC_STOP)->EnableWindow(TRUE);GetDlgItem(IDC_START)->EnableWindow(FALSE);GetDlgItem(IDC_STOP)->SetFocus();}5)数据包抓取与初步处理DWORD WINAPI CTestDlg::RecvProc(LPVOID lpParameter){SOCKET sock=((alldata*)lpParameter)->sock;CListCtrl*lis=(CListCtrl*)(((alldata*)lpParameter)->lis);struct iphead*ih;SOCKADDR_IN tem;char RecvBuf[65535]={0};char soip[16];char deip[16];char buf[100];int i=0;while(1){if(int a=recv(sock,ddat[++count].buff,sizeof(ddat[count].buff),0)<=0) continue;ih=(struct iphead*)(ddat[count].buff);tem.sin_addr.s_addr=ih->ip_SoIp;strncpy(soip,inet_ntoa(tem.sin_addr),16);tem.sin_addr.s_addr=ih->ip_DeIp;strncpy(deip,inet_ntoa(tem.sin_addr),16);lis->InsertItem(i, "fdgfg");sprintf(buf,"%d",ih->ip_EdiAndLen>>4);lis->SetItemText(i,0,buf);sprintf(buf,"%d",ih->ip_EdiAndLen&0xf);lis->SetItemText(i,1,buf);sprintf(buf,"%d",ih->ip_Serve);lis->SetItemText(i,2,buf);sprintf(buf,"%d",ih->ip_Len);lis->SetItemText(i,3,buf);sprintf(buf,"%d",ih->ip_Sign);lis->SetItemText(i,4,buf);sprintf(buf,"%d",ih->ip_MarkAndMove>>13);lis->SetItemText(i,5,buf);sprintf(buf,"%d",ih->ip_MarkAndMove&0x1fff);lis->SetItemText(i,6,buf);sprintf(buf,"%d",ih->ip_Ttl);lis->SetItemText(i,7,buf);switch((int)ih->ip_Protocol){case1:sprintf(buf,"%s","ICMP");break;case2:sprintf(buf,"%s","IGMP");break;case6:sprintf(buf,"%s","TCP");break;case8:sprintf(buf,"%s","EGP");break;case9:sprintf(buf,"%s","IGP");break;case17:sprintf(buf,"%s","UDP");break;case41:sprintf(buf,"%s","IPv6");break;case89:sprintf(buf,"%s","OSPF");break;default:sprintf(buf,"%s","Error");}lis->SetItemText(i,8,buf);sprintf(buf,"%d",ih->ip_Sum);lis->SetItemText(i,9,buf);sprintf(buf,"%s",soip);lis->SetItemText(i,10,buf);sprintf(buf,"%s",deip);lis->SetItemText(i,11,buf);i++;Sleep(100);}return true;}6)表格单击事件void CTestDlg::OnClickList1(NMHDR* pNMHDR,LRESULT*pResult) {//TODO:Add your control notification handler code hereNM_LISTVIEW*pNMListView = (NM_LISTVIEW*)pNMHDR;CString buf;char tem[100];int i;if(pNMListView->iItem!= -1){i=pNMListView->iItem;CString strtemp;CNewDlg newdlg;iphead*iph=(iphead *)(ddat[i].buff);ttttttttt=*((tcphead*)(ddat[i].buff+(iph->ip_EdiAndLen&0xf)*4)); uuuuuuuuu=*((udphead*)(ddat[i].buff+(iph->ip_EdiAndLen&0xf)*4)); icmphead ih=*((icmphead*)(ddat[i].buff+(iph->ip_EdiAndLen&0xf)*4));switch((int)iph->ip_Protocol){case6:sprintf(tem,"源端口:%d\r\n",th.tcp_SoPort);buf+=tem;sprintf(tem,"目的端口:%d\r\n",th.tcp_DePort);buf+=tem;sprintf(tem,"序列号:%d\r\n",th.tcp_Seq);buf+=tem;sprintf(tem,"确认号:%d\r\n",th.tcp_Ack);buf+=tem;sprintf(tem,"数据偏移:%d\r\n",th.tcp_LenAndRes>>4);buf+=tem;sprintf(tem,"保留:%d\r\n",th.tcp_LenAndRes&0xf);buf+=tem;sprintf(tem,"标志:%d\r\n",th.tcp_Flag&0x3f);buf+=tem;sprintf(tem,"窗口:%d\r\n",th.tcp_Win);buf+=tem;sprintf(tem,"校验和:%d\r\n",th.tcp_Wum);buf+=tem;sprintf(tem,"紧急指针:%d\r\n",th.tcp_Mov);buf+=tem;newdlg.m_data=buf;break;case17:sprintf(tem,"源端口:%d\r\r\n",uh.udp_SoPort);buf+=tem;sprintf(tem,"目的端口:%d\r\n",uh.udp_DePort);buf+=tem;sprintf(tem,"长度:%d\r\n",uh.udp_Len);buf+=tem;sprintf(tem,"校验和:%d\r\n",uh.udp_Sum);buf+=tem;newdlg.m_data=buf;break;case1:sprintf(tem,"类型:%d\r\n",ih.icmp_Type);buf+=tem;sprintf(tem,"代码:%d\r\n",ih.icmp_Code);buf+=tem;sprintf(tem,"校验和:%d\r\n",ih.icmp_Sum);buf+=tem;newdlg.m_data=buf;break;default:AfxMessageBox("No Data!");newdlg.m_data="";}newdlg.DoModal();}*pResult = 0;}7)“停止”按钮事件void CTestDlg::OnStop(){//TODO:Add your control notification handler code hereSuspendThread(m_thr);DWORD code;CString strDate;CString strBuf;int index=m_List.GetItemCount();int i,j=0;GetExitCodeThread(m_thr,&code);if(code!= STILL_ACTIVE){AfxMessageBox("程序初始化失败!\n 请检查配置后重新运行!"); } else{CTime ttime =CTime::GetCurrentTime();strDate.Format("%d-%d-%d-",ttime.GetYear(),ttime.GetMonth(),ttime.GeDay());strDate+=ttime.Format("%H-%M-%S");ofstream outfile("history\\"+strDate + ".log");outfile<<setw(6)<<"版本"<<setw(10)<<"头部长度"<<setw(10)<<"服务类型"<<setw(8)<<"总长度"<<setw(8)<<"标识符"<<setw(8)<<"标志位"<<setw(8)<<"片偏移"<<setw(10)<<"生存周期"<<setw(6)<<"协议"<<setw(12)<<"首部校验和"<<setw(20)<<"源地址"<<setw(20)<<"目的IP地址"<<endl;while(j < index){for (i= 0;i < 12;i++){strBuf=m_List.GetItemText(j,i);switch(i){case0:outfile<<setw(6)<<strBuf;break;case1:outfile<<setw(10)<<strBuf;break;case2:outfile<<setw(10)<<strBuf;break;case3:outfile<<setw(8)<<strBuf;break;case4:outfile<<setw(8)<<strBuf;break;case5:outfile<<setw(8)<<strBuf;break;case6:outfile<<setw(8)<<strBuf;break;case7:outfile<<setw(10)<<strBuf;break;case8:outfile<<setw(6)<<strBuf;break;case9:outfile<<setw(12)<<strBuf;break;case10:outfile<<setw(20)<<strBuf;break;case11:outfile<<setw(20)<<strBuf;outfile<<endl;j++;break;}}}outfile.close();AfxMessageBox("数据已写入日志文件!");}GetDlgItem(IDC_STOP)->EnableWindow(FALSE);GetDlgItem(IDC_START)->EnableWindow(TRUE);GetDlgItem(IDC_START)->SetFocus();}五、程序截图“开始”“停止”TCPUDPICMP六、实验总结通过这次实验我学会了怎么自我去学习,从刚开始的无从下手到慢慢的自我完善。