title: sendto() "invalid argument" error with IPv6 raw udp socket on linux
body: <p>I'm trying to send udp packets with raw sockets. For IPv4 everything works fine, but I can't break through problem with IPv6 sockets, where sendto() always says invalid argument. Initially I was thinking about mandatory checksum for IPv6, but IPV6_CHECKSUM option should fix that, so I'm out of options now. </p>
  
  <p>I'm using inaddr_any for addr_from, and some ipv6 address for addr_to with the same port. I looked through send_ip tool sources, it manually computes checksum and sends packet with raw/raw socket, but I want linux to automatically form IP packet with necessary source address according to policy based routing rules.</p>
  
  <p>Does anyone have any ideas what is the root cause of the issue? Or any working example with raw/ipproto_udp socket?</p>
  
  <p>Thanks in advance!</p>
  
  <p>PS: please disregard all threading stuff</p>
  
  <p>sending code is:</p>
  
  <pre><code>typedef struct thread_data {
      char msg[BUFFER_LENGTH];
      struct sockaddr_in6 addr_to;
      struct sockaddr_in6 addr_from;
  } thread_data;
  
  void create_packet( const thread_data* data, void** packet, size_t* size ) {
      size_t msg_len = strlen(data-&gt;msg), udp_len = sizeof(struct udphdr);
      struct udphdr udp = {0};
  
      udp.source = data-&gt;addr_from.sin6_port;
      udp.dest   = data-&gt;addr_to.sin6_port;
      udp.len    = htons(udp_len + msg_len);
      udp.check  = 0;
  
      *packet = malloc( udp_len + msg_len );
      if( !(*packet) ) {
          ERROR("malloc failed" );
      }
  
      memcpy( *packet, &amp;udp, sizeof(struct udphdr));
      memcpy( (*packet) + udp_len, data-&gt;msg, msg_len);
  
      *size = udp_len + msg_len;
  }
  
  void client_thread( void* args ) {
  
      thread_data* data = (thread_data*)args;
  
      int sock = -1;
      if ( (sock = socket( AF_INET6, SOCK_RAW, IPPROTO_UDP )) &lt; 0 ) {
          ERROR( "failed to create socket" );
      }
  
      int val = 2; //I tried to play with this value, but with no luck
      if( setsockopt( sock, IPPROTO_IPV6, IPV6_CHECKSUM, &amp;val, sizeof(val) ) &lt; 0 ) {
          ERROR("setsockopt failed" );
      }
      ssize_t res = sendto( sock, packet, size, 0, (struct sockaddr*)&amp;(data-&gt;addr_to), sizeof(data-&gt;addr_to));
      if ( res &lt; 0 ) {
          ERROR( "sendto failed" );
       }
  }
  </code></pre>