commit 50d754a4603888ea6703f4155ac10b752c0b9429
parent 03517f921daf448c7740aab4a1c13623d1fd92cb
Author: cnlohr <lohr85@gmail.com>
Date: Thu, 23 Feb 2017 21:36:47 -0500
Fix Windows driver to use almost no CPU
Diffstat:
6 files changed, 674 insertions(+), 358 deletions(-)
diff --git a/Makefile b/Makefile
@@ -8,7 +8,7 @@ MINGW32:=/usr/bin/i686-w64-mingw32-
cnping.exe : cnping.c DrawFunctions.c WinDriver.c os_generic.c ping.c
$(MINGW32)windres resources.rc -o resources.o
- $(MINGW32)gcc -g -mwindows -m32 $(CFLAGS) resources.o -o $@ $^ -lgdi32 -lws2_32 -s
+ $(MINGW32)gcc -g -mwindows -m32 $(CFLAGS) resources.o -o $@ $^ -lgdi32 -lws2_32 -s -D_WIN32_WINNT=0x0600
cnping : cnping.o DrawFunctions.o XDriver.o os_generic.o ping.o
gcc $(CFLAGS) -o $@ $^ -lX11 -lm -lpthread -lXinerama -lXext $(LDFLAGS)
diff --git a/WinDriver.c b/WinDriver.c
@@ -7,75 +7,46 @@
#include <stdlib.h>
#include <malloc.h> //for alloca
+static HBITMAP lsBitmap;
static HINSTANCE lhInstance;
static HWND lsHWND;
-static HDC lsHDC;
-static HBITMAP lsBackBitmap;
static HDC lsWindowHDC;
-static HBRUSH lsHBR;
-static HPEN lsHPEN;
-static HBRUSH lsClearBrush;
-static unsigned int lsLastWidth;
-static unsigned int lsLastHeight;
-
-static void InternalHandleResize()
-{
- DeleteObject( lsBackBitmap );
- lsBackBitmap = CreateCompatibleBitmap( lsHDC, lsLastWidth, lsLastHeight );
- SelectObject( lsHDC, lsBackBitmap );
-
-}
-
-uint32_t CNFGColor( uint32_t RGB )
-{
- CNFGLastColor = RGB;
-
- DeleteObject( lsHBR );
- lsHBR = CreateSolidBrush( RGB );
- SelectObject( lsHDC, lsHBR );
-
- DeleteObject( lsHPEN );
- lsHPEN = CreatePen( PS_SOLID, 0, RGB );
- SelectObject( lsHDC, lsHPEN );
-
- return RGB;
-}
+static HDC lsHDC;
+static unsigned int bufferx;
+static unsigned int buffery;
+static uint32_t * buffer = 0;
-void CNFGTackSegment( short x1, short y1, short x2, short y2 )
+void CNFGClearFrame()
{
- POINT pt[2] = { {x1, y1}, {x2, y2} };
- Polyline( lsHDC, pt, 2 );
- SetPixel( lsHDC, x1, y1, CNFGLastColor );
- SetPixel( lsHDC, x2, y2, CNFGLastColor );
+ uint32_t col = CNFGColor( CNFGBGColor );
+ int i;
+ for( i = bufferx * buffery - 1; i>=0; i-- )
+ {
+ buffer[i] = col;
+ }
}
-void CNFGTackRectangle( short x1, short y1, short x2, short y2 )
+void InternalHandleResize()
{
- RECT r;
- if( x1 < x2 ) { r.left = x1; r.right = x2; }
- else { r.left = x2; r.right = x1; }
- if( y1 < y2 ) { r.top = y1; r.bottom = y2; }
- else { r.top = y2; r.bottom = y1; }
- FillRect( lsHDC, &r, lsHBR );
-}
+ if( lsBitmap ) DeleteObject( lsBitmap );
-void CNFGClearFrame()
-{
- RECT r = { 0, 0, lsLastWidth, lsLastHeight };
- DeleteObject( lsClearBrush );
- lsClearBrush = CreateSolidBrush( CNFGBGColor );
- SelectObject( lsHDC, lsClearBrush );
+ if( buffer ) free( buffer );
+ buffer = malloc( bufferx * buffery * 4 );
- FillRect( lsHDC, &r, lsClearBrush );
+ lsBitmap = CreateBitmap( bufferx, buffery, 1, 32, buffer );
+ SelectObject( lsHDC, lsBitmap );
}
void CNFGSwapBuffers()
{
int thisw, thish;
RECT r;
- BitBlt( lsWindowHDC, 0, 0, lsLastWidth, lsLastHeight, lsHDC, 0, 0, SRCCOPY );
+
+ int a = SetBitmapBits(lsBitmap,bufferx*buffery*4,buffer);
+ a = BitBlt(lsWindowHDC, 0, 0, bufferx, buffery, lsHDC, 0, 0, SRCCOPY);
UpdateWindow( lsHWND );
+
//Check to see if the window is closed.
if( !IsWindow( lsHWND ) )
{
@@ -85,36 +56,218 @@ void CNFGSwapBuffers()
GetClientRect( lsHWND, &r );
thisw = r.right - r.left;
thish = r.bottom - r.top;
- if( thisw != lsLastWidth || thish != lsLastHeight )
+ if( thisw != bufferx || thish != buffery )
{
- lsLastWidth = thisw;
- lsLastHeight = thish;
+ bufferx = thisw;
+ buffery = thish;
InternalHandleResize();
}
}
-void CNFGTackPoly( RDPoint * points, int verts )
+
+static uint32_t SWAPS( uint32_t r )
{
- int i;
- POINT * t = (POINT*)alloca( sizeof( POINT ) * verts );
- for( i = 0; i < verts; i++ )
+ uint32_t ret = (r&0xFF)<<16;
+ r>>=8;
+ ret |= (r&0xff)<<8;
+ r>>=8;
+ ret |= r;
+ return ret;
+}
+
+uint32_t CNFGColor( uint32_t RGB )
+{
+ CNFGLastColor = SWAPS(RGB);
+ return CNFGLastColor;
+}
+
+void CNFGTackPixel( short tx, short ty )
+{
+ buffer[ty * bufferx + tx] = CNFGLastColor;
+}
+
+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( !buffer ) return;
+
+ if( dx < 0 ) dx = -dx;
+ if( dy < 0 ) dy = -dy;
+
+ if( dx > dy )
{
- t[i].x = points[i].x;
- t[i].y = points[i].y;
+ 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 >= buffery ) continue;
+ if( tx >= bufferx ) break;
+ buffer[ty * bufferx + 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 >= bufferx ) continue;
+ if( ty >= buffery ) break;
+ buffer[ty * bufferx + tx] = CNFGLastColor;
+ thisx += slope;
+ }
}
- Polygon( lsHDC, t, verts );
}
+void CNFGTackRectangle( short x1, short y1, short x2, short y2 )
+{
+ short minx = (x1<x2)?x1:x2;
+ short miny = (y1<y2)?y1:y2;
+ short maxx = (x1>=x2)?x1:x2;
+ short maxy = (y1>=y2)?y1:y2;
-void CNFGTackPixel( short x1, short y1 )
+ short x, y;
+
+ if( minx < 0 ) minx = 0;
+ if( miny < 0 ) miny = 0;
+ if( maxx >= bufferx ) maxx = bufferx-1;
+ if( maxy >= buffery ) maxy = buffery-1;
+
+ for( y = miny; y <= maxy; y++ )
+ {
+ uint32_t * bufferstart = &buffer[y * bufferx + minx];
+ for( x = minx; x <= maxx; x++ )
+ {
+ (*bufferstart++) = CNFGLastColor;
+ }
+ }
+}
+
+void CNFGTackPoly( RDPoint * points, int verts )
{
- SetPixel( lsHDC, x1, y1, CNFGLastColor );
+ short minx = 10000, miny = 10000;
+ short maxx =-10000, maxy =-10000;
+ short i, x, y;
+
+ //Just in case...
+ if( verts > 32767 ) return;
+
+ for( i = 0; i < verts; i++ )
+ {
+ RDPoint * p = &points[i];
+ if( p->x < minx ) minx = p->x;
+ if( p->y < miny ) miny = p->y;
+ if( p->x > maxx ) maxx = p->x;
+ if( p->y > maxy ) maxy = p->y;
+ }
+
+ if( miny < 0 ) miny = 0;
+ if( maxy >= buffery ) maxy = buffery-1;
+
+ for( y = miny; y <= maxy; y++ )
+ {
+ short startfillx = maxx;
+ short endfillx = minx;
+
+ //Figure out what line segments intersect this line.
+ for( i = 0; i < verts; i++ )
+ {
+ short pl = i + 1;
+ if( pl == verts ) pl = 0;
+
+ RDPoint ptop;
+ RDPoint pbot;
+
+ ptop.x = points[i].x;
+ ptop.y = points[i].y;
+ pbot.x = points[pl].x;
+ pbot.y = points[pl].y;
+//printf( "Poly: %d %d\n", pbot.y, ptop.y );
+
+ if( pbot.y < ptop.y )
+ {
+ RDPoint ptmp;
+ ptmp.x = pbot.x;
+ ptmp.y = pbot.y;
+ pbot.x = ptop.x;
+ pbot.y = ptop.y;
+ ptop.x = ptmp.x;
+ ptop.y = ptmp.y;
+ }
+
+ //Make sure this line segment is within our range.
+//printf( "PT: %d %d %d\n", y, ptop.y, pbot.y );
+ if( ptop.y <= y && pbot.y >= y )
+ {
+ short diffy = pbot.y - ptop.y;
+ uint32_t placey = (uint32_t)(y - ptop.y)<<16; //Scale by 16 so we can do integer math.
+ short diffx = pbot.x - ptop.x;
+ short isectx;
+
+ if( diffy == 0 )
+ {
+ if( pbot.x < ptop.x )
+ {
+ if( startfillx > pbot.x ) startfillx = pbot.x;
+ if( endfillx < ptop.x ) endfillx = ptop.x;
+ }
+ else
+ {
+ if( startfillx > ptop.x ) startfillx = ptop.x;
+ if( endfillx < pbot.x ) endfillx = pbot.x;
+ }
+ }
+ else
+ {
+ //Inner part is scaled by 65536, outer part must be scaled back.
+ isectx = (( (placey / diffy) * diffx + 32768 )>>16) + ptop.x;
+ if( isectx < startfillx ) startfillx = isectx;
+ if( isectx > endfillx ) endfillx = isectx;
+ }
+//printf( "R: %d %d %d\n", pbot.x, ptop.x, isectx );
+ }
+ }
+
+//printf( "%d %d %d\n", y, startfillx, endfillx );
+
+ if( endfillx >= bufferx ) endfillx = bufferx - 1;
+ if( endfillx >= bufferx ) endfillx = buffery - 1;
+ if( startfillx < 0 ) startfillx = 0;
+ if( startfillx < 0 ) startfillx = 0;
+
+ unsigned int * bufferstart = &buffer[y * bufferx + startfillx];
+ for( x = startfillx; x <= endfillx; x++ )
+ {
+ (*bufferstart++) = CNFGLastColor;
+ }
+ }
+//exit(1);
}
+
+
void CNFGGetDimensions( short * x, short * y )
{
- *x = lsLastWidth;
- *y = lsLastHeight;
+ *x = bufferx;
+ *y = buffery;
}
//This was from the article
@@ -143,8 +296,8 @@ void CNFGSetup( const char * name_of_window, int width, int height )
int w, h, wd, hd;
HINSTANCE hInstance = GetModuleHandle(NULL);
- lsLastWidth = width;
- lsLastHeight = height;
+ bufferx = width;
+ buffery = height;
wnd.style = CS_HREDRAW | CS_VREDRAW; //we will explain this later
wnd.lpfnWndProc = MyWndProc;
@@ -167,8 +320,8 @@ void CNFGSetup( const char * name_of_window, int width, int height )
WS_OVERLAPPEDWINDOW, //basic window style
CW_USEDEFAULT,
CW_USEDEFAULT, //set starting point to default value
- lsLastWidth,
- lsLastHeight, //set all the dimensions to default value
+ bufferx,
+ buffery, //set all the dimensions to default value
NULL, //no parent window
NULL, //no menu
hInstance,
@@ -176,13 +329,14 @@ void CNFGSetup( const char * name_of_window, int width, int height )
lsWindowHDC = GetDC( lsHWND );
+
lsHDC = CreateCompatibleDC( lsWindowHDC );
- lsBackBitmap = CreateCompatibleBitmap( lsWindowHDC, lsLastWidth, lsLastHeight );
- SelectObject( lsHDC, lsBackBitmap );
+ //lsBackBitmap = CreateCompatibleBitmap( lsWindowHDC, lsLastWidth, buffery );
+ //SelectObject( lsHDC, lsBackBitmap );
- lsClearBrush = CreateSolidBrush( CNFGBGColor );
- lsHBR = CreateSolidBrush( 0xFFFFFF );
- lsHPEN = CreatePen( PS_SOLID, 0, 0xFFFFFF );
+ //lsClearBrush = CreateSolidBrush( CNFGBGColor );
+ //lsHBR = CreateSolidBrush( 0xFFFFFF );
+ //lsHPEN = CreatePen( PS_SOLID, 0, 0xFFFFFF );
ShowWindow(lsHWND, 1); //display the window on the screen
@@ -193,7 +347,7 @@ void CNFGSetup( const char * name_of_window, int width, int height )
h = ( window.bottom - window.top);
wd = w - client.right;
hd = h - client.bottom;
- MoveWindow( lsHWND, window.left, window.top, lsLastWidth + wd, lsLastHeight + hd, 1 );
+ MoveWindow( lsHWND, window.left, window.top, bufferx + wd, buffery + hd, 1 );
InternalHandleResize();
}
@@ -229,3 +383,105 @@ void CNFGHandleInput()
}
}
+
+/*
+static HBITMAP lsBackBitmap;
+static HDC lsWindowHDC;
+static HBRUSH lsHBR;
+static HPEN lsHPEN;
+static HBRUSH lsClearBrush;
+
+static void InternalHandleResize()
+{
+ DeleteObject( lsBackBitmap );
+ lsBackBitmap = CreateCompatibleBitmap( lsHDC, lsLastWidth, lsLastHeight );
+ SelectObject( lsHDC, lsBackBitmap );
+
+}
+
+uint32_t CNFGColor( uint32_t RGB )
+{
+ CNFGLastColor = RGB;
+
+ DeleteObject( lsHBR );
+ lsHBR = CreateSolidBrush( RGB );
+ SelectObject( lsHDC, lsHBR );
+
+ DeleteObject( lsHPEN );
+ lsHPEN = CreatePen( PS_SOLID, 0, RGB );
+ SelectObject( lsHDC, lsHPEN );
+
+ return RGB;
+}
+
+void CNFGTackSegment( short x1, short y1, short x2, short y2 )
+{
+ POINT pt[2] = { {x1, y1}, {x2, y2} };
+ Polyline( lsHDC, pt, 2 );
+ SetPixel( lsHDC, x1, y1, CNFGLastColor );
+ SetPixel( lsHDC, x2, y2, CNFGLastColor );
+}
+
+void CNFGTackRectangle( short x1, short y1, short x2, short y2 )
+{
+ RECT r;
+ if( x1 < x2 ) { r.left = x1; r.right = x2; }
+ else { r.left = x2; r.right = x1; }
+ if( y1 < y2 ) { r.top = y1; r.bottom = y2; }
+ else { r.top = y2; r.bottom = y1; }
+ FillRect( lsHDC, &r, lsHBR );
+}
+
+void CNFGClearFrame()
+{
+ RECT r = { 0, 0, lsLastWidth, lsLastHeight };
+ DeleteObject( lsClearBrush );
+ lsClearBrush = CreateSolidBrush( CNFGBGColor );
+ SelectObject( lsHDC, lsClearBrush );
+
+ FillRect( lsHDC, &r, lsClearBrush );
+}
+
+void CNFGSwapBuffers()
+{
+ int thisw, thish;
+ RECT r;
+ BitBlt( lsWindowHDC, 0, 0, lsLastWidth, lsLastHeight, lsHDC, 0, 0, SRCCOPY );
+ UpdateWindow( lsHWND );
+
+ //Check to see if the window is closed.
+ if( !IsWindow( lsHWND ) )
+ {
+ exit( 0 );
+ }
+
+ GetClientRect( lsHWND, &r );
+ thisw = r.right - r.left;
+ thish = r.bottom - r.top;
+ if( thisw != lsLastWidth || thish != lsLastHeight )
+ {
+ lsLastWidth = thisw;
+ lsLastHeight = thish;
+ InternalHandleResize();
+ }
+}
+
+void CNFGTackPoly( RDPoint * points, int verts )
+{
+ int i;
+ POINT * t = (POINT*)alloca( sizeof( POINT ) * verts );
+ for( i = 0; i < verts; i++ )
+ {
+ t[i].x = points[i].x;
+ t[i].y = points[i].y;
+ }
+ Polygon( lsHDC, t, verts );
+}
+
+
+void CNFGTackPixel( short x1, short y1 )
+{
+ SetPixel( lsHDC, x1, y1, CNFGLastColor );
+}
+*/
+
diff --git a/cnping.exe b/cnping.exe
Binary files differ.
diff --git a/ping.c b/ping.c
@@ -1,282 +1,309 @@
-/* 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. ***/
-/*****************************************************************************/
-
-#include <unistd.h>
-#include <string.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <strings.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
-void bzero(void *location,__LONG32 count);
-#include <windows.h>
-#include <stdio.h>
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <stdint.h>
-#else
-#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;
-};
-#endif
-
-float pingperiod;
-int precise_ping;
-
-#define PACKETSIZE 1500
-struct packet
-{
- struct icmphdr hdr;
- 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;
-}
-
-
-/*--------------------------------------------------------------------*/
-/*--- listener - separate process to listen for and collect messages--*/
-/*--------------------------------------------------------------------*/
-void listener(void)
-{
-#ifndef WIN32
- const int val=255;
-
- int sd = socket(PF_INET, SOCK_RAW, proto->p_proto);
-
- if ( setsockopt(sd, SOL_IP, IP_TTL, &val, sizeof(val)) != 0)
- {
- ERRM("Erro: could not set TTL option\n");
- exit( -1 );
- }
-
-#endif
-
- struct sockaddr_in addr;
- unsigned char buf[1024];
-
- for (;;)
- {
- int i;
- int bytes, len=sizeof(addr);
-
- bzero(buf, sizeof(buf));
- bytes = recvfrom(sd, buf, sizeof(buf), 0, (struct sockaddr*)&addr, &len);
- 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;
-
- if ( bytes > 0 )
- display(buf + 28, bytes - 28 );
- else
- perror("recvfrom");
- }
- printf( "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.
- 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();
-
- do
- { int len=sizeof(r_addr);
-
-// 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.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");
-
-
- if( precise_ping )
- {
- double ctime;
- do
- {
- ctime = OGGetAbsoluteTime();
- if( pingperiod >= 1000 ) stime = ctime;
- } while( ctime < stime + pingperiod );
- stime += pingperiod;
- }
- else
- {
- if( pingperiod > 0 )
- {
- uint32_t dlw = 1000000.0*pingperiod;
- usleep( dlw );
- }
- }
- } while( pingperiod >= 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.
-}
-
-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 )
- {
- ERRM( "Fault in WSAStartup\n" );
- exit( -2 );
- }
-#endif
-
-
-#ifdef WIN32
- sd = WSASocket(AF_INET, SOCK_RAW, IPPROTO_ICMP, 0, 0, 0);
- {
- int lttl = 0xff;
- if (setsockopt(sd, IPPROTO_IP, IP_TTL, (const char*)<tl,
- sizeof(lttl)) == SOCKET_ERROR) {
- printf( "Warning: No IP_TTL.\n" );
- }
- }
-#else
- const int val=255;
-
- sd = socket(PF_INET, SOCK_RAW, proto->p_proto);
-
- if ( setsockopt(sd, SOL_IP, IP_TTL, &val, sizeof(val)) != 0)
- {
- ERRM("Error: Failed to set TTL option\n");
- exit( -1 );
- }
-
-#endif
- if ( sd < 0 )
- {
- ERRM("Error: Could not create raw socket\n");
- exit(0);
- }
-
-}
-
-void do_pinger( const char * strhost )
-{
- struct hostent *hname;
- hname = gethostbyname(strhost);
-
- bzero(&psaddr, sizeof(psaddr));
- psaddr.sin_family = hname->h_addrtype;
- psaddr.sin_port = 0;
- psaddr.sin_addr.s_addr = *(long*)hname->h_addr;
- ping(&psaddr );
-}
-
-char errbuffer[1024];
-
-
+/* 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. ***/
+/*****************************************************************************/
+
+#include <string.h>
+#include <fcntl.h>
+#include <errno.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 usleep(int x) {
+ Sleep(x / 1000);
+}
+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>
+#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;
+};
+#endif
+
+float pingperiod;
+int precise_ping;
+
+#define PACKETSIZE 1500
+struct packet
+{
+ struct icmphdr hdr;
+ 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;
+}
+
+
+/*--------------------------------------------------------------------*/
+/*--- listener - separate process to listen for and collect messages--*/
+/*--------------------------------------------------------------------*/
+void listener(void)
+{
+#ifndef WIN32
+ const int val=255;
+
+ int sd = socket(PF_INET, SOCK_RAW, proto->p_proto);
+
+ if ( setsockopt(sd, SOL_IP, IP_TTL, &val, sizeof(val)) != 0)
+ {
+ ERRM("Erro: could not set TTL option\n");
+ exit( -1 );
+ }
+
+#endif
+
+ struct sockaddr_in addr;
+ unsigned char buf[8192];
+#ifdef WIN32
+ SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
+#endif
+ for (;;)
+ {
+ int i;
+ int bytes, len=sizeof(addr);
+
+ bzero(buf, sizeof(buf));
+#ifdef WIN32
+ WSAPOLLFD fda[1];
+ fda[0].fd = sd;
+ fda[0].events = POLLIN;
+ WSAPoll(fda, 1, 10);
+#endif
+ keep_retry_quick:
+ bytes = recvfrom(sd, buf, sizeof(buf), 0, (struct sockaddr*)&addr, &len);
+ 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;
+
+ if ( bytes > 0 )
+ display(buf + 28, bytes - 28 );
+ else
+ perror("recvfrom");
+
+ goto keep_retry_quick;
+ }
+ printf( "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.
+ 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();
+
+ do
+ { int len=sizeof(r_addr);
+
+// 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.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");
+
+
+ if( precise_ping )
+ {
+ double ctime;
+ do
+ {
+ ctime = OGGetAbsoluteTime();
+ if( pingperiod >= 1000 ) stime = ctime;
+ } while( ctime < stime + pingperiod );
+ stime += pingperiod;
+ }
+ else
+ {
+ if( pingperiod > 0 )
+ {
+ uint32_t dlw = 1000000.0*pingperiod;
+ usleep( dlw );
+ }
+ }
+ } while( pingperiod >= 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.
+}
+
+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 )
+ {
+ ERRM( "Fault in WSAStartup\n" );
+ exit( -2 );
+ }
+#endif
+
+
+#ifdef WIN32
+ 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*)<tl,
+ sizeof(lttl)) == SOCKET_ERROR) {
+ printf( "Warning: No IP_TTL.\n" );
+ }
+ }
+#else
+ const int val=255;
+
+ sd = socket(PF_INET, SOCK_RAW, proto->p_proto);
+
+ if ( setsockopt(sd, SOL_IP, IP_TTL, &val, sizeof(val)) != 0)
+ {
+ ERRM("Error: Failed to set TTL option\n");
+ exit( -1 );
+ }
+
+#endif
+ if ( sd < 0 )
+ {
+ ERRM("Error: Could not create raw socket\n");
+ exit(0);
+ }
+
+}
+
+void do_pinger( const char * strhost )
+{
+ struct hostent *hname;
+ hname = gethostbyname(strhost);
+
+ bzero(&psaddr, sizeof(psaddr));
+ psaddr.sin_family = hname->h_addrtype;
+ psaddr.sin_port = 0;
+ psaddr.sin_addr.s_addr = *(long*)hname->h_addr;
+ ping(&psaddr );
+}
+
+char errbuffer[1024];
+
+
diff --git a/resources.rc b/resources.rc
@@ -0,0 +1,22 @@
+1 24 "uac.manifest"
+
+#include <windows.h>
+
+LANGUAGE 9, SUBLANG_DEFAULT
+IPDialog DIALOG 10, 10, 300, 100
+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 "[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
+ EDITTEXT 3, 1, 15, 58, 12
+ EDITTEXT 4, 1, 30, 58, 12
+ EDITTEXT 5, 1, 45, 58, 12
+ EDITTEXT 6, 1, 60, 58, 12
+ PUSHBUTTON "&Ping", 7, 25, 80, 100, 10
+ PUSHBUTTON "&Close", 8, 175, 80, 100, 10
+END
+
diff --git a/uac.manifest b/uac.manifest
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="cnping" type="win32"/>
+ <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+ <security>
+ <requestedPrivileges>
+ <requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
+ </requestedPrivileges>
+ </security>
+ </trustInfo>
+</assembly>