1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Solved [Solved] Creating and transmitting raw IP packets

Discussion in 'Userland Programming and Scripting' started by inetplumber, Dec 31, 2013.

  1. inetplumber

    inetplumber New Member

    Messages:
    3
    Thanks Received:
    0
    My goal is to create an IP packet with just headers and no payload. I am using http://www.enderunix.org/docs/en/rawipspoof/ as a guide. The current issue is that I cannot appease sendto() and I'm not sure how to get more verbose feedback on which parameter is invalid and how it is invalid. Running truss on my program.

    Code:
    sendto(3,"E\0\0<2\^^\0\0@\M^?\0\0\^?\0\0"...,20,0x0,{ AF_INET 127.0.0.1:1337 },0x10) ERR#22 'Invalid argument'


    And the code;

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <errno.h>
    #include <string.h>
    #include <netdb.h>
    
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <sys/stat.h>
    
    #include <netinet/in_systm.h>
    #include <netinet/in.h>
    #include <netinet/ip.h>
    
    #include <arpa/inet.h>
    
    int main(int argc, char *argv[])
    {
      int    sockfd;
      const int on = 1;
      struct sockaddr_in tx; 
      struct ip pkt_hdr; 
      u_char *pkt; 
    
      //Init IP packet header fields
      pkt_hdr.ip_hl  = 0x5; // 5 x 32 bit length units
      pkt_hdr.ip_v   = 0x4; // IPv4 type packet
      pkt_hdr.ip_tos = 0x0; // ?? Type of Service, packet precedence ???
      pkt_hdr.ip_len = htons(20); // Total Length of Packet
      pkt_hdr.ip_id  = htons(12830); // Packet ID
      pkt_hdr.ip_off = 0x0; // Set fragment offset to 0, don't want fragmentation
      pkt_hdr.ip_ttl = 64; // TTL in number of hops
      pkt_hdr.ip_p   = IPPROTO_RAW; // Protocol
      pkt_hdr.ip_sum = 0x0; // No checksum
      
      pkt_hdr.ip_src.s_addr = inet_addr("127.0.0.1");
      pkt_hdr.ip_dst.s_addr = inet_addr("127.0.0.1");
    
      //Copy header packet 
      pkt = (u_char *)malloc(20);
      memcpy(pkt, &pkt_hdr, sizeof(pkt_hdr));    
      
      //Open raw socket as the intended output write 
      //destination for a IP packet 
      if ((sockfd = socket(PF_INET,SOCK_RAW, IPPROTO_RAW)) < 0 )
      {
        perror("socket");
        exit(1);
      }
      
      //Tell kernel to not prepare IP header
      if (setsockopt(sockfd,IPPROTO_IP,IP_HDRINCL,&on,sizeof(on)))
      {
        perror("setsockop"); 
        exit(1);
      }
    
      //Init network IP information  
      //for routing and transmission
      //so kernel can prepare layer 1 data 
      memset(&tx, 0, sizeof(tx));
      tx.sin_family      = AF_INET;
      tx.sin_port        = htons(1337);
      tx.sin_addr.s_addr = inet_addr("127.0.0.1"); 
     
      //Write the packet out to the network pipe
      if (sendto(sockfd,pkt,20,0,(struct sockaddr *)&tx,sizeof(tx)) < 0 )
      {
        perror("sendto");
        exit(1);
      }
      
      return 0;
    }
    }


    My end goal is to be able to tcpdump these packets on lo0 and gradually build a trivial protocol.
     
  2. worldi

    worldi Member

    Messages:
    161
    Thanks Received:
    1
    Re: Creating and transmitting raw IP packets

    ip(4) mentions that the ip_len must be provided in host byte order.

    Happy New Year! :beergrin
     
  3. inetplumber

    inetplumber New Member

    Messages:
    3
    Thanks Received:
    0
    Re: Creating and transmitting raw IP packets

    Thanks for pointing out that manpage, that's illuminating more aspects of raw IP packet creation in FreeBSD.

    I modified the two packet fields to be set to host byte order as indicated.

    Code:
    ip_len = ntohs(20);
    ip_off = ntohs(0);


    Still getting the same error. My next step is to avoid crafting the layer 1 fields manually by omitting the setsockopt() call and have the kernel prepare that for me.
     
  4. worldi

    worldi Member

    Messages:
    161
    Thanks Received:
    1
    Re: Creating and transmitting raw IP packets

    Yes, that's because by using ntohs() you actually did the same wrong endian conversion again. :)

    To use a number in host byte order just ..uhm.. use it:

    Code:
    ip_len = 20;
    ip_off = 0;
    
     
  5. inetplumber

    inetplumber New Member

    Messages:
    3
    Thanks Received:
    0
    Re: Creating and transmitting raw IP packets

    That did it! Thanks for your help. Here's to more network programming in 2014!