summaryrefslogtreecommitdiffstats
path: root/src/lib/dhcp/pkt_filter.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/dhcp/pkt_filter.h')
-rw-r--r--src/lib/dhcp/pkt_filter.h139
1 files changed, 139 insertions, 0 deletions
diff --git a/src/lib/dhcp/pkt_filter.h b/src/lib/dhcp/pkt_filter.h
new file mode 100644
index 0000000..e175bef
--- /dev/null
+++ b/src/lib/dhcp/pkt_filter.h
@@ -0,0 +1,139 @@
+// Copyright (C) 2013-2017 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef PKT_FILTER_H
+#define PKT_FILTER_H
+
+#include <dhcp/pkt4.h>
+#include <asiolink/io_address.h>
+#include <boost/shared_ptr.hpp>
+
+namespace isc {
+namespace dhcp {
+
+/// @brief Exception thrown when invalid packet filter object specified.
+class InvalidPacketFilter : public Exception {
+public:
+ InvalidPacketFilter(const char* file, size_t line, const char* what) :
+ isc::Exception(file, line, what) { };
+};
+
+/// Forward declaration to the structure describing a socket.
+struct SocketInfo;
+
+/// Forward declaration to the class representing interface
+class Iface;
+
+/// @brief Abstract packet handling class
+///
+/// This class represents low level method to send and receive DHCP packet.
+/// Different methods, represented by classes derived from this class, use
+/// different socket families and socket types. Also, various packet filtering
+/// methods can be implemented by derived classes, e.g. Linux Packet
+/// Filtering (LPF) or Berkeley Packet Filtering (BPF).
+///
+/// Low-level code operating on sockets may require special privileges to execute.
+/// For example: opening raw socket or opening socket on low port number requires
+/// root privileges. This makes it impossible or very hard to unit test the IfaceMgr.
+/// In order to overcome this problem, it is recommended to create mock object derived
+/// from this class that mimics the behavior of the real packet handling class making
+/// IfaceMgr testable.
+class PktFilter {
+public:
+
+ /// @brief Virtual Destructor
+ virtual ~PktFilter() { }
+
+ /// @brief Check if packet can be sent to the host without address directly.
+ ///
+ /// Checks if the Packet Filter class has capability to send a packet
+ /// directly to the client having no address assigned. This capability
+ /// is used by DHCPv4 servers which respond to the clients they assign
+ /// addresses to. Not all classes derived from PktFilter support this
+ /// because it requires injection of the destination host HW address to
+ /// the link layer header of the packet.
+ ///
+ /// @return true of the direct response is supported.
+ virtual bool isDirectResponseSupported() const = 0;
+
+ /// @brief Open primary and fallback socket.
+ ///
+ /// A method implementation in the derived class may open one or two
+ /// sockets:
+ /// - a primary socket - used for communication with clients. DHCP messages
+ /// received using this socket are processed and the same socket is used
+ /// to send a response to the client.
+ /// - a fallback socket which is optionally opened if there is a need for
+ /// the presence of the socket which can be bound to a specific IP address
+ /// and UDP port (e.g. raw primary socket can't be). For the details, see
+ /// the documentation of @c isc::dhcp::SocketInfo.
+ ///
+ /// @param iface Interface descriptor.
+ /// @param addr Address on the interface to be used to send packets.
+ /// @param port Port number.
+ /// @param receive_bcast Configure socket to receive broadcast messages
+ /// @param send_bcast configure socket to send broadcast messages.
+ ///
+ /// @return A structure describing a primary and fallback socket.
+ virtual SocketInfo openSocket(Iface& iface,
+ const isc::asiolink::IOAddress& addr,
+ const uint16_t port,
+ const bool receive_bcast,
+ const bool send_bcast) = 0;
+
+ /// @brief Receive packet over specified socket.
+ ///
+ /// @param iface interface
+ /// @param socket_info structure holding socket information
+ ///
+ /// @return Received packet
+ virtual Pkt4Ptr receive(Iface& iface,
+ const SocketInfo& socket_info) = 0;
+
+ /// @brief Send packet over specified socket.
+ ///
+ /// @param iface interface to be used to send packet
+ /// @param sockfd socket descriptor
+ /// @param pkt packet to be sent
+ ///
+ /// @return result of sending the packet. It is 0 if successful.
+ virtual int send(const Iface& iface, uint16_t sockfd,
+ const Pkt4Ptr& pkt) = 0;
+
+protected:
+
+ /// @brief Default implementation to open a fallback socket.
+ ///
+ /// This method provides a means to open a fallback socket and bind it
+ /// to a given IPv4 address and UDP port. This function may be used by the
+ /// derived classes to create a fallback socket. It can be overridden
+ /// in the derived classes if it happens to be insufficient on some
+ /// environments.
+ ///
+ /// The fallback socket is meant to be opened together with the other socket
+ /// (a.k.a. primary socket) used to receive and handle DHCPv4 traffic. The
+ /// traffic received through the fallback should be dropped. The reasoning
+ /// behind opening the fallback socket is explained in the documentation of
+ /// @c isc::dhcp::SocketInfo structure.
+ ///
+ /// @param addr An IPv4 address to bind the socket to.
+ /// @param port A port number to bind socket to.
+ ///
+ /// @return A fallback socket descriptor. This descriptor should be assigned
+ /// to the @c fallbackfd_ field of the @c isc::dhcp::SocketInfo structure.
+ /// @throw isc::dhcp::SocketConfigError if socket opening, binding or
+ /// configuration fails.
+ virtual int openFallbackSocket(const isc::asiolink::IOAddress& addr,
+ const uint16_t port);
+};
+
+/// Pointer to a PktFilter object.
+typedef boost::shared_ptr<PktFilter> PktFilterPtr;
+
+} // namespace isc::dhcp
+} // namespace isc
+
+#endif // PKT_FILTER_H