Find the answer to your Linux question:
Results 1 to 1 of 1
Update: [SOLVED] Needed to be running as root I have found code that creates and sends custom TCP packets, but when I run it, I get the following error: Code: ...
  1. #1
    Just Joined!
    Join Date
    May 2010
    Location
    Iowa
    Posts
    4

    Question [SOLVED] Custom TCP Packet Sending Program Failing

    Update: [SOLVED]
    Needed to be running as root

    I have found code that creates and sends custom TCP packets, but when I run it, I get the following error:

    Code:
    Warning: Cannot set HDRINCL!
    error
    error
    error
    error
    error
    Easy to see that setsockopt is failing, but why?

    Code:
    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 <stdlib.h>
    #include <string.h>
    #include <stdio.h>
    
    #define P 25		/* lets flood the sendmail port */
    
    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 (void)
    {
      int s = socket (PF_INET, SOCK_RAW, IPPROTO_TCP);	/* open raw socket */
      char datagram[4096];	/* this buffer will contain ip header, tcp header,
    			   and payload. we'll point an ip header structure
    			   at its beginning, and a tcp header structure after
    			   that to write the header values into it */
      struct ip *iph = (struct ip *) datagram;
      struct tcphdr *tcph = (struct tcphdr *) datagram + sizeof (struct ip);
      struct sockaddr_in sin;
    			/* the sockaddr_in containing the dest. address is used
    			   in sendto() to determine the datagrams path */
    
      sin.sin_family = AF_INET;
      sin.sin_port = htons (P);/* you byte-order >1byte header values to network
    			      byte order (not needed on big endian machines) */
      sin.sin_addr.s_addr = inet_addr ("127.0.0.1");
    
      memset (datagram, 0, 4096);	/* zero out the buffer */
    
    /* we'll now fill in the ip/tcp header values, see above for explanations */
      iph->ip_hl = 5;
      iph->ip_v = 4;
      iph->ip_tos = 0;
      iph->ip_len = sizeof (struct ip) + sizeof (struct tcphdr);	/* no payload */
      iph->ip_id = htonl (54321);	/* the value doesn't matter here */
      iph->ip_off = 0;
      iph->ip_ttl = 255;
      iph->ip_p = 6;
      iph->ip_sum = 0;		/* set it to 0 before computing the actual checksum later */
      iph->ip_src.s_addr = inet_addr ("1.2.3.4");/* SYN's can be blindly spoofed */
      iph->ip_dst.s_addr = sin.sin_addr.s_addr;
      tcph->th_sport = htons (1234);	/* arbitrary port */
      tcph->th_dport = htons (P);
      tcph->th_seq = random ();/* in a SYN packet, the sequence is a random */
      tcph->th_ack = 0;/* number, and the ack sequence is 0 in the 1st packet */
      tcph->th_x2 = 0;
      tcph->th_off = 0;		/* first and only tcp segment */
      tcph->th_flags = TH_SYN;	/* initial connection request */
      tcph->th_win = htonl (65535);	/* maximum allowed window size */
      tcph->th_sum = 0;/* if you set a checksum to zero, your kernel's IP stack
    		      should fill in the correct checksum during transmission */
      tcph->th_urp = 0;
    
      iph->ip_sum = csum ((unsigned short *) datagram, iph->ip_len >> 1);
    
    /* finally, it is very advisable to do a IP_HDRINCL call, to make sure
       that the kernel knows the header is included in the data, and doesn't
       insert its own header into the packet before our data */
    
      {				/* lets do it the ugly way.. */
        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 i = 0;
      while (i++ < 5)
        {
          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;
    }
    Thanks,
    tyman
    Last edited by tyman475; 05-21-2010 at 03:59 PM. Reason: Solved

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...