Newsgroup: it.comp.os.linux.development
Titolo: send tcp raw socket (bogus tcp header length)

Hi,
I don't know if I post my request in the correct group.
I try to send a packet with raw socket from a program wrote with c 
langage and compiled on linux os (kernel : 2.4.27-1-386) but I have an 
error with ethereal sniffer on windows xp.
I can't find any solution on the net.   :(     Could anybody help with 
that problem?
my code :
#define __USE_BSD
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#define __FAVOR_BSD
#include <netinet/tcp.h>
#include <unistd.h>
#include <ncurses.h>
#include <stdlib.h>
#include <string.h>
unsigned short        /* this function generates header checksums */
csum (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;
}
int main (int argc, char *argv[]){
if(argc < 5){
printf("Usage : %s <srcIP> <destIP> <destPORT> <nbDatagram>\n",argv[0]);
printf("Example : %s 192.168.0.140 192.168.0.146 445 5\n",argv[0]);
return -1;
}
char datagram[4096];
struct ip *iph = (struct ip *) datagram;
struct tcphdr *tcph = (struct tcphdr *) datagram + sizeof (struct ip);
struct sockaddr_in sin;
memset (datagram, 0, 4096);    /* zero out the buffer */
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = inet_addr (argv[2]);
sin.sin_port = htons (atoi(argv[3]));
/* we'll now fill in the ip/tcp header values */
   iph->ip_hl = 5;
   iph->ip_v = IPPROTO_IPIP;
   iph->ip_tos = 0;
   iph->ip_len = sizeof (struct ip) + sizeof (struct tcphdr);
   iph->ip_id = htonl (random());
   iph->ip_off = 0;
   iph->ip_ttl = 255;
   iph->ip_p = IPPROTO_TCP;
   iph->ip_sum = 0;
   iph->ip_src.s_addr = inet_addr (argv[1]);
   iph->ip_dst.s_addr = sin.sin_addr.s_addr;
   tcph->th_sport = htons (random());
   tcph->th_dport = sin.sin_port;
   tcph->th_seq = random ();
   tcph->th_ack = 0;
   tcph->th_x2 = 0;
   tcph->th_off = 0; (I tried with tcph->th_off = 5; too)
   tcph->th_flags = TH_SYN;
   tcph->th_win = htonl (65535);
   tcph->th_sum = 0;
   tcph->th_urp = 0;
   iph->ip_sum = csum ((unsigned short *) datagram, iph->ip_len >> 1);
int s = socket (PF_INET, SOCK_RAW, IPPROTO_TCP);    /* open raw socket */
int one = 1;
const int *val = &one;
if (setsockopt (s, IPPROTO_IP, IP_HDRINCL, val, sizeof (one)) < 0)
       printf ("Warning: Cannot set HDRINCL!\n");
int loop = 0;
while (loop<atoi(argv[4]))
{
   loop++;
   if (sendto (s,        /* our socket */
                datagram,    /* the buffer containing headers and data */
          iph->ip_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 ("error\n");
    else
     printf (".");
}
return 0;
}
And This is the ethereal's response :
No.     Time        Source                Destination           Protocol 
Info
       1 0.000000    192.168.0.140         192.168.0.146         TCP   0 
 > 0 [] Seq=0 Ack=0 Win=0, bogus TCP header length (0, must be at least 20)
Frame 1 (60 bytes on wire, 60 bytes captured)
Ethernet II, Src: 3com_b6:d6:29 (00:50:da:b6:d6:29), Dst: 
DellComp_d5:be:c6 (00:b0:d0:d5:be:c6)
Internet Protocol, Src: 192.168.0.140 (192.168.0.140), Dst: 
192.168.0.146 (192.168.0.146)
     Version: 4
     Header length: 20 bytes
     Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00)
     Total Length: 40
     Identification: 0x0000 (0)
     Flags: 0x04 (Don't Fragment)
     Fragment offset: 0
     Time to live: 255
     Protocol: TCP (0x06)
     Header checksum: 0xf960 [correct]
     Source: 192.168.0.140 (192.168.0.140)
     Destination: 192.168.0.146 (192.168.0.146)
Transmission Control Protocol, Src Port: 0 (0), Dst Port: 0 (0), Seq: 0
     Source port: 0 (0)
     Destination port: 0 (0)
     Sequence number: 0    (relative sequence number)
     Header length: 0 bytes (bogus, must be at least 20)

    tcph->th_off = 0; (I tried with tcph->th_off = 5; too)
tcph->th_off = 5;
now for my OK!
Ciao
Roberto.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 Roberto.
Che ne pensate della mia esibizione in lingua inglese?? :(
Si vede molto che a sQuola non ci ho capito niente ? :)
