diff --git a/README.md b/README.md
index b8a8d8d..6af5ee9 100644
--- a/README.md
+++ b/README.md
@@ -18,4 +18,10 @@ this should improve performance and reduces network load*
- `[ ]` + host history: pressing del key or right mouse will remove selected entry
- `[ ]` * new icon
-~~~~
+### About me / why I decided to create this fork
+There isn't that much to say actually, I've been using IPv6 for a few years now thanks to [**SixXS**](http://sixxs.net/) and it always annoyed me that WinMTR couldn't handle IPv6... finally my ISP got some sort of IPv6 beta test. And that's what I wanted to compare, native vs SixXS with long-term trace routes such as those WinMTR provides.
+Since there wasn't any WinMTR build with IPv6, I decided to do it myself ;) The result can be seen here :P
+
+**If you're looking for an alternative** *(not meant for long-term traces)* there's [**vTrace**](vtrace.pl).
+It's some really interesting piece of Software ;) *(with more then just trace routes)*
+~~~~
\ No newline at end of file
diff --git a/src/WinMTR.rc b/src/WinMTR.rc
index 20399b0..b3cc862 100644
--- a/src/WinMTR.rc
+++ b/src/WinMTR.rc
@@ -70,24 +70,25 @@ IDR_MAINFRAME ICON "WinMTR.ico"
// Dialog
//
-IDD_WINMTR_DIALOG DIALOGEX 0, 0, 390, 193
+IDD_WINMTR_DIALOG DIALOGEX 0, 0, 420, 220
STYLE DS_SETFONT | DS_3DLOOK | DS_CENTER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
EXSTYLE WS_EX_APPWINDOW
FONT 8, "MS Sans Serif", 0, 0, 0x1
BEGIN
- DEFPUSHBUTTON "&Start",ID_RESTART,203,12,50,14,BS_FLAT
- PUSHBUTTON "&Options",ID_OPTIONS,270,12,51,14,BS_FLAT
- PUSHBUTTON "E&xit",IDCANCEL,328,12,49,14,BS_FLAT
- PUSHBUTTON "&Copy Text to clipboard",ID_CTTC,14,39,89,14,BS_FLAT
- PUSHBUTTON "Co&py HTML to clipboard",ID_CHTC,113,39,89,14,BS_FLAT
- PUSHBUTTON "Export &TEXT",ID_EXPT,270,39,51,14,BS_FLAT
- PUSHBUTTON "Export &HTML",ID_EXPH,328,39,49,14,BS_FLAT
- CONTROL "List1",IDC_LIST_MTR,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,7,60,376,126
- LTEXT "Host:",IDC_STATIC,13,12,20,13,SS_CENTERIMAGE
- GROUPBOX "",IDC_STATIC,7,3,251,29,BS_FLAT
- GROUPBOX "",IDC_STATICS,263,3,120,29,BS_FLAT
- GROUPBOX "",IDC_STATICJ,7,31,376,26,BS_FLAT
- COMBOBOX IDC_COMBO_HOST,35,12,164,73,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+ DEFPUSHBUTTON "&Start",ID_RESTART,235,10,50,14,BS_FLAT
+ PUSHBUTTON "&Options",ID_OPTIONS,333,10,41,14,BS_FLAT
+ PUSHBUTTON "E&xit",IDCANCEL,379,10,30,14,BS_FLAT
+ PUSHBUTTON "&Copy Text to clipboard",ID_CTTC,12,37,89,14,BS_FLAT
+ PUSHBUTTON "Co&py HTML to clipboard",ID_CHTC,111,37,89,14,BS_FLAT
+ PUSHBUTTON "Export &TEXT",ID_EXPT,301,37,51,14,BS_FLAT
+ PUSHBUTTON "Export &HTML",ID_EXPH,359,37,49,14,BS_FLAT
+ CONTROL "List1",IDC_LIST_MTR,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,5,58,409,157
+ LTEXT "Host:",IDC_STATIC,11,10,20,13,SS_LEFT | SS_CENTERIMAGE
+ GROUPBOX "",IDC_STATIC,5,0,287,30,BS_FLAT
+ GROUPBOX "",IDC_STATICS,295,0,120,30,BS_FLAT
+ GROUPBOX "",IDC_STATICJ,5,29,409,26,BS_FLAT
+ COMBOBOX IDC_COMBO_HOST,33,10,198,73,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+ AUTO3STATE "IPv6",IDC_CHECK_IPV6,301,14,31,8
END
IDD_DIALOG_OPTIONS DIALOGEX 0, 0, 251, 164
@@ -106,11 +107,11 @@ BEGIN
CONTROL "Resolve names",IDC_CHECK_DNS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,167,119,63,8
GROUPBOX "",IDC_STATIC,7,7,237,82,BS_FLAT
CTEXT "Get Fully Managed Dedicated and Cloud hosting in Europe and USA at killer prices.",IDC_STATIC,31,35,201,17
- CTEXT "WinMTR v0.92 is offered under GPL V2 by Appnor MSP",IDC_STATIC,42,14,194,17
+ CTEXT "WinMTR (Redux) v1.00 is offered under GPLv2",IDC_STATIC,42,14,194,17
PUSHBUTTON "&License and Credits",ID_LICENSE,81,67,94,14,BS_FLAT
LTEXT "Max. hosts in LRU list:",IDC_STATIC,15,119,74,10,NOT WS_GROUP
EDITTEXT IDC_EDIT_MAX_LRU,90,116,34,13,ES_AUTOHSCROLL
- CONTROL "www.appnor.com",IDC_MFCLINK1,"MfcLink",WS_TABSTOP,102,51,60,11
+ LTEXT "www.appnor.com",IDC_STATIC,102,51,60,11,NOT WS_GROUP
END
IDD_DIALOG_LICENSE DIALOGEX 0, 0, 175, 70
@@ -118,40 +119,41 @@ STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "License & Credits"
FONT 8, "MS Sans Serif", 0, 0, 0x0
BEGIN
- DEFPUSHBUTTON "OK",IDOK,59,43,50,14
- LTEXT "Read more on",IDC_STATIC,36,27,46,8
- CONTROL "www.winmtr.net",IDC_MFCLINK1,"MfcLink",WS_TABSTOP,83,26,60,14
- LTEXT "WinMTR is licensed under GPL V2.",IDC_STATIC,33,14,113,8
+ DEFPUSHBUTTON "OK",IDOK,62,36,50,14
+ LTEXT "Read more on",IDC_STATIC,36,21,46,8
+ LTEXT "www.winmtr.net",IDC_STATIC,85,21,60,8
+ CTEXT "WinMTR (Redux) is licensed under GPLv2.",IDC_STATIC,2,9,171,8,SS_CENTER
+ CTEXT "https://github.com/White-Tiger/WinMTR",IDC_STATIC,7,57,161,8,SS_CENTER
END
-IDD_DIALOG_PROPERTIES DIALOG 0, 0, 201, 159
+IDD_DIALOG_PROPERTIES DIALOG 0, 0, 282, 160
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Host properties"
FONT 8, "MS Sans Serif"
BEGIN
- DEFPUSHBUTTON "OK",IDOK,71,138,50,14,BS_FLAT
+ DEFPUSHBUTTON "OK",IDOK,116,140,50,14,BS_FLAT
LTEXT "Name:",IDC_STATIC,15,18,24,8
- EDITTEXT IDC_EDIT_PHOST,48,16,136,12,ES_RIGHT | ES_AUTOHSCROLL | ES_READONLY
+ EDITTEXT IDC_EDIT_PHOST,48,16,219,12,ES_RIGHT | ES_AUTOHSCROLL | ES_READONLY
LTEXT "IP Address:",IDC_STATIC,14,32,40,9
- EDITTEXT IDC_EDIT_PIP,58,31,126,12,ES_RIGHT | ES_AUTOHSCROLL | ES_READONLY
- GROUPBOX "Packets",IDC_STATIC,7,74,89,60,BS_FLAT
- GROUPBOX "Ping time",IDC_STATIC,108,74,86,60,BS_FLAT
- GROUPBOX "Host",IDC_STATIC,7,7,187,62,BS_FLAT
- LTEXT "Loss (%):",IDC_STATIC,13,117,31,9
- LTEXT "Received:",IDC_STATIC,13,101,36,9
- LTEXT "Sent:",IDC_STATIC,13,85,21,9
- LTEXT "Last:",IDC_STATIC,114,84,18,9
- LTEXT "Best:",IDC_STATIC,114,96,20,8
- LTEXT "Average:",IDC_STATIC,114,107,32,8
- LTEXT "Worst:",IDC_STATIC,114,118,23,8
- EDITTEXT IDC_EDIT_PSENT,53,82,35,12,ES_RIGHT | ES_AUTOHSCROLL | ES_READONLY | ES_NUMBER
- EDITTEXT IDC_EDIT_PRECV,53,99,35,12,ES_RIGHT | ES_AUTOHSCROLL | ES_READONLY | ES_NUMBER
- EDITTEXT IDC_EDIT_PLOSS,53,116,35,12,ES_RIGHT | ES_AUTOHSCROLL | ES_READONLY | ES_NUMBER
- EDITTEXT IDC_EDIT_PLAST,150,81,34,12,ES_RIGHT | ES_AUTOHSCROLL | ES_READONLY
- EDITTEXT IDC_EDIT_PBEST,150,94,34,12,ES_RIGHT | ES_AUTOHSCROLL | ES_READONLY
- EDITTEXT IDC_EDIT_PAVRG,150,106,34,12,ES_RIGHT | ES_AUTOHSCROLL | ES_READONLY
- EDITTEXT IDC_EDIT_PWORST,150,118,34,12,ES_RIGHT | ES_AUTOHSCROLL | ES_READONLY
- EDITTEXT IDC_EDIT_PCOMMENT,14,50,170,12,ES_AUTOHSCROLL | ES_READONLY
+ EDITTEXT IDC_EDIT_PIP,58,31,209,12,ES_RIGHT | ES_AUTOHSCROLL | ES_READONLY
+ GROUPBOX "Packets",IDC_STATIC,46,74,89,60,BS_FLAT
+ GROUPBOX "Ping time",IDC_STATIC,147,74,86,60,BS_FLAT
+ GROUPBOX "Host",IDC_STATIC,7,7,267,62,BS_FLAT
+ LTEXT "Loss (%):",IDC_STATIC,52,117,31,9
+ LTEXT "Received:",IDC_STATIC,52,101,36,9
+ LTEXT "Sent:",IDC_STATIC,52,85,21,9
+ LTEXT "Last:",IDC_STATIC,153,84,18,9
+ LTEXT "Best:",IDC_STATIC,153,96,20,8
+ LTEXT "Average:",IDC_STATIC,153,107,32,8
+ LTEXT "Worst:",IDC_STATIC,153,118,23,8
+ EDITTEXT IDC_EDIT_PSENT,92,82,35,12,ES_RIGHT | ES_AUTOHSCROLL | ES_READONLY | ES_NUMBER
+ EDITTEXT IDC_EDIT_PRECV,92,99,35,12,ES_RIGHT | ES_AUTOHSCROLL | ES_READONLY | ES_NUMBER
+ EDITTEXT IDC_EDIT_PLOSS,92,116,35,12,ES_RIGHT | ES_AUTOHSCROLL | ES_READONLY | ES_NUMBER
+ EDITTEXT IDC_EDIT_PLAST,189,81,34,12,ES_RIGHT | ES_AUTOHSCROLL | ES_READONLY
+ EDITTEXT IDC_EDIT_PBEST,189,94,34,12,ES_RIGHT | ES_AUTOHSCROLL | ES_READONLY
+ EDITTEXT IDC_EDIT_PAVRG,189,106,34,12,ES_RIGHT | ES_AUTOHSCROLL | ES_READONLY
+ EDITTEXT IDC_EDIT_PWORST,189,118,34,12,ES_RIGHT | ES_AUTOHSCROLL | ES_READONLY
+ EDITTEXT IDC_EDIT_PCOMMENT,14,50,253,12,ES_AUTOHSCROLL | ES_READONLY
END
IDD_DIALOG_HELP DIALOGEX 0, 0, 256, 122
@@ -160,8 +162,8 @@ CAPTION "WinMTR"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,144,101,50,14
- CONTROL "www.appnor.com",IDC_MFCLINK1,"MfcLink",WS_TABSTOP,187,8,60,11
- LTEXT "WinMTR v0.92 is offered under GPL V2 by Appnor MSP",IDC_STATIC,7,9,176,10
+ LTEXT "www.appnor.com",IDC_STATIC,187,9,60,11
+ LTEXT "WinMTR (Redux) v1.00 is offered under GPLv2",IDC_STATIC,7,9,176,10
LTEXT "Usage: WinMTR [options] target_host_name",IDC_STATIC,7,29,144,8
LTEXT "Options:",IDC_STATIC,7,39,28,8
LTEXT " --interval, -i VALUE. Set ping interval.",IDC_STATIC,26,47,131,8
@@ -178,8 +180,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 0,9,0,2
- PRODUCTVERSION 0,9,0,2
+ FILEVERSION 1,0,0,0
+ PRODUCTVERSION 1,0,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -194,13 +196,13 @@ BEGIN
BEGIN
BLOCK "040904b0"
BEGIN
- VALUE "FileDescription", "WinMTR by Appnor MSP - www.winmtr.net"
- VALUE "FileVersion", "0.9.0.2"
+ VALUE "FileDescription", "WinMTR Redux (original by Appnor MSP - www.winmtr.net)"
+ VALUE "FileVersion", "1.0.0.0"
VALUE "InternalName", "WinMTR"
VALUE "LegalCopyright", "WinMTR 0.9 (c) 2010-2011 Appnor MSP - Fully Managed Hosting & Cloud Provider www.appnor.com"
- VALUE "OriginalFilename", "WinMTR.EXE"
+ VALUE "OriginalFilename", "WinMTR.exe"
VALUE "ProductName", "WinMTR Application"
- VALUE "ProductVersion", "0.9.0.2"
+ VALUE "ProductVersion", "1.0.0.0"
END
END
BLOCK "VarFileInfo"
@@ -268,67 +270,6 @@ END
#endif // APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// Dialog Info
-//
-
-IDD_DIALOG_HELP DLGINIT
-BEGIN
- IDC_MFCLINK1, 0x37c, 238, 0
-0x4d3c, 0x4346, 0x694c, 0x6b6e, 0x555f, 0x6c72, 0x683e, 0x7474, 0x3a70,
-0x2f2f, 0x7777, 0x2e77, 0x7061, 0x6e70, 0x726f, 0x632e, 0x6d6f, 0x3f2f,
-0x7475, 0x5f6d, 0x6f73, 0x7275, 0x6563, 0x773d, 0x6e69, 0x746d, 0x2672,
-0x7475, 0x5f6d, 0x656d, 0x6964, 0x6d75, 0x643d, 0x7365, 0x746b, 0x706f,
-0x7526, 0x6d74, 0x635f, 0x6d61, 0x6170, 0x6769, 0x3d6e, 0x6f73, 0x7466,
-0x6177, 0x6572, 0x2f3c, 0x464d, 0x4c43, 0x6e69, 0x5f6b, 0x7255, 0x3e6c,
-0x4d3c, 0x4346, 0x694c, 0x6b6e, 0x555f, 0x6c72, 0x7250, 0x6665, 0x7869,
-0x3c3e, 0x4d2f, 0x4346, 0x694c, 0x6b6e, 0x555f, 0x6c72, 0x7250, 0x6665,
-0x7869, 0x3c3e, 0x464d, 0x4c43, 0x6e69, 0x5f6b, 0x6f54, 0x6c6f, 0x6974,
-0x3e70, 0x2f3c, 0x464d, 0x4c43, 0x6e69, 0x5f6b, 0x6f54, 0x6c6f, 0x6974,
-0x3e70, 0x4d3c, 0x4346, 0x694c, 0x6b6e, 0x465f, 0x6c75, 0x546c, 0x7865,
-0x5474, 0x6f6f, 0x746c, 0x7069, 0x463e, 0x4c41, 0x4553, 0x2f3c, 0x464d,
-0x4c43, 0x6e69, 0x5f6b, 0x7546, 0x6c6c, 0x6554, 0x7478, 0x6f54, 0x6c6f,
-0x6974, 0x3e70,
- 0
-END
-
-IDD_DIALOG_OPTIONS DLGINIT
-BEGIN
- IDC_MFCLINK1, 0x37c, 238, 0
-0x4d3c, 0x4346, 0x694c, 0x6b6e, 0x555f, 0x6c72, 0x683e, 0x7474, 0x3a70,
-0x2f2f, 0x7777, 0x2e77, 0x7061, 0x6e70, 0x726f, 0x632e, 0x6d6f, 0x3f2f,
-0x7475, 0x5f6d, 0x6f73, 0x7275, 0x6563, 0x773d, 0x6e69, 0x746d, 0x2672,
-0x7475, 0x5f6d, 0x656d, 0x6964, 0x6d75, 0x643d, 0x7365, 0x746b, 0x706f,
-0x7526, 0x6d74, 0x635f, 0x6d61, 0x6170, 0x6769, 0x3d6e, 0x6f73, 0x7466,
-0x6177, 0x6572, 0x2f3c, 0x464d, 0x4c43, 0x6e69, 0x5f6b, 0x7255, 0x3e6c,
-0x4d3c, 0x4346, 0x694c, 0x6b6e, 0x555f, 0x6c72, 0x7250, 0x6665, 0x7869,
-0x3c3e, 0x4d2f, 0x4346, 0x694c, 0x6b6e, 0x555f, 0x6c72, 0x7250, 0x6665,
-0x7869, 0x3c3e, 0x464d, 0x4c43, 0x6e69, 0x5f6b, 0x6f54, 0x6c6f, 0x6974,
-0x3e70, 0x2f3c, 0x464d, 0x4c43, 0x6e69, 0x5f6b, 0x6f54, 0x6c6f, 0x6974,
-0x3e70, 0x4d3c, 0x4346, 0x694c, 0x6b6e, 0x465f, 0x6c75, 0x546c, 0x7865,
-0x5474, 0x6f6f, 0x746c, 0x7069, 0x463e, 0x4c41, 0x4553, 0x2f3c, 0x464d,
-0x4c43, 0x6e69, 0x5f6b, 0x7546, 0x6c6c, 0x6554, 0x7478, 0x6f54, 0x6c6f,
-0x6974, 0x3e70,
- 0
-END
-
-IDD_DIALOG_LICENSE DLGINIT
-BEGIN
- IDC_MFCLINK1, 0x37c, 157, 0
-0x4d3c, 0x4346, 0x694c, 0x6b6e, 0x555f, 0x6c72, 0x3c3e, 0x4d2f, 0x4346,
-0x694c, 0x6b6e, 0x555f, 0x6c72, 0x3c3e, 0x464d, 0x4c43, 0x6e69, 0x5f6b,
-0x7255, 0x506c, 0x6572, 0x6966, 0x3e78, 0x2f3c, 0x464d, 0x4c43, 0x6e69,
-0x5f6b, 0x7255, 0x506c, 0x6572, 0x6966, 0x3e78, 0x4d3c, 0x4346, 0x694c,
-0x6b6e, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x3c3e, 0x4d2f, 0x4346, 0x694c,
-0x6b6e, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x3c3e, 0x464d, 0x4c43, 0x6e69,
-0x5f6b, 0x7546, 0x6c6c, 0x6554, 0x7478, 0x6f54, 0x6c6f, 0x6974, 0x3e70,
-0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x694c, 0x6b6e, 0x465f, 0x6c75,
-0x546c, 0x7865, 0x5474, 0x6f6f, 0x746c, 0x7069, "\076"
- 0
-END
-
-
/////////////////////////////////////////////////////////////////////////////
//
// String Table
@@ -337,7 +278,7 @@ END
STRINGTABLE
BEGIN
IDP_SOCKETS_INIT_FAILED "Windows sockets initialization failed."
- IDS_STRING_SB_NAME "WinMTR v0.92 GPL V2 by Appnor MSP - Fully Managed Hosting & Cloud Provider"
+ IDS_STRING_SB_NAME "WinMTR v1.00 GPLv2 (original by Appnor MSP - Fully Managed Hosting & Cloud Provider)"
IDS_STRING_SB_PING "0000000"
IDS_STRING_CLEAR_HISTORY "Clear History"
END
@@ -346,25 +287,8 @@ END
/////////////////////////////////////////////////////////////////////////////
-
-#ifndef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
//
-// Generated from the TEXTINCLUDE 3 resource.
+// Manifest resources
//
-#define _AFX_NO_SPLITTER_RESOURCES
-#define _AFX_NO_OLE_RESOURCES
-#define _AFX_NO_TRACKER_RESOURCES
-#define _AFX_NO_PROPERTY_RESOURCES
-
-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
-#ifdef _WIN32
-LANGUAGE 9, 1
-#pragma code_page(1252)
-#endif //_WIN32
-#include "afxres.rc" // Standard components
-#endif
-
-/////////////////////////////////////////////////////////////////////////////
-#endif // not APSTUDIO_INVOKED
-
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+1 RT_MANIFEST ".\\manifest.xml"
diff --git a/src/WinMTRDialog.cpp b/src/WinMTRDialog.cpp
index 9fcc82e..620c368 100644
--- a/src/WinMTRDialog.cpp
+++ b/src/WinMTRDialog.cpp
@@ -11,7 +11,6 @@
#include "WinMTRNet.h"
#include
#include
-#include "afxlinkctrl.h"
#define TRACE_MSG(msg) \
{ \
@@ -76,9 +75,12 @@ WinMTRDialog::WinMTRDialog(CWnd* pParent)
hasPingsizeFromCmdLine = false;
hasMaxLRUFromCmdLine = false;
hasUseDNSFromCmdLine = false;
+ hasUseIPv6FromCmdLine = false;
traceThreadMutex = CreateMutex(NULL, FALSE, NULL);
wmtrnet = new WinMTRNet(this);
+ if(!wmtrnet->hasIPv6) m_checkIPv6.EnableWindow(FALSE);
+ useIPv6=2;
}
WinMTRDialog::~WinMTRDialog()
@@ -99,6 +101,7 @@ void WinMTRDialog::DoDataExchange(CDataExchange* pDX)
DDX_Control(pDX, IDCANCEL, m_buttonExit);
DDX_Control(pDX, ID_RESTART, m_buttonStart);
DDX_Control(pDX, IDC_COMBO_HOST, m_comboHost);
+ DDX_Control(pDX, IDC_CHECK_IPV6, m_checkIPv6);
DDX_Control(pDX, IDC_LIST_MTR, m_listMTR);
DDX_Control(pDX, IDC_STATICS, m_staticS);
DDX_Control(pDX, IDC_STATICJ, m_staticJ);
@@ -115,11 +118,15 @@ void WinMTRDialog::DoDataExchange(CDataExchange* pDX)
BOOL WinMTRDialog::OnInitDialog()
{
CDialog::OnInitDialog();
+ if(!wmtrnet->initialized){
+ EndDialog(-1);
+ return TRUE;
+ }
#ifndef _WIN64
- char caption[] = {"WinMTR v0.92 32 bit by Appnor MSP - www.winmtr.net"};
+ char caption[] = {"WinMTR (Redux) v1.00 32bit"};
#else
- char caption[] = {"WinMTR v0.92 64 bit by Appnor MSP - www.winmtr.net"};
+ char caption[] = {"WinMTR (Redux) v1.00 64bit"};
#endif
SetTimer(1, WINMTR_DIALOG_TIMER, NULL);
@@ -136,22 +143,14 @@ BOOL WinMTRDialog::OnInitDialog()
sbi[0] = IDS_STRING_SB_NAME;
statusBar.SetIndicators( sbi,1);
statusBar.SetPaneInfo(0, statusBar.GetItemID(0),SBPS_STRETCH, NULL );
- { // Add appnor URL
- CMFCLinkCtrl* m_pWndButton = new CMFCLinkCtrl;
- if (!m_pWndButton->Create(_T("www.appnor.com"), WS_CHILD|WS_VISIBLE|WS_TABSTOP, CRect(0,0,0,0), &statusBar, 1234)) {
- TRACE(_T("Failed to create button control.\n"));
- return FALSE;
- }
-
- m_pWndButton->SetURL("http://www.appnor.com/?utm_source=winmtr&utm_medium=desktop&utm_campaign=software");
-
- if(!statusBar.AddPane(1234,1)) {
- AfxMessageBox(_T("Pane index out of range\nor pane with same ID already exists in the status bar"), MB_ICONERROR);
- return FALSE;
+
+ // create Appnor button
+ if(m_buttonAppnor.Create(_T("www.appnor.com"), WS_CHILD|WS_VISIBLE|WS_TABSTOP, CRect(0,0,0,0), &statusBar, 1234)){
+ m_buttonAppnor.SetURL("http://appnor.com/?utm_source=winmtr&utm_medium=desktop&utm_campaign=software");
+ if(statusBar.AddPane(1234,1)){
+ statusBar.SetPaneWidth(statusBar.CommandToIndex(1234),100);
+ statusBar.AddPaneControl(m_buttonAppnor,1234,true);
}
-
- statusBar.SetPaneWidth(statusBar.CommandToIndex(1234), 100);
- statusBar.AddPaneControl(m_pWndButton, 1234, true);
}
for(int i = 0; i< MTR_NR_COLS; i++)
@@ -215,27 +214,7 @@ BOOL WinMTRDialog::InitRegistry()
DWORD res, tmp_dword, value_size;
LONG r;
- r = RegCreateKeyEx( HKEY_CURRENT_USER,
- "Software",
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- KEY_ALL_ACCESS,
- NULL,
- &hKey,
- &res);
- if( r != ERROR_SUCCESS)
- return FALSE;
-
- r = RegCreateKeyEx( hKey,
- "WinMTR",
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- KEY_ALL_ACCESS,
- NULL,
- &hKey,
- &res);
+ r = RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\WinMTR",0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&res);
if( r != ERROR_SUCCESS)
return FALSE;
@@ -243,15 +222,7 @@ BOOL WinMTRDialog::InitRegistry()
RegSetValueEx(hKey,"License", 0, REG_SZ, (const unsigned char *)WINMTR_LICENSE, sizeof(WINMTR_LICENSE)+1);
RegSetValueEx(hKey,"HomePage", 0, REG_SZ, (const unsigned char *)WINMTR_HOMEPAGE, sizeof(WINMTR_HOMEPAGE)+1);
- r = RegCreateKeyEx( hKey,
- "Config",
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- KEY_ALL_ACCESS,
- NULL,
- &hKey_v,
- &res);
+ r = RegCreateKeyEx(hKey,"Config",0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey_v,&res);
if( r != ERROR_SUCCESS)
return FALSE;
@@ -259,7 +230,7 @@ BOOL WinMTRDialog::InitRegistry()
tmp_dword = pingsize;
RegSetValueEx(hKey_v,"PingSize", 0, REG_DWORD, (const unsigned char *)&tmp_dword, sizeof(DWORD));
} else {
- if(!hasPingsizeFromCmdLine) pingsize = tmp_dword;
+ if(!hasPingsizeFromCmdLine) pingsize = (WORD)tmp_dword;
}
if(RegQueryValueEx(hKey_v, "MaxLRU", 0, NULL, (unsigned char *)&tmp_dword, &value_size) != ERROR_SUCCESS) {
@@ -275,6 +246,14 @@ BOOL WinMTRDialog::InitRegistry()
} else {
if(!hasUseDNSFromCmdLine) useDNS = (BOOL)tmp_dword;
}
+ if(RegQueryValueEx(hKey_v, "UseIPv6", 0, NULL, (unsigned char *)&tmp_dword, &value_size) != ERROR_SUCCESS) {
+ tmp_dword = useIPv6;
+ RegSetValueEx(hKey_v,"UseIPv6", 0, REG_DWORD, (const unsigned char *)&tmp_dword, sizeof(DWORD));
+ } else {
+ if(!hasUseIPv6FromCmdLine) useIPv6 = (unsigned char)tmp_dword;
+ if(useIPv6>2) useIPv6=1;
+ }
+ m_checkIPv6.SetCheck(useIPv6);
if(RegQueryValueEx(hKey_v, "Interval", 0, NULL, (unsigned char *)&tmp_dword, &value_size) != ERROR_SUCCESS) {
tmp_dword = (DWORD)(interval * 1000);
@@ -283,15 +262,7 @@ BOOL WinMTRDialog::InitRegistry()
if(!hasIntervalFromCmdLine) interval = (float)tmp_dword / 1000.0;
}
- r = RegCreateKeyEx( hKey,
- "LRU",
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- KEY_ALL_ACCESS,
- NULL,
- &hKey_v,
- &res);
+ r = RegCreateKeyEx(hKey,"LRU",0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey_v,&res);
if( r != ERROR_SUCCESS)
return FALSE;
if(RegQueryValueEx(hKey_v, "NrLRU", 0, NULL, (unsigned char *)&tmp_dword, &value_size) != ERROR_SUCCESS) {
@@ -329,10 +300,10 @@ void WinMTRDialog::OnSizing(UINT fwSide, LPRECT pRect)
int iWidth = (pRect->right)-(pRect->left);
int iHeight = (pRect->bottom)-(pRect->top);
- if (iWidth < 600)
- pRect->right = pRect->left + 600;
- if (iHeight <250)
- pRect->bottom = pRect->top + 250;
+ if (iWidth<638)
+ pRect->right = pRect->left+638;
+ if (iHeight<388)
+ pRect->bottom = pRect->top+388;
}
@@ -341,50 +312,41 @@ void WinMTRDialog::OnSizing(UINT fwSide, LPRECT pRect)
//
//
//*****************************************************************************
+/// @todo (White-Tiger#1#): simplify it... use initial positions from "right" to calculate new position (no fix values here)
void WinMTRDialog::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
- CRect r;
- GetClientRect(&r);
- CRect lb;
+ CRect rct,lb;
+ if(!IsWindow(m_staticS.m_hWnd)) return;
+ GetClientRect(&rct);
+ m_staticS.GetWindowRect(&lb);
+ ScreenToClient(&lb);
+ m_staticS.SetWindowPos(NULL, lb.TopLeft().x, lb.TopLeft().y, rct.Width()-lb.TopLeft().x-8, lb.Height() , SWP_NOMOVE | SWP_NOZORDER);
+
+ m_staticJ.GetWindowRect(&lb);
+ ScreenToClient(&lb);
+ m_staticJ.SetWindowPos(NULL, lb.TopLeft().x, lb.TopLeft().y, rct.Width() - 16, lb.Height(), SWP_NOMOVE | SWP_NOZORDER);
+
+ m_buttonOptions.GetWindowRect(&lb);
+ ScreenToClient(&lb);
+ m_buttonOptions.SetWindowPos(NULL, rct.Width() - lb.Width()-52-16, lb.TopLeft().y, lb.Width(), lb.Height() , SWP_NOSIZE | SWP_NOZORDER);
+ m_buttonExit.GetWindowRect(&lb);
+ ScreenToClient(&lb);
+ m_buttonExit.SetWindowPos(NULL, rct.Width() - lb.Width()-16, lb.TopLeft().y, lb.Width(), lb.Height() , SWP_NOSIZE | SWP_NOZORDER);
- if (::IsWindow(m_staticS.m_hWnd)) {
- m_staticS.GetWindowRect(&lb);
- ScreenToClient(&lb);
- m_staticS.SetWindowPos(NULL, lb.TopLeft().x, lb.TopLeft().y, r.Width()-lb.TopLeft().x-10, lb.Height() , SWP_NOMOVE | SWP_NOZORDER);
- }
-
- if (::IsWindow(m_staticJ.m_hWnd)) {
- m_staticJ.GetWindowRect(&lb);
- ScreenToClient(&lb);
- m_staticJ.SetWindowPos(NULL, lb.TopLeft().x, lb.TopLeft().y, r.Width() - 21, lb.Height(), SWP_NOMOVE | SWP_NOZORDER);
- }
-
- if (::IsWindow(m_buttonExit.m_hWnd)) {
- m_buttonExit.GetWindowRect(&lb);
- ScreenToClient(&lb);
- m_buttonExit.SetWindowPos(NULL, r.Width() - lb.Width()-21, lb.TopLeft().y, lb.Width(), lb.Height() , SWP_NOSIZE | SWP_NOZORDER);
- }
-
- if (::IsWindow(m_buttonExpH.m_hWnd)) {
- m_buttonExpH.GetWindowRect(&lb);
- ScreenToClient(&lb);
- m_buttonExpH.SetWindowPos(NULL, r.Width() - lb.Width()-21, lb.TopLeft().y, lb.Width(), lb.Height() , SWP_NOSIZE | SWP_NOZORDER);
- }
- if (::IsWindow(m_buttonExpT.m_hWnd)) {
- m_buttonExpT.GetWindowRect(&lb);
- ScreenToClient(&lb);
- m_buttonExpT.SetWindowPos(NULL, r.Width() - lb.Width()- 103, lb.TopLeft().y, lb.Width(), lb.Height() , SWP_NOSIZE | SWP_NOZORDER);
- }
+ m_buttonExpH.GetWindowRect(&lb);
+ ScreenToClient(&lb);
+ m_buttonExpH.SetWindowPos(NULL, rct.Width() - lb.Width()-16, lb.TopLeft().y, lb.Width(), lb.Height() , SWP_NOSIZE | SWP_NOZORDER);
+ m_buttonExpT.GetWindowRect(&lb);
+ ScreenToClient(&lb);
+ m_buttonExpT.SetWindowPos(NULL, rct.Width() - lb.Width()- 103, lb.TopLeft().y, lb.Width(), lb.Height() , SWP_NOSIZE | SWP_NOZORDER);
- if (::IsWindow(m_listMTR.m_hWnd)) {
- m_listMTR.GetWindowRect(&lb);
- ScreenToClient(&lb);
- m_listMTR.SetWindowPos(NULL, lb.TopLeft().x, lb.TopLeft().y, r.Width() - 21, r.Height() - lb.top - 25, SWP_NOMOVE | SWP_NOZORDER);
- }
+ m_listMTR.GetWindowRect(&lb);
+ ScreenToClient(&lb);
+ m_listMTR.SetWindowPos(NULL, lb.TopLeft().x, lb.TopLeft().y, rct.Width() - 17, rct.Height() - lb.top - 25, SWP_NOMOVE | SWP_NOZORDER);
RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST,
- 0, reposQuery, r);
+ 0, reposQuery, rct);
RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0);
@@ -435,47 +397,39 @@ HCURSOR WinMTRDialog::OnQueryDragIcon()
// WinMTRDialog::OnDblclkList
//
//*****************************************************************************
-void WinMTRDialog::OnDblclkList(NMHDR* pNMHDR, LRESULT* pResult)
+void WinMTRDialog::OnDblclkList(NMHDR* /*pNMHDR*/, LRESULT* pResult)
{
- *pResult = 0;
-
- if(state == TRACING) {
+ *pResult=0;
+ if(state==TRACING || state==IDLE || state==STOPPING) {
POSITION pos = m_listMTR.GetFirstSelectedItemPosition();
if(pos!=NULL) {
int nItem = m_listMTR.GetNextSelectedItem(pos);
WinMTRProperties wmtrprop;
-
- if(wmtrnet->GetAddr(nItem)==0) {
+
+ union{sockaddr* addr;sockaddr_in* addr4;sockaddr_in6* addr6;};
+ addr=wmtrnet->GetAddr(nItem);
+ if(!(addr4->sin_family==AF_INET&&addr4->sin_addr.s_addr) && !(addr6->sin6_family==AF_INET6&&(addr6->sin6_addr.u.Word[0]|addr6->sin6_addr.u.Word[1]|addr6->sin6_addr.u.Word[2]|addr6->sin6_addr.u.Word[3]|addr6->sin6_addr.u.Word[4]|addr6->sin6_addr.u.Word[5]|addr6->sin6_addr.u.Word[6]|addr6->sin6_addr.u.Word[7]))){
strcpy(wmtrprop.host,"");
strcpy(wmtrprop.ip,"");
wmtrnet->GetName(nItem, wmtrprop.comment);
-
- wmtrprop.pck_loss = wmtrprop.pck_sent = wmtrprop.pck_recv = 0;
-
- wmtrprop.ping_avrg = wmtrprop.ping_last = 0.0;
- wmtrprop.ping_best = wmtrprop.ping_worst = 0.0;
- } else {
+ }else{
wmtrnet->GetName(nItem, wmtrprop.host);
- int addr = wmtrnet->GetAddr(nItem);
- sprintf ( wmtrprop.ip , "%d.%d.%d.%d",
- (addr >> 24) & 0xff,
- (addr >> 16) & 0xff,
- (addr >> 8) & 0xff,
- addr & 0xff
- );
- strcpy(wmtrprop.comment , "Host alive.");
-
- wmtrprop.ping_avrg = (float)wmtrnet->GetAvg(nItem);
- wmtrprop.ping_last = (float)wmtrnet->GetLast(nItem);
- wmtrprop.ping_best = (float)wmtrnet->GetBest(nItem);
- wmtrprop.ping_worst = (float)wmtrnet->GetWorst(nItem);
-
- wmtrprop.pck_loss = wmtrnet->GetPercent(nItem);
- wmtrprop.pck_recv = wmtrnet->GetReturned(nItem);
- wmtrprop.pck_sent = wmtrnet->GetXmit(nItem);
+ if(getnameinfo(addr,sizeof(sockaddr_in6),wmtrprop.ip,40,NULL,0,NI_NUMERICHOST)){
+ *wmtrprop.ip='\0';
+ }
+ strcpy(wmtrprop.comment, "Host alive.");
}
+ wmtrprop.ping_avrg = (float)wmtrnet->GetAvg(nItem);
+ wmtrprop.ping_last = (float)wmtrnet->GetLast(nItem);
+ wmtrprop.ping_best = (float)wmtrnet->GetBest(nItem);
+ wmtrprop.ping_worst = (float)wmtrnet->GetWorst(nItem);
+
+ wmtrprop.pck_loss = wmtrnet->GetPercent(nItem);
+ wmtrprop.pck_recv = wmtrnet->GetReturned(nItem);
+ wmtrprop.pck_sent = wmtrnet->GetXmit(nItem);
+
wmtrprop.DoModal();
}
}
@@ -497,7 +451,7 @@ void WinMTRDialog::SetHostName(const char *host)
// WinMTRDialog::SetPingSize
//
//*****************************************************************************
-void WinMTRDialog::SetPingSize(int ps)
+void WinMTRDialog::SetPingSize(WORD ps)
{
pingsize = ps;
}
@@ -547,44 +501,35 @@ void WinMTRDialog::OnRestart()
}
CString sHost;
-
if(state == IDLE) {
m_comboHost.GetWindowText(sHost);
- sHost.TrimLeft();
- sHost.TrimLeft();
-
+ sHost.TrimLeft(); sHost.TrimRight();
if(sHost.IsEmpty()) {
AfxMessageBox("No host specified!");
m_comboHost.SetFocus();
return ;
}
m_listMTR.DeleteAllItems();
- }
-
- if(state == IDLE) {
+ HKEY hKey; DWORD tmp_dword;
+ if(RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\WinMTR\\Config",0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&tmp_dword)==ERROR_SUCCESS){
+ tmp_dword=m_checkIPv6.GetCheck();
+ useIPv6=(unsigned char)tmp_dword;
+ RegSetValueEx(hKey,"UseIPv6",0,REG_DWORD,(const unsigned char*)&tmp_dword,sizeof(DWORD));
+ RegCloseKey(hKey);
+ }
if(InitMTRNet()) {
if(m_comboHost.FindString(-1, sHost) == CB_ERR) {
m_comboHost.InsertString(m_comboHost.GetCount() - 1,sHost);
-
- HKEY hKey;
- DWORD tmp_dword;
- LONG r;
char key_name[20];
-
- r = RegOpenKeyEx( HKEY_CURRENT_USER, "Software", 0, KEY_ALL_ACCESS,&hKey);
- r = RegOpenKeyEx( hKey, "WinMTR", 0, KEY_ALL_ACCESS, &hKey);
- r = RegOpenKeyEx( hKey, "LRU", 0, KEY_ALL_ACCESS, &hKey);
-
- if(nrLRU >= maxLRU)
- nrLRU = 0;
-
- nrLRU++;
- sprintf(key_name, "Host%d", nrLRU);
- r = RegSetValueEx(hKey,key_name, 0, REG_SZ, (const unsigned char *)(LPCTSTR)sHost, strlen((LPCTSTR)sHost)+1);
- tmp_dword = nrLRU;
- r = RegSetValueEx(hKey,"NrLRU", 0, REG_DWORD, (const unsigned char *)&tmp_dword, sizeof(DWORD));
- RegCloseKey(hKey);
+ if(RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\WinMTR\\LRU",0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&tmp_dword)==ERROR_SUCCESS){
+ if(++nrLRU>maxLRU) nrLRU=0;
+ sprintf(key_name, "Host%d", nrLRU);
+ RegSetValueEx(hKey,key_name, 0, REG_SZ, (const unsigned char*)(LPCTSTR)sHost, (DWORD)strlen((LPCTSTR)sHost)+1);
+ tmp_dword = nrLRU;
+ RegSetValueEx(hKey,"NrLRU", 0, REG_DWORD, (const unsigned char*)&tmp_dword, sizeof(DWORD));
+ RegCloseKey(hKey);
+ }
}
Transit(TRACING);
}
@@ -610,7 +555,7 @@ void WinMTRDialog::OnOptions()
if(IDOK == optDlg.DoModal()) {
- pingsize = optDlg.GetPingSize();
+ pingsize = (WORD)optDlg.GetPingSize();
interval = optDlg.GetInterval();
maxLRU = optDlg.GetMaxLRU();
useDNS = optDlg.GetUseDNS();
@@ -893,10 +838,10 @@ int WinMTRDialog::DisplayRedraw()
int nh = wmtrnet->GetMax();
while( m_listMTR.GetItemCount() > nh ) m_listMTR.DeleteItem(m_listMTR.GetItemCount() - 1);
- for(int i=0;i GetName(i, buf);
- if( strcmp(buf,"")==0 ) strcpy(buf,"No response from host");
+ if(!*buf) strcpy(buf,"No response from host");
sprintf(nr_crt, "%d", i+1);
if(m_listMTR.GetItemCount() <= i )
@@ -941,35 +886,33 @@ int WinMTRDialog::DisplayRedraw()
//*****************************************************************************
int WinMTRDialog::InitMTRNet()
{
- char strtmp[255];
- char *Hostname = strtmp;
+ char hostname[255];
char buf[255];
- struct hostent *host;
- m_comboHost.GetWindowText(strtmp, 255);
-
- if (Hostname == NULL) Hostname = "localhost";
-
- int isIP=1;
- char *t = Hostname;
- while(*t) {
- if(!isdigit(*t) && *t!='.') {
- isIP=0;
- break;
+ m_comboHost.GetWindowText(hostname, 255);
+
+ sprintf(buf, "Resolving host %s...", hostname);
+ statusBar.SetPaneText(0,buf);
+
+ addrinfo nfofilter={0};
+ addrinfo* anfo;
+ if(wmtrnet->hasIPv6){
+ switch(useIPv6){
+ case 0:
+ nfofilter.ai_family=AF_INET;break;
+ case 1:
+ nfofilter.ai_family=AF_INET6;break;
+ default:
+ nfofilter.ai_family=AF_UNSPEC;
}
- t++;
}
-
- if(!isIP) {
- sprintf(buf, "Resolving host %s...", strtmp);
- statusBar.SetPaneText(0,buf);
- host = gethostbyname(Hostname);
- if(host == NULL) {
- statusBar.SetPaneText(0, CString((LPCSTR)IDS_STRING_SB_NAME) );
- AfxMessageBox("Unable to resolve hostname.");
- return 0;
- }
+ nfofilter.ai_socktype=SOCK_RAW;
+ nfofilter.ai_flags=AI_NUMERICSERV|AI_ADDRCONFIG;//|AI_V4MAPPED;
+ if(getaddrinfo(hostname,NULL,&nfofilter,&anfo)||!anfo){
+ statusBar.SetPaneText(0, CString((LPCSTR)IDS_STRING_SB_NAME) );
+ AfxMessageBox("Unable to resolve hostname.");
+ return 0;
}
-
+ freeaddrinfo(anfo);
return 1;
}
@@ -984,44 +927,31 @@ void PingThread(void *p)
WinMTRDialog *wmtrdlg = (WinMTRDialog *)p;
WaitForSingleObject(wmtrdlg->traceThreadMutex, INFINITE);
- struct hostent *host, *lhost;
- char strtmp[255];
- char *Hostname = strtmp;
- int traddr;
- int localaddr;
-
- wmtrdlg->m_comboHost.GetWindowText(strtmp, 255);
-
- if (Hostname == NULL) Hostname = "localhost";
-
- int isIP=1;
- char *t = Hostname;
- while(*t) {
- if(!isdigit(*t) && *t!='.') {
- isIP=0;
- break;
+ char hostname[255];
+ wmtrdlg->m_comboHost.GetWindowText(hostname, 255);
+
+ addrinfo nfofilter={0};
+ addrinfo* anfo;
+ if(wmtrdlg->wmtrnet->hasIPv6){
+ switch(wmtrdlg->useIPv6){
+ case 0:
+ nfofilter.ai_family=AF_INET;break;
+ case 1:
+ nfofilter.ai_family=AF_INET6;break;
+ default:
+ nfofilter.ai_family=AF_UNSPEC;
}
- t++;
}
-
- if(!isIP) {
- host = gethostbyname(Hostname);
- traddr = *(int *)host->h_addr;
- } else
- traddr = inet_addr(Hostname);
-
- lhost = gethostbyname("localhost");
- if(lhost == NULL) {
- AfxMessageBox("Unable to get local IP address.");
- ReleaseMutex(wmtrdlg->traceThreadMutex);
- return;
+ nfofilter.ai_socktype=SOCK_RAW;
+ nfofilter.ai_flags=AI_NUMERICSERV|AI_ADDRCONFIG;//|AI_V4MAPPED;
+ if(getaddrinfo(hostname,NULL,&nfofilter,&anfo)||!anfo){//we use first address returned
+ AfxMessageBox("Unable to resolve hostname. (again)");
+ ReleaseMutex(wmtrdlg->traceThreadMutex);
+ return;
}
- localaddr = *(int *)lhost->h_addr;
-
- wmtrdlg->wmtrnet->DoTrace(traddr);
-
+ wmtrdlg->wmtrnet->DoTrace(anfo->ai_addr);
+ freeaddrinfo(anfo);
ReleaseMutex(wmtrdlg->traceThreadMutex);
- _endthread();
}
@@ -1137,57 +1067,53 @@ void WinMTRDialog::Transit(STATES new_state)
// modify controls according to new state
switch(transition) {
+ case IDLE_TO_IDLE:
+ // nothing to be done
+ break;
case IDLE_TO_TRACING:
m_buttonStart.EnableWindow(FALSE);
m_buttonStart.SetWindowText("Stop");
m_comboHost.EnableWindow(FALSE);
+ m_checkIPv6.EnableWindow(FALSE);
m_buttonOptions.EnableWindow(FALSE);
statusBar.SetPaneText(0, "Double click on host name for more information.");
_beginthread(PingThread, 0 , this);
m_buttonStart.EnableWindow(TRUE);
break;
- case IDLE_TO_IDLE:
- // nothing to be done
+ case IDLE_TO_EXIT:
+ m_buttonStart.EnableWindow(FALSE);
+ m_comboHost.EnableWindow(FALSE);
+ m_buttonOptions.EnableWindow(FALSE);
break;
case STOPPING_TO_IDLE:
+ DisplayRedraw();
m_buttonStart.EnableWindow(TRUE);
statusBar.SetPaneText(0, CString((LPCSTR)IDS_STRING_SB_NAME) );
m_buttonStart.SetWindowText("Start");
m_comboHost.EnableWindow(TRUE);
+ m_checkIPv6.EnableWindow(TRUE);
m_buttonOptions.EnableWindow(TRUE);
m_comboHost.SetFocus();
break;
case STOPPING_TO_STOPPING:
DisplayRedraw();
break;
+ case STOPPING_TO_EXIT:
+ break;
case TRACING_TO_TRACING:
DisplayRedraw();
break;
case TRACING_TO_STOPPING:
m_buttonStart.EnableWindow(FALSE);
- m_comboHost.EnableWindow(FALSE);
- m_buttonOptions.EnableWindow(FALSE);
wmtrnet->StopTrace();
statusBar.SetPaneText(0, "Waiting for last packets in order to stop trace ...");
DisplayRedraw();
break;
- case IDLE_TO_EXIT:
- m_buttonStart.EnableWindow(FALSE);
- m_comboHost.EnableWindow(FALSE);
- m_buttonOptions.EnableWindow(FALSE);
- break;
case TRACING_TO_EXIT:
m_buttonStart.EnableWindow(FALSE);
- m_comboHost.EnableWindow(FALSE);
- m_buttonOptions.EnableWindow(FALSE);
wmtrnet->StopTrace();
statusBar.SetPaneText(0, "Waiting for last packets in order to stop trace ...");
break;
- case STOPPING_TO_EXIT:
- m_buttonStart.EnableWindow(FALSE);
- m_comboHost.EnableWindow(FALSE);
- m_buttonOptions.EnableWindow(FALSE);
- break;
default:
TRACE_MSG("Unknown transition " << transition);
}
@@ -1196,22 +1122,18 @@ void WinMTRDialog::Transit(STATES new_state)
void WinMTRDialog::OnTimer(UINT_PTR nIDEvent)
{
- static unsigned int call_count = 0;
- call_count += 1;
-
+ static unsigned int call_count=0;
if(state == EXIT && WaitForSingleObject(traceThreadMutex, 0) == WAIT_OBJECT_0) {
ReleaseMutex(traceThreadMutex);
OnOK();
}
-
if( WaitForSingleObject(traceThreadMutex, 0) == WAIT_OBJECT_0 ) {
ReleaseMutex(traceThreadMutex);
Transit(IDLE);
- } else if( (call_count % 10 == 0) && (WaitForSingleObject(traceThreadMutex, 0) == WAIT_TIMEOUT) ) {
- ReleaseMutex(traceThreadMutex);
- if( state == TRACING) Transit(TRACING);
- else if( state == STOPPING) Transit(STOPPING);
+ }else if((++call_count&5)==5){
+ if(state==TRACING) Transit(TRACING);
+ else if(state==STOPPING) Transit(STOPPING);
}
CDialog::OnTimer(nIDEvent);
diff --git a/src/WinMTRDialog.h b/src/WinMTRDialog.h
index a214d7b..3ac6534 100644
--- a/src/WinMTRDialog.h
+++ b/src/WinMTRDialog.h
@@ -17,6 +17,7 @@
#include "WinMTRStatusBar.h"
#include "WinMTRNet.h"
+#include "afxlinkctrl.h"
//*****************************************************************************
// CLASS: WinMTRDialog
@@ -59,7 +60,9 @@ class WinMTRDialog : public CDialog
CButton m_buttonExit;
CButton m_buttonStart;
CComboBox m_comboHost;
- CListCtrl m_listMTR;
+ CButton m_checkIPv6;
+ CListCtrl m_listMTR;
+ CMFCLinkCtrl m_buttonAppnor;
CStatic m_staticS;
CStatic m_staticJ;
@@ -77,18 +80,20 @@ class WinMTRDialog : public CDialog
HANDLE traceThreadMutex;
double interval;
bool hasIntervalFromCmdLine;
- int pingsize;
+ WORD pingsize;
bool hasPingsizeFromCmdLine;
int maxLRU;
bool hasMaxLRUFromCmdLine;
int nrLRU;
BOOL useDNS;
bool hasUseDNSFromCmdLine;
+ unsigned char useIPv6;
+ bool hasUseIPv6FromCmdLine;
WinMTRNet* wmtrnet;
void SetHostName(const char *host);
void SetInterval(float i);
- void SetPingSize(int ps);
+ void SetPingSize(WORD ps);
void SetMaxLRU(int mlru);
void SetUseDNS(BOOL udns);
diff --git a/src/WinMTRGlobal.cpp b/src/WinMTRGlobal.cpp
index 0f435c8..053fba1 100644
--- a/src/WinMTRGlobal.cpp
+++ b/src/WinMTRGlobal.cpp
@@ -11,7 +11,7 @@
//
// win32 port of unix gettimeofday
//*****************************************************************************
-int gettimeofday(struct timeval* tv, struct timezone *tz)
+int gettimeofday(struct timeval* tv, struct timezone* /*tz*/)
{
if(!tv)
return -1;
@@ -19,7 +19,7 @@ int gettimeofday(struct timeval* tv, struct timezone *tz)
_ftime(&timebuffer);
- tv->tv_sec = timebuffer.time;
+ tv->tv_sec = (long)timebuffer.time;
tv->tv_usec = timebuffer.millitm * 1000 + 500;
return 0;
}
diff --git a/src/WinMTRGlobal.h b/src/WinMTRGlobal.h
index 53524ee..3f3102e 100644
--- a/src/WinMTRGlobal.h
+++ b/src/WinMTRGlobal.h
@@ -28,6 +28,8 @@
#include
#endif
#include
+#include //IP_OPTION_INFORMATION32
+#include //sockaddr_in6
#include
#include
@@ -46,10 +48,9 @@
#include "resource.h"
-#define WINMTR_VERSION "0.9"
-#define WINMTR_LICENSE "GPL - GNU Public License"
-#define WINMTR_COPYRIGHT "WinMTR 0.9 (c) 2010-2011 Appnor MSP - Fully Managed Hosting & Cloud Provider www.appnor.com"
-#define WINMTR_HOMEPAGE "http://WinMTR.sourceforge.net"
+#define WINMTR_VERSION "1.0"
+#define WINMTR_LICENSE "GPLv2 - GNU General Public License, version 2"
+#define WINMTR_HOMEPAGE "https://github.com/White-Tiger/WinMTR"
#define DEFAULT_PING_SIZE 64
#define DEFAULT_INTERVAL 1.0
@@ -98,7 +99,7 @@ const char MTR_COLS[ MTR_NR_COLS ][10] = {
};
const int MTR_COL_LENGTH[ MTR_NR_COLS ] = {
- 190, 30, 50, 40, 40, 50, 50, 50, 50
+ 249, 30, 50, 40, 40, 50, 50, 50, 50
};
int gettimeofday(struct timeval* tv, struct timezone *tz);
diff --git a/src/WinMTRMain.cpp b/src/WinMTRMain.cpp
index 7e740fe..581583f 100644
--- a/src/WinMTRMain.cpp
+++ b/src/WinMTRMain.cpp
@@ -61,6 +61,8 @@ WinMTRMain::WinMTRMain()
//*****************************************************************************
BOOL WinMTRMain::InitInstance()
{
+ INITCOMMONCONTROLSEX icex={sizeof(INITCOMMONCONTROLSEX),ICC_STANDARD_CLASSES};
+ InitCommonControlsEx(&icex);
if (!AfxSocketInit())
{
AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
@@ -68,10 +70,6 @@ BOOL WinMTRMain::InitInstance()
}
AfxEnableControlContainer();
-
-#ifdef _AFXDLL
- Enable3dControls(); // Call this when using MFC in a shared DLL
-#endif
WinMTRDialog mtrDialog;
@@ -82,7 +80,7 @@ BOOL WinMTRMain::InitInstance()
ParseCommandLineParams(m_lpCmdLine, &mtrDialog);
}
- int nResponse = mtrDialog.DoModal();
+ mtrDialog.DoModal();
return FALSE;
@@ -114,17 +112,25 @@ void WinMTRMain::ParseCommandLineParams(LPTSTR cmd, WinMTRDialog *wmtrdlg)
wmtrdlg->hasIntervalFromCmdLine = true;
}
if(GetParamValue(cmd, "size",'s', value)) {
- wmtrdlg->SetPingSize(atoi(value));
+ wmtrdlg->SetPingSize((WORD)atoi(value));
wmtrdlg->hasPingsizeFromCmdLine = true;
}
if(GetParamValue(cmd, "maxLRU",'m', value)) {
wmtrdlg->SetMaxLRU(atoi(value));
wmtrdlg->hasMaxLRUFromCmdLine = true;
}
- if(GetParamValue(cmd, "numeric",'n', value)) {
+ if(GetParamValue(cmd, "numeric",'n', NULL)) {
wmtrdlg->SetUseDNS(FALSE);
wmtrdlg->hasUseDNSFromCmdLine = true;
}
+ if(GetParamValue(cmd, "ipv6",'6', NULL)) {
+ wmtrdlg->hasUseIPv6FromCmdLine=true;
+ wmtrdlg->useIPv6=1;
+ }
+ if(GetParamValue(cmd, "ipv4",'4', NULL)) {
+ wmtrdlg->hasUseIPv6FromCmdLine=true;
+ wmtrdlg->useIPv6=0;
+ }
}
//*****************************************************************************
@@ -149,7 +155,7 @@ int WinMTRMain::GetParamValue(LPTSTR cmd, char * param, char sparam, char *value
if(p == NULL)
return 0;
- if(strcmp(param,"numeric")==0)
+ if(!value)
return 1;
while(*p && *p!=' ')
@@ -172,7 +178,7 @@ int WinMTRMain::GetParamValue(LPTSTR cmd, char * param, char sparam, char *value
int WinMTRMain::GetHostNameParamValue(LPTSTR cmd, std::string& host_name)
{
// WinMTR -h -i 1 -n google.com
- int size = strlen(cmd);
+ size_t size = strlen(cmd);
std::string name = "";
while(cmd[--size] == ' ');
@@ -200,7 +206,7 @@ int WinMTRMain::GetHostNameParamValue(LPTSTR cmd, std::string& host_name)
possible_argument = cmd[size] + possible_argument;
}
- if(possible_argument.length() && (possible_argument[0] != '-' || possible_argument == "-n" || possible_argument == "--numeric")) {
+ if(possible_argument.length() && (possible_argument[0] != '-' || possible_argument == "-n" || possible_argument == "--numeric" || possible_argument == "-6" || possible_argument == "--ipv6" || possible_argument == "-4" || possible_argument == "--ipv4")) {
host_name = name;
return 1;
}
diff --git a/src/WinMTRNet.cpp b/src/WinMTRNet.cpp
index 7c5e8ae..bcc8a6d 100644
--- a/src/WinMTRNet.cpp
+++ b/src/WinMTRNet.cpp
@@ -19,22 +19,29 @@
#define MAX_HOPS 30
struct trace_thread {
- int address;
- WinMTRNet *winmtr;
+ WinMTRNet* winmtr;
+ in_addr address;
int ttl;
};
+struct trace_thread6 {
+ WinMTRNet* winmtr;
+ sockaddr_in6 address;
+ int ttl;
+};
struct dns_resolver_thread {
+ WinMTRNet* winmtr;
int index;
- WinMTRNet *winmtr;
};
-void TraceThread(void *p);
+unsigned WINAPI TraceThread(void *p);
+unsigned WINAPI TraceThread6(void *p);
void DnsResolverThread(void *p);
WinMTRNet::WinMTRNet(WinMTRDialog *wp) {
ghMutex = CreateMutex(NULL, FALSE, NULL);
+ hasIPv6=true;
tracing=false;
initialized = false;
wmtrdlg = wp;
@@ -44,32 +51,61 @@ WinMTRNet::WinMTRNet(WinMTRDialog *wp) {
AfxMessageBox("Failed initializing windows sockets library!");
return;
}
-
- hICMP_DLL = LoadLibrary(_T("ICMP.DLL"));
- if (hICMP_DLL == 0) {
- AfxMessageBox("Failed: Unable to locate ICMP.DLL!");
- return;
- }
+ OSVERSIONINFOEX osvi={0};
+ osvi.dwOSVersionInfoSize=sizeof(OSVERSIONINFOEX);
+ if(!GetVersionEx((OSVERSIONINFO*) &osvi)){
+ AfxMessageBox("Failed to get Windows version!");
+ return;
+ }
+ if(osvi.dwMajorVersion==5 && osvi.dwMinorVersion==0){//w2k
+ hICMP_DLL=LoadLibrary(_T("ICMP.DLL"));
+ if(!hICMP_DLL){
+ AfxMessageBox("Failed: Unable to locate ICMP.DLL!");
+ return;
+ }
+ }else{
+ hICMP_DLL=LoadLibrary(_T("Iphlpapi.dll"));
+ if(!hICMP_DLL){
+ AfxMessageBox("Failed: Unable to locate Iphlpapi.dll!");
+ return;
+ }
+ }
/*
* Get pointers to ICMP.DLL functions
*/
+ //IPv4
lpfnIcmpCreateFile = (LPFNICMPCREATEFILE)GetProcAddress(hICMP_DLL,"IcmpCreateFile");
lpfnIcmpCloseHandle = (LPFNICMPCLOSEHANDLE)GetProcAddress(hICMP_DLL,"IcmpCloseHandle");
- lpfnIcmpSendEcho = (LPFNICMPSENDECHO)GetProcAddress(hICMP_DLL,"IcmpSendEcho");
- if ((!lpfnIcmpCreateFile) || (!lpfnIcmpCloseHandle) || (!lpfnIcmpSendEcho)) {
- AfxMessageBox("Wrong ICMP.DLL system library !");
+ lpfnIcmpSendEcho2 = (LPFNICMPSENDECHO2)GetProcAddress(hICMP_DLL,"IcmpSendEcho2");
+ if (!lpfnIcmpCreateFile || !lpfnIcmpCloseHandle || !lpfnIcmpSendEcho2) {
+ AfxMessageBox("Wrong ICMP system library !");
return;
}
+ //IPv6
+ lpfnIcmp6CreateFile=(LPFNICMP6CREATEFILE)GetProcAddress(hICMP_DLL,"Icmp6CreateFile");
+ lpfnIcmp6SendEcho2=(LPFNICMP6SENDECHO2)GetProcAddress(hICMP_DLL,"Icmp6SendEcho2");
+ if(!lpfnIcmp6CreateFile || !lpfnIcmp6SendEcho2){
+ hasIPv6=false;
+ AfxMessageBox("IPv6 support not found!");
+ return;//@todo : soft fail
+ }
/*
* IcmpCreateFile() - Open the ping service
*/
hICMP = (HANDLE) lpfnIcmpCreateFile();
if (hICMP == INVALID_HANDLE_VALUE) {
- AfxMessageBox("Error in ICMP.DLL !");
+ AfxMessageBox("Error in ICMP module!");
return;
}
+ if(hasIPv6){
+ hICMP6=(HANDLE)lpfnIcmp6CreateFile();
+ if(hICMP6==INVALID_HANDLE_VALUE){
+ AfxMessageBox("Error in ICMPv6 module!");
+ return;//@todo : soft fail
+ }
+ }
ResetHops();
@@ -83,6 +119,7 @@ WinMTRNet::~WinMTRNet()
/*
* IcmpCloseHandle - Close the ICMP handle
*/
+ if(hasIPv6) lpfnIcmpCloseHandle(hICMP6);
lpfnIcmpCloseHandle(hICMP);
// Shut down...
@@ -96,37 +133,42 @@ WinMTRNet::~WinMTRNet()
void WinMTRNet::ResetHops()
{
- for(int i = 0; i < MaxHost;i++) {
- host[i].addr = 0;
- host[i].xmit = 0;
- host[i].returned = 0;
- host[i].total = 0;
- host[i].last = 0;
- host[i].best = 0;
- host[i].worst = 0;
- memset(host[i].name,0,sizeof(host[i].name));
- }
+ memset(host,0,sizeof(host));
}
-void WinMTRNet::DoTrace(int address)
+void WinMTRNet::DoTrace(sockaddr* sockaddr)
{
HANDLE hThreads[MAX_HOPS];
+ unsigned char hops=0;
tracing = true;
-
ResetHops();
-
- last_remote_addr = address;
-
- // one thread per TTL value
- for(int i = 0; i < MAX_HOPS; i++) {
- trace_thread *current = new trace_thread;
- current->address = address;
- current->winmtr = this;
- current->ttl = i + 1;
- hThreads[i] = (HANDLE)_beginthread(TraceThread, 0 , current);
+ if(sockaddr->sa_family==AF_INET6){
+ host[0].addr6.sin6_family=AF_INET6;
+ last_remote_addr6=((sockaddr_in6*)sockaddr)->sin6_addr;
+ for(; hopsaddress=*(sockaddr_in6*)sockaddr;
+ current->winmtr=this;
+ current->ttl=hops+1;
+ hThreads[hops]=(HANDLE)_beginthreadex(NULL,0,TraceThread6,current,0,NULL);
+ Sleep(30);
+ if(++hops>this->GetMax()) break;
+ }
+ }else{
+ host[0].addr.sin_family=AF_INET;
+ last_remote_addr=((sockaddr_in*)sockaddr)->sin_addr;
+ for(; hopsaddress=((sockaddr_in*)sockaddr)->sin_addr;
+ current->winmtr=this;
+ current->ttl=hops+1;
+ hThreads[hops]=(HANDLE)_beginthreadex(NULL,0,TraceThread,current,0,NULL);
+ Sleep(30);
+ if(++hops>this->GetMax()) break;
+ }
}
-
- WaitForMultipleObjects(MAX_HOPS, hThreads, TRUE, INFINITE);
+ WaitForMultipleObjects(hops, hThreads, TRUE, INFINITE);
+ for(; hops; ) CloseHandle(hThreads[--hops]);
}
void WinMTRNet::StopTrace()
@@ -134,24 +176,27 @@ void WinMTRNet::StopTrace()
tracing = false;
}
-void TraceThread(void *p)
+unsigned WINAPI TraceThread(void *p)
{
trace_thread* current = (trace_thread*)p;
WinMTRNet *wmtrnet = current->winmtr;
- TRACE_MSG("Threaad with TTL=" << current->ttl << " started.");
+ TRACE_MSG("Thread with TTL=" << (int)current->ttl << " started.");
IPINFO stIPInfo, *lpstIPInfo;
DWORD dwReplyCount;
char achReqData[8192];
- int nDataLen = wmtrnet->wmtrdlg->pingsize;
- char achRepData[sizeof(ICMPECHO) + 8192];
+ WORD nDataLen = wmtrnet->wmtrdlg->pingsize;
+ union{
+ ICMP_ECHO_REPLY icmp_echo_reply;
+ char achRepData[sizeof(ICMPECHO)+8192];
+ };
/*
* Init IPInfo structure
*/
lpstIPInfo = &stIPInfo;
- stIPInfo.Ttl = current->ttl;
+ stIPInfo.Ttl = (UCHAR)current->ttl;
stIPInfo.Tos = 0;
stIPInfo.Flags = IPFLAG_DONT_FRAGMENT;
stIPInfo.OptionsSize = 0;
@@ -172,117 +217,107 @@ void TraceThread(void *p)
// - as soon as we get a hop, we start pinging directly that hop, with a greater TTL
// - a drawback would be that, some servers are configured to reply for TTL transit expire, but not to ping requests, so,
// for these servers we'll have 100% loss
- dwReplyCount = wmtrnet->lpfnIcmpSendEcho(wmtrnet->hICMP, current->address, achReqData, nDataLen, lpstIPInfo, achRepData, sizeof(achRepData), ECHO_REPLY_TIMEOUT);
-
- PICMPECHO icmp_echo_reply = (PICMPECHO)achRepData;
+ dwReplyCount = wmtrnet->lpfnIcmpSendEcho2(wmtrnet->hICMP, 0,NULL,NULL, current->address, achReqData, nDataLen, lpstIPInfo, achRepData, sizeof(achRepData), ECHO_REPLY_TIMEOUT);
wmtrnet->AddXmit(current->ttl - 1);
- if (dwReplyCount != 0) {
- TRACE_MSG("TTL " << current->ttl << " reply TTL " << icmp_echo_reply->Options.Ttl << " Status " << icmp_echo_reply->Status << " Reply count " << dwReplyCount);
+ if(dwReplyCount){
+ TRACE_MSG("TTL " << (int)current->ttl << " reply TTL " << (int)icmp_echo_reply.Options.Ttl << " Status " << icmp_echo_reply.Status << " Reply count " << dwReplyCount);
- switch(icmp_echo_reply->Status) {
+ switch(icmp_echo_reply.Status) {
case IP_SUCCESS:
case IP_TTL_EXPIRED_TRANSIT:
- wmtrnet->SetLast(current->ttl - 1, icmp_echo_reply->RoundTripTime);
- wmtrnet->SetBest(current->ttl - 1, icmp_echo_reply->RoundTripTime);
- wmtrnet->SetWorst(current->ttl - 1, icmp_echo_reply->RoundTripTime);
+ wmtrnet->UpdateRTT(current->ttl - 1, icmp_echo_reply.RoundTripTime);
wmtrnet->AddReturned(current->ttl - 1);
- wmtrnet->SetAddr(current->ttl - 1, icmp_echo_reply->Address);
- break;
- case IP_BUF_TOO_SMALL:
- wmtrnet->SetName(current->ttl - 1, "Reply buffer too small.");
- break;
- case IP_DEST_NET_UNREACHABLE:
- wmtrnet->SetName(current->ttl - 1, "Destination network unreachable.");
- break;
- case IP_DEST_HOST_UNREACHABLE:
- wmtrnet->SetName(current->ttl - 1, "Destination host unreachable.");
- break;
- case IP_DEST_PROT_UNREACHABLE:
- wmtrnet->SetName(current->ttl - 1, "Destination protocol unreachable.");
- break;
- case IP_DEST_PORT_UNREACHABLE:
- wmtrnet->SetName(current->ttl - 1, "Destination port unreachable.");
- break;
- case IP_NO_RESOURCES:
- wmtrnet->SetName(current->ttl - 1, "Insufficient IP resources were available.");
- break;
- case IP_BAD_OPTION:
- wmtrnet->SetName(current->ttl - 1, "Bad IP option was specified.");
- break;
- case IP_HW_ERROR:
- wmtrnet->SetName(current->ttl - 1, "Hardware error occurred.");
- break;
- case IP_PACKET_TOO_BIG:
- wmtrnet->SetName(current->ttl - 1, "Packet was too big.");
- break;
- case IP_REQ_TIMED_OUT:
- wmtrnet->SetName(current->ttl - 1, "Request timed out.");
- break;
- case IP_BAD_REQ:
- wmtrnet->SetName(current->ttl - 1, "Bad request.");
- break;
- case IP_BAD_ROUTE:
- wmtrnet->SetName(current->ttl - 1, "Bad route.");
- break;
- case IP_TTL_EXPIRED_REASSEM:
- wmtrnet->SetName(current->ttl - 1, "The time to live expired during fragment reassembly.");
- break;
- case IP_PARAM_PROBLEM:
- wmtrnet->SetName(current->ttl - 1, "Parameter problem.");
- break;
- case IP_SOURCE_QUENCH:
- wmtrnet->SetName(current->ttl - 1, "Datagrams are arriving too fast to be processed and datagrams may have been discarded.");
- break;
- case IP_OPTION_TOO_BIG:
- wmtrnet->SetName(current->ttl - 1, "An IP option was too big.");
- break;
- case IP_BAD_DESTINATION:
- wmtrnet->SetName(current->ttl - 1, "Bad destination.");
- break;
- case IP_GENERAL_FAILURE:
- wmtrnet->SetName(current->ttl - 1, "General failure.");
+ wmtrnet->SetAddr(current->ttl - 1, icmp_echo_reply.Address);
break;
default:
- wmtrnet->SetName(current->ttl - 1, "General failure.");
+ wmtrnet->SetErrorName(current->ttl - 1, icmp_echo_reply.Status);
}
- if(wmtrnet->wmtrdlg->interval * 1000 > icmp_echo_reply->RoundTripTime)
- Sleep(wmtrnet->wmtrdlg->interval * 1000 - icmp_echo_reply->RoundTripTime);
+ if((DWORD)(wmtrnet->wmtrdlg->interval * 1000) > icmp_echo_reply.RoundTripTime)
+ Sleep((DWORD)(wmtrnet->wmtrdlg->interval * 1000) - icmp_echo_reply.RoundTripTime);
+ }else{
+ DWORD err=GetLastError();
+ wmtrnet->SetErrorName(current->ttl - 1, err);
+ switch(err){
+ case IP_REQ_TIMED_OUT: break;
+ default:
+ Sleep((DWORD)(wmtrnet->wmtrdlg->interval * 1000));
+ }
}
-
} /* end ping loop */
- TRACE_MSG("Thread with TTL=" << current->ttl << " stopped.");
+ TRACE_MSG("Thread with TTL=" << (int)current->ttl << " stopped.");
delete p;
- _endthread();
+ return 0;
}
-int WinMTRNet::GetAddr(int at)
+unsigned WINAPI TraceThread6(void* p)
{
- WaitForSingleObject(ghMutex, INFINITE);
- int addr = ntohl(host[at].addr);
- ReleaseMutex(ghMutex);
- return addr;
+ static sockaddr_in6 sockaddrfrom={AF_INET6,0,0,in6addr_any,0};
+ trace_thread6* current = (trace_thread6*)p;
+ WinMTRNet* wmtrnet = current->winmtr;
+ TRACE_MSG("Thread with TTL=" << (int)current->ttl << " started.");
+
+ IPINFO stIPInfo, *lpstIPInfo;
+ DWORD dwReplyCount;
+ char achReqData[8192];
+ WORD nDataLen = wmtrnet->wmtrdlg->pingsize;
+ union{
+ ICMPV6_ECHO_REPLY icmpv6_echo_reply;
+ char achRepData[sizeof(PICMPV6_ECHO_REPLY) + 8192];
+ };
+
+ lpstIPInfo = &stIPInfo;
+ stIPInfo.Ttl = (UCHAR)current->ttl;
+ stIPInfo.Tos = 0;
+ stIPInfo.Flags = IPFLAG_DONT_FRAGMENT;
+ stIPInfo.OptionsSize = 0;
+ stIPInfo.OptionsData = NULL;
+ for(int i=0; itracing){
+ if(current->ttl > wmtrnet->GetMax()) break;
+ dwReplyCount = wmtrnet->lpfnIcmp6SendEcho2(wmtrnet->hICMP6, 0,NULL,NULL, &sockaddrfrom, ¤t->address, achReqData, nDataLen, lpstIPInfo, achRepData, sizeof(achRepData), ECHO_REPLY_TIMEOUT);
+ wmtrnet->AddXmit(current->ttl - 1);
+ if(dwReplyCount) {
+ TRACE_MSG("TTL " << (int)current->ttl << " Status " << icmpv6_echo_reply.Status << " Reply count " << dwReplyCount);
+ switch(icmpv6_echo_reply.Status) {
+ case IP_SUCCESS:
+ case IP_TTL_EXPIRED_TRANSIT:
+ wmtrnet->UpdateRTT(current->ttl - 1, icmpv6_echo_reply.RoundTripTime);
+ wmtrnet->AddReturned(current->ttl - 1);
+ wmtrnet->SetAddr6(current->ttl - 1, icmpv6_echo_reply.Address);
+ break;
+ default:
+ wmtrnet->SetErrorName(current->ttl - 1, icmpv6_echo_reply.Status);
+ }
+ if((DWORD)(wmtrnet->wmtrdlg->interval * 1000) > icmpv6_echo_reply.RoundTripTime)
+ Sleep((DWORD)(wmtrnet->wmtrdlg->interval * 1000) - icmpv6_echo_reply.RoundTripTime);
+ }else{
+ DWORD err=GetLastError();
+ wmtrnet->SetErrorName(current->ttl - 1, err);
+ switch(err){
+ case IP_REQ_TIMED_OUT: break;
+ default:
+ Sleep((DWORD)(wmtrnet->wmtrdlg->interval * 1000));
+ }
+ }
+ }//end loop
+ TRACE_MSG("Thread with TTL=" << (int)current->ttl << " stopped.");
+ delete p;
+ return 0;
+}
+
+sockaddr* WinMTRNet::GetAddr(int at)
+{
+ return (sockaddr*)&host[at].addr;
}
int WinMTRNet::GetName(int at, char *n)
{
WaitForSingleObject(ghMutex, INFINITE);
- if(!strcmp(host[at].name, "")) {
- int addr = GetAddr(at);
- sprintf ( n, "%d.%d.%d.%d",
- (addr >> 24) & 0xff,
- (addr >> 16) & 0xff,
- (addr >> 8) & 0xff,
- addr & 0xff
- );
- if(addr==0)
- strcpy(n,"");
- } else {
- strcpy(n, host[at].name);
- }
+ strcpy(n, host[at].name);
ReleaseMutex(ghMutex);
return 0;
}
@@ -344,112 +379,165 @@ int WinMTRNet::GetXmit(int at)
}
int WinMTRNet::GetMax()
-{
+{// @todo : improve this (last hop guess)
WaitForSingleObject(ghMutex, INFINITE);
- int max = MAX_HOPS;
-
- // first match: traced address responds on ping requests, and the address is in the hosts list
- for(int i = 0; i < MAX_HOPS; i++) {
- if(host[i].addr == last_remote_addr) {
- max = i + 1;
- break;
+ int max=0;//first try to find target, if not found, find best guess (doesn't work actually :P)
+ if(host[0].addr6.sin6_family==AF_INET6){
+ for(; max1 && !memcmp(&host[max-1].addr6.sin6_addr,&host[max-2].addr6.sin6_addr,sizeof(in6_addr)) && (host[max-1].addr6.sin6_addr.u.Word[0]|host[max-1].addr6.sin6_addr.u.Word[1]|host[max-1].addr6.sin6_addr.u.Word[2]|host[max-1].addr6.sin6_addr.u.Word[3]|host[max-1].addr6.sin6_addr.u.Word[4]|host[max-1].addr6.sin6_addr.u.Word[5]|host[max-1].addr6.sin6_addr.u.Word[6]|host[max-1].addr6.sin6_addr.u.Word[7])) --max;
+ }
+ }else{
+ for(; max1 && host[max-1].addr.sin_addr.s_addr==host[max-2].addr.sin_addr.s_addr && host[max-1].addr.sin_addr.s_addr) --max;
}
}
-
- // second match: traced address doesn't responds on ping requests
- if(max == MAX_HOPS) {
- while((max > 1) && (host[max - 1].addr == host[max - 2].addr) && (host[max - 1].addr != 0) ) max--;
- }
-
ReleaseMutex(ghMutex);
return max;
}
-void WinMTRNet::SetAddr(int at, __int32 addr)
+void WinMTRNet::SetAddr(int at, u_long addr)
{
WaitForSingleObject(ghMutex, INFINITE);
- if(host[at].addr == 0 && addr != 0) {
- TRACE_MSG("Start DnsResolverThread for new address " << addr << ". Old addr value was " << host[at].addr);
- host[at].addr = addr;
- dns_resolver_thread *dnt = new dns_resolver_thread;
- dnt->index = at;
- dnt->winmtr = this;
+ if(host[at].addr.sin_addr.s_addr==0){
+ TRACE_MSG("Start DnsResolverThread for new address " << addr << ". Old addr value was " << host[at].addr.sin_addr.s_addr);
+ host[at].addr.sin_family=AF_INET;
+ host[at].addr.sin_addr.s_addr=addr;
+ dns_resolver_thread *dnt=new dns_resolver_thread;
+ dnt->index=at;
+ dnt->winmtr=this;
if(wmtrdlg->useDNS) _beginthread(DnsResolverThread, 0, dnt);
+ else DnsResolverThread(dnt);
}
-
ReleaseMutex(ghMutex);
}
-void WinMTRNet::SetName(int at, char *n)
+void WinMTRNet::SetAddr6(int at, IPV6_ADDRESS_EX addrex)
{
WaitForSingleObject(ghMutex, INFINITE);
- strcpy(host[at].name, n);
+ if(!(host[at].addr6.sin6_addr.u.Word[0]|host[at].addr6.sin6_addr.u.Word[1]|host[at].addr6.sin6_addr.u.Word[2]|host[at].addr6.sin6_addr.u.Word[3]|host[at].addr6.sin6_addr.u.Word[4]|host[at].addr6.sin6_addr.u.Word[5]|host[at].addr6.sin6_addr.u.Word[6]|host[at].addr6.sin6_addr.u.Word[7])){
+ TRACE_MSG("Start DnsResolverThread for new address " << addrex.sin6_addr[0] << ". Old addr value was " << host[at].addr6.sin6_addr.u.Word[0]);
+ host[at].addr6.sin6_family=AF_INET6;
+ host[at].addr6.sin6_addr=*(in6_addr*)&addrex.sin6_addr;
+ dns_resolver_thread* dnt=new dns_resolver_thread;
+ dnt->index=at;
+ dnt->winmtr=this;
+ if(wmtrdlg->useDNS) _beginthread(DnsResolverThread,0,dnt);
+ else DnsResolverThread(dnt);
+ }
ReleaseMutex(ghMutex);
}
-void WinMTRNet::SetBest(int at, int current)
+void WinMTRNet::SetName(int at, char *n)
{
WaitForSingleObject(ghMutex, INFINITE);
- if(host[at].best > current || host[at].xmit == 1) {
- host[at].best = current;
- };
- if(host[at].worst < current) {
- host[at].worst = current;
- }
-
+ strcpy(host[at].name, n);
ReleaseMutex(ghMutex);
}
-void WinMTRNet::SetWorst(int at, int current)
-{
+void WinMTRNet::SetErrorName(int at, DWORD errnum){
+ const char* name;
+ switch(errnum){
+ case IP_BUF_TOO_SMALL:
+ name="Reply buffer too small.";break;
+ case IP_DEST_NET_UNREACHABLE:
+ name="Destination network unreachable.";break;
+ case IP_DEST_HOST_UNREACHABLE:
+ name="Destination host unreachable.";break;
+ case IP_DEST_PROT_UNREACHABLE:
+ name="Destination protocol unreachable.";break;
+ case IP_DEST_PORT_UNREACHABLE:
+ name="Destination port unreachable.";break;
+ case IP_NO_RESOURCES:
+ name="Insufficient IP resources were available.";break;
+ case IP_BAD_OPTION:
+ name="Bad IP option was specified.";break;
+ case IP_HW_ERROR:
+ name="Hardware error occurred.";break;
+ case IP_PACKET_TOO_BIG:
+ name="Packet was too big.";break;
+ case IP_REQ_TIMED_OUT:
+ name="Request timed out.";break;
+ case IP_BAD_REQ:
+ name="Bad request.";break;
+ case IP_BAD_ROUTE:
+ name="Bad route.";break;
+ case IP_TTL_EXPIRED_REASSEM:
+ name="The time to live expired during fragment reassembly.";break;
+ case IP_PARAM_PROBLEM:
+ name="Parameter problem.";break;
+ case IP_SOURCE_QUENCH:
+ name="Datagrams are arriving too fast to be processed and datagrams may have been discarded.";break;
+ case IP_OPTION_TOO_BIG:
+ name="An IP option was too big.";break;
+ case IP_BAD_DESTINATION:
+ name="Bad destination.";break;
+ case IP_GENERAL_FAILURE:
+ name="General failure.";break;
+ default:
+ TRACE_MSG("==UNKNOWN ERROR== " << errnum);
+ name="Unknown error! (please report)";break;
+ }
WaitForSingleObject(ghMutex, INFINITE);
+ if(!*host[at].name)
+ strcpy(host[at].name,name);
ReleaseMutex(ghMutex);
}
-void WinMTRNet::SetLast(int at, int last)
+void WinMTRNet::UpdateRTT(int at, int rtt)
{
WaitForSingleObject(ghMutex, INFINITE);
- host[at].last = last;
- host[at].total += last;
+ host[at].last=rtt;
+ host[at].total+=rtt;
+ if(host[at].best>rtt || host[at].xmit==1)
+ host[at].best=rtt;
+ if(host[at].worstwinmtr;
+ dns_resolver_thread* dnt=(dns_resolver_thread*)p;
+ WinMTRNet* wn=dnt->winmtr;
+ char hostname[NI_MAXHOST];
+ if(!getnameinfo(wn->GetAddr(dnt->index),sizeof(sockaddr_in6),hostname,NI_MAXHOST,NULL,0,NI_NUMERICHOST)){
+ wn->SetName(dnt->index,hostname);
+ }
+ if(wn->wmtrdlg->useDNS){
+ TRACE_MSG("DNS resolver thread started.");
+ if(!getnameinfo(wn->GetAddr(dnt->index),sizeof(sockaddr_in6),hostname,NI_MAXHOST,NULL,0,0)){
+ wn->SetName(dnt->index,hostname);
+ }
+ TRACE_MSG("DNS resolver thread stopped.");
+ }
+ delete p;
+}
+
+
+
+
+
+
+
+
+
- struct hostent *phent ;
- char buf[100];
- int addr = wn->GetAddr(dnt->index);
- sprintf (buf, "%d.%d.%d.%d", (addr >> 24) & 0xff, (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff);
- int haddr = htonl(addr);
- phent = gethostbyaddr( (const char*)&haddr, sizeof(int), AF_INET);
- if(phent) {
- wn->SetName(dnt->index, phent->h_name);
- } else {
- wn->SetName(dnt->index, buf);
- }
-
- delete p;
- TRACE_MSG("DNS resolver thread stopped.");
- _endthread();
-}
diff --git a/src/WinMTRNet.h b/src/WinMTRNet.h
index a372a57..d3206d6 100644
--- a/src/WinMTRNet.h
+++ b/src/WinMTRNet.h
@@ -16,18 +16,20 @@
class WinMTRDialog;
-typedef ip_option_information IPINFO, *PIPINFO, FAR *LPIPINFO;
-
+typedef IP_OPTION_INFORMATION IPINFO, *PIPINFO, FAR *LPIPINFO;
#ifdef _WIN64
-typedef icmp_echo_reply32 ICMPECHO, *PICMPECHO, FAR *LPICMPECHO;
+typedef ICMP_ECHO_REPLY32 ICMPECHO, *PICMPECHO, FAR *LPICMPECHO;
#else
-typedef icmp_echo_reply ICMPECHO, *PICMPECHO, FAR *LPICMPECHO;
-#endif
+typedef ICMP_ECHO_REPLY ICMPECHO, *PICMPECHO, FAR *LPICMPECHO;
+#endif // _WIN64
#define ECHO_REPLY_TIMEOUT 5000
struct s_nethost {
- __int32 addr; // IP as a decimal, big endian
+ union{
+ sockaddr_in addr;
+ sockaddr_in6 addr6;
+ };
int xmit; // number of PING packets sent
int returned; // number of ICMP echo replies received
unsigned long total; // total time
@@ -44,19 +46,25 @@ struct s_nethost {
//*****************************************************************************
class WinMTRNet {
+ typedef FARPROC PIO_APC_ROUTINE;//not the best way to do it, but works ;) (we do not use it anyway)
+ //IPv4
typedef HANDLE (WINAPI *LPFNICMPCREATEFILE)(VOID);
typedef BOOL (WINAPI *LPFNICMPCLOSEHANDLE)(HANDLE);
- typedef DWORD (WINAPI *LPFNICMPSENDECHO)(HANDLE, u_long, LPVOID, WORD, LPVOID, LPVOID, DWORD, DWORD);
+ typedef DWORD (WINAPI *LPFNICMPSENDECHO2)(HANDLE IcmpHandle,HANDLE Event,PIO_APC_ROUTINE ApcRoutine,PVOID ApcContext,in_addr DestinationAddress,LPVOID RequestData,WORD RequestSize,PIP_OPTION_INFORMATION RequestOptions,LPVOID ReplyBuffer,DWORD ReplySize,DWORD Timeout);
+ //IPv6
+ typedef HANDLE (WINAPI *LPFNICMP6CREATEFILE)(VOID);
+ typedef BOOL (WINAPI *LPFNICMP6CLOSEHANDLE)(HANDLE);
+ typedef DWORD (WINAPI *LPFNICMP6SENDECHO2)(HANDLE IcmpHandle,HANDLE Event,PIO_APC_ROUTINE ApcRoutine,PVOID ApcContext,sockaddr_in6* SourceAddress,sockaddr_in6* DestinationAddress,LPVOID RequestData,WORD RequestSize,PIP_OPTION_INFORMATION RequestOptions,LPVOID ReplyBuffer,DWORD ReplySize,DWORD Timeout);
public:
WinMTRNet(WinMTRDialog *wp);
~WinMTRNet();
- void DoTrace(int address);
+ void DoTrace(sockaddr* sockaddr);
void ResetHops();
void StopTrace();
- int GetAddr(int at);
+ sockaddr* GetAddr(int at);
int GetName(int at, char *n);
int GetBest(int at);
int GetWorst(int at);
@@ -67,22 +75,31 @@ class WinMTRNet {
int GetXmit(int at);
int GetMax();
- void SetAddr(int at, __int32 addr);
+ void SetAddr(int at, u_long addr);
+ void SetAddr6(int at, IPV6_ADDRESS_EX addrex);
void SetName(int at, char *n);
- void SetBest(int at, int current);
- void SetWorst(int at, int current);
- void SetLast(int at, int last);
+ void SetErrorName(int at,DWORD errnum);
+ void UpdateRTT(int at, int rtt);
void AddReturned(int at);
void AddXmit(int at);
WinMTRDialog *wmtrdlg;
- __int32 last_remote_addr;
+ union{
+ in_addr last_remote_addr;
+ in6_addr last_remote_addr6;
+ };
+ bool hasIPv6;
bool tracing;
bool initialized;
- HANDLE hICMP;
- LPFNICMPCREATEFILE lpfnIcmpCreateFile;
+ HANDLE hICMP;
+ HANDLE hICMP6;
+ //IPv4
+ LPFNICMPCREATEFILE lpfnIcmpCreateFile;
LPFNICMPCLOSEHANDLE lpfnIcmpCloseHandle;
- LPFNICMPSENDECHO lpfnIcmpSendEcho;
+ LPFNICMPSENDECHO2 lpfnIcmpSendEcho2;
+ //IPv6
+ LPFNICMP6CREATEFILE lpfnIcmp6CreateFile;
+ LPFNICMP6SENDECHO2 lpfnIcmp6SendEcho2;
private:
HINSTANCE hICMP_DLL;
diff --git a/src/WinMTRProperties.h b/src/WinMTRProperties.h
index 8a7dafc..8eae2d7 100644
--- a/src/WinMTRProperties.h
+++ b/src/WinMTRProperties.h
@@ -30,7 +30,7 @@ class WinMTRProperties : public CDialog
enum { IDD = IDD_DIALOG_PROPERTIES };
char host[255];
- char ip[16];
+ char ip[40];
char comment[255];
float ping_last;
diff --git a/src/WinMTRStatusBar.cpp b/src/WinMTRStatusBar.cpp
index 5d6ba1d..2903079 100644
--- a/src/WinMTRStatusBar.cpp
+++ b/src/WinMTRStatusBar.cpp
@@ -60,7 +60,7 @@ LRESULT WinMTRStatusBar::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
void WinMTRStatusBar::RepositionControls()
{
- HDWP _hDWP = ::BeginDeferWindowPos( m_arrPaneControls.GetSize() );
+ HDWP _hDWP = ::BeginDeferWindowPos( (int)m_arrPaneControls.GetSize() );
CRect rcClient;
GetClientRect(&rcClient);
@@ -170,7 +170,7 @@ BOOL WinMTRStatusBar::AddPane(
arrPanesTmp.Add(pNewPane);
}
- int nPanesCount = arrPanesTmp.GetSize();
+ int nPanesCount = (int)arrPanesTmp.GetSize();
UINT* lpIDArray = new UINT[ nPanesCount ];
for (iIndex = 0; iIndex < nPanesCount; iIndex++) {
lpIDArray[iIndex] = arrPanesTmp[iIndex]->nID;
@@ -232,7 +232,7 @@ BOOL WinMTRStatusBar::RemovePane(
}
// set the indicators
- SetIndicators(lpIDArray, arrPanesTmp.GetSize());
+ SetIndicators(lpIDArray, (int)arrPanesTmp.GetSize());
// free memory
for (nIndex = 0; nIndex < arrPanesTmp.GetSize(); nIndex++){
_STATUSBAR_PANE_* pPane = arrPanesTmp[nIndex];
diff --git a/src/resource.h b/src/resource.h
index 1ca45e3..955b8e3 100644
--- a/src/resource.h
+++ b/src/resource.h
@@ -39,7 +39,7 @@
#define IDC_STATICJ 1023
#define IDC_COMBO_HOST 1024
#define IDC_EDIT_MAX_LRU 1025
-#define IDC_MFCLINK1 1026
+#define IDC_CHECK_IPV6 1026
// Next default values for new objects
//