Altenate simple Client program

Hello!Thanks for your time reading this.I was doing a Client/Server app programming
the server had following routines:

1
2
3
4
socket();
bind();
listen();
connect();


client:

1
2
socket();
connect();


Using Wireshark 5 packets where sniffed:
Then I wanted to make my own client to trigger the same number of packets as before

my program is like:
1
2
3
4
5
socket(PF_INET,SOCK_RAW,IPPROTO_TCP);
setsockopt();//tell the kernel not to bother about inserting its ip header
CreateIPHeader();
CreateTCPHeader();//with SYN flag set
sendto();//with  address and port of my server 

After running the program several times the server doesn't send back SYN-ACK packet.

My platform is:Ubuntu Jaunty 9.04 kernel v2.6.28
Thanks!
I assume you are checking the return codes from these functions? If so, what errors are you getting?
Here is the source code u can run it yourself:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include<stdio.h>
#include<sys/socket.h>
#include<stdlib.h>
#include<features.h>
#include<linux/if_packet.h>
#include<linux/if_ether.h>
#include<errno.h>
#include<sys/ioctl.h>
#include<net/if.h>
#include<net/ethernet.h>
#include<linux/ip.h>
#include<linux/tcp.h>
#include<string.h>
#include<arpa/inet.h>
#include<sys/time.h>
unsigned short		
checksum (unsigned short *buf, int nwords)
{
  unsigned long sum;
  for (sum = 0; nwords > 0; nwords--)
    sum += *buf++;
  sum = (sum >> 16) + (sum & 0xffff);
  sum += (sum >> 16);
  return ~sum;
}
#define P 80
int 
main (void)
{
  int s = socket (PF_INET, SOCK_RAW,IPPROTO_TCP);	/* open raw socket */
 unsigned char*packet;	
  struct iphdr *iph = (struct iphdr *) malloc(20);
  struct tcphdr *tcph = (struct tcphdr *) malloc(20);
  packet=(unsigned char*)malloc(sizeof(iph)+sizeof(tcph)+sizeof(struct ethhdr));

  struct sockaddr_in sin;
		

  sin.sin_family = PF_INET;
  sin.sin_port = htons (P);
  sin.sin_addr.s_addr = inet_addr ("1.1.1.1");
  memset(&sin.sin_zero,'\0',8);
    int one = 1;
    const int *val = &one;
    if (setsockopt (s, IPPROTO_IP, IP_HDRINCL, val, sizeof (one)) < 0)
    perror("Warning: Cannot set HDRINCL!\n");
  
  iph->ihl = 5;
  iph->version = 4;
  iph->tos = 0;
  iph->tot_len = htons(sizeof (struct iphdr) + sizeof (struct tcphdr));	
  iph->id = htonl (54321);	
  iph->frag_off = 0;
  iph->ttl = 255;
  iph->protocol =IPPROTO_TCP;
  iph->check = 0;		
  iph->saddr = inet_addr ("1.1.1.2");//address of my client pc
  iph->daddr = sin.sin_addr.s_addr;

  /*TCP Header*/
  tcph->source = htons (12983);
  tcph->dest = htons (P);
  tcph->seq = random ();
  tcph->ack = 0;
  tcph->res1 = 0;
  tcph->doff = 5;		
  tcph->syn =1;	/* initial connection request */
  tcph->window= htonl (65535);	
  tcph->check = 0;
  tcph->urg_ptr= 0;

  iph->check = checksum ((unsigned short *) packet, ntohs(iph->tot_len)>> 1);
  memcpy(packet,iph,20);
  memcpy((packet+20),tcph,20);
  while (1)
    { 
      if (sendto (s,		/* our socket */
		  packet,	
		 40,	
		  0,		
		  (struct sockaddr *) &sin,	
		  sizeof (sin)) < 0)		
	perror ("sendto()\n");
      else
	printf ("Sent!");
	sleep(2);
    }
free(iph);
free(tcph);
free(packet);
  return 0;
}


Am trying to trigger the same effect as if it was a normal socket() and connect() procedures of normal client app.
I don't know why it's not working and I don't have access to Linux these days. But I do have some general comments:
1. You don't fill in the ethernet frame.

2. You use the structure sizes in places and your magic numbers in others. The numbers (20 for ip and tcp record sizes are correct, but still... it's a bit sloppy):
1
2
3
4
5
6
struct iphdr *iph = (struct iphdr *) malloc(20);
struct tcphdr *tcph = (struct tcphdr *) malloc(20);
packet=(unsigned char*)malloc(sizeof(iph)+sizeof(tcph)+sizeof(struct ethhdr));
//...
memcpy(packet,iph,20);
memcpy((packet+20),tcph,20);


3. Is the sendto call correct?
sendto(s, packet, 40, 0, (struct sockaddr*)&sin, sizeof(sin))

Check this out: http://www.security-freak.net/packet-injection/packet-injection.html
The ethernet frame is filled automatically,yes about the numbers its standard javascript:editbox1.editTag('code')that the ip header without options is 20 bytes ,its ok if i even use sizeof(struct iphdr);still i got the same problem?Have u happened to do what am trying to do?

Have you checked what's been sent by both sides on the wire? You need to confirm why the 3-way handshake isn't being completed.
Topic archived. No new replies allowed.