cnping

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

commit 49e4420e93e9fd29bf0106d5e032ef0cfd67f112
parent 418e61d21394806efb5c419ca6be014cbeed22f1
Author: CNLohr <charles@cnlohr.com>
Date:   Wed, 21 Jun 2017 10:33:12 -0400

Merge pull request #23 from cnlohr/dev

Bring it all into mainline.
Diffstat:
ACNFGCocoaCGDriver.m | 361+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
MLICENSE | 21+--------------------
MMakefile | 6++++++
Mcnping.c | 2+-
Mping.c | 222+++++++++++++++++++++++++++++++------------------------------------------------
Mping.h | 4++--
6 files changed, 459 insertions(+), 157 deletions(-)

diff --git a/CNFGCocoaCGDriver.m b/CNFGCocoaCGDriver.m @@ -0,0 +1,361 @@ +//Copyright (c) 2017 <>< David Chapman - Under the MIT/x11 or NewBSD License you choose. +//Copyright (C) 2017 Viknet, MIT/x11 License or NewBSD License you choose. + +#import <Cocoa/Cocoa.h> +#import <Foundation/Foundation.h> + +#define RGB2Color(RGB) (RGB&0xFF)/256., ((RGB>>8)&0xFF)/256., ((RGB>>16)&0xFF)/256. + +#include "CNFGFunctions.h" + +id app_menubar, app_appMenuItem, app_appMenu, app_appName, app_quitMenuItem, app_quitTitle, app_quitMenuItem, app_window; +NSView *app_imageView; +CGColorSpaceRef colorSpace; +CGContextRef bufferContext; +uint32_t *bufferData; + +NSAutoreleasePool *app_pool; +int app_sw=0, app_sh=0; +NSRect frameRect; +int app_mouseX=0, app_mouseY=0; +BOOL inFullscreen = false; + +uint32_t CNFGColor( uint32_t RGB ) +{ + CNFGLastColor = RGB; + unsigned char red = RGB & 0xFF; + unsigned char grn = ( RGB >> 8 ) & 0xFF; + unsigned char blu = ( RGB >> 16 ) & 0xFF; + CGContextSetRGBStrokeColor(bufferContext, RGB2Color(RGB), 1.0); + CGContextSetRGBFillColor(bufferContext, RGB2Color(RGB), 1.0); + return CNFGLastColor; +} + +void CNFGTackPixel( short x, short y ) +{ + y = app_sh - y - 1; + if( x < 0 || y < 0 || x >= app_sw || y >= app_sh ) return; + bufferData[x + app_sw * y] = CNFGLastColor; +} + +// void CNFGTackSegment( short x1, short y1, short x2, short y2 ) +// { +// y1 = app_sh - y1 - 1; +// y2 = app_sh - y2 - 1; +// CGContextBeginPath(bufferContext); +// CGContextMoveToPoint(bufferContext, x1, y1); +// CGContextAddLineToPoint(bufferContext, x2, y2); +// CGContextStrokePath(bufferContext); +// } + +void CNFGTackSegment( short x1, short y1, short x2, short y2 ) +{ + short tx, ty; + float slope, lp; + + short dx = x2 - x1; + short dy = y2 - y1; + + if( dx < 0 ) dx = -dx; + if( dy < 0 ) dy = -dy; + + if( dx > dy ) + { + short minx = (x1 < x2)?x1:x2; + short maxx = (x1 < x2)?x2:x1; + short miny = (x1 < x2)?y1:y2; + short maxy = (x1 < x2)?y2:y1; + float thisy = miny; + slope = (float)(maxy-miny) / (float)(maxx-minx); + + for( tx = minx; tx <= maxx; tx++ ) + { + ty = thisy; + if( tx < 0 || ty < 0 || ty >= app_sh ) continue; + if( tx >= app_sw ) break; + bufferData[ty * app_sw + tx] = CNFGLastColor; + thisy += slope; + } + } + else + { + short minx = (y1 < y2)?x1:x2; + short maxx = (y1 < y2)?x2:x1; + short miny = (y1 < y2)?y1:y2; + short maxy = (y1 < y2)?y2:y1; + float thisx = minx; + slope = (float)(maxx-minx) / (float)(maxy-miny); + + for( ty = miny; ty <= maxy; ty++ ) + { + tx = thisx; + if( ty < 0 || tx < 0 || tx >= app_sw ) continue; + if( ty >= app_sh ) break; + bufferData[ty * app_sw + tx] = CNFGLastColor; + thisx += slope; + } + } +} + +void CNFGTackRectangle( short x1, short y1, short x2, short y2 ) +{ + CGContextFillRect(bufferContext, CGRectMake (x1, app_sh - y1 - 1, x2, app_sh - y2 - 1 )); +} + +void CNFGTackPoly( RDPoint * points, int verts ) +{ + if (verts==0) return; + CGContextBeginPath(bufferContext); + CGContextMoveToPoint(bufferContext, points[0].x, app_sh - points[0].y - 1); + for (int i=1; i<verts; i++){ + CGContextAddLineToPoint(bufferContext, points[i].x, app_sh - points[i].y - 1); + } + CGContextFillPath(bufferContext); +} + +@interface MyView : NSView +@end +@implementation MyView +- (id)initWithFrame:(NSRect)frame { + self = [super initWithFrame:frame]; + if (self) + { + [self setWantsLayer:YES]; + [self setLayerContentsRedrawPolicy: NSViewLayerContentsRedrawOnSetNeedsDisplay]; + // [self setLayerContentsPlacement: NSViewLayerContentsPlacementCenter]; + } + return self; +} + +- (BOOL) wantsUpdateLayer +{ + return YES; +} +- (void) updateLayer +{ + CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, bufferData, 4*app_sw*app_sh, NULL); + CGImageRef frameImage = CGImageCreate(app_sw, app_sh, 8, 32, 4*app_sw, colorSpace, kCGBitmapByteOrderDefault, provider, NULL, false, kCGRenderingIntentDefault); + + [app_imageView.layer setContents:(id)frameImage]; + + CGImageRelease(frameImage); + CGDataProviderRelease(provider); +} +@end + +CGContextRef createBitmapContext (int pixelsWide, + int pixelsHigh) +{ + int bitmapBytesPerRow = (pixelsWide * 4); + + CGContextRef context = CGBitmapContextCreate (NULL, + pixelsWide, + pixelsHigh, + 8, + bitmapBytesPerRow, + colorSpace, + kCGImageAlphaNoneSkipLast); + bufferData = CGBitmapContextGetData(context); + CGContextSetInterpolationQuality(context, kCGInterpolationNone); + // CGContextSetShouldAntialias(context, NO); + // CGContextSetLineWidth(context, 0.5); + + return context; +} + +void initApp(){ + [NSApplication sharedApplication]; + [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; + app_menubar = [[NSMenu new] autorelease]; + app_appMenuItem = [[NSMenuItem new] autorelease]; + [app_menubar addItem:app_appMenuItem]; + [NSApp setMainMenu:app_menubar]; + app_appMenu = [[NSMenu new] autorelease]; + app_appName = [[NSProcessInfo processInfo] processName]; + app_quitTitle = [@"Quit " stringByAppendingString:app_appName]; + app_quitMenuItem = [[[NSMenuItem alloc] initWithTitle:app_quitTitle + action:@selector(terminate:) keyEquivalent:@"q"] autorelease]; + [app_appMenu addItem:app_quitMenuItem]; + [app_appMenuItem setSubmenu:app_appMenu]; + app_imageView = [MyView new]; + colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGBLinear); +} + +void CNFGSetupFullscreen( const char * WindowName, int screen_number ) +{ + inFullscreen = YES; + initApp(); + + NSDictionary *fullScreenOptions = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithInt: + (NSApplicationPresentationAutoHideMenuBar | NSApplicationPresentationAutoHideDock) ], + NSFullScreenModeApplicationPresentationOptions, nil]; + [app_imageView enterFullScreenMode:[[NSScreen screens] objectAtIndex:screen_number] withOptions:fullScreenOptions]; + frameRect = [app_imageView frame]; + CGSize app_imageSize = frameRect.size; + app_sw = app_imageSize.width; app_sh = app_imageSize.height; + bufferContext = createBitmapContext (app_sw, app_sh); + [NSApp finishLaunching]; + [NSApp updateWindows]; + app_pool = [NSAutoreleasePool new]; +} + +void CNFGSetup( const char * WindowName, int sw, int sh ) +{ + app_sw=sw; app_sh=sh; + frameRect = NSMakeRect(0, 0, app_sw, app_sh); + + initApp(); + + app_window = [[[NSWindow alloc] + initWithContentRect:frameRect + styleMask: + NSWindowStyleMaskBorderless | + NSWindowStyleMaskResizable | + NSWindowStyleMaskTitled | + NSWindowStyleMaskClosable | + NSWindowStyleMaskMiniaturizable + backing:NSBackingStoreBuffered defer:NO] + autorelease]; + + NSString *title = [[[NSString alloc] initWithCString: WindowName encoding: NSUTF8StringEncoding] autorelease]; + [app_window setTitle:title]; + [app_window setContentView:app_imageView]; + [app_window cascadeTopLeftFromPoint:NSMakePoint(20,20)]; + [app_window makeKeyAndOrderFront:nil]; + [NSApp activateIgnoringOtherApps:YES]; + bufferContext = createBitmapContext (app_sw, app_sh); + [NSApp finishLaunching]; + [NSApp updateWindows]; + app_pool = [NSAutoreleasePool new]; +} + +#define XK_Left 0xff51 /* Move left, left arrow */ +#define XK_Up 0xff52 /* Move up, up arrow */ +#define XK_Right 0xff53 /* Move right, right arrow */ +#define XK_Down 0xff54 /* Move down, down arrow */ +#define KEY_UNDEFINED 255 +#define KEY_LEFT_MOUSE 0 + +static int keycode(key) +{ + if (key < 256) return key; + switch(key) { + case 63232: return XK_Up; + case 63233: return XK_Down; + case 63234: return XK_Left; + case 63235: return XK_Right; + } + return KEY_UNDEFINED; +} + +void CNFGHandleInput() +{ + [app_pool release]; + app_pool = [NSAutoreleasePool new]; + // Quit if no open windows left + if ([[NSApp windows] count] == 0) [NSApp terminate: nil]; + + //---------------------- + // Peek at the next event + //---------------------- + NSDate *app_currDate = [NSDate new]; + // If we have events, handle them! + NSEvent *event; + for (;(event = [NSApp + nextEventMatchingMask:NSEventMaskAny + untilDate:app_currDate + inMode:NSDefaultRunLoopMode + dequeue:YES]);) + { + NSPoint local_point; + NSEventType type = [event type]; + switch (type) + { + case NSEventTypeKeyDown: + for (int i=0; i<[event.characters length]; i++) { + unichar ch = [event.characters characterAtIndex: i]; + HandleKey(keycode(ch), 1); + } + break; + + case NSEventTypeKeyUp: + for (int i=0; i<[event.characters length]; i++) { + unichar ch = [event.characters characterAtIndex: i]; + HandleKey(keycode(ch), 0); + } + break; + + case NSEventTypeMouseMoved: + case NSEventTypeLeftMouseDragged: + case NSEventTypeRightMouseDragged: + case NSEventTypeOtherMouseDragged: + if (inFullscreen){ + local_point = [NSEvent mouseLocation]; + } else { + if ([event window] == nil) break; + NSPoint event_location = event.locationInWindow; + local_point = [app_imageView convertPoint:event_location fromView:nil]; + } + app_mouseX = fmax(fmin(local_point.x, app_sw), 0); + // Y coordinate must be inversed? + app_mouseY = fmax(fmin(app_sh - local_point.y, app_sh), 0); + HandleMotion(app_mouseX, app_mouseY, [NSEvent pressedMouseButtons]); + break; + + case NSEventTypeLeftMouseDown: + case NSEventTypeRightMouseDown: + case NSEventTypeOtherMouseDown: + // Button number start from 1? + HandleButton(app_mouseX, app_mouseY, event.buttonNumber+1, 1); + break; + + case NSEventTypeLeftMouseUp: + case NSEventTypeRightMouseUp: + case NSEventTypeOtherMouseUp: + HandleButton(app_mouseX, app_mouseY, event.buttonNumber+1, 0); + break; + + default: + break; + } + [NSApp sendEvent:event]; + } + [app_currDate release]; +} + +void CNFGGetDimensions( short * x, short * y ) +{ + frameRect = [app_window frame]; + CGSize app_imageSize = frameRect.size; + if (app_imageSize.width != app_sw || app_imageSize.height != app_sh) + { + app_sw = app_imageSize.width; + app_sh = app_imageSize.height; + if (bufferContext != NULL) + CGContextRelease(bufferContext); + bufferContext = createBitmapContext (app_sw, app_sh); + } + *x = app_sw; + *y = app_sh; +} + +void CNFGClearFrame() +{ + CGContextSetRGBFillColor(bufferContext, RGB2Color(CNFGBGColor), 1.0); + CGContextFillRect(bufferContext, CGRectMake (0, 0, app_sw, app_sh )); +} + +void CNFGSwapBuffers() +{ + [app_imageView setNeedsDisplay:YES]; +} + +void CNFGUpdateScreenWithBitmap( unsigned long * data, int w, int h ) +{ + CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, data, 4*w*h, NULL); + CGImageRef bitmap = CGImageCreate(w, h, 8, 32, 4*w, colorSpace, kCGBitmapByteOrderDefault, provider, NULL, false, kCGRenderingIntentDefault); + CGContextDrawImage(bufferContext, frameRect, bitmap); + CGImageRelease(bitmap); + CGDataProviderRelease(provider); +} 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/Makefile b/Makefile @@ -20,6 +20,12 @@ cnping : cnping.o CNFGFunctions.o CNFGXDriver.o os_generic.o ping.o cnping-mousey : cnping-mousey.o CNFGFunctions.o CNFGXDriver.o os_generic.o ping.o gcc $(CFLAGS) -o $@ $^ -lX11 -lm -lpthread $(LDFLAGS) +cnping_mac : cnping.c CNFGFunctions.c CNFGCocoaCGDriver.m os_generic.c ping.c + gcc -o cnping $^ -x objective-c -framework Cocoa -framework QuartzCore -lm -lpthread + +cnping-mousey_mac : cnping-mousey.c CNFGFunctions.c CNFGCocoaCGDriver.m os_generic.c ping.c + gcc -o cnping-mousey $^ -x objective-c -framework Cocoa -framework QuartzCore -lm -lpthread + searchnet : os_generic.o ping.o searchnet.o gcc $(CFLAGS) -o $@ $^ -lpthread 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,85 +1,60 @@ -/* 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); -#else -#pragma comment(lib, "Ws2_32.lib") -void bzero(void * loc, int len) -{ - memset(loc, 0, len); -} -#endif -#include <windows.h> -#include <stdio.h> -#include <winsock2.h> -#include <ws2tcpip.h> -#include <stdint.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 + #include <windows.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 + #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 -#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 @@ -87,52 +62,44 @@ float pingperiodseconds; int precise_ping; #define PACKETSIZE 1500 + struct packet { struct icmphdr hdr; - char msg[PACKETSIZE-sizeof(struct icmphdr)]; + unsigned char msg[PACKETSIZE-sizeof(struct icmphdr)]; }; 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("Error: could not set TTL option\n"); + ERRM("Error: could not set TTL option - did you forget to run as root or sticky bit cnping?\n"); exit( -1 ); } - #endif struct sockaddr_in addr; @@ -143,9 +110,9 @@ void listener(void) for (;;) { int i; - int bytes, len=sizeof(addr); + socklen_t addrlenval=sizeof(addr); + int bytes; - bzero(buf, sizeof(buf)); #ifdef WIN32 WSAPOLLFD fda[1]; fda[0].fd = sd; @@ -153,8 +120,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; @@ -162,37 +130,31 @@ void listener(void) if ( bytes > 0 ) display(buf + 28, bytes - 28 ); else - { + { ERRM("Error: recvfrom 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 ) @@ -201,27 +163,24 @@ 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 ); + pckt.hdr.checksum = checksum((const unsigned char *)&pckt, sizeof( pckt.hdr ) + rsize ); - if ( sendto(sd, (char*)&pckt, sizeof(pckt) - sizeof( pckt.msg ) + rsize , 0, (struct sockaddr*)addr, sizeof(*addr)) <= 0 ) + if( sendto(sd, (char*)&pckt, sizeof( pckt.hdr ) + rsize , 0, (struct sockaddr*)addr, sizeof(*addr)) <= 0 ) { - ERRM("Sendto failed."); + ERRM("Fail on sendto."); } - if( precise_ping ) { double ctime; @@ -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 );