3 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 * Licensed under the Apache License, Version 2.0 (the License);
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
21 #include <sys/ioctl.h>
23 #include <glib-object.h>
24 #include <dbus/dbus-glib.h>
30 #include <sys/types.h>
32 #include <sys/socket.h>
33 #include <netinet/in.h>
34 #include <arpa/inet.h>
35 #include <linux/wireless.h>
37 #include <openssl/evp.h>
38 #include <openssl/sha.h>
40 #include "mobileap_common.h"
41 #include "mobileap_agent.h"
42 #include "mobileap_handler.h"
44 static pid_t dnsmasq_pid = 0;
45 static pid_t hostapd_pid = 0;
46 static int hostapd_ctrl_fd = 0;
47 static int hostapd_monitor_fd = 0;
48 static GIOChannel *hostapd_io_channel = NULL;
49 static guint hostapd_io_source = 0;
51 static int __issue_ioctl(int sock_fd, char *if_name, char *cmd, char *buf)
53 int ret_val = MOBILE_AP_ERROR_NONE;
56 memset(buf, 0, MAX_BUF_SIZE);
57 memset(&iwr, 0, sizeof(iwr));
59 /* Configure ioctl parameters */
60 g_strlcpy(iwr.ifr_name, if_name, IFNAMSIZ);
61 g_strlcpy(buf, cmd, MAX_BUF_SIZE);
62 iwr.u.data.pointer = buf;
63 iwr.u.data.length = MAX_BUF_SIZE;
68 if ((ioctl(sock_fd, SIOCSIWPRIV, &iwr)) < 0) {
69 ERR("ioctl failed...!!!\n");
70 ret_val = MOBILE_AP_ERROR_INTERNAL;
76 static int __get_psk_hexascii(const char *pass, const unsigned char *salt, char *psk, unsigned int psk_len)
78 if (pass == NULL || salt == NULL || psk == NULL || psk_len == 0) {
79 ERR("Invalid parameter\n");
80 return MOBILE_AP_ERROR_INVALID_PARAM;
83 if (psk_len < SHA256_DIGEST_LENGTH * 2 + 1) {
84 ERR("Invalid parameter\n");
85 return MOBILE_AP_ERROR_INVALID_PARAM;
91 unsigned char buf[SHA256_DIGEST_LENGTH] = {0, };
93 if (!PKCS5_PBKDF2_HMAC_SHA1(pass, strlen(pass),
94 salt, strlen((const char *)salt),
95 PSK_ITERATION_COUNT, sizeof(buf), buf)) {
96 ERR("Getting psk is failed\n");
97 return MOBILE_AP_ERROR_INTERNAL;
100 for (i = 0; i < SHA256_DIGEST_LENGTH; i++) {
104 psk[i << 1] = d_16 < 10 ? d_16 + '0' : d_16 - 10 + 'a';
105 psk[(i << 1) + 1] = r_16 < 10 ? r_16 + '0' : r_16 - 10 + 'a';
109 return MOBILE_AP_ERROR_NONE;
112 static int __execute_hostapd(const char *ssid, const char *security,
113 const char *key, int hide_mode)
117 char psk[2 * SHA256_DIGEST_LENGTH + 1] = {0, };
118 char buf[HOSTAPD_CONF_LEN] = "";
119 char sec_buf[HOSTAPD_CONF_LEN] = "";
123 if (security != NULL && !strcmp(security, "wpa2-psk")) {
124 if (__get_psk_hexascii(key, (const unsigned char *)ssid, psk,
125 sizeof(psk)) != MOBILE_AP_ERROR_NONE) {
126 ERR("Getting PSK(Hex ascii type) is failed\n");
127 return MOBILE_AP_ERROR_INTERNAL;
130 snprintf(sec_buf, HOSTAPD_CONF_LEN,
131 "\nwpa=2\nrsn_pairwise=CCMP\nwpa_psk=%s",
135 snprintf(buf, HOSTAPD_CONF_LEN, HOSTAPD_CONF,
137 HOSTAPD_CTRL_INTF_DIR,
139 MOBILE_AP_WIFI_CHANNEL,
141 MOBILE_AP_MAX_WIFI_STA,
144 fp = fopen(HOSTAPD_CONF_FILE, "w");
146 ERR("Could not create the file.\n");
147 return MOBILE_AP_ERROR_RESOURCE;
154 ERR("fork failed\n");
155 return MOBILE_AP_ERROR_RESOURCE;
159 if (execl(HOSTAPD_BIN, HOSTAPD_BIN, "-e", HOSTAPD_ENTROPY_FILE,
161 "-f", HOSTAPD_DEBUG_FILE, "-d",
163 ERR("execl failed\n");
166 ERR("Should not get here!");
167 return MOBILE_AP_ERROR_RESOURCE;
172 return MOBILE_AP_ERROR_NONE;
175 static int __terminate_hostapd()
179 if (hostapd_pid == 0) {
180 DBG("There is no hostapd\n");
181 return MOBILE_AP_ERROR_NONE;
184 kill(hostapd_pid, SIGTERM);
185 waitpid(hostapd_pid, NULL, 0);
188 return MOBILE_AP_ERROR_NONE;
192 * number NUM_STA(void)
193 * addr STA-FIRST(void)
194 * addr STA-NEXT(addr)
195 * void DISASSOCIATE(addr)
196 * void READ_WHITELIST(filename)
197 * void SET_MAXCLIENT(number)
199 static int __send_hostapd_req(int fd, const char *req, const int req_len,
200 char *buf, int *buf_len)
202 if (fd < 0 || req == NULL || req_len <= 0 ||
203 buf == NULL || buf_len == NULL || *buf_len <= 0) {
204 ERR("Invalid param\n");
205 return MOBILE_AP_ERROR_INVALID_PARAM;
208 struct timeval tv = {10, 0};
212 ret = send(fd, req, req_len, 0);
214 ERR("send is failed : %s\n", strerror(errno));
215 return MOBILE_AP_ERROR_INTERNAL;
221 ret = select(fd + 1, &fds, NULL, NULL, &tv);
223 return MOBILE_AP_ERROR_INTERNAL;
224 } else if (ret == 0) {
225 ERR("There is no response from hostapd\n");
226 return MOBILE_AP_ERROR_INTERNAL;
227 } else if (!FD_ISSET(fd, &fds)) {
228 ERR("Unknown case\n");
229 return MOBILE_AP_ERROR_INTERNAL;
232 ret = recv(fd, buf, (*buf_len) - 1, 0);
234 ERR("recv is failed\n");
235 return MOBILE_AP_ERROR_INTERNAL;
239 DBG("Unsolicited message\n");
246 ERR("socket is closed\n");
252 return MOBILE_AP_ERROR_NONE;
255 static int __open_hostapd_intf(int *fd, const char *intf)
257 if (fd == NULL || intf == NULL) {
259 return MOBILE_AP_ERROR_INVALID_PARAM;
265 char ctrl_intf[255] = {0, };
266 struct sockaddr_un src;
267 struct sockaddr_un dest;
268 struct stat stat_buf;
270 *fd = socket(PF_UNIX, SOCK_DGRAM, 0);
272 ERR("socket is failed\n");
273 return MOBILE_AP_ERROR_INTERNAL;
276 src.sun_family = AF_UNIX;
277 g_strlcpy(src.sun_path, intf, sizeof(src.sun_path));
279 if (stat(src.sun_path, &stat_buf) == 0) {
280 DBG("There is already mh interface. It will be removed\n");
281 unlink(src.sun_path);
284 if (bind(*fd, (struct sockaddr *)&src, sizeof(src)) < 0) {
285 ERR("bind is failed\n");
288 unlink(src.sun_path);
289 return MOBILE_AP_ERROR_INTERNAL;
292 snprintf(ctrl_intf, sizeof(ctrl_intf), "%s/%s",
293 HOSTAPD_CTRL_INTF_DIR, WIFI_IF);
294 dest.sun_family = AF_UNIX;
295 g_strlcpy(dest.sun_path, ctrl_intf, sizeof(dest.sun_path));
297 while (connect(*fd, (struct sockaddr *)&dest, sizeof(dest)) < 0) {
298 DBG("connect is failed : %s\n", strerror(errno));
299 if (++retry >= HOSTAPD_RETRY_MAX)
301 usleep(HOSTAPD_RETRY_DELAY);
304 return MOBILE_AP_ERROR_NONE;
307 ERR("Cannot make connection to hostapd\n");
310 unlink(src.sun_path);
312 return MOBILE_AP_ERROR_INTERNAL;
315 static int __close_hostapd_intf(int *fd)
321 return MOBILE_AP_ERROR_INVALID_PARAM;
328 return MOBILE_AP_ERROR_NONE;
331 static gboolean __hostapd_monitor_cb(GIOChannel *source)
335 char buf[HOSTAPD_REQ_MAX_LEN] = {0, };
340 #if !GLIB_CHECK_VERSION(2, 31, 0)
343 ret = g_io_channel_read(hostapd_io_channel, buf,
344 HOSTAPD_REQ_MAX_LEN, &read);
345 if (ret != G_IO_ERROR_NONE) {
346 ERR("g_io_channel_read is failed\n");
352 g_io_channel_read_chars(hostapd_io_channel, buf,
353 HOSTAPD_REQ_MAX_LEN, &read, &err);
355 ERR("g_io_channel_read_chars is failed : %s\n", err->message);
362 pbuf = strrchr(buf, '\n');
366 if (buf[0] == '<' && (pbuf = strchr(buf, '>')) != NULL) {
372 DBG("Event : %s\n", pbuf);
374 if (!strncmp(pbuf, HOSTAPD_STA_DISCONN, strlen(HOSTAPD_STA_DISCONN))) {
375 pbuf = strchr(pbuf, ' ');
377 ERR("There is no info. for disconnected station\n");
382 DBG("Disconnected station MAC : %s\n", pbuf);
383 _remove_station_info(pbuf, _slist_find_station_by_mac);
385 _get_station_count((gconstpointer)MOBILE_AP_TYPE_WIFI,
386 _slist_find_station_by_interface, &n_station);
388 _start_timeout_cb(MOBILE_AP_TYPE_WIFI);
392 DBG("Event is not handled\n");
398 static int __open_hostapd_monitor(int *fd)
402 return MOBILE_AP_ERROR_INVALID_PARAM;
407 char buf[HOSTAPD_REQ_MAX_LEN] = {0, };
410 if (__open_hostapd_intf(fd, MH_MONITOR_INTF) != MOBILE_AP_ERROR_NONE) {
411 ERR("__open_hostapd_intf() is failed\n");
412 return MOBILE_AP_ERROR_INTERNAL;
415 hostapd_io_channel = g_io_channel_unix_new(*fd);
416 if (hostapd_io_channel == NULL) {
417 ERR("g_io_channel_unix_new is failed\n");
418 return MOBILE_AP_ERROR_INTERNAL;
421 g_io_channel_set_encoding(hostapd_io_channel, NULL, NULL);
422 g_io_channel_set_flags(hostapd_io_channel,
423 G_IO_FLAG_APPEND | G_IO_FLAG_NONBLOCK, NULL);
425 hostapd_io_source = g_io_add_watch(hostapd_io_channel, G_IO_IN,
426 (GIOFunc)__hostapd_monitor_cb, NULL);
428 buf_len = sizeof(buf);
429 __send_hostapd_req(*fd, HOSTAPD_MONITOR_ATTACH,
430 strlen(HOSTAPD_MONITOR_ATTACH), buf, &buf_len);
431 DBG("return : %s\n", buf);
433 return MOBILE_AP_ERROR_NONE;
436 static int __close_hostapd_monitor(int *fd)
439 char buf[HOSTAPD_REQ_MAX_LEN] = {0, };
442 buf_len = sizeof(buf);
443 __send_hostapd_req(*fd, HOSTAPD_MONITOR_DETACH,
444 strlen(HOSTAPD_MONITOR_DETACH), buf, &buf_len);
445 DBG("return : %s\n", buf);
447 if (hostapd_io_source != 0) {
448 g_source_remove(hostapd_io_source);
449 hostapd_io_source = 0;
452 if (hostapd_io_channel != NULL) {
453 g_io_channel_shutdown(hostapd_io_channel, TRUE, &err);
454 g_io_channel_unref(hostapd_io_channel);
455 hostapd_io_channel = NULL;
458 __close_hostapd_intf(fd);
460 return MOBILE_AP_ERROR_NONE;
463 static mobile_ap_drv_interface_e __get_drv_interface(void)
465 static mobile_ap_drv_interface_e drv_interface = MOBILE_AP_DRV_INTERFACE_NONE;
467 if (drv_interface != MOBILE_AP_DRV_INTERFACE_NONE) {
468 return drv_interface;
471 const char *drv_rfkill_path = "/sys/devices/platform";
472 const char *wext_drv[] = {
473 "bcm4329-b1", "bcm4330-b0",
474 "bcm4330-b1", "bcm4330-b2",
477 char path[MAX_BUF_SIZE] = { 0 };
478 struct stat stat_buf = { 0 };
482 drv_interface = MOBILE_AP_NL80211;
484 for (i = 0; wext_drv[i] != NULL; i++) {
485 snprintf(path, sizeof(path), "%s/%s",
486 drv_rfkill_path, wext_drv[i]);
487 fd = open(path, O_RDONLY);
491 if (fstat(fd, &stat_buf) == 0 && S_ISDIR(stat_buf.st_mode)) {
492 drv_interface = MOBILE_AP_WEXT;
500 return drv_interface;
503 int _mh_core_enable_softap(const char *ssid, const char *security,
504 const char *key, int hide_mode)
506 if (ssid == NULL || security == NULL || key == NULL) {
507 ERR("Invalid param\n");
508 return MOBILE_AP_ERROR_INTERNAL;
511 char cmd[MAX_BUF_SIZE];
512 int ret_status = MOBILE_AP_ERROR_NONE;
513 mobile_ap_drv_interface_e drv_interface = MOBILE_AP_DRV_INTERFACE_NONE;
516 char *if_name = WIFI_IF;
517 char buf[MAX_BUF_SIZE] = { 0 };
519 snprintf(cmd, sizeof(cmd), "%s softap", WLAN_SCRIPT);
520 if (_execute_command(cmd)) {
521 ERR("execute script failed : %s\n", cmd);
522 return MOBILE_AP_ERROR_INTERNAL;
525 drv_interface = __get_drv_interface();
527 switch (drv_interface) {
529 if ((sock_fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
530 ERR("Failed to open socket...!!!\n");
531 ret_status = MOBILE_AP_ERROR_RESOURCE;
535 snprintf(cmd, MAX_BUF_SIZE, "ASCII_CMD=AP_CFG,"
536 "SSID_LEN=%d,SSID=%s,"
537 "SEC=%s,KEY_LEN=%d,KEY=%s,CHANNEL=%d,"
538 "PREAMBLE=0,MAX_SCB=%d,HIDE=%d,END",
540 security, strlen(key), key,
541 MOBILE_AP_WIFI_CHANNEL,
542 MOBILE_AP_MAX_WIFI_STA, hide_mode);
543 ret_status = __issue_ioctl(sock_fd, if_name, cmd, buf);
544 if (ret_status != MOBILE_AP_ERROR_NONE) {
545 ERR("__issue_ioctl failed...!!!\n");
550 /* Start broadcasting of BSS. */
551 snprintf(cmd, MAX_BUF_SIZE, "ASCII_CMD=AP_BSS_START");
552 ret_status = __issue_ioctl(sock_fd, if_name, cmd, buf);
553 if (ret_status != MOBILE_AP_ERROR_NONE) {
554 ERR("__issue_ioctl failed...!!!\n");
561 ret_status = _mh_core_set_ip_address(SOFTAP_IF,
563 if (ret_status != MOBILE_AP_ERROR_NONE) {
564 ERR("_mh_core_set_ip_address of SOFTAP_IF is failed\n");
568 DBG("Setting softap is OK\n");
569 ret_status = _mh_core_set_ip_address(WIFI_IF,
571 if (ret_status != MOBILE_AP_ERROR_NONE) {
572 ERR("_mh_core_set_ip_address of WIFI_IF is failed\n");
577 case MOBILE_AP_NL80211:
578 ret_status = _mh_core_set_ip_address(WIFI_IF,
580 if (ret_status != MOBILE_AP_ERROR_NONE) {
581 ERR("_mh_core_set_ip_address is failed\n");
585 ret_status = __execute_hostapd(ssid, security, key, hide_mode);
586 if (ret_status != MOBILE_AP_ERROR_NONE) {
587 ERR("__execute_hostapd is failed\n");
591 ret_status = __open_hostapd_intf(&hostapd_ctrl_fd, MH_CTRL_INTF);
592 if (ret_status != MOBILE_AP_ERROR_NONE) {
593 ERR("__open_hostapd_intf is failed\n");
594 __terminate_hostapd();
598 ret_status = __open_hostapd_monitor(&hostapd_monitor_fd);
599 if (ret_status != MOBILE_AP_ERROR_NONE) {
600 ERR("__open_hostapd_monitor is failed\n");
601 __close_hostapd_intf(&hostapd_ctrl_fd);
602 __terminate_hostapd();
609 DBG("Unknown driver interface : %d\n", drv_interface);
613 if (ret_status != MOBILE_AP_ERROR_NONE) {
614 snprintf(cmd, sizeof(cmd), "%s stop", WLAN_SCRIPT);
615 if (_execute_command(cmd)) {
616 ERR("execute script failed : %s\n", cmd);
623 int _mh_core_disable_softap(void)
625 char cmd[MAX_BUF_SIZE] = { 0 };
626 int ret_status = MOBILE_AP_ERROR_NONE;
627 mobile_ap_drv_interface_e drv_interface = MOBILE_AP_DRV_INTERFACE_NONE;
630 char buf[MAX_BUF_SIZE] = { 0 };
631 char *if_name = WIFI_IF;
633 drv_interface = __get_drv_interface();
635 switch (drv_interface) {
637 if ((sock_fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
638 ERR("Failed to open socket...!!!\n");
639 ret_status = MOBILE_AP_ERROR_RESOURCE;
643 /* Stop broadcasting of BSS. */
644 snprintf(cmd, MAX_BUF_SIZE, "ASCII_CMD=AP_BSS_STOP");
645 ret_status = __issue_ioctl(sock_fd, if_name, cmd, buf);
646 if (ret_status != MOBILE_AP_ERROR_NONE) {
647 ERR("__issue_ioctl failed...!!!\n");
655 case MOBILE_AP_NL80211:
656 ret_status = __close_hostapd_intf(&hostapd_ctrl_fd);
657 if (ret_status != MOBILE_AP_ERROR_NONE)
658 ERR("hostapd termination is failed\n");
660 ret_status = __close_hostapd_monitor(&hostapd_monitor_fd);
661 if (ret_status != MOBILE_AP_ERROR_NONE)
662 ERR("hostapd termination is failed\n");
664 ret_status = __terminate_hostapd();
665 if (ret_status != MOBILE_AP_ERROR_NONE) {
666 ERR("hostapd termination is failed\n");
671 DBG("Unknown driver interface : %d\n", drv_interface);
675 snprintf(cmd, sizeof(cmd), "%s stop", WLAN_SCRIPT);
676 if (_execute_command(cmd)) {
677 ERR("execute script failed : %s\n", cmd);
678 ret_status = MOBILE_AP_ERROR_INTERNAL;
684 static int __get_device_info_by_wext(softap_device_info_t *di)
687 char *if_name = SOFTAP_IF;
688 char cmd[MAX_BUF_SIZE];
689 char buf[MAX_BUF_SIZE] = { 0 };
690 int ret = MOBILE_AP_ERROR_NONE;
692 char *buf_ptr = NULL;
695 if ((sock_fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
696 ERR("Failed to open socket...!!!\n");
698 return MOBILE_AP_ERROR_RESOURCE;
701 snprintf(cmd, MAX_BUF_SIZE, "AP_GET_STA_LIST");
702 ret = __issue_ioctl(sock_fd, if_name, cmd, buf);
703 if (ret != MOBILE_AP_ERROR_NONE) {
704 ERR("__issue_ioctl failed...!!!\n");
712 sscanf(buf_ptr, "%02x", &di->number);
713 DBG("connected station : %d\n", di->number);
716 for (i = 0; i < di->number; i++) {
717 unsigned int l_bssid[MOBILE_AP_WIFI_BSSID_LEN];
718 sscanf(buf_ptr, "%02X%02X%02X%02X%02X%02X", &l_bssid[0],
719 &l_bssid[1], &l_bssid[2], &l_bssid[3],
720 &l_bssid[4], &l_bssid[5]);
721 snprintf(di->bssid[i], MOBILE_AP_STR_INFO_LEN,
722 "%02X:%02X:%02X:%02X:%02X:%02X",
723 l_bssid[0], l_bssid[1], l_bssid[2],
724 l_bssid[3], l_bssid[4], l_bssid[5]);
726 DBG("STA[%d] address[%s]\n", i, di->bssid[i]);
736 static int __get_device_info_by_nl80211(softap_device_info_t *di)
741 char req[HOSTAPD_REQ_MAX_LEN] = {0, };
742 char buf[MOBILE_AP_STR_INFO_LEN] = {0, };
744 buf_len = sizeof(buf);
745 g_strlcpy(req, "NUM_STA", sizeof(req));
746 ret = __send_hostapd_req(hostapd_ctrl_fd,
747 req, strlen(req), buf, &buf_len);
748 if (ret != MOBILE_AP_ERROR_NONE) {
749 ERR("__send_hostapd_req is failed : %d\n", ret);
753 DBG("The number of station : %s\n", buf);
754 if (atoi(buf) == 0) {
755 DBG("There is no station\n");
756 return MOBILE_AP_ERROR_NONE;
759 buf_len = sizeof(buf);
760 g_strlcpy(req, "STA-FIRST", sizeof(req));
761 ret = __send_hostapd_req(hostapd_ctrl_fd,
762 req, strlen(req), buf, &buf_len);
763 if (ret != MOBILE_AP_ERROR_NONE) {
764 ERR("__send_hostapd_req is failed : %d\n", ret);
769 if (!strncmp(buf, "FAIL", 4)) {
770 ERR("FAIL is returned\n");
774 if (buf[0] == '\0') {
775 ERR("NULL string\n");
779 DBG("Station : %s\n", buf);
780 g_strlcpy(di->bssid[no_of_sta++], buf, MOBILE_AP_STR_INFO_LEN);
782 buf_len = sizeof(buf);
783 snprintf(req, sizeof(req), "STA-NEXT %s", buf);
784 ret = __send_hostapd_req(hostapd_ctrl_fd,
785 req, strlen(req), buf, &buf_len);
786 } while (ret == MOBILE_AP_ERROR_NONE);
788 di->number = no_of_sta;
793 int _mh_core_get_device_info(softap_device_info_t *di)
796 ERR("Invalid param\n");
797 return MOBILE_AP_ERROR_INVALID_PARAM;
800 int ret = MOBILE_AP_ERROR_NONE;
802 switch (__get_drv_interface()) {
804 ret = __get_device_info_by_wext(di);
807 case MOBILE_AP_NL80211:
808 ret = __get_device_info_by_nl80211(di);
812 ERR("Unknown interface\n");
819 int _mh_core_execute_dhcp_server(void)
821 char buf[DNSMASQ_CONF_LEN] = "";
825 fp = fopen(DNSMASQ_CONF_FILE, "w");
827 ERR("Could not create the file.\n");
828 return MOBILE_AP_ERROR_RESOURCE;
830 snprintf(buf, DNSMASQ_CONF_LEN, DNSMASQ_CONF);
836 ERR("fork failed\n");
837 return MOBILE_AP_ERROR_RESOURCE;
843 * -C file : Configuration file path
845 if (execl("/usr/bin/dnsmasq", "/usr/bin/dnsmasq", "-d",
846 "-p", "0", "-C", DNSMASQ_CONF_FILE,
848 ERR("execl failed\n");
851 ERR("Should not get here!");
852 return MOBILE_AP_ERROR_RESOURCE;
857 return MOBILE_AP_ERROR_NONE;
860 int _mh_core_terminate_dhcp_server(void)
862 if (dnsmasq_pid == 0) {
863 DBG("There is no dnsmasq\n");
864 return MOBILE_AP_ERROR_NONE;
867 kill(dnsmasq_pid, SIGTERM);
868 waitpid(dnsmasq_pid, NULL, 0);
871 return MOBILE_AP_ERROR_NONE;
874 int _mh_core_enable_masquerade(const char *ext_if)
876 if (ext_if == NULL || strlen(ext_if) == 0) {
877 ERR("ext_if[%s] is invalid\n", ext_if);
878 return MOBILE_AP_ERROR_INVALID_PARAM;
882 char cmd[MAX_BUF_SIZE] = {0, };
884 fd = open(IP_FORWARD, O_WRONLY);
886 ERR("open failed\n");
887 return MOBILE_AP_ERROR_RESOURCE;
890 if (write(fd, "1", 1) != 1) {
891 ERR("write failed\n");
893 return MOBILE_AP_ERROR_INTERNAL;
897 snprintf(cmd, sizeof(cmd), "%s -t nat -A POSTROUTING "MASQUERADE_RULE,
899 if (_execute_command(cmd)) {
900 ERR("iptables failed : %s\n", cmd);
901 return MOBILE_AP_ERROR_INTERNAL;
904 _add_data_usage_rule(WIFI_IF, ext_if);
905 _add_data_usage_rule(BT_IF_ALL, ext_if);
906 _add_data_usage_rule(USB_IF, ext_if);
908 return MOBILE_AP_ERROR_NONE;
911 int _mh_core_disable_masquerade(const char *ext_if)
913 if (ext_if == NULL || strlen(ext_if) == 0) {
914 ERR("ext_if[%s] is invalid\n", ext_if);
915 return MOBILE_AP_ERROR_INVALID_PARAM;
919 char cmd[MAX_BUF_SIZE] = {0, };
921 fd = open(IP_FORWARD, O_WRONLY);
923 ERR("open failed\n");
924 return MOBILE_AP_ERROR_RESOURCE;
927 if (write(fd, "0", 1) != 1) {
928 ERR("write failed\n");
930 return MOBILE_AP_ERROR_INTERNAL;
934 snprintf(cmd, sizeof(cmd), "%s -t nat -D POSTROUTING "MASQUERADE_RULE,
936 if (_execute_command(cmd)) {
937 ERR("iptables failed : %s\n", cmd);
938 return MOBILE_AP_ERROR_INTERNAL;
941 _del_data_usage_rule(WIFI_IF, ext_if);
942 _del_data_usage_rule(BT_IF_ALL, ext_if);
943 _del_data_usage_rule(USB_IF, ext_if);
945 return MOBILE_AP_ERROR_NONE;
948 void _mh_core_add_data_to_array(GPtrArray *array, guint type, gchar *dev_name)
950 GValue value = {0, {{0}}};
952 g_value_init(&value, DBUS_STRUCT_UINT_STRING);
953 g_value_take_boxed(&value,
954 dbus_g_type_specialized_construct(DBUS_STRUCT_UINT_STRING));
955 dbus_g_type_struct_set(&value, 0, type, 1, dev_name, G_MAXUINT);
956 g_ptr_array_add(array, g_value_get_boxed(&value));
959 int _mh_core_set_ip_address(const char *if_name, const in_addr_t ip)
962 struct sockaddr_in addr;
965 DBG("if_name : %s ip address : 0x%X\n", if_name, ip);
967 if ((sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
968 ERR("socket open failed!!!\n");
969 perror("ioctl fail");
970 return MOBILE_AP_ERROR_RESOURCE;
973 g_strlcpy(ifr.ifr_name, if_name, IFNAMSIZ);
975 memset(&addr, 0, sizeof(struct sockaddr));
976 addr.sin_family = AF_INET;
978 addr.sin_addr.s_addr = htonl(ip);
980 memcpy(&ifr.ifr_addr, &addr, sizeof(struct sockaddr));
981 if (ioctl(sock_fd, SIOCSIFADDR, &ifr) < 0) {
982 ERR("ioctl failed...!!!\n");
983 perror("ioctl fail");
985 return MOBILE_AP_ERROR_INTERNAL;
988 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifr) < 0) {
989 ERR("ioctl failed...!!!\n");
990 perror("ioctl fail");
992 return MOBILE_AP_ERROR_INTERNAL;
995 ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
996 if (ioctl(sock_fd, SIOCSIFFLAGS, &ifr) < 0) {
997 ERR("ioctl failed...!!!\n");
998 perror("ioctl fail");
1000 return MOBILE_AP_ERROR_INTERNAL;
1005 return MOBILE_AP_ERROR_NONE;