Internet Control Message Protocol (ICMP)
Programs


In the earlier tutorial we discussed the generalities of the various uses ICMP can be put to. Here are some programs that use Serial communication under Windows95 and PPP to send ICMP packets all over the web. We strongly suggest you read through our PPP tutorial ( which has a section on Serial Communication) before you try this because we won't be explaining either of them here.

Lets jump right into the first program here and try it out. We used VC++ 4.0 to create these projects.

The function you have to watch out for is zzz(), the callback. This is because it's only when you click on the menu 'Echo Request' that the ICMP packets are generated and released.

The explanation is at the end of the program.

PING

icmp1.rc

mmm menu
begin
menuitem "Echo Request",100
end

icmp1.c


#include <windows.h>
#include <stdio.h>
struct packet
{
unsigned char data[1000];
unsigned int packetsize;
};

struct iphdr
{
unsigned char verlen;
unsigned char tos;
unsigned short totlen;
unsigned short id;
unsigned short frag;
unsigned char ttl;
unsigned char prot;
unsigned short chksum;
unsigned char  sourceip[4];
unsigned char destip[4];
};

struct icmp
{
	unsigned char type;
	unsigned char code;
	unsigned short chksum;
	unsigned short id;
	unsigned short seqno;
};

unsigned short checksum(unsigned short *ip1,unsigned int len);
unsigned int ohtons(unsigned int h);
unsigned long ohtonl(unsigned long h);
unsigned char id=0;
void abcchar(unsigned char );
void abc(char *);
void processpacket();
void unescape(struct packet *,struct packet *);
void removeframe(struct packet *,struct packet *);
long _stdcall zzz(HWND ,UINT ,WPARAM ,LPARAM );
void lcppacket(struct packet *);
unsigned int calcchksum(unsigned char *,int );
void escapeit(struct packet *);
void escapeip(struct packet *);
void addsevene(struct packet *);
void sendit(struct packet *);
void sendconfack(struct packet *);
unsigned int addffthree(struct packet *);
void sendconfreq();
void ipcppacket(struct packet * );
void sendipcpack(struct packet *);
void sendipcpreq();
void sendechoreply(struct packet *);
void erequest();
void writeabc(unsigned char * ip, unsigned char *tcp, unsigned char opt[]);

unsigned char sipaddress[4]={0,0,0,0};

HDC  hDC ;
HANDLE  idComDev ;
HWND  hTTYWnd ;

struct packet recdpacket;
int  nColumn, nRow, xChar, yChar ,cnt=0, ctr=0;
DWORD dwThreadID, dwBytesRecd,dwBytesWritten;
DCB dcb;
WNDCLASS a;
MSG c;
unsigned char aa[200],packetrecd[1000],cc,dd;

typedef unsigned short u16;
static u16 fcstab[256] = {
    0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
    0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
    0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
    0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
    0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
    0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
    0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
    0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
    0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
    0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
    0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
    0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
    0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
    0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
    0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
    0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
    0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
    0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
    0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
    0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
    0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
    0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
    0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
    0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
    0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
    0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
    0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
    0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
    0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
    0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
    0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
    0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
};
#define PPPINITFCS16 0xffff
#define PPPGOODFCS16 0xf0b8

DWORD FAR PASCAL CommWatchProc()
{
 BYTE abIn[2] ; 
 while (1)
 { 	  
	ReadFile(idComDev,abIn,1,&dwBytesRecd,0);
	if (abIn[0] == 0x7e )
	{
	  if(ctr == 0)
	  {
		  cnt=0;	
		  ctr=1;
	  }
	  else if (ctr == 1)
	  { 
		  	ctr++;
			
	  }
  	  else if (ctr == 2)
	  { 
		  	ctr = 1;
			recdpacket.data[cnt]=abIn[0];
			cnt++;
			recdpacket.packetsize=cnt;
			cnt=0;
			processpacket();
	  }
    }	 
	if (ctr ==2 )
	{	  
		recdpacket.data[cnt]=abIn[0];
		cnt++;
	}
    if (abIn[0] == 13 )
		nColumn = 0 ;
    if (abIn[0] == 10)
		nRow++;
    if (abIn[0] == 0x08)
	    nColumn -- ;
	if (abIn[0] != 0x0a && abIn[0] != 0x0d)
	{
		TextOut(hDC,nColumn*xChar,nRow*yChar,abIn,1);
		if (nColumn < 79)
				nColumn++ ;
		else
		{
			nColumn = 0;
			nRow++;
		}
	}
 }
 return( TRUE ) ;
}


int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpszCmdLine, int nCmdShow )
{
a.lpfnWndProc=zzz;
a.hInstance=hInstance;
a.hbrBackground=(HBRUSH)(COLOR_WINDOW + 1) ;
a.lpszClassName="aa";
a.lpszMenuName="mmm";
RegisterClass(&a);
hTTYWnd=CreateWindow("aa","hi",WS_OVERLAPPEDWINDOW,0,0,0,0,0,0,hInstance,0);
xChar = 8;
yChar = 19;
ShowWindow( hTTYWnd, 3 ) ;
hDC=GetDC(hTTYWnd);

idComDev= CreateFile( "COM1", GENERIC_READ | GENERIC_WRITE,1,NULL,	
	OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL );

dcb.DCBlength = sizeof( DCB ) ;
GetCommState( idComDev, &dcb ) ;
dcb.BaudRate = 14400 ;
SetCommState( idComDev, &dcb ) ;
CreateThread(0,0,(LPTHREAD_START_ROUTINE) CommWatchProc,0,0, &dwThreadID );
strcpy(aa,"atdt2659385\r");
WriteFile(idComDev,aa,strlen(aa),&dwBytesWritten,0) ;
while (GetMessage( &c, NULL, 0, 0 ))
   {
       TranslateMessage( &c ) ;
       DispatchMessage( &c ) ;
   }
   return ( (int) 0 ) ;
}


long _stdcall zzz(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
   	if(uMsg == WM_COMMAND && wParam == 100)
	{
		erequest();
	}
	if(uMsg == WM_CHAR)
    {
         cc = wParam;
         WriteFile(idComDev,&cc,1,&dwBytesWritten,0) ;
    }
    if(uMsg == WM_DESTROY)
	{
		 ReleaseDC(hWnd,hDC);
         PostQuitMessage( 0 ) ;
	}
         return( DefWindowProc( hWnd, uMsg, wParam, lParam ) ) ;
}  


void processpacket()
{
	struct packet unescpacket,finalpacket;
	unsigned int i;
       
	
	abc("Recd Packet After Unescaping");
	unescape(&recdpacket,&unescpacket);
	for(i=0; i<unescpacket.packetsize;i++)
		abcchar(unescpacket.data[i]);
	removeframe(&unescpacket,&finalpacket);
	
	if(finalpacket.data[0] == 0xc0 && finalpacket.data[1] == 0x21)
		lcppacket(&finalpacket);
	if(finalpacket.data[0] == 0x80 && finalpacket.data[1] == 0x21)
		ipcppacket(&finalpacket);
	if(finalpacket.data[0] == 0x00 && finalpacket.data[1] == 0x21)
		MessageBox(0,"IP Packet Received","IP Packet Received",0);
}
void ipcppacket(struct packet * f)
{
if (f->data[2]== 1)
{
	sendipcpack(f);
	sendipcpreq(sipaddress);
}

if (f->data[2]== 2)
{
	MessageBox(0,"ipcp Ack received","ipcp Ack received",0);
}

if (f->data[2]== 3)
{
	sipaddress[0]=f->data[8];
	sipaddress[1]=f->data[9];
	sipaddress[2]=f->data[10];
	sipaddress[3]=f->data[11];
	sendipcpreq(sipaddress);
}

if (f->data[2]== 4)
{
	MessageBox(0,"ipcp Reject received","ipcp Reject received",0);
}

}

void sendipcpack(struct packet *aipcp)
{
aipcp->data[2]=2;
aipcp->packetsize=addffthree(aipcp);
aipcp->packetsize=calcchksum(aipcp->data,aipcp->packetsize);
escapeit(aipcp);
addsevene(aipcp);
sendit(aipcp);
}


void sendipcpreq(char ipadd[])
{
struct packet ipcpreq;
ipcpreq.data[0]=0x80;
ipcpreq.data[1]=0x21;
ipcpreq.data[2]=0x01;
ipcpreq.data[3]=0x1;
ipcpreq.data[4]=0x00;
ipcpreq.data[5]=0xa;
ipcpreq.data[6]=0x3;
ipcpreq.data[7]=0x6;
ipcpreq.data[8]=ipadd[0];
ipcpreq.data[9]=ipadd[1];
ipcpreq.data[10]=ipadd[2];
ipcpreq.data[11]=ipadd[3];
ipcpreq.packetsize=12;
ipcpreq.packetsize=addffthree(&ipcpreq);
ipcpreq.packetsize=calcchksum(ipcpreq.data,ipcpreq.packetsize);
escapeit(&ipcpreq);
addsevene(&ipcpreq);
sendit(&ipcpreq);

}



void unescape(struct packet *r, struct packet *u)
{	
	unsigned int i,j;
	for(j=0,i=0;i<r->packetsize;i++,j++)
	{
		if (r->data[i]==0x7d)
		{
			i++;
			u->data[j]=r->data[i]^0x20;
		}
		else
		{
		u->data[j]=r->data[i];
		}
	}
	u->packetsize=j;
}


