We've already done TCP/IP over Ethernet, so we decided to round off the tutorial with a feature on TCP/IP over PPP. We strongly recommend you read the TCP/IP Ethernet and the PPP tutorials before you proceed.
There isn't much of a difference between TCP/IP over Ethernet and TCP/IP over a PPP link. The outer frame changes, but the TCP/IP packets remain the same. In PPP, the concept of an Ethernet packet doesn't exist and so there's no need for ARP under PPP or for any tedious IP to Ethernet conversions. However, the PPP protocol is more complicated and convoluted than the Ethernet one. This is because we have to reestablish contact every time we want to try out a new program. On Ethernet, you're always connected to the wire.
The programs look larger because of all the sub-protocols under PPP, but we're leading up to the same thing out here as with Ethernet, sending a GET / and receiving an HTML file.
The SYN
tcp1.rc
mmm menu begin menuitem "Connect",100 end
tcp1.c
The first program here does exactly what the first Ethernet program did, it sends a TCP/IP packet with the SYN flag on to the server at the other end. All the action occurs in the function connection(). It's here that the TCP and IP headers are created. Once that's done, the function writeabc() is called and it's passed the TCP/IP headers and the TCP options as parameters. The headers are copied into a structure called tcpip and several functions like escapeip() addsevene() and sendit() are called. These functions do exactly what their name suggests and if you couldn't figure that out, maybe a revision of your basics is in order!#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 tcphdr { unsigned short srcport; unsigned short destport; unsigned long seqno; unsigned long ackno; unsigned char hdrlen; unsigned char flags; unsigned short win; unsigned short chksum; unsigned short urgptr; }; struct dummytcp { unsigned char src[4]; unsigned char dest[4]; char u; char prot; unsigned short len; }; unsigned long datasent; unsigned int ipctr; 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 abcsa(unsigned 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 connection(); void writeabc(unsigned char * ip, unsigned char *tcp, unsigned char opt[],unsigned int l); unsigned short tcpchecksum(struct tcphdr * tcp,char * o,unsigned int len,unsigned int * l); unsigned char sipaddress[4]={0,0,0,0}; void ippacket(struct packet *f); void tcpippacket(struct packet *f); unsigned short fconnected; unsigned short len; 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; char sseq[4]; char aack[4]; char destnipaddress[4]={206,103,13,130}; 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 unsigned short ii; 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) { if(fconnected == 0) 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) { connection(); } 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 short i; abc("In process packet"); abc("Received Packet"); for(i=0; i<recdpacket.packetsize;i++) abcchar(recdpacket.data[i]); unescape(&recdpacket,&unescpacket); abc("Unescaped Packet"); for(i=0; i<unescpacket.packetsize;i++) abcchar(unescpacket.data[i]); removeframe(&unescpacket,&finalpacket); abc("Final Packet"); for(i=0; i<finalpacket.packetsize;i++) abcchar(finalpacket.data[i]); abcchar(finalpacket.data[0]); abcchar(finalpacket.data[1]); 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) tcpippacket(&finalpacket); for(i=0;i<1000;i++) { recdpacket.data[i]=0; unescpacket.data[i]=0; finalpacket.data[i]=0; } recdpacket.packetsize=0; unescpacket.packetsize=0; finalpacket.packetsize=0; } void ipcppacket(struct packet * f) { if (f->data[2]== 1) { abc("ipcpReq Sent...."); sendipcpack(f); sendipcpreq(sipaddress); } if (f->data[2]== 2) { abc("IPCP Ack Received"); MessageBox(0,"ipcp Ack received","ipcp Ack received",0); } if (f->data[2]== 3) { abc("ipcp NAck received"); 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 short i=0,j=0; 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 short i=0,j=0; if(u->packetsize > 3) { for(i=0,j=3;j<u->packetsize-3;i++,j++) { f->data[i]=u->data[j]; } f->packetsize=i; } else f->packetsize=0; } void lcppacket(struct packet *lcp) { if (lcp->data[2]== 1) { sendconfack(lcp); sendconfreq(); //MessageBox(0,"Configure Ack and Req","Configure Ack and Req",0); } if (lcp->data[2]== 2) { abc("Configure Ack Received"); } 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 short 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 short 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 short 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 short 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 short i; WriteFile(idComDev,spacket->data,spacket->packetsize,&dwBytesWritten,0) ; sprintf(aa,"WriteFile...spacket->packetsize=%d...dwBytesWritten=%d", spacket->packetsize,dwBytesWritten); abc(aa); for(i=0; i< spacket->packetsize;i++) abcchar(spacket->data[i]); } void connection() { struct tcphdr tcp; struct iphdr ip; char opt[4]={2,4,2,0}; abc("In Connection"); tcp.srcport=ohtons(1024); tcp.destport=ohtons(80); tcp.seqno=ohtonl(5); tcp.ackno=ohtonl(0); tcp.hdrlen=0x60; tcp.flags=0x2; tcp.win=ohtons(1024); tcp.chksum=0; tcp.urgptr=0; tcp.chksum=tcpchecksum(&tcp,opt,4,20); ip.verlen =0x45; ip.tos =0x0; ip.totlen =ohtons(44); ip.id =ohtons(1); ip.frag =0x00; ip.ttl =0x1f; ip.prot =0x6; 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] =destnipaddress[0]; ip.destip[1] =destnipaddress[1]; ip.destip[2] =destnipaddress[2]; ip.destip[3] =destnipaddress[3]; ip.chksum =checksum(&ip,20); writeabc(&ip,&tcp,opt,4); } void ippacket(struct packet *f) { MessageBox(0,"Send the Last ACK","Send the Last ACK",0); } void writeabc(unsigned char * ip, unsigned char *tcp, unsigned char *opt,unsigned int l) { struct packet tcpip; unsigned short i,j; unsigned char uu[1000]; abc("writeabc"); 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]=tcp[i]; } if (opt != 0) { for(i=0;i<l;i++,j++) { uu[j]=opt[i]; } } for(i=0;i<j;i++) { tcpip.data[i]=uu[i]; } tcpip.packetsize=j; tcpip.packetsize=calcchksum(tcpip.data,tcpip.packetsize); escapeip(&tcpip); addsevene(&tcpip); sendit(&tcpip); } unsigned short tcpchecksum(unsigned char * tcp,char * o,unsigned int len,unsigned int l) { unsigned char u[1000]; unsigned char * t; struct dummytcp d; unsigned short chksum; unsigned short i,j; unsigned short tcplen; tcplen=l; for(i=0;i<tcplen;i++) { u[i]=tcp[i]; } if(o != 0) { tcplen=tcplen+len; for(j=0;j<len;j++,i++) u[i]=o[j]; } l = tcplen; d.src[0]=sipaddress[0]; d.src[1]=sipaddress[1]; d.src[2]=sipaddress[2]; d.src[3]=sipaddress[3]; d.dest[0]=destnipaddress[0]; d.dest[1]=destnipaddress[1]; d.dest[2]=destnipaddress[2]; d.dest[3]=destnipaddress[3]; d.u=0; d.prot=6; d.len=ohtons(l); t=&d; for ( i = 0;i<=11;i++,l++) { u[l] = t[i]; } tcplen=l; chksum=checksum(u,tcplen); return chksum; } 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; } unsigned long oinet_addr(unsigned char data[]) { unsigned long h5; h5=((((long)1<<24)*data[0])+(data[1]*65536)+(data[2]*256)+data[3]); return h5; } void tcpippacket(struct packet *f) { MessageBox(0,"data ","data",0); if((f->data[35]&0x12)==0x12) { abc("Syn Ack Received"); ippacket(f); } if((f->data[35]&0x10)==0x10) { abc("Ack Received"); } if((f->data[35]&0x01)==0x01) { abc("Fin Received"); MessageBox(0,"Fin","Fin",0); } }
The Server sends us a SYN/ACK when it receives our ACK and that packet is captured and placed in the file z.txt. Unlike Ethernet, there's no need for any ARP because if you're on PPP, you don't have an Ethernet card!
The output shown below is not the complete z.txt file. They are only the relevant bytes for the program. You can click on the z.txt to get the complete file.
Sent Packet WriteFile...spacket->packetsize=49...dwBytesWritten=49 ~..7e..126 !..21..33 E..45..69 ..0..0 ..0..0 ,..2c..44 ..0..0 ..1..1 ..0..0 ..0..0 ..1f..31 ..6..6 ..f2..242 V..56..86 ..ca..202 6..36..54 ..3..3 U..55..85 ..ce..206 g..67..103 ..d..13 ..82..130 ..4..4 ..0..0 ..0..0 P..50..80 ..0..0 ..0..0 ..0..0 ..5..5 ..0..0 ..0..0 ..0..0 ..0..0 `..60..96 ..2..2 ..4..4 ..0..0 ..ea..234 ..10..16 ..0..0 ..0..0 ..2..2 ..4..4 ..2..2 ..0..0 ..6..6 ..81..129 ~..7e..126 Received Packet Unescaped Packet ~..7e..126 ..ff..255 ..3..3 ..0..0 !..21..33 E..45..69 ..0..0 ..0..0 ,..2c..44 ..ec..236 ..4..4 ..0..0 ..0..0 9..39..57 ..6..6 ..ec..236 R..52..82 ..ce..206 g..67..103 ..d..13 ..82..130 ..ca..202 6..36..54 ..3..3 U..55..85 ..0..0 P..50..80 ..4..4 ..0..0 ..fd..253 4..34..52 t..74..116 ..20..32 ..0..0 ..0..0 ..0..0 ..6..6 `..60..96 ..12..18 :..3a..58 0..30..48 B..42..66 b..62..98 ..0..0 ..0..0 ..2..2 ..4..4 ..2..2 ..18..24 ..a6..166 ..dc..220 ~..7e..126 Final Packet ..0..0 !..21..33 E..45..69 ..0..0 ..0..0 ,..2c..44 ..ec..236 ..4..4 ..0..0 ..0..0 9..39..57 ..6..6 ..ec..236 R..52..82 ..ce..206 g..67..103 ..d..13 ..82..130 ..ca..202 6..36..54 ..3..3 U..55..85 ..0..0 P..50..80 ..4..4 ..0..0 ..fd..253 4..34..52 t..74..116 ..20..32 ..0..0 ..0..0 ..0..0 ..6..6 `..60..96 ..12..18 :..3a..58 0..30..48 B..42..66 b..62..98 ..0..0 ..0..0 ..2..2 ..4..4 ..2..2 ..18..24 ..0..0 !..21..33 Syn Ack Received
The ACK
tcp2.rc
mmm menu begin menuitem "Connect",100 end
tcp2.c
In this program we're actually responding to the SYN/ACK sent to us by the server at the other end. The function processpacket() is called each time we receive a packet. It checks to see if the packet is a part of PPP or TCP/IP. If the packet is TCP/IP, the function tcpippacket() is called and the code within it executed.#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 tcphdr { unsigned short srcport; unsigned short destport; unsigned long seqno; unsigned long ackno; unsigned char hdrlen; unsigned char flags; unsigned short win; unsigned short chksum; unsigned short urgptr; }; struct dummytcp { unsigned char src[4]; unsigned char dest[4]; char u; char prot; unsigned short len; }; unsigned long datasent; unsigned int ipctr; 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 connection(); void writeabc(unsigned char * ip, unsigned char *tcp, unsigned char opt[],unsigned int l); unsigned short tcpchecksum(struct tcphdr * tcp,char * o,unsigned int len,unsigned int * l); unsigned char sipaddress[4]={0,0,0,0}; void ippacket(struct packet *f); void ipack(struct packet * f); void tcpippacket(struct packet *f); unsigned short fconnected; unsigned short len; 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; char sseq[4]; char aack[4]; char destnipaddress[4]={206,103,13,130}; 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 unsigned short ii; 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) { if(fconnected == 0) 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) { connection(); } 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 short i; abc("In process packet"); abc("Received Packet"); unescape(&recdpacket,&unescpacket); abc("Unescaped Packet"); removeframe(&unescpacket,&finalpacket); abc("Final Packet"); 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) tcpippacket(&finalpacket); for(i=0;i<1000;i++) { recdpacket.data[i]=0; unescpacket.data[i]=0; finalpacket.data[i]=0; } recdpacket.packetsize=0; unescpacket.packetsize=0; finalpacket.packetsize=0; } void ipcppacket(struct packet * f) { if (f->data[2]== 1) { abc("ipcpReq Sent...."); sendipcpack(f); sendipcpreq(sipaddress); } if (f->data[2]== 2) { abc("IPCP Ack Received"); MessageBox(0,"ipcp Ack received","ipcp Ack received",0); } if (f->data[2]== 3) { abc("ipcp NAck received"); 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 short i=0,j=0; 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..%d..%x\n",c,c,c); fclose(fp); } void removeframe(struct packet *u,struct packet *f) { unsigned short i=0,j=0; if(u->packetsize > 3) { for(i=0,j=3;j<u->packetsize-3;i++,j++) { f->data[i]=u->data[j]; } f->packetsize=i; } else f->packetsize=0; } void lcppacket(struct packet *lcp) { if (lcp->data[2]== 1) { sendconfack(lcp); sendconfreq(); //MessageBox(0,"Configure Ack and Req","Configure Ack and Req",0); } if (lcp->data[2]== 2) { abc("Configure Ack Received"); } 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 short 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 short 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 short 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 short 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 short i; WriteFile(idComDev,spacket->data,spacket->packetsize,&dwBytesWritten,0) ; sprintf(aa,"WriteFile...spacket->packetsize=%d...dwBytesWritten=%d", spacket->packetsize,dwBytesWritten); abc(aa); /*for(i=0; i< spacket->packetsize;i++) abcchar(spacket->data[i]);*/ } void connection() { struct tcphdr tcp; struct iphdr ip; char opt[4]={2,4,2,0}; abc("In Connection"); tcp.srcport=ohtons(1024); tcp.destport=ohtons(80); tcp.seqno=ohtonl(5); tcp.ackno=ohtonl(0); tcp.hdrlen=0x60; tcp.flags=0x2; tcp.win=ohtons(1024); tcp.chksum=0; tcp.urgptr=0; tcp.chksum=tcpchecksum(&tcp,opt,4,20); ip.verlen =0x45; ip.tos =0x0; ip.totlen =ohtons(44); ip.id =ohtons(1); ip.frag =0x00; ip.ttl =0x1f; ip.prot =0x6; 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] =destnipaddress[0]; ip.destip[1] =destnipaddress[1]; ip.destip[2] =destnipaddress[2]; ip.destip[3] =destnipaddress[3]; ip.chksum =checksum(&ip,20); writeabc(&ip,&tcp,opt,4); } void ippacket(struct packet *f) { struct tcphdr tcp; struct iphdr ip; unsigned long seqno; unsigned long ackno; sseq[0]=f->data[30]; sseq[1]=f->data[31]; sseq[2]=f->data[32]; sseq[3]=f->data[33]; aack[0]=f->data[26]; aack[1]=f->data[27]; aack[2]=f->data[28]; aack[3]=f->data[29]; seqno=oinet_addr(sseq); ackno=oinet_addr(aack); tcp.srcport=ohtons(1024); tcp.destport=ohtons(80); tcp.seqno=ohtonl(seqno); tcp.ackno=ohtonl(ackno +1); tcp.hdrlen=0x50; tcp.flags=0x10; tcp.win=ohtons(1024); tcp.chksum=0; tcp.urgptr=0; tcp.chksum=tcpchecksum(&tcp,0,0,20); ip.verlen =0x45; ip.tos =0x0; ip.totlen =ohtons(40); ip.id =ohtons(1); ip.frag =0x00; ip.ttl =0x1f; ip.prot =0x6; 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] =destnipaddress[0]; ip.destip[1] =destnipaddress[1]; ip.destip[2] =destnipaddress[2]; ip.destip[3] =destnipaddress[3]; ip.chksum =checksum(&ip,20); writeabc(&ip,&tcp,0,0); ipctr++; MessageBox(0,"Sent the Last ACK","Sent the Last ACK",0); fconnected = 1; } void writeabc(unsigned char * ip, unsigned char *tcp, unsigned char *opt,unsigned int l) { struct packet tcpip; unsigned short i,j; unsigned char uu[1000]; abc("writeabc"); 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]=tcp[i]; } if (opt != 0) { for(i=0;i<l;i++,j++) { uu[j]=opt[i]; } } for(i=0;i<j;i++) { tcpip.data[i]=uu[i]; } tcpip.packetsize=j; tcpip.packetsize=calcchksum(tcpip.data,tcpip.packetsize); escapeip(&tcpip); addsevene(&tcpip); sendit(&tcpip); } unsigned short tcpchecksum(unsigned char * tcp,char * o,unsigned int len,unsigned int l) { unsigned char u[1000]; unsigned char * t; struct dummytcp d; unsigned short chksum; unsigned short i,j; unsigned short tcplen; tcplen=l; for(i=0;i<tcplen;i++) { u[i]=tcp[i]; } if(o != 0) { tcplen=tcplen+len; for(j=0;j<len;j++,i++) u[i]=o[j]; } l = tcplen; d.src[0]=sipaddress[0]; d.src[1]=sipaddress[1]; d.src[2]=sipaddress[2]; d.src[3]=sipaddress[3]; d.dest[0]=destnipaddress[0]; d.dest[1]=destnipaddress[1]; d.dest[2]=destnipaddress[2]; d.dest[3]=destnipaddress[3]; d.u=0; d.prot=6; d.len=ohtons(l); t=&d; for ( i = 0;i<=11;i++,l++) { u[l] = t[i]; } tcplen=l; chksum=checksum(u,tcplen); return chksum; } 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; } unsigned long oinet_addr(unsigned char data[]) { unsigned long h5; h5=((((long)1<<24)*data[0])+(data[1]*65536)+(data[2]*256)+data[3]); return h5; } void ipack(struct packet * f) { MessageBox(0,"ipack","ipack",0); } void tcpippacket(struct packet *f) { unsigned short i,j; for(i=0,j=40;i<f->packetsize;i++,j++) abcchar(f->data[j]); if((f->data[35]&0x12)==0x12) { abc("Syn Ack Received"); ippacket(f); } if((f->data[35]&0x10)==0x10) { abc("Ack Received"); ipack(f); } if((f->data[35]&0x01)==0x01) { abc("Fin Received"); MessageBox(0,"Fin","Fin",0); } }
In tcpippacket(), we check the flags to discover the type of packet. If the packet is a SYN/ACK, ippacket() is called, if it's an ACK, ipack() is called and so on. Since the packet we've received is an SYN/ACK, let's jump over to ippacket().
In ippacket() we create our response to the SYN/ACK, a simple ACK. Once the ACK is sent, the three way handshake will be over and a connection will be established. The only thing worthy of note here are the lines which switch the acknowledgment and sequence numbers around and add a 1 to the acknowledgment number. Once that's done, checksums are calculated, numbers switched from Little Endian to Big Endian and writeabc() is called which shoots the packet across to the server.
SYN Flooding
We've already explained the basics of this little trick, so we won't repeat ourselves here. What I wanted to bring to everyone's notice was that this program itself, if suitably modified, will work like a SYN flooder. All you have to do is keep sending SYN's as fast as you can and ignore the SYN/ACK's. That's all there is to it! However, don't be surprised if this doesn't work, most servers have implemented patched to negate this problem.
..0..0 !..21..33 E..45..69 ..0..0 ..0..0 ,..2c..44 ..ec..236 ..4..4 ..0..0 ..0..0 9..39..57 ..6..6 ..ec..236 R..52..82 ..ce..206 g..67..103 ..d..13 ..82..130 ..ca..202 6..36..54 ..3..3 U..55..85 ..0..0 P..50..80 ..4..4 ..0..0 ..fd..253 4..34..52 t..74..116 ..20..32 ..0..0 ..0..0 ..0..0 ..6..6 `..60..96 ..12..18 :..3a..58 0..30..48 B..42..66 b..62..98 ..0..0 ..0..0 ..2..2 ..4..4 ..2..2 ..18..24 ..0..0 !..21..33 Syn Ack Received writeabc WriteFile...spacket->packetsize=45...dwBytesWritten=45 ~..7e..126 !..21..33 E..45..69 ..0..0 ..0..0 (..28..40 ..0..0 ..1..1 ..0..0 ..0..0 ..1f..31 ..6..6 ..f2..242 Z..5a..90 ..ca..202 6..36..54 ..3..3 U..55..85 ..ce..206 g..67..103 ..d..13 ..82..130 ..4..4 ..0..0 ..0..0 P..50..80 ..0..0 ..0..0 ..0..0 ..6..6 ..fd..253 4..34..52 t..74..116 !..21..33 P..50..80 ..10..16 ..4..4 ..0..0 ..8c..140 ..b3..179 ..0..0 ..0..0 ..b3..179 ..a4..164 ~..7e..126 Ack Received writeabc WriteFile...spacket->packetsize=45...dwBytesWritten=45 ~..7e..126 !..21..33 E..45..69 ..0..0 ..0..0 (..28..40 ..0..0 ..1..1 ..0..0 ..0..0 ..1f..31 ..6..6 ..f2..242 Z..5a..90 ..ca..202 6..36..54 ..3..3 U..55..85 ..ce..206 g..67..103 ..d..13 ..82..130 ..4..4 ..0..0 ..0..0 P..50..80 ..0..0 ..0..0 ..0..0 ..6..6 ..fd..253 4..34..52 t..74..116 $..24..36 P..50..80 ..10..16 ..4..4 ..0..0 ..8c..140 ..b0..176 ..0..0 ..0..0 ..cf..207 9..39..57 ~..7e..126
GET /
tcp3.rc
mmm menu begin menuitem "Connect",100 menuitem "Get",101 end
tcp3.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 tcphdr { unsigned short srcport; unsigned short destport; unsigned long seqno; unsigned long ackno; unsigned char hdrlen; unsigned char flags; unsigned short win; unsigned short chksum; unsigned short urgptr; }; struct dummytcp { unsigned char src[4]; unsigned char dest[4]; char u; char prot; unsigned short len; }; unsigned long datasent; unsigned int ipctr; 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 connection(); void writeabc(unsigned char * ip, unsigned char *tcp, unsigned char opt[],unsigned int l); unsigned short tcpchecksum(struct tcphdr * tcp,char * o,unsigned int len,unsigned int * l); unsigned char sipaddress[4]={0,0,0,0}; void getfile(); void tcpippacket(struct packet *f); void ippacket(struct packet *f); void ipack(struct *f); void common(char sseq[],char aack[],unsigned short len, unsigned char hdrlen,unsigned char flags,char data[], unsigned short datalen,unsigned short iplen); unsigned short fconnected; unsigned short len; 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; char sseqno[4]; char aackno[4]; char destnipaddress[4]={206,103,13,130}; 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 unsigned short ii; 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) { if(fconnected == 0) 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) { connection(); } if(uMsg == WM_COMMAND && wParam == 101) { getfile(); } 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 common(char sseq[],char aack[],unsigned short len, unsigned char hdrlen,unsigned char flags,char data[], unsigned short datalen,unsigned short iplen) { unsigned long seqno; unsigned long ackno; struct tcphdr tcp; struct iphdr ip; seqno=oinet_addr(sseq); ackno=oinet_addr(aack); tcp.srcport=ohtons(1024); tcp.destport=ohtons(80); tcp.seqno=ohtonl(seqno); tcp.ackno=ohtonl(ackno+len); tcp.win=ohtons(1024); tcp.chksum=0; tcp.urgptr=0; tcp.hdrlen=hdrlen; tcp.flags=flags; tcp.chksum=tcpchecksum(&tcp,data,datalen,20); ip.verlen =0x45; ip.tos =0x0; ip.id =ohtons(1); ip.frag =0x00; ip.ttl =0x1f; ip.prot =0x6; 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] =destnipaddress[0]; ip.destip[1] =destnipaddress[1]; ip.destip[2] =destnipaddress[2]; ip.destip[3] =destnipaddress[3]; ip.totlen =ohtons(iplen); ip.chksum =checksum(&ip,20); writeabc(&ip,&tcp,data,datalen); } void connection() { unsigned char hdrlen,flags; char opt[4]={2,4,2,0}; abc("In Connection"); sseqno[0]=0; sseqno[1]=0; sseqno[2]=0; sseqno[3]=5; aackno[0]=0; aackno[1]=0; aackno[2]=0; aackno[3]=0; hdrlen=0x60; flags=0x2; common(sseqno,aackno,0,hdrlen,flags,opt,4,44); } void getfile() { unsigned char hdrlen,flags; char tcpdata[]="GET / HTTP/1.0\r\n\r\n"; hdrlen=0x50; flags=0x10; common(sseqno,aackno,1,hdrlen,flags,tcpdata,strlen(tcpdata),40+strlen(tcpdata)); } void ipack(struct packet *f) { unsigned char hdrlen,flags; unsigned short len; unsigned char iplen[2]; abc("Ack Received"); sseqno[0]=f->data[30]; sseqno[1]=f->data[31]; sseqno[2]=f->data[32]; sseqno[3]=f->data[33]; aackno[0]=f->data[26]; aackno[1]=f->data[27]; aackno[2]=f->data[28]; aackno[3]=f->data[29]; hdrlen=0x50; flags=0x10; iplen[0]=f->data[4]; iplen[1]=f->data[5]; len=((iplen[0]*256)+iplen[1])-40; common(sseqno,aackno,len,hdrlen,flags,0,0,40); } void ippacket(struct packet *f) { unsigned char hdrlen,flags; abc("Syn Ack Received"); sseqno[0]=f->data[30]; sseqno[1]=f->data[31]; sseqno[2]=f->data[32]; sseqno[3]=f->data[33]; aackno[0]=f->data[26]; aackno[1]=f->data[27]; aackno[2]=f->data[28]; aackno[3]=f->data[29]; hdrlen=0x50; flags=0x10; common(sseqno,aackno,1,hdrlen,flags,0,0,40); ipctr++; MessageBox(0,"Sent the Last ACK","Sent the Last ACK",0); fconnected = 1; } void processpacket() { struct packet unescpacket,finalpacket; unsigned short i; abc("In process packet"); abc("Received Packet"); unescape(&recdpacket,&unescpacket); abc("Unescaped Packet"); for(i=0;i<unescpacket.packetsize;i++) abcchar(unescpacket.data[i]); removeframe(&unescpacket,&finalpacket); abc("Final Packet"); 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) tcpippacket(&finalpacket); for(i=0;i<1000;i++) { recdpacket.data[i]=0; unescpacket.data[i]=0; finalpacket.data[i]=0; } recdpacket.packetsize=0; unescpacket.packetsize=0; finalpacket.packetsize=0; } void ipcppacket(struct packet * f) { if (f->data[2]== 1) { abc("ipcpReq Sent...."); sendipcpack(f); sendipcpreq(sipaddress); } if (f->data[2]== 2) { abc("IPCP Ack Received"); MessageBox(0,"ipcp Ack received","ipcp Ack received",0); } if (f->data[2]== 3) { abc("ipcp NAck received"); 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 short i=0,j=0; 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:\\aa.txt","a+"); fprintf(fp,"%c",c); fclose(fp); } void removeframe(struct packet *u,struct packet *f) { unsigned short i=0,j=0; if(u->packetsize > 3) { for(i=0,j=3;j<u->packetsize-3;i++,j++) { f->data[i]=u->data[j]; } f->packetsize=i; } else f->packetsize=0; } void lcppacket(struct packet *lcp) { if (lcp->data[2]== 1) { sendconfack(lcp); sendconfreq(); } if (lcp->data[2]== 2) { abc("Configure Ack Received"); } 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 short 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 short 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 short 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 short 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 short i; WriteFile(idComDev,spacket->data,spacket->packetsize,&dwBytesWritten,0) ; sprintf(aa,"WriteFile...spacket->packetsize=%d...dwBytesWritten=%d", spacket->packetsize,dwBytesWritten); abc(aa); } void writeabc(unsigned char * ip, unsigned char *tcp, unsigned char *opt,unsigned int l) { struct packet tcpip; unsigned short i,j; unsigned char uu[1000]; abc("writeabc"); 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]=tcp[i]; } if (opt != 0) { for(i=0;i<l;i++,j++) { uu[j]=opt[i]; } } for(i=0;i<j;i++) { tcpip.data[i]=uu[i]; } tcpip.packetsize=j; tcpip.packetsize=calcchksum(tcpip.data,tcpip.packetsize); escapeip(&tcpip); addsevene(&tcpip); sendit(&tcpip); } unsigned short tcpchecksum(unsigned char * tcp,char * o,unsigned int len,unsigned int l) { unsigned char u[1000]; unsigned char * t; struct dummytcp d; unsigned short chksum; unsigned short i,j; unsigned short tcplen; tcplen=l; for(i=0;i<tcplen;i++) { u[i]=tcp[i]; } if(o != 0) { tcplen=tcplen+len; for(j=0;j<len;j++,i++) u[i]=o[j]; } l = tcplen; d.src[0]=sipaddress[0]; d.src[1]=sipaddress[1]; d.src[2]=sipaddress[2]; d.src[3]=sipaddress[3]; d.dest[0]=destnipaddress[0]; d.dest[1]=destnipaddress[1]; d.dest[2]=destnipaddress[2]; d.dest[3]=destnipaddress[3]; d.u=0; d.prot=6; d.len=ohtons(l); t=&d; for ( i = 0;i<=11;i++,l++) { u[l] = t[i]; } tcplen=l; chksum=checksum(u,tcplen); return chksum; } 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; } unsigned long oinet_addr(unsigned char data[]) { unsigned long h5; h5=((((long)1<<24)*data[0])+(data[1]*65536)+(data[2]*256)+data[3]); return h5; } void tcpippacket(struct packet *f) { unsigned short i,j; for(i=0,j=40;i<f->packetsize;i++,j++) abcchar(f->data[j]); if((f->data[35]&0x12)==0x12) { ippacket(f); } if((f->data[35]&0x10)==0x10) { ipack(f); } if((f->data[35]&0x01)==0x01) { abc("Fin Received"); MessageBox(0,"Fin","Fin",0); } }
This is the final program and it sends an HTTP command, GET / after we've connected. Once we connect to the remote server, click on the menu item get and the function getfile() will be called. In getfile() we change the TCP header length to 0x50 and the flags to 0x10 (ACK only). Once that's done we call common, a function that concatenates all the available header and data information into one packet. Notice that the acknowledgment number is incremented by one. Once we're through, writeabc() is called and the packet is sent on it's way.
When the server at the other end receives the GET /, it responds with a packet containing the HTML file. This is different from what happens under Ethernet. There the server (We've used the same server software) sent us an ACK packet first and then the data. Here the data packet itself contains the ACK for the HTTP command (GET /). The HTML page is written to disk by the function tcpippacket() which calls abcchar() internally. When we receive a packet, processpacket() is called as usual. It in turn calls tcpippacket() which checks the flags. Tcpippacket() then calls ipack() which handles the ACK packet. It switches the acknowledgment and sequence numbers around and calculates the length of the data by converting the IP length field into Little Endian (length * 256) and subtracting the header bytes (length - 40). It then calls common(). Common() does exactly what it did in the second program and after that we write the bytes to the COM port and hope for the best. In this way we keep ACKing the data the server keeps sending us. If we didn't do this, the server would repeat itself for some time and then hang-up by sending a packet with the FIN (finished) flag on. Once it's through with the transfer, the server does send us a FIN and we're supposed to respond with another FIN, but we don't. We don't cause we're lazy... ... So SUE us! That just about wraps it up for this topic.
aa.txt
6Q P N P:0. <HTML><HEAD><title>Welcome</title></HEAD> <BODY BGCOLOR=9999FF> <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=600> <TR VALIGN=MIDDLE> <TD WIDTH=18><A HREF="http://www.eff.org/blueribbon.html"><IMG ALT="Blue Ribbon" BORDER=0 WIDTH=18 HEIGHT=30 SRC=e~ <HTML><HEAD><title>Welcome</title></HEAD> <BODY BGCOLOR=9999FF> <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=600> <TR VALIGN=MIDDLE> <TD WIDTH=18><A HREF="http://www.eff.org/blueribbon.html"><IMG ALT="Blue Ribbon" BORDER=0 WIDTH=18 HEIGHT=30 SRC= ~~~~~ !E ( 7xg 6Q P N P:0 Bill of Rights" BORDER=0 WIDTH=226 HEIGHT=30 SRC="/Images/eConstitution.gif"></A></TD> <TD WIDTH=10></TD> <TD WIDTH=32><A HREF="http://www.starnine.com/webstar/"><IMG ALT="Starnine's Webstar" BORDER=0 WIDTH=32 HEIGHT=32 SRC="/Images/webstar32x32.GIF"></A></TD> <TD WIDTH=10></TD> <TD WIDTH=33><A HREF="http://www.servers.apple.com/"><IMG ALT="Apple Internet Server Solution" BORDER=0 WIDTH=33 HEIGHT=34 SRC="/Images/aiss33x34.GIF"></A></TD> <TD WIDTH=139><IMG ALIGN=RIGHT ALT="Page Counter" SRC="/CGIs/coun~ Bill of Rights" BORDER=0 WIDTH=226 HEIGHT=30 SRC="/Images/eConstitution.gif"></A></TD> <TD WIDTH=10></TD> <TD WIDTH=32><A HREF="http://www.starnine.com/webstar/"><IMG ALT="Starnine's Webstar" BORDER=0 WIDTH=32 HEIGHT=32 SRC="/Images/webstar32x32.GIF"></A></TD> <TD WIDTH=10></TD> <TD WIDTH=33><A HREF="http://www.servers.apple.com/"><IMG ALT="Apple Internet Server Solution" BORDER=0 WIDTH=33 HEIGHT=34 SRC="/Images/aiss33x34.GIF"></A></TD> <TD WIDTH=139><IMG ALIGN=RIGHT ALT="Page Counter" SRC="/CGIs/coun ~! a&D ~~~~~~ !E ( 7qg 6Q P N P:0/ ="http://www.apple.com/"><IMG ALT="Best Viewed with Macintosh" BORDER=0 WIDTH=170 HEIGHT=38 SRC="/Images/macbut170x38.GIF"></A></TD> </TABLE> <P></P> <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=600> <TR VALIGN=MIDDLE> <TD WIDTH=117><A HREF="/Images/IndiaMap546x599.GIF"><IMG ALT="Map of India" BORDER=0 WIDTH=117 HEIGHT=128 SRC="/Images/IndiaMap117x128.GIF"></A></TD> <TD WIDTH=10></TD> <TD WIDTH=94><IMG ALT="Server's Home" BORDER=0 WIDTH=94 HEIGHT=128 SRC="Images/Server/Home94x128.gif"></TD> <TD \~ ="http://www.apple.com/"><IMG ALT="Best Viewed with Macintosh" BORDER=0 WIDTH=170 HEIGHT=38 SRC="/Images/macbut170x38.GIF"></A></TD> </TABLE> <P></P> <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=600> <TR VALIGN=MIDDLE> <TD WIDTH=117><A HREF="/Images/IndiaMap546x599.GIF"><IMG ALT="Map of India" BORDER=0 WIDTH=117 HEIGHT=128 SRC="/Images/IndiaMap117x128.GIF"></A></TD> <TD WIDTH=10></TD> <TD WIDTH=94><IMG ALT="Server's Home" BORDER=0 WIDTH=94 HEIGHT=128 SRC="Images/Server/Home94x128.gif"></TD> <TD ~~~ !E ( 7mg 6Q P N P:0 HREF="misc/GatesOnMac.html"><IMG ALT="IntelOutside-BillGatesOnMacintosh" BORDER=0 WIDTH=171 HEIGHT=128 SRC="Images/IntelOut-BillGates.gif"></A></TD> </TABLE> <P></P> <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=600> <TR VALIGN=MIDDLE> <TD WIDTH=190><CENTER>Shekhar Kapur's<A HREF="http://www.quasar.co.in/"><IMG ALT="Quasar Films" BORDER=0 WIDTH=190 HEIGHT=80 SRC="/Quasar/Images/Quasar-190x80.GIF"></A></CENTER></TD> <TD WIDTH=160><!--CENTER><!--A HREF="http://www.nasscom.org.in/"><!--IMG ALT="N.A.S.D~ HREF="misc/GatesOnMac.html"><IMG ALT="IntelOutside-BillGatesOnMacintosh" BORDER=0 WIDTH=171 HEIGHT=128 SRC="Images/IntelOut-BillGates.gif"></A></TD> </TABLE> <P></P> <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=600> <TR VALIGN=MIDDLE> <TD WIDTH=190><CENTER>Shekhar Kapur's<A HREF="http://www.quasar.co.in/"><IMG ALT="Quasar Films" BORDER=0 WIDTH=190 HEIGHT=80 SRC="/Quasar/Images/Quasar-190x80.GIF"></A></CENTER></TD> <TD WIDTH=160><!--CENTER><!--A HREF="http://www.nasscom.org.in/"><!--IMG ALT="N.A.S. ~~~~~~~ !E x 7 g 6Q P N P:00 S.COM." BORDER=0 WIDTH=62 HEIGHT=10 SRC="http://www.nasscom.org.in/Images/NASSCOM-124x19.GIF"><!--/A><!--/CENTER></TD> <TD WIDTH=250> <A HREF="http://www.quasar.co.in/SuchitraKrishnamoorthi/"><IMG ALT="Suchitra Krishnamoorthi" BORDER=0 WIDTH=250 HEIGHT=40 SRC="/Quasar/SuchitraKrishnamoorthi/Images/banSuchitraKrishnamoorthi.gif"></A> ~ S.COM." BORDER=0 WIDTH=62 HEIGHT=10 SRC="http://www.nasscom.org.in/Images/NASSCOM-124x19.GIF"><!--/A><!--/CENTER></TD> <TD WIDTH=250> <A HREF="http://www.quasar.co.in/SuchitraKrishnamoorthi/"><IMG ALT="Suchitra Krishnamoorthi" BORDER=0 WIDTH=250 HEIGHT=40 SRC="/Quasar/SuchitraKrishnamoorthi/Images/banSuchitraKrishnamoorthi.gif"></A> ~~~~~ !E ( 7Zg 6Q P N1 P:0C rotra's<A HREF="http://www.ArtistTree.co.in/"><IMG ALT="ArtistTree" BORDER=0 WIDTH=180 HEIGHT=38 SRC="/Images/Guests/ArtistTree.GIF"></A></CENTER></TD> <TD WIDTH=170></TD> <TD WIDTH=250><A HREF="http://www.jazz.org.in/"><IMG ALT="Jazz India" BORDER=0 WIDTH=250 HEIGHT=40 SRC="Images/Guests/JazzIndia250x40.GIF"></A></TD> </TABLE> <P></P> <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=600> <TR VALIGN=MIDDLE> <TD WIDTH=204><CENTER>Vijay Mukhi's<A HREF="SevenEleven/"><IMG ALT="7 SevenEleven 11" BORDER=0~ rotra's<A HREF="http://www.ArtistTree.co.in/"><IMG ALT="ArtistTree" BORDER=0 WIDTH=180 HEIGHT=38 SRC="/Images/Guests/ArtistTree.GIF"></A></CENTER></TD> <TD WIDTH=170></TD> <TD WIDTH=250><A HREF="http://www.jazz.org.in/"><IMG ALT="Jazz India" BORDER=0 WIDTH=250 HEIGHT=40 SRC="Images/Guests/JazzIndia250x40.GIF"></A></TD> </TABLE> <P></P> <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=600> <TR VALIGN=MIDDLE> <TD WIDTH=204><CENTER>Vijay Mukhi's<A HREF="SevenEleven/"><IMG ALT="7 SevenEleven 11" BORDER=0 ~! a&D e~~~~~~ !E ( 7Vg 6Q P N1 P:09 36 ALIGN=MIDDLE ALT="Talk City" BORDER=0 SRC="CCCclan/Images/TalkCity3Dquarter.gif"></A></FONT></H1></P> <H3><A HREF="misc/toc.html"><BIG>Table Of Contents</BIG></A> <FONT COLOR="white"> of (some of) the other stuff on this server.</FONT></H3> <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=600> <TR VALIGN=MIDDLE> <TD WIDTH=251><A HREF="http://www.solutions.apple.com/"><IMG ALT="Apple Internet Server Solution" BORDER=0 WIDTH=251 HEIGHT=42 SRC="Images/AISS.GIF"></A></TD> <TD WIDTH=197><CENTER><A HREF="e+~ 36 ALIGN=MIDDLE ALT="Talk City" BORDER=0 SRC="CCCclan/Images/TalkCity3Dquarter.gif"></A></FONT></H1></P> <H3><A HREF="misc/toc.html"><BIG>Table Of Contents</BIG></A> <FONT COLOR="white"> of (some of) the other stuff on this server.</FONT></H3> <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=600> <TR VALIGN=MIDDLE> <TD WIDTH=251><A HREF="http://www.solutions.apple.com/"><IMG ALT="Apple Internet Server Solution" BORDER=0 WIDTH=251 HEIGHT=42 SRC="Images/AISS.GIF"></A></TD> <TD WIDTH=197><CENTER><A HREF=" ~~~~~ !E 7dg 6Q P N1 P:0 atlal.co.in/default.html" name=url> <input type=submit value="Click here to: Register to receive eMail when this page is updated."> </form> <hr> <font color="yellow">The <a href="mailto:Webmaster@mail.mafatlal.co.in">WebMaster</a> welcomes all Comments, Compliments and Constructive Criticism.</font> <font color="blue">:-)</font> <BR> <FONT COLOR="white"><BIG>BTW, <STRONG>this is not anyone's</STRONG> Home Page - <EM>it's just the Home Page of this server.<EM></BIG></FONT> </BODY></HTML>~ atlal.co.in/default.html" name=url> <input type=submit value="Click here to: Register to receive eMail when this page is updated."> </form> <hr> <font color="yellow">The <a href="mailto:Webmaster@mail.mafatlal.co.in">WebMaster</a> welcomes all Comments, Compliments and Constructive Criticism.</font> <font color="blue">:-)</font> <BR> <FONT COLOR="white"><BIG>BTW, <STRONG>this is not anyone's</STRONG> Home Page - <EM>it's just the Home Page of this server.<EM></BIG></FONT> </BODY></HTML> ~~~~~~~ !E ( 7Dg 6Q P N P:0S u~ ~! a&D ~~~
Mr. Vijay Mukhi
Ms. Sonal Kotecha
Mr. Arsalan Zaidi
Mr. Rajkumar Ganesan
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