Results 1 to 3 of 3
I'm using the following function to create a tcp SYN packet and send it. Im expecting an RST from the destination :
the tcp packet has 20bytes tcpheader, 44 bytes ...
- 03-24-2006 #1Just Joined!
- Join Date
- Feb 2006
- Posts
- 11
Help needed: constructing TCP SYN packet
I'm using the following function to create a tcp SYN packet and send it. Im expecting an RST from the destination :
the tcp packet has 20bytes tcpheader, 44 bytes data. (total 64 bytes )
main()
{
.....
s = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
.....
....
send_packet();
recvfrom(s, ...);
...
}
void send_packet()
{
u_char outpack[PING_MAXPACKET];
bzero(outpack,PING_MAXPACKET);
struct tcphdr *tcph = (struct tcphdr*)outpack;
tcph->source = htons(MYPORT);
tcph->dest = htons(THEIRPORT);
tcph->seq = htonl(seqno);
tcph->ack_seq = 0;
*((u_int8_t*)(outpack+12)) = 80; //to set the data offset to 5 (20 bytes)
*((u_int8_t*)(outpack+13)) = 2; // to set SYN flag
//tcph->window = 1000;
tcph->check = in_cksum(tcph,64);
int i = sendto( s, outpack, 64, 0, &whereto, sizeof(struct sockaddr) );
// struct sockaddr whereto is filled with destination IP,port
}
I did not receive TCP RST from dest IP. Ethereal shows an error in the checksum. I used the checksum function used in ping program:
in_cksum(u_short *addr, int len)
{
u_short *w = addr;
int sum = 0;
for (sum = 0; len > 0; len--)
sum += *w++;
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
return ~sum;
}
Please correct me where I went wrong. Include code if possible. Iam running it on Fedora Core 3 (kernel 2.4.20-8 )
Thanx
- 04-22-2006 #2Just Joined!
- Join Date
- Apr 2006
- Posts
- 5
I think when u r sending ur syn packet better use struct sockaddr_ll structure in the destination field( as u are using raw socket ).also use the size of that structure.
struct sockaddr_ll toaddr;
sendto(sock,packet_to_send,sizeof(packet),0,(strcu t sockaddr*)&toaddr,sizeof(struct sockaddr_ll));
i think this should work.
if it works then plz tell me.
- 04-23-2006 #3Just Joined!
- Join Date
- Feb 2006
- Posts
- 11
Thanx for the reply, hex.
Actually I came to know where I went wrong (see the tcp_cksum function comments):
#define DATASIZE 12
/* this function calculates the TCP-checksum with its pseudo-header */
u_short tcp_cksum(struct iphdr *ip, struct tcphdr *tcp)
{
char header[100], *p = header; // header size shud be enuf to acomdate pseudo+actual hdrs,data
/* the pseudo-header includes the source-address, the destination-
* * address (each 32 bit), 8 bit set to zero, 8 bit with the protocol
* * and 16 bit with the TCP-packet's length. The rest of the header
* * is the 'real' TCP-header.
* */
*(unsigned long*)p = ip->saddr;
p += 4;
*(unsigned long*)p = ip->daddr;
p += 4;
*p = 0;
p++;
*p = ip->protocol;
p++;
//*(unsigned short*)p = htons(4 * tcp->doff); THIS IS WHERE I WENT WRONG. I forgot to include the data size
*(unsigned short*)p = htons(4 * tcp->doff +DATASIZE); // 20 tcphdr bytes + 12 data bytes
p += 2;
//memcpy(p, tcp, 4 * tcp->doff);
memcpy(p, tcp, 4 * tcp->doff +DATASIZE);
//return in_cksum((unsigned short*)header, 32);
return in_cksum((unsigned short*)header, 32+DATASIZE); // 12 pseudo hdr + 20 tcphdr + 12 data bytes
}
I also included code to create the SYN packet, in case som1 else needs it
/* this function sends the SYN-packets out to the net */
int do_scan(int s, unsigned long src, unsigned long dst,
unsigned short lo, unsigned short hi)
{
struct iphdr *ip;
struct tcphdr *tcp;
char packet[sizeof(*ip) + sizeof(*tcp)+ DATASIZE]; // header + 12 data bytes
struct sockaddr_in to;
unsigned short i;
ip = (struct iphdr*) packet;
tcp = (struct tcphdr*) (packet + sizeof(*ip));
memset(packet, 0, sizeof(packet));
ip->ihl = 5;
ip->version = 4;
ip->tot_len = htons(sizeof(packet));
ip->ttl = 64;
ip->protocol = IPPROTO_TCP;
ip->saddr = src;
ip->daddr = dst;
ip->check = in_cksum((unsigned short*)ip, sizeof(*ip));
to.sin_addr.s_addr = dst;
to.sin_family = AF_INET;
to.sin_port = 0; /* filled later */
tcp->doff = 5;
tcp->source = htons(1024);
tcp->seq = rand();
tcp->syn = 1;
tcp->window = htons(1024);
for(i = lo; i <= hi; i++)
{
usleep(USLEEP_MS);
tcp->dest = htons(i);
tcp->check = 0;
tcp->check = tcp_cksum(ip, tcp);
//tcp->check = 0;
if (sendto(s, packet, sizeof(packet), 0,
(struct sockaddr*)&to, sizeof(to)) == -1)
{
perror("sendto() failed");
return 1;
}
}
close(s);
return 0;
}


Reply With Quote