Getting an ACK for RAW SYN packet


 
Thread Tools Search this Thread
Top Forums Programming Getting an ACK for RAW SYN packet
# 8  
Old 05-18-2004
Thanks for the reply. Here is the complete code, with all the includes and accessory functions.

This code compiles on Linux machines on which I'm working.

I can't use struct tcphdr and iphdr, since I have to manipulate the options in the tcp header. That's the whole purpose of this struggle.

Thanks.

#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 <arpa/inet.h>
#include <netdb.h>
#include <sys/time.h>/* struct timeval */
#include <unistd.h>
#include <string.h>
#include <time.h>

typedef struct ip_header_t {
unsigned char ihl:4,
version:4;
unsigned char tos;
unsigned short tot_len;
unsigned short id;
unsigned short frag_off;
unsigned char ttl;
unsigned char protocol;
unsigned short check;
unsigned int saddr;
unsigned int daddr;
} * ip_header_t;

typedef struct tcp_header_t {
unsigned short source;
unsigned short dest;
unsigned int seq;
unsigned int ack_seq;
unsigned short res1:4,
doff:4,
fin:1,
syn:1,
rst:1,
psh:1,
ack:1,
urg:1,
ece:1,
cwr:1;
unsigned short window;
unsigned short check;
unsigned short urg_ptr;
} * tcp_header_t;

int readn(int, void *, int);

int main(int argc, char * argv[])
{
int sock,sent, temp, rcvd;
struct sockaddr_in sin;
unsigned short local_port;
unsigned short remote_port;
unsigned char protocol;
char * buffer;
//char data[1452];
ip_header_t ip_header;
tcp_header_t tcp_header;
char *remote_ip_str;
int semantics = 0;
unsigned short buffer_size = 0;
int tmp;

protocol = IPPROTO_TCP;
semantics = SOCK_RAW;

//data = (char *)calloc(1452, 1);
//printf( "Data is %d\n", sizeof(data));
remote_ip_str=DEST_IP_ADDR
local_port = 6666;
remote_port = 6666;

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);
}

tmp = 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 ip_header_t) + sizeof(struct tcp_header_t)
+ sizeof(data);
*/
buffer_size = sizeof(struct ip_header_t) + sizeof(struct tcp_header_t);
//buffer_size = sizeof (struct ip_header_t) + sizeof(data);

printf("buff %d\n", buffer_size);

srand(getpid());

buffer = (char *) malloc(buffer_size);

ip_header = (ip_header_t) 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->check = 0;
ip_header->daddr = inet_addr(remote_ip_str);
ip_header->saddr = 0;

tcp_header = (tcp_header_t) (ip_header + 1);

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->doff = 4;
tcp_header->syn = 1;
tcp_header->check = 0;

printf("SEQ is %u\n", tcp_header->seq);
if((sent=sendto(sock, buffer, buffer_size, 0, (struct sockaddr *) &sin,
sizeof(sin))) < buffer_size) {
perror("sendto");
exit(1);
}
printf("Came here sent %d bytes \n",sent);
if((rcvd = readn(sock, buffer, buffer_size)) < 0 ) {
fprintf(stderr, "nread error\n");
}
else
printf("Received %d bytes\n", rcvd);

close(sock);

return 0;
}

/* R E A D N
Reads N byted from the discriptor
*/

int readn(int fd, void *vptr, int n)
{
size_t nleft;
ssize_t nread;
char *ptr;

ptr = vptr;
nleft = n;
while (nleft > 0) {
printf( "Nleft is %d\n", nleft);
if ((nread = read(fd, ptr, nleft)) < 0) {
if (errno == EINTR)
nread = 0; /* and call read() again */
else
return(-1);
} else if (nread == 0)
break; /* EOF */

nleft -= nread;
ptr += nread;
}
return(n - nleft); /* return >= 0 */
}
# 9  
Old 05-18-2004
Computer

/* tcp_header->check = 0; */
While working on it very long time ago, i found out i cannot let the kernel compute tcp checksum for me... at least on a k2.0 series :-)

Make sure you have the correct checksum in tcp hdr that is compute it yourself, You will have to create a pseudo-header only for that puspose

I'm looking for my old archives and i'll post the checksum portion if you want

BTW, trying to implement a DoS or man-in-the-middle attack ??? :-)
# 10  
Old 05-18-2004
Andryk, thanks for your reply.

Please post the checksum portion of the pseudo header.

Haha, I'm not trying to implement anything like DoS or Man-in-the-middle, but if happens accidenly, I won't mind Smilie.

Thanks.
# 11  
Old 05-19-2004
Here it is, the trick is to correctly build the pseudo hdr (struct cksum) and then run the cksum algo. on it.
I ran my test on loopback as there are less output ...
-------------------------------------------
struct cksum {
unsigned int src_addr; /* source from ip hdr */
unsigned int dst_addr; /* dest from ip hdr */
unsigned char placeholder; /* this is for memory displacement */
unsigned char protocol;
unsigned short pr_length;

struct tcphdr tcp;

char buf[4096]; /* Any size your packet data needs */
};

