send tcp raw socket (bogus tcp header length)

T

Tiger

Hi,
I try to send a packet with raw socket 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;
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)
 
R

Robert Gamble

Tiger said:
Hi,
I try to send a packet with raw socket 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?

[snip code]

Whoa there Tiger, we only discuss Standard C here which does not have
any networking facilities. You should try a network programming or
windows programming group.

Robert Gamble
 
T

Tiger

Robert Gamble a écrit :
Tiger said:
Hi,
I try to send a packet with raw socket 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?

[snip code]

Whoa there Tiger, we only discuss Standard C here which does not have
any networking facilities. You should try a network programming or
windows programming group.

Robert Gamble

Thanks,
can you send me the news group where I can send my request ?
 
F

Flash Gordon

Tiger said:
Hi,
I try to send a packet with raw socket 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>

<snip>

What you are doing is not standard C and we only deal with standard C
here. You would probably be best off in a networking group.
 
R

Robert Gamble

Tiger said:
Robert Gamble a écrit :
Tiger said:
Hi,
I try to send a packet with raw socket 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?

[snip code]

Whoa there Tiger, we only discuss Standard C here which does not have
any networking facilities. You should try a network programming or
windows programming group.

Robert Gamble

Thanks,
can you send me the news group where I can send my request ?

I don't do windows network programming but I might try:
comp.os.ms-windows.programmer.win32
comp.os.ms-windows.programmer.misc

There are other groups that also have "networking" in the name but they
don't appear to be very active. If one of the above groups can't help
they are probably in a much better position to point you in the right
direction than we are.

Robert Gamble
 
D

Dave Thompson

Hi,
I try to send a packet with raw socket 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?

All the IP and socket stuff is offtopic as others have noted, but your
actual problem is ontopic.

char datagram[4096];

struct ip *iph = (struct ip *) datagram;

This isn't guaranteed to work. Structs and other noncharacter types
require alignment on some platforms and converting a pointer to a type
for which it isn't properly aligned is Undefined Behavior. To be safe:
union { char bytes [4096]; struct ip align; } buffer;
... buffer.bytes is both large enough and aligned enough.
Or struct ip datagram [ 4096 / sizeof (struct ip) + 1].
Or, use malloc'ed space, which is aligned for _any_ object.
struct tcphdr *tcph = (struct tcphdr *) datagram + sizeof (struct ip);

This is your actual problem. Pointer addition and subtraction in C are
scaled by the target type. You want:
(struct tcphdr *) (datagram + sizeof (struct ip))
or IMO more clearly just (struct tcphdr *) &iph[1]
or equivalently (struct tcphdr *) (iph + 1) .

Again, this isn't guaranteed to be aligned correctly, although the
IP(v4) header is carefully designed so that if it itself is aligned
(which it may not be for zero-move receives on some link types) then
the IP-body = upper layer header following is also on most machines.

Incidently, sending out a TCP SYN with a seqnum you don't remember and
an invalid checksum, when you can't handle the reply which if valid
would instead provoke immediate RST, is pretty useless. But that is
definitely offtopic; try comp.unix.programmer or a more specific OS
group, or comp.protocols.tcp-ip .


- David.Thompson1 at worldnet.att.net
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,965
Messages
2,570,148
Members
46,710
Latest member
FredricRen

Latest Threads

Top