xref: /openbmc/google-misc/dhcp-done/subprojects/ncsid/src/net_iface.h (revision 7d6fa42fd19cf708de1257414bb375d5a552b722)
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