njngypp 发表于 2008-9-16 11:09:14

关于IPv6的原始套接字

想利用原始套接字编写一个可以在发送UDP数据包时更改源地址的程序,v4下已经成功,但在v6下出现问题,没找到对应v4中setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, &flag, sizeof(flag)); 中IP_HDRINCL对应的套接字选项,请大家指点迷津,谢谢!

我的代码:
#define MAX_SIZE 1024
int main ( int argc, char **argv )
{
      int sockfd;
      struct sockaddr_in6 addr;
      memset ( &addr, 0, sizeof ( struct sockaddr_in6 ) );

      unsigned char buffer[ MAX_SIZE ];
      memset( buffer, 0, MAX_SIZE);
      int addrlen;

      const int flag = 1;
      if ( ( sockfd = socket ( PF_INET6, SOCK_RAW, IPPROTO_UDP ) ) < 0 )
      {
                fprintf ( stderr, "Create Error:%s\n", strerror ( errno ) );
                exit ( 1 );
      }

      setsockopt(sockfd, IPPROTO_IPV6, IP_HDRINCL, &flag, sizeof(flag)); // [ ? ]

      struct ip6_hdr *ip6;
      struct udphdr *udp;
      int head_len = sizeof(struct ip6_hdr) + sizeof(struct udphdr);

      ip6 = (struct ip6_hdr*)buffer;
      if ( inet_pton ( AF_INET6, "2001:da8:1001:300::1", &ip6->ip6_src ) <= 0 )
      {
                fprintf ( stderr, "Address Error:%s\n", strerror ( errno ) );
                exit ( 1 );
      }
      if ( inet_pton ( AF_INET6, "2001:da8:1001:230::1", &ip6->ip6_dst ) <= 0 )
      {
                fprintf ( stderr, "Address Error:%s\n", strerror ( errno ) );
                exit ( 1 );
      }

      ip6->ip6_plen = htons(head_len);
      ip6->ip6_nxt = IPPROTO_UDP;
      ip6->ip6_hlim = 255 ;

      udp =(struct udphdr *)(buffer + sizeof(struct ip6_hdr) );
      udp->source = htons( 8888 );
      udp->dest = htons( 8888 );
      udp->len = htons(sizeof( struct udphdr ));
      udp->check = 0;

      // [ fill the address struct of the socket ]
      addr.sin6_family = AF_INET6;
      addr.sin6_port = htons ( 8888 );
      if ( inet_pton ( AF_INET6, "2001:da8:1001:230::1", &addr.sin6_addr ) <= 0 )
      {
                fprintf ( stderr, "Address Error:%s\n", strerror ( errno ) );
                exit ( 1 );
      }
      while(1)
      {
                addrlen = sizeof ( struct sockaddr_in6 );
                sendto ( sockfd, buffer, head_len, 0, ( struct sockaddr * )&addr, addrlen );
      }
      close ( sockfd );
}
页: [1]
查看完整版本: 关于IPv6的原始套接字