1 /*
2 * Copyright (c) 2022-2022 Huawei Technologies Co., Ltd. All rights reserved.
3 *
4 * UniProton is licensed under Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 * http://license.coscl.org.cn/MulanPSL2
8 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
9 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
10 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
11 * See the Mulan PSL v2 for more details.
12 * Create: 2022-09-21
13 * Description: 网络
14 */
15
16 #include <lwip/sys.h>
17 #include <lwip/etharp.h>
18 #include <lwip/netifapi.h>
19 #include <lwip/priv/api_msg.h>
20
21 #if LWIP_DHCP
22 #include <lwip/dhcp.h>
23 #include <lwip/prot/dhcp.h>
24
OsDhcpIsBound(struct netif * netif)25 err_t OsDhcpIsBound(struct netif *netif)
26 {
27 struct dhcp *dhcp = NULL;
28
29 LWIP_ERROR("netif != NULL", (netif != NULL), return ERR_ARG);
30
31 dhcp = netif_dhcp_data(netif);
32 LWIP_ERROR("netif->dhcp != NULL", (dhcp != NULL), return ERR_ARG);
33
34 if (dhcp->state == DHCP_STATE_BOUND) {
35 return ERR_OK;
36 } else {
37 return ERR_INPROGRESS;
38 }
39 }
40 #endif /* LWIP_DHCP */
41
OsNetifFindByName(const char * name)42 static struct netif *OsNetifFindByName(const char *name)
43 {
44 struct netif *netif = NULL;
45 LWIP_ASSERT_CORE_LOCKED();
46 if (name == NULL) {
47 return NULL;
48 }
49 NETIF_FOREACH(netif) {
50 if (strcmp("lo", name) == 0 && (netif->name[0] == 'l' && netif->name[1] == 'o')) {
51 LWIP_DEBUGF(NETIF_DEBUG, ("OsNetifFindByName: found lo\n"));
52 return netif;
53 }
54
55 if (strcmp(netif->full_name, name) == 0) {
56 LWIP_DEBUGF(NETIF_DEBUG, ("OsNetifFindByName: found %s\n", name));
57 return netif;
58 }
59 }
60 return NULL;
61 }
62
OsNetifapiDoFindByName(struct tcpip_api_call_data * m)63 static err_t OsNetifapiDoFindByName(struct tcpip_api_call_data *m)
64 {
65 /* cast through void* to silence alignment warnings.
66 * We know it works because the structs have been instantiated as struct netifapi_msg */
67 struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m;
68 msg->netif = OsNetifFindByName(msg->msg.ifs.name);
69 return ERR_OK;
70 }
71
OsNetifapiNetifFindByName(const char * name)72 struct netif *OsNetifapiNetifFindByName(const char *name)
73 {
74 struct netif *netif = NULL;
75 API_VAR_DECLARE(struct netifapi_msg, msg);
76 API_VAR_ALLOC(struct netifapi_msg, MEMP_NETIFAPI_MSG, msg, ERR_MEM);
77 API_VAR_REF(msg).netif = NULL;
78 #if LWIP_MPU_COMPATIBLE
79 if (strncpy_s(API_VAR_REF(msg).msg.ifs.name, NETIF_NAMESIZE, name, NETIF_NAMESIZE - 1)) {
80 API_VAR_FREE(MEMP_NETIFAPI_MSG, msg);
81 return netif;
82 }
83 API_VAR_REF(msg).msg.ifs.name[NETIF_NAMESIZE - 1] = '\0';
84 #else
85 API_VAR_REF(msg).msg.ifs.name = (char *)name;
86 #endif /* LWIP_MPU_COMPATIBLE */
87
88 (void)tcpip_api_call(OsNetifapiDoFindByName, &API_VAR_REF(msg).call);
89 netif = msg.netif;
90 API_VAR_FREE(MEMP_NETIFAPI_MSG, msg);
91
92 return netif;
93 }
94
95 #if LWIP_IPV6
ip6addr_aton(const char * cp,ip6_addr_t * addr)96 int ip6addr_aton(const char *cp, ip6_addr_t *addr)
97 {
98 const S32 ipv6Blocks = 8;
99 U16 currentBlockIndex = 0;
100 U16 currentBlockValue = 0;
101 U16 addr16[ipv6Blocks];
102 U16 *a16 = (u16_t *)addr->addr;
103 S32 squashPos = ipv6Blocks;
104 S32 i;
105 S32 num5 = 5;
106 S32 num16 = 16;
107 const char *sc = (const char *)cp;
108 const char *ss = cp - 1;
109
110 for (; ; sc++) {
111 if (currentBlockIndex >= ipv6Blocks) {
112 return 0; // address too long
113 }
114 if (*sc == 0) {
115 if (sc - ss == 1) {
116 if (squashPos != currentBlockIndex) {
117 return 0; // empty address or address ends with a single ':'
118 } // else address ends with one valid "::"
119 } else {
120 addr16[currentBlockIndex++] = currentBlockValue;
121 }
122 break;
123 } else if (*sc == ':') {
124 if (sc - ss == 1) {
125 if (sc != cp || sc[1] != ':') {
126 return 0; // address begins with a single ':' or contains ":::"
127 } // else address begins with one valid "::"
128 } else {
129 addr16[currentBlockIndex++] = currentBlockValue;
130 }
131 if (sc[1] == ':') {
132 if (squashPos != ipv6Blocks) {
133 return 0; // more than one "::"
134 }
135 squashPos = currentBlockIndex;
136 sc++;
137 }
138 ss = sc; // ss points to the recent ':' position
139 currentBlockValue = 0;
140 } else if (lwip_isxdigit(*sc) && (sc - ss) < num5) { // 4 hex-digits at most
141 currentBlockValue = (currentBlockValue << 4) +
142 (*sc | ('a' - 'A')) - '0' - ('a' - '9' - 1) * (*sc >= 'A');
143 #if LWIP_IPV4
144 } else if (*sc == '.' && currentBlockIndex < ipv6Blocks - 1) {
145 ip4_addr_t ip4;
146 int ret = ip4addr_aton(ss+1, &ip4);
147 if (!ret) {
148 return 0;
149 }
150 ip4.addr = lwip_ntohl(ip4.addr);
151 addr16[currentBlockIndex++] = (u16_t)(ip4.addr >> num16);
152 addr16[currentBlockIndex++] = (u16_t)(ip4.addr);
153 break;
154 #endif /* LWIP_IPV4 */
155 } else {
156 return 0; // unexpected char or too many digits
157 }
158 }
159
160 if (squashPos == ipv6Blocks && currentBlockIndex != ipv6Blocks) {
161 return 0; // address too short
162 }
163 if (squashPos != ipv6Blocks && currentBlockIndex == ipv6Blocks) {
164 return 0; // unexpected "::" in address
165 }
166
167 for (i = 0; i < squashPos; ++i) {
168 a16[i] = lwip_htons(addr16[i]);
169 }
170 for (; i < ipv6Blocks - currentBlockIndex + squashPos; ++i) {
171 a16[i] = 0;
172 }
173 for (; i < ipv6Blocks; ++i) {
174 a16[i] = lwip_htons(addr16[i - ipv6Blocks + currentBlockIndex]);
175 }
176
177 return 1;
178 }
179 #endif /* LWIP_IPV6 */
180