1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
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 */
15
16 #include "lnn_ip_utils_adapter.h"
17
18 #include <arpa/inet.h>
19 #include <ifaddrs.h>
20 #include <net/if.h>
21 #include <netinet/in.h>
22 #include <sys/ioctl.h>
23 #include <sys/socket.h>
24 #include <unistd.h>
25
26 #include "comm_log.h"
27
GetNetworkIfIp(int32_t fd,struct ifreq * req,char * ip,char * netmask,uint32_t len)28 static int32_t GetNetworkIfIp(int32_t fd, struct ifreq *req, char *ip, char *netmask, uint32_t len)
29 {
30 if (ioctl(fd, SIOCGIFFLAGS, (char *)req) < 0) {
31 return SOFTBUS_NETWORK_IOCTL_FAIL;
32 }
33 if (!((uint16_t)req->ifr_flags & IFF_UP)) {
34 return SOFTBUS_NETWORK_IFF_NOT_UP;
35 }
36
37 /* get IP of this interface */
38 if (ioctl(fd, SIOCGIFADDR, (char *)req) < 0) {
39 return SOFTBUS_NETWORK_IOCTL_FAIL;
40 }
41 struct sockaddr_in *sockAddr = (struct sockaddr_in *)&(req->ifr_addr);
42 if (inet_ntop(sockAddr->sin_family, &sockAddr->sin_addr, ip, len) == NULL) {
43 COMM_LOGE(COMM_ADAPTER, "convert ip addr to string failed");
44 return SOFTBUS_NETWORK_INET_NTOP_FAIL;
45 }
46
47 /* get netmask of this interface */
48 if (netmask != NULL) {
49 if (ioctl(fd, SIOCGIFNETMASK, (char *)req) < 0) {
50 COMM_LOGE(COMM_ADAPTER, "ioctl SIOCGIFNETMASK fail, errno=%{public}d", errno);
51 return SOFTBUS_NETWORK_IOCTL_FAIL;
52 }
53 sockAddr = (struct sockaddr_in *)&(req->ifr_netmask);
54 if (inet_ntop(sockAddr->sin_family, &sockAddr->sin_addr, netmask, len) == NULL) {
55 COMM_LOGE(COMM_ADAPTER, "convert netmask addr to string failed");
56 return SOFTBUS_NETWORK_INET_NTOP_FAIL;
57 }
58 }
59 return SOFTBUS_OK;
60 }
61
GetNetworkIpByIfName(const char * ifName,char * ip,char * netmask,uint32_t len)62 int32_t GetNetworkIpByIfName(const char *ifName, char *ip, char *netmask, uint32_t len)
63 {
64 if (ifName == NULL || ip == NULL) {
65 COMM_LOGE(COMM_ADAPTER, "ifName or ip buffer is NULL!");
66 return SOFTBUS_INVALID_PARAM;
67 }
68 int32_t fd = socket(AF_INET, SOCK_DGRAM, 0);
69 if (fd < 0) {
70 COMM_LOGE(COMM_ADAPTER, "open socket failed");
71 return SOFTBUS_NETWORK_OPEN_SOCKET_FAIL;
72 }
73 struct ifreq ifr;
74 if (strncpy_s(ifr.ifr_name, sizeof(ifr.ifr_name), ifName, strlen(ifName)) != EOK) {
75 COMM_LOGE(COMM_ADAPTER, "copy netIfName fail. netIfName=%{public}s", ifName);
76 close(fd);
77 return SOFTBUS_STRCPY_ERR;
78 }
79 int32_t ret = GetNetworkIfIp(fd, &ifr, ip, netmask, len);
80 if (ret != SOFTBUS_OK) {
81 close(fd);
82 return ret;
83 }
84 close(fd);
85 return SOFTBUS_OK;
86 }
87
GetNetworkIpv6ByIfName(const char * ifName,char * ip,uint32_t len)88 int32_t GetNetworkIpv6ByIfName(const char *ifName, char *ip, uint32_t len)
89 {
90 if (ifName == NULL || ip == NULL) {
91 COMM_LOGE(COMM_ADAPTER, "ifName or ip buffer is NULL!");
92 return SOFTBUS_INVALID_PARAM;
93 }
94 if (len < INET6_ADDRSTRLEN) {
95 COMM_LOGE(COMM_ADAPTER, "len value is not long enough !");
96 return SOFTBUS_INVALID_PARAM;
97 }
98 struct ifaddrs *allAddr = NULL;
99 if (getifaddrs(&allAddr) == -1) {
100 COMM_LOGE(COMM_ADAPTER, "getifaddrs fail!");
101 return SOFTBUS_NETWORK_GET_IP_ADDR_FAILED;
102 }
103 for (struct ifaddrs *ifa = allAddr; ifa != NULL; ifa = ifa->ifa_next) {
104 if (ifa->ifa_addr == NULL || ifa->ifa_addr->sa_family != AF_INET6 || ifa->ifa_netmask == NULL ||
105 ifa->ifa_name == NULL || strcmp(ifa->ifa_name, ifName) != 0) {
106 continue;
107 }
108 struct sockaddr_in6 *addr = (struct sockaddr_in6 *)(ifa->ifa_addr);
109 if (inet_ntop(AF_INET6, &addr->sin6_addr.s6_addr, ip, len) == NULL) {
110 COMM_LOGE(COMM_ADAPTER, "convert ip addr to string failed");
111 freeifaddrs(allAddr);
112 return SOFTBUS_NETWORK_GET_IP_ADDR_FAILED;
113 }
114 freeifaddrs(allAddr);
115 return SOFTBUS_OK;
116 }
117 freeifaddrs(allAddr);
118 COMM_LOGE(COMM_ADAPTER, "not found ifname %{public}s ip", ifName);
119 return SOFTBUS_NETWORK_GET_IP_ADDR_FAILED;
120 }
121
GetLinkUpStateByIfName(const char * ifName)122 bool GetLinkUpStateByIfName(const char *ifName)
123 {
124 if (ifName == NULL) {
125 COMM_LOGE(COMM_ADAPTER, "ifName buffer is NULL!");
126 return false;
127 }
128 int32_t fd = socket(AF_INET, SOCK_DGRAM, 0);
129 if (fd < 0) {
130 COMM_LOGE(COMM_ADAPTER, "open socket failed");
131 return false;
132 }
133 struct ifreq ifr;
134 if (strncpy_s(ifr.ifr_name, sizeof(ifr.ifr_name), ifName, strlen(ifName)) != EOK) {
135 COMM_LOGE(COMM_ADAPTER, "copy netIfName fail. netIfName=%{public}s", ifName);
136 close(fd);
137 return false;
138 }
139 if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0) {
140 COMM_LOGE(COMM_ADAPTER, "open socket failed");
141 close(fd);
142 return false;
143 }
144 if (!((uint16_t)ifr.ifr_flags & IFF_UP)) {
145 COMM_LOGE(COMM_ADAPTER, "ifname flag is not up");
146 close(fd);
147 return false;
148 }
149 close(fd);
150 return true;
151 }
152