Code:
#define LOCALPORT 8888
//pseudo header,12 bytes
struct prseuheader
{
unsigned long s_addr;//resource addr
unsigned long d_addr;//dest addr
unsigned char zero; //0
unsigned char prototp;//tcp=6
unsigned short len; //length
};
/*20 bytes*/
struct IP_Head
{
unsigned char length:4;
unsigned char version:4;
unsigned char tos;
unsigned short total_length;
unsigned short id;
unsigned short flagoff;
unsigned char ttl;
unsigned char protocol;
unsigned short cksum;
unsigned int source;
unsigned int dest;
};
/* 20 bytes */
struct TCP_Head
{
unsigned short source_port;
unsigned short dest_port;
unsigned int seqno;
unsigned int ackno;
unsigned char rev1:4;
unsigned char len:4;
unsigned char fin:1;
unsigned char syn:1;
unsigned char rst:1;
unsigned char psh:1;
unsigned char ack:1;
unsigned char urg:1;
unsigned char rev2:2;
unsigned short winsize;
unsigned short cksum;
unsigned short urgent;
};
static struct sockaddr_in Localaddr;//Local IP address
static struct sockaddr_in RemoteAddr;//remote IP address
/* Checksum */
unsigned short checksum(unsigned short* buffer, int size)
{
unsigned long cksum = 0;
while(size>1)
{
cksum += *buffer++;
size -= 2;
}
if(size)
{
cksum += *(u_char*)buffer;
}
cksum = (cksum>>16) + (cksum&0xffff);
cksum += (cksum>>16);
return (unsigned short)(~cksum);
}
//main
int main()
{
int sk;
char ipaddr[16]="192.168.1.6";//remote IP
struct in_addr in;
inet_aton(ipaddr,&in);
//set RemoteAddr
bzero(&RemoteAddr,sizeof(struct sockaddr_in));
RemoteAddr.sin_family=AF_INET;
RemoteAddr.sin_addr=in;
sk=socket(AF_INET,SOCK_RAW,IPPROTO_TCP); //create SOCK_RAW
if(sk<0)
{
perror("socket error");
return -1;
}
int iRet;
struct timeval timeout={1,0}; //timeout
int len=sizeof(struct timeval);
//set timeout
iRet =setsockopt(sk,SOL_SOCKET,SO_SNDTIMEO, &timeout,len);
if (iRet<0)
{
perror("[Error]Set socket SO_SNDTIMEO option");
close(sk);
return -1;
}
iRet =setsockopt(sk,SOL_SOCKET,SO_RCVTIMEO, &timeout,len);
if (iRet<0)
{
perror("[Error]Set socket SO_RCVTIMEO option");
close(sk);
return -1;
}
bzero(&Localaddr,sizeof(struct sockaddr_in));
Localaddr.sin_family=AF_INET;
Localaddr.sin_addr.s_addr=inet_addr("192.168.124.128"); //My PC's real IP
iRet = bind(sk,(struct sockaddr*)&Localaddr,sizeof(struct sockaddr));
if (iRet<0)
{
perror("[Error]Bind sk the interface");
close(sk);
return -1;
}
struct TCP_Head Tcph;//TCP packet
struct IP_TCP_Head
{
struct IP_Head Iph;
struct TCP_Head Tcph;
}*Reply; //for receiving
struct prseuheader theheader;//pseudo header
char tcpbuff[32]; //pseudo header and TCP header
unsigned char buffer[200]; //buffer for receiving
struct sockaddr_in taddr; //
int lenfrom,lenrecv;
bzero(&Tcph,20);
Tcph.source_port =htons(8888);//local port
//Tcph.dest_port =htons(21);//dest port;
Tcph.seqno =0;
Tcph.ackno =0;
Tcph.len =5;
Tcph.syn =1; //SYN=1
Tcph.winsize =htons(6000);
Tcph.cksum =0;
bzero(tcpbuff,32);
//fill
theheader.s_addr = Localaddr.sin_addr.s_addr;
theheader.d_addr = RemoteAddr.sin_addr.s_addr;
theheader.zero = 0;
theheader.prototp = 6; // protocol of TCP
theheader.len = htons(20); //length of TCP
//pseudo header+TCP header
memcpy(tcpbuff,&theheader,12);
memcpy(tcpbuff+12,&Tcph,20);
//Tcph.cksum =checksum((unsigned short *)tcpbuff,32);
int port=21;
//for(port=1;port<30;port++)
{
Tcph.dest_port =htons(port);
memcpy(tcpbuff+12,&Tcph,20);
Tcph.cksum =0;
Tcph.cksum =checksum((unsigned short *)tcpbuff,32);
//sending data
iRet=sendto(sk,(unsigned char*)&Tcph,20,0,(struct sockaddr*)&RemoteAddr,sizeof(struct sockaddr_in));
if(iRet<0)
perror("error sendto");
//receiving data
bzero(buffer,200);
bzero(&taddr,sizeof(taddr));
lenrecv=recvfrom(sk,buffer,200,0,(struct sockaddr*)&taddr,&lenfrom);
if(lenrecv>0) /*it express PC has received data*/
{
Reply=(struct IP_TCP_Head*)buffer;
printf("syn,ask=%d,%d\n",(Reply->Tcph).syn,(Reply->Tcph).ack);
if((Reply->Tcph).syn==1 &&(Reply->Tcph).ack==1 && (Reply->Iph).source==RemoteAddr.sin_addr.s_addr && (Reply->Iph).dest==Localaddr.sin_addr.s_addr)
{
printf("active Port:%d\n",21);
bzero(Reply,sizeof(Reply));
}
}
else
{
//it always displays
printf("len=%d\n",lenrecv);
perror("recv len");
}
}
return 0;
}