Tuesday, November 21, 2006

Network Traffic Calculator using VC++ 6 on XP

An Introduction
This is a simple VC++ (made in 6) program that calculates the total number of bytes transfered in a network connection. Made in and tested for Windows XP.

main.cpp


/*
Network Traffic Calculator
(c) digitalpbk.blogspot.com
*/


#include <windows.h>
#include <wingdi.h>
#include <protocol.h>
#include <stdio.h>

#define REGULAR 0
#define BOLD 1
#define ITALIC 2
#define ULINE 3

void getInterfaceList(char list[][17],int max);
int ConnectSock(char sck[],int port,HWND hwnd);
void processData(char[]);

HWND txtW;

HFONT GetAFont(int fnFont);

typedef struct _DATA // our datatransfer structure.
{
int mb;
int kb;
int bytes;
}BITDATA;

BITDATA recd,sent,total;
SOCKET gSokt;

BITDATA Add(BITDATA b1,BITDATA b2) // adds bytes to our data structure
{
BITDATA ret;
ret.bytes = b1.bytes + b2.bytes;
ret.kb = b1.kb + b2.kb;
ret.mb = b1.mb + b2.mb;

if(ret.bytes >= 1024)
{
ret.bytes = 0;
ret.kb ++;
}
if(ret.kb >=1024)
{
ret.mb ++;
ret.kb =0;
}
return ret;
}
BITDATA Add(BITDATA b1,int bytes)
{
BITDATA ret=b1;
ret.bytes += bytes;
if(ret.bytes >= 1024)
{
ret.bytes = 0;
ret.kb ++;
}
if(ret.kb >=1024)
{
ret.mb ++;
ret.kb =0;
}
return ret;
}

long FAR PASCAL WndProc( HWND hwnd,UINT msg,UINT wParam, LONG lParam )
{
PAINTSTRUCT ps;
RECT rc;
HDC hdc;


int x;
static si=48;
si++;
char bfr[60]={si,0},num[6];

long l;

switch(msg)
{

case 0x401: // network event detected.
if(lParam == FD_READ)
{
x=0;
char *bufr=new char[10000];
do
{
x=recv(wParam,bufr,10000,0);
processData(bufr);
}while(x==10000);
delete bufr;
}
case WM_PAINT:

hdc=BeginPaint(hwnd,&ps);

strcpy(bfr ,"Data S/R: ");
itoa(total.mb,num,10);
strcat(bfr,num);
strcat(bfr,".");

itoa(total.kb,num,10);
strcat(bfr,num);
strcat(bfr,".");

itoa(total.bytes,num,10);
strcat(bfr,num);

l=strlen(bfr);
SetWindowText(txtW,bfr);

EndPaint(hwnd,&ps);
return 0;
case WM_DESTROY:
WSAAsyncSelect(gSokt,hwnd,0x401,0);
closesocket(gSokt);
if(WSAIsBlocking())WSACancelBlockingCall();
WSACleanup();

PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd,msg,wParam,lParam);
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpszCmdParam,int nCmdShow) //Windows Main
{
/*standard win32 application init*/
static char szAppName[] = "Traffic Analyzer";
HWND hwnd;
MSG msg;
WNDCLASS wc;

if(!hPrevInstance)
{
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL,IDI_WARNING);
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = szAppName;
RegisterClass(&amb;wc);
}
/*gets network addresses*/
char localaddr[5][17];
if(getInterfaceList(localaddr,5))
return 1;
char szTitle[100]="Traffic Calc on ";
strcat(szTitle,localaddr[0]);
/*window creation
hwnd = CreateWindowEx(WS_EX_TOOLWINDOW|WS_EX_TOPMOST,szAppName,szTitle,WS_SYSMENU,CW_USEDEFAULT,CW_USEDEFAULT,240,40,NULL,NULL,hInstance,NULL);

HWND hwndTxtOut=CreateWindow("EDIT","Usage Stats loading....",WS_CHILD|WS_VISIBLE,0,0,240,20,hwnd,NULL,hInstance ,NULL);
txtW = hwndTxtOut;

gSokt = ConnectSock(localaddr[0],7000,hwnd);

ShowWindow(hwnd,nCmdShow);
UpdateWindow( hwnd );

/*Window Procedure Loop
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

return msg.wParam;
}

void processData(char data[])
{
IP_HEADER iphead;
memcpy(&iphead,data,sizeof(iphead)); //gets the Length of each packet
total = Add(total,ntohs(iphead.length)); // adds with previous results
}


winsocks.cpp

/*winsocks.cpp
(c) digitalpbk.blogspot.com
*/


