From: Marcin Siodelski Date: Mon, 29 Apr 2013 17:05:22 +0000 (+0200) Subject: [2902] Set valid destination HW address when replying to the DHCP4 client. X-Git-Tag: bind10-1.2.0beta1-release~440^2~14 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4f47c644ff2ba7b3d062e51d4b7eef4f87417301;p=thirdparty%2Fkea.git [2902] Set valid destination HW address when replying to the DHCP4 client. --- diff --git a/src/bin/dhcp4/dhcp4_srv.cc b/src/bin/dhcp4/dhcp4_srv.cc index b0908bb754..41233e2f4e 100644 --- a/src/bin/dhcp4/dhcp4_srv.cc +++ b/src/bin/dhcp4/dhcp4_srv.cc @@ -371,6 +371,17 @@ Dhcpv4Srv::copyDefaultFields(const Pkt4Ptr& question, Pkt4Ptr& answer) { if (client_id) { answer->addOption(client_id); } + + // If src/dest HW addresses are used by the packet filtering class + // we need to copy them as well. + HWAddrPtr src_hw_addr = question->getLocalHWAddr(); + HWAddrPtr dst_hw_addr = question->getRemoteHWAddr(); + if (src_hw_addr) { + answer->setRemoteHWAddr(src_hw_addr); + } + if (dst_hw_addr) { + answer->setLocalHWAddr(dst_hw_addr); + } } void diff --git a/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc b/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc index daa94d72fa..f74c2408d5 100644 --- a/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc +++ b/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc @@ -173,6 +173,11 @@ public: EXPECT_EQ(q->getIface(), a->getIface()); EXPECT_EQ(q->getIndex(), a->getIndex()); EXPECT_EQ(q->getGiaddr(), a->getGiaddr()); + // When processing an incoming packet the remote address + // is copied as a src address, and the source address is + // copied as a remote address to the response. + EXPECT_TRUE(q->getLocalHWAddr() == a->getRemoteHWAddr()); + EXPECT_TRUE(q->getRemoteHWAddr() == a->getLocalHWAddr()); // Check that bare minimum of required options are there. // We don't check options requested by a client. Those @@ -374,12 +379,19 @@ public: mac[i] = i*10; } + vector dst_mac(6); + for (int i = 0; i < 6; i++) { + dst_mac[i] = i * 20; + } + boost::shared_ptr req(new Pkt4(msg_type, 1234)); boost::shared_ptr rsp; req->setIface("eth0"); req->setIndex(17); + req->setRemoteHWAddr(1, 6, dst_mac); req->setHWAddr(1, 6, mac); + req->setLocalHWAddr(1, 6, mac); req->setRemoteAddr(IOAddress(client_addr)); req->setGiaddr(relay_addr); diff --git a/src/lib/dhcp/pkt_filter_lpf.cc b/src/lib/dhcp/pkt_filter_lpf.cc index beffa8b8ff..59637078dc 100644 --- a/src/lib/dhcp/pkt_filter_lpf.cc +++ b/src/lib/dhcp/pkt_filter_lpf.cc @@ -153,6 +153,8 @@ PktFilterLPF::receive(const Iface& iface, const SocketInfo& socket_info) { pkt->setRemoteAddr(dummy_pkt->getRemoteAddr()); pkt->setLocalPort(dummy_pkt->getLocalPort()); pkt->setRemotePort(dummy_pkt->getRemotePort()); + pkt->setLocalHWAddr(dummy_pkt->getLocalHWAddr()); + pkt->setRemoteHWAddr(dummy_pkt->getRemoteHWAddr()); return (pkt); } @@ -163,9 +165,12 @@ PktFilterLPF::send(const Iface& iface, uint16_t sockfd, const Pkt4Ptr& pkt) { OutputBuffer buf(14); // Ethernet frame header - std::vector dest_addr = pkt->getHWAddr()->hwaddr_; - if (dest_addr.empty()) { + HWAddrPtr hwaddr = pkt->getRemoteHWAddr(); + std::vector dest_addr; + if (!hwaddr) { dest_addr.resize(HWAddr::ETHERNET_HWADDR_LEN); + } else { + dest_addr = pkt->getRemoteHWAddr()->hwaddr_; } writeEthernetHeader(iface.getMac(), &dest_addr[0], buf);