37# include <sys/types.h>
38# include <sys/socket.h>
39#include <netinet/in.h>
68#define INVALID_SOCKET -1
72 struct in6_addr *from)
75 struct sockaddr_in cto, cfrom;
79 auto s=socket(AF_INET, SOCK_DGRAM, 0);
81 return (
"failed to open DGRAM socket for src addr selection.");
83 len=
sizeof(
struct sockaddr_in);
84 memcpy(&cto, to, len);
85 cto.sin_port=htons(65535);
86 if (connect(s, (
struct sockaddr *)&cto, len) == -1) {
87 errstr=
"failed to connect to peer for src addr selection.";
91 if (getsockname(s, (
struct sockaddr *)&cfrom, &len) == -1) {
92 errstr=
"failed to get socket name for src addr selection.";
96 if (len !=
sizeof(
struct sockaddr_in) || cfrom.sin_family != AF_INET) {
97 errstr=
"unexpected address family in src addr selection.";
103 ((
uint32_t *)from)[2]=htonl(0xffff);
104 ((
uint32_t *)from)[3]=cfrom.sin_addr.s_addr;
114 struct in6_addr *from)
117 struct sockaddr_in6 cto, cfrom;
121 if (IN6_IS_ADDR_LOOPBACK(&to->sin6_addr)) {
122 memcpy(from, &to->sin6_addr,
sizeof(
struct in6_addr));
126 auto s=socket(AF_INET6, SOCK_DGRAM, 0);
128 return (
"failed to open DGRAM socket for src addr selection.");
133 if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (
char *)&sock_flg,
134 sizeof(sock_flg)) == -1) {
135 errstr=
"setsockopt failed to set dual stack mode.";
139 len=
sizeof(
struct sockaddr_in6);
140 memcpy(&cto, to, len);
141 cto.sin6_port=htons(65535);
142 if (connect(s, (
struct sockaddr *)&cto, len) == -1) {
143 errstr=
"failed to connect to peer for src addr selection.";
147 if (getsockname(s, (
struct sockaddr *)&cfrom, &len) == -1) {
148 errstr=
"failed to get socket name for src addr selection.";
152 if (len !=
sizeof(
struct sockaddr_in6) || cfrom.sin6_family != AF_INET6) {
153 errstr=
"unexpected address family in src addr selection.";
157 memcpy(from->s6_addr, cfrom.sin6_addr.s6_addr,
sizeof(
struct in6_addr));
const char * findsaddr6(const struct sockaddr_in6 *to, struct in6_addr *from)
const char * findsaddr(const struct sockaddr_in *to, struct in6_addr *from)