From: Marcin Siodelski Date: Mon, 5 Sep 2016 13:47:32 +0000 (+0200) Subject: [5003] Minor improvements in the PktFilterInet code. X-Git-Tag: trac5006_base~25 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=afdb633536a131706c591d636d0cfb340fcc2139;p=thirdparty%2Fkea.git [5003] Minor improvements in the PktFilterInet code. --- diff --git a/src/lib/dhcp/pkt_filter_inet.cc b/src/lib/dhcp/pkt_filter_inet.cc index 73b75536cb..5c61b514d3 100644 --- a/src/lib/dhcp/pkt_filter_inet.cc +++ b/src/lib/dhcp/pkt_filter_inet.cc @@ -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(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(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();