From: Marcin Siodelski Date: Tue, 23 Apr 2013 17:42:00 +0000 (+0200) Subject: [2902] Parse incoming packet's headers on reception. X-Git-Tag: bind10-1.2.0beta1-release~440^2~30 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f5b9768aba32bb7673458eeeb14f0f56734427bc;p=thirdparty%2Fkea.git [2902] Parse incoming packet's headers on reception. --- diff --git a/src/lib/dhcp/pkt_filter_lpf.cc b/src/lib/dhcp/pkt_filter_lpf.cc index 83bb707d9c..93aae142d3 100644 --- a/src/lib/dhcp/pkt_filter_lpf.cc +++ b/src/lib/dhcp/pkt_filter_lpf.cc @@ -56,19 +56,29 @@ PktFilterLPF::openSocket(const Iface& iface, const isc::asiolink::IOAddress&, Pkt4Ptr PktFilterLPF::receive(const Iface& iface, const SocketInfo& socket_info) { // @todo: implement this function - uint8_t buf[IfaceMgr::RCVBUFSIZE]; - int data_len = read(socket_info.sockfd_, buf, sizeof(buf)); + uint8_t raw_buf[IfaceMgr::RCVBUFSIZE]; + int data_len = read(socket_info.sockfd_, raw_buf, sizeof(raw_buf)); if (data_len <= 0) { return Pkt4Ptr(); } - // Length of the Ethernet, IP and UDP. - int data_offset = 42; - Pkt4Ptr pkt = Pkt4Ptr(new Pkt4(buf + data_offset, - data_len - data_offset)); + InputBuffer buf(raw_buf, data_len); + + Pkt4Ptr dummy_pkt = Pkt4Ptr(new Pkt4(DHCPDISCOVER, 0)); + decodeEthernetHeader(buf, dummy_pkt); + decodeIpUdpHeader(buf, dummy_pkt); + + std::vector dhcp_buf; + buf.readVector(dhcp_buf, buf.getLength() - buf.getPosition()); + + Pkt4Ptr pkt = Pkt4Ptr(new Pkt4(&dhcp_buf[0], dhcp_buf.size())); pkt->setIndex(iface.getIndex()); pkt->setIface(iface.getName()); + pkt->setLocalAddr(dummy_pkt->getLocalAddr()); + pkt->setRemoteAddr(dummy_pkt->getRemoteAddr()); + pkt->setLocalPort(dummy_pkt->getLocalPort()); + pkt->setRemotePort(dummy_pkt->getRemotePort()); return (pkt); } diff --git a/src/lib/dhcp/protocol_util.cc b/src/lib/dhcp/protocol_util.cc index 63bb59dcae..b2b954d07f 100644 --- a/src/lib/dhcp/protocol_util.cc +++ b/src/lib/dhcp/protocol_util.cc @@ -45,15 +45,18 @@ decodeEthernetHeader(InputBuffer& buf, Pkt4Ptr& pkt) { // error that we want to detect in the compilation time. BOOST_STATIC_ASSERT(ETHERNET_HEADER_LEN > HWAddr::ETHERNET_HWADDR_LEN); + // Remember initial position. + size_t start_pos = buf.getPosition(); + // Skip destination address. - buf.setPosition(HWAddr::ETHERNET_HWADDR_LEN); + buf.setPosition(start_pos + HWAddr::ETHERNET_HWADDR_LEN); // Read the source HW address. std::vector dest_addr; buf.readVector(dest_addr, HWAddr::ETHERNET_HWADDR_LEN); // Set the address we have read. pkt->setHWAddr(HWTYPE_ETHERNET, HWAddr::ETHERNET_HWADDR_LEN, dest_addr); // Move the buffer read pointer to the end of the Ethernet frame header. - buf.setPosition(ETHERNET_HEADER_LEN); + buf.setPosition(start_pos + ETHERNET_HEADER_LEN); } void @@ -76,6 +79,9 @@ decodeIpUdpHeader(InputBuffer& buf, Pkt4Ptr& pkt) { BOOST_STATIC_ASSERT(IP_SRC_ADDR_OFFSET < MIN_IP_HEADER_LEN); + // Remember initial position of the read pointer. + size_t start_pos = buf.getPosition(); + // Read IP header length (mask most significant bits as they indicate IP version). uint8_t ip_len = buf.readUint8() & 0xF; // IP length is the number of 4 byte chunks that construct IPv4 header. @@ -85,18 +91,22 @@ decodeIpUdpHeader(InputBuffer& buf, Pkt4Ptr& pkt) { } // Seek to the position of source IP address. - buf.setPosition(IP_SRC_ADDR_OFFSET); + buf.setPosition(start_pos + IP_SRC_ADDR_OFFSET); // Read source address. pkt->setRemoteAddr(IOAddress(buf.readUint32())); // Read destination address. pkt->setLocalAddr(IOAddress(buf.readUint32())); + + // Skip IP header options (if any). + buf.setPosition(start_pos + ip_len * 4); + // Read source port from UDP header. pkt->setRemotePort(buf.readUint16()); // Read destination port from UDP header. pkt->setLocalPort(buf.readUint16()); // Set the pointer position to the tail of UDP header. - buf.setPosition(ip_len * 4 + UDP_HEADER_LEN); + buf.setPosition(start_pos + ip_len * 4 + UDP_HEADER_LEN); } void