头结构定义

/// @file ping.h
/// @brief ping需要的数据结构#ifndef __PING_H_2016_0408__
#define __PING_H_2016_0408__#pragma pack(push)
#pragma pack(1)#define ICMP_ECHOREPLY  0
#define ICMP_HOST_NOTEXIST 3 ///< 主机不存在
#define ICMP_ECHOREQ    8// IP Header -- RFC 791
typedef struct tagIPHDR
{// u_char  VIHL;        // Version and IHLu_char h_len:4;         // length of headeru_char version:4;       // Version of IPu_char  TOS;            // Type Of Serviceshort   TotLen;         // Total Lengthshort   ID;             // Identificationshort   FlagOff;        // Flags and Fragment Offsetu_char  TTL;            // Time To Liveu_char  Protocol;       // Protocol(tcp, udp, etc.)u_short Checksum;       // Checksumstruct  in_addr iaSrc;  // Internet Address - Sourcestruct  in_addr iaDst;  // Internet Address - Destination
}IPHDR, *PIPHDR;typedef struct _UDP_HEADER
{USHORT nSourPort ;   // 源端口号16bitUSHORT nDestPort ;   // 目的端口号16bitUSHORT nLength ;     // 数据包长度16bitUSHORT nCheckSum ;   // 校验和16bit
}UDP_HEADER, *PUDP_HEADER;typedef struct _TCP_HEADER
{USHORT nSourPort; // 源端口号16bitUSHORT nDestPort; // 目的端口号16bitUINT nSequNum; // 序列号32bitUINT nAcknowledgeNum; // 确认号32bit// USHORT nHLenAndFlag; // 前4位:TCP头长度;中6位:保留;后6位:标志位16bitUSHORT nTcpLen:4;USHORT nTcpUnused:6;USHORT nTcpFlag:6;USHORT nWindowSize; // 窗口大小16bitUSHORT nCheckSum; // 检验和16bitUSHORT nrgentPointer; // 紧急数据偏移量16bit
}TCP_HEADER, *PTCP_HEADER;// ICMP Header - RFC 792
typedef struct tagICMPHDR
{u_char  Type;           // Typeu_char  Code;           // Codeu_short Checksum;       // Checksumu_short ID;             // Identificationu_short Seq;            // Sequence// char Data;           // DataULONG   Data;           // Data, for GetTickCount
}ICMPHDR, *PICMPHDR;#define REQ_DATASIZE 32     // Echo Request Data size// ICMP Echo Request
typedef struct tagECHOREQUEST
{ICMPHDR icmpHdr;
//  DWORD   dwTime;char    cData[REQ_DATASIZE];
}ECHOREQUEST, *PECHOREQUEST;// ICMP Echo Reply
typedef struct tagECHOREPLY
{IPHDR   ipHdr;ECHOREQUEST echoRequest;char    cFiller[256];
}ECHOREPLY, *PECHOREPLY;#pragma pack(pop)#endif // #ifndef __PING_H_2016_0408__

应用-ping

