--- /dev/null
+#!/bin/sh
+PATH=/bin:/usr/bin:/sbin:/usr/sbin
+
+#--------------------------------------
+# Common Information Dump
+#--------------------------------------
+
+# not allow to use relative path
+if [[ $0 == "/"* ]]; then
+ echo "Absolute path"
+else
+ echo "Relative path"
+ exit -1
+fi
+
+export DISPLAY=:0.0
+
+REPORT_TYPE=offline_detection
+COMMON_INFO_FILE=$1
+
+echo $2 > ${COMMON_INFO_FILE}
+echo $3 >> ${COMMON_INFO_FILE}
+
+if [ $4 == ${REPORT_TYPE} ]; then
+echo "" >> ${COMMON_INFO_FILE}
+echo "[Default Connection Information]" >> ${COMMON_INFO_FILE}
+dbus-send --system --print-reply --dest=net.connman / net.connman.Manager.GetDefaultService >> ${COMMON_INFO_FILE}
+fi
+
+echo "" >> ${COMMON_INFO_FILE}
+echo [netstat -na] >> ${COMMON_INFO_FILE}
+/usr/bin/netstat -na >> ${COMMON_INFO_FILE}
+echo "" >> ${COMMON_INFO_FILE}
+
+echo [route -n] >> ${COMMON_INFO_FILE}
+/usr/sbin/route -n >> ${COMMON_INFO_FILE}
+echo "" >> ${COMMON_INFO_FILE}
+
+echo [route -A inet6 -n] >> ${COMMON_INFO_FILE}
+/usr/sbin/route -A inet6 -n >> ${COMMON_INFO_FILE}
+echo "" >> ${COMMON_INFO_FILE}
+
+echo [proc/net/wireless] >> ${COMMON_INFO_FILE}
+/usr/bin/cat /proc/net/wireless >> ${COMMON_INFO_FILE}
+echo "" >> ${COMMON_INFO_FILE}
+
+echo [resolv.conf] >> ${COMMON_INFO_FILE}
+/usr/bin/cat /etc/resolv.conf >> ${COMMON_INFO_FILE}
+echo "" >> ${COMMON_INFO_FILE}
+
+echo [ifconfig -a] >> ${COMMON_INFO_FILE}
+/usr/sbin/ifconfig -a >> ${COMMON_INFO_FILE}
+echo "" >> ${COMMON_INFO_FILE}
+
+echo [iptables -L] >> ${COMMON_INFO_FILE}
+/usr/sbin/iptables -L >> ${COMMON_INFO_FILE}
+echo "" >> ${COMMON_INFO_FILE}
+
+echo [ip6tables -L] >> ${COMMON_INFO_FILE}
+/usr/sbin/ip6tables -L >> ${COMMON_INFO_FILE}
+echo "" >> ${COMMON_INFO_FILE}
+
+echo [/proc/net/tcp] >> ${COMMON_INFO_FILE}
+/usr/bin/cat /proc/net/tcp >> ${COMMON_INFO_FILE}
+echo "" >> ${COMMON_INFO_FILE}
+
+echo [/proc/net/tcp6] >> ${COMMON_INFO_FILE}
+/usr/bin/cat /proc/net/tcp6 >> ${COMMON_INFO_FILE}
+echo "" >> ${COMMON_INFO_FILE}
+
+echo [/proc/net/route] >> ${COMMON_INFO_FILE}
+/usr/bin/cat /proc/net/route >> ${COMMON_INFO_FILE}
+echo "" >> ${COMMON_INFO_FILE}
+
+echo [ip -4 rule] >> ${COMMON_INFO_FILE}
+/usr/sbin/ip -4 rule >> ${COMMON_INFO_FILE}
+echo "" >> ${COMMON_INFO_FILE}
+
+echo [ip -6 rule] >> ${COMMON_INFO_FILE}
+/usr/sbin/ip -6 rule >> ${COMMON_INFO_FILE}
+echo "" >> ${COMMON_INFO_FILE}
+
+echo [ip -4 route show table all] >> ${COMMON_INFO_FILE}
+/usr/sbin/ip -4 route show table all >> ${COMMON_INFO_FILE}
+echo "" >> ${COMMON_INFO_FILE}
+
+echo [ip -6 route show table all] >> ${COMMON_INFO_FILE}
+/usr/sbin/ip -6 route show table all >> ${COMMON_INFO_FILE}
+echo "" >> ${COMMON_INFO_FILE}
+
+echo [memory/dnet] >> ${COMMON_INFO_FILE}
+/usr/bin/vconftool -r get memory/dnet >> ${COMMON_INFO_FILE}
+echo "" >> ${COMMON_INFO_FILE}
+
+echo [memory/wifi] >> ${COMMON_INFO_FILE}
+/usr/bin/vconftool -r get memory/wifi >> ${COMMON_INFO_FILE}
+echo "" >> ${COMMON_INFO_FILE}
+
+echo [file/private/wifi] >> ${COMMON_INFO_FILE}
+/usr/bin/vconftool -r get file/private/wifi >> ${COMMON_INFO_FILE}
+echo "" >> ${COMMON_INFO_FILE}
+
+echo [db/wifi] >> ${COMMON_INFO_FILE}
+/usr/bin/vconftool -r get db/wifi >> ${COMMON_INFO_FILE}
*
*/
+#include <stdio.h>
+#include <sys/wait.h>
#include "online-monitor.h"
+#define ONLINE_MON_LOG_PATH "/opt/usr/data/network/online_mon/"
+
+#define OFFLINE_DETECT_COMMON_LOG ONLINE_MON_LOG_PATH "offline_detection_common.log"
+#define OFFLINE_DETECT_DLOG ONLINE_MON_LOG_PATH "offline_detection_dlog.log"
+#define OFFLINE_DETECT_PACKET_DUMP ONLINE_MON_LOG_PATH "offline_detection_dump.log"
+#define OFFLINE_DETECT_PACKET_DUMP0 ONLINE_MON_LOG_PATH "offline_detection_dump.log0"
+#define OFFLINE_DETECT_PACKET_DUMP1 ONLINE_MON_LOG_PATH "offline_detection_dump.log1"
+
+#define DOWNGRADE_COMMON_LOG ONLINE_MON_LOG_PATH "downgrade_common.log"
+#define DOWNGRADE_DLOG ONLINE_MON_LOG_PATH "downgrade_dlog.log"
+#define DOWNGRADE_SUPP_LOG ONLINE_MON_LOG_PATH "downgrade_supp.log"
+
+#define KILLALL_EXEC_PATH "/usr/bin/killall"
+#define TCPDUMP_EXEC_PATH "/usr/sbin/tcpdump"
+#define COMMON_INFO_SCRIPT "/opt/var/lib/net-config/common_info_dump.sh"
+#define SUPPLICANT_LOG_SCRIPT "/opt/var/lib/net-config/supp_log_dump.sh"
+#define DLOGUTIL_EXEC_PATH "/usr/bin/dlogutil"
+
+static struct {
+ char *ifname;
+ online_monitor_state_e state;
+ online_monitor_detection_e reason;
+ gboolean tcpdump_started;
+ int detection_count;
+ int downgrade_count;
+ int max_log_count;
+} report_manager_info;
+
+static inline void report_manager_update_file_revision(int rev, const char *file_path)
+{
+ int next_log_rev = 0;
+ char *log_file = NULL;
+ char *next_log_file = NULL;
+
+ next_log_rev = rev + 1;
+
+ log_file = g_strdup_printf("%s.%d", file_path, rev);
+ next_log_file = g_strdup_printf("%s.%d", file_path, next_log_rev);
+
+ if (next_log_rev >= report_manager_info.max_log_count - 1)
+ remove(next_log_file);
+
+ if (access(next_log_file, F_OK) == 0)
+ report_manager_update_file_revision(next_log_rev, file_path);
+
+ if (rename(log_file, next_log_file) != 0)
+ remove(log_file);
+
+ g_free(log_file);
+ g_free(next_log_file);
+}
+
+static inline void report_manager_make_backup(const char *file_path)
+{
+ const int rev = 0;
+ char *backup = NULL;
+
+ backup = g_strdup_printf("%s.%d", file_path, rev);
+
+ if (access(backup, F_OK) == 0)
+ report_manager_update_file_revision(rev, file_path);
+
+ if (rename(file_path, backup) != 0)
+ remove(file_path);
+
+ g_free(backup);
+}
+
+static int report_manager_execute_file(const char *file_path,
+ char *const args[], char *const envs[])
+{
+ pid_t pid = 0;
+ int status = 0;
+ int rv = 0;
+ errno = 0;
+ register unsigned int index = 0;
+ char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
+
+ while (args[index] != NULL) {
+ DBG("%s", args[index]);
+ index++;
+ }
+
+ if (!(pid = fork())) {
+ DBG("pid(%d), ppid (%d)", getpid(), getppid());
+ DBG("Inside child, exec (%s) command", file_path);
+
+ errno = 0;
+ if (execve(file_path, args, envs) == -1) {
+ DBG("Fail to execute command (%s)",
+ strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
+ exit(1);
+ }
+ } else if (pid > 0) {
+ if (waitpid(pid, &status, 0) == -1)
+ DBG("wait pid (%u) status (%d)", pid, status);
+
+ if (WIFEXITED(status)) {
+ rv = WEXITSTATUS(status);
+ DBG("exited, status=%d", rv);
+ } else if (WIFSIGNALED(status)) {
+ DBG("killed by signal %d", WTERMSIG(status));
+ } else if (WIFSTOPPED(status)) {
+ DBG("stopped by signal %d", WSTOPSIG(status));
+ } else if (WIFCONTINUED(status)) {
+ DBG("continued");
+ }
+
+ return rv;
+ }
+
+ DBG("failed to fork(%s)",
+ strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
+ return -EIO;
+}
+
+static void no_wait_signal_handler()
+{
+ pid_t child_pid = 0;
+ int state = 0;
+
+ child_pid = waitpid(-1, &state, WNOHANG);
+
+ DBG("child_id(%d) state(%d)", child_pid, WEXITSTATUS(state));
+}
+
+static int report_manager_execute_file_no_wait(const char *file_path, char *const args[])
+{
+ pid_t pid = 0;
+ int rv = 0;
+ errno = 0;
+ register unsigned int index = 0;
+
+ struct sigaction act;
+ int state = 0;
+ char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
+
+ act.sa_handler = no_wait_signal_handler;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = 0;
+
+ state = sigaction(SIGCHLD, &act, 0);
+ if (state != 0) {
+ DBG("sigaction() : %d", state);
+ return -1;
+ }
+
+ while (args[index] != NULL) {
+ DBG("%s", args[index]);
+ index++;
+ }
+
+ if (!(pid = fork())) {
+ DBG("pid(%d), ppid (%d)", getpid(), getppid());
+ DBG("Inside child, exec (%s) command", file_path);
+
+ errno = 0;
+ if (execvp(file_path, args) == -1) {
+ ERR("Fail to execute command (%s)",
+ strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
+ return -1;
+ }
+ } else if (pid > 0) {
+ ERR("Successfully launched child process");
+ return rv;
+ }
+
+ DBG("failed to fork(%s)",
+ strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
+ return -EIO;
+}
+
+static gboolean report_manager_stop_tcpdump(void)
+{
+ int ret;
+ const char *path = KILLALL_EXEC_PATH;
+ char *const args[] = { KILLALL_EXEC_PATH, "tcpdump", NULL };
+ char *const envs[] = { NULL };
+
+ if (!report_manager_info.tcpdump_started) {
+ DBG("tcpdump is not running");
+ return FALSE;
+ }
+
+ ret = report_manager_execute_file(path, args, envs);
+ if (ret < 0) {
+ DBG("Failed to Kill tcpdump, ret : %d\n", ret);
+ return FALSE;
+ }
+
+ report_manager_info.tcpdump_started = FALSE;
+
+ return TRUE;
+}
+
+static gboolean report_manager_start_tcpdump(void)
+{
+ int ret;
+ const char *start_path = TCPDUMP_EXEC_PATH;
+
+ if (access(OFFLINE_DETECT_PACKET_DUMP0, F_OK) == 0)
+ report_manager_make_backup(OFFLINE_DETECT_PACKET_DUMP0);
+ if (access(OFFLINE_DETECT_PACKET_DUMP1, F_OK) == 0)
+ report_manager_make_backup(OFFLINE_DETECT_PACKET_DUMP1);
+
+ char *const start_args[] = { TCPDUMP_EXEC_PATH,
+ "-W", "2", "-C", "25", "-i", report_manager_info.ifname,
+ "-s", "0", "-w", OFFLINE_DETECT_PACKET_DUMP, NULL};
+
+ if (report_manager_info.tcpdump_started) {
+ DBG("kill tcpdump.");
+ gboolean ret = report_manager_stop_tcpdump();
+
+ if (!ret)
+ DBG("Failed to kill tcpdump.. ret : %d", ret);
+
+ return FALSE;
+ }
+
+ ret = report_manager_execute_file_no_wait(start_path, start_args);
+ if (ret < 0) {
+ DBG("Failed to start tcpdump, ret : %d", ret);
+ return FALSE;
+ }
+
+ report_manager_info.tcpdump_started = TRUE;
+
+ return report_manager_info.tcpdump_started;
+}
+
+static char *convert_detection_reason(online_monitor_detection_e reason)
+{
+ switch (reason) {
+ case ONLINE_MONITOR_DETECTION_UNREACHABLE:
+ return "Destination Unreachable";
+ case ONLINE_MONITOR_DETECTION_DNS_REFUSED:
+ return "DNS Refused";
+ case ONLINE_MONITOR_DETECTION_NO_DNS_RESPONSE:
+ return "No DNS Response";
+ default:
+ return "None";
+ }
+}
+
+static void report_manager_start_common_info_dump(gboolean is_downgrade)
+{
+ int rv = 0;
+ gchar *path = COMMON_INFO_SCRIPT;
+ char log_file_name[100] = { 0, };
+ char detection_count[64] = { 0, };
+ char sub_info[64] = { 0, };
+ char report_type[32] = { 0, };
+
+ if (is_downgrade) {
+ g_snprintf(log_file_name, 100, DOWNGRADE_COMMON_LOG);
+ g_snprintf(detection_count, 64, "Offline Detection Count: %d",
+ report_manager_info.detection_count);
+ g_snprintf(sub_info, 64, "Downgrade Count: %d",
+ report_manager_info.downgrade_count);
+ g_snprintf(report_type, 32, "downgrade");
+ } else {
+ g_snprintf(log_file_name, 100, OFFLINE_DETECT_COMMON_LOG);
+ g_snprintf(detection_count, 64, "Offline Detection Count: %d",
+ report_manager_info.detection_count);
+ g_snprintf(sub_info, 64, "Detection Reason: %s",
+ convert_detection_reason(report_manager_info.reason));
+ g_snprintf(report_type, 32, "offline_detection");
+ }
+
+ if (access(log_file_name, F_OK) == 0)
+ report_manager_make_backup(log_file_name);
+
+ char *const args[] = { COMMON_INFO_SCRIPT,
+ log_file_name, detection_count, sub_info, report_type, NULL };
+ char *const envs[] = { NULL };
+
+ rv = report_manager_execute_file(path, args, envs);
+
+ if (rv < 0)
+ ERR("Fail to execute network log dump shell");
+}
+
+static void report_manager_start_dlog_dump(gboolean is_downgrade)
+{
+ int rv = 0;
+ gchar *path = DLOGUTIL_EXEC_PATH;
+ char log_file_name[100] = { 0, };
+
+ if (is_downgrade)
+ g_snprintf(log_file_name, 100, DOWNGRADE_DLOG);
+ else
+ g_snprintf(log_file_name, 100, OFFLINE_DETECT_DLOG);
+
+ if (access(log_file_name, F_OK) == 0)
+ report_manager_make_backup(log_file_name);
+
+ char *const args[] = { DLOGUTIL_EXEC_PATH, "-f", log_file_name, "-d", "-t", "2000", NULL };
+ char *const envs[] = { NULL };
+
+ rv = report_manager_execute_file(path, args, envs);
+
+ if (rv < 0)
+ ERR("Fail to execute dlog dump command");
+}
+
+static void report_manager_start_supp_dump(void)
+{
+ int rv = 0;
+ gchar *path = SUPPLICANT_LOG_SCRIPT;
+
+ if (access(DOWNGRADE_SUPP_LOG, F_OK) == 0)
+ report_manager_make_backup(DOWNGRADE_SUPP_LOG);
+
+ char *const args[] = { SUPPLICANT_LOG_SCRIPT, DOWNGRADE_SUPP_LOG, NULL };
+ char *const envs[] = { NULL };
+
+ rv = report_manager_execute_file(path, args, envs);
+
+ if (rv < 0)
+ ERR("Fail to execute supplicant log dump shell");
+}
+
+static void report_manager_start_downgrade_dump(void)
+{
+ online_monitor_config_t *config = online_monitor_get_configuration();
+
+ report_manager_stop_tcpdump();
+
+ if (config->common_info)
+ report_manager_start_common_info_dump(TRUE);
+
+ if (config->dlog)
+ report_manager_start_dlog_dump(TRUE);
+
+ if (config->supplicant_log)
+ report_manager_start_supp_dump();
+}
+
+static void report_manager_start_detection_dump(void)
+{
+ online_monitor_config_t *config = online_monitor_get_configuration();
+
+ if (config->common_info)
+ report_manager_start_common_info_dump(FALSE);
+
+ if (config->dlog)
+ report_manager_start_dlog_dump(FALSE);
+
+ if (config->packet_dump)
+ report_manager_start_tcpdump();
+}
+
static void report_manager_state_chaged_cb(online_monitor_state_e state,
char *ifname, online_monitor_detection_e reason)
{
DBG("state %d, ifname %s, reason %d", state, ifname, reason);
+
+ report_manager_info.state = state;
+ report_manager_info.reason = reason;
+
+ switch (state) {
+ case ONLINE_MONITOR_STATE_MONITORING_STARTED:
+ report_manager_info.ifname = ifname;
+ break;
+ case ONLINE_MONITOR_STATE_MONITORING_STOPPED:
+ report_manager_stop_tcpdump();
+ report_manager_info.ifname = NULL;
+ break;
+ case ONLINE_MONITOR_STATE_OFFLINE_DETECTED:
+ report_manager_info.detection_count++;
+ report_manager_start_detection_dump();
+ break;
+ case ONLINE_MONITOR_STATE_URL_CHECK_SUCCEEDED:
+ report_manager_stop_tcpdump();
+ break;
+ case ONLINE_MONITOR_STATE_URL_CHECK_FAILED:
+ report_manager_info.downgrade_count++;
+ report_manager_start_downgrade_dump();
+ break;
+ default :
+ break;
+ }
}
int report_manager_init(void)
{
- online_monitor_notifier_register(report_manager_state_chaged_cb);
+ online_monitor_config_t *config = online_monitor_get_configuration();
+
+ if (config->common_info || config->dlog || config->supplicant_log || config->packet_dump)
+ online_monitor_notifier_register(report_manager_state_chaged_cb);
+
+ memset(&report_manager_info, 0, sizeof(report_manager_info));
+
+ report_manager_info.max_log_count = config->max_report_count;
+ report_manager_info.state = ONLINE_MONITOR_STATE_INITIALIZED;
DBG("report_manager initialized");
+
return 0;
}
int report_manager_deinit(void)
{
online_monitor_notifier_unregister(report_manager_state_chaged_cb);
+ report_manager_stop_tcpdump();
+
+ report_manager_info.state = ONLINE_MONITOR_STATE_UNINITIALIZED;
DBG("report_manager deinitialized");
+
return 0;
}