1 /*
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 * Description: implementation for nat64 API
15 * Author: NA
16 * Create: 2020
17 */
18
19 #include <stdint.h>
20 #include "lwip/opt.h"
21 #if LWIP_NAT64
22 #include "lwip/nat64_api.h"
23 #include "lwip/nat64.h"
24 #include "lwip/nat64_addr.h"
25 #include "lwip/netifapi.h"
26 #include "lwip/nat64_v4_dhcpc.h"
27 #include "rpl_common.h"
28
29 static err_t
lwip_nat64_translate(lwip_nat64_entry_t * nate,nat64_entry_t * dst)30 lwip_nat64_translate(lwip_nat64_entry_t *nate, nat64_entry_t *dst)
31 {
32 int ret;
33
34 ret = memcpy_s(dst->mac.addr, NETIF_MAX_HWADDR_LEN, nate->mac, NETIF_MAX_HWADDR_LEN);
35 if (ret != EOK) {
36 return ERR_MEM;
37 }
38 dst->mac.addrlen = NETIF_MAX_HWADDR_LEN;
39
40 #if !LWIP_NAT64_MIN_SUBSTITUTE
41 dst->ip.addr = nate->ip;
42 #endif
43
44 dst->lifetime = nate->lifetime;
45 dst->conn_time = nate->conn_time;
46 dst->state = nate->state;
47 dst->dao_sn = nate->dao_sn;
48 dst->mnid = nate->mnid;
49 dst->orig_mnid = nate->orig_mnid;
50 return ERR_OK;
51 }
52
53 static err_t
lwip_nat64_copy(nat64_entry_t * nate,void * data)54 lwip_nat64_copy(nat64_entry_t *nate, void *data)
55 {
56 lwip_nate_arg_t *arg = (lwip_nate_arg_t *)data;
57 lwip_nat64_entry_t *dst = NULL;
58 int ret;
59
60 if (arg->index >= arg->cnt) {
61 return ERR_VAL;
62 }
63 if ((arg->is_all == lwIP_FALSE) && (nate->nat64_sync == lwIP_TRUE)) {
64 return ERR_OK;
65 }
66 if (nate->state != NAT64_STATE_ESTABLISH) {
67 return ERR_OK;
68 }
69 dst = &arg->nate[arg->index];
70
71 ret = memcpy_s(dst->mac, NETIF_MAX_HWADDR_LEN, nate->mac.addr, nate->mac.addrlen);
72 if (ret != EOK) {
73 return ERR_MEM;
74 }
75
76 dst->ip = nate->ip.addr;
77 dst->lifetime = nate->lifetime;
78 dst->conn_time = nate->conn_time;
79 dst->state = nate->state;
80 dst->dao_sn = nate->dao_sn;
81 dst->mnid = rpl_get_mbr_mnid();
82 dst->orig_mnid = nate->orig_mnid;
83 dst->nat64_sync = lwIP_TRUE;
84
85 arg->index++;
86 return ERR_OK;
87 }
88
89 static err_t
lwip_nat64_get(struct netif * nif,void * arg)90 lwip_nat64_get(struct netif *nif, void *arg)
91 {
92 lwip_nate_arg_t *nate_arg = (lwip_nate_arg_t *)arg;
93 nate_arg->index = 0;
94 (void)nat64_entry_traverse(lwip_nat64_copy, arg);
95
96 LWIP_UNUSED_ARG(nif);
97 return ERR_OK;
98 }
99
100 static err_t
lwip_nat64_get_cnt(struct netif * nif,void * arg)101 lwip_nat64_get_cnt(struct netif *nif, void *arg)
102 {
103 LWIP_UNUSED_ARG(nif);
104 lwip_nate_arg_t *nate_arg = (lwip_nate_arg_t *)arg;
105 nate_arg->index = 0;
106 int state = 0;
107 nat64_entry_t *nate = NULL;
108 while ((nate = nat64_get_next_inuse_entry(&state)) != NULL) {
109 if (nate_arg->type == NAT64_ENTRY_GET_ALL) {
110 if (nate->state == NAT64_STATE_ESTABLISH) {
111 nate_arg->index++;
112 }
113 } else if ((nate_arg->type == NAT64_ENERY_GET_SYNC) && (nate->nat64_sync != lwIP_TRUE)) {
114 if (nate->state == NAT64_STATE_ESTABLISH) {
115 nate_arg->index++;
116 }
117 }
118 }
119
120 return ERR_OK;
121 }
122
123 static void
lwip_nat64_handle_add(nat64_entry_t * dst_nate,nat64_entry_t * nate_exist,u8_t mbr_mnid)124 lwip_nat64_handle_add(nat64_entry_t *dst_nate, nat64_entry_t *nate_exist, u8_t mbr_mnid)
125 {
126 err_t ret;
127 if (dst_nate->mnid == mbr_mnid) {
128 return;
129 }
130 if ((nate_exist != NULL) && (nate_exist->mnid != dst_nate->mnid)) {
131 if (nate_exist->nat64_sync == lwIP_FALSE) {
132 if (nate_exist->conn_time < dst_nate->conn_time) {
133 return;
134 }
135 ret = nat64_dhcp_stop(nat64_netif_get(), &(nate_exist->mac), lwIP_FALSE);
136 if (ret != ERR_OK) {
137 LWIP_DEBUGF(NAT64_DEBUG, ("stop nat64 dhcp proxy fail\n"));
138 }
139 }
140 (void)nat64_entry_update(dst_nate, lwIP_TRUE);
141 return;
142 }
143 (void)nat64_entry_add_new(dst_nate);
144 }
145
146 static err_t
lwip_nat64_handle(struct netif * nif,void * arg)147 lwip_nat64_handle(struct netif *nif, void *arg)
148 {
149 nat64_entry_t dst_nate;
150 u8_t mbr_mnid;
151 (void)memset_s(&dst_nate, sizeof(nat64_entry_t), 0, sizeof(nat64_entry_t));
152
153 mbr_mnid = rpl_get_mbr_mnid();
154
155 lwip_nate_arg_t *lwip_nate = (lwip_nate_arg_t *)arg;
156
157 (void)lwip_nat64_translate(lwip_nate->nate, &dst_nate);
158
159 nat64_entry_t *nate_exist = NULL;
160 nate_exist = nat64_entry_lookup_by_mac(&dst_nate.mac);
161
162 switch (lwip_nate->type) {
163 case NAT64_ENTRY_ADD:
164 lwip_nat64_handle_add(&dst_nate, nate_exist, mbr_mnid);
165 break;
166 case NAT64_ENTRY_DEL:
167 if (nate_exist != NULL) {
168 if ((nate_exist->mnid == dst_nate.mnid) && (nate_exist->nat64_sync == lwIP_TRUE)) {
169 (void)nat64_entry_remove(nate_exist, lwIP_FALSE);
170 }
171 }
172 break;
173 case NAT64_ENTRY_UPDATE:
174 if (dst_nate.mnid == mbr_mnid) {
175 break;
176 }
177 if ((nate_exist != NULL) && (nate_exist->mnid == dst_nate.mnid) &&
178 (nate_exist->nat64_sync == lwIP_TRUE)) {
179 (void)nat64_entry_update(&dst_nate, lwIP_TRUE);
180 }
181 break;
182 default:
183 break;
184 }
185 LWIP_UNUSED_ARG(nif);
186 return ERR_OK;
187 }
188
189 int
lwip_nat64_entry_delete(lwip_nat64_entry_t * nate)190 lwip_nat64_entry_delete(lwip_nat64_entry_t *nate)
191 {
192 lwip_nate_arg_t arg;
193 err_t ret;
194 if (nate == NULL) {
195 return ERR_VAL;
196 }
197
198 arg.nate = nate;
199 arg.type = NAT64_ENTRY_DEL;
200
201 ret = netifapi_call_argcb(lwip_nat64_handle, (void *)&arg);
202 if (ret != ERR_OK) {
203 return ERR_VAL;
204 }
205 return ERR_OK;
206 }
207
208 int
lwip_nat64_entry_add(lwip_nat64_entry_t * nate)209 lwip_nat64_entry_add(lwip_nat64_entry_t *nate)
210 {
211 lwip_nate_arg_t arg;
212 err_t ret;
213 if (nate == NULL) {
214 return ERR_VAL;
215 }
216
217 arg.nate = nate;
218 arg.type = NAT64_ENTRY_ADD;
219
220 ret = netifapi_call_argcb(lwip_nat64_handle, (void *)&arg);
221 if (ret != ERR_OK) {
222 return ERR_VAL;
223 }
224 return ERR_OK;
225 }
226
227 int
lwip_nat64_entry_update(lwip_nat64_entry_t * nate)228 lwip_nat64_entry_update(lwip_nat64_entry_t *nate)
229 {
230 lwip_nate_arg_t arg;
231 err_t ret;
232 if (nate == NULL) {
233 return ERR_VAL;
234 }
235
236 arg.nate = nate;
237 arg.type = NAT64_ENTRY_UPDATE;
238
239 ret = netifapi_call_argcb(lwip_nat64_handle, (void *)&arg);
240 if (ret != ERR_OK) {
241 return ERR_VAL;
242 }
243 return ERR_OK;
244 }
245
246 int
lwip_nat64_entry_get(lwip_nat64_entry_t * nate,uint16_t cnt,uint8_t is_all)247 lwip_nat64_entry_get(lwip_nat64_entry_t *nate, uint16_t cnt, uint8_t is_all)
248 {
249 lwip_nate_arg_t arg;
250 err_t ret;
251
252 if ((nate == NULL) || (cnt == 0)) {
253 return -1;
254 }
255
256 arg.nate = nate;
257 arg.cnt = cnt;
258 arg.is_all = is_all;
259
260 ret = netifapi_call_argcb(lwip_nat64_get, &arg);
261 if (ret != ERR_OK) {
262 return -1;
263 }
264
265 return arg.index;
266 }
267
268 uint16_t
lwip_nat64_entry_cnt(uint8_t type)269 lwip_nat64_entry_cnt(uint8_t type)
270 {
271 err_t ret;
272 lwip_nate_arg_t arg;
273 (void)memset_s(&arg, sizeof(lwip_nate_arg_t), 0, sizeof(lwip_nate_arg_t));
274 arg.type = type;
275 ret = netifapi_call_argcb(lwip_nat64_get_cnt, &arg);
276 if (ret != ERR_OK) {
277 return 0;
278 }
279 return arg.index;
280 }
281
282 int
lwip_nat64_sync_entry_remove(uint8_t mnid)283 lwip_nat64_sync_entry_remove(uint8_t mnid)
284 {
285 uint8_t arg = mnid;
286 err_t ret;
287 ret = netifapi_call_argcb(nat64_entry_remove_by_mnid, &arg);
288 if (ret != ERR_OK) {
289 return -1;
290 }
291
292 return ERR_OK;
293 }
294
295 static err_t
nat64_clients_mac_get(struct netif * netif,void * arg)296 nat64_clients_mac_get(struct netif *netif, void *arg)
297 {
298 struct mesh_clients_mac_info *clis_info = (struct mesh_clients_mac_info *)arg;
299 int state = 0;
300 nat64_entry_t *nate = NULL;
301 struct mesh_client_mac_info *cli_mac = NULL;
302 u16_t cnt = 0;
303
304 (void)netif;
305
306 if ((clis_info == NULL) || (clis_info->num == 0)) {
307 LWIP_DEBUGF(NAT64_DEBUG, ("nat64_clients_mac_get: invalid arg\n"));
308 return ERR_ARG;
309 }
310
311 while (((nate = nat64_get_next_inuse_entry(&state)) != NULL) && (cnt < clis_info->num)) {
312 cli_mac = &((clis_info->clis)[cnt]);
313 (void)memcpy_s(cli_mac->mac, NETIF_MAX_HWADDR_LEN, nate->mac.addr, NETIF_MAX_HWADDR_LEN);
314 cli_mac->mac_len = nate->mac.addrlen;
315 cnt++;
316 }
317 clis_info->num = cnt;
318 return ERR_OK;
319 }
320
321 static err_t
nat64_client_address_find(struct netif * netif,void * cli_address)322 nat64_client_address_find(struct netif *netif, void *cli_address)
323 {
324 struct mesh_client_address *cli_info = (struct mesh_client_address *)cli_address;
325 nat64_entry_t *nate = NULL;
326 linklayer_addr_t lladdr = {0};
327
328 (void)netif;
329
330 if (cli_info == NULL) {
331 LWIP_DEBUGF(NAT64_DEBUG, ("nat64_client_address_find: invalid arg\n"));
332 return ERR_ARG;
333 }
334
335 (void)memcpy_s(lladdr.addr, NETIF_MAX_HWADDR_LEN, cli_info->mac, NETIF_MAX_HWADDR_LEN);
336 lladdr.addrlen = cli_info->mac_len;
337 nate = nat64_entry_lookup_by_mac((const linklayer_addr_t *)&lladdr);
338 if (nate == NULL) {
339 LWIP_DEBUGF(NAT64_DEBUG, ("nat64_client_address_find: no entry\n"));
340 return ERR_VAL;
341 }
342 cli_info->ip4addr.addr = 0;
343 (void)nat64_entry_to4(nate, &(cli_info->ip4addr));
344 (void)memset_s(&(cli_info->ip6addr), sizeof(ip6_addr_t), 0, sizeof(ip6_addr_t));
345 (void)nat64_entry_to6(nate, &(cli_info->ip6addr));
346 cli_info->is_sync = nate->nat64_sync;
347
348 return ERR_OK;
349 }
350
351 err_t
lwip_nat64_clients_mac_get(struct mesh_clients_mac_info * clis_info)352 lwip_nat64_clients_mac_get(struct mesh_clients_mac_info *clis_info)
353 {
354 return netifapi_call_argcb(nat64_clients_mac_get, (void *)clis_info);
355 }
356
357 err_t
lwip_nat64_client_address_find(struct mesh_client_address * cli_address)358 lwip_nat64_client_address_find(struct mesh_client_address *cli_address)
359 {
360 return netifapi_call_argcb(nat64_client_address_find, (void *)cli_address);
361 }
362 #endif
363
364