【发布时间】:2014-01-04 03:12:06
【问题描述】:
我正在尝试使用原始套接字发送 udp 数据包。对于 IPv4,一切正常,但我无法解决 IPv6 套接字的问题,其中 sendto() 总是说无效参数。最初我在考虑 IPv6 的强制校验和,但 IPV6_CHECKSUM 选项应该可以解决这个问题,所以我现在没有选择。
我将 inaddr_any 用于 addr_from,并将一些 ipv6 地址用于 addr_to 具有相同的端口。我查看了 send_ip 工具源,它手动计算校验和并使用原始/原始套接字发送数据包,但我希望 linux 根据基于策略的路由规则自动形成具有必要源地址的 IP 数据包。
有没有人知道问题的根本原因是什么?或者任何使用 raw/ipproto_udp 套接字的工作示例?
提前致谢!
PS:请忽略所有线程的东西
发送代码是:
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->msg), udp_len = sizeof(struct udphdr);
struct udphdr udp = {0};
udp.source = data->addr_from.sin6_port;
udp.dest = data->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, &udp, sizeof(struct udphdr));
memcpy( (*packet) + udp_len, data->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 )) < 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, &val, sizeof(val) ) < 0 ) {
ERROR("setsockopt failed" );
}
ssize_t res = sendto( sock, packet, size, 0, (struct sockaddr*)&(data->addr_to), sizeof(data->addr_to));
if ( res < 0 ) {
ERROR( "sendto failed" );
}
}
【问题讨论】:
-
您使用什么作为 IPv6 地址
addr_from和addr_to? -
对于 addr_from,我使用了 in6addr_any,对于 addr_to,我使用了一些可以从主机访问的有效 IPv6 地址。 addr_to 和 addr_from 的端口号相同。
-
您使用什么作为您的 IPv6 地址
addr_to? -
似乎我在你的问题中遗漏了一些东西。完整答案是:addr_to 是用 IPv6 地址和端口适当填充的 sockaddr_in6 结构。
-
您说的是“一些有效的 IPv6 地址”。您需要准确说出实际地址。