Merge pull request #18913 from jempatel/improve_apinger-procd-uci
apinger: improve uci and procd support
This commit is contained in:
commit
6c34135cad
9 changed files with 1027 additions and 9 deletions
|
@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk
|
|||
PKG_NAME:=apinger
|
||||
PKG_SOURCE_DATE:=2015-04-09
|
||||
PKG_SOURCE_VERSION:=78eb328721ba1a10571c19df95acddcb5f0c17c8
|
||||
PKG_RELEASE:=2
|
||||
PKG_RELEASE:=$(AUTORELEASE)
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://github.com/Jajcus/apinger
|
||||
|
@ -46,7 +46,8 @@ define Package/apinger/description
|
|||
endef
|
||||
|
||||
define Package/apinger/conffiles
|
||||
/etc/apinger.conf
|
||||
/etc/config/apinger
|
||||
/etc/apinger.user
|
||||
endef
|
||||
|
||||
define Package/apinger/install
|
||||
|
@ -56,6 +57,14 @@ define Package/apinger/install
|
|||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/src/apinger.conf $(1)/etc/apinger.conf
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_BIN) ./files/apinger.init $(1)/etc/init.d/apinger
|
||||
$(INSTALL_DIR) $(1)/etc/config
|
||||
$(INSTALL_DATA) ./files/apinger.config $(1)/etc/config/apinger
|
||||
$(INSTALL_DIR) $(1)/usr/libexec
|
||||
$(INSTALL_BIN) ./files/apinger-hotplug $(1)/usr/libexec/apinger-hotplug
|
||||
$(INSTALL_DIR) $(1)/etc/hotplug.d/apinger
|
||||
$(INSTALL_DATA) ./files/user.hotplug $(1)/etc/hotplug.d/apinger/01-user
|
||||
$(INSTALL_DIR) $(1)/etc/hotplug.d/iface
|
||||
$(INSTALL_DATA) ./files/iface.hotplug $(1)/etc/hotplug.d/iface/25-apinger
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,apinger))
|
||||
|
|
22
net/apinger/files/apinger-hotplug
Normal file
22
net/apinger/files/apinger-hotplug
Normal file
|
@ -0,0 +1,22 @@
|
|||
#!/bin/sh
|
||||
|
||||
usage_help()
|
||||
{
|
||||
echo "$0 <action> <instance> <target> <srcip> <target_desc> <alarm> <alarmtype> <reason> <send> <recieved> <loss> <delay> <timestamp>"
|
||||
}
|
||||
|
||||
export ACTION=$1
|
||||
export INSTANCE=$2
|
||||
export APINGER_TARGET=$3
|
||||
export APINGER_SRCIP=$4
|
||||
export APINGER_TARGET_ID=$5
|
||||
export APINGER_ALARM=$6
|
||||
export APINGER_ALARM_TYPE=$7
|
||||
export APINGER_ALARM_MESSAGE=$8
|
||||
export APINGER_PROBES_SENT=$9
|
||||
export APINGER_PROBES_RECEIVED=${10}
|
||||
export APINGER_LOSS=${11}
|
||||
export APINGER_DELAY=${12}
|
||||
export APINGER_TIMESTAMP=${13}
|
||||
|
||||
exec /sbin/hotplug-call apinger $@
|
28
net/apinger/files/apinger.config
Normal file
28
net/apinger/files/apinger.config
Normal file
|
@ -0,0 +1,28 @@
|
|||
config interface 'wan'
|
||||
option debug '0'
|
||||
option status_interval '5'
|
||||
|
||||
#config interface 'wan2'
|
||||
# option debug '0'
|
||||
# option status_interval '5'
|
||||
|
||||
# delay is in ms
|
||||
#config alarm_delay 'delay200'
|
||||
# option delay_low '100'
|
||||
# option delay_high '200'
|
||||
|
||||
# loss is in %
|
||||
#config alarm_loss 'loss50'
|
||||
# option percent_low '30'
|
||||
# option percent_high '50'
|
||||
|
||||
#config target 'target1'
|
||||
# option interface 'wan'
|
||||
# option address '8.8.8.8'
|
||||
# option alarm_delay 'a1'
|
||||
# option alarm_loss 'loss50'
|
||||
# option probe_interval '5'
|
||||
|
||||
#config target 'target2'
|
||||
# option interface 'wan2'
|
||||
# option address '8.8.8.8'
|
|
@ -2,17 +2,233 @@
|
|||
# Copyright (C) 2006-2011 OpenWrt.org
|
||||
|
||||
START=80
|
||||
USE_PROCD=1
|
||||
|
||||
SERVICE_USE_PID=1
|
||||
. /lib/functions/network.sh
|
||||
|
||||
start() {
|
||||
service_start /usr/sbin/apinger
|
||||
set_config_file() {
|
||||
export CONFIG_FILE="/var/run/apinger-$instance.conf"
|
||||
}
|
||||
|
||||
stop() {
|
||||
service_stop /usr/sbin/apinger
|
||||
set_status_file() {
|
||||
export STATUS_FILE="/var/run/apinger-$instance.status"
|
||||
}
|
||||
|
||||
reload() {
|
||||
service_reload /usr/sbin/apinger
|
||||
write_config_block() {
|
||||
local cfg_var="CONFIG_BLOCK_$instance"
|
||||
eval echo -e "\$$cfg_var" >> "$CONFIG_FILE"
|
||||
}
|
||||
|
||||
start_config_block() {
|
||||
eval "export CONFIG_BLOCK_$instance=''"
|
||||
append CONFIG_BLOCK_$instance "$* {" "\n"
|
||||
}
|
||||
|
||||
close_config_block() {
|
||||
append CONFIG_BLOCK_$instance "}" "\n"
|
||||
}
|
||||
|
||||
append_config_line() {
|
||||
append CONFIG_BLOCK_$instance "\t$*" "\n"
|
||||
}
|
||||
|
||||
append_target() {
|
||||
local target=$1
|
||||
local interface address probe_interval srcip
|
||||
local avg_delay_samples avg_loss_samples avg_loss_delay_samples
|
||||
local alarm_down alarm_delay alarm_loss alarms
|
||||
|
||||
config_get interface "$target" interface wan
|
||||
[ "$interface" != "$instance" ] && return 0
|
||||
|
||||
config_get address "$target" address
|
||||
config_get probe_interval "$target" probe_interval
|
||||
config_get avg_delay_samples "$target" avg_delay_samples
|
||||
config_get avg_loss_samples "$target" avg_loss_samples
|
||||
config_get avg_loss_delay_samples "$target" avg_loss_delay_samples
|
||||
config_get alarm_down "$target" alarm_down
|
||||
config_get alarm_delay "$target" alarm_delay
|
||||
config_get alarm_loss "$target" alarm_loss
|
||||
|
||||
[ -z "$address" ] && return 0
|
||||
|
||||
srcip=$(uci_get network "$interface" ipaddr)
|
||||
[ -z "$srcip" ] && network_get_ipaddr srcip "$interface"
|
||||
srcip="${srcip:-0.0.0.0}"
|
||||
|
||||
alarms=${alarm_down:+\"${alarm_down}\"}
|
||||
alarms=${alarm_delay:+${alarms:+${alarms}, }}${alarm_delay:+\"${alarm_delay}\"}
|
||||
alarms=${alarm_loss:+${alarms:+${alarms}, }}${alarm_loss:+\"${alarm_loss}\"}
|
||||
|
||||
start_config_block "target \"$address\""
|
||||
append_config_line "srcip \"$srcip\""
|
||||
append_config_line "description \"$target\""
|
||||
|
||||
[ -n "$probe_interval" ] && append_config_line "interval ${probe_interval}s"
|
||||
[ -n "$avg_delay_samples" ] && append_config_line "avg_delay_samples ${avg_delay_samples}"
|
||||
[ -n "$avg_loss_samples" ] && append_config_line "avg_loss_samples ${avg_loss_samples}"
|
||||
[ -n "$avg_loss_delay_samples" ] && append_config_line "avg_loss_delay_samples ${avg_loss_delay_samples}"
|
||||
[ -n "$alarms" ] && append_config_line "alarms override ${alarms}"
|
||||
|
||||
close_config_block
|
||||
write_config_block
|
||||
}
|
||||
|
||||
append_alarm_down() {
|
||||
local alarm=$1
|
||||
local time
|
||||
|
||||
config_get time "$alarm" time 5
|
||||
|
||||
[ -z "$time" ] && return
|
||||
|
||||
start_config_block "alarm down \"$alarm\""
|
||||
append_config_line "time ${time}s"
|
||||
close_config_block
|
||||
write_config_block
|
||||
}
|
||||
|
||||
append_alarm_delay() {
|
||||
local alarm=$1
|
||||
local delay_low delay_high
|
||||
|
||||
config_get delay_low "$alarm" delay_low
|
||||
config_get delay_high "$alarm" delay_high
|
||||
|
||||
if [ -z "$delay_low" ] || [ -z "$delay_high" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
start_config_block "alarm delay \"$alarm\""
|
||||
append_config_line "delay_low ${delay_low}ms"
|
||||
append_config_line "delay_high ${delay_high}ms"
|
||||
close_config_block
|
||||
write_config_block
|
||||
}
|
||||
|
||||
append_alarm_loss() {
|
||||
local alarm=$1
|
||||
local percent_low percent_high
|
||||
|
||||
config_get percent_low "$alarm" percent_low
|
||||
config_get percent_high "$alarm" percent_low
|
||||
|
||||
if [ -z "$percent_low" ] || [ -z "$percent_high" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
start_config_block "alarm loss \"$alarm\""
|
||||
append_config_line "percent_low ${percent_low}"
|
||||
append_config_line "percent_high ${percent_high}"
|
||||
close_config_block
|
||||
write_config_block
|
||||
}
|
||||
|
||||
init_apinger_config() {
|
||||
local debug status_interval instance
|
||||
instance=$1
|
||||
|
||||
config_get_bool debug apinger debug 0
|
||||
config_get status_interval apinger status_interval 1
|
||||
|
||||
[ "$debug" == "1" ] && debug=on || debug=off
|
||||
|
||||
set_config_file
|
||||
set_status_file
|
||||
|
||||
cat << EOF > "$CONFIG_FILE"
|
||||
user "root"
|
||||
group "root"
|
||||
debug ${debug}
|
||||
|
||||
status {
|
||||
scriptformat on
|
||||
file "$STATUS_FILE"
|
||||
interval ${status_interval}s
|
||||
}
|
||||
alarm down "down" {
|
||||
time 30s
|
||||
}
|
||||
alarm delay "delay" {
|
||||
delay_low 5ms
|
||||
delay_high 20ms
|
||||
}
|
||||
alarm loss "loss" {
|
||||
percent_low 3
|
||||
percent_high 5
|
||||
}
|
||||
alarm default {
|
||||
command on "/usr/libexec/apinger-hotplug up $instance '%t' '%i' '%T' '%a' '%A' '%r' '%p' '%P' '%l' '%d' '%s'"
|
||||
command off "/usr/libexec/apinger-hotplug down $instance '%t' '%i' '%T' '%a' '%A' '%r' '%p' '%P' '%l' '%d' '%s'"
|
||||
}
|
||||
target default {
|
||||
interval 1s
|
||||
avg_delay_samples 10
|
||||
avg_loss_samples 50
|
||||
avg_loss_delay_samples 20
|
||||
alarms "down", "delay", "loss"
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
start_instance() {
|
||||
export instance=$1
|
||||
|
||||
local enabled
|
||||
config_get_bool enabled "$instance" enabled 1
|
||||
[ "$enabled" != "1" ] && return 0
|
||||
|
||||
init_apinger_config "$instance"
|
||||
config_foreach append_alarm_down alarm_down
|
||||
config_foreach append_alarm_delay alarm_delay
|
||||
config_foreach append_alarm_loss alarm_loss
|
||||
config_foreach append_target target
|
||||
|
||||
procd_open_instance "$instance"
|
||||
procd_set_param command /usr/sbin/apinger -f -c $CONFIG_FILE
|
||||
procd_set_param stderr 1
|
||||
procd_set_param stdout 1
|
||||
procd_close_instance
|
||||
}
|
||||
|
||||
start_service() {
|
||||
local instance=$1
|
||||
|
||||
config_load apinger
|
||||
|
||||
if [ -n "$instance" ]; then
|
||||
start_instance "$instance"
|
||||
else
|
||||
config_foreach start_instance interface
|
||||
fi
|
||||
}
|
||||
|
||||
service_triggers() {
|
||||
procd_add_reload_trigger apinger
|
||||
}
|
||||
|
||||
clean_instance() {
|
||||
local instance=$1
|
||||
|
||||
set_config_file
|
||||
set_status_file
|
||||
|
||||
[ -e $CONFIG_FILE ] && rm -f $CONFIG_FILE
|
||||
[ -e $STATUS_FILE ] && rm -f $STATUS_FILE
|
||||
}
|
||||
|
||||
service_stopped() {
|
||||
local instance=$1
|
||||
|
||||
config_load apinger
|
||||
|
||||
if [ -n "$instance" ]; then
|
||||
clean_instance "$instance"
|
||||
else
|
||||
config_foreach clean_instance interface
|
||||
fi
|
||||
}
|
||||
|
||||
reload_service() {
|
||||
restart
|
||||
}
|
||||
|
|
12
net/apinger/files/iface.hotplug
Normal file
12
net/apinger/files/iface.hotplug
Normal file
|
@ -0,0 +1,12 @@
|
|||
#!/bin/sh
|
||||
|
||||
. /lib/functions.sh
|
||||
|
||||
/etc/init.d/apinger enabled && {
|
||||
[ "$(uci_get apinger $INTERFACE)" == "interface" ] || exit 0
|
||||
|
||||
[ "$ACTION" = "ifup" ] && {
|
||||
/etc/init.d/apinger $INTERFACE restart
|
||||
}
|
||||
|
||||
}
|
7
net/apinger/files/user.hotplug
Normal file
7
net/apinger/files/user.hotplug
Normal file
|
@ -0,0 +1,7 @@
|
|||
#!/bin/sh
|
||||
|
||||
[ -e /etc/apinger.user ] && {
|
||||
sh /etc/apinger.user
|
||||
}
|
||||
|
||||
exit 0
|
34
net/apinger/patches/030-apinger-no_exit.patch
Normal file
34
net/apinger/patches/030-apinger-no_exit.patch
Normal file
|
@ -0,0 +1,34 @@
|
|||
--- a/src/apinger.c
|
||||
+++ b/src/apinger.c
|
||||
@@ -786,7 +786,6 @@ struct alarm_cfg *a;
|
||||
time_t tm;
|
||||
int i,qp,really_lost;
|
||||
char *buf1,*buf2;
|
||||
-int err=0;
|
||||
|
||||
if (config->status_file==NULL) return;
|
||||
|
||||
@@ -849,12 +848,10 @@ int err=0;
|
||||
}
|
||||
}
|
||||
buf2[i]=0;
|
||||
- fprintf(f,"Received packets buffer: %s %s\n",buf2,buf1);
|
||||
if (t->recently_lost!=really_lost){
|
||||
- fprintf(f," lost packet count mismatch (%i!=%i)!\n",t->recently_lost,really_lost);
|
||||
- logit("%s: Lost packet count mismatch (%i!=%i)!",t->name,t->recently_lost,really_lost);
|
||||
- logit("%s: Received packets buffer: %s %s\n",t->name,buf2,buf1);
|
||||
- err=1;
|
||||
+ logit("Target \"%s\": Lost packet count mismatch (%i(recently_lost) != %i(really_lost))!",t->name,t->recently_lost,really_lost);
|
||||
+ logit("Target \"%s\": Received packets buffer: %s %s\n",t->name,buf2,buf1);
|
||||
+ t->recently_lost = really_lost = 0;
|
||||
}
|
||||
free(buf1);
|
||||
free(buf2);
|
||||
@@ -862,7 +859,6 @@ int err=0;
|
||||
fprintf(f,"\n");
|
||||
}
|
||||
fclose(f);
|
||||
- if (err) abort();
|
||||
}
|
||||
|
||||
#ifdef FORKED_RECEIVER
|
564
net/apinger/patches/040-srcip.patch
Normal file
564
net/apinger/patches/040-srcip.patch
Normal file
|
@ -0,0 +1,564 @@
|
|||
--- a/src/apinger.c
|
||||
+++ b/src/apinger.c
|
||||
@@ -161,6 +161,9 @@ time_t tim;
|
||||
case 't':
|
||||
values[n]=t->name;
|
||||
break;
|
||||
+ case 'i':
|
||||
+ values[n]=t->config->srcip;
|
||||
+ break;
|
||||
case 'T':
|
||||
values[n]=t->description;
|
||||
break;
|
||||
@@ -276,6 +279,7 @@ time_t tm;
|
||||
else
|
||||
fprintf(f,"alarm canceled: %s\n",a->name);
|
||||
fprintf(f,"Target: %s\n",t->name);
|
||||
+ fprintf(f,"Source: %s\n",t->config->srcip);
|
||||
fprintf(f,"Description: %s\n",t->description);
|
||||
fprintf(f,"Probes sent: %i\n",t->last_sent+1);
|
||||
fprintf(f,"Replies received: %i\n",t->received);
|
||||
@@ -645,7 +649,7 @@ void configure_targets(void){
|
||||
struct target *t,*pt,*nt;
|
||||
struct target_cfg *tc;
|
||||
struct active_alarm_list *al,*nal;
|
||||
-union addr addr;
|
||||
+union addr addr, srcaddr;
|
||||
int r;
|
||||
int l;
|
||||
|
||||
@@ -665,6 +669,8 @@ int l;
|
||||
nal=al->next;
|
||||
free(al);
|
||||
}
|
||||
+ if (t->socket)
|
||||
+ close(t->socket);
|
||||
free(t->queue);
|
||||
free(t->rbuf);
|
||||
free(t->name);
|
||||
@@ -681,20 +687,16 @@ int l;
|
||||
break;
|
||||
if (t==NULL) { /* new target */
|
||||
memset(&addr,0,sizeof(addr));
|
||||
+ logit("Checking target IP %s", tc->srcip);
|
||||
r=inet_pton(AF_INET,tc->name,&addr.addr4.sin_addr);
|
||||
if (r){
|
||||
- if (icmp_sock<0){
|
||||
- logit("Sorry, IPv4 is not available\n");
|
||||
- logit("Ignoring target %s\n",tc->name);
|
||||
- continue;
|
||||
- }
|
||||
addr.addr.sa_family=AF_INET;
|
||||
}else{
|
||||
#ifdef HAVE_IPV6
|
||||
r=inet_pton(AF_INET6,tc->name,&addr.addr6.sin6_addr);
|
||||
if (r==0){
|
||||
#endif
|
||||
- logit("Bad host address: %s\n",tc->name);
|
||||
+ logit("Bad target IP address: %s\n",tc->name);
|
||||
logit("Ignoring target %s\n",tc->name);
|
||||
continue;
|
||||
#ifdef HAVE_IPV6
|
||||
@@ -707,12 +709,38 @@ int l;
|
||||
addr.addr.sa_family=AF_INET6;
|
||||
#endif
|
||||
}
|
||||
+ memset(&srcaddr,0,sizeof(srcaddr));
|
||||
+ logit("Checking source IP %s", tc->srcip);
|
||||
+ r=inet_pton(AF_INET,tc->srcip,&srcaddr.addr4.sin_addr);
|
||||
+ if (r){
|
||||
+ srcaddr.addr.sa_family=AF_INET;
|
||||
+ }else{
|
||||
+#ifdef HAVE_IPV6
|
||||
+ r=inet_pton(AF_INET6,tc->srcip,&srcaddr.addr6.sin6_addr);
|
||||
+ if (r==0){
|
||||
+#endif
|
||||
+ logit("Bad source IP address %s for target %s\n", tc->srcip, tc->name);
|
||||
+ logit("Ignoring target %s\n",tc->name);
|
||||
+ continue;
|
||||
+#ifdef HAVE_IPV6
|
||||
+ }
|
||||
+ if (icmp6_sock<0){
|
||||
+ logit("Sorry, IPv6 is not available\n");
|
||||
+ logit("Ignoring target %s\n",tc->name);
|
||||
+ continue;
|
||||
+ }
|
||||
+ srcaddr.addr.sa_family=AF_INET6;
|
||||
+#endif
|
||||
+ }
|
||||
t=NEW(struct target,1);
|
||||
memset(t,0,sizeof(struct target));
|
||||
t->name=strdup(tc->name);
|
||||
t->description=strdup(tc->description);
|
||||
t->addr=addr;
|
||||
+ t->ifaddr=srcaddr;
|
||||
t->next=targets;
|
||||
+ if(t->addr.addr.sa_family==AF_INET) make_icmp_socket(t);
|
||||
+ if(t->addr.addr.sa_family==AF_INET6) make_icmp6_socket(t);
|
||||
targets=t;
|
||||
}
|
||||
t->config=tc;
|
||||
@@ -752,6 +780,8 @@ struct active_alarm_list *al,*nal;
|
||||
nal=al->next;
|
||||
free(al);
|
||||
}
|
||||
+ if (t->socket)
|
||||
+ close(t->socket);
|
||||
free(t->queue);
|
||||
free(t->rbuf);
|
||||
free(t->name);
|
||||
@@ -799,6 +829,7 @@ char *buf1,*buf2;
|
||||
fprintf(f,"%s\n",ctime(&tm));
|
||||
for(t=targets;t;t=t->next){
|
||||
fprintf(f,"Target: %s\n",t->name);
|
||||
+ fprintf(f,"Source: %s\n",t->config->srcip);
|
||||
fprintf(f,"Description: %s\n",t->description);
|
||||
fprintf(f,"Last reply received: #%i %s",t->last_received,
|
||||
ctime(&t->last_received_tv.tv_sec));
|
||||
@@ -909,7 +940,7 @@ int i;
|
||||
void main_loop(void){
|
||||
struct target *t;
|
||||
struct timeval cur_time,next_status={0,0},tv,next_report={0,0},next_rrd_update={0,0};
|
||||
-struct pollfd pfd[2];
|
||||
+struct pollfd pfd[1024];
|
||||
int timeout;
|
||||
int npfd=0;
|
||||
int i;
|
||||
@@ -946,18 +977,8 @@ struct piped_info pi;
|
||||
pfd[npfd].events=POLLIN|POLLERR|POLLHUP|POLLNVAL;
|
||||
pfd[npfd].revents=0;
|
||||
pfd[npfd++].fd=recv_pipe[0];
|
||||
-#else
|
||||
- if (icmp_sock){
|
||||
- pfd[npfd].events=POLLIN|POLLERR|POLLHUP|POLLNVAL;
|
||||
- pfd[npfd].revents=0;
|
||||
- pfd[npfd++].fd=icmp_sock;
|
||||
- }
|
||||
- if (icmp6_sock){
|
||||
- pfd[npfd].events=POLLIN|POLLERR|POLLHUP|POLLNVAL;
|
||||
- pfd[npfd++].fd=icmp6_sock;
|
||||
- pfd[npfd].revents=0;
|
||||
- }
|
||||
#endif
|
||||
+ memset(&pfd, '\0', sizeof pfd);
|
||||
if (config->status_interval){
|
||||
gettimeofday(&cur_time,NULL);
|
||||
tv.tv_sec=config->status_interval/1000;
|
||||
@@ -965,10 +986,16 @@ struct piped_info pi;
|
||||
timeradd(&cur_time,&tv,&next_status);
|
||||
}
|
||||
while(!interrupted_by){
|
||||
+ npfd = 0;
|
||||
gettimeofday(&cur_time,NULL);
|
||||
if ( !timercmp(&next_probe,&cur_time,>) )
|
||||
timerclear(&next_probe);
|
||||
for(t=targets;t;t=t->next){
|
||||
+ if (t->socket){
|
||||
+ pfd[npfd].events=POLLIN|POLLERR|POLLHUP|POLLNVAL;
|
||||
+ pfd[npfd].revents=0;
|
||||
+ pfd[npfd++].fd=t->socket;
|
||||
+ }
|
||||
for(al=t->config->alarms;al;al=nal){
|
||||
a=al->alarm;
|
||||
nal=al->next;
|
||||
@@ -1051,8 +1078,20 @@ struct piped_info pi;
|
||||
analyze_reply(pi.recv_timestamp,pi.icmp_seq,&pi.ti);
|
||||
}
|
||||
#else
|
||||
- if (pfd[i].fd==icmp_sock) recv_icmp();
|
||||
- else if (pfd[i].fd==icmp6_sock) recv_icmp6();
|
||||
+ for(t=targets;t;t=t->next){
|
||||
+ if (t->addr.addr.sa_family==AF_INET) {
|
||||
+ if (t->socket == pfd[i].fd) {
|
||||
+ recv_icmp(t);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ if (t->addr.addr.sa_family==AF_INET6) {
|
||||
+ if (t->socket == pfd[i].fd) {
|
||||
+ recv_icmp6(t);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
#endif
|
||||
pfd[i].revents=0;
|
||||
}
|
||||
--- a/src/apinger.conf
|
||||
+++ b/src/apinger.conf
|
||||
@@ -47,6 +47,7 @@ alarm default {
|
||||
|
||||
## Following "macros" may be used in options below:
|
||||
## %t - target name (address)
|
||||
+ ## %i - source name (address)
|
||||
## %T - target description
|
||||
## %a - alarm name
|
||||
## %A - alarm type ("down"/"loss"/"delay")
|
||||
--- a/src/apinger.h
|
||||
+++ b/src/apinger.h
|
||||
@@ -46,6 +46,8 @@
|
||||
#endif
|
||||
#include "conf.h"
|
||||
|
||||
+#include <ifaddrs.h>
|
||||
+
|
||||
union addr {
|
||||
struct sockaddr addr;
|
||||
struct sockaddr_in addr4;
|
||||
@@ -70,6 +72,7 @@ struct target {
|
||||
char *queue; /*
|
||||
contains info about recently sent packets
|
||||
"1" means it was received */
|
||||
+ int socket;
|
||||
int last_sent; /* sequence number of the last ping sent */
|
||||
int last_received; /* sequence number of the last ping received */
|
||||
struct timeval last_received_tv; /* timestamp of the last ping received */
|
||||
@@ -89,6 +92,7 @@ struct target {
|
||||
struct target_cfg *config;
|
||||
|
||||
struct target *next;
|
||||
+ union addr ifaddr; /* iface address */
|
||||
};
|
||||
|
||||
#define AVG_DELAY_KNOWN(t) (t->upsent >= t->config->avg_delay_samples)
|
||||
@@ -118,16 +122,16 @@ extern char *config_file;
|
||||
|
||||
extern int icmp_sock;
|
||||
extern int icmp6_sock;
|
||||
-extern int ident;
|
||||
+extern uint16_t ident;
|
||||
|
||||
extern struct timeval next_probe;
|
||||
|
||||
-int make_icmp_socket(void);
|
||||
-void recv_icmp(void);
|
||||
+int make_icmp_socket(struct target *t);
|
||||
+void recv_icmp(struct target *t);
|
||||
void send_icmp_probe(struct target *t,int seq);
|
||||
|
||||
-int make_icmp6_socket(void);
|
||||
-void recv_icmp6(void);
|
||||
+int make_icmp6_socket(struct target *t);
|
||||
+void recv_icmp6(struct target *t);
|
||||
void send_icmp6_probe(struct target *t,int seq);
|
||||
|
||||
#ifdef FORKED_RECEIVER
|
||||
--- a/src/cfgparser1.y
|
||||
+++ b/src/cfgparser1.y
|
||||
@@ -96,6 +96,7 @@ struct target_cfg *cur_target;
|
||||
%token DELAY_HIGH
|
||||
|
||||
%token DESCRIPTION
|
||||
+%token SRCIP
|
||||
%token ALARMS
|
||||
%token INTERVAL
|
||||
%token AVG_DELAY_SAMPLES
|
||||
@@ -247,6 +248,8 @@ target: TARGET getdeftarget DEFAULT '{'
|
||||
targetcfg: /* */
|
||||
| DESCRIPTION string
|
||||
{ cur_target->description=$2; }
|
||||
+ | SRCIP string
|
||||
+ { cur_target->srcip = $2; }
|
||||
| ALARMS alarmlist
|
||||
{ cur_target->alarms=$2; }
|
||||
| ALARMS OVERRIDE alarmlist
|
||||
--- a/src/cfgparser2.l
|
||||
+++ b/src/cfgparser2.l
|
||||
@@ -81,6 +81,7 @@ delay { LOC; LOCINC; return DELAY; }
|
||||
delay_high { LOC; LOCINC; return DELAY_HIGH; }
|
||||
delay_low { LOC; LOCINC; return DELAY_LOW; }
|
||||
description { LOC; LOCINC; return DESCRIPTION; }
|
||||
+srcip { LOC; LOCINC; return SRCIP; }
|
||||
down { LOC; LOCINC; return DOWN; }
|
||||
false { LOC; LOCINC; return FALSE; }
|
||||
file { LOC; LOCINC; return FILE_; }
|
||||
--- a/src/conf.c
|
||||
+++ b/src/conf.c
|
||||
@@ -174,6 +174,14 @@ int ret;
|
||||
}
|
||||
}
|
||||
for(t=cur_config.targets;t;t=t->next){
|
||||
+ if (t->name==NULL || strlen(t->name)==0){
|
||||
+ logit("Target name can't be empty.");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ else if (t->srcip==NULL){
|
||||
+ logit("No source IP defined for target \"%s\".", t->name);
|
||||
+ return 1;
|
||||
+ }
|
||||
if (t->description==NULL)
|
||||
t->description=cur_config.target_defaults.description;
|
||||
if (t->interval<=0)
|
||||
--- a/src/conf.h
|
||||
+++ b/src/conf.h
|
||||
@@ -71,6 +71,7 @@ struct alarm_list {
|
||||
struct target_cfg {
|
||||
char *name;
|
||||
char *description;
|
||||
+ char *srcip;
|
||||
int interval;
|
||||
int avg_delay_samples;
|
||||
int avg_loss_delay_samples;
|
||||
--- a/src/icmp6.c
|
||||
+++ b/src/icmp6.c
|
||||
@@ -112,14 +112,14 @@ int ret;
|
||||
memcpy(p+1,&ti,sizeof(ti));
|
||||
size=sizeof(*p)+sizeof(ti);
|
||||
|
||||
- ret=sendto(icmp6_sock,p,size,MSG_DONTWAIT,
|
||||
+ ret=sendto(t->socket,p,size,MSG_DONTWAIT,
|
||||
(struct sockaddr *)&t->addr.addr6,sizeof(t->addr.addr6));
|
||||
if (ret<0){
|
||||
if (config->debug) myperror("sendto");
|
||||
}
|
||||
}
|
||||
|
||||
-void recv_icmp6(void){
|
||||
+void recv_icmp6(struct target *t){
|
||||
int len,icmplen,datalen;
|
||||
char buf[1024];
|
||||
char abuf[100];
|
||||
@@ -133,6 +133,7 @@ char ans_data[4096];
|
||||
struct iovec iov;
|
||||
struct msghdr msg;
|
||||
struct cmsghdr *c;
|
||||
+reloophack6:
|
||||
|
||||
iov.iov_base=buf;
|
||||
iov.iov_len=1000;
|
||||
@@ -142,12 +143,13 @@ struct cmsghdr *c;
|
||||
msg.msg_iovlen=1;
|
||||
msg.msg_control=ans_data;
|
||||
msg.msg_controllen=sizeof(ans_data);
|
||||
- len=recvmsg(icmp6_sock, &msg, MSG_DONTWAIT);
|
||||
+ len=recvmsg(t->socket, &msg, MSG_DONTWAIT);
|
||||
#else
|
||||
socklen_t sl;
|
||||
+reloophack6:
|
||||
|
||||
sl=sizeof(from);
|
||||
- len=recvfrom(icmp6_sock,buf,1024,0,(struct sockaddr *)&from,&sl);
|
||||
+ len=recvfrom(t->socket,buf,1024,0,(struct sockaddr *)&from,&sl);
|
||||
#endif
|
||||
if (len<0){
|
||||
if (errno==EAGAIN) return;
|
||||
@@ -169,7 +171,7 @@ socklen_t sl;
|
||||
#endif
|
||||
if (time_recvp==NULL){
|
||||
#ifdef SIOCGSTAMP
|
||||
- if (!ioctl(icmp6_sock, SIOCGSTAMP, &time_recv)){
|
||||
+ if (!ioctl(t->socket, SIOCGSTAMP, &time_recv)){
|
||||
debug("Got timestamp from ioctl()");
|
||||
}else
|
||||
#endif
|
||||
@@ -182,8 +184,11 @@ socklen_t sl;
|
||||
icmplen=len;
|
||||
icmp=(struct icmp6_hdr *)buf;
|
||||
if (icmp->icmp6_type != ICMP6_ECHO_REPLY) return;
|
||||
- if (icmp->icmp6_id != ident) return;
|
||||
-
|
||||
+ if (icmp->icmp6_id != ident){
|
||||
+ debug("Alien echo-reply received from xxx. Expected %i, received %i", ident, icmp->icmp6_id);
|
||||
+ goto reloophack6;
|
||||
+ return;
|
||||
+ }
|
||||
name=inet_ntop(AF_INET6,&from.sin6_addr,abuf,100);
|
||||
debug("Ping reply from %s",name);
|
||||
datalen=icmplen-sizeof(*icmp);
|
||||
@@ -199,33 +204,36 @@ socklen_t sl;
|
||||
}
|
||||
|
||||
|
||||
-int make_icmp6_socket(void){
|
||||
+int make_icmp6_socket(struct target *t){
|
||||
int opt;
|
||||
|
||||
- icmp6_sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
|
||||
- if (icmp6_sock<0)
|
||||
+ t->socket = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
|
||||
+ if (t->socket <0)
|
||||
myperror("socket");
|
||||
else {
|
||||
opt=2;
|
||||
#if defined(SOL_RAW) && defined(IPV6_CHECKSUM)
|
||||
- if (setsockopt(icmp6_sock, SOL_RAW, IPV6_CHECKSUM, &opt, sizeof(int)))
|
||||
+ if (setsockopt(t->socket, SOL_RAW, IPV6_CHECKSUM, &opt, sizeof(int)))
|
||||
myperror("setsockopt(IPV6_CHECKSUM)");
|
||||
#endif
|
||||
#ifdef SO_TIMESTAMP
|
||||
opt=1;
|
||||
- if (setsockopt(icmp6_sock, SOL_SOCKET, SO_TIMESTAMP, &opt, sizeof(opt)))
|
||||
+ if (setsockopt(t->socket, SOL_SOCKET, SO_TIMESTAMP, &opt, sizeof(opt)))
|
||||
myperror("setsockopt(SO_TIMESTAMP)");
|
||||
#endif
|
||||
/*install_filter6();*/
|
||||
}
|
||||
- return icmp6_sock;
|
||||
+ if (bind(t->socket, (struct sockaddr *)&t->ifaddr.addr6, sizeof(t->ifaddr.addr6)) < 0)
|
||||
+ myperror("bind socket");
|
||||
+
|
||||
+ return t->socket;
|
||||
}
|
||||
|
||||
#else /*HAVE_IPV6*/
|
||||
#include "apinger.h"
|
||||
|
||||
-int make_icmp6_socket(void){ return -1; }
|
||||
-void recv_icmp6(void){}
|
||||
+int make_icmp6_socket(struct target *t){ return -1; }
|
||||
+void recv_icmp6(struct target *t){}
|
||||
void send_icmp6_probe(struct target *t,int seq){}
|
||||
|
||||
#endif /*HAVE_IPV6*/
|
||||
--- a/src/icmp.c
|
||||
+++ b/src/icmp.c
|
||||
@@ -150,14 +150,14 @@ int ret;
|
||||
size=sizeof(*p)+sizeof(ti);
|
||||
|
||||
p->icmp_cksum = in_cksum((u_short *)p,size,0);
|
||||
- ret=sendto(icmp_sock,p,size,MSG_DONTWAIT,
|
||||
+ ret=sendto(t->socket,p,size,MSG_DONTWAIT,
|
||||
(struct sockaddr *)&t->addr.addr4,sizeof(t->addr.addr4));
|
||||
if (ret<0){
|
||||
if (config->debug) myperror("sendto");
|
||||
}
|
||||
}
|
||||
|
||||
-void recv_icmp(void){
|
||||
+void recv_icmp(struct target *t){
|
||||
int len,hlen,icmplen,datalen;
|
||||
char buf[1024];
|
||||
struct sockaddr_in from;
|
||||
@@ -170,6 +170,7 @@ char ans_data[4096];
|
||||
struct iovec iov;
|
||||
struct msghdr msg;
|
||||
struct cmsghdr *c;
|
||||
+reloophack:
|
||||
|
||||
iov.iov_base=buf;
|
||||
iov.iov_len=1000;
|
||||
@@ -179,12 +180,13 @@ struct cmsghdr *c;
|
||||
msg.msg_iovlen=1;
|
||||
msg.msg_control=ans_data;
|
||||
msg.msg_controllen=sizeof(ans_data);
|
||||
- len=recvmsg(icmp_sock, &msg, MSG_DONTWAIT);
|
||||
+ len=recvmsg(t->socket, &msg, MSG_DONTWAIT);
|
||||
#else
|
||||
socklen_t sl;
|
||||
+reloophack:
|
||||
|
||||
sl=sizeof(from);
|
||||
- len=recvfrom(icmp_sock,buf,1024,MSG_DONTWAIT,(struct sockaddr *)&from,&sl);
|
||||
+ len=recvfrom(t->socket,buf,1024,MSG_DONTWAIT,(struct sockaddr *)&from,&sl);
|
||||
#endif
|
||||
if (len<0){
|
||||
if (errno==EAGAIN) return;
|
||||
@@ -196,7 +198,7 @@ socklen_t sl;
|
||||
debug("checking CMSG...");
|
||||
for (c = CMSG_FIRSTHDR(&msg); c; c = CMSG_NXTHDR(&msg, c)) {
|
||||
debug("CMSG level: %i type: %i",c->cmsg_level,c->cmsg_type);
|
||||
- if (c->cmsg_level != SOL_SOCKET || c->cmsg_type != SO_TIMESTAMP)
|
||||
+ if (c->cmsg_level != SOL_SOCKET || c->cmsg_type != SCM_TIMESTAMP)
|
||||
continue;
|
||||
if (c->cmsg_len < CMSG_LEN(sizeof(struct timeval)))
|
||||
continue;
|
||||
@@ -206,7 +208,7 @@ socklen_t sl;
|
||||
#endif
|
||||
if (time_recvp==NULL){
|
||||
#ifdef SIOCGSTAMP
|
||||
- if (!ioctl(icmp_sock, SIOCGSTAMP, &time_recv)){
|
||||
+ if (!ioctl(t->socket, SIOCGSTAMP, &time_recv)){
|
||||
debug("Got timestampt from ioctl()");
|
||||
}else
|
||||
#endif
|
||||
@@ -226,7 +228,8 @@ socklen_t sl;
|
||||
return;
|
||||
}
|
||||
if (icmp->icmp_id != ident){
|
||||
- debug("Alien echo-reply received");
|
||||
+ debug("Alien echo-reply received from %s. Expected %i, received %i",inet_ntoa(from.sin_addr), ident, icmp->icmp_id);
|
||||
+ goto reloophack;
|
||||
return;
|
||||
}
|
||||
debug("Ping reply from %s",inet_ntoa(from.sin_addr));
|
||||
@@ -242,19 +245,23 @@ socklen_t sl;
|
||||
#endif
|
||||
}
|
||||
|
||||
-int make_icmp_socket(void){
|
||||
+int make_icmp_socket(struct target *t){
|
||||
int on;
|
||||
|
||||
- icmp_sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
|
||||
- if (icmp_sock<0)
|
||||
+ t->socket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
|
||||
+ if (t->socket < 0)
|
||||
myperror("socket");
|
||||
#ifdef SO_TIMESTAMP
|
||||
else{
|
||||
on=1;
|
||||
- if (setsockopt(icmp_sock, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on)))
|
||||
+ if (setsockopt(t->socket, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on)))
|
||||
myperror("setsockopt(SO_TIMESTAMP)");
|
||||
}
|
||||
#endif
|
||||
- return icmp_sock;
|
||||
+
|
||||
+ if (bind(t->socket, (struct sockaddr *)&t->ifaddr.addr4, sizeof(t->ifaddr.addr4)) < 0)
|
||||
+ myperror("bind socket");
|
||||
+
|
||||
+ return t->socket;
|
||||
}
|
||||
|
||||
--- a/src/main.c
|
||||
+++ b/src/main.c
|
||||
@@ -71,6 +71,7 @@ struct config default_config={
|
||||
{ /* target defaults */
|
||||
"default", /* name */
|
||||
"", /* description */
|
||||
+ "", /* interface */
|
||||
1000, /* interval */
|
||||
20, /* avg_delay_samples */
|
||||
5, /* avg_loss_delay_samples */
|
||||
@@ -95,7 +96,7 @@ char *config_file=CONFIG;
|
||||
|
||||
int icmp_sock;
|
||||
int icmp6_sock;
|
||||
-int ident;
|
||||
+uint16_t ident;
|
||||
|
||||
struct timeval next_probe={0,0};
|
||||
|
||||
@@ -216,12 +217,6 @@ char *graph_location="/apinger/";
|
||||
}
|
||||
}
|
||||
|
||||
- make_icmp_socket();
|
||||
- make_icmp6_socket();
|
||||
- if (icmp6_sock<0 && icmp_sock<0){
|
||||
- return 1;
|
||||
- }
|
||||
-
|
||||
pw=getpwnam(config->user);
|
||||
if (!pw) {
|
||||
debug("getpwnam(\"%s\") failed.",config->user);
|
||||
@@ -276,7 +271,7 @@ char *graph_location="/apinger/";
|
||||
return 1;
|
||||
}
|
||||
|
||||
- ident=getpid();
|
||||
+ ident=getpid() & 0xFFFF;
|
||||
signal(SIGTERM,signal_handler);
|
||||
signal(SIGINT,signal_handler);
|
||||
signal(SIGHUP,signal_handler);
|
||||
@@ -285,9 +280,8 @@ char *graph_location="/apinger/";
|
||||
#ifdef FORKED_RECEIVER
|
||||
signal(SIGCHLD,sigchld_handler);
|
||||
#endif
|
||||
+ logit("Starting Alarm Pinger, apinger(%i)", ident);
|
||||
main_loop();
|
||||
- if (icmp_sock>=0) close(icmp_sock);
|
||||
- if (icmp6_sock>=0) close(icmp6_sock);
|
||||
|
||||
logit("Exiting on signal %i.",interrupted_by);
|
||||
|
126
net/apinger/patches/050-statusformat.patch
Normal file
126
net/apinger/patches/050-statusformat.patch
Normal file
|
@ -0,0 +1,126 @@
|
|||
--- a/src/apinger.c
|
||||
+++ b/src/apinger.c
|
||||
@@ -826,26 +826,49 @@ char *buf1,*buf2;
|
||||
return;
|
||||
}
|
||||
tm=time(NULL);
|
||||
- fprintf(f,"%s\n",ctime(&tm));
|
||||
+ if(!config->status_format) fprintf(f,"%s\n",ctime(&tm));
|
||||
for(t=targets;t;t=t->next){
|
||||
- fprintf(f,"Target: %s\n",t->name);
|
||||
- fprintf(f,"Source: %s\n",t->config->srcip);
|
||||
- fprintf(f,"Description: %s\n",t->description);
|
||||
- fprintf(f,"Last reply received: #%i %s",t->last_received,
|
||||
- ctime(&t->last_received_tv.tv_sec));
|
||||
- fprintf(f,"Average delay: %0.3fms\n",AVG_DELAY(t));
|
||||
+ if(config->status_format){
|
||||
+ fprintf(f,"%s|%s|%s|%i|%i|%u|",t->name, t->config->srcip, t->description, t->last_sent+1,
|
||||
+ t->received, t->last_received_tv.tv_sec);
|
||||
+ fprintf(f,"%0.3fms|", AVG_DELAY(t));
|
||||
+ }
|
||||
+ else{
|
||||
+ fprintf(f,"Target: %s\n",t->name);
|
||||
+ fprintf(f,"Source: %s\n",t->config->srcip);
|
||||
+ fprintf(f,"Description: %s\n",t->description);
|
||||
+ fprintf(f,"Last reply received: #%i %s",t->last_received,
|
||||
+ ctime(&t->last_received_tv.tv_sec));
|
||||
+ fprintf(f,"Average delay: %0.3fms\n",AVG_DELAY(t));
|
||||
+ }
|
||||
if (AVG_LOSS_KNOWN(t)){
|
||||
- fprintf(f,"Average packet loss: %0.1f%%\n",AVG_LOSS(t));
|
||||
+ if(config->status_format){
|
||||
+ fprintf(f,"%0.1f%%",AVG_LOSS(t));
|
||||
+ }
|
||||
+ else{
|
||||
+ fprintf(f,"Average packet loss: %0.1f%%\n",AVG_LOSS(t));
|
||||
+ }
|
||||
+ }
|
||||
+ if(config->status_format){
|
||||
+ fprintf(f, "|");
|
||||
+ }
|
||||
+ else{
|
||||
+ fprintf(f,"Active alarms: ");
|
||||
}
|
||||
- fprintf(f,"Active alarms:");
|
||||
if (t->active_alarms){
|
||||
for(al=t->active_alarms;al;al=al->next){
|
||||
a=al->alarm;
|
||||
- fprintf(f," \"%s\"",a->name);
|
||||
+ if(config->status_format){
|
||||
+ fprintf(f,"%s",a->name);
|
||||
+ }
|
||||
+ else{
|
||||
+ fprintf(f," \"%s\"",a->name);
|
||||
+ }
|
||||
}
|
||||
- fprintf(f,"\n");
|
||||
+ if(!config->status_format) fprintf(f,"\n");
|
||||
}
|
||||
- else fprintf(f," None\n");
|
||||
+ else fprintf(f,"none");
|
||||
+ if(!config->status_format) fprintf(f,"\n");
|
||||
|
||||
buf1=NEW(char,t->config->avg_loss_delay_samples+1);
|
||||
buf2=NEW(char,t->config->avg_loss_samples+1);
|
||||
--- a/src/apinger.conf
|
||||
+++ b/src/apinger.conf
|
||||
@@ -29,6 +29,10 @@ group "nogroup"
|
||||
# ## Interval between file updates
|
||||
# ## when 0 or not set, file is written only when SIGUSR1 is received
|
||||
# interval 5m
|
||||
+#
|
||||
+# ## Create status file in script parseable format (on) or human
|
||||
+# ## readable format (off)
|
||||
+# scriptformat off
|
||||
#}
|
||||
|
||||
########################################
|
||||
--- a/src/cfgparser1.y
|
||||
+++ b/src/cfgparser1.y
|
||||
@@ -104,6 +104,7 @@ struct target_cfg *cur_target;
|
||||
%token AVG_LOSS_DELAY_SAMPLES
|
||||
|
||||
%token FILE_
|
||||
+%token SCRIPTFORMAT
|
||||
|
||||
%token ERROR
|
||||
|
||||
@@ -282,6 +283,8 @@ statuscfg: /* */
|
||||
{ cur_config.status_interval=$2; }
|
||||
| INTERVAL TIME
|
||||
{ cur_config.status_interval=$2; }
|
||||
+ | SCRIPTFORMAT boolean
|
||||
+ { cur_config.status_format=$2; }
|
||||
| statuscfg separator statuscfg
|
||||
;
|
||||
|
||||
--- a/src/cfgparser2.l
|
||||
+++ b/src/cfgparser2.l
|
||||
@@ -85,6 +85,7 @@ srcip { LOC; LOCINC; return SRCIP; }
|
||||
down { LOC; LOCINC; return DOWN; }
|
||||
false { LOC; LOCINC; return FALSE; }
|
||||
file { LOC; LOCINC; return FILE_; }
|
||||
+scriptformat { LOC; LOCINC; return SCRIPTFORMAT; }
|
||||
group { LOC; LOCINC; return GROUP; }
|
||||
interval { LOC; LOCINC; return INTERVAL; }
|
||||
loss { LOC; LOCINC; return LOSS; }
|
||||
--- a/src/conf.h
|
||||
+++ b/src/conf.h
|
||||
@@ -97,6 +97,7 @@ struct config {
|
||||
char *pid_file;
|
||||
char *status_file;
|
||||
int status_interval;
|
||||
+ int status_format;
|
||||
char *timestamp_format;
|
||||
};
|
||||
|
||||
--- a/src/main.c
|
||||
+++ b/src/main.c
|
||||
@@ -88,6 +88,7 @@ struct config default_config={
|
||||
"/var/run/apinger.pid", /* pid file */
|
||||
NULL, /* status file */
|
||||
0, /* status interval */
|
||||
+ 0, /* status format */
|
||||
"%b %d %H:%M:%S" /* timestamp format */
|
||||
};
|
||||
|
Loading…
Reference in a new issue