对MAC、IP、TCP等的数据包进行抓取分析其结构,使用了pcap库
1.mac.h
#include <string> #include <iostream> #include <cstdio> class PMacHeader { private: const unsigned char *m; std::string dst, src, type, tpname; public: PMacHeader(const unsigned char *p = 0){m = p;} ~PMacHeader(){m = 0;} void ResetPt(const unsigned char * p){m = p;} unsigned short GetProtocol(); std::string& GetDstStr(); std::string& GetSrcStr(); };
#include "stdafx.h" #include "mac.h" unsigned short PMacHeader::GetProtocol() { unsigned short thetype; thetype = (unsigned short)m[12] << 8; thetype += (unsigned short)m[12+1]; return thetype; } std::string& PMacHeader::GetDstStr() { char dstBuf[6*3+1]; std::sprintf(dstBuf, "%.2x %.2x %.2x %.2x %.2x %.2x ", m[0], m[1], m[2], m[3], m[4], m[5]); dst = dstBuf; return dst; } std::string& PMacHeader::GetSrcStr() { char srcBuf[6*3+1]; std::sprintf(srcBuf,"%.2x %.2x %.2x %.2x %.2x %.2x ", m[6], m[7], m[8], m[9], m[10], m[11]); src = srcBuf; return src; }3.ip.h
#include <string> #include <iostream> #include <cstdio> class PIpHeader { private: const unsigned char *p; std::string src, dst; public: PIpHeader(const unsigned char *pt = 0):p(pt){} ~PIpHeader(){p = 0;} void Reset(const unsigned char *pt){ p = pt;} short GetVesion();//取IP的版本 short GetHeaderLen();//取IP报头的长度 (1单位/4字节) short GetServer();//服务 unsigned short GetTotalLen();//总长度 unsigned short GetID();//标识 short GetFlag(); short GetEx();//偏移量 short GetTTL(); unsigned short GetProtocol(); unsigned short GetCheck();//校验码 std::string& GetSrcStr();//源IP的字符串形式 std::string& GetDstStr();//目标IP的字符串形式 };4.ip.cpp
#include "stdafx.h" #include "IP.h" short PIpHeader::GetVesion() { return p[0] >> 4;} short PIpHeader::GetHeaderLen() { return p[0] & 0x0f;} short PIpHeader::GetServer() { return p[1];} unsigned short PIpHeader::GetTotalLen() { unsigned short length = (unsigned short)p[2] << 8; length += (unsigned short)p[3]; return length; } unsigned short PIpHeader::GetID() { unsigned short id = (unsigned short)p[4] << 8; id += (unsigned short)p[5]; return id; } short PIpHeader::GetFlag() { return p[6] >> 5; } short PIpHeader::GetEx() { unsigned short ex = ((unsigned short)p[6] & 0x1f) << 8; ex += (unsigned short)p[7]; return ex; } short PIpHeader::GetTTL() { return (unsigned short)p[8]; } unsigned short PIpHeader::GetProtocol() { return (unsigned short)p[9]; } unsigned short PIpHeader::GetCheck() { unsigned short check = (unsigned short)p[10] << 8; check += (unsigned short)p[11]; return check; } std::string& PIpHeader::GetSrcStr() { char srcbuf[16+1]; std::sprintf(srcbuf, "%d.%d.%d.%d", p[12], p[13], p[14], p[15]); src = srcbuf; return src; } std::string& PIpHeader::GetDstStr() { char dstbuf[16+1]; std::sprintf(dstbuf, "%d.%d.%d.%d", p[16], p[17], p[18], p[19]); dst = dstbuf; return dst; }
#include "stdafx.h" #include "ProtocolType.h" const unsigned char* GetMacPointer(const unsigned char *p) { return p; } const unsigned char* GetArpPointer(const unsigned char *p) { return p+14; } const unsigned char* GetIpPointer(const unsigned char *p) { return p+14; } const unsigned char* GetTcpPointer(const unsigned char *p) { return GetIpPointer(p)+(((unsigned short)(GetIpPointer(p)[0]) & 0x0f)*4); }
bool CPCDlgDlg::InitAdapter(void) { CString adapter; char errBuf[PCAP_ERRBUF_SIZE]; TCHAR t_errBuf[PCAP_ERRBUF_SIZE]; if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errBuf) == -1) { MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, errBuf, sizeof(errBuf), t_errBuf, sizeof(t_errBuf)); adapter.Format(_T("Error in pcap_findalldevs:%s\n"), t_errBuf); ((CListBox*)GetDlgItem(IDC_LIST_ADAPTER))->AddString(adapter); return false; } else { for (dev = alldevs; dev; dev = dev->next) { DWORD dwNameNum = MultiByteToWideChar (CP_ACP, 0, dev->name, -1, NULL, 0); DWORD dwDesNum = MultiByteToWideChar (CP_ACP, 0, dev->description, -1, NULL, 0); TCHAR* dev_name = new TCHAR[dwNameNum]; TCHAR* dev_des = new TCHAR[dwDesNum]; MultiByteToWideChar(CP_ACP, 0, dev->name, -1, dev_name, dwNameNum); MultiByteToWideChar(CP_ACP, 0, dev->description, -1, dev_des, dwDesNum); adapter.Format(_T("%s(%s)"),dev_name, dev_des); delete [] dev_name; delete [] dev_des; ((CListBox*)GetDlgItem(IDC_LIST_ADAPTER))->AddString(adapter); } } return true; } CPCDlgDlg::~CPCDlgDlg(void) { pcap_freealldevs(alldevs); } void CPCDlgDlg::OnBnClickedButtonCatch() { int select = 0; select = ((CListBox*)GetDlgItem(IDC_LIST_ADAPTER))->GetCurSel(); dev = alldevs; for (int i = 0; i < select; dev = dev->next, ++i); char errBuf[PCAP_ERRBUF_SIZE]; TCHAR t_errBuf[PCAP_ERRBUF_SIZE]; pcap_t *adhandle; if ((adhandle = pcap_open(dev->name, 65536, PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, errBuf )) == NULL) { CString errStr; MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, errBuf, sizeof(errBuf), t_errBuf, sizeof(t_errBuf)); errStr.Format(_T("Error in pcap_findalldevs:%s\n"), t_errBuf); ((CListBox*)GetDlgItem(IDC_LIST_ADAPTER))->AddString(errStr); return; } if (!isCatch) { isCatch = true; HCatchThread = AfxBeginThread(CatchPacket, adhandle); } } void CPCDlgDlg::InsertPacketToList(pcap_t *adhandle, pcap_pkthdr *header, const u_char *pkt_data) { static CString strPacketInfo; std::string total_info_ascii_str; // using std::cout; using std::endl; //总体信息 static struct tm ltime; static time_t local_tv_sec; static char timestr[16]; local_tv_sec = header->ts.tv_sec; localtime_s(<ime, &local_tv_sec); strftime(timestr, sizeof(timestr), "%H:%M:%S", <ime); static char Buffer[150]; sprintf(Buffer, "时间:%s,%.6d 总长度:%d\n", timestr, header->ts.tv_usec, header->len); total_info_ascii_str = Buffer; //输出MAC首部主要内容 static PMacHeader pmac; pmac.ResetPt(GetMacPointer(pkt_data)); total_info_ascii_str += " MAC首部---"; total_info_ascii_str += "目的地址:" + pmac.GetDstStr() + "源地址:"+pmac.GetSrcStr(); unsigned short protocol_type = pmac.GetProtocol(); //输出ARP首部主要内容 if (protocol_type == PROTOCOL_ARP) { static PArpHeader parp; parp.Reset(GetArpPointer(pkt_data)); total_info_ascii_str += " ARP首部---"; total_info_ascii_str += "谁是:" + parp.GetDstIPStr() + "请告诉:" + parp.GetSrcIPStr(); DWORD dwNum = MultiByteToWideChar (CP_ACP, 0, total_info_ascii_str.c_str(), -1, NULL, 0); TCHAR* packet_info = new TCHAR[dwNum]; MultiByteToWideChar(CP_ACP, 0, total_info_ascii_str.c_str(), -1, packet_info, dwNum); strPacketInfo.Format(_T("%s"), packet_info); delete [] packet_info; ((CListBox*)GetDlgItem(IDC_LIST_PACKET))->AddString(strPacketInfo); return; } //输出IP首部主要内容 if (protocol_type == PROTOCOL_IP) { static PIpHeader pip; pip.Reset(GetIpPointer(pkt_data)); sprintf(Buffer, " IP首部---版本号:%d 首部长度:%d IP数据报总长度:%d TTL:%d目的IP:%s 源IP:%s ", pip.GetVesion(),pip.GetHeaderLen(),pip.GetTotalLen(), pip.GetTTL(), pip.GetDstStr().c_str(),pip.GetSrcStr().c_str()); total_info_ascii_str += Buffer; protocol_type = pip.GetProtocol(); //输出TCP首部主要内容 if (protocol_type == PROTOCOL_TCP) { static PTcpHeader ptcp; ptcp.Reset(GetTcpPointer(pkt_data)); sprintf(Buffer, " TCP首部---目的端口:%d 源端口:%d 确认号:%ud 序号:%ud SYN:%d ACK:%d 窗口大小:%d" , ptcp.GetDstPort(), ptcp.GetSrcPort(), ptcp.GetACKNum(), ptcp.GetNum(), ptcp.GetSYN(), ptcp.GetACK(), ptcp.GetWinSize()); total_info_ascii_str += Buffer; } } total_info_ascii_str += " 未知协议"; DWORD dwNum = MultiByteToWideChar (CP_ACP, 0, total_info_ascii_str.c_str(), -1, NULL, 0); TCHAR* packet_info = new TCHAR[dwNum]; MultiByteToWideChar(CP_ACP, 0, total_info_ascii_str.c_str(), -1, packet_info, dwNum); strPacketInfo.Format(_T("%s"), packet_info); delete [] packet_info; ((CListBox*)GetDlgItem(IDC_LIST_PACKET))->AddString(strPacketInfo); return; } UINT CPCDlgDlg::CatchPacket(LPVOID pParam) { struct pcap_pkthdr *header; const u_char *pkt_data; int res; while ((res = pcap_next_ex((pcap_t*)pParam, &header, &pkt_data)) >= 0) { if (res == 0) { continue; } pDlgDlg->InsertPacketToList((pcap_t*)pParam, header, pkt_data); if (!pDlgDlg->isCatch) { AfxEndThread(1); } } if (res == -1) { return 1; } return 0; } void CPCDlgDlg::OnBnClickedButtonStop() { // TODO: 在此添加控件通知处理程序代码 if(isCatch) { isCatch = false; } } void CPCDlgDlg::OnBnClickedButtonClean() { // TODO: 在此添加控件通知处理程序代码 ((CListBox*)GetDlgItem(IDC_LIST_PACKET))->ResetContent(); }