@ -19,7 +19,7 @@
//#pragma comment(lib, "user32.lib")
//#pragma comment(lib, "gdi32.lib")
# define WINDOW_WIDTH 900
# define WINDOW_HEIGHT 108 0
# define WINDOW_HEIGHT 115 0
# define UPDATE_INTERVAL 10 /* 50ms → 20 samples per second */
/* Global app pointer for callbacks */
static struct etcpmon_app * g_app = NULL ;
@ -255,7 +255,7 @@ static void CreateControls(struct etcpmon_app* app) {
y = 485 ;
CreateWindowExA ( 0 , " BUTTON " , " ETCP Metrics " ,
WS_CHILD | WS_VISIBLE | BS_GROUPBOX ,
x , y , 430 , 22 0, hWnd , ( HMENU ) IDC_STATIC , hInst , NULL ) ;
x , y , 430 , 18 0, hWnd , ( HMENU ) IDC_STATIC , hInst , NULL ) ;
int mx = x + 10 , my = y + 20 ;
@ -263,7 +263,7 @@ static void CreateControls(struct etcpmon_app* app) {
WS_CHILD | WS_VISIBLE , mx , my , 80 , 20 , hWnd , ( HMENU ) IDC_STATIC , hInst , NULL ) ;
app - > hEditEtcpName = CreateWindowExA ( WS_EX_CLIENTEDGE , " EDIT " , " " ,
WS_CHILD | WS_VISIBLE | ES_READONLY | ES_AUTOHSCROLL ,
mx + 85 , my , 33 0 , 20 , hWnd , ( HMENU ) IDC_EDIT_ETCP_NAME , hInst , NULL ) ;
mx + 85 , my , 31 0 , 20 , hWnd , ( HMENU ) IDC_EDIT_ETCP_NAME , hInst , NULL ) ;
my + = 25 ;
CreateWindowExA ( 0 , " STATIC " , " RTT Last: " ,
@ -324,11 +324,11 @@ static void CreateControls(struct etcpmon_app* app) {
WS_CHILD | WS_VISIBLE | ES_READONLY ,
mx + 85 , my , 100 , 20 , hWnd , ( HMENU ) IDC_EDIT_ETCP_LINKS , hInst , NULL ) ;
/* TUN Metrics group - right of ETCP Metrics */
/* TUN/Routing Metrics group - right of ETCP Metrics */
x = 460 ; y = 485 ;
CreateWindowExA ( 0 , " BUTTON " , " TUN Metrics " ,
CreateWindowExA ( 0 , " BUTTON " , " TUN/Routing Metrics " ,
WS_CHILD | WS_VISIBLE | BS_GROUPBOX ,
x , y , 430 , 14 0 , hWnd , ( HMENU ) IDC_STATIC , hInst , NULL ) ;
x , y , 430 , 18 0 , hWnd , ( HMENU ) IDC_STATIC , hInst , NULL ) ;
mx = x + 10 ; my = y + 20 ;
@ -339,7 +339,7 @@ static void CreateControls(struct etcpmon_app* app) {
mx + 85 , my , 100 , 20 , hWnd , ( HMENU ) IDC_EDIT_TUN_READ_BYTES , hInst , NULL ) ;
CreateWindowExA ( 0 , " STATIC " , " Write Bytes: " ,
WS_CHILD | WS_VISIBLE , mx + 200 , my , 8 0, 20 , hWnd , ( HMENU ) IDC_STATIC , hInst , NULL ) ;
WS_CHILD | WS_VISIBLE , mx + 200 , my , 9 0, 20 , hWnd , ( HMENU ) IDC_STATIC , hInst , NULL ) ;
app - > hEditTunWriteBytes = CreateWindowExA ( WS_EX_CLIENTEDGE , " EDIT " , " " ,
WS_CHILD | WS_VISIBLE | ES_READONLY ,
mx + 285 , my , 100 , 20 , hWnd , ( HMENU ) IDC_EDIT_TUN_WRITE_BYTES , hInst , NULL ) ;
@ -352,7 +352,7 @@ static void CreateControls(struct etcpmon_app* app) {
mx + 85 , my , 100 , 20 , hWnd , ( HMENU ) IDC_EDIT_TUN_READ_PKTS , hInst , NULL ) ;
CreateWindowExA ( 0 , " STATIC " , " Write Pkts: " ,
WS_CHILD | WS_VISIBLE , mx + 200 , my , 8 0, 20 , hWnd , ( HMENU ) IDC_STATIC , hInst , NULL ) ;
WS_CHILD | WS_VISIBLE , mx + 200 , my , 9 0, 20 , hWnd , ( HMENU ) IDC_STATIC , hInst , NULL ) ;
app - > hEditTunWritePkts = CreateWindowExA ( WS_EX_CLIENTEDGE , " EDIT " , " " ,
WS_CHILD | WS_VISIBLE | ES_READONLY ,
mx + 285 , my , 100 , 20 , hWnd , ( HMENU ) IDC_EDIT_TUN_WRITE_PKTS , hInst , NULL ) ;
@ -365,11 +365,63 @@ static void CreateControls(struct etcpmon_app* app) {
mx + 85 , my , 100 , 20 , hWnd , ( HMENU ) IDC_EDIT_TUN_READ_ERRS , hInst , NULL ) ;
CreateWindowExA ( 0 , " STATIC " , " Write Errs: " ,
WS_CHILD | WS_VISIBLE , mx + 200 , my , 8 0, 20 , hWnd , ( HMENU ) IDC_STATIC , hInst , NULL ) ;
WS_CHILD | WS_VISIBLE , mx + 200 , my , 9 0, 20 , hWnd , ( HMENU ) IDC_STATIC , hInst , NULL ) ;
app - > hEditTunWriteErrs = CreateWindowExA ( WS_EX_CLIENTEDGE , " EDIT " , " " ,
WS_CHILD | WS_VISIBLE | ES_READONLY ,
mx + 285 , my , 100 , 20 , hWnd , ( HMENU ) IDC_EDIT_TUN_WRITE_ERRS , hInst , NULL ) ;
/* Routing section */
my + = 30 ;
CreateWindowExA ( 0 , " STATIC " , " Routed: " ,
WS_CHILD | WS_VISIBLE , mx , my , 60 , 18 , hWnd , ( HMENU ) IDC_STATIC , hInst , NULL ) ;
app - > hEditRtRouted = CreateWindowExA ( WS_EX_CLIENTEDGE , " EDIT " , " " ,
WS_CHILD | WS_VISIBLE | ES_READONLY | ES_CENTER ,
mx + 65 , my - 2 , 80 , 18 , hWnd , ( HMENU ) IDC_EDIT_RT_ROUTED , hInst , NULL ) ;
CreateWindowExA ( 0 , " STATIC " , " Dropped: " ,
WS_CHILD | WS_VISIBLE , mx + 155 , my , 60 , 18 , hWnd , ( HMENU ) IDC_STATIC , hInst , NULL ) ;
app - > hEditRtDropped = CreateWindowExA ( WS_EX_CLIENTEDGE , " EDIT " , " " ,
WS_CHILD | WS_VISIBLE | ES_READONLY | ES_CENTER ,
mx + 220 , my - 2 , 80 , 18 , hWnd , ( HMENU ) IDC_EDIT_RT_DROPPED , hInst , NULL ) ;
my + = 25 ;
CreateWindowExA ( 0 , " STATIC " , " TunInQ: " ,
WS_CHILD | WS_VISIBLE , mx , my , 60 , 18 , hWnd , ( HMENU ) IDC_STATIC , hInst , NULL ) ;
app - > hEditRtTunInQPkts = CreateWindowExA ( WS_EX_CLIENTEDGE , " EDIT " , " " ,
WS_CHILD | WS_VISIBLE | ES_READONLY | ES_CENTER ,
mx + 65 , my - 2 , 50 , 18 , hWnd , ( HMENU ) IDC_EDIT_RT_TUN_IN_Q_PKTS , hInst , NULL ) ;
app - > hEditRtTunInQBytes = CreateWindowExA ( WS_EX_CLIENTEDGE , " EDIT " , " " ,
WS_CHILD | WS_VISIBLE | ES_READONLY | ES_CENTER ,
mx + 120 , my - 2 , 60 , 18 , hWnd , ( HMENU ) IDC_EDIT_RT_TUN_IN_Q_BYTES , hInst , NULL ) ;
CreateWindowExA ( 0 , " STATIC " , " TunOutQ: " ,
WS_CHILD | WS_VISIBLE , mx + 190 , my , 60 , 18 , hWnd , ( HMENU ) IDC_STATIC , hInst , NULL ) ;
app - > hEditRtTunOutQPkts = CreateWindowExA ( WS_EX_CLIENTEDGE , " EDIT " , " " ,
WS_CHILD | WS_VISIBLE | ES_READONLY | ES_CENTER ,
mx + 255 , my - 2 , 50 , 18 , hWnd , ( HMENU ) IDC_EDIT_RT_TUN_OUT_Q_PKTS , hInst , NULL ) ;
app - > hEditRtTunOutQBytes = CreateWindowExA ( WS_EX_CLIENTEDGE , " EDIT " , " " ,
WS_CHILD | WS_VISIBLE | ES_READONLY | ES_CENTER ,
mx + 310 , my - 2 , 60 , 18 , hWnd , ( HMENU ) IDC_EDIT_RT_TUN_OUT_Q_BYTES , hInst , NULL ) ;
my + = 25 ;
CreateWindowExA ( 0 , " STATIC " , " RT: " ,
WS_CHILD | WS_VISIBLE , mx , my , 30 , 18 , hWnd , ( HMENU ) IDC_STATIC , hInst , NULL ) ;
app - > hEditRtCount = CreateWindowExA ( WS_EX_CLIENTEDGE , " EDIT " , " " ,
WS_CHILD | WS_VISIBLE | ES_READONLY | ES_CENTER ,
mx + 35 , my - 2 , 50 , 18 , hWnd , ( HMENU ) IDC_EDIT_RT_COUNT , hInst , NULL ) ;
CreateWindowExA ( 0 , " STATIC " , " Local: " ,
WS_CHILD | WS_VISIBLE , mx + 95 , my , 40 , 18 , hWnd , ( HMENU ) IDC_STATIC , hInst , NULL ) ;
app - > hEditRtLocal = CreateWindowExA ( WS_EX_CLIENTEDGE , " EDIT " , " " ,
WS_CHILD | WS_VISIBLE | ES_READONLY | ES_CENTER ,
mx + 140 , my - 2 , 50 , 18 , hWnd , ( HMENU ) IDC_EDIT_RT_LOCAL , hInst , NULL ) ;
CreateWindowExA ( 0 , " STATIC " , " Learned: " ,
WS_CHILD | WS_VISIBLE , mx + 200 , my , 55 , 18 , hWnd , ( HMENU ) IDC_STATIC , hInst , NULL ) ;
app - > hEditRtLearned = CreateWindowExA ( WS_EX_CLIENTEDGE , " EDIT " , " " ,
WS_CHILD | WS_VISIBLE | ES_READONLY | ES_CENTER ,
mx + 260 , my - 2 , 50 , 18 , hWnd , ( HMENU ) IDC_EDIT_RT_LEARNED , hInst , NULL ) ;
/* Links list */
y = 715 ;
CreateWindowExA ( 0 , " STATIC " , " Links: " ,
@ -378,10 +430,10 @@ static void CreateControls(struct etcpmon_app* app) {
app - > hListLinks = CreateWindowExA ( WS_EX_CLIENTEDGE , " LISTBOX " , " " ,
WS_CHILD | WS_VISIBLE | LBS_NOTIFY | WS_VSCROLL | LBS_NOINTEGRALHEIGHT ,
10 , y + 20 , 880 , 10 0 , hWnd , ( HMENU ) IDC_LIST_LINKS , hInst , NULL ) ;
10 , y + 20 , 880 , 16 0 , hWnd , ( HMENU ) IDC_LIST_LINKS , hInst , NULL ) ;
/* Queues & Errors group - below Links */
y = 84 5;
y = 90 5;
CreateWindowExA ( 0 , " BUTTON " , " Queues & Errors " ,
WS_CHILD | WS_VISIBLE | BS_GROUPBOX ,
10 , y , 880 , 165 , hWnd , ( HMENU ) IDC_STATIC_QUEUES , hInst , NULL ) ;
@ -765,6 +817,17 @@ void etcpmon_gui_update_metrics(struct etcpmon_app* app,
UpdateEditIfChanged ( hMain , IDC_EDIT_TUN_READ_ERRS , " %u " , metrics - > tun . read_errors ) ;
UpdateEditIfChanged ( hMain , IDC_EDIT_TUN_WRITE_ERRS , " %u " , metrics - > tun . write_errors ) ;
/* Routing Metrics */
UpdateEditIfChanged ( hMain , IDC_EDIT_RT_ROUTED , " %llu " , ( unsigned long long ) metrics - > tun . routed_packets ) ;
UpdateEditIfChanged ( hMain , IDC_EDIT_RT_DROPPED , " %llu " , ( unsigned long long ) metrics - > tun . dropped_packets ) ;
UpdateEditIfChanged ( hMain , IDC_EDIT_RT_TUN_IN_Q_PKTS , " %u " , metrics - > tun . tun_in_q_packets ) ;
UpdateEditIfChanged ( hMain , IDC_EDIT_RT_TUN_IN_Q_BYTES , " %u " , metrics - > tun . tun_in_q_bytes ) ;
UpdateEditIfChanged ( hMain , IDC_EDIT_RT_TUN_OUT_Q_PKTS , " %u " , metrics - > tun . tun_out_q_packets ) ;
UpdateEditIfChanged ( hMain , IDC_EDIT_RT_TUN_OUT_Q_BYTES , " %u " , metrics - > tun . tun_out_q_bytes ) ;
UpdateEditIfChanged ( hMain , IDC_EDIT_RT_COUNT , " %u " , metrics - > tun . rt_count ) ;
UpdateEditIfChanged ( hMain , IDC_EDIT_RT_LOCAL , " %u " , metrics - > tun . rt_local ) ;
UpdateEditIfChanged ( hMain , IDC_EDIT_RT_LEARNED , " %u " , metrics - > tun . rt_learned ) ;
/* Queue Metrics */
UpdateEditIfChanged ( hMain , IDC_EDIT_Q_IN_Q_BYTES , " %u " , metrics - > etcp . input_queue_bytes ) ;
UpdateEditIfChanged ( hMain , IDC_EDIT_Q_IN_Q_PKTS , " %u " , metrics - > etcp . input_queue_packets ) ;
@ -798,13 +861,13 @@ void etcpmon_gui_update_metrics(struct etcpmon_app* app,
if ( app - > hListLinks ) {
SendMessage ( app - > hListLinks , LB_RESETCONTENT , 0 , 0 ) ;
for ( uint8_t i = 0 ; i < links_count ; i + + ) {
char display [ 380 ] ;
snprintf ( display , sizeof ( display ) ,
char line1 [ 320 ] ;
char line2 [ 256 ] ;
snprintf ( line1 , sizeof ( line1 ) ,
" Link %u: Status=%s, EncErr=%u, DecErr=%u, "
" SndErr=%u, RcvErr=%u, Enc=%llu, Dec=%llu, "
" BW=%u Kbps, NAT=%u, RTT=%u us, TT=%u us, "
" Timers: Init=%s, KA=%s, Shaper=%s, "
" KAsent=%u, KArecv=%u " ,
" BW=%u Kbps, NAT=%u, RTT=%u us, TT=%u us " ,
links [ i ] . local_link_id ,
links [ i ] . status ? " UP " : " DOWN " ,
links [ i ] . encrypt_errors ,
@ -816,13 +879,19 @@ void etcpmon_gui_update_metrics(struct etcpmon_app* app,
links [ i ] . bandwidth ,
links [ i ] . nat_changes_count ,
links [ i ] . rtt_last * 100 ,
links [ i ] . tt_last * 100 ,
links [ i ] . tt_last * 100 ) ;
snprintf ( line2 , sizeof ( line2 ) ,
" Timers: Init=%s, KA=%s, Shaper=%s | "
" KAsent=%u, KArecv=%u " ,
links [ i ] . init_timer_active ? " ON " : " OFF " ,
links [ i ] . keepalive_timer_active ? " ON " : " OFF " ,
links [ i ] . shaper_timer_active ? " ON " : " OFF " ,
links [ i ] . keepalive_sent ,
links [ i ] . keepalive_recv ) ;
SendMessageA ( app - > hListLinks , LB_ADDSTRING , 0 , ( LPARAM ) display ) ;
SendMessageA ( app - > hListLinks , LB_ADDSTRING , 0 , ( LPARAM ) line1 ) ;
SendMessageA ( app - > hListLinks , LB_ADDSTRING , 0 , ( LPARAM ) line2 ) ;
}
InvalidateRect ( app - > hListLinks , NULL , FALSE ) ;
}
@ -851,6 +920,16 @@ void etcpmon_gui_clear_metrics(struct etcpmon_app* app) {
SetDlgItemTextA ( app - > hWndMain , IDC_EDIT_TUN_READ_ERRS , " " ) ;
SetDlgItemTextA ( app - > hWndMain , IDC_EDIT_TUN_WRITE_ERRS , " " ) ;
SetDlgItemTextA ( app - > hWndMain , IDC_EDIT_RT_ROUTED , " " ) ;
SetDlgItemTextA ( app - > hWndMain , IDC_EDIT_RT_DROPPED , " " ) ;
SetDlgItemTextA ( app - > hWndMain , IDC_EDIT_RT_TUN_IN_Q_PKTS , " " ) ;
SetDlgItemTextA ( app - > hWndMain , IDC_EDIT_RT_TUN_IN_Q_BYTES , " " ) ;
SetDlgItemTextA ( app - > hWndMain , IDC_EDIT_RT_TUN_OUT_Q_PKTS , " " ) ;
SetDlgItemTextA ( app - > hWndMain , IDC_EDIT_RT_TUN_OUT_Q_BYTES , " " ) ;
SetDlgItemTextA ( app - > hWndMain , IDC_EDIT_RT_COUNT , " " ) ;
SetDlgItemTextA ( app - > hWndMain , IDC_EDIT_RT_LOCAL , " " ) ;
SetDlgItemTextA ( app - > hWndMain , IDC_EDIT_RT_LEARNED , " " ) ;
SetDlgItemTextA ( app - > hWndMain , IDC_EDIT_Q_IN_Q_BYTES , " " ) ;
SetDlgItemTextA ( app - > hWndMain , IDC_EDIT_Q_IN_Q_PKTS , " " ) ;
SetDlgItemTextA ( app - > hWndMain , IDC_EDIT_Q_IN_SEND_BYTES , " " ) ;