i'm working on a TCP IP project right now.
And i got a problem with my code for sending a TCP SYN packet.
The code supposed to be generate a TCP SYN packet and send it to a receiver. but the TCP SYN seems to be not valid because the receiver didn't response it, just ignore it.
So, would anybody please help me find the missing thing in my code below.
Or anybody can give me an example code of building and sending a valid TCP SYN packet please ...
thanks in advance ..
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/in_systm.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#define error -1
#define srcip "10.20.10.19"
#define dstip "10.20.10.55"
#define sport 1111
#define dport 23
#include "/root/LoadBalancer/loadblc.h"
__u16 cksum(__u16 *buf, int nbytes)
{
__u32 sum;
__u16 oddbyte;
sum = 0;
while (nbytes > 1) {
sum += *buf++;
nbytes -= 2;
}
if (nbytes == 1) {
oddbyte = 0;
*((__u16 *) &oddbyte) = *(__u8 *) buf;
sum += oddbyte;
}
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
return (__u16) ~sum;
}
main() {
struct iphdr *iphdr;
//struct tcphdr *tcp;
struct TCPhdr *tcp;
u_char packet[sizeof(struct iphdr) + sizeof(struct TCPhdr)+ 14];
//u_char *packet;
struct sockaddr_in target;
struct in_addr saddr, daddr;
int sock, on = 1;
char *payload;
/*===[ unsnip ]==========================================
Here we open a socket. We have to provide a domain, which is AF_INET, the
type of socket this is, which is a raw socket, and the protocol, which is
a raw protocol. We also have error checking. You should always have it.
It's very useful.
*/
if ((sock = socket(AF_INET,SOCK_RAW,IPPROTO_RAW)) == error) {
printf("socket error\n"
exit(1);
}
/*===[ unsnip ]==========================================
Now we set the socket options, setsockopt. We use the option IP_HDRINCL.
This allows us to create our own ip header. If you don't have this option
on your system then you can't spoof packets .
*/
if (setsockopt(sock,IPPROTO_IP,IP_HDRINCL,&on,sizeof(on)) == error) {
printf("setsockopt error\n"
exit(1);
}
/*===[ unsnip ]==========================================
Here we just make the ip and tcp headers equal to their structures and the
packet. Then we zero them out.
*/
iphdr = (struct iphdr *) (packet);
tcp = (struct TCPhdr *) (packet + sizeof(struct iphdr));
payload = (char *) (packet + sizeof(struct iphdr) + sizeof(struct TCPhdr));
memset((char *)iphdr,'\0',sizeof(struct iphdr));
memset((char *)tcp,'\0',sizeof(struct TCPhdr));
/*===[ unsnip ]==========================================
Now we make the saddr.s_addr equal too the srcip defined earlier in the
code. And I do the same for the destionation ip address.
*/
saddr.s_addr = inet_addr(srcip);
daddr.s_addr = inet_addr(dstip);
/*===[ unsnip ]==========================================
Finally we get to the good part, creating the packet. This is mainly self
explained. Look at 3.2 The Header Fields for explaination.
*/
iphdr->ihl = 20;
iphdr->version = 4;
iphdr->tot_len = htons(sizeof (struct iphdr));
iphdr->id = 1234;
iphdr->ttl = 250;
iphdr->frag_off |= htons((unsigned short) 0x2000);
iphdr->frag_off |= htons((0x2000) >> 3);
iphdr->protocol = 6;
iphdr->saddr = saddr.s_addr;
iphdr->daddr = daddr.s_addr;
iphdr->check = 0;
int data_size = 20;
int packet_size;
int tcp_opt_size = 0;
packet_size = TCPHDR_SIZE + tcp_opt_size + data_size;
/*tcp->dest = htons(dport);
tcp->seq = 12345; //htonl(rand());
tcp->ack_seq = 0;
tcp->res1 = 0;
tcp->doff = 5;
tcp->window = 512;
tcp->syn = 1; */
tcp->th_sport = htons(sport);
tcp->th_dport = htons(dport);
tcp->th_seq = 12345;
tcp->th_ack = 0;
tcp->th_flags = 0x2;
tcp->th_win = 512;
tcp->th_sum = cksum((u_short*) packet, PSEUDOHDR_SIZE + packet_size);
payload[0] = 0x2;
payload[1] = 0x4;
payload[2] = 0x5;
payload[3] = 0xb3;
payload[4] = 0x1;
payload[5] = 0x1;
payload[6] = 0x4;
payload[7] = 0x2;
payload[8] = 0x0;
/*===[ unsnip ]==========================================
First we zero out our target. Then we define our sin family, port, and
address.
*/
memset(&target,'\0',sizeof(target));
target.sin_family = AF_INET;
target.sin_port = htons(dport);
target.sin_addr = daddr;
/*===[ unsnip ]==========================================
Now we finally get to send the packet. So we simply use the sendto()
funtion to send it out.
*/
printf("sending packet: \n"
if (sendto(sock,&packet,sizeof(packet),0x0,(struct sockaddr *)&target,
sizeof(target)) != sizeof(packet)) {
printf("packet wasn't sent\n"
exit(1);
} else {
printf("packet sent\n"
}
exit(0);
}
And i got a problem with my code for sending a TCP SYN packet.
The code supposed to be generate a TCP SYN packet and send it to a receiver. but the TCP SYN seems to be not valid because the receiver didn't response it, just ignore it.
So, would anybody please help me find the missing thing in my code below.
Or anybody can give me an example code of building and sending a valid TCP SYN packet please ...
thanks in advance ..
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/in_systm.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#define error -1
#define srcip "10.20.10.19"
#define dstip "10.20.10.55"
#define sport 1111
#define dport 23
#include "/root/LoadBalancer/loadblc.h"
__u16 cksum(__u16 *buf, int nbytes)
{
__u32 sum;
__u16 oddbyte;
sum = 0;
while (nbytes > 1) {
sum += *buf++;
nbytes -= 2;
}
if (nbytes == 1) {
oddbyte = 0;
*((__u16 *) &oddbyte) = *(__u8 *) buf;
sum += oddbyte;
}
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
return (__u16) ~sum;
}
main() {
struct iphdr *iphdr;
//struct tcphdr *tcp;
struct TCPhdr *tcp;
u_char packet[sizeof(struct iphdr) + sizeof(struct TCPhdr)+ 14];
//u_char *packet;
struct sockaddr_in target;
struct in_addr saddr, daddr;
int sock, on = 1;
char *payload;
/*===[ unsnip ]==========================================
Here we open a socket. We have to provide a domain, which is AF_INET, the
type of socket this is, which is a raw socket, and the protocol, which is
a raw protocol. We also have error checking. You should always have it.
It's very useful.
*/
if ((sock = socket(AF_INET,SOCK_RAW,IPPROTO_RAW)) == error) {
printf("socket error\n"
exit(1);
}
/*===[ unsnip ]==========================================
Now we set the socket options, setsockopt. We use the option IP_HDRINCL.
This allows us to create our own ip header. If you don't have this option
on your system then you can't spoof packets .
*/
if (setsockopt(sock,IPPROTO_IP,IP_HDRINCL,&on,sizeof(on)) == error) {
printf("setsockopt error\n"
exit(1);
}
/*===[ unsnip ]==========================================
Here we just make the ip and tcp headers equal to their structures and the
packet. Then we zero them out.
*/
iphdr = (struct iphdr *) (packet);
tcp = (struct TCPhdr *) (packet + sizeof(struct iphdr));
payload = (char *) (packet + sizeof(struct iphdr) + sizeof(struct TCPhdr));
memset((char *)iphdr,'\0',sizeof(struct iphdr));
memset((char *)tcp,'\0',sizeof(struct TCPhdr));
/*===[ unsnip ]==========================================
Now we make the saddr.s_addr equal too the srcip defined earlier in the
code. And I do the same for the destionation ip address.
*/
saddr.s_addr = inet_addr(srcip);
daddr.s_addr = inet_addr(dstip);
/*===[ unsnip ]==========================================
Finally we get to the good part, creating the packet. This is mainly self
explained. Look at 3.2 The Header Fields for explaination.
*/
iphdr->ihl = 20;
iphdr->version = 4;
iphdr->tot_len = htons(sizeof (struct iphdr));
iphdr->id = 1234;
iphdr->ttl = 250;
iphdr->frag_off |= htons((unsigned short) 0x2000);
iphdr->frag_off |= htons((0x2000) >> 3);
iphdr->protocol = 6;
iphdr->saddr = saddr.s_addr;
iphdr->daddr = daddr.s_addr;
iphdr->check = 0;
int data_size = 20;
int packet_size;
int tcp_opt_size = 0;
packet_size = TCPHDR_SIZE + tcp_opt_size + data_size;
/*tcp->dest = htons(dport);
tcp->seq = 12345; //htonl(rand());
tcp->ack_seq = 0;
tcp->res1 = 0;
tcp->doff = 5;
tcp->window = 512;
tcp->syn = 1; */
tcp->th_sport = htons(sport);
tcp->th_dport = htons(dport);
tcp->th_seq = 12345;
tcp->th_ack = 0;
tcp->th_flags = 0x2;
tcp->th_win = 512;
tcp->th_sum = cksum((u_short*) packet, PSEUDOHDR_SIZE + packet_size);
payload[0] = 0x2;
payload[1] = 0x4;
payload[2] = 0x5;
payload[3] = 0xb3;
payload[4] = 0x1;
payload[5] = 0x1;
payload[6] = 0x4;
payload[7] = 0x2;
payload[8] = 0x0;
/*===[ unsnip ]==========================================
First we zero out our target. Then we define our sin family, port, and
address.
*/
memset(&target,'\0',sizeof(target));
target.sin_family = AF_INET;
target.sin_port = htons(dport);
target.sin_addr = daddr;
/*===[ unsnip ]==========================================
Now we finally get to send the packet. So we simply use the sendto()
funtion to send it out.
*/
printf("sending packet: \n"
if (sendto(sock,&packet,sizeof(packet),0x0,(struct sockaddr *)&target,
sizeof(target)) != sizeof(packet)) {
printf("packet wasn't sent\n"
exit(1);
} else {
printf("packet sent\n"
}
exit(0);
}