blob: d7c2b4c9b038c3bf2cf9755449cb5ba4c17cf47f [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:
90 explicit IFace(const std::string& name) : IFaceBase(name)
91 {}
92
93 /** @brief Bind given socket to this interface. Similar to bind
94 * syscall, except that it fills in sll_ifindex field
95 * of struct sockaddr_ll with the index of this interface.
96 */
97 int bind_sock(int sockfd, struct sockaddr_ll* saddr) const override;
98
99 private:
100 /** @brief Similar to ioctl syscall, but the socket is created inside
101 * the function and the interface name in struct ifreq is
102 * properly populated with the index of this interface.
103 */
104 int ioctl(int request, struct ifreq* ifr) const override;
105 /** @brief Similar to ioctl syscall. The interface index in
106 * struct ifreq is
107 * properly populated with the index of this interface.
108 */
109 int ioctl_sock(int sockfd, int request, struct ifreq* ifr) const override;
110};
111
112} // namespace net