1 /*
2  * Copyright (C) 2021 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 #ifdef __cplusplus
20 
21 #include <aidl/android/hardware/net/nlinterceptor/InterceptedSocket.h>
22 #include <android-base/unique_fd.h>
23 #include <linux/netlink.h>
24 
25 #include <optional>
26 #include <string>
27 
28 namespace android::nlinterceptor {
29 
30 /**
31  * Wrapper structure to uniquely identifies a socket that Netlink Interceptor
32  * has allocated for us.
33  */
34 struct InterceptedSocket {
35     uint32_t nlFamily;
36     uint32_t portId;
37 
38     InterceptedSocket(
39         ::aidl::android::hardware::net::nlinterceptor::InterceptedSocket sock);
40     InterceptedSocket(uint32_t nlFamily, uint32_t portId);
41 
42     bool operator<(const InterceptedSocket& other) const;
43     operator sockaddr_nl() const;
44     operator ::aidl::android::hardware::net::nlinterceptor::InterceptedSocket()
45         const;
46 };
47 
48 /**
49  * Output stream operator for InterceptedSocket
50  */
51 std::ostream& operator<<(std::ostream& os, const InterceptedSocket& sock);
52 
53 /**
54  * Checks if an instance Netlink Interceptor exists.
55  *
56  * \return true if supported, false if not.
57  */
58 bool isEnabled();
59 
60 /**
61  * Asks Netlink Interceptor to allocate a socket to which we can send Netlink
62  * traffic.
63  *
64  * \param clientSocket - File descriptor for the client's Netlink socket.
65  * \param clientName - Human readable name of the client application.
66  * \return Identifier for the socket created by Netlink Interceptor, nullopt on
67  * error.
68  */
69 std::optional<InterceptedSocket> createSocket(base::borrowed_fd clientSocket,
70                                               const std::string& clientName);
71 
72 /**
73  * Asks Netlink Interceptor to close a socket that it created for us previously,
74  * if it exists.
75  *
76  * \param sock - Identifier for the socket created by Netlink Interceptor.
77  */
78 void closeSocket(const InterceptedSocket& sock);
79 
80 /**
81  * Asks Netlink Interceptor to subscribe a socket that it created for us
82  * previously to a specified multicast group.
83  *
84  * \param sock - Identifier for the socket created by Netlink Interceptor.
85  * \param group - A single Netlink multicast group for which we would like to
86  * receive events.
87  * \return true for success, false if something went wrong.
88  */
89 bool subscribe(const InterceptedSocket& sock, uint32_t group);
90 
91 /**
92  * Asks Netlink Interceptor to unsubscribe a socket that it created for us
93  * previously from a specified multicast group.
94  *
95  * \param sock - Identifier for the socket created by Netlink Interceptor.
96  * \param group - A single Netlink multicast group for which we no longer wish
97  * to receive events.
98  * \return true for success, false if something went wrong.
99  */
100 bool unsubscribe(const InterceptedSocket& sock, uint32_t group);
101 }  // namespace android::nlinterceptor
102 #endif
103 
104 #ifdef __cplusplus
105 extern "C" {
106 #endif
107 
108 // C wrappers for libnlinterceptor
109 struct android_nlinterceptor_InterceptedSocket {
110     uint32_t nlFamily;
111     uint32_t portId;
112 };
113 
114 bool android_nlinterceptor_isEnabled();
115 
116 bool android_nlinterceptor_createSocket(
117     int clientSocketFd, const char* clientName,
118     struct android_nlinterceptor_InterceptedSocket* interceptedSocket);
119 
120 void android_nlinterceptor_closeSocket(struct android_nlinterceptor_InterceptedSocket sock);
121 
122 bool android_nlinterceptor_subscribe(struct android_nlinterceptor_InterceptedSocket sock,
123                                      uint32_t group);
124 
125 bool android_nlinterceptor_unsubscribe(struct android_nlinterceptor_InterceptedSocket sock,
126                                        uint32_t group);
127 
128 #ifdef __cplusplus
129 }
130 #endif
131