#include <winsock2.h>
#include <WS2TCPIP.H>

int getInterfaceList(char list[][17],int max) // gets all network connections
{
WORD wVs = MAKEWORD(2,2);
WSADATA wsaData;


int err=WSAStartup(wVs,&wsaData);
if(err!=0)
return err;

long lnRes;
SOCKET Sock;
unsigned long lnBytesReturned;
INTERFACE_INFO buffer[7];
//start up winsock

Sock = socket(AF_INET,SOCK_STREAM,IPPROTO_IP);

lnRes = WSAIoctl(Sock, SIO_GET_INTERFACE_LIST,0, 0,&buffer, 1024, &lnBytesReturned,0, 0);

if(lnRes)
return WSAGetLastError();

for(int i=0u;i<lnBytesReturned/76;i++)
{
if(i<max)strcpy(list[i],inet_ntoa(buffer[i].iiAddress.AddressIn.sin_addr));
}
closesocket(Sock);
return 0;
}
int ConnectSock(char sck[],int port,HWND hwnd)
{
WORD wVs = MAKEWORD(2,2);
WSADATA wsaData;

int err=WSAStartup(wVs,&wsaData);
if(err!=0)
return INVALID_SOCKET;

SOCKADDR_IN sin;

sin.sin_family = AF_INET;
sin.sin_port = htons(port);

if(sin.sin_port == INVALID_SOCKET)
return INVALID_SOCKET;
unsigned long iret = inet_addr(sck);
memcpy(&sin.sin_addr,&iret,4);

SOCKET s=socket(AF_INET,SOCK_RAW,IPPROTO_IP);
if(s<0)return INVALID_SOCKET;
long TIMEO = 5000;
err = setsockopt(s,SOL_SOCKET,SO_RCVTIMEO,(char *)&TIMEO,4);
if(err)
{
if(s>0)closesocket(s);
return INVALID_SOCKET;
}
err = bind(s,(sockaddr *)&sin,sizeof(sin));
if(err)
{
if(s>0)closesocket(s);
return INVALID_SOCKET;
}
unsigned long retd;
long lnInpBufr=1,lnOutBufr=0;

err = WSAIoctl(s,0x98000001,&lnInpBufr,sizeof(long),&lnOutBufr,sizeof(long),&retd,NULL,NULL);
if(err)
{
if(s>0)closesocket(s);
return INVALID_SOCKET;
}
err = WSAAsyncSelect(s,hwnd,0x401,FD_READ);
if(err)
{
if(s>0)closesocket(s);
return INVALID_SOCKET;
}
return s;
}

Dont know what to do with the code?
Take VC++ 6,
File > New, In Projects tab, new Win32 Application, give a name also like "trafficcalc",
Choose empty project.
Next File > New, In Files tab, take C++ source file, give filename "main.cpp"
repeat the step for filename "winsocks.cpp"
Copy the sources to the files.
Save and Execute!

Download the full source with Workspace files from planet-source-code.com

Anything else?
leave a comment...

2 comments:

ann said...

while i tried to compile this code ,the following error is reported
"fatal error C1083: Cannot open include file: 'protocol.h': No such file or directory"
how can i get rid of it ???

Arun Prabhakar said...

Please use correct VC++ 6 and ensure the required header files are there.
I have a protocol.h in my distribution.