Commit afdb6335 authored by Marcin Siodelski's avatar Marcin Siodelski
Browse files

[5003] Minor improvements in the PktFilterInet code.

parent 17b17f73
......@@ -84,8 +84,8 @@ PktFilterInet::openSocket(Iface& iface,
<< "/port=" << port);
}
// if there is no support for IP_PKTINFO, we are really out of luck
// it will be difficult to undersand, where this packet came from
// On Linux systems IP_PKTINFO socket option is supported. This
// option is used to retrieve destination address of the packet.
#if defined (IP_PKTINFO) && defined (OS_LINUX)
int flag = 1;
if (setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &flag, sizeof(flag)) != 0) {
......@@ -93,6 +93,7 @@ PktFilterInet::openSocket(Iface& iface,
isc_throw(SocketConfigError, "setsockopt: IP_PKTINFO: failed.");
}
// On BSD systems IP_RECVDSTADDR is used instead of IP_PKTINFO.
#elif defined (IP_RECVDSTADDR) && defined (OS_BSD)
int flag = 1;
if (setsockopt(sock, IPPROTO_IP, IP_RECVDSTADDR, &flag, sizeof(flag)) != 0) {
......@@ -164,19 +165,15 @@ PktFilterInet::receive(Iface& iface, const SocketInfo& socket_info) {
struct cmsghdr* cmsg;
cmsg = CMSG_FIRSTHDR(&m);
// In the future the OS-specific code may be abstracted to a different
// file but for now we keep it here because there is no code yet, which
// is specific to non-Linux systems.
// Linux systems support IP_PKTINFO option which is used to retrieve the
// destination address of the received packet. On BSD systems IP_RECVDSTADDR
// is used instead.
#if defined (IP_PKTINFO) && defined (OS_LINUX)
struct in_pktinfo* pktinfo;
struct in_addr to_addr;
memset(&to_addr, 0, sizeof(to_addr));
while (cmsg != NULL) {
if ((cmsg->cmsg_level == IPPROTO_IP) &&
(cmsg->cmsg_type == IP_PKTINFO)) {
pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsg);
pktinfo = reinterpret_cast<struct in_pktinfo*>(CMSG_DATA(cmsg));
pkt->setIndex(pktinfo->ipi_ifindex);
pkt->setLocalAddr(IOAddress(htonl(pktinfo->ipi_addr.s_addr)));
......@@ -199,7 +196,7 @@ PktFilterInet::receive(Iface& iface, const SocketInfo& socket_info) {
while (cmsg != NULL) {
if ((cmsg->cmsg_level == IPPROTO_IP) &&
(cmsg->cmsg_type == IP_RECVDSTADDR)) {
to_addr = (struct in_addr*)CMSG_DATA(cmsg);
to_addr = reinterpret_cast<struct in_addr*>(CMSG_DATA(cmsg));
pkt->setLocalAddr(IOAddress(htonl(to_addr->s_addr)));
break;
}
......@@ -261,23 +258,6 @@ PktFilterInet::send(const Iface&, uint16_t sockfd,
pktinfo->ipi_ifindex = pkt->getIndex();
pktinfo->ipi_spec_dst.s_addr = htonl(pkt->getLocalAddr()); // set the source IP address
m.msg_controllen = CMSG_SPACE(sizeof(struct in_pktinfo));
#elif defined (IP_RECVDSTADDR) && defined (OS_BSD)
/* // Setting the interface is a bit more involved.
//
// We have to create a "control message", and set that to
// define the IPv4 packet information. We set the source address
// to handle correctly interfaces with multiple addresses.
m.msg_control = &control_buf_[0];
m.msg_controllen = control_buf_len_;
struct cmsghdr* cmsg = CMSG_FIRSTHDR(&m);
cmsg->cmsg_level = IPPROTO_IP;
cmsg->cmsg_type = IP_RECVDSTADDR;
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
struct in_addr* pktinfo =(struct in_addr *)CMSG_DATA(cmsg);
memset(pktinfo, 0, sizeof(struct in_addr));
pktinfo->s_addr = htonl(pkt->getLocalAddr());
m.msg_controllen = CMSG_SPACE(sizeof(struct in_addr)); */
#endif
pkt->updateTimestamp();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment