cnping

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

commit b1468249f48a9379717c8f52048ea793c9e28feb
parent 16ee54ac8a6630a778aa1d1354c4303a70ca56eb
Author: CNLohr <lohr85@gmail.com>
Date:   Sat, 15 Apr 2023 04:49:43 -0400

Merge pull request #103 from cntools/fix_searchnet

Fix searchnet. Closes #102
Diffstat:
MMakefile | 2+-
Mping.c | 114+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
Mping.h | 2++
Msearchnet.c | 11+++++++++--
4 files changed, 121 insertions(+), 8 deletions(-)

diff --git a/Makefile b/Makefile @@ -48,7 +48,7 @@ cnping_ogl : cnping.c ping.c httping.c resolve.c cnping_mac : cnping.c ping.c httping.c resolve.c $(CC) -o cnping $^ -x objective-c -framework Cocoa -framework QuartzCore -lm -lpthread -DOSX -searchnet : ping.o searchnet.o +searchnet : ping.c searchnet.c resolve.c $(CC) $(CFLAGS) -o $@ $^ -lpthread linuxinstall : cnping diff --git a/ping.c b/ping.c @@ -22,6 +22,7 @@ float pingperiodseconds; int precise_ping; struct sockaddr_in6 psaddr; socklen_t psaddr_len; +int using_regular_ping; #ifdef WIN_USE_NO_ADMIN_PING @@ -54,7 +55,10 @@ void ping_setup(const char * strhost, const char * device) { // resolve host psaddr_len = sizeof(psaddr); - resolveName((struct sockaddr*) &psaddr, &psaddr_len, strhost, AF_INET); // only resolve ipv4 on windows + if( strhost ) + resolveName((struct sockaddr*) &psaddr, &psaddr_len, strhost, AF_INET); // only resolve ipv4 on windows + else + psaddr.sin6_family = AF_INET; s_disp = OGCreateSema(); s_ping = OGCreateSema(); @@ -123,12 +127,51 @@ static void * pingerthread( void * v ) return 0; } +void singleping(struct sockaddr *addr, socklen_t addr_len ) +{ + int i; + (void) addr; + (void) addr_len; + + if( psaddr.sin6_family != AF_INET ) + { + // ipv6 ICMP Ping is not supported on windows + ERRM( "ERROR: ipv6 ICMP Ping is not supported on windows\n" ); + exit( -1 ); + } + + static int did_init_threads = 0; + if( !did_init_threads ) + { + did_init_threads = 1; + //Launch pinger threads + for( i = 0; i < PINGTHREADS; i++ ) + { + HANDLE ih = pinghandles[i] = IcmpCreateFile(); + if( ih == INVALID_HANDLE_VALUE ) + { + ERRM( "Cannot create ICMP thread %d\n", i ); + exit( 0 ); + } + + OGCreateThread( pingerthread, &pinghandles[i] ); + } + } + //This function is executed as a thread after setup. + + if( i >= PINGTHREADS-1 ) i = 0; + else i++; + OGUnlockSema( s_ping ); +} + void ping(struct sockaddr *addr, socklen_t addr_len ) { int i; (void) addr; (void) addr_len; + using_regular_ping = 1; + if( psaddr.sin6_family != AF_INET ) { // ipv6 ICMP Ping is not supported on windows @@ -335,7 +378,7 @@ void listener() if( !isICMPResponse(buf, bytes) ) continue; // compare the sender - if( memcmp(&addr, &psaddr, addrlenval) != 0 ) continue; + if( using_regular_ping && memcmp(&addr, &psaddr, addrlenval) != 0 ) continue; // sizeof(packet.hdr) + 20 int offset = 0; @@ -366,10 +409,64 @@ void listener() exit( 0 ); } +void singleping(struct sockaddr *addr, socklen_t addr_len ) +{ + int cnt=1; + +#ifdef WIN32 + { + //Setup windows socket for nonblocking io. + unsigned long iMode = 1; + ioctlsocket(sd, FIONBIO, &iMode); + } +#else + if ( fcntl(sd, F_SETFL, O_NONBLOCK) != 0 ) + ERRM("Warning: Request nonblocking I/O failed."); +#endif + + double stime = OGGetAbsoluteTime(); + + struct packet pckt; + + { + int rsize = load_ping_packet( pckt.msg, sizeof( pckt.msg ) ); + memset( &pckt.hdr, 0, sizeof( pckt.hdr ) ); //This needs to be here, but I don't know why, since I think the struct is fully populated. +#ifdef __FreeBSD__ + pckt.hdr.icmp_code = 0; + pckt.hdr.icmp_type = ICMP_ECHO; + pckt.hdr.icmp_id = pid; + pckt.hdr.icmp_seq = cnt++; + pckt.hdr.icmp_cksum = checksum((const unsigned char *)&pckt, sizeof( pckt.hdr ) + rsize ); +#else + pckt.hdr.code = 0; + pckt.hdr.type = (psaddr.sin6_family == AF_INET) ? ICMP_ECHO : ICMP6_ECHO_REQUEST; + pckt.hdr.un.echo.id = pid; + pckt.hdr.un.echo.sequence = cnt++; + pckt.hdr.checksum = checksum((const unsigned char *)&pckt, sizeof( pckt.hdr ) + rsize ); +#endif + + int sr = sendto(sd, (char*)&pckt, sizeof( pckt.hdr ) + rsize , 0, addr, addr_len); + + if( sr <= 0 ) + { + ping_failed_to_send = 1; + if( using_regular_ping ) + { + ERRMB("Ping send failed:\n%s (%d)\n", strerror(errno), errno); + } + } + else + { + ping_failed_to_send = 0; + } + } +} + void ping(struct sockaddr *addr, socklen_t addr_len ) { int cnt=1; + using_regular_ping = 1; #ifdef WIN32 { //Setup windows socket for nonblocking io. @@ -407,7 +504,10 @@ void ping(struct sockaddr *addr, socklen_t addr_len ) if( sr <= 0 ) { ping_failed_to_send = 1; - ERRMB("Ping send failed:\n%s (%d)\n", strerror(errno), errno); + if( using_regular_ping ) + { + ERRMB("Ping send failed:\n%s (%d)\n", strerror(errno), errno); + } } else { @@ -433,7 +533,7 @@ void ping(struct sockaddr *addr, socklen_t addr_len ) } } } while( pingperiodseconds >= 0 ); - //close( sd ); //Hacky, we don't close here because SD doesn't come from here, rather from ping_setup. We may want to run this multiple times. + //close( sd ); //Hacky, we don't close here because SD doesn't come from here, rather from ping_setup. We may want to run this multiple times. } void ping_setup(const char * strhost, const char * device) @@ -463,7 +563,11 @@ void ping_setup(const char * strhost, const char * device) #else // resolve host psaddr_len = sizeof(psaddr); - resolveName((struct sockaddr*) &psaddr, &psaddr_len, strhost, AF_UNSPEC); + + if( strhost ) + resolveName((struct sockaddr*) &psaddr, &psaddr_len, strhost, AF_UNSPEC); + else + psaddr.sin6_family = AF_INET; sd = createSocket(); diff --git a/ping.h b/ping.h @@ -22,6 +22,8 @@ void listener(); void ping(struct sockaddr *addr, socklen_t addr_len ); void do_pinger( ); +void singleping(struct sockaddr *addr, socklen_t addr_len ); // If using this, must call ping_setup( 0, 0); to begin. + //If pingperiodseconds = -1, run ping/do_pinger once and exit. extern float pingperiodseconds; extern int precise_ping; //if 0, use minimal CPU, but ping send-outs are only approximate, if 1, spinlock until precise time for ping is hit. diff --git a/searchnet.c b/searchnet.c @@ -5,11 +5,14 @@ #include <arpa/inet.h> #include <stdint.h> #include <stdlib.h> +#include "resolve.h" #include "rawdraw/os_generic.h" uint32_t my_random_key; uint8_t send_id[4]; +extern float pingperiodseconds; + void * PingListen( void * r ) { listener(); @@ -50,7 +53,7 @@ int main( int argc, char ** argv ) char dispip[32]; float speed; - ping_setup(); + ping_setup( 0, 0); OGCreateThread( PingListen, 0 ); srand( ((int)(OGGetAbsoluteTime()*10000)) ); my_random_key = rand(); @@ -77,7 +80,11 @@ int main( int argc, char ** argv ) send_id[3] = (cur)&0xff; // printf( "Pinging: %s\n", dispip ); pingperiodseconds = -1; - do_pinger( dispip ); + + struct sockaddr_in6 psaddr; + socklen_t psaddr_len = sizeof(psaddr); + resolveName((struct sockaddr*) &psaddr, &psaddr_len, dispip, AF_UNSPEC); + singleping((struct sockaddr*) &psaddr, psaddr_len ); OGUSleep( (int)(speed * 1000000) ); }