SniffDlg.h : 头文件
#pragma once
#include "afxcmn.h"
#include "afxwin.h"
typedef struct _PROTN2T
{
int proto;
char *pprototext;
}PROTN2T;
#define PROTO_NUM 11
typedef struct _IPHEADER {
unsigned char header_len : 4;
unsigned char version : 4;
unsigned char tos;
unsigned short total_len;
unsigned short ident;
unsigned short flags;
unsigned char ttl;
unsigned char proto;
unsigned short checksum;
unsigned int sourceIP;
unsigned int destIP;
}IPHEADER;
#define UDP_HEAD_LEN 8
#define PSEUDO_HEAD_LEN 12
#define ICMP_HEAD_LEN 4
struct TCPPacketHead {
WORD SourPort;
WORD DestPort;
DWORD SeqNo;
DWORD AckNo;
BYTE HLen;
BYTE Flag;
WORD WndSize;
WORD ChkSum;
WORD UrgPtr;
};
struct ICMPPacketHead {
BYTE Type;
BYTE Code;
WORD ChkSum;
};
struct UDPPacketHead {
WORD SourPort;
WORD DestPort;
WORD Len;
WORD ChkSum;
};
class CSniffDlg : public CDialogEx
{
public:
CSniffDlg(CWnd* pParent = NULL);
void AddData(CString s0, CString s1, CString s2, CString s3, CString s4, CString s5, CString s6);
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_SNIFF_DIALOG };
#endif
CListCtrl m_ctrList;
CButton m_start;
protected:
virtual void DoDataExchange(CDataExchange* pDX);
protected:
HICON m_hIcon;
DWORD m_ipsource;
DWORD m_iphostsource;
DWORD m_iphost;
DWORD m_ipcheckedhost;
SOCKET m_s;
DWORD m_threadID;
BOOL m_Multihomed;
BOOL m_Local;
CDWordArray m_IPArr;
friend UINT threadFunc(LPVOID p);
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedLookup();
afx_msg void OnBnClickedOk();
private:
CComboBox m_cAdapter;
public:
afx_msg void OnSelendokComboAdapter();
};
SniffDlg.cpp : 实现文件
#include "stdafx.h"
#include "Sniff.h"
#include "SniffDlg.h"
#include "afxdialogex.h"
#pragma comment(lib, "IPHLPAPI.lib")
#include "Iphlpapi.h"
#include "mstcpip.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
PROTN2T aOfProto[PROTO_NUM + 1] =
{
{ IPPROTO_IP , "IP" },
{ IPPROTO_ICMP , "ICMP" },
{ IPPROTO_IGMP , "IGMP" },
{ IPPROTO_GGP , "GGP" },
{ IPPROTO_TCP , "TCP" },
{ IPPROTO_PUP , "PUP" },
{ IPPROTO_UDP , "UDP" },
{ IPPROTO_IDP , "IDP" },
{ IPPROTO_ND , "NP" },
{ IPPROTO_RAW , "RAW" },
{ IPPROTO_MAX , "MAX" },
{ NULL , "" }
};
char *get_proto_name(unsigned char proto)
{
BOOL bFound = FALSE;
int i;
for (i = 0; i < PROTO_NUM; i++)
{
if (aOfProto[i].proto == proto)
{
bFound = TRUE;
break;
}
}
if (bFound)
return aOfProto[i].pprototext;
return aOfProto[PROTO_NUM].pprototext;
}
class CAboutDlg : public CDialogEx
{
public:
CAboutDlg();
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_ABOUTBOX };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX);
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
CSniffDlg::CSniffDlg(CWnd* pParent )
: CDialogEx(IDD_SNIFF_DIALOG, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_threadID = 0;
m_Multihomed = FALSE;
m_Local = TRUE;
}
void CSniffDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST, m_ctrList);
DDX_Control(pDX, IDC_LOOKUP, m_start);
DDX_Control(pDX, IDC_COMBO_ADAPTER, m_cAdapter);
}
BEGIN_MESSAGE_MAP(CSniffDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_LOOKUP, &CSniffDlg::OnBnClickedLookup)
ON_BN_CLICKED(IDOK, &CSniffDlg::OnBnClickedOk)
ON_CBN_SELENDOK(IDC_COMBO_ADAPTER, &CSniffDlg::OnSelendokComboAdapter)
END_MESSAGE_MAP()
BOOL CSniffDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
SetIcon(m_hIcon, TRUE);
SetIcon(m_hIcon, FALSE);
CHAR szHostName[128] = { 0 };
HOSTENT* pHost = NULL;
CHAR* pszIp = NULL;
int iNum = 0;
if (AfxSocketInit(NULL) == FALSE)
{
AfxMessageBox("Sorry, socket load error!");
return FALSE;
}
if (gethostname(szHostName, 128) == 0)
{
pHost = gethostbyname(szHostName);
if (pHost != NULL)
{
for (pszIp = *pHost->h_addr_list;pszIp != NULL;pszIp = *(pHost->h_addr_list + iNum))
{
m_cAdapter.InsertString(iNum++, inet_ntoa(*(in_addr*)pszIp));
}
pszIp = inet_ntoa(*(in_addr*)pHost->h_addr_list[0]);
m_ipsource = inet_addr(pszIp);
m_cAdapter.SetCurSel(0);
}
else
{
AfxMessageBox("pHost = NULL!");
}
}
else
{
AfxMessageBox("can't find host name!");
}
DWORD dwStyle = GetWindowLong(m_ctrList.GetSafeHwnd(), GWL_STYLE);
dwStyle &= ~LVS_TYPEMASK;
dwStyle |= LVS_REPORT;
SetWindowLong(m_ctrList.GetSafeHwnd(), GWL_STYLE, dwStyle);
m_ctrList.InsertColumn(0, "数据", LVCFMT_LEFT, 525);
m_ctrList.InsertColumn(0, "大小", LVCFMT_LEFT, 80);
m_ctrList.InsertColumn(0, "端口", LVCFMT_LEFT, 40);
m_ctrList.InsertColumn(0, "目的地址", LVCFMT_LEFT, 100);
m_ctrList.InsertColumn(0, "端口", LVCFMT_LEFT, 40);
m_ctrList.InsertColumn(0, "源地址", LVCFMT_LEFT, 100);
m_ctrList.InsertColumn(0, "协议", LVCFMT_LEFT, 50);
::SendMessage(m_ctrList.m_hWnd, LVM_SETEXTENDEDLISTVIEWSTYLE,
LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT);
DWORD dwSize = 0;
GetIpAddrTable(NULL, &dwSize, FALSE);
PMIB_IPADDRTABLE pIpAddrTable = (PMIB_IPADDRTABLE)new BYTE[dwSize];
if (pIpAddrTable)
{
if (GetIpAddrTable((PMIB_IPADDRTABLE)pIpAddrTable,
&dwSize,
FALSE
) == NO_ERROR)
{
if (pIpAddrTable->dwNumEntries > 2)
{
m_Multihomed = TRUE;
char szIP[16];
for (int i = 0; i < (int)pIpAddrTable->dwNumEntries; i++)
{
in_addr ina;
ina.S_un.S_addr = pIpAddrTable->table[i].dwAddr;
char *pIP = inet_ntoa(ina);
strcpy(szIP, pIP);
if (stricmp(szIP, "127.0.0.1"))
m_IPArr.Add(pIpAddrTable->table[i].dwAddr);
}
}
}
delete[] pIpAddrTable;
}
return TRUE;
}
void CSniffDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}
void CSniffDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this);
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
HCURSOR CSniffDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
UINT threadFunc(LPVOID p)
{
CSniffDlg *pDlg = static_cast<CSniffDlg *>(p);
char buf[1000], *bufwork;
MSG msg;
int iRet;
DWORD dwErr;
char *pSource, *pDest;
IPHEADER *pIpHeader;
in_addr ina;
char szSource[16], szDest[16], szErr[50];
char *pLastBuf = NULL;
int HdrLen, totallen;
WORD sourport, destport;
struct TCPPacketHead *pTCPHead;
struct ICMPPacketHead *pICMPHead;
struct UDPPacketHead *pUDPHead;
BYTE *pdata = NULL;
PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
pDlg->m_threadID = GetCurrentThreadId();
while (TRUE)
{
if (PeekMessage(&msg, 0, WM_CLOSE, WM_CLOSE, PM_NOREMOVE))
{
closesocket(pDlg->m_s);
pDlg->m_threadID = 0;
pDlg->m_start.EnableWindow(TRUE);
break;
}
memset(buf, 0, sizeof(buf));
iRet = recv(pDlg->m_s, buf, sizeof(buf), 0);
if (iRet == SOCKET_ERROR)
{
dwErr = WSAGetLastError();
sprintf(szErr, "Error recv() = %ld ", dwErr);
continue;
}
else
{
if (*buf)
{
bufwork = buf;
pIpHeader = (IPHEADER *)bufwork;
WORD iLen = ntohs(pIpHeader->total_len);
while (TRUE)
{
if (iLen <= iRet)
{
ina.S_un.S_addr = pIpHeader->sourceIP;
pSource = inet_ntoa(ina);
strcpy(szSource, pSource);
ina.S_un.S_addr = pIpHeader->destIP;
pDest = inet_ntoa(ina);
strcpy(szDest, pDest);
CString str, strProto, strSourPort, strDestPort, strData, strSize;
strProto = get_proto_name(pIpHeader->proto);
HdrLen = pIpHeader->header_len & 0xf;
HdrLen *= 4;
totallen = ntohs(pIpHeader->total_len);
totallen -= HdrLen;
switch (pIpHeader->proto)
{
case IPPROTO_ICMP:
{
pICMPHead = (struct ICMPPacketHead *)(buf + HdrLen);
strSourPort = "-";
strDestPort = "-";
pdata = ((BYTE *)pICMPHead) + ICMP_HEAD_LEN;
totallen -= ICMP_HEAD_LEN;
break;
}
case IPPROTO_TCP:
{
pTCPHead = (struct TCPPacketHead *)(buf + HdrLen);
sourport = ntohs(pTCPHead->SourPort);
destport = ntohs(pTCPHead->DestPort);
strSourPort.Format("%d", sourport);
strDestPort.Format("%d", destport);
HdrLen = (pTCPHead->HLen) >> 4;
HdrLen *= 4;
pdata = ((BYTE *)pTCPHead) + HdrLen;
totallen -= HdrLen;
break;
}
case IPPROTO_UDP:
{
pUDPHead = (struct UDPPacketHead *)(buf + HdrLen);
sourport = ntohs(pUDPHead->SourPort);
destport = ntohs(pUDPHead->DestPort);
strSourPort.Format("%d", sourport);
strDestPort.Format("%d", destport);
pdata = ((BYTE *)pUDPHead) + UDP_HEAD_LEN;
totallen -= UDP_HEAD_LEN;
break;
}
}
if (pIpHeader->proto == IPPROTO_ICMP)
strData.Format("type:%d code:%d data:%s", pICMPHead->Type, pICMPHead->Code, pdata);
else strData.Format(" %s", pdata);
strSize.Format("%d", totallen);
pDlg->AddData(strProto, szSource, strSourPort, szDest, strDestPort, strSize, strData);
if (iLen < iRet)
{
iRet -= iLen;
bufwork += iLen;
pIpHeader = (IPHEADER *)bufwork;
}
else
break;
}
else
{
int iLast = iLen - iRet;
pLastBuf = new char[iLen];
int iReaden = iRet;
memcpy(pLastBuf, bufwork, iReaden);
iRet = recv(pDlg->m_s, pLastBuf + iReaden, iLast, 0);
if (iRet == SOCKET_ERROR)
{
dwErr = WSAGetLastError();
sprintf(szErr, "Error recv() = %ld ", dwErr);
break;
}
else
{
bufwork = pLastBuf;
pIpHeader = (IPHEADER *)bufwork;
if (iRet == iLast)
iRet = iLen;
else
{
iReaden += iRet;
iLast -= iRet;
while (TRUE)
{
iRet = recv(pDlg->m_s, pLastBuf + iReaden, iLast, 0);
if (iRet == SOCKET_ERROR)
{
dwErr = WSAGetLastError();
sprintf(szErr, "Error recv() = %ld ", dwErr);
break;
}
else
{
iReaden += iRet;
iLast -= iRet;
if (iLast <= 0)
{
break;
}
}
}
}
}
}
}
if (pLastBuf)
delete[] pLastBuf;
}
else
{
AfxMessageBox("No data on network");
continue;
}
}
}
return TRUE;
}
void CSniffDlg::OnBnClickedLookup()
{
char szErr[50], szHostName[MAX_PATH];
DWORD dwErr;
SOCKADDR_IN sa;
gethostname(szHostName, sizeof(szHostName));
m_iphostsource = m_ipsource;
m_ipcheckedhost = ntohl(m_iphost);
if (0 == m_threadID)
{
SetDlgItemText(IDC_LOOKUP, "停止查看!");
m_cAdapter.EnableWindow(false);
}
else
{
if (m_threadID)
{
PostThreadMessage(m_threadID, WM_CLOSE, 0, 0);
SetDlgItemText(IDC_LOOKUP, "开始查看!");
m_start.EnableWindow(FALSE);
m_cAdapter.EnableWindow(true);
}
return;
}
DWORD dwBufferLen[10];
DWORD dwBufferInLen = 1;
DWORD dwBytesReturned = 0;
m_s = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
if (INVALID_SOCKET == m_s)
{
dwErr = WSAGetLastError();
sprintf(szErr, "Error socket() = %ld ", dwErr);
AfxMessageBox(szErr);
closesocket(m_s);
return;
}
int rcvtimeo = 5000;
if (setsockopt(m_s, SOL_SOCKET, SO_RCVTIMEO, (const char *)&rcvtimeo, sizeof(rcvtimeo)) == SOCKET_ERROR)
{
dwErr = WSAGetLastError();
sprintf(szErr, "Error WSAIoctl = %ld ", dwErr);
AfxMessageBox(szErr);
closesocket(m_s);
return;
}
sa.sin_family = AF_INET;
sa.sin_port = htons(7000);
sa.sin_addr.s_addr = m_iphostsource;
if (bind(m_s, (PSOCKADDR)&sa, sizeof(sa)) == SOCKET_ERROR)
{
dwErr = WSAGetLastError();
sprintf(szErr, "Error bind() = %ld ", dwErr);
AfxMessageBox(szErr);
closesocket(m_s);
return;
}
if (SOCKET_ERROR != WSAIoctl(m_s, SIO_RCVALL, &dwBufferInLen, sizeof(dwBufferInLen),
&dwBufferLen, sizeof(dwBufferLen),
&dwBytesReturned, NULL, NULL))
AfxBeginThread(threadFunc, (LPVOID)this);
else
{
dwErr = WSAGetLastError();
sprintf(szErr, "Error WSAIoctl = %ld ", dwErr);
AfxMessageBox(szErr);
closesocket(m_s);
return;
}
}
void CSniffDlg::OnBnClickedOk()
{
if (NULL != m_threadID)
{
PostThreadMessage(m_threadID, WM_CLOSE, 0, 0);
}
if (m_IPArr.GetSize())
{
m_IPArr.RemoveAll();
}
CDialogEx::OnOK();
}
void CSniffDlg::AddData(CString s0, CString s1, CString s2, CString s3, CString s4, CString s5, CString s6)
{
int index;
index = m_ctrList.InsertItem(0, s0);
m_ctrList.SetItem(index, 1, LVIF_TEXT, s1, 0, 0, 0, 0);
m_ctrList.SetItem(index, 2, LVIF_TEXT, s2, 0, 0, 0, 0);
m_ctrList.SetItem(index, 3, LVIF_TEXT, s3, 0, 0, 0, 0);
m_ctrList.SetItem(index, 4, LVIF_TEXT, s4, 0, 0, 0, 0);
m_ctrList.SetItem(index, 5, LVIF_TEXT, s5, 0, 0, 0, 0);
m_ctrList.SetItem(index, 6, LVIF_TEXT, s6, 0, 0, 0, 0);
}
void CSniffDlg::OnSelendokComboAdapter()
{
CHAR pszIp[100];
int index=m_cAdapter.GetCurSel();
m_cAdapter.GetLBText(index, pszIp);
m_ipsource = inet_addr(pszIp);
}
DWORD_PTR a;
Sniff.rc
IDD_SNIFF_DIALOG DIALOGEX 0, 0, 320, 200
STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
EXSTYLE WS_EX_APPWINDOW
CAPTION "Sniff嗅探器"
FONT 9, "MS Shell Dlg", 0, 0, 0x1
BEGIN
CONTROL "",IDC_LIST,"SysListView32",LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,15,31,291,135
PUSHBUTTON "查看",IDC_LOOKUP,109,172,45,14
PUSHBUTTON "确定",IDOK,178,172,45,14
COMBOBOX IDC_COMBO_ADAPTER,15,14,291,86,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP
END