void abc(char *p)
{
	FILE *fp;
	fp=fopen("c:\\z.txt","a+");
	fprintf(fp,"%s\n",p);
	fclose(fp);
}
void abcchar(unsigned char c)
{
	FILE *fp;
	fp=fopen("c:\\z.txt","a+");
	fprintf(fp,"%c..%x..%d\n",c,c,c);
	fclose(fp);
}

void removeframe(struct packet *u,struct packet *f)
{
	unsigned int i,j;
	for(i=0,j=3;j<u->packetsize-3;i++,j++)
	{
	f->data[i]=u->data[j];
	}
	f->packetsize=i;
}

void lcppacket(struct packet *lcp)
{
if (lcp->data[2]== 1)
{
	sendconfack(lcp);
	sendconfreq();
}
if (lcp->data[2]== 9)
{
	sendechoreply(lcp);
	
}
}

void sendechoreply(struct packet * alcp)
{
alcp->data[2]=10;
alcp->packetsize=addffthree(alcp);
alcp->packetsize=calcchksum(alcp->data,alcp->packetsize);
escapeit(alcp);
addsevene(alcp);
sendit(alcp);

}


void sendconfreq()
{
	
struct packet lcpreq;
lcpreq.data[0]=0xc0;
lcpreq.data[1]=0x21;
lcpreq.data[2]=0x01;
lcpreq.data[3]=id;
lcpreq.data[4]=0x00;
lcpreq.data[5]=0x04;
lcpreq.packetsize=6;
lcpreq.packetsize=addffthree(&lcpreq);
lcpreq.packetsize=calcchksum(lcpreq.data,lcpreq.packetsize);
escapeit(&lcpreq);
addsevene(&lcpreq);
sendit(&lcpreq);
id++;

}



void sendconfack(struct packet *alcp)
{

alcp->data[2]=2;
alcp->packetsize=addffthree(alcp);
alcp->packetsize=calcchksum(alcp->data,alcp->packetsize);
escapeit(alcp);
addsevene(alcp);
sendit(alcp);

}


u16 pppfcs16(fcs,cp,len)
register u16 fcs;
register unsigned char *cp;
register int len;
{
while ( len -- )
fcs = ( fcs>>8 ) ^ fcstab[ (fcs^*cp++) & 0xff];
return fcs;
}

unsigned int calcchksum(cp,len)
register unsigned char *cp;
register int len;
{
u16 trialfcs;
trialfcs = pppfcs16(PPPINITFCS16,cp,len);
trialfcs ^= 0xffff;
cp[len] = (trialfcs & 0x00ff);
cp[len+1] = ((trialfcs >> 8 ) & 0x00ff);
return len+2;
}

unsigned int addffthree(struct packet *flcp)
{
	struct packet dummy;
	unsigned int i,j=0;
	dummy.data[j]=0xff;
	j++;
	dummy.data[j]=0x03;
	j++;
	for(i=0; i< flcp->packetsize;i++,j++)
	{
		dummy.data[j]=flcp->data[i];
	}
	dummy.packetsize=j;
	for(i=0;i<dummy.packetsize;i++)
	{
		flcp->data[i]=dummy.data[i];
	}
	flcp->packetsize=dummy.packetsize;
	
	
	return flcp->packetsize;
	}


void escapeit(struct packet * epacket)
{
	struct packet dummy;
	unsigned int i,j;
	for(i=0;i<epacket->packetsize;i++)
	{
		dummy.data[i]=epacket->data[i];
	}
	dummy.packetsize=epacket->packetsize;
     
	for(j=0,i=0;i<dummy.packetsize;i++,j++)
	{
		if (dummy.data[i] <= 31 || dummy.data[i] == 0x7e || dummy.data[i]== 0x7d)
		{
			epacket->data[j]=0x7d;
			j++;
			epacket->data[j]=dummy.data[i]^0x20;
		}
		else
			epacket->data[j]=dummy.data[i];
	}
	epacket->packetsize=j;
	
}
void escapeip(struct packet * epacket)
{
	struct packet dummy;
	unsigned int i,j;
	for(i=0;i<epacket->packetsize;i++)
	{
		dummy.data[i]=epacket->data[i];
	}
	dummy.packetsize=epacket->packetsize;
     
	for(j=0,i=0;i<dummy.packetsize;i++,j++)
	{
		if (dummy.data[i] == 0x7e || dummy.data[i]== 0x7d)
		{
			epacket->data[j]=0x7d;
			j++;
			epacket->data[j]=dummy.data[i]^0x20;
		}
		else
			epacket->data[j]=dummy.data[i];
	}
	epacket->packetsize=j;
	
}

void addsevene(struct packet * apacket)
{
	struct packet dummy;
	unsigned int i,j;
	for(i=0;i<apacket->packetsize;i++)
	{
		dummy.data[i]=apacket->data[i];
	}
	dummy.packetsize=i;
	apacket->data[0]=0x7e;
	for(i=0,j=1;i<dummy.packetsize;i++,j++)
	{
		apacket->data[j]=dummy.data[i];
	}

	apacket->data[j]=0x7e;
	j++;
	apacket->packetsize=j;
}

void sendit(struct packet * spacket)
{
unsigned int i;
WriteFile(idComDev,spacket->data,spacket->packetsize,&dwBytesWritten,0) ;
abc("Final Packet Sent");
for(i=0; i< spacket->packetsize;i++)
	abcchar(spacket->data[i]);
}


void erequest()
{
	struct icmp er;
	struct iphdr ip;
	er.type=0x08;
	er.code=0;
	er.chksum=0;
	er.id=ohtons(7);
	er.seqno=ohtons(9);
	er.chksum=checksum(&er,8);
	ip.verlen	=0x45;
	ip.tos		=0x0;
	ip.totlen	=ohtons(28);
	ip.id		=ohtons(1);
	ip.frag		=0x00;
	ip.ttl		=32;
	ip.prot		=0x1;
	ip.chksum	=0;
	ip.sourceip[0]	=sipaddress[0];
	ip.sourceip[1]	=sipaddress[1];
	ip.sourceip[2]	=sipaddress[2];
	ip.sourceip[3]	=sipaddress[3];
	ip.destip[0]	=202;
	ip.destip[1]	=54;
	ip.destip[2]	=1;
	ip.destip[3]	=30;
	ip.chksum	=checksum(&ip,20);

	writeabc(&ip,&er,0);

}

void writeabc(unsigned char * ip, unsigned char *icmp, unsigned char opt[])
{
	struct packet ipicmp;
	unsigned int i,j;
	unsigned char uu[1000];
	uu[0]=0x21;
	for(j=1,i=0;i<20;i++,j++)
	{
		uu[j]=ip[i];
	}
	
	for(i=0;i<8;i++,j++)
	{	
		uu[j]=icmp[i];
	}

	
	for(i=0;i<j;i++)
	{
	ipicmp.data[i]=uu[i];
	}
	ipicmp.packetsize=j;
	ipicmp.packetsize=calcchksum(ipicmp.data,ipicmp.packetsize);
	abc("Unescaped Packet To Be Sent");
	for(i=0; i< ipicmp.packetsize;i++)
		abcchar(ipicmp.data[i]);
	escapeip(&ipicmp);
	
	addsevene(&ipicmp);
	sendit(&ipicmp);
	MessageBox(0,"IP Packet","Icmp",0);
}

unsigned short checksum(unsigned short *ip1,unsigned int len)
{
long sum = 0;
while ( len > 1)
{
sum += *ip1++;
if ( sum & 0x80000000 )
sum = ( sum & 0xffff) + ( sum >> 16);
len -= 2;
}
while ( sum >> 16)
sum = ( sum & 0xffff) + ( sum >> 16);
return ~sum;
}
unsigned int ohtons(unsigned int h)
{
unsigned char h1,h2;
unsigned short h5;
h1 = (unsigned char ) h & 0xff;
h2 = (h >> 8)&0xff;
h5 = 256*h1 + h2 ;
return h5;
}
unsigned long ohtonl(unsigned long h)
{
unsigned char h1,h2,h3,h4;
unsigned long h5;
h1 = (unsigned char ) h & 0x000000ff;
h2 = (h >> 8)&0x000000ff;
h3 = (h >> 16) & 0x000000ff;
h4 = (h >> 24 ) & 0x000000ff;
h5 = ((long)1<<24)*h1 + h4 + h3*256 + h2*65536;
return h5;
}

z.txt

Recd Packet After Unescaping
~..7e..126
..ff..255
..3..3
 ..0..0
!..21..33
E..45..69
 ..0..0
 ..0..0
..1c..28
..be..190
..97..151
@..40..64
 ..0..0
..fd..253
..1..1
&..26..38
8..38..56
..ca..202
6..36..54
..1..1
..1e..30
..ca..202
6..36..54
..3..3
..86..134
 ..0..0                 /// Echo Reply
 ..0..0
..ff..255
..ef..239
 ..0..0
..7..7
 ..0..0
	..9..9
l..6c..108
..9f..159
~..7e..126

Once you've connected to your ISP and filled in the necessary details at the prompt, the PPP bytes will start appearing in the window. Once you get the message box "IPCP ACK received", it's safe for you to click on the menu and send your packet. When you click on the menu item 'Echo Request', the function zzz() is called. Zzz() in turn calls the function erequest which actually does all the work.