-----------------------------------------------------
...
char *pkt; /* ptr to begin of packet buffer */
struct iphdr *ip;
struct tcphdr *tcp;
char *dta;

struct cksum _cksum;
unsigned short cksum = 0;

ip = (struct iphdr *)pkt;
tcp = (struct tcphdr *)(pkt + (ip->ihl << 2));

/* building pseudo header */
bzero( (char *)&_cksum, sizeof(struct cksum) );
_cksum.src_addr = ip->saddr;
_cksum.dst_addr = ip->daddr;
_cksum.protocol = IPPROTO_TCP;
_cksum.pr_length = htons( ntohs(ip->tot_len) - (ip->ihl<<2) );
tcp->check = 0;
bcopy( tcp, &_cksum.tcp, 20 ); /* sizeof tcp hdr */

/* Any data following tcp hdr to be checksummed */
dta = (char *) (pkt + (ip->ihl<<2) + (tcp->doff<<2) );
bcopy( dta, _cksum.buf, ntohs(ip->tot_len) - (ip->ihl<<2) - (tcp->doff<<2) );

/* compute 16-bits tcp checksum */
cksum = in_cksum( (unsigned short *)&_cksum, 12 + ntohs(ip->tot_len) - (ip->ihl<<2) );
return cksum;
...
------------------------------------------------------
unsigned short in_cksum( unsigned short *addr, int len ) {
int nleft = len;
int sum = 0; /* 32-bit */

unsigned short *w = addr;
unsigned short answer = 0; /* 16-bit */

/* Our algorithm is simple, using 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.
*/

while(nleft > 1) {
sum += *w++;
nleft -= 2;
}

/* mop up an odd byte, if necessary */
if (nleft == 1) {
*(unsigned char *) (&answer) = *(unsigned char *) w;
sum += answer;
}
/* add back carry outs from top 16 bits to low 16 bits */

sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
sum += (sum >> 16); /* add carry */
answer = ~sum; /* truncate to 16 bits */
return (answer);
}
# 12  
Old 05-19-2004
Can you tell me what's the problem in this code of mine. I have used your checksum code. I'm not entirely sure, if it's correct or not.

Thanks.

#include<stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <netdb.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#define MYPORT 6666

typedef struct ip_header_t {
unsigned char ihl:4,
version:4;
unsigned char tos;
unsigned short tot_len;
unsigned short id;
unsigned short frag_off;
unsigned char ttl;
unsigned char protocol;
unsigned short check;
unsigned int saddr;
unsigned int daddr;
} *iphdr;

typedef struct tcp_header_t {
unsigned short source;
unsigned short dest;
unsigned int seq;
unsigned int ack_seq;
unsigned short res1:4,
doff:4,
fin:1,
syn:1,
rst:1,
psh:1,
ack:1,
urg:1,
ece:1,
cwr:1;
unsigned short window;
unsigned short check;
unsigned short urg_ptr;
} *tcphdr;

struct pseudo {
u_long saddr;
u_long daddr;
u_char zero;
u_char protocol;
u_short length;

struct tcp_header_t tcp;
};

/* Calculate the checksum here */
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);
}

int sendpack( int s, u_long srcaddr, u_short srcport, u_long dstaddr, u_short dstport, u_long length)
{
int one=1;
unsigned short local_port, remote_port;
u_char packet[sizeof(struct ip_header_t)
+ sizeof(struct pseudo) + sizeof(struct tcp_header_t)];
struct sockaddr_in foo;
struct in_addr srcinaddr,dstinaddr;
iphdr ip = (iphdr) packet;
struct pseudo *pseudo = (struct pseudo *)(packet+ sizeof(struct ip_header_t)
+sizeof(struct tcp_header_t));
//tcphdr tcp = (tcphdr) (packet + sizeof(struct ip_header_t)
// + sizeof(struct pseudo));
tcphdr tcp;
//bzero((char *)&pseudo, sizeof(struct pseudo));
bzero(packet, sizeof(packet));

foo.sin_port = htons(srcport);

/* I have to bind the RAW socket to a local port. It's required here */
if ((bind(s, (struct sockaddr *)& foo, sizeof(foo))) < 0) {
perror("bind");
exit(1);
}

setsockopt(s, 0, IP_HDRINCL, &one, sizeof(one));

bzero((char *)&foo,sizeof(foo));
foo.sin_family = AF_INET;
foo.sin_port = htons(remote_port);
foo.sin_addr.s_addr=dstaddr;

/* building packets */
ip->ihl = 5;
ip->version = 4;
ip->tos = 0;
ip->tot_len = htons(sizeof(struct ip_header_t)+sizeof(struct tcp_header_t));
ip->id = 0;
ip->ttl = 64;
ip->frag_off = 0x40;
ip->protocol = IPPROTO_TCP;
ip->check = in_cksum( (u_short *)ip, sizeof( struct ip_header_t));
ip->daddr = dstaddr;
ip->saddr = srcaddr;

pseudo->saddr = srcaddr;
pseudo->daddr = dstaddr;
pseudo->zero = 0;
pseudo->protocol = IPPROTO_TCP;
pseudo->length = htons(ntohs(ip->tot_len)-(ip->ihl<<2));

tcp = (tcphdr) (packet + (ip->ihl << 2));
tcp->source = htons(local_port);
tcp->dest = htons(remote_port);
tcp->seq = rand()%time(NULL);
tcp->ack_seq = rand()%time(NULL);
tcp->res1 = 0;
tcp->doff = 4;
tcp->syn = 1;
tcp->check = 0;

bcopy(tcp, &pseudo->tcp, sizeof(struct tcp_header_t));
tcp->check = in_cksum((unsigned short *)&pseudo,
12 + sizeof(struct tcp_header_t));
if((sendto(s, packet, sizeof(packet), 0,
(struct sockaddr *) &foo,sizeof(foo))) < sizeof(packet)) {
perror("sendto");
exit(1);
}
printf("Sent packet of size %d\n", sizeof(packet));

return 0;
}

