[Solved] Creating and transmitting raw IP packets

C, C++, Python, Perl, Shell, etc.

[Solved] Creating and transmitting raw IP packets

Postby inetplumber » 31 Dec 2013, 16:37

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: Select all
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: Select all
#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.
Last edited by DutchDaemon on 02 Jan 2014, 12:26, edited 2 times in total.
Reason: Proper forum formatting.
inetplumber
Junior Member
 
Posts: 3
Joined: 06 Sep 2013, 03:37

Re: Creating and transmitting raw IP packets

Postby worldi » 31 Dec 2013, 23:21

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

Happy New Year! :beergrin
"If my answers frighten you then you should cease asking scary questions." -- Jules, Pulp Fiction
User avatar
worldi
Member
 
Posts: 156
Joined: 21 Dec 2013, 11:58
Location: berlin.de

Re: Creating and transmitting raw IP packets

Postby inetplumber » 01 Jan 2014, 01:35

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: Select all
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.
Last edited by DutchDaemon on 01 Jan 2014, 21:16, edited 1 time in total.
Reason: Proper forum formatting.
inetplumber
Junior Member
 
Posts: 3
Joined: 06 Sep 2013, 03:37

Re: Creating and transmitting raw IP packets

Postby worldi » 01 Jan 2014, 03:19

inetplumber wrote:
Code: Select all
ip_len = ntohs(20);
ip_off = ntohs(0);


Still getting the same error.


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: Select all
ip_len = 20;
ip_off = 0;
"If my answers frighten you then you should cease asking scary questions." -- Jules, Pulp Fiction
User avatar
worldi
Member
 
Posts: 156
Joined: 21 Dec 2013, 11:58
Location: berlin.de

Re: Creating and transmitting raw IP packets

Postby inetplumber » 01 Jan 2014, 23:55

That did it! Thanks for your help. Here's to more network programming in 2014!
inetplumber
Junior Member
 
Posts: 3
Joined: 06 Sep 2013, 03:37


Return to Userland Programming & Scripting

Who is online

Users browsing this forum: No registered users and 2 guests