00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00026
00027 #include "SocketSink.hh"
00028 #include <senf/Socket/ClientSocketHandle.hh>
00029
00030 #define prefix_
00031
00032 prefix_ senf::ppi::IPv4SourceForcingDgramWriter::IPv4SourceForcingDgramWriter()
00033 {
00034 source_ = senf::INet4Address::from_string("0.0.0.0");
00035 destination_ = senf::INet4Address::from_string("0.0.0.0");
00036 protocolId_ = 0;
00037 }
00038
00039 prefix_ senf::ppi::IPv4SourceForcingDgramWriter::
00040 IPv4SourceForcingDgramWriter(senf::INet4Address sourceAddr, senf::INet4SocketAddress destAddr)
00041 {
00042 source(sourceAddr);
00043 destination(destAddr);
00044 }
00045
00046 prefix_ void senf::ppi::IPv4SourceForcingDgramWriter::source(senf::INet4Address & source)
00047 {
00048 source_ = source;
00049 }
00050
00051 prefix_ void senf::ppi::IPv4SourceForcingDgramWriter::destination(senf::INet4SocketAddress & dest)
00052 {
00053 destination_ = dest.address();
00054 protocolId_ = dest.port();
00055 }
00056
00057 prefix_ bool senf::ppi::IPv4SourceForcingDgramWriter::operator()(Handle & handle,
00058 Packet const & packet)
00059 {
00060 return sendtoandfrom(
00061 handle.fd(),
00062 reinterpret_cast<void*> (&*packet.data().begin()),
00063 packet.size(),
00064 reinterpret_cast<in_addr*> (&destination_),
00065 protocolId_,
00066 reinterpret_cast<in_addr*> (&source_)) > 0;
00067 }
00068
00069 prefix_ int senf::ppi::IPv4SourceForcingDgramWriter::sendtoandfrom(
00070 int sock,
00071 const void *data,
00072 size_t dataLen,
00073 const in_addr *dst,
00074 int port,
00075 const in_addr *src)
00076 {
00077 uint8_t cbuf[CMSG_SPACE(sizeof(struct in_pktinfo))];
00078 struct cmsghdr *c = (struct cmsghdr *)cbuf;
00079 struct in_pktinfo *pi;
00080 struct iovec iov;
00081 struct msghdr h;
00082
00083 c->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
00084 c->cmsg_level = IPPROTO_IP;
00085 c->cmsg_type = IP_PKTINFO;
00086
00087 pi = (struct in_pktinfo *)CMSG_DATA(c);
00088 pi->ipi_ifindex = 0;
00089 memcpy(&pi->ipi_addr, src, 16);
00090
00091 iov.iov_base = (void *)data;
00092 iov.iov_len = dataLen;
00093
00094 sockaddr_in dstpeer;
00095 memset(&dstpeer, 0, sizeof(dstpeer));
00096 dstpeer.sin_family = AF_INET;
00097 dstpeer.sin_addr = *dst;
00098 dstpeer.sin_port = htons(port);
00099
00100 memset(&h, 0, sizeof(h));
00101 h.msg_name = (struct sockaddr *)&dstpeer;
00102 h.msg_namelen = sizeof(dstpeer);
00103 h.msg_iov = &iov;
00104 h.msg_iovlen = 1;
00105 h.msg_control = c;
00106 h.msg_controllen = sizeof(cbuf);
00107
00108 return sendmsg(sock, &h, 0);
00109 }
00110
00111 prefix_ senf::ppi::IPv6SourceForcingDgramWriter::IPv6SourceForcingDgramWriter()
00112 {
00113 source_ = senf::INet6Address::from_string("0::0");
00114 destination_ = senf::INet6Address::from_string("0::0");
00115 protocolId_ = 0;
00116 }
00117
00118 prefix_ senf::ppi::IPv6SourceForcingDgramWriter::
00119 IPv6SourceForcingDgramWriter(senf::INet6Address sourceAddr, senf::INet6SocketAddress destAddr)
00120 {
00121 source(sourceAddr);
00122 destination(destAddr);
00123 }
00124
00125 prefix_ void senf::ppi::IPv6SourceForcingDgramWriter::source(senf::INet6Address & source)
00126 {
00127 source_ = source;
00128 }
00129
00130 prefix_ void senf::ppi::IPv6SourceForcingDgramWriter::destination(senf::INet6SocketAddress & dest)
00131 {
00132 destination_ = dest.address();
00133 protocolId_ = dest.port();
00134 }
00135
00136 prefix_ bool senf::ppi::IPv6SourceForcingDgramWriter::operator()(Handle & handle,
00137 Packet const & packet)
00138 {
00139 return sendtoandfrom(
00140 handle.fd(),
00141 reinterpret_cast<void*> (&*packet.data().begin()),
00142 packet.size(),
00143 reinterpret_cast<in6_addr*> (&destination_),
00144 protocolId_,
00145 reinterpret_cast<in6_addr*> (&source_)) > 0;
00146 }
00147
00148 prefix_ int senf::ppi::IPv6SourceForcingDgramWriter::sendtoandfrom(
00149 int sock,
00150 const void *data,
00151 size_t dataLen,
00152 const in6_addr *dst,
00153 int port,
00154 const in6_addr *src)
00155 {
00156 uint8_t cbuf[CMSG_SPACE(sizeof(struct in6_pktinfo))];
00157 struct cmsghdr *c = (struct cmsghdr *)cbuf;
00158 struct in6_pktinfo *pi;
00159 struct iovec iov;
00160 struct msghdr h;
00161
00162 c->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
00163 c->cmsg_level = IPPROTO_IPV6;
00164 c->cmsg_type = IPV6_PKTINFO;
00165
00166 pi = (struct in6_pktinfo *)CMSG_DATA(c);
00167 pi->ipi6_ifindex = 0;
00168 memcpy(&pi->ipi6_addr, src, 16);
00169
00170 iov.iov_base = (void *)data;
00171 iov.iov_len = dataLen;
00172
00173 sockaddr_in6 dstpeer;
00174 memset(&dstpeer, 0, sizeof(dstpeer));
00175 dstpeer.sin6_family = AF_INET6;
00176 dstpeer.sin6_addr = *dst;
00177 dstpeer.sin6_port = htons(port);
00178
00179 memset(&h, 0, sizeof(h));
00180 h.msg_name = (struct sockaddr *)&dstpeer;
00181 h.msg_namelen = sizeof(dstpeer);
00182 h.msg_iov = &iov;
00183 h.msg_iovlen = 1;
00184 h.msg_control = c;
00185 h.msg_controllen = sizeof(cbuf);
00186
00187 return sendmsg(sock, &h, 0);
00188 }
00189
00190 #undef prefix_