1 /*
2  * Copyright (C) 2019 The Android Open Source Project
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 
17 #pragma once
18 
19 #include <linux/if_ether.h>
20 
21 #include <array>
22 #include <optional>
23 #include <set>
24 #include <string>
25 
26 namespace android::netdevice {
27 
28 typedef std::array<uint8_t, ETH_ALEN> hwaddr_t;
29 
30 /**
31  * Configures libnetdevice to use other socket domain than AF_INET,
32  * what requires less permissive SEPolicy rules for a given process.
33  *
34  * In such case, the process would only be able to control interfaces of a given kind.
35 
36  * \param domain Socket domain to use (e.g. AF_CAN), see socket(2) for details
37  */
38 void useSocketDomain(int domain);
39 
40 /**
41  * Checks, if the network interface exists.
42  *
43  * \param ifname Interface to check
44  * \return true if it exists, false otherwise
45  */
46 bool exists(std::string_view ifname);
47 
48 /**
49  * Checks if network interface is up.
50  *
51  * \param ifname Interface to check
52  * \return true/false if the check succeeded, nullopt otherwise
53  */
54 std::optional<bool> isUp(std::string_view ifname);
55 
56 /**
57  * Interface condition to wait for.
58  */
59 enum class WaitCondition {
60     /**
61      * Interface is present (but not necessarily up).
62      */
63     PRESENT,
64 
65     /**
66      * Interface is up.
67      */
68     PRESENT_AND_UP,
69 
70     /**
71      * Interface is up and with IPv4 address configured.
72      */
73     PRESENT_AND_IPV4,
74 
75     /**
76      * Interface is down or not present (disconnected) at all.
77      */
78     DOWN_OR_GONE,
79 };
80 
81 enum class Quantifier {
82     ALL_OF,
83     ANY_OF,
84 };
85 
86 /**
87  * Listens for interface changes until anticipated condition takes place.
88  *
89  * \param ifnames List of interfaces to watch for.
90  * \param cnd Awaited condition.
91  * \param quant Whether all interfaces need to satisfy the condition or just one satistying
92  *        interface should stop the wait.
93  * \return name of one interface that satisfied the condition
94  */
95 std::optional<std::string> waitFor(std::set<std::string> ifnames, WaitCondition cnd,
96                                    Quantifier quant = Quantifier::ALL_OF);
97 
98 /**
99  * Brings network interface up.
100  *
101  * \param ifname Interface to bring up
102  * \return true in case of success, false otherwise
103  */
104 bool up(std::string_view ifname);
105 
106 /**
107  * Brings network interface down.
108  *
109  * \param ifname Interface to bring down
110  * \return true in case of success, false otherwise
111  */
112 bool down(std::string_view ifname);
113 
114 /**
115  * Retrieves all IPv4 addresses of a given interface.
116  *
117  * \param ifname Interface to query
118  * \return list of IPv4 addresses of this interface
119  */
120 std::set<std::string> getAllAddr4(std::string_view ifname);
121 
122 /**
123  * Set IPv4 address on a given interface.
124  *
125  * This function will overwrite any other existing IPv4 addresses.
126  *
127  * \param ifname Interface to modify
128  * \param addr IPv4 address to set
129  * \return true in case of success, false otherwise
130  */
131 bool setAddr4(std::string_view ifname, std::string_view addr,
132               std::optional<uint8_t> prefixlen = std::nullopt);
133 
134 /**
135  * Add new IPv4 address to a given interface.
136  *
137  * Please note this doesn't remove existing IPv4 addresses.
138  *
139  * \param ifname Interface to modify
140  * \param addr IPv4 address to add
141  * \param prefixlen IPv4 netmask length
142  * \return true in case of success, false otherwise
143  */
144 bool addAddr4(std::string_view ifname, std::string_view addr, uint8_t prefixlen = 24);
145 
146 /**
147  * Adds virtual link.
148  *
149  * \param dev the name of the new virtual device
150  * \param type the type of the new device
151  * \return true in case of success, false otherwise
152  */
153 bool add(std::string_view dev, std::string_view type);
154 
155 /**
156  * Deletes virtual link.
157  *
158  * \param dev the name of the device to remove
159  * \return true in case of success, false otherwise
160  */
161 bool del(std::string_view dev);
162 
163 /**
164  * Fetches interface's hardware address.
165  *
166  * \param ifname Interface name
167  * \return Hardware address (MAC address) or nullopt if the lookup failed
168  */
169 std::optional<hwaddr_t> getHwAddr(std::string_view ifname);
170 
171 /**
172  * Changes interface's hardware address.
173  *
174  * \param ifname Interface name
175  * \param hwaddr New hardware address to set
176  */
177 bool setHwAddr(std::string_view ifname, hwaddr_t hwaddr);
178 
179 }  // namespace android::netdevice
180 
181 bool operator==(const android::netdevice::hwaddr_t lhs, const unsigned char rhs[ETH_ALEN]);
182