|
int icmpv6_NS(char *pIfname, struct in6_addr *dst)
{
int sockfd = -1;
int sockopt = 0;
int rc = 0;
char buff[512] = {0};
int len = 0;
struct sockaddr_in6 multi_addr;
struct ipv6_mreq mreq6;
struct nd_neighbor_solicit *ns_pkt;
fd_set rset;
struct timeval timeout;
if((NULL == pIfname) || (NULL == dst))
{
return -1;
}
sockfd = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
if(sockfd <= 0)
{
printf("NS icmpv6 socket create error!\r\n");
return -1;
}
sockopt = offsetof(struct icmp6_hdr, icmp6_cksum);
if(2 != sockopt)
{
perror("icmp_cksum offset error\r\n");
close(sockfd);
return -1;
}
if(setsockopt(sockfd, SOL_RAW, IPV6_CHECKSUM, &sockopt, sizeof(sockopt)) < 0)
{
perror("icmp_cksum set error\r\n");
close(sockfd);
return -1;
}
/*ns packet*/
ns_pkt = (struct nd_neighbor_solicit*)buff;
ns_pkt->nd_ns_type = ND_NEIGHBOR_SOLICIT;
ns_pkt->nd_ns_code = 0;
ns_pkt->nd_ns_reserved = 0;
memcpy(&ns_pkt->nd_ns_target, dst, sizeof(struct in6_addr));
multi_addr.sin6_family = AF_INET6;
//get node multi_addr
inet_pton(AF_INET6, "FF02::1:FF00:0", &multi_addr.sin6_addr);
multi_addr.sin6_addr.s6_addr[13] = dst->s6_addr[13];
multi_addr.sin6_addr.s6_addr[14] = dst->s6_addr[14];
multi_addr.sin6_addr.s6_addr[15] = dst->s6_addr[15];
//join group
memcpy(&mreq6.ipv6mr_multiaddr, &multi_addr.sin6_addr,sizeof(struct in6_addr));
mreq6.ipv6mr_interface = if_nametoindex(pIfname);
setsockopt(sockfd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq6, sizeof(mreq6));
//set multicast hops to 255
sockopt = 255;
setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &sockopt, sizeof(int));
//send data
len = sendto(sockfd, buff, sizeof(struct nd_neighbor_solicit), 0, (struct sockaddr*)&multi_addr, sizeof(struct sockaddr_in6));
printf("len is %d\r\n", len);
perror("len is \r\n");
//recv
timeout.tv_sec = 2;
timeout.tv_usec = 0;
FD_ZERO(&rset);
FD_SET(sockfd, &rset);
rc = select(sockfd+1,&rset,NULL,NULL,&timeout);
len = recv(sockfd, buff, sizeof(buff), 0);
printf("len is %d\r\n", len);
/*
while(1)
{
FD_ZERO(&fdset);
FD_SET(sockfd_rec, &fdset);
rc = select(sockfd_rec + 1, &fdset, NULL, NULL, &tm);
if(rc == 0)
{
printf("----------time out\r\n");
break;
}
else if(rc > 0)
{
//recvfrom(sockfd, );
len = recv(sockfd_rec, buff, sizeof(buff), 0);
break;
}
}
*/
//leave the group
setsockopt(sockfd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &mreq6, sizeof(mreq6));
close(sockfd);
return 0;
}
这段代码是检测地址冲突的,
当使用select时,sendto发送失败,为什么?
|
|