From MSDN:
WSASendMsg function
[...]
On an IPv4 socket of type SOCK_DGRAM
or SOCK_RAW
, an application can specific the local IP source address to use for sending with the WSASendMsg
function. One of the control data objects passed in the WSAMSG
structure to the WSASendMsg
function may contain an in_pktinfo
structure used to specify the local IPv4 source address to use for sending.
The same applies to an IPv6 socket with the in6_pktinfo
structure.
For dual-mode sockets, it is important that an IPv4 source address is not specified as an IPv4-mapped IPv6 address in the in6_pktinfo
, but as an IPv4 address in the in_pktinfo
structure.
Example:
union {
char in[WSA_CMSG_SPACE(sizeof(struct in_pktinfo))];
char in6[WSA_CMSG_SPACE(sizeof(struct in6_pktinfo))];
} cdata;
WSAMSG msg;
memset(&msg, 0, sizeof(msg));
msg.name = &remote_sysaddr.addr.generic;
msg.namelen = remote_sysaddr.len;
msg.lpBuffers = &buf;
msg.dwBufferCount = 1;
msg.Control.buf = (char *)&cdata;
msg.Control.len = sizeof(cdata);
int sum = 0;
WSACMSGHDR *cmsg = WSA_CMSG_FIRSTHDR(&msg);
...
memset(cmsg, 0, WSA_CMSG_SPACE(sizeof(struct in_pktinfo)));
cmsg->cmsg_level = IPPROTO_IP;
cmsg->cmsg_type = IP_PKTINFO;
cmsg->cmsg_len = WSA_CMSG_LEN(sizeof(struct in_pktinfo));
struct in_pktinfo *pktinfo = (struct in_pktinfo *)WSA_CMSG_DATA(cmsg);
pktinfo->ipi_addr.s_addr = local_addr->ipv4;
sum += WSA_CMSG_SPACE(sizeof(struct in_pktinfo));
...
msg.Control.len = sum;
if (bs->WSASendMsg(bs->socket, &msg, 0, &bytes, NULL, NULL) != 0) {
...