00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00030 #define _GNU_SOURCE
00031
00032 #include <stdio.h>
00033 #include <stdlib.h>
00034 #include <syslog.h>
00035 #include <errno.h>
00036 #include <pthread.h>
00037 #include <sys/wait.h>
00038 #include <sys/types.h>
00039 #include <sys/unistd.h>
00040 #include <netinet/in.h>
00041 #include <sys/ioctl.h>
00042
00043 #ifdef __linux__
00044 #include <net/if.h>
00045 #endif
00046
00047 #include <string.h>
00048 #include <pthread.h>
00049 #include <netdb.h>
00050
00051 #include "common.h"
00052 #include "client_list.h"
00053 #include "safe.h"
00054 #include "util.h"
00055 #include "conf.h"
00056 #include "debug.h"
00057
00058 static pthread_mutex_t ghbn_mutex = PTHREAD_MUTEX_INITIALIZER;
00059
00060
00061 extern time_t started_time;
00062
00063
00064 extern pthread_mutex_t client_list_mutex;
00065 extern pthread_mutex_t config_mutex;
00066
00067
00068 static time_t last_online_time = 0;
00069 static time_t last_offline_time = 0;
00070 static time_t last_auth_online_time = 0;
00071 static time_t last_auth_offline_time = 0;
00072
00078 int
00079 execute(char *cmd_line, int quiet)
00080 {
00081 int pid,
00082 status,
00083 rc;
00084
00085 const char *new_argv[4];
00086 new_argv[0] = "/bin/sh";
00087 new_argv[1] = "-c";
00088 new_argv[2] = cmd_line;
00089 new_argv[3] = NULL;
00090
00091 if ((pid = fork()) < 0) {
00092 debug(LOG_ERR, "fork(): %s", strerror(errno));
00093 exit(1);
00094 } else if (pid == 0) {
00095
00096 if (quiet) close(2);
00097 if (execvp("/bin/sh", (char *const *)new_argv) < 0) {
00098 debug(LOG_ERR, "execvp(): %s", strerror(errno));
00099 exit(1);
00100 }
00101 } else {
00102 do {
00103 rc = wait(&status);
00104 } while (rc != pid && rc != -1);
00105 }
00106
00107 return (WEXITSTATUS(status));
00108 }
00109
00110 struct in_addr *
00111 wd_gethostbyname(const char *name)
00112 {
00113 struct hostent *he;
00114 struct in_addr *h_addr, *in_addr_temp;
00115
00116
00117
00118 h_addr = safe_malloc(sizeof(struct in_addr));
00119
00120 LOCK_GHBN();
00121
00122 he = gethostbyname(name);
00123
00124 if (he == NULL) {
00125 free(h_addr);
00126 UNLOCK_GHBN();
00127 return NULL;
00128 }
00129
00130 mark_online();
00131
00132 in_addr_temp = (struct in_addr *)he->h_addr_list[0];
00133 h_addr->s_addr = in_addr_temp->s_addr;
00134
00135 UNLOCK_GHBN();
00136
00137 return h_addr;
00138 }
00139
00140 char *get_iface_ip(char *ifname) {
00141 #ifdef __linux__
00142 struct ifreq if_data;
00143 #endif
00144 struct in_addr in;
00145 char *ip_str;
00146 int sockd;
00147 u_int32_t ip;
00148
00149 #ifdef __linux__
00150
00151
00152 if ((sockd = socket (AF_INET, SOCK_PACKET, htons(0x8086))) < 0) {
00153 debug(LOG_ERR, "socket(): %s", strerror(errno));
00154 return NULL;
00155 }
00156
00157
00158 strcpy (if_data.ifr_name, ifname);
00159
00160
00161 if (ioctl (sockd, SIOCGIFADDR, &if_data) < 0) {
00162 debug(LOG_ERR, "ioctl(): SIOCGIFADDR %s", strerror(errno));
00163 return NULL;
00164 }
00165 memcpy ((void *) &ip, (void *) &if_data.ifr_addr.sa_data + 2, 4);
00166 in.s_addr = ip;
00167
00168 ip_str = (char *)inet_ntoa(in);
00169 return safe_strdup(ip_str);
00170 #else
00171 return safe_strdup("0.0.0.0");
00172 #endif
00173 }
00174
00175 void mark_online() {
00176 int before;
00177 int after;
00178
00179 before = is_online();
00180 time(&last_online_time);
00181 after = is_online();
00182
00183 if (before != after) {
00184 debug(LOG_INFO, "ONLINE status became %s", (after ? "ON" : "OFF"));
00185 }
00186
00187 }
00188
00189 void mark_offline() {
00190 int before;
00191 int after;
00192
00193 before = is_online();
00194 time(&last_offline_time);
00195 after = is_online();
00196
00197 if (before != after) {
00198 debug(LOG_INFO, "ONLINE status became %s", (after ? "ON" : "OFF"));
00199 }
00200
00201
00202 mark_auth_offline();
00203
00204 }
00205
00206 int is_online() {
00207 if (last_online_time == 0 || (last_offline_time - last_online_time) >= (config_get_config()->checkinterval * 2) ) {
00208
00209 return (0);
00210 }
00211 else {
00212
00213 return (1);
00214 }
00215 }
00216
00217 void mark_auth_online() {
00218 int before;
00219 int after;
00220
00221 before = is_auth_online();
00222 time(&last_auth_online_time);
00223 after = is_auth_online();
00224
00225 if (before != after) {
00226 debug(LOG_INFO, "AUTH_ONLINE status became %s", (after ? "ON" : "OFF"));
00227 }
00228
00229
00230 mark_online();
00231
00232 }
00233
00234 void mark_auth_offline() {
00235 int before;
00236 int after;
00237
00238 before = is_auth_online();
00239 time(&last_auth_offline_time);
00240 after = is_auth_online();
00241
00242 if (before != after) {
00243 debug(LOG_INFO, "AUTH_ONLINE status became %s", (after ? "ON" : "OFF"));
00244 }
00245
00246 }
00247
00248 int is_auth_online() {
00249 if (!is_online()) {
00250
00251 return (0);
00252 }
00253 else if (last_auth_online_time == 0 || (last_auth_offline_time - last_auth_online_time) >= (config_get_config()->checkinterval * 2) ) {
00254
00255 return (0);
00256 }
00257 else {
00258
00259 return (1);
00260 }
00261 }
00262
00263
00264
00265
00266 char * get_status_text() {
00267 char buffer[STATUS_BUF_SIZ];
00268 ssize_t len;
00269 s_config *config;
00270 t_auth_serv *auth_server;
00271 t_client *first;
00272 int count;
00273 unsigned long int uptime = 0;
00274 unsigned int days = 0, hours = 0, minutes = 0, seconds = 0;
00275
00276 len = 0;
00277 snprintf(buffer, (sizeof(buffer) - len), "WiFiDog status\n\n");
00278 len = strlen(buffer);
00279
00280 uptime = time(NULL) - started_time;
00281 days = uptime / (24 * 60 * 60);
00282 uptime -= days * (24 * 60 * 60);
00283 hours = uptime / (60 * 60);
00284 uptime -= hours * (60 * 60);
00285 minutes = uptime / 60;
00286 uptime -= minutes * 60;
00287 seconds = uptime;
00288
00289 snprintf((buffer + len), (sizeof(buffer) - len), "Uptime: %ud %uh %um %us\n", days, hours, minutes, seconds);
00290 len = strlen(buffer);
00291
00292 snprintf((buffer + len), (sizeof(buffer) - len), "is_online: %s\n", (is_online() ? "yes" : "no"));
00293 len = strlen(buffer);
00294
00295 snprintf((buffer + len), (sizeof(buffer) - len), "is_auth_online: %s\n\n", (is_auth_online() ? "yes" : "no"));
00296 len = strlen(buffer);
00297
00298 LOCK_CLIENT_LIST();
00299
00300 first = client_get_first_client();
00301
00302 if (first == NULL) {
00303 count = 0;
00304 } else {
00305 count = 1;
00306 while (first->next != NULL) {
00307 first = first->next;
00308 count++;
00309 }
00310 }
00311
00312 snprintf((buffer + len), (sizeof(buffer) - len), "%d clients "
00313 "connected.\n", count);
00314 len = strlen(buffer);
00315
00316 first = client_get_first_client();
00317
00318 count = 0;
00319 while (first != NULL) {
00320 snprintf((buffer + len), (sizeof(buffer) - len), "Client %d\t"
00321 "Ip: %s\tMac: %s\tToken: %s\n", count,
00322 first->ip, first->mac, first->token);
00323 len = strlen(buffer);
00324
00325 snprintf((buffer + len), (sizeof(buffer) - len), "\tIn: %llu\t"
00326 "Out: %llu\n" , first->counters.incoming,
00327 first->counters.outgoing);
00328 len = strlen(buffer);
00329
00330 count++;
00331 first = first->next;
00332 }
00333
00334 UNLOCK_CLIENT_LIST();
00335
00336 snprintf((buffer + len), (sizeof(buffer) - len), "\nAuthentication servers:\n");
00337 len = strlen(buffer);
00338
00339 LOCK_CONFIG();
00340
00341 config = config_get_config();
00342 for (auth_server = config->auth_servers; auth_server != NULL; auth_server = auth_server->next) {
00343 snprintf((buffer + len), (sizeof(buffer) - len), " Host: %s (%s)\n", auth_server->authserv_hostname, auth_server->last_ip);
00344 len = strlen(buffer);
00345 }
00346
00347 UNLOCK_CONFIG();
00348
00349 return safe_strdup(buffer);
00350 }