In erequest(), we first declare two structures called er and ip which stand for the ICMP and IP headers. The ICMP header is filled out first and all the necessary details like the Type number (0x08 for echo request) and ID are filled in. The checksum is also calculated. Right after that the IP header is filled up with all the usual bytes. The function writeabc() is then called and passed both the headers and a 0. The function writeabc() places the bytes into a structure ipicmp which looks like packet and sends the bytes across the wire. Before being sent, other functions like escapeip() and addsevene() are also called. Whatever we receive is placed in the file z.txt. If we're successful, we receive an ICMP packet with a Type equal to 0. This is the Echo reply.

Subnet Masks

icmp2.rc


mmm menu
begin
menuitem "Subnet Mask",100
end

icmp2.c


#include <windows.h>
#include <stdio.h>
struct packet
{
unsigned char data[1000];
unsigned int packetsize;
};

struct iphdr
{
unsigned char verlen;
unsigned char tos;
unsigned short totlen;
unsigned short id;
unsigned short frag;
unsigned char ttl;
unsigned char prot;
unsigned short chksum;
unsigned char  sourceip[4];
unsigned char destip[4];
};

struct icmp
{
	unsigned char type;
	unsigned char code;
	unsigned short chksum;
	unsigned short id;
	unsigned short seqno;
	unsigned long subnet;
};

unsigned short checksum(unsigned short *ip1,unsigned int len);
unsigned int ohtons(unsigned int h);
unsigned long ohtonl(unsigned long h);
unsigned char id=0;
void abcchar(unsigned char );
void abc(char *);
void processpacket();
void unescape(struct packet *,struct packet *);
void removeframe(struct packet *,struct packet *);
long _stdcall zzz(HWND ,UINT ,WPARAM ,LPARAM );
void lcppacket(struct packet *);
unsigned int calcchksum(unsigned char *,int );
void escapeit(struct packet *);
void escapeip(struct packet *);
void addsevene(struct packet *);
void sendit(struct packet *);
void sendconfack(struct packet *);
unsigned int addffthree(struct packet *);
void sendconfreq();
void ipcppacket(struct packet * );
void sendipcpack(struct packet *);
void sendipcpreq();
void sendechoreply(struct packet *);
void erequest();
void writeabc(unsigned char * ip, unsigned char *tcp, unsigned char opt[]);

unsigned char sipaddress[4]={0,0,0,0};

HDC  hDC ;
HANDLE  idComDev ;
HWND  hTTYWnd ;

struct packet recdpacket;
int  nColumn, nRow, xChar, yChar ,cnt=0, ctr=0;
DWORD dwThreadID, dwBytesRecd,dwBytesWritten;
DCB dcb;
WNDCLASS a;
MSG c;
unsigned char aa[200],packetrecd[1000],cc,dd;

typedef unsigned short u16;
static u16 fcstab[256] = {
    0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
    0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
    0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
    0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
    0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
    0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
    0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
    0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
    0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
    0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
    0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
    0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
    0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
    0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
    0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
    0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
    0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
    0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
    0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
    0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
    0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
    0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
    0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
    0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
    0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
    0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
    0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
    0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
    0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
    0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
    0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
    0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
};
#define PPPINITFCS16 0xffff
#define PPPGOODFCS16 0xf0b8

DWORD FAR PASCAL CommWatchProc()
{
 BYTE abIn[2] ; 
 while (1)
 { 	  
	ReadFile(idComDev,abIn,1,&dwBytesRecd,0);
	if (abIn[0] == 0x7e )
	{
	  if(ctr == 0)
	  {
		  cnt=0;	
		  ctr=1;
	  }
	  else if (ctr == 1)
	  { 
		  	ctr++;
			
	  }
  	  else if (ctr == 2)
	  { 
		  	ctr = 1;
			recdpacket.data[cnt]=abIn[0];
			cnt++;
			recdpacket.packetsize=cnt;
			cnt=0;
			processpacket();
	  }
    }	 
	if (ctr ==2 )
	{	  
		recdpacket.data[cnt]=abIn[0];
		cnt++;
	}
    if (abIn[0] == 13 )
		nColumn = 0 ;
    if (abIn[0] == 10)
		nRow++;
    if (abIn[0] == 0x08)
	    nColumn -- ;
	if (abIn[0] != 0x0a && abIn[0] != 0x0d)
	{
		TextOut(hDC,nColumn*xChar,nRow*yChar,abIn,1);
		if (nColumn < 79)
				nColumn++ ;
		else
		{
			nColumn = 0;
			nRow++;
		}
	}
 }
 return( TRUE ) ;
}


int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpszCmdLine, int nCmdShow )
{
a.lpfnWndProc=zzz;
a.hInstance=hInstance;
a.hbrBackground=(HBRUSH)(COLOR_WINDOW + 1) ;
a.lpszClassName="aa";
a.lpszMenuName="mmm";
RegisterClass(&a);
hTTYWnd=CreateWindow("aa","hi",WS_OVERLAPPEDWINDOW,0,0,0,0,0,0,hInstance,0);
xChar = 8;
yChar = 19;
ShowWindow( hTTYWnd, 3 ) ;
hDC=GetDC(hTTYWnd);

idComDev= CreateFile( "COM1", GENERIC_READ | GENERIC_WRITE,1,NULL,	
	OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL );

dcb.DCBlength = sizeof( DCB ) ;
GetCommState( idComDev, &dcb ) ;
dcb.BaudRate = 14400 ;
SetCommState( idComDev, &dcb ) ;
CreateThread(0,0,(LPTHREAD_START_ROUTINE) CommWatchProc,0,0, &dwThreadID );
strcpy(aa,"atdt2659385\r");
WriteFile(idComDev,aa,strlen(aa),&dwBytesWritten,0) ;
while (GetMessage( &c, NULL, 0, 0 ))
   {
       TranslateMessage( &c ) ;
       DispatchMessage( &c ) ;
   }
   return ( (int) 0 ) ;
}


long _stdcall zzz(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
   	if(uMsg == WM_COMMAND && wParam == 100)
	{
		erequest();
	}
	if(uMsg == WM_CHAR)
    {
         cc = wParam;
         WriteFile(idComDev,&cc,1,&dwBytesWritten,0) ;
    }
    if(uMsg == WM_DESTROY)
	{
		 ReleaseDC(hWnd,hDC);
         PostQuitMessage( 0 ) ;
	}
         return( DefWindowProc( hWnd, uMsg, wParam, lParam ) ) ;
}  


void processpacket()
{
	struct packet unescpacket,finalpacket;
	unsigned int i;
       
	
	abc("Recd Packet After Unescaping");
	unescape(&recdpacket,&unescpacket);
	for(i=0; i<unescpacket.packetsize;i++)
		abcchar(unescpacket.data[i]);
	removeframe(&unescpacket,&finalpacket);
	
	if(finalpacket.data[0] == 0xc0 && finalpacket.data[1] == 0x21)
		lcppacket(&finalpacket);
	if(finalpacket.data[0] == 0x80 && finalpacket.data[1] == 0x21)
		ipcppacket(&finalpacket);
	if(finalpacket.data[0] == 0x00 && finalpacket.data[1] == 0x21)
		MessageBox(0,"IP Packet Received","IP Packet Received",0);
}
void ipcppacket(struct packet * f)
{
if (f->data[2]== 1)
{
	sendipcpack(f);
	sendipcpreq(sipaddress);
}

if (f->data[2]== 2)
{
	MessageBox(0,"ipcp Ack received","ipcp Ack received",0);
}

if (f->data[2]== 3)
{
	sipaddress[0]=f->data[8];
	sipaddress[1]=f->data[9];
	sipaddress[2]=f->data[10];
	sipaddress[3]=f->data[11];
	sendipcpreq(sipaddress);
}

if (f->data[2]== 4)
{
	MessageBox(0,"ipcp Reject received","ipcp Reject received",0);
}

}

void sendipcpack(struct packet *aipcp)
{
aipcp->data[2]=2;
aipcp->packetsize=addffthree(aipcp);
aipcp->packetsize=calcchksum(aipcp->data,aipcp->packetsize);
escapeit(aipcp);
addsevene(aipcp);
sendit(aipcp);
}


void sendipcpreq(char ipadd[])
{
struct packet ipcpreq;
ipcpreq.data[0]=0x80;
ipcpreq.data[1]=0x21;
ipcpreq.data[2]=0x01;
ipcpreq.data[3]=0x1;
ipcpreq.data[4]=0x00;
ipcpreq.data[5]=0xa;
ipcpreq.data[6]=0x3;
ipcpreq.data[7]=0x6;
ipcpreq.data[8]=ipadd[0];
ipcpreq.data[9]=ipadd[1];
ipcpreq.data[10]=ipadd[2];
ipcpreq.data[11]=ipadd[3];
ipcpreq.packetsize=12;
ipcpreq.packetsize=addffthree(&ipcpreq);
ipcpreq.packetsize=calcchksum(ipcpreq.data,ipcpreq.packetsize);
escapeit(&ipcpreq);
addsevene(&ipcpreq);
sendit(&ipcpreq);

}



void unescape(struct packet *r, struct packet *u)
{	
	unsigned int i,j;
	for(j=0,i=0;i<r->packetsize;i++,j++)
	{
		if (r->data[i]==0x7d)
		{
			i++;
			u->data[j]=r->data[i]^0x20;
		}
		else
		{
		u->data[j]=r->data[i];
		}
	}
	u->packetsize=j;
}


void abc(char *p)
{
	FILE *fp;
	fp=fopen("c:\\z.txt","a+");
	fprintf(fp,"%s\n",p);
	fclose(fp);
}
void abcchar(unsigned char c)
{
	FILE *fp;
	fp=fopen("c:\\z.txt","a+");
	fprintf(fp,"%c..%x..%d\n",c,c,c);
	fclose(fp);
}

