20 PktFilterInet::PktFilterInet()
21 : recv_control_buf_len_(CMSG_SPACE(sizeof(struct in6_pktinfo))),
22 send_control_buf_len_(CMSG_SPACE(sizeof(struct in6_pktinfo))),
23 recv_control_buf_(new char[recv_control_buf_len_]),
24 send_control_buf_(new char[send_control_buf_len_])
32 const bool receive_bcast,
33 const bool send_bcast) {
35 struct sockaddr_in addr4;
36 memset(&addr4, 0,
sizeof(sockaddr));
37 addr4.sin_family = AF_INET;
38 addr4.sin_port = htons(port);
43 addr4.sin_addr.s_addr = INADDR_ANY;
45 addr4.sin_addr.s_addr = htonl(addr.
toUint32());
48 int sock = socket(AF_INET, SOCK_DGRAM, 0);
54 if (fcntl(sock, F_SETFD, FD_CLOEXEC) < 0) {
57 <<
" on socket " << sock);
60 #ifdef SO_BINDTODEVICE 63 if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, iface.
getName().c_str(),
64 iface.
getName().length() + 1) < 0) {
67 <<
" on socket " << sock);
75 if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &flag,
sizeof(flag)) < 0) {
78 <<
" on socket " << sock);
82 if (bind(sock, (
struct sockaddr *)&addr4,
sizeof(addr4)) < 0) {
91 #if defined (IP_PKTINFO) && defined (OS_LINUX) 93 if (setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &flag,
sizeof(flag)) != 0) {
99 #elif defined (IP_RECVDSTADDR) && defined (OS_BSD) 101 if (setsockopt(sock, IPPROTO_IP, IP_RECVDSTADDR, &flag,
sizeof(flag)) != 0) {
114 struct sockaddr_in from_addr;
117 memset(&recv_control_buf_[0], 0, recv_control_buf_len_);
118 memset(&from_addr, 0,
sizeof(from_addr));
122 memset(&m, 0,
sizeof(m));
125 m.msg_name = &from_addr;
126 m.msg_namelen =
sizeof(from_addr);
129 v.iov_base = static_cast<void*>(buf);
140 m.msg_control = &recv_control_buf_[0];
141 m.msg_controllen = recv_control_buf_len_;
143 int result = recvmsg(socket_info.
sockfd_, &m, 0);
151 pkt->updateTimestamp();
153 unsigned int ifindex = iface.
getIndex();
155 IOAddress from(htonl(from_addr.sin_addr.s_addr));
156 uint16_t from_port = htons(from_addr.sin_port);
161 pkt->setIndex(ifindex);
162 pkt->setIface(iface.
getName());
163 pkt->setRemoteAddr(from);
164 pkt->setRemotePort(from_port);
165 pkt->setLocalPort(socket_info.
port_);
170 #if defined (IP_PKTINFO) && defined (OS_LINUX) 171 struct in_pktinfo* pktinfo;
172 struct cmsghdr* cmsg = CMSG_FIRSTHDR(&m);
174 while (cmsg != NULL) {
175 if ((cmsg->cmsg_level == IPPROTO_IP) &&
176 (cmsg->cmsg_type == IP_PKTINFO)) {
177 pktinfo = reinterpret_cast<struct in_pktinfo*>(CMSG_DATA(cmsg));
179 pkt->setIndex(pktinfo->ipi_ifindex);
180 pkt->setLocalAddr(
IOAddress(htonl(pktinfo->ipi_addr.s_addr)));
191 cmsg = CMSG_NXTHDR(&m, cmsg);
194 #elif defined (IP_RECVDSTADDR) && defined (OS_BSD) 195 struct in_addr* to_addr;
196 struct cmsghdr* cmsg = CMSG_FIRSTHDR(&m);
198 while (cmsg != NULL) {
199 if ((cmsg->cmsg_level == IPPROTO_IP) &&
200 (cmsg->cmsg_type == IP_RECVDSTADDR)) {
201 to_addr = reinterpret_cast<struct in_addr*>(CMSG_DATA(cmsg));
202 pkt->setLocalAddr(
IOAddress(htonl(to_addr->s_addr)));
205 cmsg = CMSG_NXTHDR(&m, cmsg);
216 memset(&send_control_buf_[0], 0, send_control_buf_len_);
220 memset(&to, 0,
sizeof(to));
221 to.sin_family = AF_INET;
222 to.sin_port = htons(pkt->getRemotePort());
223 to.sin_addr.s_addr = htonl(pkt->getRemoteAddr().toUint32());
227 memset(&m, 0,
sizeof(m));
229 m.msg_namelen =
sizeof(to);
235 memset(&v, 0,
sizeof(v));
238 v.iov_base = const_cast<void *>(pkt->getBuffer().getData());
239 v.iov_len = pkt->getBuffer().getLength();
246 #if defined (IP_PKTINFO) && defined (OS_LINUX) 252 m.msg_control = &send_control_buf_[0];
253 m.msg_controllen = send_control_buf_len_;
254 struct cmsghdr* cmsg = CMSG_FIRSTHDR(&m);
255 cmsg->cmsg_level = IPPROTO_IP;
256 cmsg->cmsg_type = IP_PKTINFO;
257 cmsg->cmsg_len = CMSG_LEN(
sizeof(
struct in_pktinfo));
258 struct in_pktinfo* pktinfo =(
struct in_pktinfo *)CMSG_DATA(cmsg);
259 memset(pktinfo, 0,
sizeof(
struct in_pktinfo));
265 if (pkt->indexSet()) {
266 pktinfo->ipi_ifindex = pkt->getIndex();
271 if (!pkt->getLocalAddr().isV4Zero()) {
272 pktinfo->ipi_spec_dst.s_addr = htonl(pkt->getLocalAddr().toUint32());
275 m.msg_controllen = CMSG_SPACE(
sizeof(
struct in_pktinfo));
278 pkt->updateTimestamp();
280 int result = sendmsg(sockfd, &m, 0);
283 " with an error: " << strerror(errno));
IfaceMgr exception thrown thrown when socket opening or configuration failed.
virtual SocketInfo openSocket(Iface &iface, const isc::asiolink::IOAddress &addr, const uint16_t port, const bool receive_bcast, const bool send_bcast)
Open primary and fallback socket.
Represents a single network interface.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
virtual int send(const Iface &iface, uint16_t sockfd, const Pkt4Ptr &pkt)
Send packet over specified socket.
uint32_t toUint32() const
Converts IPv4 address to uint32_t.
boost::shared_ptr< Pkt4 > Pkt4Ptr
A pointer to Pkt4 object.
uint16_t port_
bound address
std::string getName() const
Returns interface name.
IfaceMgr exception thrown thrown when error occurred during reading data from socket.
bool flag_broadcast_
Flag specifies if selected interface is broadcast capable.
static const uint32_t RCVBUFSIZE
Packet reception buffer size.
Defines the logger used by the top-level component of kea-dhcp-ddns.
Represents DHCPv4 packet.
uint16_t getIndex() const
Returns interface index.
virtual Pkt4Ptr receive(Iface &iface, const SocketInfo &socket_info)
Receive packet over specified socket.
The IOAddress class represents an IP addresses (version agnostic)
IfaceMgr exception thrown thrown when error occurred during sending data through socket.
Holds information about socket.