cnping

Minimal Graphical Ping Tool
git clone https://git.sinitax.com/cnlohr/cnping
Log | Files | Refs | Submodules | README | LICENSE | sfeed.txt

commit dab665d732902fa3d3fe697af5ae8d46045909f0
parent 64051c4c40c8f7b35fca7ff4a8577bde9946dd51
Author: cnlohr <charles@cnlohr.com>
Date:   Sat, 17 Feb 2018 03:10:54 -0500

Update - include http:// as an optional protocol to cnping.

Diffstat:
MMakefile | 4++--
Mcnping-mousey.c | 1+
Mcnping.c | 32+++++++++++++++++++++++++++-----
Mcnping.exe | 0
Aerror_handling.h | 20++++++++++++++++++++
Ahttping.c | 213+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ahttping.h | 12++++++++++++
Mping.c | 3+++
Mping.h | 14--------------
Mresources.rc | 2+-
10 files changed, 279 insertions(+), 22 deletions(-)

diff --git a/Makefile b/Makefile @@ -10,11 +10,11 @@ LDFLAGS:=-g -L/opt/X11/lib/ #MINGW32:=/usr/bin/i686-w64-mingw32- MINGW32:=i686-w64-mingw32- -cnping.exe : cnping.c CNFGFunctions.c CNFGWinDriver.c os_generic.c ping.c +cnping.exe : cnping.c CNFGFunctions.c CNFGWinDriver.c os_generic.c ping.c httping.c $(MINGW32)windres resources.rc -o resources.o $(MINGW32)gcc -g -mwindows -m32 $(CFLAGS) resources.o -o $@ $^ -lgdi32 -lws2_32 -s -D_WIN32_WINNT=0x0600 -DWIN32 -cnping : cnping.o CNFGFunctions.o CNFGXDriver.o os_generic.o ping.o +cnping : cnping.o CNFGFunctions.o CNFGXDriver.o os_generic.o ping.o httping.o gcc $(CFLAGS) -o $@ $^ -lX11 -lm -lpthread $(LDFLAGS) cnping-mousey : cnping-mousey.o CNFGFunctions.o CNFGXDriver.o os_generic.o ping.o diff --git a/cnping-mousey.c b/cnping-mousey.c @@ -18,6 +18,7 @@ #include "CNFGFunctions.h" #include "os_generic.h" #include "ping.h" +#include "error_handling.h" unsigned frames = 0; unsigned long iframeno = 0; diff --git a/cnping.c b/cnping.c @@ -21,6 +21,8 @@ #include "CNFGFunctions.h" #include "os_generic.h" #include "ping.h" +#include "error_handling.h" +#include "httping.h" unsigned frames = 0; unsigned long iframeno = 0; @@ -41,6 +43,20 @@ int current_cycle = 0; int ExtraPingSize; + +void HTTPingCallbackStart( int seqno ) +{ + current_cycle = seqno; + + PingSendTimes[seqno] = OGGetAbsoluteTime(); + PingRecvTimes[seqno] = 0; +} + +void HTTPingCallbackGot( int seqno ) +{ + PingRecvTimes[seqno] = OGGetAbsoluteTime(); +} + void display(uint8_t *buf, int bytes) { int reqid = (buf[0] << 24) | (buf[1]<<16) | (buf[2]<<8) | (buf[3]); @@ -420,7 +436,7 @@ int main( int argc, const char ** argv ) ERRM( "Need at least a host address to ping.\n" ); #else ERRM( "Usage: cnping [host] [period] [extra size] [y-axis scaling] [window title]\n" - " (-h) [host] -- domain or IP address of ping target \n" + " (-h) [host] -- domain, IP address of ping target for ICMP or http host, i.e. http://google.com\n" " (-p) [period] -- period in seconds (optional), default 0.02 \n" " (-s) [extra size] -- ping packet extra size (above 12), optional, default = 0 \n" " (-y) [const y-axis scaling] -- use a fixed scaling factor instead of auto scaling (optional)\n" @@ -431,10 +447,16 @@ int main( int argc, const char ** argv ) CNFGSetup( title, 320, 155 ); - ping_setup(); - - OGCreateThread( PingSend, 0 ); - OGCreateThread( PingListen, 0 ); + if( memcmp( pinghost, "http://", 7 ) == 0 ) + { + StartHTTPing( pinghost+7, pingperiodseconds ); + } + else + { + ping_setup(); + OGCreateThread( PingSend, 0 ); + OGCreateThread( PingListen, 0 ); + } while(1) { diff --git a/cnping.exe b/cnping.exe Binary files differ. diff --git a/error_handling.h b/error_handling.h @@ -0,0 +1,20 @@ +#ifndef _ERROR_HANDLING +#define _ERROR_HANDLING + +#ifdef WIN32 + +extern char errbuffer[1024]; +#ifndef _MSC_VER +#define ERRM(x...) { sprintf( errbuffer, x ); MessageBox( 0, errbuffer, "cnping", 0 ); } +#else +#define ERRM(...) { sprintf( errbuffer, __VA_ARGS__ ); MessageBox( 0, errbuffer, "cnping", 0 ); } +#endif + +#else + +#define ERRM(x...) fprintf( stderr, x ); + +#endif + + +#endif diff --git a/httping.c b/httping.c @@ -0,0 +1,213 @@ +#include "httping.h" +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/types.h> + +#ifdef WIN32 + #include <winsock2.h> + #ifndef MSG_NOSIGNAL + #define MSG_NOSIGNAL 0 + #endif + +#else + #include <sys/socket.h> + #include <netinet/in.h> + #include <netdb.h> +#endif + +#include "os_generic.h" +#include "error_handling.h" + + +#define HTTPTIMEOUT 3.0 + +//Callbacks (when started/received) +void HTTPingCallbackStart( int seqno ); +void HTTPingCallbackGot( int seqno ); + +//Don't dynamically allocate resources here, since execution may be stopped arbitrarily. +void DoHTTPing( const char * addy, double minperiod, int * seqnoptr, volatile double * timeouttime, int * socketptr, volatile int * getting_host_by_name ) +{ + struct sockaddr_in serveraddr; + struct hostent *server; + int httpsock; + int addylen = strlen(addy); + char hostname[addylen+1]; + char * eportmarker = strchr( hostname, ':' ); + char * eurl = strchr( hostname, '/' ); + + int portno = 80; + + (*seqnoptr) ++; + HTTPingCallbackStart( *seqnoptr ); + + memcpy( hostname, addy, addylen + 1 ); + + if( eportmarker ) + { + portno = atoi( eportmarker+1 ); + *eportmarker = 0; + } + else + { + if( eurl ) + *eurl = 0; + } + + *socketptr = httpsock = socket(AF_INET, SOCK_STREAM, 0); + if (httpsock < 0) + { + ERRM( "Error opening socket\n" ); + return; + } + + /* gethostbyname: get the server's DNS entry */ + *getting_host_by_name = 1; + server = gethostbyname(hostname); + *getting_host_by_name = 0; + if (server == NULL) { + ERRM("ERROR, no such host as %s\n", hostname); + goto fail; + } + + /* build the server's Internet address */ + bzero((char *) &serveraddr, sizeof(serveraddr)); + serveraddr.sin_family = AF_INET; + memcpy((char *)server->h_addr, (char *)&serveraddr.sin_addr.s_addr, server->h_length); + serveraddr.sin_port = htons(portno); + + /* connect: create a connection with the server */ + if (connect(httpsock, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < 0) + { + ERRM( "%s: ERROR connecting\n", hostname ); + goto fail; + } + + + while( 1 ) + { + char buf[8192]; + + int n = sprintf( buf, "HEAD %s HTTP/1.1\r\nConnection: keep-alive\r\n\r\n", eurl?eurl:"/favicon.ico" ); + send( httpsock, buf, n, MSG_NOSIGNAL ); + double starttime = *timeouttime = OGGetAbsoluteTime(); + + int endstate = 0; + int breakout = 0; + while( !breakout ) + { + n = read( httpsock, buf, sizeof(buf)-1 ); + if( n < 0 ) return; + int i; + for( i = 0; i < n; i++ ) + { + char c = buf[i]; + switch( endstate ) + { + case 0: if( c == '\r' ) endstate++; break; + case 1: if( c == '\n' ) endstate++; else endstate = 0; break; + case 2: if( c == '\r' ) endstate++; else endstate = 0; break; + case 3: if( c == '\n' ) breakout = 1; else endstate = 0; break; + } + } + } + + *timeouttime = OGGetAbsoluteTime(); + + HTTPingCallbackGot( *seqnoptr ); + + double delay_time = minperiod - (*timeouttime - starttime); + if( delay_time > 0 ) + usleep( (int)(delay_time * 1000000) ); + (*seqnoptr) ++; + HTTPingCallbackStart( *seqnoptr ); + + + } +fail: + return; +} + + +struct HTTPPingLaunch +{ + const char * addy; + double minperiod; + + volatile double timeout_time; + volatile int failed; + int seqno; + int socket; + volatile int getting_host_by_name; +}; + +static void * DeployPing( void * v ) +{ + struct HTTPPingLaunch *hpl = (struct HTTPPingLaunch*)v; + hpl->socket = 0; + hpl->getting_host_by_name = 0; + DoHTTPing( hpl->addy, hpl->minperiod, &hpl->seqno, &hpl->timeout_time, &hpl->socket, &hpl->getting_host_by_name ); + hpl->failed = 1; + return 0; +} + + +static void * PingRunner( void * v ) +{ + struct HTTPPingLaunch *hpl = (struct HTTPPingLaunch*)v; + hpl->seqno = 0; + while( 1 ) + { + hpl->timeout_time = OGGetAbsoluteTime(); + og_thread_t thd = OGCreateThread( DeployPing, hpl ); + while( 1 ) + { + double Now = OGGetAbsoluteTime(); + double usl = hpl->timeout_time - Now + HTTPTIMEOUT; + if( usl > 0 ) usleep( (int)(usl*1000000 + 1000)); + else usleep( 10000 ); + + if( hpl->timeout_time + HTTPTIMEOUT < Now && !hpl->getting_host_by_name ) //Can't terminate in the middle of a gethostbyname operation otherwise bad things can happen. + { + if( hpl->socket ) + { +#ifdef WIN32 + closesocket( hpl->socket ); +#else + close( hpl->socket ); +#endif + } + + OGCancelThread( thd ); + break; + } + } + } + return 0; +} + +int StartHTTPing( const char * addy, double minperiod ) +{ + +#ifdef WIN32 + WSADATA wsaData; + int r = WSAStartup(MAKEWORD(2,2), &wsaData); + if( r ) + { + ERRM( "Fault in WSAStartup\n" ); + exit( -2 ); + } +#endif + + struct HTTPPingLaunch *hpl = malloc( sizeof( struct HTTPPingLaunch ) ); + hpl->addy = addy; + hpl->minperiod = minperiod; + OGCreateThread( PingRunner, hpl ); + return 0; +} + + + diff --git a/httping.h b/httping.h @@ -0,0 +1,12 @@ +#ifndef _HTTPING_H +#define _HTTPING_H + +//Callbacks (when started/received) +void HTTPingCallbackStart( int seqno ); +void HTTPingCallbackGot( int seqno ); + +//addy should be google.com/blah or something like that. Do not include prefixing http://. Port numbers OK. +int StartHTTPing( const char * addy, double minperiod ); + +#endif + diff --git a/ping.c b/ping.c @@ -11,6 +11,9 @@ #include "ping.h" #include "os_generic.h" + +#include "error_handling.h" + #ifdef WIN32 #include <winsock2.h> #define SOL_IP 0 diff --git a/ping.h b/ping.h @@ -24,20 +24,6 @@ extern int precise_ping; //if 0, use minimal CPU, but ping send-outs are only ap extern int ping_failed_to_send; void ping_setup(); -#ifdef WIN32 - -extern char errbuffer[1024]; -#ifndef _MSC_VER -#define ERRM(x...) { sprintf( errbuffer, x ); MessageBox( 0, errbuffer, "cnping", 0 ); } -#else -#define ERRM(...) { sprintf( errbuffer, __VA_ARGS__ ); MessageBox( 0, errbuffer, "cnping", 0 ); } -#endif - -#else - -#define ERRM(x...) fprintf( stderr, x ); - -#endif #endif diff --git a/resources.rc b/resources.rc @@ -8,7 +8,7 @@ STYLE WS_CAPTION | WS_SYSMENU CAPTION "cnping" BEGIN LTEXT "Usage: cnping [host] [period] [extra size] [y-axis scaling]", 0, 60, 0, 300, 20, SS_LEFT - LTEXT "[host] -- domain or IP address of ping target", 0, 60, 15, 300, 20, SS_LEFT + LTEXT "[host] -- domain or IP address of icmp ping, or http://host", 0, 60, 15, 300, 20, SS_LEFT LTEXT "[period] -- period in seconds (optional), default is 0.02", 0, 60, 30, 300, 20, SS_LEFT LTEXT "[extra size] -- ping packet extra size (above 12), optional, default = 0", 0, 60, 45, 300, 10, SS_LEFT LTEXT "[const y-axis scaling] -- use a fixed scaling factor instead of auto scaling", 0, 60, 60, 300, 10, SS_LEFT