2 * Network Configuration Module
4 * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
27 #include <arpa/inet.h>
28 #include <sys/ioctl.h>
34 #include "wmesh-log.h"
35 #include "wmesh-util.h"
36 #include "wmesh-service.h"
37 #include "wmesh-interface.h"
39 #define IPV4_MAX_LENGTH 16
40 #define BUF_LENGTH 256
42 #define MESH_DEFAULT_BASE_INTERFACE "wlan0"
43 #define MESH_DEFAULT_MESH_INTERFACE "mesh0"
44 #define MESH_DEFAULT_BRIDGE_INTERFACE "br0"
45 #define MESH_DEFAULT_EXTERNAL_INTERFACE "eth0"
46 #define MESH_DEFAULT_SOFTAP_INTERFACE "wlan1"
49 ETHERNET_CABLE_DETACHED = 0,
50 ETHERNET_CABLE_ATTACHED
53 int wmesh_interface_set(const char *interface, const char* ip_addr,
54 wmesh_set_interface_type_e type)
60 char ip[IPV4_MAX_LENGTH] = {0,};
61 char buf[BUF_LENGTH] = {0,};
63 if (interface == NULL) {
64 WMESH_LOGE("Invalid interface name !");
65 return WMESHD_ERROR_INVALID_PARAMETER;
68 sock = socket(AF_INET, SOCK_STREAM, 0);
70 WMESH_LOGE("Cannot open network interface socket");
71 return WMESHD_ERROR_IO_ERROR;
74 WMESH_LOGD("Initialize interface [%s]...", interface);
75 snprintf(ifr.ifr_name, IFNAMSIZ, "%s", interface);
78 if (NULL != ip_addr) {
79 struct sockaddr_in sai;
80 memset(&sai, 0, sizeof(struct sockaddr_in));
81 sai.sin_family = AF_INET;
83 snprintf(ip, IPV4_MAX_LENGTH, "%s", ip_addr);
85 WMESH_LOGD("Setting IP address: [%s]\n", ip);
86 if (!inet_aton(ip, &sai.sin_addr)) {
87 WMESH_LOGE("Failed to convert ip address");
89 return WMESHD_ERROR_OPERATION_FAILED;
92 memcpy(&ifr.ifr_addr, &sai, sizeof(sai));
94 ret = ioctl(sock, SIOCSIFADDR, &ifr);
96 (void) strerror_r(errno, buf, BUF_LENGTH);
97 WMESH_LOGE("Failed to set IP[%s] for interface[%s] : %s",
98 ip, ifr.ifr_name, buf);
102 /* Get status flag */
103 if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) {
104 (void) strerror_r(errno, buf, BUF_LENGTH);
105 WMESH_LOGE("Failed to get interface[%s] status : %s",
108 snprintf(ifr.ifr_name, IFNAMSIZ, "%s", interface);
110 /* Set status flag */
111 if (WMESH_INTERFACE_UP == type) {
112 ifr.ifr_flags |= (IFF_UP);
113 if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) {
114 (void) strerror_r(errno, buf, BUF_LENGTH);
115 WMESH_LOGE("Failed to change interface[%s] status UP : %s",
118 } else if (WMESH_INTERFACE_DOWN == type) {
119 ifr.ifr_flags &= (~IFF_UP);
120 if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) {
121 (void) strerror_r(errno, buf, BUF_LENGTH);
122 WMESH_LOGE("Failed to change interface[%s] status DOWN : %s",
126 WMESH_LOGD("Do not change up/down status");
130 return WMESHD_ERROR_NONE;
134 /* Returns interface name in sequence order which is exists */
135 static char* _get_interface_exists_in_seq(const char* prefix)
141 const int IF_INDEX_MAX = 9;
143 for (i = 0; i <= IF_INDEX_MAX; i++) {
144 snprintf(buf, sizeof(buf), "/sys/class/net/%s%d", prefix, i);
146 ret = access(buf, F_OK);
148 /* This name is exists. use it */
149 snprintf(buf, sizeof(buf), "%s%d", prefix, i);
151 WMESH_LOGD(" use [%s]", res);
159 /* Returns interface name in sequence order which is exists */
160 static char* _get_interface_not_exists_in_seq(const char* prefix)
166 const int IF_INDEX_MAX = 9;
168 for (i = 0; i <= IF_INDEX_MAX; i++) {
169 snprintf(buf, sizeof(buf), "/sys/class/net/%s%d", prefix, i);
171 ret = access(buf, F_OK);
173 /* This name is not exists. use it */
174 snprintf(buf, sizeof(buf), "%s%d", prefix, i);
176 WMESH_LOGD(" use [%s]", res);
185 static bool _check_interface_exists(const char* if_name)
190 const int IF_INDEX_MAX = 9;
192 for (i = 0; i <= IF_INDEX_MAX; i++) {
193 snprintf(buf, sizeof(buf), "/sys/class/net/%s", if_name);
195 ret = access(buf, F_OK);
197 /* This name is exists. */
205 /* Check if interface is bridged */
206 static bool _check_bridge_interface_exists(const char* bridge, const char* if_name)
211 const int IF_INDEX_MAX = 9;
213 for (i = 0; i <= IF_INDEX_MAX; i++) {
214 snprintf(buf, sizeof(buf), "/sys/class/net/%s/brif/%s", bridge, if_name);
216 ret = access(buf, F_OK);
218 /* This name is exists. */
226 char* wmesh_interface_get_address(const char* if_name)
229 char buf[32] = { 0, };
232 snprintf(buf, sizeof(buf), "/sys/class/net/%s/address", if_name);
233 pf = fopen(buf, "r");
236 WMESH_LOGD("Interface[%s] address[%s]", if_name, buf);
239 result = g_strdup(buf);
247 int wmesh_interface_initialize(wmesh_interface_s *info)
250 WMESH_LOGE("Invalid parameter");
251 return WMESHD_ERROR_INVALID_PARAMETER;
254 info->bridge_interface = g_strdup(MESH_DEFAULT_BRIDGE_INTERFACE);
255 if (NULL == info->bridge_interface) {
256 WMESH_LOGE("Failed to get bridge interface !");
257 return WMESHD_ERROR_OPERATION_FAILED;
260 info->base_interface = g_strdup(MESH_DEFAULT_BASE_INTERFACE);
261 if (NULL == info->bridge_interface) {
262 WMESH_LOGE("Failed to get base interface !");
263 return WMESHD_ERROR_OPERATION_FAILED;
266 info->mesh_interface = g_strdup(MESH_DEFAULT_MESH_INTERFACE);
267 if (NULL == info->bridge_interface) {
268 WMESH_LOGE("Failed to get mesh interface !");
269 return WMESHD_ERROR_OPERATION_FAILED;
272 info->softap_interface = g_strdup(MESH_DEFAULT_SOFTAP_INTERFACE);
273 info->external_interface = g_strdup(MESH_DEFAULT_EXTERNAL_INTERFACE);
275 WMESH_LOGD("Interface configuration for mesh network :");
276 WMESH_LOGD(" Base : [%s]", info->base_interface);
277 WMESH_LOGD(" Mesh : [%s]", info->mesh_interface);
278 WMESH_LOGD(" Bridge : [%s]", info->bridge_interface);
279 WMESH_LOGD(" SoftAP : [%s]", info->softap_interface);
280 WMESH_LOGD(" External: [%s]", info->external_interface);
282 return WMESHD_ERROR_NONE;
285 static int _check_ethernet_cable_plugin_status(const char* interface,
286 cable_state_e *status)
291 char error_buf[256] = {0, };
292 char file_path[256] = {0, };
294 snprintf(file_path, 256, "/sys/class/net/%s/carrier", interface);
296 if (0 == access(file_path, F_OK)) {
297 fd = fopen(file_path, "r");
299 WMESH_LOGE("Error! Could not open /sys/class/net/%s/carrier file",
301 return WMESHD_ERROR_IO_ERROR;
304 WMESH_LOGE("Error! Could not access /sys/class/net/%s/carrier file",
306 return WMESHD_ERROR_IO_ERROR;
310 rv = fscanf(fd, "%d", &ret);
312 strerror_r(errno, error_buf, 256);
313 WMESH_LOGE("Error! Failed to read from file, rv:[%d], error:[%s]",
316 return WMESHD_ERROR_IO_ERROR;
320 WMESH_LOGD("/sys/class/net/%s/carrier : [%d]", interface, ret);
321 *status = ETHERNET_CABLE_ATTACHED;
322 } else if (ret == 0) {
323 WMESH_LOGD("/sys/class/net/%s/carrier : [%d]", interface, ret);
324 *status = ETHERNET_CABLE_DETACHED;
328 return WMESHD_ERROR_NONE;
331 int wmesh_interface_check_external_exists(const char* external_interface, bool *state)
333 /* TODO: Current logic checks only ethernet interface.
334 This logic should consider wireless interface if can */
335 int ret = WMESHD_ERROR_NONE;
336 cable_state_e cable_state = ETHERNET_CABLE_DETACHED;
338 if (NULL == external_interface || NULL == state)
339 return WMESHD_ERROR_INVALID_PARAMETER;
341 bool ex = _check_interface_exists(external_interface);
343 WMESH_LOGE("External interface[%s] was not found.", external_interface);
344 return WMESHD_ERROR_INVALID_PARAMETER;
347 /* If external interface seems Ethernet, check cable state */
348 if (g_str_has_prefix(external_interface, "eth")) {
349 ret = _check_ethernet_cable_plugin_status(external_interface, &cable_state);
350 if (WMESHD_ERROR_NONE != ret) {
351 WMESH_LOGE("Failed to get Ethernet cable state");
352 return WMESHD_ERROR_OPERATION_FAILED;
357 if (ETHERNET_CABLE_ATTACHED == cable_state)
360 return WMESHD_ERROR_NONE;
363 int wmesh_interface_check(const char* interface)
367 if (NULL == interface || strlen(interface) == 0)
368 return WMESHD_ERROR_INVALID_PARAMETER;
370 ex = _check_interface_exists(interface);
372 WMESH_LOGE("Interface[%s] was not found.", interface);
373 return WMESHD_ERROR_NO_DATA;
376 return WMESHD_ERROR_NONE;
379 int wmesh_interface_check_bridge_interface_exists(const char* bridge, const char* interface)
383 if (NULL == bridge || NULL == interface ||
384 strlen(bridge) == 0 || strlen(interface) == 0)
385 return WMESHD_ERROR_INVALID_PARAMETER;
387 ex = _check_bridge_interface_exists(bridge, interface);
389 WMESH_LOGE("Interface[%s] was not found.", interface);
390 return WMESHD_ERROR_NO_DATA;
393 return WMESHD_ERROR_NONE;