// pingUIDlg.h : header file
//#if !defined(AFX_PINGUIDLG_H__C679F26E_6016_4CEE_8821_677F00F4C247__INCLUDED_)
#define AFX_PINGUIDLG_H__C679F26E_6016_4CEE_8821_677F00F4C247__INCLUDED_#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000#include "MyThread.h"
#include <list>
using namespace std;/////////////////////////////////////////////////////////////////////////////
// CPingUIDlg dialogclass CPingUIDlg : public CDialog
{
// Construction
public:CPingUIDlg(CWnd* pParent = NULL);   // standard constructor// Dialog Data//{{AFX_DATA(CPingUIDlg)enum { IDD = IDD_PINGUI_DIALOG };CListBox    m_CtrlListBoxMsg;CString m_strIpOrDoMainName;//}}AFX_DATA// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CPingUIDlg)protected:virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support//}}AFX_VIRTUAL// Implementation
protected:HICON m_hIcon;// Generated message map functions//{{AFX_MSG(CPingUIDlg)virtual BOOL OnInitDialog();afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();afx_msg void OnButtonPing();afx_msg void OnDestroy();//}}AFX_MSGafx_msg void OnShowThreadMsg(WPARAM wParam, LPARAM lParam);DECLARE_MESSAGE_MAP()public:static unsigned __stdcall ThreadProcPing(void* pParam);unsigned ThreadProcPing();private:void DataInit();void DataUnInit();void ShowErrMsg(int iErrSn);void ShowSocketErrMsg();void ShowErrMsg();void ShowThreadMsg(TCHAR* pMsg);void ClearThreadMsg();void ShowUiMsg(TCHAR* pcMsg);void Ping(LPCSTR pstrHost);int SendEchoRequest(SOCKET s, LPSOCKADDR_IN lpstToAddr);int WaitForEchoReply(SOCKET s);DWORD RecvEchoReply(SOCKET s, LPSOCKADDR_IN lpsaFrom, u_char *pTTL, DWORD& dwTimeSent);u_short in_cksum(u_short *addr, int len);private:list<CString> m_ListDispMsg;CRITICAL_SECTION g_csDispMsg;CMyThread m_ThreadProcPing;
};//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_PINGUIDLG_H__C679F26E_6016_4CEE_8821_677F00F4C247__INCLUDED_)
// pingUIDlg.cpp : implementation file
//#include "stdafx.h"
#include <atlconv.h>#include "pingUI.h"
#include "pingUIDlg.h"
#include "ping.h"#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif#define WM_SHOW_THREAD_MSG (WM_APP + 1000)/////////////////////////////////////////////////////////////////////////////
// CPingUIDlg dialogCPingUIDlg::CPingUIDlg(CWnd* pParent /*=NULL*/): CDialog(CPingUIDlg::IDD, pParent)
{//{{AFX_DATA_INIT(CPingUIDlg)m_strIpOrDoMainName = _T("192.168.2.60");//}}AFX_DATA_INIT// Note that LoadIcon does not require a subsequent DestroyIcon in Win32m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}void CPingUIDlg::DoDataExchange(CDataExchange* pDX)
{CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CPingUIDlg)DDX_Control(pDX, IDC_LIST_MSG, m_CtrlListBoxMsg);DDX_Text(pDX, IDC_EDIT_IP_OR_DOMAIN_NAME, m_strIpOrDoMainName);//}}AFX_DATA_MAP
}BEGIN_MESSAGE_MAP(CPingUIDlg, CDialog)//{{AFX_MSG_MAP(CPingUIDlg)ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDC_BUTTON_PING, OnButtonPing)ON_WM_DESTROY()//}}AFX_MSG_MAPON_MESSAGE(WM_SHOW_THREAD_MSG, OnShowThreadMsg)
END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
// CPingUIDlg message handlersBOOL CPingUIDlg::OnInitDialog()
{CDialog::OnInitDialog();// Set the icon for this dialog.  The framework does this automatically//  when the application's main window is not a dialogSetIcon(m_hIcon, TRUE);         // Set big iconSetIcon(m_hIcon, FALSE);        // Set small icon// TODO: Add extra initialization hereDataInit();return TRUE;  // return TRUE  unless you set the focus to a control
}// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.void CPingUIDlg::OnPaint()
{if (IsIconic()){CPaintDC dc(this); // device context for paintingSendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);// Center icon in client rectangleint 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;// Draw the icondc.DrawIcon(x, y, m_hIcon);}else{CDialog::OnPaint();}
}// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CPingUIDlg::OnQueryDragIcon()
{return (HCURSOR) m_hIcon;
}void CPingUIDlg::OnButtonPing()
{UpdateData(TRUE);if (m_strIpOrDoMainName.IsEmpty()) {ShowThreadMsg(_T("请输入IP或域名"));} else {if (m_ThreadProcPing.IsRunning()) {ShowThreadMsg(_T("ping任务还没有结束, 请稍等"));} else {m_ThreadProcPing.SetParam(ThreadProcPing,NULL,NULL,this);m_ThreadProcPing.Start();}}
}unsigned __stdcall CPingUIDlg::ThreadProcPing(void* pParam) {if (NULL == pParam) {return S_FALSE;}return ((CPingUIDlg*)pParam)->ThreadProcPing();
}unsigned CPingUIDlg::ThreadProcPing() {ClearThreadMsg();Ping((LPCTSTR)m_strIpOrDoMainName);ShowThreadMsg(_T("==========任务结束=========="));return S_OK;
}void CPingUIDlg::OnDestroy()
{CDialog::OnDestroy();// TODO: Add your message handler code herem_ThreadProcPing.Stop();DataUnInit();
}void CPingUIDlg::DataInit() {WSADATA m_WSAData;WSAStartup(MAKEWORD(2,2), &m_WSAData);InitializeCriticalSection(&g_csDispMsg);
}void CPingUIDlg::DataUnInit() {DeleteCriticalSection(&g_csDispMsg);WSACleanup();
}void CPingUIDlg::OnShowThreadMsg(WPARAM wParam, LPARAM lParam) {CString str;EnterCriticalSection(&g_csDispMsg);if (0 == wParam) {while (!m_ListDispMsg.empty()) {str = m_ListDispMsg.front();m_ListDispMsg.pop_front();ShowUiMsg((LPTSTR)(LPCTSTR)str);}} else {m_CtrlListBoxMsg.ResetContent();}LeaveCriticalSection(&g_csDispMsg);
}void CPingUIDlg::ShowUiMsg(TCHAR* pcMsg) {int iRc = 0;if (NULL != pcMsg) {iRc = m_CtrlListBoxMsg.AddString(pcMsg);if (LB_ERRSPACE == iRc) {m_CtrlListBoxMsg.ResetContent();m_CtrlListBoxMsg.AddString(pcMsg);}}
}void CPingUIDlg::ShowSocketErrMsg() {int iErrSn = WSAGetLastError();ShowErrMsg(iErrSn);
}void CPingUIDlg::ShowErrMsg() {int iErrSn = GetLastError();ShowErrMsg(iErrSn);
}void CPingUIDlg::ShowErrMsg(int iErrSn) {LPVOID lpMsgBuf = NULL;FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,NULL,iErrSn,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language(LPTSTR) &lpMsgBuf,0,NULL);if (NULL != lpMsgBuf) {ShowThreadMsg((LPTSTR)lpMsgBuf);}LocalFree(lpMsgBuf);
}void CPingUIDlg::ShowThreadMsg(TCHAR* pMsg) {if (NULL != pMsg) {EnterCriticalSection(&g_csDispMsg);m_ListDispMsg.push_back(pMsg);LeaveCriticalSection(&g_csDispMsg);PostMessage(WM_SHOW_THREAD_MSG, 0, 0);}
}void CPingUIDlg::ClearThreadMsg() {EnterCriticalSection(&g_csDispMsg);m_ListDispMsg.clear();LeaveCriticalSection(&g_csDispMsg);PostMessage(WM_SHOW_THREAD_MSG, 1, 0);
}void CPingUIDlg::Ping(LPCSTR pstrHost)
{CString str;SOCKET    rawSocket;LPHOSTENT lpHost;struct    sockaddr_in saDest;struct    sockaddr_in saSrc;DWORD     dwTimeSent = 0;DWORD     dwElapsed = 0;DWORD dwTick = 0;u_char    cTTL;int       nLoop;int       nRet;DWORD dwReplyType = ICMP_ECHOREPLY;// Create a Raw socketrawSocket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);if (rawSocket == SOCKET_ERROR) {ShowSocketErrMsg();return;}// Lookup hostlpHost = gethostbyname(pstrHost);if (lpHost == NULL){str.Format(_T("\nHost not found: %s"), pstrHost);ShowThreadMsg((LPTSTR)(LPCTSTR)str);return;}// Setup destination socket addresssaDest.sin_addr.s_addr = *((u_long FAR *) (lpHost->h_addr));saDest.sin_family = AF_INET;saDest.sin_port = 0;// Tell the user what we're doingstr.Format(_T("Pinging %s [%s] with %d bytes of data:\n"),pstrHost,inet_ntoa(saDest.sin_addr),REQ_DATASIZE);ShowThreadMsg((LPTSTR)(LPCTSTR)str);// Ping multiple timesfor (nLoop = 0; nLoop < 4; nLoop++){// Send ICMP echo requestSendEchoRequest(rawSocket, &saDest);// Use select() to wait for data to be receivednRet = WaitForEchoReply(rawSocket);if (nRet == SOCKET_ERROR){ShowSocketErrMsg();break;}if (!nRet){ShowThreadMsg("TimeOut");continue;}// Receive replydwReplyType = RecvEchoReply(rawSocket, &saSrc, &cTTL, dwTimeSent);if (ICMP_ECHOREPLY == dwReplyType) {// Calculate elapsed timedwTick = GetTickCount();dwElapsed = dwTick - dwTimeSent;str.Format(_T("\nReply from: %s: bytes=%d time=%ldms TTL=%d"), inet_ntoa(saSrc.sin_addr), REQ_DATASIZE,dwElapsed,cTTL);} else if (ICMP_HOST_NOTEXIST == dwReplyType) {str = _T("无法访问目标主机");} else {str.Format(_T("ICMP回答类型为%d, 请联系软件开发者"), dwReplyType);}ShowThreadMsg((LPTSTR)(LPCTSTR)str);}nRet = closesocket(rawSocket);if (nRet == SOCKET_ERROR)ShowSocketErrMsg();
}int CPingUIDlg::SendEchoRequest(SOCKET s,LPSOCKADDR_IN lpstToAddr)
{static ECHOREQUEST echoReq;static nId = 1;static nSeq = 1;int nRet;// Fill in echo requestechoReq.icmpHdr.Type        = ICMP_ECHOREQ;echoReq.icmpHdr.Code        = 0;echoReq.icmpHdr.Checksum    = 0;echoReq.icmpHdr.ID          = nId++;echoReq.icmpHdr.Seq         = nSeq++;// Fill in some data to sendfor (nRet = 0; nRet < REQ_DATASIZE; nRet++)echoReq.cData[nRet] = ' '+nRet;// Save tick count when sentechoReq.icmpHdr.Data = GetTickCount();// Put data in packet and compute checksumechoReq.icmpHdr.Checksum = in_cksum((u_short *)&echoReq, sizeof(ECHOREQUEST));// Send the echo request                                  nRet = sendto(s,                        /* socket */(LPSTR)&echoReq,           /* buffer */sizeof(ECHOREQUEST),0,                         /* flags */(LPSOCKADDR)lpstToAddr, /* destination */sizeof(SOCKADDR_IN));   /* address length */if (nRet == SOCKET_ERROR) ShowSocketErrMsg();return (nRet);
}int CPingUIDlg::WaitForEchoReply(SOCKET s)
{struct timeval Timeout;fd_set readfds;readfds.fd_count = 1;readfds.fd_array[0] = s;Timeout.tv_sec = 5;Timeout.tv_usec = 0;return(select(1, &readfds, NULL, NULL, &Timeout));
}DWORD CPingUIDlg::RecvEchoReply(SOCKET s, LPSOCKADDR_IN lpsaFrom, u_char *pTTL, DWORD& dwTimeSent)
{CString str;ECHOREPLY echoReply;int nRet;int nAddrLen = sizeof(struct sockaddr_in);// Receive the echo replyZeroMemory(&echoReply, sizeof(echoReply));nRet = recvfrom(s,                  // socket(LPSTR)&echoReply,  // buffersizeof(ECHOREPLY),  // size of buffer0,                  // flags(LPSOCKADDR)lpsaFrom,   // From address&nAddrLen);         // pointer to address len// Check return valueif (nRet == SOCKET_ERROR) ShowSocketErrMsg();// return time sent and IP TTLif (echoReply.echoRequest.icmpHdr.Type == ICMP_ECHOREPLY) {*pTTL = echoReply.ipHdr.TTL;dwTimeSent = echoReply.echoRequest.icmpHdr.Data;}return echoReply.echoRequest.icmpHdr.Type;
}//
// Mike Muuss' in_cksum() function
// and his comments from the original
// ping program
//
// * Author -
// *    Mike Muuss
// *    U. S. Army Ballistic Research Laboratory
// *    December, 1983/**          I N _ C K S U M** Checksum routine for Internet Protocol family headers (C Version)**/
u_short CPingUIDlg::in_cksum(u_short *addr, int len)
{register int nleft = len;register u_short *w = addr;register u_short answer;register int sum = 0;/**  Our algorithm is simple, using a 32 bit accumulator (sum),*  we add sequential 16 bit words to it, and at the end, fold*  back all the carry bits from the top 16 bits into the lower*  16 bits.*/while( nleft > 1 )  {sum += *w++;nleft -= 2;}/* mop up an odd byte, if necessary */if( nleft == 1 ) {u_short u = 0;*(u_char *)(&u) = *(u_char *)w ;sum += u;}/** add back carry outs from top 16 bits to low 16 bits*/sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */sum += (sum >> 16);         /* add carry */answer = ~sum;             /* truncate to 16 bits */return (answer);
}

