root/trunk/wifidog/src/util.c @ 469

Revision 469, 5.8 KB (checked in by minaguib, 8 years ago)

* Partial merge from CaptiveDNS branch: Consolidated much of the networking calls to the auth servers into a magical function called connect_auth_server() that's responsible for dns lookup, connecting, marking servers bad, marking online/auth_online, and refreshing the firewall rules.
* Partial merge from CaptiveDNS branch: Added new functions mark_auth_online(), mark_auth_offline() and is_auth_online() - similar in nature to is_online() etc. except tailored to decide on auth servers status - currently being called by connect_auth_server()
* Partial merge from CaptiveDNS branch: Different apology in 404 handler depending on whether internet is down or just auth server is down
* Partial merge from CaptiveDNS branch: wdctl status now shows status of is_online and is_auth_online

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/********************************************************************\
2 * This program is free software; you can redistribute it and/or    *
3 * modify it under the terms of the GNU General Public License as   *
4 * published by the Free Software Foundation; either version 2 of   *
5 * the License, or (at your option) any later version.              *
6 *                                                                  *
7 * This program is distributed in the hope that it will be useful,  *
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
10 * GNU General Public License for more details.                     *
11 *                                                                  *
12 * You should have received a copy of the GNU General Public License*
13 * along with this program; if not, contact:                        *
14 *                                                                  *
15 * Free Software Foundation           Voice:  +1-617-542-5942       *
16 * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
17 * Boston, MA  02111-1307,  USA       gnu@gnu.org                   *
18 *                                                                  *
19 \********************************************************************/
20
21/*
22 * $Header$
23 */
24/**
25  @file util.c
26  @brief Misc utility functions
27  @author Copyright (C) 2004 Philippe April <papril777@yahoo.com>
28 */
29
30#define _GNU_SOURCE
31
32#include <stdio.h>
33#include <stdlib.h>
34#include <syslog.h>
35#include <errno.h>
36#include <pthread.h>
37#include <sys/wait.h>
38#include <sys/types.h>
39#include <sys/unistd.h>
40#include <netinet/in.h>
41#include <sys/ioctl.h>
42#include <net/if.h>
43
44#include <string.h>
45#include <pthread.h>
46#include <netdb.h>
47
48#include "safe.h"
49#include "util.h"
50#include "conf.h"
51#include "debug.h"
52
53static pthread_mutex_t ghbn_mutex = PTHREAD_MUTEX_INITIALIZER;
54
55/* XXX Do these need to be locked ? */
56static time_t last_online_time = 0;
57static time_t last_offline_time = 0;
58static time_t last_auth_online_time = 0;
59static time_t last_auth_offline_time = 0;
60
61/** Fork a child and execute a shell command, the parent
62 * process waits for the child to return and returns the child's exit()
63 * value.
64 * @return Return code of the command
65 */
66int
67execute(char *cmd_line, int quiet)
68{
69    int pid,
70        status,
71        rc;
72
73    const char *new_argv[4];
74    new_argv[0] = "/bin/sh";
75    new_argv[1] = "-c";
76    new_argv[2] = cmd_line;
77    new_argv[3] = NULL;
78
79    if ((pid = fork()) < 0) {    /* fork a child process           */
80        debug(LOG_ERR, "fork(): %s", strerror(errno));
81        exit(1);
82    } else if (pid == 0) {    /* for the child process:         */
83        /* We don't want to see any errors if quiet flag is on */
84        if (quiet) close(2);
85        if (execvp("/bin/sh", (char *const *)new_argv) < 0) {    /* execute the command  */
86            debug(LOG_ERR, "execvp(): %s", strerror(errno));
87            exit(1);
88        }
89    } else {        /* for the parent:      */
90        do {
91            rc = wait(&status);
92        } while (rc != pid && rc != -1);    /* wait for completion  */
93    }
94
95    return (WEXITSTATUS(status));
96}
97
98struct in_addr *
99wd_gethostbyname(const char *name)
100{
101        struct hostent *he;
102        struct in_addr *h_addr, *in_addr_temp;
103
104        /* XXX Calling function is reponsible for free() */
105
106        h_addr = safe_malloc(sizeof(struct in_addr));
107       
108        LOCK_GHBN();
109
110        he = gethostbyname(name);
111
112        if (he == NULL) {
113                free(h_addr);
114                UNLOCK_GHBN();
115                mark_offline();
116                return NULL;
117        }
118
119        mark_online();
120
121        in_addr_temp = (struct in_addr *)he->h_addr_list[0];
122        h_addr->s_addr = in_addr_temp->s_addr;
123       
124        UNLOCK_GHBN();
125
126        return h_addr;
127}
128
129char *get_iface_ip(char *ifname) {
130    struct ifreq if_data;
131    struct in_addr in;
132    char *ip_str;
133    int sockd;
134    u_int32_t ip;
135
136    /* Create a socket */
137    if ((sockd = socket (AF_INET, SOCK_PACKET, htons(0x8086))) < 0) {
138        debug(LOG_ERR, "socket(): %s", strerror(errno));
139        return NULL;
140    }
141
142    /* Get IP of internal interface */
143    strcpy (if_data.ifr_name, ifname);
144
145    /* Get the IP address */
146    if (ioctl (sockd, SIOCGIFADDR, &if_data) < 0) {
147        debug(LOG_ERR, "ioctl(): SIOCGIFADDR %s", strerror(errno));
148        return NULL;
149    }
150    memcpy ((void *) &ip, (void *) &if_data.ifr_addr.sa_data + 2, 4);
151    in.s_addr = ip;
152
153    ip_str = (char *)inet_ntoa(in);
154    return safe_strdup(ip_str);
155}
156
157void mark_online() {
158        int isonline;
159        isonline = is_online();
160        time(&last_online_time);
161        if (!isonline) {
162                debug(LOG_INFO, "ONLINE status changed to ON");
163        }
164}
165
166void mark_offline() {
167        int isonline;
168        isonline = is_online();
169        time(&last_offline_time);
170        /* If we're offline it definately means the auth server is offline */
171        mark_auth_offline();
172        if (isonline) {
173                debug(LOG_INFO, "ONLINE status changed to OFF");
174        }
175}
176
177int is_online() {
178        if (last_online_time == 0 || (last_offline_time - last_online_time) >= (config_get_config()->checkinterval * 2) ) {
179                /* We're probably offline */
180                return (0);
181        }
182        else {
183                /* We're probably online */
184                return (1);
185        }
186}
187
188void mark_auth_online() {
189        int isauthonline;
190        isauthonline = is_auth_online();
191        time(&last_auth_online_time);
192        /* If auth server is online it means we're definately online */
193        mark_online();
194        if (!isauthonline) {
195                debug(LOG_INFO, "AUTH_ONLINE status changed to ON");
196        }
197}
198
199void mark_auth_offline() {
200        int isauthonline;
201        isauthonline = is_auth_online();
202        time(&last_auth_offline_time);
203        if (isauthonline) {
204                debug(LOG_INFO, "AUTH_ONLINE status changed to OFF");
205        }
206}
207
208int is_auth_online() {
209        if (!is_online()) {
210                /* If we're not online auth is definately not online :) */
211                return (0);
212        }
213        else if (last_auth_online_time == 0 || (last_auth_offline_time - last_auth_online_time) >= (config_get_config()->checkinterval * 2) ) {
214                /* Auth is  probably offline */
215                return (0);
216        }
217        else {
218                /* Auth is probably online */
219                return (1);
220        }
221}
222
Note: See TracBrowser for help on using the browser.