7e5e17340470c809f13cb6bee64bb5f81c7b4301
[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 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //    David Wagner <dw6@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief SocketSink non-inline non-template implementation */
25
26 // Custom includes
27 #include "SocketSink.hh"
28 #include <senf/Socket/ClientSocketHandle.hh>
29
30 #define prefix_
31
32 prefix_ senf::ppi::IPv4SourceForcingDgramWriter::IPv4SourceForcingDgramWriter()
33 {
34     source_ = senf::INet4Address::from_string("0.0.0.0");
35     destination_ = senf::INet4Address::from_string("0.0.0.0");
36     protocolId_ = 0;
37 }
38
39 prefix_ senf::ppi::IPv4SourceForcingDgramWriter::
40 IPv4SourceForcingDgramWriter(senf::INet4Address sourceAddr, senf::INet4SocketAddress destAddr)
41 {
42     source(sourceAddr);
43     destination(destAddr);
44 }
45
46 prefix_ void senf::ppi::IPv4SourceForcingDgramWriter::source(senf::INet4Address & source)
47 {
48     source_ = source;
49 }
50
51 prefix_ void senf::ppi::IPv4SourceForcingDgramWriter::destination(senf::INet4SocketAddress & dest)
52 {
53     destination_ = dest.address();
54     protocolId_ = dest.port();
55 }
56
57 prefix_ bool senf::ppi::IPv4SourceForcingDgramWriter::operator()(Handle & handle,
58                                                                  Packet const & packet)
59 {
60     return sendtoandfrom(
61             handle.fd(),
62             reinterpret_cast<void*> (&*packet.data().begin()),
63             packet.size(),
64             reinterpret_cast<in_addr*> (&destination_),
65             protocolId_,
66             reinterpret_cast<in_addr*> (&source_)) > 0;
67 }
68
69 prefix_ int senf::ppi::IPv4SourceForcingDgramWriter::sendtoandfrom(
70         int sock,
71         const void *data,
72         size_t dataLen,
73         const in_addr *dst,
74         int port,
75         const in_addr *src)
76 {
77     uint8_t cbuf[CMSG_SPACE(sizeof(struct in_pktinfo))];
78     struct cmsghdr *c = (struct cmsghdr *)cbuf;
79     struct in_pktinfo *pi;
80     struct iovec iov;
81     struct msghdr h;
82
83     c->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
84     c->cmsg_level = IPPROTO_IP;
85     c->cmsg_type = IP_PKTINFO;
86
87     pi = (struct in_pktinfo *)CMSG_DATA(c);
88     pi->ipi_ifindex = 0;
89     memcpy(&pi->ipi_addr, src, 16);
90
91     iov.iov_base = (void *)data;
92     iov.iov_len = dataLen;
93
94     sockaddr_in dstpeer;
95     memset(&dstpeer, 0, sizeof(dstpeer));
96     dstpeer.sin_family = AF_INET;
97     dstpeer.sin_addr = *dst;
98     dstpeer.sin_port = htons(port);
99
100     memset(&h, 0, sizeof(h));
101     h.msg_name = (struct sockaddr *)&dstpeer;
102     h.msg_namelen = sizeof(dstpeer);
103     h.msg_iov = &iov;
104     h.msg_iovlen = 1;
105     h.msg_control = c;
106     h.msg_controllen = sizeof(cbuf);
107
108     return sendmsg(sock, &h, 0);
109 }
110
111 prefix_ senf::ppi::IPv6SourceForcingDgramWriter::IPv6SourceForcingDgramWriter()
112 {
113     source_ = senf::INet6Address::from_string("0::0");
114     destination_ = senf::INet6Address::from_string("0::0");
115     protocolId_ = 0;
116 }
117
118 prefix_ senf::ppi::IPv6SourceForcingDgramWriter::
119 IPv6SourceForcingDgramWriter(senf::INet6Address sourceAddr, senf::INet6SocketAddress destAddr)
120 {
121     source(sourceAddr);
122     destination(destAddr);
123 }
124
125 prefix_ void senf::ppi::IPv6SourceForcingDgramWriter::source(senf::INet6Address & source)
126 {
127     source_ = source;
128 }
129
130 prefix_ void senf::ppi::IPv6SourceForcingDgramWriter::destination(senf::INet6SocketAddress & dest)
131 {
132     destination_ = dest.address();
133     protocolId_ = dest.port();
134 }
135
136 prefix_ bool senf::ppi::IPv6SourceForcingDgramWriter::operator()(Handle & handle,
137                                                                  Packet const & packet)
138 {
139     return sendtoandfrom(
140             handle.fd(),
141             reinterpret_cast<void*> (&*packet.data().begin()),
142             packet.size(),
143             reinterpret_cast<in6_addr*> (&destination_),
144             protocolId_,
145             reinterpret_cast<in6_addr*> (&source_)) > 0;
146 }
147
148 prefix_ int senf::ppi::IPv6SourceForcingDgramWriter::sendtoandfrom(
149         int sock,
150         const void *data,
151         size_t dataLen,
152         const in6_addr *dst,
153         int port,
154         const in6_addr *src)
155 {
156     uint8_t cbuf[CMSG_SPACE(sizeof(struct in6_pktinfo))];
157     struct cmsghdr *c = (struct cmsghdr *)cbuf;
158     struct in6_pktinfo *pi;
159     struct iovec iov;
160     struct msghdr h;
161
162     c->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
163     c->cmsg_level = IPPROTO_IPV6;
164     c->cmsg_type = IPV6_PKTINFO;
165
166     pi = (struct in6_pktinfo *)CMSG_DATA(c);
167     pi->ipi6_ifindex = 0;
168     memcpy(&pi->ipi6_addr, src, 16);
169
170     iov.iov_base = (void *)data;
171     iov.iov_len = dataLen;
172
173     sockaddr_in6 dstpeer;
174     memset(&dstpeer, 0, sizeof(dstpeer));
175     dstpeer.sin6_family = AF_INET6;
176     dstpeer.sin6_addr = *dst;
177     dstpeer.sin6_port = htons(port);
178
179     memset(&h, 0, sizeof(h));
180     h.msg_name = (struct sockaddr *)&dstpeer;
181     h.msg_namelen = sizeof(dstpeer);
182     h.msg_iov = &iov;
183     h.msg_iovlen = 1;
184     h.msg_control = c;
185     h.msg_controllen = sizeof(cbuf);
186
187     return sendmsg(sock, &h, 0);
188 }
189
190 #undef prefix_