]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[2902] Parse incoming packet's headers on reception.
authorMarcin Siodelski <marcin@isc.org>
Tue, 23 Apr 2013 17:42:00 +0000 (19:42 +0200)
committerMarcin Siodelski <marcin@isc.org>
Tue, 23 Apr 2013 17:42:00 +0000 (19:42 +0200)
src/lib/dhcp/pkt_filter_lpf.cc
src/lib/dhcp/protocol_util.cc

index 83bb707d9c98504b5793eb6d293f57a6d6b9fec0..93aae142d3a977827a87ee29185fab85cfacc6b6 100644 (file)
@@ -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<uint8_t> 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);
 }
index 63bb59dcae0f9762141e3579f65757b05b524ac3..b2b954d07f700a5daebc5b07814f90c8d30b9745 100644 (file)
@@ -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<uint8_t> 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