Advertisement
Guest User

Untitled

a guest
Sep 21st, 2017
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.66 KB | None | 0 0
  1. ssize_t UDPSendWithSourceIP(int fd, void * data, size_t len, const H323TransportAddress & toAddress)
  2. {
  3. struct sockaddr_in6 dest;
  4.  
  5. // set dest address
  6. PIPSocket::Address toIP;
  7. WORD toPort = 0;
  8. toAddress.GetIpAndPort(toIP, toPort);
  9. SetSockaddr(dest, toIP, toPort);
  10.  
  11. // set source address
  12. PIPSocket::Address src = RasServer::Instance()->GetLocalAddress(toIP);
  13.  
  14. struct msghdr msgh;
  15. struct cmsghdr *cmsg;
  16. struct iovec iov = { };
  17. char cbuf[256];
  18. memset(&cbuf, 0, sizeof(cbuf));
  19.  
  20. // Set up iov and msgh structures
  21. memset(&msgh, 0, sizeof(struct msghdr));
  22. iov.iov_base = data;
  23. iov.iov_len = len;
  24. msgh.msg_iov = &iov;
  25. msgh.msg_iovlen = 1;
  26. msgh.msg_name = (struct sockaddr*)&dest;
  27. // must pass short len when sending to IPv4 address on Solaris 11, OpenBSD and NetBSD
  28. // sizeof(dest) is OK on Linux and FreeBSD
  29. size_t addr_len = sizeof(sockaddr_in);
  30. if (toIP.GetVersion() == 6)
  31. addr_len = sizeof(sockaddr_in6);
  32. msgh.msg_namelen = addr_len;
  33.  
  34. if ((((struct sockaddr*)&dest)->sa_family == AF_INET6)) {
  35. struct in6_pktinfo *pkt;
  36.  
  37. msgh.msg_control = cbuf;
  38. msgh.msg_controllen = CMSG_SPACE(sizeof(*pkt));
  39.  
  40. cmsg = CMSG_FIRSTHDR(&msgh);
  41. cmsg->cmsg_level = IPPROTO_IPV6;
  42. cmsg->cmsg_type = IPV6_PKTINFO;
  43. cmsg->cmsg_len = CMSG_LEN(sizeof(*pkt));
  44.  
  45. pkt = (struct in6_pktinfo *) CMSG_DATA(cmsg);
  46. memset(pkt, 0, sizeof(*pkt));
  47. pkt->ipi6_addr = src;
  48. msgh.msg_controllen = cmsg->cmsg_len;
  49. } else
  50. {
  51. #if defined(IP_PKTINFO) && !defined(P_NETBSD) // Linux and Solaris 11 (NetBSD 7 only has incomplete IP_PKTINFO support)
  52. struct in_pktinfo *pkt;
  53. msgh.msg_control = cbuf;
  54. msgh.msg_controllen = CMSG_SPACE(sizeof(*pkt));
  55.  
  56. cmsg = CMSG_FIRSTHDR(&msgh);
  57. cmsg->cmsg_level = IPPROTO_IP;
  58. cmsg->cmsg_type = IP_PKTINFO;
  59. cmsg->cmsg_len = CMSG_LEN(sizeof(*pkt));
  60.  
  61. pkt = (struct in_pktinfo *) CMSG_DATA(cmsg);
  62. memset(pkt, 0, sizeof(*pkt));
  63. pkt->ipi_spec_dst = src;
  64. #else
  65. #ifdef IP_SENDSRCADDR // FreeBSD
  66. struct in_addr *in;
  67.  
  68. msgh.msg_control = cbuf;
  69. msgh.msg_controllen = CMSG_SPACE(sizeof(*in));
  70.  
  71. cmsg = CMSG_FIRSTHDR(&msgh);
  72. cmsg->cmsg_level = IPPROTO_IP;
  73. cmsg->cmsg_type = IP_SENDSRCADDR;
  74. cmsg->cmsg_len = CMSG_LEN(sizeof(*in));
  75.  
  76. in = (struct in_addr *) CMSG_DATA(cmsg);
  77. *in = src;
  78. #endif // IP_SENDSRCADDR
  79. #endif // IP_PKTINFO else
  80. }
  81.  
  82. ssize_t bytesSent = sendmsg(fd, &msgh, 0);
  83. if (bytesSent < 0) {
  84. PTRACE(5, "RTPtSend error " << strerror(errno));
  85. }
  86.  
  87. return bytesSent;
  88. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement