1 #pragma once 2 3 #include <linux/if.h> 4 #include <linux/if_packet.h> 5 #include <net/ethernet.h> 6 #include <netinet/in.h> 7 #include <sys/ioctl.h> 8 #include <sys/socket.h> 9 10 #include <functional> 11 #include <string> 12 13 namespace net 14 { 15 16 class IFaceBase 17 { 18 public: 19 explicit IFaceBase(const std::string& name); 20 virtual ~IFaceBase() = default; 21 22 /** @brief Get the index of the network interface corresponding 23 * to this object. 24 */ 25 int get_index() const; 26 27 /** @brief Set interface flags using provided socket. 28 * 29 * @param[in] sockfd - Socket to use for SIOCSIFFLAGS ioctl call. 30 * @param[in] flags - Flags to set. 31 */ 32 int set_sock_flags(int sockfd, short flags) const; 33 34 /** @brief Clear interface flags using provided socket. 35 * 36 * @param[in] sockfd - Socket to use for SIOCSIFFLAGS/SIOCGIFFLAGS 37 * ioctl call. 38 * @param[in] flags - Flags to clear. 39 */ 40 int clear_sock_flags(int sockfd, short flags) const; 41 42 /** @brief Bind given socket to this interface. Similar to bind 43 * syscall, except that it fills in sll_ifindex field 44 * of struct sockaddr_ll with the index of this interface. 45 */ 46 virtual int bind_sock(int sockfd, struct sockaddr_ll* saddr) const = 0; 47 48 protected: 49 std::string name_; 50 51 private: 52 /** @brief Similar to ioctl syscall, but the socket is created inside 53 * the function and the interface name in struct ifreq is 54 * properly populated with the index of this interface. 55 */ 56 virtual int ioctl(int request, struct ifreq* ifr) const = 0; 57 58 /** @brief Similar to ioctl syscall. The interface index in 59 * struct ifreq is 60 * properly populated with the index of this interface. 61 */ 62 virtual int ioctl_sock(int sockfd, int request, 63 struct ifreq* ifr) const = 0; 64 65 /** @brief Modify interface flags, using the given socket for 66 * ioctl call. 67 */ 68 int mod_sock_flags(int sockfd, short flags, bool set) const; 69 }; 70 71 class IFace : public IFaceBase 72 { 73 public: 74 explicit IFace(const std::string& name) : IFaceBase(name) 75 {} 76 77 /** @brief Bind given socket to this interface. Similar to bind 78 * syscall, except that it fills in sll_ifindex field 79 * of struct sockaddr_ll with the index of this interface. 80 */ 81 int bind_sock(int sockfd, struct sockaddr_ll* saddr) const override; 82 83 private: 84 /** @brief Similar to ioctl syscall, but the socket is created inside 85 * the function and the interface name in struct ifreq is 86 * properly populated with the index of this interface. 87 */ 88 int ioctl(int request, struct ifreq* ifr) const override; 89 /** @brief Similar to ioctl syscall. The interface index in 90 * struct ifreq is 91 * properly populated with the index of this interface. 92 */ 93 int ioctl_sock(int sockfd, int request, struct ifreq* ifr) const override; 94 }; 95 96 } // namespace net 97