title: Injecting raw packet onto network in C (Linux)
body: <p>I am trying to write a function that takes a stream of bytes (including ethernet header and perhaps upper layer protocols encapsulated within the ethernet packet as well) and send it out on the network on a particular interface.</p>
  
  <p>Here is a summary of my code:</p>
  
  <pre><code>// create socket
  int s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
  if (s &lt; 0) {
      // error handling
  }
  
  // set up to just receive/send packets on one interface (stored in the variable iface_name e.g. eth0)
  struct ifreq ifr;
  bzero(&amp;ifr, sizeof(struct ifreq));
  strncpy(ifr.ifr_ifrn.ifrn_name, iface_name, IFNAMSIZ);
  if (ioctl(s, SIOCGIFINDEX, &amp;ifr) &lt; 0) {
      // error handling
  }
  
  // set up socaddr for write
  struct sockaddr sa;
  sa.sa_family = PF_PACKET;
  sa.sa_data = htons(ETH_P_ALL);
  
  // write to wire
  // buf has type char* and len has type int
  // buf contains ethernet header, followed by payload (e.g. ARP packet or IP packet)
  if ( sendto(s, buf, len, 0, &amp;sa, sizeof(struct sockaddr) ) &lt; 0 ) {
      perror("sendto");
      // more error handling
  }
  </code></pre>
  
  <p>I get the error</p>
  
  <pre><code>sendto: Invalid argument
  </code></pre>
  
  <p>How can I fix this error?</p>
  
  <p>My initial guess is that this is somehow caused by the <code>sa</code> argument, since all the others are fairly standard and there's not much to go wrong. I could replace this with an argument of <code>sockaddr_ll</code> type as in <a href="http://aschauf.landshut.org/fh/linux/udp_vs_raw/ch01s03.html" rel="nofollow">this example</a>, but this would mean extracting the header information from <code>buf</code> and this seems a little pointless since it's already there, ready to go. There must be a better way? Encapsulate, unencapsulate, re-encapsulate, send seems like it has too many unnecessary steps. I am writing an underlying interface for some pre-existing code, so there is no way I can adapt the input to not already have the data-link layer headers included.</p>