cnping

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

commit 7513a9cbc18e76b36d1b24eb9417b295012876d7
parent 3b0af5357c0788382adaba926e117392875b94b1
Author: cnlohr <lohr85@gmail.com>
Date:   Tue, 23 May 2017 01:19:50 -0400

Update license info with new ping system.

Diffstat:
MLICENSE | 21+--------------------
Mcnping.c | 2+-
Mping.c | 226++++++++++++++++++++++++++++++++-----------------------------------------------
Mping.h | 4++--
4 files changed, 94 insertions(+), 159 deletions(-)

diff --git a/LICENSE b/LICENSE @@ -1,22 +1,3 @@ -//The myping tool is licensed under the below license. -//The rest of rawdraw and CNPing may be licensed feely under the MIT-x11 +//Rawdraw and CNPing may be licensed feely under the MIT-x11 //or NewBSD Licenses. You choose! -/* myping.c - * - * Copyright (c) 2000 Sean Walton and Macmillan Publishers. Use may be in - * whole or in part in accordance to the General Public License (GPL). - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. -*/ - diff --git a/cnping.c b/cnping.c @@ -29,7 +29,7 @@ int GuiYscaleFactorIsConstant; uint8_t pattern[8]; -#define PINGCYCLEWIDTH 2048 +#define PINGCYCLEWIDTH 8192 #define TIMEOUT 4 double PingSendTimes[PINGCYCLEWIDTH]; diff --git a/ping.c b/ping.c @@ -1,89 +1,62 @@ -/* myping.c - * - * Copyright (c) 2000 Sean Walton and Macmillan Publishers. Use may be in - * whole or in part in accordance to the General Public License (GPL). - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. -*/ - -/*****************************************************************************/ -/*** ping.c ***/ -/*** ***/ -/*** Use the ICMP protocol to request "echo" from destination. ***/ -/*****************************************************************************/ +//Copyright 2017 <>< C. Lohr, under the MIT/x11 License +//Rewritten from Sean Walton and Macmillan Publishers. +//Most of it was rewritten but the header was never updated. +//Now I finished the job. #include <string.h> #include <fcntl.h> #include <errno.h> +#include <stdio.h> +#include <stdlib.h> #include "ping.h" #include "os_generic.h" + #ifdef WIN32 -#include <winsock2.h> -#define SOL_IP 0 -#define F_SETFL 4 -#define ICMP_ECHO 8 -#define IP_TTL 2 -# define O_NONBLOCK 04000 - -#ifndef _MSC_VER -void bzero(void *location,__LONG32 count); + #include <winsock2.h> + #define SOL_IP 0 + #define F_SETFL 4 + #define ICMP_ECHO 8 + #define IP_TTL 2 + #define O_NONBLOCK 04000 + void usleep(int x) { Sleep(x / 1000); } + #include <windows.h> + #include <winsock2.h> + #include <ws2tcpip.h> + #include <stdint.h> #else -#pragma comment(lib, "Ws2_32.lib") -void bzero(void * loc, int len) -{ - memset(loc, 0, len); -} + #include <unistd.h> + #include <sys/socket.h> + #include <resolv.h> + #include <netdb.h> + #ifdef __APPLE__ + #ifndef SOL_IP + #define SOL_IP IPPROTO_IP + #endif + #endif + #include <netinet/ip.h> + #include <netinet/ip_icmp.h> #endif -void usleep(int x) { - Sleep(x / 1000); -} - -#include <windows.h> -#include <stdio.h> -#include <winsock2.h> -#include <ws2tcpip.h> -#include <stdint.h> -#else -#include <unistd.h> -#include <sys/socket.h> -#include <resolv.h> -#include <netdb.h> -#ifdef __APPLE__ -#ifndef SOL_IP -#define SOL_IP IPPROTO_IP -#endif -#endif -#include <netinet/ip.h> -#include <netinet/ip_icmp.h> -#endif -#include <stdlib.h> #if defined WIN32 || defined __APPLE__ -struct icmphdr { - uint8_t type; - uint8_t code; - uint16_t checksum; - union { - struct { - uint16_t id; - uint16_t sequence; - } echo; - uint32_t gateway; - struct { - uint16_t __unused; - uint16_t mtu; - } frag; - } un; +struct icmphdr +{ + uint8_t type; + uint8_t code; + uint16_t checksum; + union + { + struct + { + uint16_t id; + uint16_t sequence; + } echo; + uint32_t gateway; + struct + { + uint16_t __unused; + uint16_t mtu; + } frag; + } un; }; #endif @@ -91,6 +64,7 @@ float pingperiod; int precise_ping; #define PACKETSIZE 1500 + struct packet { struct icmphdr hdr; @@ -99,44 +73,35 @@ struct packet int sd; int pid=-1; -struct protoent *proto=NULL; struct sockaddr_in psaddr; -/*--------------------------------------------------------------------*/ -/*--- checksum - standard 1s complement checksum ---*/ -/*--------------------------------------------------------------------*/ -unsigned short checksum(void *b, int len) -{ unsigned short *buf = b; - unsigned int sum=0; - unsigned short result; - - for ( sum = 0; len > 1; len -= 2 ) - sum += *buf++; - if ( len == 1 ) - sum += *(unsigned char*)buf; - sum = (sum >> 16) + (sum & 0xFFFF); - sum += (sum >> 16); - result = ~sum; - return result; +uint16_t checksum( const unsigned char * start, uint16_t len ) +{ + uint16_t i; + const uint16_t * wptr = (uint16_t*) start; + uint32_t csum = 0; + for (i=1;i<len;i+=2) + csum += (uint32_t)(*(wptr++)); + if( len & 1 ) //See if there's an odd number of bytes? + csum += *(uint8_t*)wptr; + if (csum>>16) + csum = (csum & 0xFFFF)+(csum >> 16); + //csum = (csum>>8) | ((csum&0xff)<<8); + return ~csum; } - -/*--------------------------------------------------------------------*/ -/*--- listener - separate process to listen for and collect messages--*/ -/*--------------------------------------------------------------------*/ -void listener(void) +void listener() { #ifndef WIN32 const int val=255; - int sd = socket(PF_INET, SOCK_RAW, proto->p_proto); + int sd = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP); if ( setsockopt(sd, SOL_IP, IP_TTL, &val, sizeof(val)) != 0) { ERRM("Erro: could not set TTL option\n"); - exit( -1 ); + exit( -1 ); } - #endif struct sockaddr_in addr; @@ -147,9 +112,9 @@ void listener(void) for (;;) { int i; - int bytes, len=sizeof(addr); + int addrlenval=sizeof(addr); + int bytes; - bzero(buf, sizeof(buf)); #ifdef WIN32 WSAPOLLFD fda[1]; fda[0].fd = sd; @@ -157,8 +122,9 @@ void listener(void) WSAPoll(fda, 1, 10); #endif keep_retry_quick: - bytes = recvfrom(sd, buf, sizeof(buf), 0, (struct sockaddr*)&addr, &len); - if (bytes == -1) continue; + + bytes = recvfrom(sd, buf, sizeof(buf), 0, (struct sockaddr*)&addr, &addrlenval ); + if( bytes == -1 ) continue; if( buf[20] != 0 ) continue; //Make sure ping response. if( buf[9] != 1 ) continue; //ICMP if( addr.sin_addr.s_addr != psaddr.sin_addr.s_addr ) continue; @@ -166,35 +132,29 @@ void listener(void) if ( bytes > 0 ) display(buf + 28, bytes - 28 ); else - perror("recvfrom"); + ERRM( "recfrom failed." ); goto keep_retry_quick; } - printf( "Fault on listen.\n" ); - exit(0); + ERRM( "Fault on listen.\n" ); + exit( 0 ); } -/*--------------------------------------------------------------------*/ -/*--- ping - Create message and send it. ---*/ -/*--------------------------------------------------------------------*/ void ping(struct sockaddr_in *addr ) { - #ifdef WIN32 const char val=255; #else const int val=255; #endif int i, cnt=1; - struct packet pckt; struct sockaddr_in r_addr; + #ifdef WIN32 { - //this /was/ recommended. + //Setup windows socket for nonblocking io. unsigned long iMode = 1; ioctlsocket(sd, FIONBIO, &iMode); - - } #else if ( fcntl(sd, F_SETFL, O_NONBLOCK) != 0 ) @@ -203,24 +163,23 @@ void ping(struct sockaddr_in *addr ) double stime = OGGetAbsoluteTime(); + struct packet pckt; do - { int len=sizeof(r_addr); + { + int len = sizeof(r_addr); + 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. -// printf("Msg #%d\n", cnt); -// if ( recvfrom(sd, &pckt, sizeof(pckt), 0, (struct sockaddr*)&r_addr, &len) > 0 ) - { - //printf("***Got message!***\n"); - } - bzero(&pckt, sizeof(pckt)); + pckt.hdr.code = 0; pckt.hdr.type = ICMP_ECHO; pckt.hdr.un.echo.id = pid; - int rsize = load_ping_packet( pckt.msg, sizeof( pckt.msg ) ); pckt.hdr.un.echo.sequence = cnt++; - pckt.hdr.checksum = checksum(&pckt, sizeof(pckt) - sizeof( pckt.msg ) + rsize ); - - if ( sendto(sd, (char*)&pckt, sizeof(pckt) - sizeof( pckt.msg ) + rsize , 0, (struct sockaddr*)addr, sizeof(*addr)) <= 0 ) - perror("sendto"); + pckt.hdr.checksum = checksum(&pckt, sizeof( pckt.hdr ) + rsize ); + if( sendto(sd, (char*)&pckt, sizeof( pckt.hdr ) + rsize , 0, (struct sockaddr*)addr, sizeof(*addr)) <= 0 ) + { + ERRM("Fail on sendto."); + } if( precise_ping ) { @@ -247,13 +206,8 @@ void ping(struct sockaddr_in *addr ) void ping_setup() { pid = getpid(); - proto = getprotobyname("ICMP"); #ifdef WIN32 -/* - WSADATA wsaData; - int r = WSAStartup(0x0202, &wsaData ); -*/ WSADATA wsaData; int r = WSAStartup(MAKEWORD(2,2), &wsaData); if( r ) @@ -268,15 +222,15 @@ void ping_setup() sd = WSASocket(AF_INET, SOCK_RAW, IPPROTO_ICMP, 0, 0, WSA_FLAG_OVERLAPPED); { int lttl = 0xff; - if (setsockopt(sd, IPPROTO_IP, IP_TTL, (const char*)&lttl, - sizeof(lttl)) == SOCKET_ERROR) { + if (setsockopt(sd, IPPROTO_IP, IP_TTL, (const char*)&lttl, sizeof(lttl)) == SOCKET_ERROR) + { printf( "Warning: No IP_TTL.\n" ); } } #else const int val=255; - sd = socket(PF_INET, SOCK_RAW, proto->p_proto); + sd = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP); if ( setsockopt(sd, SOL_IP, IP_TTL, &val, sizeof(val)) != 0) { @@ -298,7 +252,7 @@ void do_pinger( const char * strhost ) struct hostent *hname; hname = gethostbyname(strhost); - bzero(&psaddr, sizeof(psaddr)); + memset(&psaddr, 0, sizeof(psaddr)); psaddr.sin_family = hname->h_addrtype; psaddr.sin_port = 0; psaddr.sin_addr.s_addr = *(long*)hname->h_addr; diff --git a/ping.h b/ping.h @@ -5,7 +5,7 @@ struct sockaddr_in; -unsigned short checksum(void *b, int len); +unsigned short checksum(const unsigned char *b, uint16_t len); //Callback (when received) void display(uint8_t *buf, int bytes); @@ -14,7 +14,7 @@ void display(uint8_t *buf, int bytes); //return value = # of bytes to send in ping message. int load_ping_packet( uint8_t * buffer, int buffersize ); -void listener(void); +void listener(); void ping(struct sockaddr_in *addr ); void do_pinger( const char * strhost );