BOOL AllocAndInitIpv6PktInfo(LPWSAMSG pWSAMsg) { PBYTE CtrlBuf = (PBYTE)MALLOC(WSA_CMSG_SPACE(sizeof IN6_PKTINFO)); //caller frees heap allocated CtrlBuf if(NULL == CtrlBuf) { ERR("HeapAlloc"); return FALSE; } pWSAMsg->Control.buf = (CHAR*)CtrlBuf; pWSAMsg->Control.len = (ULONG)MSIZE(CtrlBuf); return TRUE; }
int MDDSocket_Sendto(MDDSocket_t socket, unsigned char *buf, int buf_len, MDDSocketAddr_t *to, MDDIface_t *iface) { struct sockaddr_in sa; struct sockaddr_in6 sa6; WSAMSG msg; WSABUF io; DWORD sent_len = 0; INT nRet = 0; if (socket == INVALID_SOCKET) { return MDD_ERROR; } SecureZeroMemory(&io, sizeof(io)); io.buf = (char *)buf; io.len = buf_len; SecureZeroMemory (&msg, sizeof(msg)); msg.lpBuffers = &io; msg.dwBufferCount = 1; msg.dwFlags = 0; if (to->family == MDDNet_INET) { memset(&sa, 0, sizeof(sa)); sa.sin_family = AF_INET; sa.sin_port = to->port; sa.sin_addr.s_addr = to->addr.ip.ipv4; msg.name = (LPSOCKADDR)(&sa); msg.namelen = sizeof(sa); } else if (to->family == MDDNet_INET6) { memset(&sa6, 0, sizeof(sa6)); sa6.sin6_family = AF_INET6; sa6.sin6_port = to->port; memcpy(sa6.sin6_addr.s6_addr, to->addr.ip.ipv6, 16); msg.name = (LPSOCKADDR)(&sa6); msg.namelen = sizeof(sa6); } else { return MDD_ERROR; } if (iface != NULL && iface->ifindex > 0) { if (to->family == MDDNet_INET) { PIN_PKTINFO pkti; WSACMSGHDR *cmsg; char in[WSA_CMSG_SPACE(sizeof(struct in_pktinfo))]; int sum = 0; memset(in, 0, sizeof(in)); msg.Control.buf = (char *)∈ msg.Control.len = sizeof(in); 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)); pkti = (PIN_PKTINFO) WSA_CMSG_DATA(cmsg); if (iface->ifindex > 0) { pkti->ipi_ifindex = iface->ifindex; pkti->ipi_addr.S_un.S_addr = iface->addr.ip.ipv4; // [email protected], 2012/07/24, workaround to resolve can't sent in release mode. DO NOT remove this printf until find solution printf(""); } sum += WSA_CMSG_SPACE(sizeof(struct in_pktinfo)); msg.Control.len = sum; } else if (to->family == MDDNet_INET6) { PIN6_PKTINFO pkti; WSACMSGHDR *cmsg; char in[WSA_CMSG_SPACE(sizeof(struct in6_pktinfo))]; int sum = 0; memset(in, 0, sizeof(in)); msg.Control.buf = (char *)∈ msg.Control.len = sizeof(in); cmsg = WSA_CMSG_FIRSTHDR(&msg); memset(cmsg, 0, WSA_CMSG_SPACE(sizeof(struct in6_pktinfo))); cmsg->cmsg_level = IPPROTO_IPV6; cmsg->cmsg_type = IPV6_PKTINFO; cmsg->cmsg_len = WSA_CMSG_LEN(sizeof(struct in6_pktinfo)); pkti = (PIN6_PKTINFO) WSA_CMSG_DATA(cmsg); if (iface->ifindex > 0) { pkti->ipi6_ifindex = iface->ifindex; memcpy(&pkti->ipi6_addr.u.Byte, iface->addr.ip.ipv6, 16); // [email protected], 2012/07/24, workaround to resolve can't sent in release mode. DO NOT remove this printf until find solution printf(""); } sum += WSA_CMSG_SPACE(sizeof(struct in6_pktinfo)); msg.Control.len = sum; } } if (SOCKET_ERROR == (nRet = fpWSASendMsg(socket, &msg, 0, &sent_len, NULL, NULL))) { LOG_ERROR("MDDSocket_Sendto by WSASendMsg error %d\n", WSAGetLastError()); return MDD_ERROR; } else { return sent_len; } }