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

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  * $Header: /cvsroot/wifidog/wifidog/src/util.c,v 1.19 2005/03/12 02:02:01 minaguib Exp $
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 /* Defined in ping_thread.c */
00061 extern time_t started_time;
00062 
00063 /* Defined in clientlist.c */
00064 extern  pthread_mutex_t client_list_mutex;
00065 extern  pthread_mutex_t config_mutex;
00066 
00067 /* XXX Do these need to be locked ? */
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) {    /* fork a child process           */
00092         debug(LOG_ERR, "fork(): %s", strerror(errno));
00093         exit(1);
00094     } else if (pid == 0) {    /* for the child process:         */
00095         /* We don't want to see any errors if quiet flag is on */
00096         if (quiet) close(2);
00097         if (execvp("/bin/sh", (char *const *)new_argv) < 0) {    /* execute the command  */
00098             debug(LOG_ERR, "execvp(): %s", strerror(errno));
00099             exit(1);
00100         }
00101     } else {        /* for the parent:      */
00102         do {
00103             rc = wait(&status);
00104         } while (rc != pid && rc != -1);    /* wait for completion  */
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         /* XXX Calling function is reponsible for free() */
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     /* Create a socket */
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     /* Get IP of internal interface */
00158     strcpy (if_data.ifr_name, ifname);
00159 
00160     /* Get the IP address */
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         /* If we're offline it definately means the auth server is offline */
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                 /* We're probably offline */
00209                 return (0);
00210         }
00211         else {
00212                 /* We're probably online */
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         /* If auth server is online it means we're definately online */
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                 /* If we're not online auth is definately not online :) */
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                 /* Auth is  probably offline */
00255                 return (0);
00256         }
00257         else {
00258                 /* Auth is probably online */
00259                 return (1);
00260         }
00261 }
00262 
00263 /*
00264  * @return A string containing human-readable status text. MUST BE free()d by caller
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 }

Generated on Sun Apr 3 20:04:46 2005 for WifiDog by  doxygen 1.4.1