21PktFilterInet::CONTROL_BUF_LEN = CMSG_SPACE(
sizeof(
struct in6_pktinfo));
27 const bool receive_bcast,
28 const bool send_bcast) {
29 struct sockaddr_in addr4;
30 memset(&addr4, 0,
sizeof(sockaddr));
31 addr4.sin_family = AF_INET;
32 addr4.sin_port = htons(port);
37 addr4.sin_addr.s_addr = INADDR_ANY;
39 addr4.sin_addr.s_addr = htonl(addr.
toUint32());
42 int sock = socket(AF_INET, SOCK_DGRAM, 0);
48 if (fcntl(sock, F_SETFD, FD_CLOEXEC) < 0) {
51 <<
" on socket " << sock);
57 if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, iface.
getName().c_str(),
58 iface.
getName().length() + 1) < 0) {
61 <<
" on socket " << sock);
69 if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &flag,
sizeof(flag)) < 0) {
72 <<
" on socket " << sock);
76 if (bind(sock, (
struct sockaddr *)&addr4,
sizeof(addr4)) < 0) {
85#if defined (IP_PKTINFO) && defined (OS_LINUX)
87 if (setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &flag,
sizeof(flag)) != 0) {
93#elif defined (IP_RECVDSTADDR) && defined (OS_BSD)
95 if (setsockopt(sock, IPPROTO_IP, IP_RECVDSTADDR, &flag,
sizeof(flag)) != 0) {
108 struct sockaddr_in from_addr;
110 uint8_t control_buf[CONTROL_BUF_LEN];
112 memset(&control_buf[0], 0, CONTROL_BUF_LEN);
113 memset(&from_addr, 0,
sizeof(from_addr));
117 memset(&m, 0,
sizeof(m));
120 m.msg_name = &from_addr;
121 m.msg_namelen =
sizeof(from_addr);
124 v.iov_base =
static_cast<void*
>(buf);
135 m.msg_control = &control_buf[0];
136 m.msg_controllen = CONTROL_BUF_LEN;
138 int result = recvmsg(socket_info.
sockfd_, &m, 0);
146 pkt->updateTimestamp();
148 unsigned int ifindex = iface.
getIndex();
150 IOAddress from(htonl(from_addr.sin_addr.s_addr));
151 uint16_t from_port = htons(from_addr.sin_port);
156 pkt->setIndex(ifindex);
157 pkt->setIface(iface.
getName());
158 pkt->setRemoteAddr(from);
159 pkt->setRemotePort(from_port);
160 pkt->setLocalPort(socket_info.
port_);
165#if defined (IP_PKTINFO) && defined (OS_LINUX)
166 struct in_pktinfo* pktinfo;
167 struct cmsghdr* cmsg = CMSG_FIRSTHDR(&m);
169 while (cmsg != NULL) {
170 if ((cmsg->cmsg_level == IPPROTO_IP) &&
171 (cmsg->cmsg_type == IP_PKTINFO)) {
172 pktinfo =
reinterpret_cast<struct in_pktinfo*
>(CMSG_DATA(cmsg));
174 pkt->setIndex(pktinfo->ipi_ifindex);
175 pkt->setLocalAddr(
IOAddress(htonl(pktinfo->ipi_addr.s_addr)));
186 cmsg = CMSG_NXTHDR(&m, cmsg);
189#elif defined (IP_RECVDSTADDR) && defined (OS_BSD)
190 struct in_addr* to_addr;
191 struct cmsghdr* cmsg = CMSG_FIRSTHDR(&m);
193 while (cmsg != NULL) {
194 if ((cmsg->cmsg_level == IPPROTO_IP) &&
195 (cmsg->cmsg_type == IP_RECVDSTADDR)) {
196 to_addr =
reinterpret_cast<struct in_addr*
>(CMSG_DATA(cmsg));
197 pkt->setLocalAddr(
IOAddress(htonl(to_addr->s_addr)));
200 cmsg = CMSG_NXTHDR(&m, cmsg);
210 uint8_t control_buf[CONTROL_BUF_LEN];
211 memset(&control_buf[0], 0, CONTROL_BUF_LEN);
215 memset(&to, 0,
sizeof(to));
216 to.sin_family = AF_INET;
217 to.sin_port = htons(pkt->getRemotePort());
218 to.sin_addr.s_addr = htonl(pkt->getRemoteAddr().toUint32());
222 memset(&m, 0,
sizeof(m));
224 m.msg_namelen =
sizeof(to);
230 memset(&v, 0,
sizeof(v));
233 v.iov_base =
const_cast<void *
>(pkt->getBuffer().getData());
234 v.iov_len = pkt->getBuffer().getLength();
241#if defined (IP_PKTINFO) && defined (OS_LINUX)
247 m.msg_control = &control_buf[0];
248 m.msg_controllen = CONTROL_BUF_LEN;
249 struct cmsghdr* cmsg = CMSG_FIRSTHDR(&m);
250 cmsg->cmsg_level = IPPROTO_IP;
251 cmsg->cmsg_type = IP_PKTINFO;
252 cmsg->cmsg_len = CMSG_LEN(
sizeof(
struct in_pktinfo));
253 struct in_pktinfo* pktinfo =(
struct in_pktinfo *)CMSG_DATA(cmsg);
254 memset(pktinfo, 0,
sizeof(
struct in_pktinfo));
260 if (pkt->indexSet()) {
261 pktinfo->ipi_ifindex = pkt->getIndex();
266 if (!pkt->getLocalAddr().isV4Zero()) {
267 pktinfo->ipi_spec_dst.s_addr = htonl(pkt->getLocalAddr().toUint32());
270 m.msg_controllen = CMSG_SPACE(
sizeof(
struct in_pktinfo));
273 pkt->updateTimestamp();
275 int result = sendmsg(sockfd, &m, 0);
278 " with an error: " << strerror(errno));
The IOAddress class represents an IP addresses (version agnostic)
uint32_t toUint32() const
Converts IPv4 address to uint32_t.
static const uint32_t RCVBUFSIZE
Packet reception buffer size.
Represents a single network interface.
std::string getName() const
Returns interface name.
unsigned int getIndex() const
Returns interface index.
bool flag_broadcast_
Flag specifies if selected interface is broadcast capable.
Represents DHCPv4 packet.
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.
virtual int send(const Iface &iface, uint16_t sockfd, const Pkt4Ptr &pkt)
Send packet over specified socket.
virtual Pkt4Ptr receive(Iface &iface, const SocketInfo &socket_info)
Receive packet over specified socket.
IfaceMgr exception thrown thrown when socket opening or configuration failed.
IfaceMgr exception thrown thrown when error occurred during reading data from socket.
IfaceMgr exception thrown thrown when error occurred during sending data through socket.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
boost::shared_ptr< Pkt4 > Pkt4Ptr
A pointer to Pkt4 object.
Defines the logger used by the top-level component of kea-lfc.
Holds information about socket.
uint16_t port_
bound address