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.
28 #include <arpa/inet.h>
29 #include <sys/ioctl.h>
34 #include <net_connection.h>
38 #include "mesh-util.h"
39 #include "mesh-service.h"
40 #include "mesh-interface.h"
42 #define IPV4_MAX_LENGTH 16
43 #define BUF_LENGTH 256
45 int mesh_interface_set(const char *interface, const char* ip_addr,
46 mesh_set_interface_type_e type)
52 char ip[IPV4_MAX_LENGTH] = {0,};
53 char buf[BUF_LENGTH] = {0,};
55 if (interface == NULL) {
56 MESH_LOGE("Invalid interface name !");
57 return MESHD_ERROR_INVALID_PARAMETER;
60 sock = socket(AF_INET, SOCK_STREAM, 0);
62 MESH_LOGE("Cannot open network interface socket");
63 return MESHD_ERROR_IO_ERROR;
66 MESH_LOGD("Initialize interface [%s]...", interface);
67 snprintf(ifr.ifr_name, IFNAMSIZ, "%s", interface);
70 if (NULL != ip_addr) {
71 struct sockaddr_in sai;
72 memset(&sai, 0, sizeof(struct sockaddr_in));
73 sai.sin_family = AF_INET;
75 snprintf(ip, IPV4_MAX_LENGTH, "%s", ip_addr);
77 MESH_LOGD("Setting IP address: [%s]\n", ip);
78 if (!inet_aton(ip, &sai.sin_addr)) {
79 MESH_LOGE("Failed to convert ip address");
81 return MESHD_ERROR_OPERATION_FAILED;
84 memcpy(&ifr.ifr_addr, &sai, sizeof(sai));
86 ret = ioctl(sock, SIOCSIFADDR, &ifr);
88 (void) strerror_r(errno, buf, BUF_LENGTH);
89 MESH_LOGE("Failed to set IP[%s] for interface[%s] : %s",
90 ip, ifr.ifr_name, buf);
95 if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) {
96 (void) strerror_r(errno, buf, BUF_LENGTH);
97 MESH_LOGE("Failed to get interface[%s] status : %s",
100 snprintf(ifr.ifr_name, IFNAMSIZ, "%s", interface);
102 /* Set status flag */
103 if (MESH_INTERFACE_UP == type) {
104 ifr.ifr_flags |= (IFF_UP);
105 if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) {
106 (void) strerror_r(errno, buf, BUF_LENGTH);
107 MESH_LOGE("Failed to change interface[%s] status UP : %s",
110 } else if (MESH_INTERFACE_DOWN == type) {
111 ifr.ifr_flags &= (~IFF_UP);
112 if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) {
113 (void) strerror_r(errno, buf, BUF_LENGTH);
114 MESH_LOGE("Failed to change interface[%s] status DOWN : %s",
118 MESH_LOGD("Do not change up/down status");
122 return MESHD_ERROR_NONE;
125 /* Returns interface name in sequence order which is exists */
126 static char* _get_interface_exists_in_seq(const char* prefix)
132 const int IF_INDEX_MAX = 9;
134 for (i = 0; i <= IF_INDEX_MAX; i++) {
135 snprintf(buf, sizeof(buf), "/sys/class/net/%s%d", prefix, i);
137 ret = access(buf, F_OK);
139 /* This name is exists. use it */
140 snprintf(buf, sizeof(buf), "%s%d", prefix, i);
142 MESH_LOGD(" use [%s]", res);
150 /* Returns interface name in sequence order which is exists */
151 static char* _get_interface_not_exists_in_seq(const char* prefix)
157 const int IF_INDEX_MAX = 9;
159 for (i = 0; i <= IF_INDEX_MAX; i++) {
160 snprintf(buf, sizeof(buf), "/sys/class/net/%s%d", prefix, i);
162 ret = access(buf, F_OK);
164 /* This name is not exists. use it */
165 snprintf(buf, sizeof(buf), "%s%d", prefix, i);
167 MESH_LOGD(" use [%s]", res);
175 /* Returns interface name in sequence order which is exists */
176 static bool _check_interface_exists(const char* if_name)
181 const int IF_INDEX_MAX = 9;
183 for (i = 0; i <= IF_INDEX_MAX; i++) {
184 snprintf(buf, sizeof(buf), "/sys/class/net/%s", if_name);
186 ret = access(buf, F_OK);
188 /* This name is exists. */
196 char* mesh_interface_get_address(const char* if_name)
203 snprintf(buf, sizeof(buf), "/sys/class/net/%s/address", if_name);
204 pf = fopen(buf, "r");
206 cnt = fscanf(pf, "%s", buf);
207 MESH_LOGD("Interface[%s] address[%s] %d", if_name, buf, cnt);
208 result = g_strdup(buf);
216 int mesh_interface_initialize(mesh_interface_s *info)
218 info->bridge_interface = _get_interface_not_exists_in_seq("br");
219 if (NULL == info->bridge_interface) {
220 MESH_LOGE("Failed to get bridge interface !");
221 return MESHD_ERROR_OPERATION_FAILED;
224 info->base_interface = _get_interface_exists_in_seq("wlan");
225 if (NULL == info->bridge_interface) {
226 MESH_LOGE("Failed to get base interface !");
227 return MESHD_ERROR_OPERATION_FAILED;
230 info->mesh_interface = _get_interface_not_exists_in_seq("mesh");
231 if (NULL == info->bridge_interface) {
232 MESH_LOGE("Failed to get mesh interface !");
233 return MESHD_ERROR_OPERATION_FAILED;
236 info->softap_interface = g_strdup("wlan1"); /* CHECK: interface changed */
237 info->external_interface = _get_interface_exists_in_seq("eth");
238 info->mesh_id = g_strdup("meshnet");
239 if (NULL == info->bridge_interface) {
240 MESH_LOGE("Failed to get mesh id !");
241 return MESHD_ERROR_OPERATION_FAILED;
243 info->mesh_channel = 7;
245 return MESHD_ERROR_NONE;
248 int mesh_interface_check_external_exists(const char* external_interface, bool *state)
250 /* TODO: Current logic checks only ethernet interface.
251 This logic should consider wireless interface if can */
252 int ret = MESHD_ERROR_NONE;
254 connection_ethernet_cable_state_e cable_state =
255 CONNECTION_ETHERNET_CABLE_DETACHED;
257 if (NULL == external_interface || NULL == state) {
258 return MESHD_ERROR_INVALID_PARAMETER;
261 bool ex = _check_interface_exists(external_interface);
263 MESH_LOGE("External interface[%s] was not found.", external_interface);
264 return MESHD_ERROR_INVALID_PARAMETER;
267 ret = connection_create(&handle);
268 if (CONNECTION_ERROR_NONE != ret) {
269 MESH_LOGE("Failed to get connection handle");
270 return MESHD_ERROR_OPERATION_FAILED;
273 ret = connection_get_ethernet_cable_state(handle, &cable_state);
274 if (CONNECTION_ERROR_NONE != ret) {
275 MESH_LOGE("Failed to get ethernet cable state");
276 return MESHD_ERROR_OPERATION_FAILED;
280 if (CONNECTION_ETHERNET_CABLE_ATTACHED == cable_state) {
284 return MESHD_ERROR_NONE;