Topic : Socket Programming
Author : Vijay Mukhi
Page : << Previous 10  
Go to page :


long and that kind'a makes it stand out but after these two programs, you should appreciate our coding style a little more.

The first function we look at is WinMain(). Here we load the DLL icmp.dll into memory and pass it's handle to hIcmp. The reason we do this rather than simply including the .lib file into the project and calling code directly is because Microsoft hasn't released a .lib file for this DLL yet! So we have to LoadLibrary it to use it. We then call WSAStartup() as usual. Right after that we initialize phostent, which is a pointer to the structure hostent, to the address returned by gethostbyname(). The next line assigns the IP address of www.microsoft.com to dwIPAddr.

The next three lines are a bunch of initialzations where we initialse three pointers to functions; pIcmpCreateFile, pIcmpCreateHandle and pIcmpSendEcho to the addresses of related functions.

We're getting to the real heart of the matter now...

After initializing the three pointers, we pass the handle returned by pIcmpCreateFile to hIP and then set the TTL to 60, a comfortably large number. The structure I looks like o which is the first structure to be defined in our source file. The fields in it correspond to fields in the IP header which can be changed by us.

pIcmpSendEcho is the main function of the code around which the entire program revolves. In pIcmpSendEcho, the first parameter is hIP, the handle to the ICMP connection. The next parameter is dwIPAddr which is a pointer to the IP address of www.microsoft.com. The next two parameters are zeros and these parameters are used when we're sending some data along with the ICMP packet. The reason we occasionally ping a computer with data is to check line reliability. When the recipient receives the bytes, it's supposed to respond with the same bytes. At our end, we can check the bytes to see it they've been corrupted or not.

After the zero's the next parameter is &I which is the address of the structure. The parameter after that is the address of the structure E. It too is defined before the WinMain(). E will hold data about the ping target and other information. The next parameter is the size of the structure and the final one is the total size.

The ICMP Ping packet is sent now and the structure E is filled up.

In the next couple of lines, we display data about the target, like it's IP address, the Round Trip Time of the packet and the TTL of the return trip packet.

Before we end, we close the ICMP handle, unload the DLL from memory and WSACleanup after ourselves.

Traceroute

trace.c


#include <windows.h>
     #include <stdio.h>
     void abc(char *p)
     {
      FILE *fp=fopen("z.txt","a+");
         fprintf(fp,"%s\n",p);
           fclose(fp);
     }
     struct o
     {
     unsigned char Ttl;unsigned char a[7];
     };
     struct
     {
     DWORD Address;
     unsigned long  Status,RoundTripTime;
     unsigned char a[8];
     struct o  Options;
     } E;

     HANDLE hIP;WSADATA wsa;HANDLE hIcmp;DWORD *dwIPAddr;struct hostent *phostent;
     DWORD d;char aa[100];struct o I;char bb[100];int z;

     HANDLE ( WINAPI *pIcmpCreateFile )( VOID );
     BOOL ( WINAPI *pIcmpCloseHandle )( HANDLE );
     DWORD (WINAPI *pIcmpSendEcho) (HANDLE,DWORD,LPVOID,WORD, LPVOID,    LPVOID,DWORD,DWORD);

     int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrev,
                                             LPSTR lpCmd,int nShow )
     {
     hIcmp = LoadLibrary( "ICMP.DLL" );
     WSAStartup( 0x0101, &wsa );
     pIcmpCreateFile=GetProcAddress( hIcmp,"IcmpCreateFile");
     pIcmpCloseHandle=GetProcAddress( hIcmp,"IcmpCloseHandle");
     pIcmpSendEcho =GetProcAddress( hIcmp,"IcmpSendEcho" );
     hIP = pIcmpCreateFile();

     for ( z = 1; z<= 20 ; z++)
     {
         I.Ttl=(unsigned char)z;
           phostent = gethostbyname( "www.neca.com");
         dwIPAddr = (DWORD *)( *phostent->h_addr_list );
         pIcmpSendEcho(hIP,*dwIPAddr,0,0,&I,&E,sizeof(E),8000 );
         d=E.Address;
           phostent = gethostbyaddr((char *)&d,4,PF_INET);
         if ( phostent != 0)
                strcpy(aa,phostent->h_name)  ;
         else
                strcpy(aa,"no host name");
        wsprintf(bb," RTT: %dms,  TTL:   %d", E.RoundTripTime,    E.Options.Ttl );
        strcat(aa,bb);
        abc(aa);
        if ( E.Options.Ttl )
             break;
     }
     MessageBox(0,"over","hi",0);
     pIcmpCloseHandle( hIP );
     FreeLibrary( hIcmp );
     WSACleanup();
     }



OUTPUT-(z.txt)


     no host name RTT: 241ms,  TTL: 0
     no host name RTT: 224ms,  TTL: 0
     border7-serial3-7.WestOrange.mci.net RTT: 798ms,  TTL: 0
     core2-fddi-0.WestOrange.mci.net RTT: 856ms,  TTL: 0
     core3.WestOrange.mci.net RTT: 841ms,  TTL: 0
     sprint-nap.WestOrange.mci.net RTT: 990ms,  TTL: 0
     sl-pen-2-F4/0.sprintlink.net RTT: 804ms,  TTL: 0
     sl-pen-7-F0/0.sprintlink.net RTT: 796ms,  TTL: 0
     sl-new2-1-S0-1544k.sprintlink.net RTT: 850ms,  TTL: 0
     cygnus.neca.com RTT: 803ms,  TTL: 246



The traceroute program given above is just an extension of the previous program. Through this program we try and discover the route our packet takes to and from it's final destination. If the route is overly long and complicated, then the data flow will be slow and unreliable, but if the server is just a few hops away, then the connection should be firm and stable. A tracer also helps us pinpoint the source of a network problem. There could be two reasons behind a failed ping; a dead server or a malfunctioning router on the way. If it's the latter, then a tracer helps us map out the route till the dead router and if it's part of an Intranet (a corporate Internet) we administer, we can call the service personnel and have it repaired.

The traceroute is an extension of the ping idea. What we do here is send a large number of packets with different TTL's. The first packet we send will have a TTL of 1. So when the packet reaches the very first router on the way, it'll expire. When the router drops the packet, it will send us an ICMP error message which we trap and decipher. That error message contains data about the router like it's IP address and Hostname. We capture that data and store it to a file on disk.

The next packet we send has a TTL of 2. So it's be dropped by the second router. That router too will send us an ICMP error message and we'll decipher that message too to extract the IP address and the Hostname. The next packet will have a TTL of 3 and it'll die at the third router and so on.

In this way we can map out the route our packets would take if sent down the Internet at that time. The very last message should be from the destination server. If it isn't there, then that means there's a broken link along the way somewhere, try another IP address or try again later.

Wrapping it all up

That just about wraps it up for now. If you want to dig deeper into the intricacies of WinSock programming, check out our tutorials on various Socket level protocols like LDAP, SNMP, IMAP and others. If you feel the urge to discover more about the protocols that actually constitute the Internet, like TCP, IP, UDP etc. Read our Core Internet Concepts tutorial.





The above tutorial is a joint effort of
Mr. Vijay Mukhi
Mr. Arsalan Zaidi
Ms. Sonal Kotecha
Mr. R. D. Parab


Page : << Previous 10