原始套接字头结构定义相关推荐

  1. 补充学习——原始套接字中协议结构体

    原始套接字中使用结构体,快速获取数据中字节含义 struct iphdr{#if __BYTE_ORDER==__LITTLE_ENDIANunsigned int inl:4;unsigned in ...

  2. Linux原始套接字学习总结

    Linux网络编程:原始套接字的魔力[上] http://blog.chinaunix.net/uid-23069658-id-3280895.html 基于原始套接字编程        在开发面向连 ...

  3. Raw_Socket原始套接字

    一.创建raw socket的权限:只有root权限才能够创建. 二.raw socket的用途:主要有三个方面 (1):通过raw socket来接收发向本机的ICMP,IGMP协议包,或者用来发送 ...

  4. 002.ICMP--拼接ICMP包,实现简单Ping程序(原始套接字)

    一.大致流程: 将ICMP头和时间数据设置好后,通过创建好的原始套接字socket发出去.目的主机计算效验和后会将数据原样返回,用当前时间和返回的数据结算时间差,计算出rtt. 二.数据结构: ICM ...

  5. 【Linux网络编程】原始套接字编程

    原始套接字编程和之前的 UDP 编程差不多,无非就是创建一个套接字后,通过这个套接字接收数据或者发送数据.区别在于,原始套接字可以自行组装数据包(伪装本地 IP,本地 MAC),可以接收本机网卡上所有 ...

  6. 基于嗅探原理的原始套接字木马

    首先我们说说现有木马的特点和功能.早期木马一般都是基于TCP连接的,现在这种木马的生存能力 非常有限,因为直接基于连接的木马很容易被拦截或者发现.然后有通过改变协议来实现通讯隐藏的木马, 比如采用UD ...

  7. 原始套接字与sniffer

    原始套接字与sniffer 2009-05-11 23:40:30 分类: LINUX 下面是原文件附的代码.我运行过,很好. 文件: source.rar 大小: 7KB 下载: 下载 今天从网上看 ...

  8. linux sock_raw原始套接字编程

    sock_raw原始套接字编程可以接收到本机网卡上的数据帧或者数据包,对与监听网络的流量和分析是很有作用的.一共可以有3种方式创建这种socket   1.socket(AF_INET, SOCK_R ...

  9. 原始套接字AF_PACKET用法尝试

    摘抄自 https://www.xuebuyuan.com/2179173.html 学步园 PACKET_MMAP实现原理分析 2014年10月06日 ⁄ 综合 ⁄ 共 4737字 ⁄ 字号 小 中 ...

最新文章

  1. CVPR2020 论文解读:少点目标检测
  2. 谁的青春不迷茫,其实我们都一样
  3. zabbix企业应用之low level discovery监控磁盘吞吐量与iops
  4. Windows中常用的git GUI客户端的介绍
  5. 怎样用matlab模型建立,怎样在matlab里建立一个BP神经网络模型?
  6. 前端学习(2217):react元素渲染之时钟
  7. Ubuntu下gcc多版本共存和版本切换
  8. IT行业学习网站汇总
  9. Intel Core Enhanced Core架构/微架构/流水线 (15) - 先进智能缓存
  10. python图像压缩主成分分析实例_python机器学习API介绍13: 数据降维及主成分分析...
  11. 为什么修改配置文件要重启server
  12. 2017计算机办公自动化试题,2017年计算机考试办公自动化试题及答案
  13. 大数据离线分析之企业实战分享
  14. 图像预处理流程与方法
  15. http协议及基于http协议的文件下载
  16. 在线轻松制作微信公众号封面次图的方法
  17. cad相对坐标快捷键_cad 怎么用相对坐标
  18. H5+Vue2: input(number/tel)唤起数字键盘,踩坑日记
  19. Doris源码解析[一、负载均衡]
  20. http.Request

热门文章

  1. 编码器Atom使用指南
  2. 如何优雅的写UI——(1)MFC六大核心机制-程序初始化
  3. mac电脑垃圾清理 mac电脑垃圾桶清空的如何撤回
  4. 搜索引擎如何进行排名?
  5. 测试稳定性三板斧,你了解多少?
  6. udesk教你呼叫中心的运营与管理——第九讲 呼叫中心系统管理
  7. 安卓手机测评_安卓优化大师破解版2020-安卓优化大师去广告版下载v4.1.5
  8. [渝粤教育] 中国地质大学 政府与事业单位会计 复习题
  9. Three.js多细节层次LOD
  10. Linux 下 UltraEdit v15 破解 30 天试用限制