blob: d44f23c9d8841317d901076790f805d767f0d7a7 [file] [log] [blame]
Brandon Kimdab96f12021-02-18 11:21:37 -08001/*
2 * Copyright 2021 Google LLC
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
William A. Kennington III7d6fa422021-02-08 17:04:02 -080017#pragma once
18
19#include <linux/if.h>
20#include <linux/if_packet.h>
21#include <net/ethernet.h>
22#include <netinet/in.h>
23#include <sys/ioctl.h>
24#include <sys/socket.h>
25
26#include <functional>
27#include <string>
28
29namespace net
30{
31
32class IFaceBase
33{
34 public:
35 explicit IFaceBase(const std::string& name);
36 virtual ~IFaceBase() = default;
37
38 /** @brief Get the index of the network interface corresponding
39 * to this object.
40 */
41 int get_index() const;
42
43 /** @brief Set interface flags using provided socket.
44 *
45 * @param[in] sockfd - Socket to use for SIOCSIFFLAGS ioctl call.
46 * @param[in] flags - Flags to set.
47 */
48 int set_sock_flags(int sockfd, short flags) const;
49
50 /** @brief Clear interface flags using provided socket.
51 *
52 * @param[in] sockfd - Socket to use for SIOCSIFFLAGS/SIOCGIFFLAGS
53 * ioctl call.
54 * @param[in] flags - Flags to clear.
55 */
56 int clear_sock_flags(int sockfd, short flags) const;
57
58 /** @brief Bind given socket to this interface. Similar to bind
59 * syscall, except that it fills in sll_ifindex field
60 * of struct sockaddr_ll with the index of this interface.
61 */
62 virtual int bind_sock(int sockfd, struct sockaddr_ll* saddr) const = 0;
63
64 protected:
65 std::string name_;
66
67 private:
68 /** @brief Similar to ioctl syscall, but the socket is created inside
69 * the function and the interface name in struct ifreq is
70 * properly populated with the index of this interface.
71 */
72 virtual int ioctl(int request, struct ifreq* ifr) const = 0;
73
74 /** @brief Similar to ioctl syscall. The interface index in
75 * struct ifreq is
76 * properly populated with the index of this interface.
77 */
78 virtual int ioctl_sock(int sockfd, int request,
79 struct ifreq* ifr) const = 0;
80
81 /** @brief Modify interface flags, using the given socket for
82 * ioctl call.
83 */
84 int mod_sock_flags(int sockfd, short flags, bool set) const;
85};
86
87class IFace : public IFaceBase
88{
89 public:
Patrick Williams2be45232023-05-10 07:51:22 -050090 explicit IFace(const std::string& name) : IFaceBase(name) {}
William A. Kennington III7d6fa422021-02-08 17:04:02 -080091
92 /** @brief Bind given socket to this interface. Similar to bind
93 * syscall, except that it fills in sll_ifindex field
94 * of struct sockaddr_ll with the index of this interface.
95 */
96 int bind_sock(int sockfd, struct sockaddr_ll* saddr) const override;
97
98 private:
99 /** @brief Similar to ioctl syscall, but the socket is created inside
100 * the function and the interface name in struct ifreq is
101 * properly populated with the index of this interface.
102 */
103 int ioctl(int request, struct ifreq* ifr) const override;
104 /** @brief Similar to ioctl syscall. The interface index in
105 * struct ifreq is
106 * properly populated with the index of this interface.
107 */
108 int ioctl_sock(int sockfd, int request, struct ifreq* ifr) const override;
109};
110
111} // namespace net