void removeframe(struct packet *u,struct packet *f)
{
	unsigned int i,j;
	for(i=0,j=3;j<u->packetsize-3;i++,j++)
	{
	f->data[i]=u->data[j];
	}
	f->packetsize=i;
}

void lcppacket(struct packet *lcp)
{
if (lcp->data[2]== 1)
{
	sendconfack(lcp);
	sendconfreq();
}
if (lcp->data[2]== 9)
{
	sendechoreply(lcp);
	
}
}

void sendechoreply(struct packet * alcp)
{
alcp->data[2]=10;
alcp->packetsize=addffthree(alcp);
alcp->packetsize=calcchksum(alcp->data,alcp->packetsize);
escapeit(alcp);
addsevene(alcp);
sendit(alcp);

}


void sendconfreq()
{
	
struct packet lcpreq;
lcpreq.data[0]=0xc0;
lcpreq.data[1]=0x21;
lcpreq.data[2]=0x01;
lcpreq.data[3]=id;
lcpreq.data[4]=0x00;
lcpreq.data[5]=0x04;
lcpreq.packetsize=6;
lcpreq.packetsize=addffthree(&lcpreq);
lcpreq.packetsize=calcchksum(lcpreq.data,lcpreq.packetsize);
escapeit(&lcpreq);
addsevene(&lcpreq);
sendit(&lcpreq);
id++;

}



void sendconfack(struct packet *alcp)
{

alcp->data[2]=2;
alcp->packetsize=addffthree(alcp);
alcp->packetsize=calcchksum(alcp->data,alcp->packetsize);
escapeit(alcp);
addsevene(alcp);
sendit(alcp);

}


u16 pppfcs16(fcs,cp,len)
register u16 fcs;
register unsigned char *cp;
register int len;
{
while ( len -- )
fcs = ( fcs>>8 ) ^ fcstab[ (fcs^*cp++) & 0xff];
return fcs;
}

unsigned int calcchksum(cp,len)
register unsigned char *cp;
register int len;
{
u16 trialfcs;
trialfcs = pppfcs16(PPPINITFCS16,cp,len);
trialfcs ^= 0xffff;
cp[len] = (trialfcs & 0x00ff);
cp[len+1] = ((trialfcs >> 8 ) & 0x00ff);
return len+2;
}

unsigned int addffthree(struct packet *flcp)
{
	struct packet dummy;
	unsigned int i,j=0;
	dummy.data[j]=0xff;
	j++;
	dummy.data[j]=0x03;
	j++;
	for(i=0; i< flcp->packetsize;i++,j++)
	{
		dummy.data[j]=flcp->data[i];
	}
	dummy.packetsize=j;
	for(i=0;i<dummy.packetsize;i++)
	{
		flcp->data[i]=dummy.data[i];
	}
	flcp->packetsize=dummy.packetsize;
	
	
	return flcp->packetsize;
	}


void escapeit(struct packet * epacket)
{
	struct packet dummy;
	unsigned int i,j;
	for(i=0;i<epacket->packetsize;i++)
	{
		dummy.data[i]=epacket->data[i];
	}
	dummy.packetsize=epacket->packetsize;
     
	for(j=0,i=0;i<dummy.packetsize;i++,j++)
	{
		if (dummy.data[i] <= 31 || dummy.data[i] == 0x7e || dummy.data[i]== 0x7d)
		{
			epacket->data[j]=0x7d;
			j++;
			epacket->data[j]=dummy.data[i]^0x20;
		}
		else
			epacket->data[j]=dummy.data[i];
	}
	epacket->packetsize=j;
	
}
void escapeip(struct packet * epacket)
{
	struct packet dummy;
	unsigned int i,j;
	for(i=0;i<epacket->packetsize;i++)
	{
		dummy.data[i]=epacket->data[i];
	}
	dummy.packetsize=epacket->packetsize;
     
	for(j=0,i=0;i<dummy.packetsize;i++,j++)
	{
		if (dummy.data[i] == 0x7e || dummy.data[i]== 0x7d)
		{
			epacket->data[j]=0x7d;
			j++;
			epacket->data[j]=dummy.data[i]^0x20;
		}
		else
			epacket->data[j]=dummy.data[i];
	}
	epacket->packetsize=j;
	
}

void addsevene(struct packet * apacket)
{
	struct packet dummy;
	unsigned int i,j;
	for(i=0;i<apacket->packetsize;i++)
	{
		dummy.data[i]=apacket->data[i];
	}
	dummy.packetsize=i;
	apacket->data[0]=0x7e;
	for(i=0,j=1;i<dummy.packetsize;i++,j++)
	{
		apacket->data[j]=dummy.data[i];
	}

	apacket->data[j]=0x7e;
	j++;
	apacket->packetsize=j;
}

void sendit(struct packet * spacket)
{
unsigned int i;
WriteFile(idComDev,spacket->data,spacket->packetsize,&dwBytesWritten,0) ;
abc("Final Packet Sent");
for(i=0; i< spacket->packetsize;i++)
	abcchar(spacket->data[i]);
}

void erequest()
{
	struct icmp am;
	struct iphdr ip;
	am.type=17;
	am.code=0;
	am.chksum=0;
	am.id=ohtons(7);
	am.seqno=ohtons(9);
	am.subnet=0;
	am.chksum=checksum(&am,12);
	ip.verlen	=0x45;
	ip.tos		=0x0;
	ip.totlen	=ohtons(20 + 12);
	ip.id		=ohtons(1);
	ip.frag		=0x00;
	ip.ttl		=0x1f;
	ip.prot		=0x1;
	ip.chksum	=0;
	ip.sourceip[0]	=sipaddress[0];
	ip.sourceip[1]	=sipaddress[1];
	ip.sourceip[2]	=sipaddress[2];
	ip.sourceip[3]	=sipaddress[3];
	ip.destip[0]	=202;
	ip.destip[1]	=54;
	ip.destip[2]	=1;
	ip.destip[3]	=30;
	ip.chksum	=checksum(&ip,20);

	writeabc(&ip,&am,0);

}

void writeabc(unsigned char * ip, unsigned char *icmp, unsigned char opt[])
{
	struct packet ipicmp;
	unsigned int i,j;
	unsigned char uu[1000];
	uu[0]=0x21;
	for(j=1,i=0;i<20;i++,j++)
	{
		uu[j]=ip[i];
	}
	
	for(i=0;i<12;i++,j++)
	{	
		uu[j]=icmp[i];
	}

	
	for(i=0;i<j;i++)
	{
	ipicmp.data[i]=uu[i];
	}
	ipicmp.packetsize=j;
	ipicmp.packetsize=calcchksum(ipicmp.data,ipicmp.packetsize);
	abc("Unescaped Packet To Be Sent");
	for(i=0; i< ipicmp.packetsize;i++)
		abcchar(ipicmp.data[i]);
	escapeip(&ipicmp);
	
	addsevene(&ipicmp);
	sendit(&ipicmp);
	MessageBox(0,"IP Packet","Icmp",0);
}

unsigned short checksum(unsigned short *ip1,unsigned int len)
{
long sum = 0;
while ( len > 1)
{
sum += *ip1++;
if ( sum & 0x80000000 )
sum = ( sum & 0xffff) + ( sum >> 16);
len -= 2;
}
while ( sum >> 16)
sum = ( sum & 0xffff) + ( sum >> 16);
return ~sum;
}
unsigned int ohtons(unsigned int h)
{
unsigned char h1,h2;
unsigned short h5;
h1 = (unsigned char ) h & 0xff;
h2 = (h >> 8)&0xff;
h5 = 256*h1 + h2 ;
return h5;
}
unsigned long ohtonl(unsigned long h)
{
unsigned char h1,h2,h3,h4;
unsigned long h5;
h1 = (unsigned char ) h & 0x000000ff;
h2 = (h >> 8)&0x000000ff;
h3 = (h >> 16) & 0x000000ff;
h4 = (h >> 24 ) & 0x000000ff;
h5 = ((long)1<<24)*h1 + h4 + h3*256 + h2*65536;
return h5;
}

This is a program that collects the subnet mask of the server. To do that we have to send a Type number of 0x11 and a long number set to zero (for the subnet mask). When the server replies to us it'll place a 0x12 in the Type field and the subnet mask as the long number.

As usual, the function erequest() handles everything. There's nothing to it really.

z.txt

Recd Packet After Unescaping
~..7e..126
..ff..255
..3..3
 ..0..0
!..21..33
E..45..69
 ..0..0
 ..0..0
 ..20..32
~..7e..126
..1f..31
@..40..64
 ..0..0
