FreeBSD/sys/ofed/include/rdma/ib_addr.h
/* Important - sockaddr should be a union of sockaddr_in and sockaddr_in6 */
sockaddr should be a union of sockaddr_in and sockaddr_in6
sockaddr should be a union of sockaddr_in and sockaddr_in6
static inline int rdma_gid2ip(struct sockaddr *out, union ib_gid *gid,
    uint32_t scope_id)
{
	if (ipv6_addr_v4mapped((struct in6_addr *)gid)) {
		struct sockaddr_in *out_in = (struct sockaddr_in *)out;
		memset(out_in, 0, sizeof(*out_in));
		out_in->sin_len = sizeof(*out_in);
		out_in->sin_family = AF_INET;
		memcpy(&out_in->sin_addr.s_addr, gid->raw + 12, 4);
	} else {
		struct sockaddr_in6 *out_in = (struct sockaddr_in6 *)out;
		memset(out_in, 0, sizeof(*out_in));
		out_in->sin6_len = sizeof(*out_in);
		out_in->sin6_family = AF_INET6;
		memcpy(&out_in->sin6_addr.s6_addr, gid->raw, 16);
		if (scope_id < 256 &&
		    IN6_IS_SCOPE_LINKLOCAL(&out_in->sin6_addr))
			out_in->sin6_scope_id = scope_id;
	}
	return 0;
}
static inline int rdma_gid2ip ( struct sockaddr * out , union ib_gid * gid , uint32_t scope_id ) { if ( ipv6_addr_v4mapped ( ( struct in6_addr * ) gid ) ) { struct sockaddr_in * out_in = ( struct sockaddr_in * ) out ; memset ( out_in , 0 , sizeof ( * out_in ) ) ; out_in -> sin_len = sizeof ( * out_in ) ; out_in -> sin_family = AF_INET ; memcpy ( & out_in -> sin_addr . s_addr , gid -> raw + 12 , 4 ) ; } else { struct sockaddr_in6 * out_in = ( struct sockaddr_in6 * ) out ; memset ( out_in , 0 , sizeof ( * out_in ) ) ; out_in -> sin6_len = sizeof ( * out_in ) ; out_in -> sin6_family = AF_INET6 ; memcpy ( & out_in -> sin6_addr . s6_addr , gid -> raw , 16 ) ; if ( scope_id < 256 && IN6_IS_SCOPE_LINKLOCAL ( & out_in -> sin6_addr ) ) out_in -> sin6_scope_id = scope_id ; } return 0 ; }
Important - sockaddr should be a union of sockaddr_in and sockaddr_in6
Important - sockaddr should be a union of sockaddr_in and sockaddr_in6