blob: ebd6edc2f244e0130825445920ed6ff49eceb2fe [file] [log] [blame]
William A. Kennington III7d6fa422021-02-08 17:04:02 -08001#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
13namespace net
14{
15
16class 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
71class 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