..fb..251
..1..1
g..67..103
..d2..210
..ca..202
6..36..54
..1..1
-..1e..30
..ca..202
6..36..54
..4..4
`..60..96
..12..18                     //reply
 ..0..0                       
..ee..238
...2e..46
 ..0..0
..7..7
 ..0..0
	..9..9
..ff..255				// subnet mask
..ff..255
..ff..255
..c0..192				// subnet mask ends
Z..5a..90
..bb..187
~..7e..126

So there you have it. The numbers enclosed in the comments are the subnet mask. If we cut those number up we get...

11111111  11111111  11111111  11000000
This means only 64 machines can be connected to our PPP server at one time.

Timestamps

icmp3.rc

mmm menu
begin
menuitem "Timestamp",100
end

icmp3.c

#include <windows.h>
#include <stdio.h>
struct packet
{
unsigned char data[1000];
unsigned int packetsize;
};

struct iphdr
{
unsigned char verlen;
unsigned char tos;
unsigned short totlen;
unsigned short id;
unsigned short frag;
unsigned char ttl;
unsigned char prot;
unsigned short chksum;
unsigned char  sourceip[4];
unsigned char destip[4];
};

struct icmp
{
	unsigned char type;
	unsigned char code;
	unsigned short chksum;
	unsigned short id;
	unsigned short seqno;
	unsigned long torigin;
	unsigned long trecd;
	unsigned long ttransmit;
};

unsigned short checksum(unsigned short *ip1,unsigned int len);
unsigned int ohtons(unsigned int h);
unsigned long ohtonl(unsigned long h);
unsigned char id=0;
void abcchar(unsigned char );
void abc(char *);
void processpacket();
void unescape(struct packet *,struct packet *);
void removeframe(struct packet *,struct packet *);
long _stdcall zzz(HWND ,UINT ,WPARAM ,LPARAM );
void lcppacket(struct packet *);
unsigned int calcchksum(unsigned char *,int );
void escapeit(struct packet *);
void escapeip(struct packet *);
void addsevene(struct packet *);
void sendit(struct packet *);
void sendconfack(struct packet *);
unsigned int addffthree(struct packet *);
void sendconfreq();
void ipcppacket(struct packet * );
void sendipcpack(struct packet *);
void sendipcpreq();
void sendechoreply(struct packet *);
void erequest();
void writeabc(unsigned char * ip, unsigned char *tcp, unsigned char opt[]);

unsigned char sipaddress[4]={0,0,0,0};

HDC  hDC ;
HANDLE  idComDev ;
HWND  hTTYWnd ;

struct packet recdpacket;
int  nColumn, nRow, xChar, yChar ,cnt=0, ctr=0;
DWORD dwThreadID, dwBytesRecd,dwBytesWritten;
DCB dcb;
WNDCLASS a;
MSG c;
unsigned char aa[200],packetrecd[1000],cc,dd;

typedef unsigned short u16;
static u16 fcstab[256] = {
    0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
    0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
    0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
    0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
    0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
    0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
    0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
    0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
    0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
    0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
    0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
    0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
    0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
    0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
    0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
    0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
    0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
    0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
    0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
    0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
    0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
    0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
    0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
    0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
    0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
    0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
    0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
    0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
    0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
    0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
    0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
    0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
};
#define PPPINITFCS16 0xffff
#define PPPGOODFCS16 0xf0b8

DWORD FAR PASCAL CommWatchProc()
{
 BYTE abIn[2] ; 
 while (1)
 { 	  
	ReadFile(idComDev,abIn,1,&dwBytesRecd,0);
	if (abIn[0] == 0x7e )
	{
	  if(ctr == 0)
	  {
		  cnt=0;	
		  ctr=1;
	  }
	  else if (ctr == 1)
	  { 
		  	ctr++;
			
	  }
  	  else if (ctr == 2)
	  { 
		  	ctr = 1;
			recdpacket.data[cnt]=abIn[0];
			cnt++;
			recdpacket.packetsize=cnt;
			cnt=0;
			processpacket();
	  }
    }	 
	if (ctr ==2 )
	{	  
		recdpacket.data[cnt]=abIn[0];
		cnt++;
	}
    if (abIn[0] == 13 )
		nColumn = 0 ;
    if (abIn[0] == 10)
		nRow++;
    if (abIn[0] == 0x08)
	    nColumn -- ;
	if (abIn[0] != 0x0a && abIn[0] != 0x0d)
	{
		TextOut(hDC,nColumn*xChar,nRow*yChar,abIn,1);
		if (nColumn < 79)
				nColumn++ ;
		else
		{
			nColumn = 0;
			nRow++;
		}
	}
 }
 return( TRUE ) ;
}


int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpszCmdLine, int nCmdShow )
{
a.lpfnWndProc=zzz;
a.hInstance=hInstance;
a.hbrBackground=(HBRUSH)(COLOR_WINDOW + 1) ;
a.lpszClassName="aa";
a.lpszMenuName="mmm";
RegisterClass(&a);
hTTYWnd=CreateWindow("aa","hi",WS_OVERLAPPEDWINDOW,0,0,0,0,0,0,hInstance,0);
xChar = 8;
yChar = 19;
ShowWindow( hTTYWnd, 3 ) ;
hDC=GetDC(hTTYWnd);

idComDev= CreateFile( "COM1", GENERIC_READ | GENERIC_WRITE,1,NULL,	
	OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL );

dcb.DCBlength = sizeof( DCB ) ;
GetCommState( idComDev, &dcb ) ;
dcb.BaudRate = 14400 ;
SetCommState( idComDev, &dcb ) ;
CreateThread(0,0,(LPTHREAD_START_ROUTINE) CommWatchProc,0,0, &dwThreadID );
strcpy(aa,"atdt2659385\r");
WriteFile(idComDev,aa,strlen(aa),&dwBytesWritten,0) ;
while (GetMessage( &c, NULL, 0, 0 ))
   {
       TranslateMessage( &c ) ;
       DispatchMessage( &c ) ;
   }
   return ( (int) 0 ) ;
}


long _stdcall zzz(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
   	if(uMsg == WM_COMMAND && wParam == 100)
	{
		erequest();
	}
	if(uMsg == WM_CHAR)
    {
         cc = wParam;
         WriteFile(idComDev,&cc,1,&dwBytesWritten,0) ;
    }
    if(uMsg == WM_DESTROY)
	{
		 ReleaseDC(hWnd,hDC);
         PostQuitMessage( 0 ) ;
	}
         return( DefWindowProc( hWnd, uMsg, wParam, lParam ) ) ;
}  


void processpacket()
{
	struct packet unescpacket,finalpacket;
	unsigned int i;
       
	
	abc("Recd Packet After Unescaping");
	unescape(&recdpacket,&unescpacket);
	for(i=0; i<unescpacket.packetsize;i++)
		abcchar(unescpacket.data[i]);
	removeframe(&unescpacket,&finalpacket);
	
	if(finalpacket.data[0] == 0xc0 && finalpacket.data[1] == 0x21)
		lcppacket(&finalpacket);
	if(finalpacket.data[0] == 0x80 && finalpacket.data[1] == 0x21)
		ipcppacket(&finalpacket);
	if(finalpacket.data[0] == 0x00 && finalpacket.data[1] == 0x21)
		MessageBox(0,"IP Packet Received","IP Packet Received",0);
}
void ipcppacket(struct packet * f)
{
if (f->data[2]== 1)
{
	sendipcpack(f);
	sendipcpreq(sipaddress);
}

if (f->data[2]== 2)
{
	MessageBox(0,"ipcp Ack received","ipcp Ack received",0);
}

if (f->data[2]== 3)
{
	sipaddress[0]=f->data[8];
	sipaddress[1]=f->data[9];
	sipaddress[2]=f->data[10];
	sipaddress[3]=f->data[11];
	sendipcpreq(sipaddress);
}

if (f->data[2]== 4)
{
	MessageBox(0,"ipcp Reject received","ipcp Reject received",0);
}

}

void sendipcpack(struct packet *aipcp)
{
aipcp->data[2]=2;
aipcp->packetsize=addffthree(aipcp);
aipcp->packetsize=calcchksum(aipcp->data,aipcp->packetsize);
escapeit(aipcp);
addsevene(aipcp);
sendit(aipcp);
}


void sendipcpreq(char ipadd[])
{
struct packet ipcpreq;
ipcpreq.data[0]=0x80;
ipcpreq.data[1]=0x21;
ipcpreq.data[2]=0x01;
ipcpreq.data[3]=0x1;
ipcpreq.data[4]=0x00;
ipcpreq.data[5]=0xa;
ipcpreq.data[6]=0x3;
ipcpreq.data[7]=0x6;
ipcpreq.data[8]=ipadd[0];
ipcpreq.data[9]=ipadd[1];
ipcpreq.data[10]=ipadd[2];
ipcpreq.data[11]=ipadd[3];
ipcpreq.packetsize=12;
ipcpreq.packetsize=addffthree(&ipcpreq);
ipcpreq.packetsize=calcchksum(ipcpreq.data,ipcpreq.packetsize);
escapeit(&ipcpreq);
addsevene(&ipcpreq);
sendit(&ipcpreq);

}



void unescape(struct packet *r, struct packet *u)
{	
	unsigned int i,j;
	for(j=0,i=0;i<r->packetsize;i++,j++)
	{
		if (r->data[i]==0x7d)
		{
			i++;
			u->data[j]=r->data[i]^0x20;
		}
		else
		{
		u->data[j]=r->data[i];
		}
	}
	u->packetsize=j;
}


void abc(char *p)
{
	FILE *fp;
	fp=fopen("c:\\z.txt","a+");
	fprintf(fp,"%s\n",p);
	fclose(fp);
}
void abcchar(unsigned char c)
{
	FILE *fp;
	fp=fopen("c:\\z.txt","a+");
	fprintf(fp,"%c..%x..%d\n",c,c,c);
	fclose(fp);
}

void removeframe(struct packet *u,struct packet *f)
{
	unsigned int i,j;
	for(i=0,j=3;j<u->packetsize-3;i++,j++)
	{
	f->data[i]=u->data[j];
	}
	f->packetsize=i;
}

void lcppacket(struct packet *lcp)
{
if (lcp->data[2]== 1)
{
	sendconfack(lcp);
	sendconfreq();
}
if (lcp->data[2]== 9)
{
	sendechoreply(lcp);
	
}
}

void sendechoreply(struct packet * alcp)
{
alcp->data[2]=10;
alcp->packetsize=addffthree(alcp);
alcp->packetsize=calcchksum(alcp->data,alcp->packetsize);
escapeit(alcp);
addsevene(alcp);
sendit(alcp);

}


void sendconfreq()
{
	
struct packet lcpreq;
lcpreq.data[0]=0xc0;
lcpreq.data[1]=0x21;
lcpreq.data[2]=0x01;
lcpreq.data[3]=id;
lcpreq.data[4]=0x00;
lcpreq.data[5]=0x04;
lcpreq.packetsize=6;
lcpreq.packetsize=addffthree(&lcpreq);
lcpreq.packetsize=calcchksum(lcpreq.data,lcpreq.packetsize);
escapeit(&lcpreq);
addsevene(&lcpreq);
sendit(&lcpreq);
id++;

}



void sendconfack(struct packet *alcp)
{

alcp->data[2]=2;
alcp->packetsize=addffthree(alcp);
alcp->packetsize=calcchksum(alcp->data,alcp->packetsize);
escapeit(alcp);
addsevene(alcp);
sendit(alcp);

}


u16 pppfcs16(fcs,cp,len)
register u16 fcs;
register unsigned char *cp;
register int len;
{
while ( len -- )
fcs = ( fcs>>8 ) ^ fcstab[ (fcs^*cp++) & 0xff];
return fcs;
}

unsigned int calcchksum(cp,len)
register unsigned char *cp;
register int len;
{
u16 trialfcs;
trialfcs = pppfcs16(PPPINITFCS16,cp,len);
trialfcs ^= 0xffff;
cp[len] = (trialfcs & 0x00ff);
cp[len+1] = ((trialfcs >> 8 ) & 0x00ff);
return len+2;
}

unsigned int addffthree(struct packet *flcp)
{
	struct packet dummy;
	unsigned int i,j=0;
	dummy.data[j]=0xff;
	j++;
	dummy.data[j]=0x03;
	j++;
	for(i=0; i< flcp->packetsize;i++,j++)
	{
		dummy.data[j]=flcp->data[i];
	}
	dummy.packetsize=j;
	for(i=0;i<dummy.packetsize;i++)
	{
		flcp->data[i]=dummy.data[i];
	}
	flcp->packetsize=dummy.packetsize;
	
	
	return flcp->packetsize;
	}


void escapeit(struct packet * epacket)
{
	struct packet dummy;
	unsigned int i,j;
	for(i=0;i<epacket->packetsize;i++)
	{
		dummy.data[i]=epacket->data[i];
	}
	dummy.packetsize=epacket->packetsize;
     
	for(j=0,i=0;i<dummy.packetsize;i++,j++)
	{
		if (dummy.data[i] <= 31 || dummy.data[i] == 0x7e || dummy.data[i]== 0x7d)
		{
			epacket->data[j]=0x7d;
			j++;
			epacket->data[j]=dummy.data[i]^0x20;
		}
		else
			epacket->data[j]=dummy.data[i];
	}
	epacket->packetsize=j;
	
}
void escapeip(struct packet * epacket)
{
	struct packet dummy;
	unsigned int i,j;
	for(i=0;i<epacket->packetsize;i++)
	{
		dummy.data[i]=epacket->data[i];
	}
	dummy.packetsize=epacket->packetsize;
     
	for(j=0,i=0;i<dummy.packetsize;i++,j++)
	{
		if (dummy.data[i] == 0x7e || dummy.data[i]== 0x7d)
		{
			epacket->data[j]=0x7d;
			j++;
			epacket->data[j]=dummy.data[i]^0x20;
		}
		else
			epacket->data[j]=dummy.data[i];
	}
	epacket->packetsize=j;
	
}

void addsevene(struct packet * apacket)
{
	struct packet dummy;
	unsigned int i,j;
	for(i=0;i<apacket->packetsize;i++)
	{
		dummy.data[i]=apacket->data[i];
	}
	dummy.packetsize=i;
	apacket->data[0]=0x7e;
	for(i=0,j=1;i<dummy.packetsize;i++,j++)
	{
		apacket->data[j]=dummy.data[i];
	}

	apacket->data[j]=0x7e;
	j++;	apacket->packetsize=j;
}

void sendit(struct packet * spacket)
{
unsigned int i;
WriteFile(idComDev,spacket->data,spacket->packetsize,&dwBytesWritten,0) ;
abc("Final Packet Sent");
for(i=0; i< spacket->packetsize;i++)
	abcchar(spacket->data[i]);
}

/*
Time stamp
*/
void erequest()
{
	struct icmp ts;
	struct iphdr ip;
	ts.type=13;
	ts.code=0;
	ts.chksum=0;
	ts.id=ohtons(7);
	ts.seqno=ohtons(9);
	ts.torigin=1;
	ts.trecd=0;
	ts.ttransmit=0;

	ts.chksum=checksum(&ts,20);
	ip.verlen	=0x45;
	ip.tos		=0x0;
	ip.totlen	=ohtons(20 + 20);
	ip.id		=ohtons(1);
	ip.frag		=0x00;
	ip.ttl		=0xff;
	ip.prot		=0x1;
	ip.chksum	=0;
	ip.sourceip[0]	=sipaddress[0];
	ip.sourceip[1]	=sipaddress[1];
	ip.sourceip[2]	=sipaddress[2];
	ip.sourceip[3]	=sipaddress[3];
	ip.destip[0]	=202;
	ip.destip[1]	=54;
	ip.destip[2]	=1;
	ip.destip[3]	=18;
	ip.chksum	=checksum(&ip,20);

	writeabc(&ip,&ts,0);

}

void writeabc(unsigned char * ip, unsigned char *icmp, unsigned char opt[])
{
	struct packet ipicmp;
	unsigned int i,j;
	unsigned char uu[1000];
	uu[0]=0x21;
	for(j=1,i=0;i<20;i++,j++)
	{
		uu[j]=ip[i];
	}
	
	for(i=0;i<20;i++,j++)
	{	
		uu[j]=icmp[i];
	}

	
	for(i=0;i<j;i++)
	{
	ipicmp.data[i]=uu[i];
	}
	ipicmp.packetsize=j;
	ipicmp.packetsize=calcchksum(ipicmp.data,ipicmp.packetsize);
	abc("Unescaped Packet To Be Sent");
	for(i=0; i< ipicmp.packetsize;i++)
		abcchar(ipicmp.data[i]);
	escapeip(&ipicmp);
	
	addsevene(&ipicmp);
	sendit(&ipicmp);
	MessageBox(0,"IP Packet","Icmp",0);
}

unsigned short checksum(unsigned short *ip1,unsigned int len)
{
long sum = 0;
while ( len > 1)
{
sum += *ip1++;
if ( sum & 0x80000000 )
sum = ( sum & 0xffff) + ( sum >> 16);
len -= 2;
}
while ( sum >> 16)
sum = ( sum & 0xffff) + ( sum >> 16);
return ~sum;
}
unsigned int ohtons(unsigned int h)
{
unsigned char h1,h2;
unsigned short h5;
h1 = (unsigned char ) h & 0xff;
h2 = (h >> 8)&0xff;
h5 = 256*h1 + h2 ;
return h5;
}
unsigned long ohtonl(unsigned long h)
{
unsigned char h1,h2,h3,h4;
unsigned long h5;
h1 = (unsigned char ) h & 0x000000ff;
h2 = (h >> 8)&0x000000ff;
h3 = (h >> 16) & 0x000000ff;
h4 = (h >> 24 ) & 0x000000ff;
h5 = ((long)1<<24)*h1 + h4 + h3*256 + h2*65536;
return h5;
}

This is the timestamp program. In the function erequest() the ICMP header is filled up with the time of origin (1). The rest of the Timestamp fields are left blank and are supposed to be filled up by the target.

The type field is set to 13h. In the response the Type field is 14h.

z.txt

Recd Packet After Unescaping
~..7e..126
..ff..255
..3..3
 ..0..0
!..21..33
E..45..69
 ..0..0
 ..0..0
(..28..40
..d1..209
..c0..192
 ..0..0
 ..0..0
..fe..254
..1..1
R..52..82
a..61..97
..ca..202
6..36..54
..1..1
..12..18
..ca..202
6..36..54
..3..3
4..34..52
..e..14
 ..0..0
C..43..67

..a..10
 ..0..0
..7..7
 ..0..0
	..9..9
..1..1
 ..0..0
 ..0..0
 ..0..0
..2..2
..c..12
..d4..212
..e6..230
..2..2
..c..12
..d4..212
..e6..230
..ad..173
t..74..116
~..7e..126

Traceroute

icmp4.rc

mmm menu
begin
menuitem "TTL 1",100
end

icmp4.c

#include <windows.h>
#include <stdio.h>
struct packet
{
unsigned char data[1000];
unsigned int packetsize;
};

struct iphdr
{
unsigned char verlen;
unsigned char tos;
unsigned short totlen;
unsigned short id;
unsigned short frag;
unsigned char ttl;
unsigned char prot;
unsigned short chksum;
unsigned char  sourceip[4];
unsigned char destip[4];
};

struct icmp
{
	unsigned char type;
	unsigned char code;
	unsigned short chksum;
	unsigned short id;
	unsigned short seqno;
};

unsigned short checksum(unsigned short *ip1,unsigned int len);
unsigned int ohtons(unsigned int h);
unsigned long ohtonl(unsigned long h);
unsigned char id=0;
void abcchar(unsigned char );
void abc(char *);
void processpacket();
void unescape(struct packet *,struct packet *);
void removeframe(struct packet *,struct packet *);
long _stdcall zzz(HWND ,UINT ,WPARAM ,LPARAM );
void lcppacket(struct packet *);
unsigned int calcchksum(unsigned char *,int );
void escapeit(struct packet *);
void escapeip(struct packet *);
void addsevene(struct packet *);
void sendit(struct packet *);
void sendconfack(struct packet *);
unsigned int addffthree(struct packet *);
void sendconfreq();
void ipcppacket(struct packet * );
void sendipcpack(struct packet *);
void sendipcpreq();
void sendechoreply(struct packet *);
void erequest();
void writeabc(unsigned char * ip, unsigned char *tcp, unsigned char opt[]);

unsigned char sipaddress[4]={0,0,0,0};

HDC  hDC ;
HANDLE  idComDev ;
HWND  hTTYWnd ;

struct packet recdpacket;
int  nColumn, nRow, xChar, yChar ,cnt=0, ctr=0;
DWORD dwThreadID, dwBytesRecd,dwBytesWritten;
DCB dcb;
WNDCLASS a;
MSG c;
unsigned char aa[200],packetrecd[1000],cc,dd;

typedef unsigned short u16;
static u16 fcstab[256] = {
    0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
    0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
    0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
    0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
    0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
    0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
    0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
    0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
    0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
    0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
    0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
    0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
    0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
    0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
    0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
    0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
    0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
    0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
    0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
    0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
    0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
    0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
    0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
    0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
    0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
    0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
    0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
    0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
    0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
    0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
    0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
    0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
};
#define PPPINITFCS16 0xffff
#define PPPGOODFCS16 0xf0b8

DWORD FAR PASCAL CommWatchProc()
{
 BYTE abIn[2] ; 
 while (1)
 { 	  
	ReadFile(idComDev,abIn,1,&dwBytesRecd,0);
	if (abIn[0] == 0x7e )
	{
	  if(ctr == 0)
	  {
		  cnt=0;	
		  ctr=1;
	  }
	  else if (ctr == 1)
	  { 
		  	ctr++;
			
	  }
  	  else if (ctr == 2)
	  { 
		  	ctr = 1;
			recdpacket.data[cnt]=abIn[0];
			cnt++;
			recdpacket.packetsize=cnt;
			cnt=0;
			processpacket();
	  }
    }	 
	if (ctr ==2 )
	{	  
		recdpacket.data[cnt]=abIn[0];
		cnt++;
	}
    if (abIn[0] == 13 )
		nColumn = 0 ;
    if (abIn[0] == 10)
		nRow++;
    if (abIn[0] == 0x08)
	    nColumn -- ;
	if (abIn[0] != 0x0a && abIn[0] != 0x0d)
	{
		TextOut(hDC,nColumn*xChar,nRow*yChar,abIn,1);
		if (nColumn < 79)
				nColumn++ ;
		else
		{
			nColumn = 0;
			nRow++;
		}
	}
 }
 return( TRUE ) ;
}


int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpszCmdLine, int nCmdShow )
{
a.lpfnWndProc=zzz;
a.hInstance=hInstance;
a.hbrBackground=(HBRUSH)(COLOR_WINDOW + 1) ;
a.lpszClassName="aa";
a.lpszMenuName="mmm";
RegisterClass(&a);
hTTYWnd=CreateWindow("aa","hi",WS_OVERLAPPEDWINDOW,0,0,0,0,0,0,hInstance,0);
xChar = 8;
yChar = 19;
ShowWindow( hTTYWnd, 3 ) ;
hDC=GetDC(hTTYWnd);

idComDev= CreateFile( "COM1", GENERIC_READ | GENERIC_WRITE,1,NULL,	
	OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL );

dcb.DCBlength = sizeof( DCB ) ;
GetCommState( idComDev, &dcb ) ;
dcb.BaudRate = 14400 ;
SetCommState( idComDev, &dcb ) ;
CreateThread(0,0,(LPTHREAD_START_ROUTINE) CommWatchProc,0,0, &dwThreadID );
strcpy(aa,"atdt2659385\r");
WriteFile(idComDev,aa,strlen(aa),&dwBytesWritten,0) ;
while (GetMessage( &c, NULL, 0, 0 ))
   {
       TranslateMessage( &c ) ;
       DispatchMessage( &c ) ;
   }
   return ( (int) 0 ) ;
}


long _stdcall zzz(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
   	if(uMsg == WM_COMMAND && wParam == 100)
	{
		erequest();
	}
	if(uMsg == WM_CHAR)
    {
         cc = wParam;
         WriteFile(idComDev,&cc,1,&dwBytesWritten,0) ;
    }
    if(uMsg == WM_DESTROY)
	{
		 ReleaseDC(hWnd,hDC);
         PostQuitMessage( 0 ) ;
	}
         return( DefWindowProc( hWnd, uMsg, wParam, lParam ) ) ;
}  


void processpacket()
{
	struct packet unescpacket,finalpacket;
	unsigned int i;
       
	
	abc("Recd Packet After Unescaping");
	unescape(&recdpacket,&unescpacket);
	for(i=0; i<unescpacket.packetsize;i++)
		abcchar(unescpacket.data[i]);
	removeframe(&unescpacket,&finalpacket);
	
	if(finalpacket.data[0] == 0xc0 && finalpacket.data[1] == 0x21)
		lcppacket(&finalpacket);
	if(finalpacket.data[0] == 0x80 && finalpacket.data[1] == 0x21)
		ipcppacket(&finalpacket);
	if(finalpacket.data[0] == 0x00 && finalpacket.data[1] == 0x21)
		MessageBox(0,"IP Packet Received","IP Packet Received",0);
}
void ipcppacket(struct packet * f)
{
if (f->data[2]== 1)
{
	sendipcpack(f);
	sendipcpreq(sipaddress);
}

if (f->data[2]== 2)
{
	MessageBox(0,"ipcp Ack received","ipcp Ack received",0);
}

if (f->data[2]== 3)
{
	sipaddress[0]=f->data[8];
	sipaddress[1]=f->data[9];
	sipaddress[2]=f->data[10];
	sipaddress[3]=f->data[11];
	sendipcpreq(sipaddress);
}

if (f->data[2]== 4)
{
	MessageBox(0,"ipcp Reject received","ipcp Reject received",0);
}

}

void sendipcpack(struct packet *aipcp)
{
aipcp->data[2]=2;
aipcp->packetsize=addffthree(aipcp);
aipcp->packetsize=calcchksum(aipcp->data,aipcp->packetsize);
escapeit(aipcp);
addsevene(aipcp);
sendit(aipcp);
}


void sendipcpreq(char ipadd[])
{
struct packet ipcpreq;
ipcpreq.data[0]=0x80;
ipcpreq.data[1]=0x21;
ipcpreq.data[2]=0x01;
ipcpreq.data[3]=0x1;
ipcpreq.data[4]=0x00;
ipcpreq.data[5]=0xa;
ipcpreq.data[6]=0x3;
ipcpreq.data[7]=0x6;
ipcpreq.data[8]=ipadd[0];
ipcpreq.data[9]=ipadd[1];
ipcpreq.data[10]=ipadd[2];
ipcpreq.data[11]=ipadd[3];
ipcpreq.packetsize=12;
ipcpreq.packetsize=addffthree(&ipcpreq);
ipcpreq.packetsize=calcchksum(ipcpreq.data,ipcpreq.packetsize);
escapeit(&ipcpreq);
addsevene(&ipcpreq);
sendit(&ipcpreq);

}



void unescape(struct packet *r, struct packet *u)
{	
	unsigned int i,j;
	for(j=0,i=0;i<r->packetsize;i++,j++)
	{
		if (r->data[i]==0x7d)
		{
			i++;
			u->data[j]=r->data[i]^0x20;
		}
		else
		{
		u->data[j]=r->data[i];
		}
	}
	u->packetsize=j;
}


void abc(char *p)
{
	FILE *fp;
	fp=fopen("c:\\z.txt","a+");
	fprintf(fp,"%s\n",p);
	fclose(fp);
}
void abcchar(unsigned char c)
{
	FILE *fp;
	fp=fopen("c:\\z.txt","a+");
	fprintf(fp,"%c..%x..%d\n",c,c,c);
	fclose(fp);
}

void removeframe(struct packet *u,struct packet *f)
{
	unsigned int i,j;
	for(i=0,j=3;j<u->packetsize-3;i++,j++)
	{
	f->data[i]=u->data[j];
	}
	f->packetsize=i;
}

void lcppacket(struct packet *lcp)
{
if (lcp->data[2]== 1)
{
	sendconfack(lcp);
	sendconfreq();
}
if (lcp->data[2]== 9)
{
	sendechoreply(lcp);
	
}
}

void sendechoreply(struct packet * alcp)
{
alcp->data[2]=10;
alcp->packetsize=addffthree(alcp);
alcp->packetsize=calcchksum(alcp->data,alcp->packetsize);
escapeit(alcp);
addsevene(alcp);
sendit(alcp);

}


void sendconfreq()
{
	
struct packet lcpreq;
lcpreq.data[0]=0xc0;
lcpreq.data[1]=0x21;
lcpreq.data[2]=0x01;
lcpreq.data[3]=id;
lcpreq.data[4]=0x00;
lcpreq.data[5]=0x04;
lcpreq.packetsize=6;
lcpreq.packetsize=addffthree(&lcpreq);
lcpreq.packetsize=calcchksum(lcpreq.data,lcpreq.packetsize);
escapeit(&lcpreq);
addsevene(&lcpreq);
sendit(&lcpreq);
id++;

}



void sendconfack(struct packet *alcp)
{

alcp->data[2]=2;
alcp->packetsize=addffthree(alcp);
alcp->packetsize=calcchksum(alcp->data,alcp->packetsize);
escapeit(alcp);
addsevene(alcp);
sendit(alcp);

}


u16 pppfcs16(fcs,cp,len)
register u16 fcs;
register unsigned char *cp;
register int len;
{
while ( len -- )
fcs = ( fcs>>8 ) ^ fcstab[ (fcs^*cp++) & 0xff];
return fcs;
}

unsigned int calcchksum(cp,len)
register unsigned char *cp;
register int len;
{
u16 trialfcs;
trialfcs = pppfcs16(PPPINITFCS16,cp,len);
trialfcs ^= 0xffff;
cp[len] = (trialfcs & 0x00ff);
cp[len+1] = ((trialfcs >> 8 ) & 0x00ff);
return len+2;
}

unsigned int addffthree(struct packet *flcp)
{
	struct packet dummy;
	unsigned int i,j=0;
	dummy.data[j]=0xff;
	j++;
	dummy.data[j]=0x03;
	j++;
	for(i=0; i< flcp->packetsize;i++,j++)
	{
		dummy.data[j]=flcp->data[i];
	}
	dummy.packetsize=j;
	for(i=0;i<dummy.packetsize;i++)
	{
		flcp->data[i]=dummy.data[i];
	}
	flcp->packetsize=dummy.packetsize;
	
	
	return flcp->packetsize;
	}


void escapeit(struct packet * epacket)
{
	struct packet dummy;
	unsigned int i,j;
	for(i=0;i<epacket->packetsize;i++)
	{
		dummy.data[i]=epacket->data[i];
	}
	dummy.packetsize=epacket->packetsize;
     
	for(j=0,i=0;i<dummy.packetsize;i++,j++)
	{
		if (dummy.data[i] <= 31 || dummy.data[i] == 0x7e || dummy.data[i]== 0x7d)
		{
			epacket->data[j]=0x7d;
			j++;
			epacket->data[j]=dummy.data[i]^0x20;
		}
		else
			epacket->data[j]=dummy.data[i];
	}
	epacket->packetsize=j;
	
}
void escapeip(struct packet * epacket)
{
	struct packet dummy;
	unsigned int i,j;
	for(i=0;i<epacket->packetsize;i++)
	{
		dummy.data[i]=epacket->data[i];
	}
	dummy.packetsize=epacket->packetsize;
     
	for(j=0,i=0;i<dummy.packetsize;i++,j++)
	{
		if (dummy.data[i] == 0x7e || dummy.data[i]== 0x7d)
		{
			epacket->data[j]=0x7d;
			j++;
			epacket->data[j]=dummy.data[i]^0x20;
		}
		else
			epacket->data[j]=dummy.data[i];
	}
	epacket->packetsize=j;
	
}

void addsevene(struct packet * apacket)
{
	struct packet dummy;
	unsigned int i,j;
	for(i=0;i<apacket->packetsize;i++)
	{
		dummy.data[i]=apacket->data[i];
	}
	dummy.packetsize=i;
	apacket->data[0]=0x7e;
	for(i=0,j=1;i<dummy.packetsize;i++,j++)
	{
		apacket->data[j]=dummy.data[i];
	}

	apacket->data[j]=0x7e;
	j++;
	apacket->packetsize=j;
}

void sendit(struct packet * spacket)
{
unsigned int i;
WriteFile(idComDev,spacket->data,spacket->packetsize,&dwBytesWritten,0) ;
abc("Final Packet Sent");
for(i=0; i< spacket->packetsize;i++)
	abcchar(spacket->data[i]);
}


void erequest()
{
	struct icmp er;
	struct iphdr ip;
	er.type=0x08;
	er.code=0;
	er.chksum=0;
	er.id=ohtons(7);
	er.seqno=ohtons(9);
	er.chksum=checksum(&er,8);
	ip.verlen	=0x45;
	ip.tos		=0x0;
	ip.totlen	=ohtons(28);
	ip.id		=ohtons(1);
	ip.frag		=0x00;
	ip.ttl		=3;
	ip.prot		=0x1;
	ip.chksum	=0;
	ip.sourceip[0]	=sipaddress[0];
	ip.sourceip[1]	=sipaddress[1];
	ip.sourceip[2]	=sipaddress[2];
	ip.sourceip[3]	=sipaddress[3];
	ip.destip[0]	=206;
	ip.destip[1]	=103;
	ip.destip[2]	=13;
	ip.destip[3]	=130;
	ip.chksum	=checksum(&ip,20);

	writeabc(&ip,&er,0);

}

void writeabc(unsigned char * ip, unsigned char *icmp, unsigned char opt[])
{
	struct packet ipicmp;
	unsigned int i,j;
	unsigned char uu[1000];
	uu[0]=0x21;
	for(j=1,i=0;i<20;i++,j++)
	{
		uu[j]=ip[i];
	}
	
	for(i=0;i<8;i++,j++)
	{	
		uu[j]=icmp[i];
	}

	
	for(i=0;i<j;i++)
	{
	ipicmp.data[i]=uu[i];
	}
	ipicmp.packetsize=j;
	ipicmp.packetsize=calcchksum(ipicmp.data,ipicmp.packetsize);
	abc("Unescaped Packet To Be Sent");
	for(i=0; i< ipicmp.packetsize;i++)
		abcchar(ipicmp.data[i]);
	escapeip(&ipicmp);
	
	addsevene(&ipicmp);
	sendit(&ipicmp);
	MessageBox(0,"IP Packet","Icmp",0);
}

unsigned short checksum(unsigned short *ip1,unsigned int len)
{
long sum = 0;
while ( len > 1)
{
sum += *ip1++;
if ( sum & 0x80000000 )
sum = ( sum & 0xffff) + ( sum >> 16);
len -= 2;
}
while ( sum >> 16)
sum = ( sum & 0xffff) + ( sum >> 16);
return ~sum;
}
unsigned int ohtons(unsigned int h)
{
unsigned char h1,h2;
unsigned short h5;
h1 = (unsigned char ) h & 0xff;
h2 = (h >> 8)&0xff;
h5 = 256*h1 + h2 ;
return h5;
}
unsigned long ohtonl(unsigned long h)
{
unsigned char h1,h2,h3,h4;
unsigned long h5;
h1 = (unsigned char ) h & 0x000000ff;
h2 = (h >> 8)&0x000000ff;
h3 = (h >> 16) & 0x000000ff;
h4 = (h >> 24 ) & 0x000000ff;
h5 = ((long)1<<24)*h1 + h4 + h3*256 + h2*65536;
return h5;
}
This is a rough and ready traceroute program. The ICMP packet has the type field set to 0x80 which marks it as an Echo Request. The TTL field in the ???IP header is 0x00 ??so the packet will be dropped by the very first router on it's path. It's not very difficult to modify the program to loop till you get an Echo reply from the server and then print out the path.

See the z.txt displayed below for the router error message

z.txt

Recd Packet After Unescaping
~..7e..126
..ff..255
..3..3
 ..0..0
!..21..33
E..45..69
 ..0..0
 ..0..0
8..38..56
..1f..31
'..27..39
 ..0..0
 ..0..0
..fd..253
..1..1
 ..0..0
..d7..215
..ca..202
6..36..54
..5..5
..cd..205
..ca..202
6..36..54
..3..3
..8d..141
..b..11                // error - ttl expired
 ..0..0
..f4..244
..ff..255
 ..0..0
 ..0..0
 ..0..0
 ..0..0
E..45..69
 ..0..0
 ..0..0
..1c..28
 ..0..0
..1..1
 ..0..0
 ..0..0
..1..1
..1..1
..10..16
4..34..52
..ca..202
6..36..54
..3..3
..8d..141
..ce..206
g..67..103

..d..13
..82..130
..8..8
 ..0..0
..f7..247
..ef..239
 ..0..0
..7..7
 ..0..0
	..9..9
Z..5a..90
..e7..231
~..7e..126

The packet you receive is marked out using /'s. It starts off normally, but instead of the target's IP address, you end up with a routers address in the source field. When you reach the actual ICMP packet, it starts off with a 0x0B (TTL Expired) error code. The entire packet we had sent is then repeated verbatim. In this way we can extract the routers IP address from the IP header. Once we have the IP address, we can perform a reverse DNS lookup, where we send the IP address to the DNS server and ask it for the routers name, and print out the routers host and domain name.


The above tutorial is a joint effort of

Mr. Vijay Mukhi
Ms. Sonal Kotecha
Mr. Arsalan Zaidi


Back to the main page


Vijay Mukhi's Computer Institute
VMCI, B-13, Everest Building, Tardeo, Mumbai 400 034, India
Tel : 91-22-496 4335 /6/7/8/9     Fax : 91-22-307 28 59
e-mail : vmukhi@giasbm01.vsnl.net.in
http://www.vijaymukhi.com