u_long resolve_name(char *hostname) {
struct hostent *host;
u_long addr;
if ((addr = inet_addr(hostname)) != -1) return addr;
if ((host = gethostbyname(hostname)) == NULL) {
fprintf(stderr,"Can not resolve name: %s\n",hostname);
exit(1);
}
bcopy(host->h_addr,&addr,host->h_length);
return addr;
}
int main(argc,argv)
int argc;
char **argv;
{
int rawfd;
int one=1;
struct in_addr srcip,dstip;
u_short srcport,dstport;

srcip.s_addr=resolve_name("source name");
srcport=MYPORT;
dstip.s_addr=resolve_name("dest name");
dstport=MYPORT;

if ((rawfd=socket(PF_INET,SOCK_RAW,IPPROTO_TCP))<0) {
perror("RawSocket:");
exit(1);
}

if (setsockopt(rawfd,IPPROTO_IP,IP_HDRINCL,&one,sizeof(one))<0) {
perror("SetSockOpt:");
close(rawfd);
exit(1);
}

printf("sending packet from: %s:%i ",inet_ntoa(srcip),srcport);
printf("to %s:%i\n",inet_ntoa(dstip),dstport);
sendpack(rawfd,srcip.s_addr,srcport,dstip.s_addr,dstport,0);

close(rawfd);
return 0;
}
# 13  
Old 05-19-2004
Shouldn't you fill in the src/dst addresses of your iphdr BEFORE calculating its checksum?
# 14  
Old 05-19-2004
Even after that, the problem remains.
Login or Register to Ask a Question

Previous Thread | Next Thread

7 More Discussions You Might Find Interesting

1. AIX

Packet loss coming with big packet size ping

(5 Replies)
Discussion started by: Vishal_dba
5 Replies

2. Programming

Raw Socket Programming - Efficient Packet Sniffer

Hi, I have the requirement to sniff packets from the Ethernet card on my Linux machine and process it and feed it to a RANAP protocol stack. So far I have written the raw packet sniffer and successfully sniffing packets and do little processing. However, for huge number of packets ... (9 Replies)
Discussion started by: rstnsrr
9 Replies

3. IP Networking

TCP Same Ack Sequencing for Two Packets

I was analyzing a TCP snoop. And found following scenario From Server to Client ---> SEQ 2993 ACK 1744 WIN 8192 LEN 13 From Server to Client ---> SEQ 3006 ACK 1744 WIN 8192 LEN 13 From Client to server --> SEQ 1744 ACK 3019 WIN 3304 I just want to know Why Packet 1 and 2... (3 Replies)
Discussion started by: mr_deb
3 Replies

4. UNIX for Dummies Questions & Answers

plug in for syn on

I am using vim version 7.1.314.It don't have syn on.Is there any plug in available for syn on or I have to update the version. (2 Replies)
Discussion started by: karthigayan
2 Replies

5. UNIX for Advanced & Expert Users

What is FIN/ACK/SYN

Please tell me details about terms FIN, ACK, SYN, RST; used in TCP based communication. Also tell me any RFC or other document which tell me details about these terms. (1 Reply)
Discussion started by: mansoorulhaq
1 Replies

6. Shell Programming and Scripting

syn

suppose I have data in a log file in the below format date|time|name|email|address|SSN date|time|name|email|address|SSN date|time|name|email|address|SSN is it possible to create a search engine which takes input as three filters out of which two filters should be optional? say i give... (4 Replies)
Discussion started by: wannalearn
4 Replies

7. UNIX for Dummies Questions & Answers

ACK! Help! What do I do?

Hiya folks, I am a windows xp home user and for awhile I have been thinking about changing my OS, the only problem is that I don't know where to start. Is it called Unix or Linux? Are they the same thing? It's really confusing. I would really appreaciate some help on this. I have looked all... (1 Reply)
Discussion started by: Mr_Pinky
1 Replies
Login or Register to Ask a Question