#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <ctype.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/time.h>/* struct timeval */
#include <unistd.h>
#include <string.h>
#include <time.h>
#define MYPORT 7777
#define REMOTEPORT 5555
int readn(int, void *, int);
unsigned short in_cksum(unsigned short *ptr, int nbytes);
int main(int argc, char * argv[])
{
int sock,sent, rcvd;
struct sockaddr_in sin;
unsigned short local_port;
unsigned short remote_port;
unsigned char protocol;
char * buffer;
char * in_buffer;
//char data[1452];
char *remote_ip_str, *local_ip_str;
int semantics = 0;
unsigned short buffer_size = 0;
const int tmp=1;
struct iphdr *ip_header;
struct tcphdr *tcp_header;
struct pseudo_header {
unsigned int source_address;
unsigned int dest_address;
unsigned char placeholder;
unsigned char protocol;
unsigned short tcp_length;
struct tcphdr tcp;
} pseudo;
/* Following two fields are added for calculating the checksum */
protocol = IPPROTO_TCP;
semantics = SOCK_RAW;
remote_ip_str="REMOTE_IP";
local_ip_str="MY_IP";
local_port = MYPORT;
remote_port = REMOTEPORT;
if((sock = socket(PF_INET, semantics, protocol)) < 0) {
perror("socket");
exit(1);
}
bzero((char *)& sin, sizeof(sin));
sin.sin_port = htons(local_port);
if ((bind(sock, (struct sockaddr *)& sin, sizeof(sin))) < 0) {
perror("bind");
exit(1);
}
setsockopt(sock, 0, IP_HDRINCL, &tmp, sizeof(tmp));
bzero((char *)& sin, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(remote_port);
sin.sin_addr.s_addr = inet_addr(remote_ip_str);
buffer_size = sizeof(struct iphdr) + sizeof(struct tcphdr);
printf("buff %d\n", buffer_size);
srand(getpid());
buffer = (char *) malloc(buffer_size);
ip_header = (struct iphdr *) buffer;
ip_header->ihl = 5;
ip_header->version = 4;
ip_header->tos = 0;
ip_header->tot_len = htons(buffer_size);
ip_header->id = 0;
ip_header->ttl = 64;
ip_header->frag_off = 0x40;
ip_header->protocol = protocol;
ip_header->daddr = inet_addr(remote_ip_str);
ip_header->saddr = inet_addr(local_ip_str);
ip_header->check = in_cksum((unsigned short *)&ip_header, 20);
tcp_header=(struct tcphdr *)(buffer+sizeof(struct iphdr));
tcp_header->source = htons(local_port);
tcp_header->dest = htons(remote_port);
tcp_header->seq = rand()%time(NULL);
tcp_header->ack_seq = rand()%time(NULL);
tcp_header->res1 = 0;
tcp_header->window = htons(1000);
tcp_header->doff = 4;
tcp_header->syn = 1;
tcp_header->check = 0;
bzero(&pseudo, 12+sizeof(struct tcphdr));
pseudo.source_address = ip_header->saddr;
pseudo.dest_address = ip_header->daddr;
pseudo.placeholder = 0;
pseudo.protocol = IPPROTO_TCP;
pseudo.tcp_length = htons(sizeof( struct tcphdr));
bcopy((char *)tcp_header, (char *)&pseudo.tcp, sizeof(struct tcphdr));
tcp_header->check = in_cksum((unsigned short *)&pseudo,
12+ sizeof(struct tcphdr));
if((sent=sendto(sock, buffer, buffer_size, 0, (struct sockaddr *) &sin,
sizeof(sin))) < sizeof(buffer)) {
perror("sendto");
exit(1);
}
printf("Came here sent %d bytes \n",sent);
close(sock);
if((sock = socket(PF_INET, semantics, protocol)) < 0) {
perror("socket");
exit(1);
}
bzero((char *)& sin, sizeof(sin));
sin.sin_port = htons(local_port);
if ((bind(sock, (struct sockaddr *)& sin, sizeof(sin))) < 0) {
perror("bind");
exit(1);
}
return 0;
}
unsigned short in_cksum(u_short *buf, int nwords) {
unsigned long sum ;
u_short *w=buf;
for(sum=0; nwords > 0; nwords-=2)
sum += *w++;
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
return ~( sum & 0xffff ) ;
}