luci-0.8: Merge r4467, r4468
This commit is contained in:
parent
684dc1a1aa
commit
0ddb6064a3
8 changed files with 1811 additions and 0 deletions
50
contrib/package/freifunk-watchdog/Makefile
Normal file
50
contrib/package/freifunk-watchdog/Makefile
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
#
|
||||||
|
# Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org>
|
||||||
|
#
|
||||||
|
# This is free software, licensed under the GNU General Public License v2.
|
||||||
|
# See /LICENSE for more information.
|
||||||
|
#
|
||||||
|
|
||||||
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
|
PKG_NAME:=freifunk-watchdog
|
||||||
|
PKG_RELEASE:=1
|
||||||
|
|
||||||
|
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
|
||||||
|
|
||||||
|
include $(INCLUDE_DIR)/package.mk
|
||||||
|
|
||||||
|
define Package/freifunk-watchdog
|
||||||
|
SECTION:=utils
|
||||||
|
CATEGORY:=Utilities
|
||||||
|
TITLE:=Freifunk Ad-Hoc watchdog daemon
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/freifunk-watchdog/description
|
||||||
|
A watchdog daemon that monitors wireless interfaces to ensure the correct bssid and channel.
|
||||||
|
The process will initiate a wireless restart as soon as it detects a bssid or channel mismatch.
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Build/Prepare
|
||||||
|
mkdir -p $(PKG_BUILD_DIR)
|
||||||
|
$(CP) ./src/* $(PKG_BUILD_DIR)/
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Build/Configure
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Build/Compile
|
||||||
|
$(MAKE) -C $(PKG_BUILD_DIR) \
|
||||||
|
CC="$(TARGET_CC)" \
|
||||||
|
CFLAGS="$(TARGET_CFLAGS) -I$(STAGING_DIR)/usr/include" \
|
||||||
|
LDFLAGS="$(TARGET_LDFLAGS)"
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/freifunk-watchdog/install
|
||||||
|
$(INSTALL_DIR) $(1)/etc/init.d
|
||||||
|
$(INSTALL_BIN) ./files/freifunk-watchdog.init $(1)/etc/init.d/freifunk-watchdog
|
||||||
|
$(INSTALL_DIR) $(1)/usr/sbin
|
||||||
|
$(INSTALL_BIN) $(PKG_BUILD_DIR)/ffwatchd $(1)/usr/sbin/
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(eval $(call BuildPackage,freifunk-watchdog))
|
24
contrib/package/freifunk-watchdog/files/freifunk-watchdog.init
Executable file
24
contrib/package/freifunk-watchdog/files/freifunk-watchdog.init
Executable file
|
@ -0,0 +1,24 @@
|
||||||
|
#!/bin/sh /etc/rc.common
|
||||||
|
|
||||||
|
START=99
|
||||||
|
PID=/var/run/ffwatchd.pid
|
||||||
|
BIN=/usr/sbin/ffwatchd
|
||||||
|
|
||||||
|
boot()
|
||||||
|
{
|
||||||
|
if ! grep -q "$BIN" /etc/crontabs/root 2>/dev/null; then
|
||||||
|
echo "* * * * * $BIN running || /etc/init.d/freifunk-watchdog restart" >> /etc/crontabs/root
|
||||||
|
fi
|
||||||
|
|
||||||
|
start
|
||||||
|
}
|
||||||
|
|
||||||
|
start()
|
||||||
|
{
|
||||||
|
start-stop-daemon -q -b -m -p $PID -x $BIN -S
|
||||||
|
}
|
||||||
|
|
||||||
|
stop()
|
||||||
|
{
|
||||||
|
start-stop-daemon -q -p $PID -x $BIN -K
|
||||||
|
}
|
12
contrib/package/freifunk-watchdog/src/Makefile
Normal file
12
contrib/package/freifunk-watchdog/src/Makefile
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
WD_BINARY:=ffwatchd
|
||||||
|
WD_CFLAGS:=$(CFLAGS) -c -DBINARY=\"$(WD_BINARY)\"
|
||||||
|
WD_LDFLAGS:=$(LDFLAGS) -lm -luci
|
||||||
|
|
||||||
|
watchdog:
|
||||||
|
$(CC) $(WD_CFLAGS) -o ucix.o ucix.c
|
||||||
|
$(CC) $(WD_CFLAGS) -o watchdog.o watchdog.c
|
||||||
|
$(CC) $(WD_LDFLAGS) -o $(WD_BINARY) watchdog.o ucix.o
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *~ $(WD_BINARY) *.o
|
||||||
|
|
98
contrib/package/freifunk-watchdog/src/ucix.c
Normal file
98
contrib/package/freifunk-watchdog/src/ucix.c
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
/*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008 John Crispin <blogic@openwrt.org>
|
||||||
|
*
|
||||||
|
* Changed by Jo-Philipp Wich <xm@subsignal.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <uci_config.h>
|
||||||
|
#include <uci.h>
|
||||||
|
#include "ucix.h"
|
||||||
|
|
||||||
|
static struct uci_ptr ptr;
|
||||||
|
|
||||||
|
static inline int ucix_get_ptr(struct uci_context *ctx, const char *p, const char *s, const char *o, const char *t)
|
||||||
|
{
|
||||||
|
memset(&ptr, 0, sizeof(ptr));
|
||||||
|
ptr.package = p;
|
||||||
|
ptr.section = s;
|
||||||
|
ptr.option = o;
|
||||||
|
ptr.value = t;
|
||||||
|
return uci_lookup_ptr(ctx, &ptr, NULL, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct uci_context* ucix_init(const char *config_file)
|
||||||
|
{
|
||||||
|
struct uci_context *ctx = uci_alloc_context();
|
||||||
|
uci_add_history_path(ctx, "/var/state");
|
||||||
|
if(uci_load(ctx, config_file, NULL) != UCI_OK)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ucix_cleanup(struct uci_context *ctx)
|
||||||
|
{
|
||||||
|
uci_free_context(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* ucix_get_option(struct uci_context *ctx, const char *p, const char *s, const char *o)
|
||||||
|
{
|
||||||
|
struct uci_element *e = NULL;
|
||||||
|
const char *value = NULL;
|
||||||
|
if(ucix_get_ptr(ctx, p, s, o, NULL))
|
||||||
|
return NULL;
|
||||||
|
if (!(ptr.flags & UCI_LOOKUP_COMPLETE))
|
||||||
|
return NULL;
|
||||||
|
e = ptr.last;
|
||||||
|
switch (e->type)
|
||||||
|
{
|
||||||
|
case UCI_TYPE_SECTION:
|
||||||
|
value = uci_to_section(e)->type;
|
||||||
|
break;
|
||||||
|
case UCI_TYPE_OPTION:
|
||||||
|
switch(ptr.o->type) {
|
||||||
|
case UCI_TYPE_STRING:
|
||||||
|
value = ptr.o->v.string;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
value = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ucix_for_each_section_type(struct uci_context *ctx,
|
||||||
|
const char *p, const char *t,
|
||||||
|
void (*cb)(const char*, void*), void *priv)
|
||||||
|
{
|
||||||
|
struct uci_element *e;
|
||||||
|
if(ucix_get_ptr(ctx, p, NULL, NULL, NULL))
|
||||||
|
return;
|
||||||
|
uci_foreach_element(&ptr.p->sections, e)
|
||||||
|
if (!strcmp(t, uci_to_section(e)->type))
|
||||||
|
cb(e->name, priv);
|
||||||
|
}
|
||||||
|
|
29
contrib/package/freifunk-watchdog/src/ucix.h
Normal file
29
contrib/package/freifunk-watchdog/src/ucix.h
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008 John Crispin <blogic@openwrt.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _UCI_H__
|
||||||
|
#define _UCI_H__
|
||||||
|
struct uci_context* ucix_init(const char *config_file);
|
||||||
|
|
||||||
|
void ucix_for_each_section_type(struct uci_context *ctx,
|
||||||
|
const char *p, const char *t,
|
||||||
|
void (*cb)(const char*, void*), void *priv);
|
||||||
|
|
||||||
|
const char* ucix_get_option(struct uci_context *ctx,
|
||||||
|
const char *p, const char *s, const char *o);
|
||||||
|
#endif
|
352
contrib/package/freifunk-watchdog/src/watchdog.c
Normal file
352
contrib/package/freifunk-watchdog/src/watchdog.c
Normal file
|
@ -0,0 +1,352 @@
|
||||||
|
/*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "watchdog.h"
|
||||||
|
|
||||||
|
/* Get BSSID of given interface */
|
||||||
|
static int iw_get_bssid(int iwfd, const char *ifname, char *bssid)
|
||||||
|
{
|
||||||
|
struct iwreq iwrq;
|
||||||
|
|
||||||
|
if( iw_ioctl(iwfd, ifname, SIOCGIWAP, &iwrq) >= 0 )
|
||||||
|
{
|
||||||
|
unsigned char *addr = (unsigned char *)iwrq.u.ap_addr.sa_data;
|
||||||
|
|
||||||
|
sprintf(bssid, "%02X:%02X:%02X:%02X:%02X:%02X",
|
||||||
|
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get channel of given interface */
|
||||||
|
static int iw_get_channel(int iwfd, const char *ifname, int *channel)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char buffer[sizeof(struct iw_range)];
|
||||||
|
double cur_freq, cmp_freq;
|
||||||
|
struct iwreq iwrq;
|
||||||
|
struct iw_range *range;
|
||||||
|
|
||||||
|
memset(buffer, 0, sizeof(buffer));
|
||||||
|
|
||||||
|
iwrq.u.data.pointer = (char *)buffer;
|
||||||
|
iwrq.u.data.length = sizeof(buffer);
|
||||||
|
iwrq.u.data.flags = 0;
|
||||||
|
|
||||||
|
if( iw_ioctl(iwfd, ifname, SIOCGIWRANGE, &iwrq) < 0)
|
||||||
|
{
|
||||||
|
*channel = -1;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
range = (struct iw_range *)buffer;
|
||||||
|
|
||||||
|
if( iw_ioctl(iwfd, ifname, SIOCGIWFREQ, &iwrq) >= 0 )
|
||||||
|
{
|
||||||
|
cur_freq = ((double)iwrq.u.freq.m) * pow(10, iwrq.u.freq.e);
|
||||||
|
if( cur_freq < 1000.00 )
|
||||||
|
{
|
||||||
|
*channel = (int)cur_freq;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < range->num_frequency; i++)
|
||||||
|
{
|
||||||
|
cmp_freq = ((double)range->freq[i].m) * pow(10, range->freq[i].e);
|
||||||
|
if( cmp_freq == cur_freq )
|
||||||
|
{
|
||||||
|
*channel = (int)range->freq[i].i;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*channel = -1;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the (first) pid of given process name */
|
||||||
|
static int find_process(const char *name)
|
||||||
|
{
|
||||||
|
int pid = -1;
|
||||||
|
int file;
|
||||||
|
char buffer[128];
|
||||||
|
char cmpname[128];
|
||||||
|
DIR *dir;
|
||||||
|
struct dirent *entry;
|
||||||
|
|
||||||
|
if( (dir = opendir("/proc")) != NULL )
|
||||||
|
{
|
||||||
|
snprintf(cmpname, sizeof(cmpname), "Name:\t%s\n", name);
|
||||||
|
|
||||||
|
while( (entry = readdir(dir)) != NULL )
|
||||||
|
{
|
||||||
|
if( !strcmp(entry->d_name, "..") || !isdigit(*entry->d_name) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
sprintf(buffer, "/proc/%s/status", entry->d_name);
|
||||||
|
if( (file = open(buffer, O_RDONLY)) > -1 )
|
||||||
|
{
|
||||||
|
read(file, buffer, sizeof(buffer));
|
||||||
|
close(file);
|
||||||
|
|
||||||
|
if( strstr(buffer, cmpname) == buffer )
|
||||||
|
{
|
||||||
|
pid = atoi(entry->d_name);
|
||||||
|
|
||||||
|
/* Skip myself ... */
|
||||||
|
if( pid == getpid() )
|
||||||
|
pid = -1;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(dir);
|
||||||
|
return pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
syslog(LOG_CRIT, "Unable to open /proc: %s",
|
||||||
|
strerror(errno));
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if given uci file was updated */
|
||||||
|
static int check_uci_update(const char *config, time_t *mtime)
|
||||||
|
{
|
||||||
|
struct stat s;
|
||||||
|
char path[128];
|
||||||
|
|
||||||
|
snprintf(path, sizeof(path), "/etc/config/%s", config);
|
||||||
|
if( stat(path, &s) > -1 )
|
||||||
|
{
|
||||||
|
if( (*mtime == 0) || (s.st_mtime > *mtime) )
|
||||||
|
{
|
||||||
|
*mtime = s.st_mtime;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
snprintf(path, sizeof(path), "/var/state/%s", config);
|
||||||
|
if( stat(path, &s) > -1 )
|
||||||
|
{
|
||||||
|
if( (*mtime == 0) || (s.st_mtime > *mtime) )
|
||||||
|
{
|
||||||
|
*mtime = s.st_mtime;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add tuple */
|
||||||
|
static void load_wifi_uci_add_iface(const char *section, struct uci_itr_ctx *itr)
|
||||||
|
{
|
||||||
|
wifi_tuple_t *t;
|
||||||
|
const char *ucitmp;
|
||||||
|
int val = 0;
|
||||||
|
|
||||||
|
if( (t = (wifi_tuple_t *)malloc(sizeof(wifi_tuple_t))) != NULL )
|
||||||
|
{
|
||||||
|
ucitmp = ucix_get_option(itr->ctx, "wireless", section, "ifname");
|
||||||
|
if(ucitmp)
|
||||||
|
{
|
||||||
|
strncpy(t->ifname, ucitmp, sizeof(t->ifname));
|
||||||
|
val++;
|
||||||
|
}
|
||||||
|
|
||||||
|
ucitmp = ucix_get_option(itr->ctx, "wireless", section, "bssid");
|
||||||
|
if(ucitmp)
|
||||||
|
{
|
||||||
|
strncpy(t->bssid, ucitmp, sizeof(t->bssid));
|
||||||
|
val++;
|
||||||
|
}
|
||||||
|
|
||||||
|
ucitmp = ucix_get_option(itr->ctx, "wireless", section, "device");
|
||||||
|
if(ucitmp)
|
||||||
|
{
|
||||||
|
ucitmp = ucix_get_option(itr->ctx, "wireless", ucitmp, "channel");
|
||||||
|
if(ucitmp)
|
||||||
|
{
|
||||||
|
t->channel = atoi(ucitmp);
|
||||||
|
val++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( val == 3 )
|
||||||
|
{
|
||||||
|
syslog(LOG_INFO, "Monitoring %s: bssid=%s channel=%d",
|
||||||
|
t->ifname, t->bssid, t->channel);
|
||||||
|
|
||||||
|
t->next = itr->list;
|
||||||
|
itr->list = t;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load config */
|
||||||
|
static wifi_tuple_t * load_wifi_uci(wifi_tuple_t *ifs, time_t *modtime)
|
||||||
|
{
|
||||||
|
struct uci_context *ctx;
|
||||||
|
struct uci_itr_ctx itr;
|
||||||
|
wifi_tuple_t *cur, *next;
|
||||||
|
|
||||||
|
if( check_uci_update("wireless", modtime) )
|
||||||
|
{
|
||||||
|
syslog(LOG_INFO, "Config changed, reloading");
|
||||||
|
|
||||||
|
if( (ctx = ucix_init("wireless")) != NULL )
|
||||||
|
{
|
||||||
|
if( ifs != NULL )
|
||||||
|
{
|
||||||
|
for(cur = ifs; cur; cur = next)
|
||||||
|
{
|
||||||
|
next = cur->next;
|
||||||
|
free(cur);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
itr.list = NULL;
|
||||||
|
itr.ctx = ctx;
|
||||||
|
|
||||||
|
ucix_for_each_section_type(ctx, "wireless", "wifi-iface",
|
||||||
|
(void *)load_wifi_uci_add_iface, &itr);
|
||||||
|
|
||||||
|
return itr.list;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ifs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Daemon implementation */
|
||||||
|
static int do_daemon(void)
|
||||||
|
{
|
||||||
|
int iwfd;
|
||||||
|
int channel;
|
||||||
|
char bssid[18];
|
||||||
|
|
||||||
|
wifi_tuple_t *ifs = NULL, *curif;
|
||||||
|
time_t modtime = 0;
|
||||||
|
|
||||||
|
int restart_wifi = 0;
|
||||||
|
int restart_cron = 0;
|
||||||
|
|
||||||
|
openlog(SYSLOG_IDENT, 0, LOG_DAEMON);
|
||||||
|
//daemon(1, 1);
|
||||||
|
|
||||||
|
if( (iwfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1 )
|
||||||
|
{
|
||||||
|
perror("Can not open wireless control socket");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while( 1 )
|
||||||
|
{
|
||||||
|
if( (ifs = load_wifi_uci(ifs, &modtime)) == NULL )
|
||||||
|
{
|
||||||
|
printf("Can not load wireless uci. File corrupt?\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check crond */
|
||||||
|
if( find_process("crond") < 0 )
|
||||||
|
{
|
||||||
|
syslog(LOG_WARNING, "The crond process died, restarting");
|
||||||
|
restart_cron++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check wireless interfaces */
|
||||||
|
for( curif = ifs; curif; curif = curif->next )
|
||||||
|
{
|
||||||
|
/* Get current channel and bssid */
|
||||||
|
if( (iw_get_bssid(iwfd, curif->ifname, bssid) == 0) &&
|
||||||
|
(iw_get_channel(iwfd, curif->ifname, &channel) == 0) )
|
||||||
|
{
|
||||||
|
/* Check BSSID */
|
||||||
|
if( strcasecmp(bssid, curif->bssid) != 0 )
|
||||||
|
{
|
||||||
|
syslog(LOG_WARNING, "BSSID mismatch on %s: current=%s wanted=%s",
|
||||||
|
curif->ifname, bssid, curif->bssid);
|
||||||
|
|
||||||
|
restart_wifi++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check channel */
|
||||||
|
if( channel != curif->channel )
|
||||||
|
{
|
||||||
|
syslog(LOG_WARNING, "Channel mismatch on %s: current=%d wanted=%d",
|
||||||
|
curif->ifname, channel, curif->channel);
|
||||||
|
|
||||||
|
restart_wifi++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
syslog(LOG_WARNING, "Requested interface %s not present", curif->ifname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Wifi restart required? */
|
||||||
|
if( restart_wifi > 0 )
|
||||||
|
{
|
||||||
|
restart_wifi = 0;
|
||||||
|
EXEC(WIFI_ACTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cron restart required? */
|
||||||
|
if( restart_cron > 0 )
|
||||||
|
{
|
||||||
|
restart_cron = 0;
|
||||||
|
EXEC(CRON_ACTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep(INTERVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
closelog();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
/* Check if watchdog is running ... */
|
||||||
|
if( (argc > 1) && (strcmp(argv[1], "running") == 0) )
|
||||||
|
{
|
||||||
|
return (find_process(BINARY) == -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Start daemon */
|
||||||
|
return do_daemon();
|
||||||
|
}
|
107
contrib/package/freifunk-watchdog/src/watchdog.h
Normal file
107
contrib/package/freifunk-watchdog/src/watchdog.h
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
/*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include "ucix.h"
|
||||||
|
#include "wireless.22.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Check interval */
|
||||||
|
#define INTERVAL 30
|
||||||
|
|
||||||
|
/* How to call myself in the logs */
|
||||||
|
#define SYSLOG_IDENT "Freifunk Watchdog"
|
||||||
|
|
||||||
|
/* Wifi error action */
|
||||||
|
#define WIFI_ACTION "/sbin/wifi", "/sbin/wifi"
|
||||||
|
|
||||||
|
/* Crond error action */
|
||||||
|
#define CRON_ACTION "/etc/init.d/cron", "/etc/init.d/cron", "restart"
|
||||||
|
|
||||||
|
/* Fallback binary name (passed by makefile) */
|
||||||
|
#ifndef BINARY
|
||||||
|
#define BINARY "ffwatchd"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* ifname/bssid/channel tuples */
|
||||||
|
struct wifi_tuple {
|
||||||
|
char ifname[16];
|
||||||
|
char bssid[18];
|
||||||
|
int channel;
|
||||||
|
struct wifi_tuple *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* structure to hold tuple-list and uci context during iteration */
|
||||||
|
struct uci_itr_ctx {
|
||||||
|
struct wifi_tuple *list;
|
||||||
|
struct uci_context *ctx;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct wifi_tuple wifi_tuple_t;
|
||||||
|
|
||||||
|
|
||||||
|
/* ioctl() helper (stolen from iwlib) */
|
||||||
|
static inline int
|
||||||
|
iw_ioctl(int skfd, /* Socket to the kernel */
|
||||||
|
const char * ifname, /* Device name */
|
||||||
|
int request, /* WE ID */
|
||||||
|
struct iwreq * pwrq) /* Fixed part of the request */
|
||||||
|
{
|
||||||
|
/* Set device name */
|
||||||
|
strncpy(pwrq->ifr_ifrn.ifrn_name, ifname, 16);
|
||||||
|
|
||||||
|
/* Do the request */
|
||||||
|
return(ioctl(skfd, request, pwrq));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fork() & execl() helper */
|
||||||
|
#define EXEC(x) \
|
||||||
|
do { \
|
||||||
|
switch(fork()) \
|
||||||
|
{ \
|
||||||
|
case -1: \
|
||||||
|
syslog(LOG_CRIT, "Unable to fork child: %s", \
|
||||||
|
strerror(errno)); \
|
||||||
|
\
|
||||||
|
break; \
|
||||||
|
\
|
||||||
|
case 0: \
|
||||||
|
execl(x, NULL); \
|
||||||
|
syslog(LOG_CRIT, "Unable to execute action: %s", \
|
||||||
|
strerror(errno)); \
|
||||||
|
\
|
||||||
|
return 1; \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
1139
contrib/package/freifunk-watchdog/src/wireless.22.h
Normal file
1139
contrib/package/freifunk-watchdog/src/wireless.22.h
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue