Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ssize_t UDPSendWithSourceIP(int fd, void * data, size_t len, const H323TransportAddress & toAddress)
- {
- struct sockaddr_in6 dest;
- // set dest address
- PIPSocket::Address toIP;
- WORD toPort = 0;
- toAddress.GetIpAndPort(toIP, toPort);
- SetSockaddr(dest, toIP, toPort);
- // set source address
- PIPSocket::Address src = RasServer::Instance()->GetLocalAddress(toIP);
- struct msghdr msgh;
- struct cmsghdr *cmsg;
- struct iovec iov = { };
- char cbuf[256];
- memset(&cbuf, 0, sizeof(cbuf));
- // Set up iov and msgh structures
- memset(&msgh, 0, sizeof(struct msghdr));
- iov.iov_base = data;
- iov.iov_len = len;
- msgh.msg_iov = &iov;
- msgh.msg_iovlen = 1;
- msgh.msg_name = (struct sockaddr*)&dest;
- // must pass short len when sending to IPv4 address on Solaris 11, OpenBSD and NetBSD
- // sizeof(dest) is OK on Linux and FreeBSD
- size_t addr_len = sizeof(sockaddr_in);
- if (toIP.GetVersion() == 6)
- addr_len = sizeof(sockaddr_in6);
- msgh.msg_namelen = addr_len;
- if ((((struct sockaddr*)&dest)->sa_family == AF_INET6)) {
- struct in6_pktinfo *pkt;
- msgh.msg_control = cbuf;
- msgh.msg_controllen = CMSG_SPACE(sizeof(*pkt));
- cmsg = CMSG_FIRSTHDR(&msgh);
- cmsg->cmsg_level = IPPROTO_IPV6;
- cmsg->cmsg_type = IPV6_PKTINFO;
- cmsg->cmsg_len = CMSG_LEN(sizeof(*pkt));
- pkt = (struct in6_pktinfo *) CMSG_DATA(cmsg);
- memset(pkt, 0, sizeof(*pkt));
- pkt->ipi6_addr = src;
- msgh.msg_controllen = cmsg->cmsg_len;
- } else
- {
- #if defined(IP_PKTINFO) && !defined(P_NETBSD) // Linux and Solaris 11 (NetBSD 7 only has incomplete IP_PKTINFO support)
- struct in_pktinfo *pkt;
- msgh.msg_control = cbuf;
- msgh.msg_controllen = CMSG_SPACE(sizeof(*pkt));
- cmsg = CMSG_FIRSTHDR(&msgh);
- cmsg->cmsg_level = IPPROTO_IP;
- cmsg->cmsg_type = IP_PKTINFO;
- cmsg->cmsg_len = CMSG_LEN(sizeof(*pkt));
- pkt = (struct in_pktinfo *) CMSG_DATA(cmsg);
- memset(pkt, 0, sizeof(*pkt));
- pkt->ipi_spec_dst = src;
- #else
- #ifdef IP_SENDSRCADDR // FreeBSD
- struct in_addr *in;
- msgh.msg_control = cbuf;
- msgh.msg_controllen = CMSG_SPACE(sizeof(*in));
- cmsg = CMSG_FIRSTHDR(&msgh);
- cmsg->cmsg_level = IPPROTO_IP;
- cmsg->cmsg_type = IP_SENDSRCADDR;
- cmsg->cmsg_len = CMSG_LEN(sizeof(*in));
- in = (struct in_addr *) CMSG_DATA(cmsg);
- *in = src;
- #endif // IP_SENDSRCADDR
- #endif // IP_PKTINFO else
- }
- ssize_t bytesSent = sendmsg(fd, &msgh, 0);
- if (bytesSent < 0) {
- PTRACE(5, "RTPtSend error " << strerror(errno));
- }
- return bytesSent;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement