• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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