@@ -607,6 +607,13 @@ int main(int argc, char **argv)
607607#endif
608608 } else if (strstr (optparse_state .optlongname , "print-srcaddr" ) != NULL ) {
609609 opt_print_srcaddr_on = 1 ;
610+ #if defined(IPV6 ) && defined(IPV6_RECVPKTINFO )
611+ if (socket6 >= 0 ) {
612+ if (setsockopt (socket6 , IPPROTO_IPV6 , IPV6_RECVPKTINFO , & sock_opt_on , sizeof (sock_opt_on ))) {
613+ perror ("setsockopt IPV6_RECVPKTINFO" );
614+ }
615+ }
616+ #endif
610617 } else if (strstr (optparse_state .optlongname , "seqmap-timeout" ) != NULL ) {
611618 opt_seqmap_timeout = strtod_strict (optparse_state .optarg ) * 1000000 ;
612619 } else if (strstr (optparse_state .optlongname , "oiface" ) != NULL ) {
@@ -2077,7 +2084,13 @@ int receive_packet(int64_t wait_time,
20772084 char * reply_buf ,
20782085 size_t reply_buf_len ,
20792086 int * ip_header_tos ,
2080- int * ip_header_ttl )
2087+ int * ip_header_ttl ,
2088+ #ifdef IPV6
2089+ struct in6_addr * recv_dst_addr_ipv6
2090+ #else
2091+ void * recv_dst_addr_ipv6
2092+ #endif
2093+ )
20812094{
20822095 struct timeval to ;
20832096 int s = 0 ;
@@ -2161,6 +2174,11 @@ int receive_packet(int64_t wait_time,
21612174 if (cmsg -> cmsg_level == IPPROTO_IPV6 && cmsg -> cmsg_type == IPV6_HOPLIMIT ) {
21622175 memcpy (ip_header_ttl , CMSG_DATA (cmsg ), sizeof (* ip_header_ttl ));
21632176 }
2177+ if (cmsg -> cmsg_level == IPPROTO_IPV6 && cmsg -> cmsg_type == IPV6_PKTINFO ) {
2178+ struct in6_pktinfo * pktinfo = (struct in6_pktinfo * )CMSG_DATA (cmsg );
2179+ if (recv_dst_addr_ipv6 )
2180+ memcpy (recv_dst_addr_ipv6 , & pktinfo -> ipi6_addr , sizeof (* recv_dst_addr_ipv6 ));
2181+ }
21642182#endif
21652183 }
21662184 }
@@ -2384,7 +2402,8 @@ int decode_icmp_ipv6(
23842402 size_t reply_buf_len ,
23852403 unsigned short * id ,
23862404 unsigned short * seq ,
2387- IP_HEADER_RESULT * ip_header_res )
2405+ IP_HEADER_RESULT * ip_header_res ,
2406+ struct in6_addr * local_addr )
23882407{
23892408 struct icmp6_hdr * icp ;
23902409
@@ -2494,8 +2513,10 @@ int decode_icmp_ipv6(
24942513 * seq = ntohs (icp -> icmp6_seq );
24952514
24962515 if (opt_print_srcaddr_on ) {
2497- strncpy (ip_header_res -> src_addr , "not supported" , sizeof (ip_header_res -> src_addr ) - 1 );
2498- ip_header_res -> src_addr [sizeof (ip_header_res -> src_addr ) - 1 ] = '\0' ;
2516+ if (local_addr == NULL || IN6_IS_ADDR_UNSPECIFIED (local_addr ) || inet_ntop (AF_INET6 , local_addr , ip_header_res -> src_addr , sizeof (ip_header_res -> src_addr )) == NULL ) {
2517+ strncpy (ip_header_res -> src_addr , "unknown" , sizeof (ip_header_res -> src_addr ) - 1 );
2518+ ip_header_res -> src_addr [sizeof (ip_header_res -> src_addr ) - 1 ] = '\0' ;
2519+ }
24992520 }
25002521
25012522 return 1 ;
@@ -2517,6 +2538,11 @@ int wait_for_reply(int64_t wait_time)
25172538 unsigned short seq ;
25182539 IP_HEADER_RESULT ip_header_res = default_ip_header_result ();
25192540
2541+ #ifdef IPV6
2542+ struct in6_addr recv_dst_addr_ipv6 ;
2543+ memset (& recv_dst_addr_ipv6 , 0 , sizeof (recv_dst_addr_ipv6 ));
2544+ #endif
2545+
25202546 /* Receive packet */
25212547 result = receive_packet (wait_time , /* max. wait time, in ns */
25222548 & recv_time , /* reply_timestamp */
@@ -2525,7 +2551,12 @@ int wait_for_reply(int64_t wait_time)
25252551 buffer , /* reply_buf */
25262552 sizeof (buffer ), /* reply_buf_len */
25272553 & ip_header_res .tos , /* TOS resp. TC byte */
2528- & ip_header_res .ttl /* TTL resp. hop limit */
2554+ & ip_header_res .ttl , /* TTL resp. hop limit */
2555+ #ifdef IPV6
2556+ & recv_dst_addr_ipv6
2557+ #else
2558+ NULL
2559+ #endif
25292560 );
25302561
25312562 if (result <= 0 ) {
@@ -2567,7 +2598,8 @@ int wait_for_reply(int64_t wait_time)
25672598 sizeof (buffer ),
25682599 & id ,
25692600 & seq ,
2570- & ip_header_res )) {
2601+ & ip_header_res ,
2602+ & recv_dst_addr_ipv6 )) {
25712603 return 1 ;
25722604 }
25732605 if (id != ident6 ) {
@@ -3165,6 +3197,6 @@ void usage(int is_error)
31653197 fprintf (out , " -X, --fast-reachable=N exits true immediately when N hosts are found\n" );
31663198 fprintf (out , " --print-tos show received TOS value\n" );
31673199 fprintf (out , " --print-ttl show IP TTL value\n" );
3168- fprintf (out , " --print-srcaddr show used IP source address (IPv6 is currently not supported). \n" );
3200+ fprintf (out , " --print-srcaddr show used IP source address\n" );
31693201 exit (is_error );
31703202}
0 commit comments