Main Page | Data Structures | Directories | File List | Data Fields

wifidog-1.1.3_beta2/src/util.c

00001 /********************************************************************\
00002  * This program is free software; you can redistribute it and/or    *
00003  * modify it under the terms of the GNU General Public License as   *
00004  * published by the Free Software Foundation; either version 2 of   *
00005  * the License, or (at your option) any later version.              *
00006  *                                                                  *
00007  * This program is distributed in the hope that it will be useful,  *
00008  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
00009  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
00010  * GNU General Public License for more details.                     *
00011  *                                                                  *
00012  * You should have received a copy of the GNU General Public License*
00013  * along with this program; if not, contact:                        *
00014  *                                                                  *
00015  * Free Software Foundation           Voice:  +1-617-542-5942       *
00016  * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
00017  * Boston, MA  02111-1307,  USA       gnu@gnu.org                   *
00018  *                                                                  *
00019  \********************************************************************/
00020 
00021 /*
00022  * $Id: util.c 935 2006-01-31 22:22:04 -0500 (Tue, 31 Jan 2006) benoitg $
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 /* Defined in ping_thread.c */
00063 extern time_t started_time;
00064 
00065 /* Defined in clientlist.c */
00066 extern  pthread_mutex_t client_list_mutex;
00067 extern  pthread_mutex_t config_mutex;
00068 
00069 /* Defined in commandline.c */
00070 extern pid_t restart_orig_pid;
00071 
00072 /* XXX Do these need to be locked ? */
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) {    /* for the child process:         */
00100         /* We don't want to see any errors if quiet flag is on */
00101         if (quiet) close(2);
00102         if (execvp("/bin/sh", (char *const *)new_argv) < 0) {    /* execute the command  */
00103             debug(LOG_ERR, "execvp(): %s", strerror(errno));
00104             exit(1);
00105         }
00106     }
00107          else {        /* for the parent:      */
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         /* XXX Calling function is reponsible for free() */
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     /* Create a socket */
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     /* Get IP of internal interface */
00164     strcpy (if_data.ifr_name, ifname);
00165 
00166     /* Get the IP address */
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         /* If we're offline it definately means the auth server is offline */
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                 /* We're probably offline */
00253                 return (0);
00254         }
00255         else {
00256                 /* We're probably online */
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         /* If auth server is online it means we're definately online */
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                 /* If we're not online auth is definately not online :) */
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                 /* Auth is  probably offline */
00299                 return (0);
00300         }
00301         else {
00302                 /* Auth is probably online */
00303                 return (1);
00304         }
00305 }
00306 
00307 /*
00308  * @return A string containing human-readable status text. MUST BE free()d by caller
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 }

Generated on Tue Jan 31 23:13:16 2006 for WifiDog by  doxygen 1.4.4