switch to new MPL based Fraunhofer FOKUS Public License
[senf.git] / senf / PPI / SocketSink.cc
1 // $Id: SocketSink.cc 661 2008-02-05 09:53:54Z dw6 $
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //    David Wagner <dw6@berlios.de>
6 //
7 // The contents of this file are subject to the Fraunhofer FOKUS Public License
8 // Version 1.0 (the "License"); you may not use this file except in compliance
9 // with the License. You may obtain a copy of the License at 
10 // http://senf.berlios.de/license.html
11 //
12 // The Fraunhofer FOKUS Public License Version 1.0 is based on, 
13 // but modifies the Mozilla Public License Version 1.1.
14 // See the full license text for the amendments.
15 //
16 // Software distributed under the License is distributed on an "AS IS" basis, 
17 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
18 // for the specific language governing rights and limitations under the License.
19 //
20 // The Original Code is Fraunhofer FOKUS code.
21 //
22 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. 
23 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
24 // All Rights Reserved.
25 //
26 // Contributor(s):
27
28 /** \file
29     \brief SocketSink non-inline non-template implementation */
30
31 // Custom includes
32 #include "SocketSink.hh"
33 #include <senf/Socket/ClientSocketHandle.hh>
34
35 #define prefix_
36
37 prefix_ senf::ppi::IPv4SourceForcingDgramWriter::IPv4SourceForcingDgramWriter()
38 {
39     source_ = senf::INet4Address::from_string("0.0.0.0");
40     destination_ = senf::INet4Address::from_string("0.0.0.0");
41     protocolId_ = 0;
42 }
43
44 prefix_ senf::ppi::IPv4SourceForcingDgramWriter::
45 IPv4SourceForcingDgramWriter(senf::INet4Address sourceAddr, senf::INet4SocketAddress destAddr)
46 {
47     source(sourceAddr);
48     destination(destAddr);
49 }
50
51 prefix_ void senf::ppi::IPv4SourceForcingDgramWriter::source(senf::INet4Address & source)
52 {
53     source_ = source;
54 }
55
56 prefix_ void senf::ppi::IPv4SourceForcingDgramWriter::destination(senf::INet4SocketAddress & dest)
57 {
58     destination_ = dest.address();
59     protocolId_ = dest.port();
60 }
61
62 prefix_ bool senf::ppi::IPv4SourceForcingDgramWriter::operator()(Handle & handle,
63                                                                  Packet const & packet)
64 {
65     return sendtoandfrom(
66             handle.fd(),
67             reinterpret_cast<void*> (&*packet.data().begin()),
68             packet.size(),
69             reinterpret_cast<in_addr*> (&destination_),
70             protocolId_,
71             reinterpret_cast<in_addr*> (&source_)) > 0;
72 }
73
74 prefix_ int senf::ppi::IPv4SourceForcingDgramWriter::sendtoandfrom(
75         int sock,
76         const void *data,
77         size_t dataLen,
78         const in_addr *dst,
79         int port,
80         const in_addr *src)
81 {
82     uint8_t cbuf[CMSG_SPACE(sizeof(struct in_pktinfo))];
83     struct cmsghdr *c = (struct cmsghdr *)cbuf;
84     struct in_pktinfo *pi;
85     struct iovec iov;
86     struct msghdr h;
87
88     c->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
89     c->cmsg_level = IPPROTO_IP;
90     c->cmsg_type = IP_PKTINFO;
91
92     pi = (struct in_pktinfo *)CMSG_DATA(c);
93     pi->ipi_ifindex = 0;
94     memcpy(&pi->ipi_addr, src, 16);
95
96     iov.iov_base = (void *)data;
97     iov.iov_len = dataLen;
98
99     sockaddr_in dstpeer;
100     memset(&dstpeer, 0, sizeof(dstpeer));
101     dstpeer.sin_family = AF_INET;
102     dstpeer.sin_addr = *dst;
103     dstpeer.sin_port = htons(port);
104
105     memset(&h, 0, sizeof(h));
106     h.msg_name = (struct sockaddr *)&dstpeer;
107     h.msg_namelen = sizeof(dstpeer);
108     h.msg_iov = &iov;
109     h.msg_iovlen = 1;
110     h.msg_control = c;
111     h.msg_controllen = sizeof(cbuf);
112
113     return sendmsg(sock, &h, 0);
114 }
115
116 prefix_ senf::ppi::IPv6SourceForcingDgramWriter::IPv6SourceForcingDgramWriter()
117 {
118     source_ = senf::INet6Address::from_string("0::0");
119     destination_ = senf::INet6Address::from_string("0::0");
120     protocolId_ = 0;
121 }
122
123 prefix_ senf::ppi::IPv6SourceForcingDgramWriter::
124 IPv6SourceForcingDgramWriter(senf::INet6Address sourceAddr, senf::INet6SocketAddress destAddr)
125 {
126     source(sourceAddr);
127     destination(destAddr);
128 }
129
130 prefix_ void senf::ppi::IPv6SourceForcingDgramWriter::source(senf::INet6Address & source)
131 {
132     source_ = source;
133 }
134
135 prefix_ void senf::ppi::IPv6SourceForcingDgramWriter::destination(senf::INet6SocketAddress & dest)
136 {
137     destination_ = dest.address();
138     protocolId_ = dest.port();
139 }
140
141 prefix_ bool senf::ppi::IPv6SourceForcingDgramWriter::operator()(Handle & handle,
142                                                                  Packet const & packet)
143 {
144     return sendtoandfrom(
145             handle.fd(),
146             reinterpret_cast<void*> (&*packet.data().begin()),
147             packet.size(),
148             reinterpret_cast<in6_addr*> (&destination_),
149             protocolId_,
150             reinterpret_cast<in6_addr*> (&source_)) > 0;
151 }
152
153 prefix_ int senf::ppi::IPv6SourceForcingDgramWriter::sendtoandfrom(
154         int sock,
155         const void *data,
156         size_t dataLen,
157         const in6_addr *dst,
158         int port,
159         const in6_addr *src)
160 {
161     uint8_t cbuf[CMSG_SPACE(sizeof(struct in6_pktinfo))];
162     struct cmsghdr *c = (struct cmsghdr *)cbuf;
163     struct in6_pktinfo *pi;
164     struct iovec iov;
165     struct msghdr h;
166
167     c->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
168     c->cmsg_level = IPPROTO_IPV6;
169     c->cmsg_type = IPV6_PKTINFO;
170
171     pi = (struct in6_pktinfo *)CMSG_DATA(c);
172     pi->ipi6_ifindex = 0;
173     memcpy(&pi->ipi6_addr, src, 16);
174
175     iov.iov_base = (void *)data;
176     iov.iov_len = dataLen;
177
178     sockaddr_in6 dstpeer;
179     memset(&dstpeer, 0, sizeof(dstpeer));
180     dstpeer.sin6_family = AF_INET6;
181     dstpeer.sin6_addr = *dst;
182     dstpeer.sin6_port = htons(port);
183
184     memset(&h, 0, sizeof(h));
185     h.msg_name = (struct sockaddr *)&dstpeer;
186     h.msg_namelen = sizeof(dstpeer);
187     h.msg_iov = &iov;
188     h.msg_iovlen = 1;
189     h.msg_control = c;
190     h.msg_controllen = sizeof(cbuf);
191
192     return sendmsg(sock, &h, 0);
193 }
194
195 #undef prefix_