send tcp raw socket (bogus tcp header length)

Discussion in 'C Programming' started by Tiger, Apr 18, 2006.

  1. Tiger

    Tiger Guest

    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)
    Tiger, Apr 18, 2006
    #1
    1. Advertising

  2. Tiger wrote:
    > 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
    Robert Gamble, Apr 18, 2006
    #2
    1. Advertising

  3. Tiger

    Tiger Guest

    Robert Gamble a écrit :
    > Tiger wrote:
    >> 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 ?
    Tiger, Apr 18, 2006
    #3
  4. Tiger

    Flash Gordon Guest

    Tiger wrote:
    > 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.
    --
    Flash Gordon, living in interesting times.
    Web site - http://home.flash-gordon.me.uk/
    comp.lang.c posting guidelines and intro:
    http://clc-wiki.net/wiki/Intro_to_clc
    Flash Gordon, Apr 18, 2006
    #4
  5. Tiger wrote:
    > Robert Gamble a écrit :
    > > Tiger wrote:
    > >> 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
    Robert Gamble, Apr 18, 2006
    #5
  6. On Tue, 18 Apr 2006 20:50:41 +0200, Tiger <> wrote:

    > 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.

    <snip>
    > 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
    Dave Thompson, May 1, 2006
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Karl Seguin

    firewalls "removing bogus header"

    Karl Seguin, Feb 10, 2004, in forum: ASP .Net
    Replies:
    4
    Views:
    1,404
    George Ter-Saakov
    Feb 10, 2004
  2. Fengyuan
    Replies:
    3
    Views:
    346
    rossum
    Mar 30, 2007
  3. =?ISO-8859-15?Q?Bastian_P=F6ttner?=

    tcp socket send - Resource temporarily unavailable?

    =?ISO-8859-15?Q?Bastian_P=F6ttner?=, Jun 14, 2007, in forum: C++
    Replies:
    4
    Views:
    4,160
    Peter
    Jun 14, 2007
  4. Chris Reay

    Does Socket.send send all bytes?

    Chris Reay, Nov 3, 2003, in forum: Ruby
    Replies:
    2
    Views:
    218
    Chris Reay
    Nov 4, 2003
  5. Ben Nagy

    Send over raw socket?

    Ben Nagy, Dec 5, 2006, in forum: Ruby
    Replies:
    1
    Views:
    255
    Joel VanderWerf
    Dec 5, 2006
Loading...

Share This Page