//
Authors: Rajesh Balla, Wei Cheng, Corinne Rhodes, Saifee Suterwala. //
Date Created: May 2, 2000 //
Last Modified: Sept 15, 2000 // // Description: This is
a program that implements the construction of a TCP packet. // It takes a source address, source port,
destination address, destination port // number, sequence number, acknowledgement number, the values for
the SYN, ACK, // FIN, and RST flags. #include
<stdio.h> // for printf()
and fprintf() #include
<stdlib.h> // for atoi() #include
<signal.h> #include
<string.h> // for memset() #include
<unistd.h> // or close() #include
<netdb.h> #include
<netinet/in.h> #include
<sys/socket.h> // for socket(), connect(), send(), and recv() #include
<arpa/inet.h> // for socketaddr_in
and inet_addr() #include
<netinet/ip.h> // for ip struct #include
<netinet/tcp.h>// for tcp struct char
myBUFFER[80]; void
send_packet(unsigned int, unsigned short, unsigned int, unsigned short); unsigned
short in_cksum(unsigned short *, int); unsigned
int host2ip(char *); void
DieWithError (char *errorMessage); /* error handling function*/ main(int
argc, char **argv) { unsigned int srchost; unsigned int dsthost; unsigned short dstport; unsigned short srcport; //check
for the minimum number of arguements if(argc < 5 || argc >= 6) { fprintf(stderr, "Usage: %s <srchost> <srcport>
<dsthost> <dstport>\n", argv[0]); exit(0); } srchost= host2ip(argv[1]); srcport = atoi(argv[2]); dsthost = host2ip(argv[3]); dstport = atoi(argv[4]); if(dstport == 0) dstport = 80; send_packet(srchost, srcport, dsthost,
dstport); } //
Creates the IP and TCP packet, opens the socket, calculate IP checksum, void
send_packet(unsigned int source_addr, unsigned short srcport, unsigned int
dest_addr, unsigned short dest_port) { struct send_tcp /* structure for the TCP/IP packet to send */ { struct iphdr ip; struct tcphdr tcp; } send_tcp; struct pseudo_header /* for calculating the checksum */ { unsigned int source_address; unsigned int dest_address; unsigned char placeholder; unsigned char protocol; unsigned short tcp_length; struct tcphdr tcp; } pseudo_header; int i; int tcp_socket; /* raw socket to send our TCP packet through */ struct sockaddr_in sin; int sinlen; char ans = 'n'; char temp; memset (&send_tcp, 0,
sizeof(send_tcp)); printf("\n Do you want to enter the
sequence number (y/n)?:"); fflush(stdin); ans = getchar(); if(ans =='y' || ans == 'Y') { printf("\n Enter the sequence
number: "); scanf("%u",&
send_tcp.tcp.seq); } else { printf("\n
Using default sequence number = %d \n", getpid()); send_tcp.tcp.seq = getpid(); } ans ='n'; printf("\n Do you want to enter the
Acknowledge Number (y/n)?:"); getchar(); ans = getchar(); if(ans =='y' || ans == 'Y') { printf("\n
Enter the Acknowledge Number: "); scanf("%u",
& send_tcp.tcp.ack_seq); } else { printf("\n
Using default Acknowledge number = %d\n", 0); send_tcp.tcp.ack_seq
= 0; } ans ='n'; printf("\n Do you want to set the
SYN Flag (y/n)?:"); getchar(); ans = getchar(); if(ans =='y' || ans == 'Y') { printf("\n
Setting the SYN flag\n"); send_tcp.tcp.syn
= 1; } else { printf("\n
Resetting the SYN flag\n"); send_tcp.tcp.syn
= 0; } ans ='n'; printf("\n Do you want to set the
ACK Flag (y/n)?:"); getchar(); ans = getchar(); if(ans =='y' || ans == 'Y') { printf("\n
Setting the ACK flag\n"); send_tcp.tcp.ack
= 1; } else { printf("\n Resetting the ACK
flag\n"); send_tcp.tcp.ack
= 0; } ans ='n'; printf("\n Do you want to set the
FIN Flag (y/n)?:"); getchar(); ans = getchar(); if(ans =='y' || ans == 'Y') { printf("\n
Setting the FIN flag\n"); send_tcp.tcp.fin
= 1; } else { printf("\n
Resetting the FIN flag\n"); send_tcp.tcp.fin
= 0; } ans ='n'; printf("\n Do you want to set the
RESET Flag (y/n)?:"); getchar(); ans = getchar(); if(ans =='y' || ans == 'Y') { printf("\n
Setting the RESET flag\n"); send_tcp.tcp.rst
= 1; } else { printf("\n Resetting the RESET
flag\n\n"); send_tcp.tcp.rst
= 0; } ans ='n'; /* form ip packet */ send_tcp.ip.ihl = 5; send_tcp.ip.version = 4; send_tcp.ip.tos = 0; send_tcp.ip.tot_len = htons(40); send_tcp.ip.id = getpid(); send_tcp.ip.frag_off = 0; send_tcp.ip.ttl = 255; send_tcp.ip.protocol = IPPROTO_TCP; send_tcp.ip.check = 0; send_tcp.ip.saddr = source_addr; send_tcp.ip.daddr = dest_addr; /* form tcp packet */ send_tcp.tcp.source = htons(srcport); send_tcp.tcp.dest =
htons(dest_port); send_tcp.tcp.seq = htonl(send_tcp.tcp.seq); send_tcp.tcp.ack_seq = htonl(send_tcp.tcp.ack_seq); send_tcp.tcp.res1 = 0; send_tcp.tcp.doff = 5; send_tcp.tcp.psh = 0; send_tcp.tcp.urg = 0; send_tcp.tcp.res2 = 0; send_tcp.tcp.window = htons(1024); send_tcp.tcp.check = 0; send_tcp.tcp.urg_ptr = 0; /* setup the sin struct */ sin.sin_family = AF_INET; sin.sin_port = send_tcp.tcp.source; sin.sin_addr.s_addr =
send_tcp.ip.daddr; /* (try to) open the socket */ tcp_socket = socket(AF_INET, SOCK_RAW,
IPPROTO_RAW); if(tcp_socket < 0) { perror("socket"); exit(1); } /* calculate the ip checksum */ send_tcp.ip.check = in_cksum((unsigned
short *)&send_tcp.ip, 20); /* set the pseudo header fields */ pseudo_header.source_address =
send_tcp.ip.saddr; pseudo_header.dest_address =
send_tcp.ip.daddr; pseudo_header.placeholder = 0; pseudo_header.protocol = IPPROTO_TCP; pseudo_header.tcp_length = htons(20); bcopy((char *)&send_tcp.tcp, (char
*)&pseudo_header.tcp, 20); send_tcp.tcp.check = in_cksum((unsigned
short *)&pseudo_header, 32); sinlen = sizeof(sin); printf("\n Hit a key to
continue"); getchar(); getchar(); sendto(tcp_socket, &send_tcp,
sizeof(send_tcp), 0, (struct sockaddr *)&sin, sinlen); printf("\n***** Sent TCP packet
*****\n"); getchar(); printf("\n Hit any key to
terminate!\n"); getchar(); close(tcp_socket); } // finds the TCP checksum unsigned
short in_cksum(unsigned short *ptr, int nbytes) { register long sum; /* assumes long == 32 bits */ u_short oddbyte; register u_short answer; /* assumes u_short == 16 bits */ /* * Our algorithm is simple, using a
32-bit accumulator (sum), * we add sequential 16-bit words to
it, and at the end, fold back * all the carry bits from the top
16 bits into the lower 16 bits. */ sum = 0; while (nbytes > 1) { sum += *ptr++; nbytes -= 2; } /* mop up an odd byte, if necessary */ if (nbytes == 1) { oddbyte = 0; /* make sure top half is zero */ *((u_char *) &oddbyte) =
*(u_char *)ptr; /* one byte only */ sum += oddbyte; } /* * Add back carry outs from top 16
bits to low 16 bits. */ sum
= (sum >> 16) + (sum & 0xffff); /* add high-16 to low-16 */ sum += (sum >> 16); /* add carry */ answer = ~sum; /* ones-complement, then truncate
to 16 bits */ return(answer); } //
converts the char string IP address to valid internet address unsigned
int host2ip(char *hostname) { static struct in_addr i; struct hostent *h; i.s_addr = inet_addr(hostname); if(i.s_addr == -1) { h = gethostbyname(hostname); if(h == NULL) { fprintf(stderr, "cant find
%s!\n", hostname); exit(0); } bcopy(h->h_addr, (char
*)&i.s_addr, h->h_length); } return i.s_addr; } |