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 #include "../config.h"
00059
00060 static pthread_mutex_t ghbn_mutex = PTHREAD_MUTEX_INITIALIZER;
00061
00062
00063 extern time_t started_time;
00064
00065
00066 extern pthread_mutex_t client_list_mutex;
00067 extern pthread_mutex_t config_mutex;
00068
00069
00070 extern pid_t restart_orig_pid;
00071
00072
00073 static time_t last_online_time = 0;
00074 static time_t last_offline_time = 0;
00075 static time_t last_auth_online_time = 0;
00076 static time_t last_auth_offline_time = 0;
00077
00078 long served_this_session = 0;
00079
00085 int
00086 execute(char *cmd_line, int quiet)
00087 {
00088 int pid,
00089 status,
00090 rc;
00091
00092 const char *new_argv[4];
00093 new_argv[0] = "/bin/sh";
00094 new_argv[1] = "-c";
00095 new_argv[2] = cmd_line;
00096 new_argv[3] = NULL;
00097
00098 pid = safe_fork();
00099 if (pid == 0) {
00100
00101 if (quiet) close(2);
00102 if (execvp("/bin/sh", (char *const *)new_argv) < 0) {
00103 debug(LOG_ERR, "execvp(): %s", strerror(errno));
00104 exit(1);
00105 }
00106 }
00107 else {
00108 debug(LOG_DEBUG, "Waiting for PID %d to exit", pid);
00109 rc = waitpid(pid, &status, 0);
00110 debug(LOG_DEBUG, "Process PID %d exited", rc);
00111 }
00112
00113 return (WEXITSTATUS(status));
00114 }
00115
00116 struct in_addr *
00117 wd_gethostbyname(const char *name)
00118 {
00119 struct hostent *he;
00120 struct in_addr *h_addr, *in_addr_temp;
00121
00122
00123
00124 h_addr = safe_malloc(sizeof(struct in_addr));
00125
00126 LOCK_GHBN();
00127
00128 he = gethostbyname(name);
00129
00130 if (he == NULL) {
00131 free(h_addr);
00132 UNLOCK_GHBN();
00133 return NULL;
00134 }
00135
00136 mark_online();
00137
00138 in_addr_temp = (struct in_addr *)he->h_addr_list[0];
00139 h_addr->s_addr = in_addr_temp->s_addr;
00140
00141 UNLOCK_GHBN();
00142
00143 return h_addr;
00144 }
00145
00146 char *get_iface_ip(char *ifname) {
00147 #ifdef __linux__
00148 struct ifreq if_data;
00149 #endif
00150 struct in_addr in;
00151 char *ip_str;
00152 int sockd;
00153 u_int32_t ip;
00154
00155 #ifdef __linux__
00156
00157
00158 if ((sockd = socket (AF_INET, SOCK_PACKET, htons(0x8086))) < 0) {
00159 debug(LOG_ERR, "socket(): %s", strerror(errno));
00160 return NULL;
00161 }
00162
00163
00164 strcpy (if_data.ifr_name, ifname);
00165
00166
00167 if (ioctl (sockd, SIOCGIFADDR, &if_data) < 0) {
00168 debug(LOG_ERR, "ioctl(): SIOCGIFADDR %s", strerror(errno));
00169 return NULL;
00170 }
00171 memcpy ((void *) &ip, (void *) &if_data.ifr_addr.sa_data + 2, 4);
00172 in.s_addr = ip;
00173
00174 ip_str = (char *)inet_ntoa(in);
00175 return safe_strdup(ip_str);
00176 #else
00177 return safe_strdup("0.0.0.0");
00178 #endif
00179 }
00180
00181 char *get_iface_mac (char *ifname) {
00182 #ifdef __linux__
00183 int r, s;
00184 struct ifreq ifr;
00185 char *hwaddr, mac[13];
00186
00187 strcpy(ifr.ifr_name, ifname);
00188
00189 s = socket(PF_INET, SOCK_DGRAM, 0);
00190 if (-1 == s) {
00191 debug(LOG_ERR, "get_iface_mac socket: %s", strerror(errno));
00192 return NULL;
00193 }
00194
00195 r = ioctl(s, SIOCGIFHWADDR, &ifr);
00196 if (r == -1) {
00197 debug(LOG_ERR, "get_iface_mac ioctl(SIOCGIFHWADDR): %s", strerror(errno));
00198 close(s);
00199 return NULL;
00200 }
00201
00202 hwaddr = ifr.ifr_hwaddr.sa_data;
00203 snprintf(mac, 13, "%02X%02X%02X%02X%02X%02X",
00204 hwaddr[0] & 0xFF,
00205 hwaddr[1] & 0xFF,
00206 hwaddr[2] & 0xFF,
00207 hwaddr[3] & 0xFF,
00208 hwaddr[4] & 0xFF,
00209 hwaddr[5] & 0xFF
00210 );
00211
00212 close(s);
00213 return safe_strdup(mac);
00214 #else
00215 return NULL;
00216 #endif
00217 }
00218
00219 void mark_online() {
00220 int before;
00221 int after;
00222
00223 before = is_online();
00224 time(&last_online_time);
00225 after = is_online();
00226
00227 if (before != after) {
00228 debug(LOG_INFO, "ONLINE status became %s", (after ? "ON" : "OFF"));
00229 }
00230
00231 }
00232
00233 void mark_offline() {
00234 int before;
00235 int after;
00236
00237 before = is_online();
00238 time(&last_offline_time);
00239 after = is_online();
00240
00241 if (before != after) {
00242 debug(LOG_INFO, "ONLINE status became %s", (after ? "ON" : "OFF"));
00243 }
00244
00245
00246 mark_auth_offline();
00247
00248 }
00249
00250 int is_online() {
00251 if (last_online_time == 0 || (last_offline_time - last_online_time) >= (config_get_config()->checkinterval * 2) ) {
00252
00253 return (0);
00254 }
00255 else {
00256
00257 return (1);
00258 }
00259 }
00260
00261 void mark_auth_online() {
00262 int before;
00263 int after;
00264
00265 before = is_auth_online();
00266 time(&last_auth_online_time);
00267 after = is_auth_online();
00268
00269 if (before != after) {
00270 debug(LOG_INFO, "AUTH_ONLINE status became %s", (after ? "ON" : "OFF"));
00271 }
00272
00273
00274 mark_online();
00275
00276 }
00277
00278 void mark_auth_offline() {
00279 int before;
00280 int after;
00281
00282 before = is_auth_online();
00283 time(&last_auth_offline_time);
00284 after = is_auth_online();
00285
00286 if (before != after) {
00287 debug(LOG_INFO, "AUTH_ONLINE status became %s", (after ? "ON" : "OFF"));
00288 }
00289
00290 }
00291
00292 int is_auth_online() {
00293 if (!is_online()) {
00294
00295 return (0);
00296 }
00297 else if (last_auth_online_time == 0 || (last_auth_offline_time - last_auth_online_time) >= (config_get_config()->checkinterval * 2) ) {
00298
00299 return (0);
00300 }
00301 else {
00302
00303 return (1);
00304 }
00305 }
00306
00307
00308
00309
00310 char * get_status_text() {
00311 char buffer[STATUS_BUF_SIZ];
00312 ssize_t len;
00313 s_config *config;
00314 t_auth_serv *auth_server;
00315 t_client *first;
00316 int count;
00317 unsigned long int uptime = 0;
00318 unsigned int days = 0, hours = 0, minutes = 0, seconds = 0;
00319 t_trusted_mac *p;
00320
00321 len = 0;
00322 snprintf(buffer, (sizeof(buffer) - len), "WiFiDog status\n\n");
00323 len = strlen(buffer);
00324
00325 uptime = time(NULL) - started_time;
00326 days = uptime / (24 * 60 * 60);
00327 uptime -= days * (24 * 60 * 60);
00328 hours = uptime / (60 * 60);
00329 uptime -= hours * (60 * 60);
00330 minutes = uptime / 60;
00331 uptime -= minutes * 60;
00332 seconds = uptime;
00333
00334 snprintf((buffer + len), (sizeof(buffer) - len), "Version: " VERSION "\n");
00335 len = strlen(buffer);
00336
00337 snprintf((buffer + len), (sizeof(buffer) - len), "Uptime: %ud %uh %um %us\n", days, hours, minutes, seconds);
00338 len = strlen(buffer);
00339
00340 snprintf((buffer + len), (sizeof(buffer) - len), "Has been restarted: ");
00341 len = strlen(buffer);
00342 if (restart_orig_pid) {
00343 snprintf((buffer + len), (sizeof(buffer) - len), "yes (from PID %d)\n", restart_orig_pid);
00344 len = strlen(buffer);
00345 }
00346 else {
00347 snprintf((buffer + len), (sizeof(buffer) - len), "no\n");
00348 len = strlen(buffer);
00349 }
00350
00351 snprintf((buffer + len), (sizeof(buffer) - len), "Internet Connectivity: %s\n", (is_online() ? "yes" : "no"));
00352 len = strlen(buffer);
00353
00354 snprintf((buffer + len), (sizeof(buffer) - len), "Auth server reachable: %s\n", (is_auth_online() ? "yes" : "no"));
00355 len = strlen(buffer);
00356
00357 snprintf((buffer + len), (sizeof(buffer) - len), "Clients served this session: %lu\n\n", served_this_session);
00358 len = strlen(buffer);
00359
00360 LOCK_CLIENT_LIST();
00361
00362 first = client_get_first_client();
00363
00364 if (first == NULL) {
00365 count = 0;
00366 } else {
00367 count = 1;
00368 while (first->next != NULL) {
00369 first = first->next;
00370 count++;
00371 }
00372 }
00373
00374 snprintf((buffer + len), (sizeof(buffer) - len), "%d clients "
00375 "connected.\n", count);
00376 len = strlen(buffer);
00377
00378 first = client_get_first_client();
00379
00380 count = 0;
00381 while (first != NULL) {
00382 snprintf((buffer + len), (sizeof(buffer) - len), "\nClient %d\n", count);
00383 len = strlen(buffer);
00384
00385 snprintf((buffer + len), (sizeof(buffer) - len), " IP: %s MAC: %s\n", first->ip, first->mac);
00386 len = strlen(buffer);
00387
00388 snprintf((buffer + len), (sizeof(buffer) - len), " Token: %s\n", first->token);
00389 len = strlen(buffer);
00390
00391 snprintf((buffer + len), (sizeof(buffer) - len), " Downloaded: %llu\n Uploaded: %llu\n" , first->counters.incoming, first->counters.outgoing);
00392 len = strlen(buffer);
00393
00394 count++;
00395 first = first->next;
00396 }
00397
00398 UNLOCK_CLIENT_LIST();
00399
00400 config = config_get_config();
00401
00402 if (config->trustedmaclist != NULL) {
00403 snprintf((buffer + len), (sizeof(buffer) - len), "\nTrusted MAC addresses:\n");
00404 len = strlen(buffer);
00405
00406 for (p = config->trustedmaclist; p != NULL; p = p->next) {
00407 snprintf((buffer + len), (sizeof(buffer) - len), " %s\n", p->mac);
00408 len = strlen(buffer);
00409 }
00410 }
00411
00412 snprintf((buffer + len), (sizeof(buffer) - len), "\nAuthentication servers:\n");
00413 len = strlen(buffer);
00414
00415 LOCK_CONFIG();
00416
00417 for (auth_server = config->auth_servers; auth_server != NULL; auth_server = auth_server->next) {
00418 snprintf((buffer + len), (sizeof(buffer) - len), " Host: %s (%s)\n", auth_server->authserv_hostname, auth_server->last_ip);
00419 len = strlen(buffer);
00420 }
00421
00422 UNLOCK_CONFIG();
00423
00424 return safe_strdup(buffer);
00425 }