• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 dhcp proxy
15  * Author: NA
16  * Create: 2019
17  */
18 #include "lwip/opt.h"
19 #include "lwip/dhcp.h"
20 #if LWIP_NAT64
21 #include "arch/sys_arch.h"
22 #include "lwip/nat64.h"
23 #include "lwip/nat64_addr.h"
24 #include "lwip/nat64_v4_dhcpc.h"
25 #include "lwip/lwip_rpl.h"
26 #include "rpl_event_api.h"
27 
28 err_t
nat64_dhcp_request_ip(struct netif * ntf,const linklayer_addr_t * lladdr,const ip4_addr_t * ip)29 nat64_dhcp_request_ip(struct netif *ntf, const linklayer_addr_t *lladdr, const ip4_addr_t *ip)
30 {
31   err_t ret;
32 #if LWIP_DHCP_SUBSTITUTE
33   dhcp_num_t index = 0;
34 #endif
35   if ((ntf == NULL) || (lladdr == NULL)) {
36     return ERR_ARG;
37   }
38 
39 #if LWIP_DHCP_SUBSTITUTE
40   ret = nat64_entry_mac_to_idx(lladdr->addr, lladdr->addrlen, &index);
41   if (ret != ERR_OK) {
42     return ERR_VAL;
43   }
44 
45   ret = dhcp_substitute_start(ntf, index, ip->addr);
46 #else
47   ret = ERR_ARG;
48 #endif
49 
50   return ret;
51 }
52 
53 err_t
nat64_dhcp_stop(struct netif * ntf,const linklayer_addr_t * lladdr,u8_t now)54 nat64_dhcp_stop(struct netif *ntf, const linklayer_addr_t *lladdr, u8_t now)
55 {
56   err_t ret;
57 #if LWIP_DHCP_SUBSTITUTE
58   dhcp_num_t index = 0;
59 #endif
60   if ((ntf == NULL) || (lladdr == NULL)) {
61     return ERR_ARG;
62   }
63 #if LWIP_DHCP_SUBSTITUTE
64   ret = nat64_entry_mac_to_idx(lladdr->addr, lladdr->addrlen, &index);
65   if (ret != ERR_OK) {
66     return ERR_VAL;
67   }
68 
69   dhcp_substitute_stop(ntf, index, now);
70   ret = ERR_OK;
71 #else
72   ret = ERR_ARG;
73 #endif
74 
75   return ret;
76 }
77 
78 
79 void
nat64_dhcp_ip4_event(const u8_t * mac,u8_t maclen,const ip4_addr_t * ipaddr,int event)80 nat64_dhcp_ip4_event(const u8_t *mac, u8_t maclen, const ip4_addr_t *ipaddr, int event)
81 {
82   nat64_entry_t *entry = NULL;
83   int ret;
84   linklayer_addr_t llmac;
85   if (mac == NULL) {
86     return;
87   }
88 
89   (void)memset_s(&llmac, sizeof(linklayer_addr_t), 0, sizeof(linklayer_addr_t));
90   ret = memcpy_s(llmac.addr, sizeof(llmac.addr), mac, maclen);
91   if (ret != EOK) {
92     LWIP_DEBUGF(NAT64_DEBUG, ("%s:memcpy_s fail(%d)\n", __FUNCTION__, ret));
93     return;
94   }
95   llmac.addrlen = maclen > sizeof(llmac.addr) ? sizeof(llmac.addr) : maclen;
96   entry = nat64_entry_lookup_by_mac(&llmac);
97   if ((entry == NULL) || (entry->nat64_sync == lwIP_TRUE)) {
98     return;
99   }
100 
101   if (((event == NAT64_DHCP_EVENT_OFFER) || (event == NAT64_DHCP_EVENT_RENEW)) &&
102       (ipaddr != NULL)) {
103     if ((entry->state == NAT64_STATE_DHCP_REQUEST) ||
104         (entry->state == NAT64_STATE_ESTABLISH)) {
105       entry->state = NAT64_STATE_ESTABLISH;
106 #if !LWIP_NAT64_MIN_SUBSTITUTE
107       /* dhcp clinet renew its ip, get ipv4 addr may change */
108       if (ip4_addr_isany_val(entry->ip)) {
109         ip4_addr_copy(entry->ip, *ipaddr);
110 #if LWIP_MMBR && LWIP_NAT64_CHANGE_MSG
111         nat64_send_change_entry_msg(entry, RPL_EVT_NODE_NAT64_ADD);
112 #endif /* LWIP_MMBR && LWIP_NAT64_CHANGE_MSG */
113       } else if (!ip4_addr_cmp(ipaddr, &entry->ip)) {
114         ip4_addr_copy(entry->ip, *ipaddr);
115 #if LWIP_MMBR && LWIP_NAT64_CHANGE_MSG
116         nat64_send_change_entry_msg(entry, RPL_EVT_NODE_NAT64_UPDATE);
117       } else {
118         /*
119          * When a node switches from an MBR to another MBR and gets the dhcp event,
120          * it also needs to send the add event because the IPv4 address of the node remains unchanged.
121          */
122         nat64_send_change_entry_msg(entry, RPL_EVT_NODE_NAT64_ADD);
123 #endif /* LWIP_MMBR && LWIP_NAT64_CHANGE_MSG */
124       }
125       ip6_addr_t ip6addr;
126       if (nat64_entry_to6(entry, &ip6addr) == 0) {
127         lwip_notify_rpl_get_ipv4_addr(entry->mnid, &ip6addr);
128       }
129 #else
130       (void)ipaddr;
131 #endif
132       return;
133     }
134   }
135 
136   if (event == NAT64_DHCP_EVENT_RELEASE) {
137     entry->state = NAT64_STATE_DIRECT_RELEASE;
138     entry->lifetime = 0;
139   }
140 }
141 #endif
142