]> git.ipfire.org Git - ipfire-2.x.git/commitdiff
WIO: first addon release v1.3.1
authorStephan Feddersen <sfeddersen@ipfire.org>
Fri, 14 Jul 2017 10:26:55 +0000 (12:26 +0200)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 15 Aug 2017 10:45:46 +0000 (11:45 +0100)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
48 files changed:
config/rootfiles/packages/wio [new file with mode: 0644]
lfs/wio [new file with mode: 0644]
make.sh
src/misc-progs/Makefile
src/misc-progs/list.h [new file with mode: 0644]
src/misc-progs/wiohelper.c [new file with mode: 0644]
src/misc-progs/wioscan.c [new file with mode: 0644]
src/paks/wio/install.sh [new file with mode: 0644]
src/paks/wio/uninstall.sh [new file with mode: 0644]
src/paks/wio/update.sh [new file with mode: 0644]
src/wio/EX-wio.menu [new file with mode: 0644]
src/wio/config/backup/includes/wio [new file with mode: 0644]
src/wio/images/add.png [new file with mode: 0644]
src/wio/images/back.png [new file with mode: 0644]
src/wio/images/blue.png [new file with mode: 0644]
src/wio/images/fqdn.png [new file with mode: 0644]
src/wio/images/graph.png [new file with mode: 0644]
src/wio/images/green.png [new file with mode: 0644]
src/wio/images/http.png [new file with mode: 0644]
src/wio/images/https.png [new file with mode: 0644]
src/wio/images/ip.png [new file with mode: 0644]
src/wio/images/mailgreenoff.png [new file with mode: 0644]
src/wio/images/mailgreenon.png [new file with mode: 0644]
src/wio/images/mailredoff.png [new file with mode: 0644]
src/wio/images/mailredon.png [new file with mode: 0644]
src/wio/images/no_graph.png [new file with mode: 0644]
src/wio/images/none.png [new file with mode: 0644]
src/wio/images/orange.png [new file with mode: 0644]
src/wio/images/ovpn.png [new file with mode: 0644]
src/wio/images/ovpnn2n.png [new file with mode: 0644]
src/wio/images/ovpnrw.png [new file with mode: 0644]
src/wio/images/red.png [new file with mode: 0644]
src/wio/images/refresh.png [new file with mode: 0644]
src/wio/images/vpn.png [new file with mode: 0644]
src/wio/images/vpnn2n.png [new file with mode: 0644]
src/wio/images/vpnrw.png [new file with mode: 0644]
src/wio/images/white.png [new file with mode: 0644]
src/wio/lang/wio.de.pl [new file with mode: 0644]
src/wio/lang/wio.en.pl [new file with mode: 0644]
src/wio/main/wio.conf [new file with mode: 0644]
src/wio/main/wio.pl [new file with mode: 0644]
src/wio/main/wiovpn.pl [new file with mode: 0644]
src/wio/wio [new file with mode: 0644]
src/wio/wio-graphs.pl [new file with mode: 0644]
src/wio/wio-lib.pl [new file with mode: 0644]
src/wio/wio.cgi [new file with mode: 0644]
src/wio/wiographs.cgi [new file with mode: 0644]
src/wio/wioips [new file with mode: 0644]

diff --git a/config/rootfiles/packages/wio b/config/rootfiles/packages/wio
new file mode 100644 (file)
index 0000000..f238662
--- /dev/null
@@ -0,0 +1,45 @@
+srv/web/ipfire/cgi-bin/wio.cgi
+srv/web/ipfire/cgi-bin/wiographs.cgi
+etc/fcron.minutely/wio
+var/ipfire/wio
+var/ipfire/wio/wio.conf
+var/ipfire/wio/wio.pl
+var/ipfire/wio/wiovpn.pl
+usr/lib/wio
+usr/lib/wio/wio-lib.pl
+usr/lib/wio/wio-graphs.pl
+usr/local/bin/wiohelper
+usr/local/bin/wioscan
+var/log/wio
+var/log/wio/wioips
+var/log/rrd/wio
+var/ipfire/addon-lang/wio.de.pl
+var/ipfire/addon-lang/wio.en.pl
+var/ipfire/menu.d/EX-wio.menu
+srv/web/ipfire/html/images/wio
+srv/web/ipfire/html/images/wio/add.png
+srv/web/ipfire/html/images/wio/back.png
+srv/web/ipfire/html/images/wio/blue.png
+srv/web/ipfire/html/images/wio/fqdn.png
+srv/web/ipfire/html/images/wio/graph.png
+srv/web/ipfire/html/images/wio/green.png
+srv/web/ipfire/html/images/wio/http.png
+srv/web/ipfire/html/images/wio/https.png
+srv/web/ipfire/html/images/wio/ip.png
+srv/web/ipfire/html/images/wio/mailgreenoff.png
+srv/web/ipfire/html/images/wio/mailgreenon.png
+srv/web/ipfire/html/images/wio/mailredoff.png
+srv/web/ipfire/html/images/wio/mailredon.png
+srv/web/ipfire/html/images/wio/no_graph.png
+srv/web/ipfire/html/images/wio/none.png
+srv/web/ipfire/html/images/wio/orange.png
+srv/web/ipfire/html/images/wio/ovpn.png
+srv/web/ipfire/html/images/wio/ovpnn2n.png
+srv/web/ipfire/html/images/wio/ovpnrw.png
+srv/web/ipfire/html/images/wio/red.png
+srv/web/ipfire/html/images/wio/refresh.png
+srv/web/ipfire/html/images/wio/vpnn2n.png
+srv/web/ipfire/html/images/wio/vpn.png
+srv/web/ipfire/html/images/wio/vpnrw.png
+srv/web/ipfire/html/images/wio/white.png
+var/ipfire/backup/addons/includes/wio
diff --git a/lfs/wio b/lfs/wio
new file mode 100644 (file)
index 0000000..a3c00d9
--- /dev/null
+++ b/lfs/wio
@@ -0,0 +1,65 @@
+###############################################################################
+# IPFire.org    - An Open Source Firewall Solution                            #
+# Copyright (C) - IPFire Development Team <info@ipfire.org>                   #
+###############################################################################
+
+###############################################################################
+# Definitions
+###############################################################################
+
+include Config
+
+VER        = 1.3.1
+
+THISAPP    = wio-$(VER)
+DIR_APP    = $(DIR_SRC)/$(THISAPP)
+TARGET     = $(DIR_INFO)/$(THISAPP)
+PROG       = wio
+PAK_VER    = 1
+
+###############################################################################
+# Top-level Rules
+###############################################################################
+
+install : $(TARGET)
+
+check : 
+
+download :
+
+md5 : 
+
+dist: 
+       @$(PAK)
+
+###############################################################################
+# Installation Details
+###############################################################################
+
+$(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
+       @$(PREBUILD)
+       @rm -rf $(DIR_APP) && mkdir $(DIR_APP) && cp -R $(DIR_SRC)/src/wio/ $(DIR_APP)
+       cd $(DIR_APP)
+       mkdir -p /usr/lib/wio
+       mkdir -p /var/log/wio
+       mkdir -p /var/log/rrd/wio
+       mkdir -p /srv/web/ipfire/html/images/wio
+       mkdir -p /var/ipfire/wio
+
+       install -v -m 755 $(DIR_APP)/wio/wio.cgi /srv/web/ipfire/cgi-bin/
+       install -v -m 755 $(DIR_APP)/wio/wiographs.cgi /srv/web/ipfire/cgi-bin/
+       install -v -m 755 $(DIR_APP)/wio/wio /etc/fcron.minutely/
+       install -v -m 644 $(DIR_APP)/wio/main/wio.conf /var/ipfire/wio/
+       install -v -m 754 $(DIR_APP)/wio/main/wio.pl /var/ipfire/wio/
+       install -v -m 754 $(DIR_APP)/wio/main/wiovpn.pl /var/ipfire/wio/
+       install -v -m 644 $(DIR_APP)/wio/wio-lib.pl /usr/lib/wio/
+       install -v -m 644 $(DIR_APP)/wio/wio-graphs.pl /usr/lib/wio/
+       install -v -m 644 $(DIR_APP)/wio/wioips /var/log/wio/
+       install -v -m 644 $(DIR_APP)/wio/images/* /srv/web/ipfire/html/images/wio/
+       install -v -m 655 $(DIR_APP)/wio/lang/wio.de.pl /var/ipfire/addon-lang/
+       install -v -m 655 $(DIR_APP)/wio/lang/wio.en.pl /var/ipfire/addon-lang/
+       install -v -m 655 $(DIR_APP)/wio/EX-wio.menu /var/ipfire/menu.d/
+       install -v -m 644 $(DIR_APP)/wio/config/backup/includes/wio /var/ipfire/backup/addons/includes/wio
+
+       @rm -rf $(DIR_APP)
+       @$(POSTBUILD)
diff --git a/make.sh b/make.sh
index f2a8b2baead33940ef5c5e4f5e33fe73191efea7..f48c92f23e0a6648bc525c2e56ecd9adda32331c 100755 (executable)
--- a/make.sh
+++ b/make.sh
@@ -885,6 +885,7 @@ buildipfire() {
   lfsmake2 perl-common-sense
   lfsmake2 perl-inotify2
   lfsmake2 perl-Net-IP
+  lfsmake2 wio
 }
 
 buildinstaller() {
index 08a4e37d9c12d61be5d4c4be3e34222585fb257d..7cc70b48211c66002d06934daf11a4f09218074f 100644 (file)
@@ -26,7 +26,7 @@ PROGS = iowrap
 SUID_PROGS = squidctrl sshctrl ipfirereboot \
        ipsecctrl timectrl dhcpctrl snortctrl \
        applejuicectrl rebuildhosts backupctrl collectdctrl \
-       logwatch openvpnctrl firewallctrl \
+       logwatch wioscan wiohelper openvpnctrl firewallctrl \
        wirelessctrl getipstat qosctrl launch-ether-wake \
        redctrl syslogdctrl extrahdctrl sambactrl upnpctrl \
        smartctrl clamavctrl addonctrl pakfire mpfirectrl wlanapctrl \
diff --git a/src/misc-progs/list.h b/src/misc-progs/list.h
new file mode 100644 (file)
index 0000000..19bd21e
--- /dev/null
@@ -0,0 +1,129 @@
+/* list.h by Jan Bobrowski. Inspired by list.h from Linux */
+
+#ifndef LIST_H
+#define LIST_H
+
+typedef struct list {
+       struct list *next, *prev;
+} list_t;
+
+static inline void list_link(struct list *a, struct list *b)
+{
+       a->next = b;
+       b->prev = a;
+}
+
+static inline void list_add(struct list *head, struct list *item)
+{
+       struct list *first = head->next;
+       list_link(head, item);
+       list_link(item, first);
+}
+
+static inline void list_add_end(struct list *head, struct list *item)
+{
+       struct list *last = head->prev;
+       list_link(item, head);
+       list_link(last, item);
+}
+
+static inline list_t *list_del(struct list *item)
+{
+       struct list *prev = item->prev, *next = item->next;
+       list_link(prev, next);
+       return next;
+}
+
+static inline void list_init(struct list *head)
+{
+       list_link(head, head);
+}
+
+/* delete item from one list and add it to another */
+static inline void list_del_add(list_t *head, list_t *item)
+{
+       list_t *prev = item->prev, *next = item->next;
+       list_link(prev, next);
+       next = head->next;
+       list_link(head, item);
+       list_link(item, next);
+}
+
+/*static inline list_check(list_t *l)
+{
+       list_t *a = l;
+       list_t *b;
+       do {
+               b = a->next;
+               assert(b->prev == a);
+               if(a==l) break;
+               a = b;
+       } while(1);
+}*/
+
+static inline void list_del_add_end(list_t *head, list_t *item)
+{
+       list_t *prev = item->prev, *next = item->next;
+       list_link(prev, next);
+       prev = head->prev;
+       list_link(item, head);
+       item->prev = prev;
+       prev->next = item;
+}
+
+static inline void list_del_init(struct list *item)
+{
+       struct list *prev = item->prev, *next = item->next;
+       list_link(item, item);
+       list_link(prev, next);
+}
+
+static inline void list_join(struct list *a, struct list *b)
+{
+       list_t *ae = a->prev;
+       list_t *be = b->prev;
+       b->prev = ae;
+       a->prev = be;
+       ae->next = b;
+       be->next = a;
+}
+
+static inline int list_empty(struct list *head)
+{
+       return head->next == head;
+}
+
+#define LIST(L) struct list L = {&L, &L}
+
+#define list_entry(L, T, M) ((T*)((char*)(L) - (long)(&((T*)0)->M)))
+#define list_item(L, T, M) ((T*)((char*)(L) - (long)(&((T*)0)->M)))
+
+#define list_first(H, T, M) list_item((H)->next, T, M)
+#define list_last(H, T, M) list_item((H)->prev, T, M)
+#define list_next(O, M) list_item((O)->M.next, typeof(*(O)), M)
+
+/* remove first element and return it */
+static inline struct list *list_get(struct list *head)
+{
+       struct list *item = head->next;
+       struct list *next = item->next;
+       list_link(head, next);
+       return item;
+}
+
+/* remove first element, initialize and return it */
+static inline struct list *list_get_init(struct list *head)
+{
+       struct list *item = head->next;
+       struct list *next = item->next;
+       list_link(item, item);
+       list_link(head, next);
+       return item;
+}
+
+#define list_get_entry(H, T, M) list_item(list_get((H)), T, M)
+#define list_get_init_entry(H, T, M) list_item(list_get_init((H)), T, M)
+#define list_get_item(H, T, M) list_item(list_get((H)), T, M)
+#define list_get_init_item(H, T, M) list_item(list_get_init((H)), T, M)
+
+#endif
diff --git a/src/misc-progs/wiohelper.c b/src/misc-progs/wiohelper.c
new file mode 100644 (file)
index 0000000..0f7fd86
--- /dev/null
@@ -0,0 +1,31 @@
+/* wiohelper - a Who Is Online? Addon helper program
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * This program is distributed under the terms of the GNU General Public
+ * Licence.  See the file COPYING for details.
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 
+ * IPFire.org - A linux based firewall
+ * Copyright (C) 2017 Stephan Feddersen <addons@h-loit.de>
+ *
+ * All Rights Reserved.
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * Simple program intended to be installed setuid(0) that can be used from WIO
+ *
+*/
+
+#include "setuid.h"
+
+int main(void)
+{
+       if (!(initsetuid()))
+               exit(1);
+
+       safe_system("/var/ipfire/wio/wio.pl");
+
+       return 0;
+}
diff --git a/src/misc-progs/wioscan.c b/src/misc-progs/wioscan.c
new file mode 100644 (file)
index 0000000..206456c
--- /dev/null
@@ -0,0 +1,665 @@
+/*
+ *     wioscan
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ */
+
+#define _GNU_SOURCE
+#include <sys/types.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <poll.h>
+#include <errno.h>
+#include <err.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <netpacket/packet.h>
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <netinet/ether.h>
+#include <arpa/inet.h>
+#include <stdint.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#define _STR(S) #S
+#define STR(S) _STR(S)
+
+#define ARP htons(ETHERTYPE_ARP)
+#define IP htons(ETHERTYPE_IP)
+
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+
+#include "list.h"
+#define elemof(T) (sizeof T/sizeof*T)
+#define endof(T) (T+elemof(T))
+#ifndef offsetof
+#define offsetof(T,M) ((int)(long)&((T*)0)->M)
+#endif
+
+#define HWMAX 8
+
+union addr {
+       struct sockaddr sa;
+       struct sockaddr_in in;
+       struct sockaddr_ll ll;
+};
+
+int sock; /* packet socket */
+union addr bcast;
+
+struct opts {
+       unsigned sort:1;
+       unsigned noown:1;
+       unsigned noethn:1;
+       unsigned proui:1;
+       unsigned isrange:1;
+       unsigned passive:1;
+       unsigned nsend;
+       unsigned wait;
+} opts = {nsend:8, wait:250};
+
+void print_oui(int sp, u8 a[6]);
+
+struct he;
+void print_he(struct he *he);
+
+struct hwaddr {
+       u8 len, addr[HWMAX];
+};
+
+static inline hw_eq(struct hwaddr *h, int hl, u8 *ha)
+{
+       return h->len == hl && memcmp(h->addr, ha, hl) == 0;
+}
+
+static inline void hw_set(struct hwaddr *h, int hl, u8 *ha)
+{
+       memcpy(h->addr, ha, (h->len = hl));
+}
+
+struct ifinfo {
+       int index;
+       char *name;
+       u32 ip, net, mask, bcast;
+       u16 hw_type;
+       struct hwaddr hw;
+} ifinfo;
+
+static inline u32 ip_from_sa(struct sockaddr *sa)
+{
+       return ntohl(((struct sockaddr_in*)sa)->sin_addr.s_addr);
+}
+
+/* TABLE */
+
+struct list hashtbl[128];
+struct he {
+       struct list hash;
+       u32 ip;
+       struct hwaddr hw;
+       struct hwaddr from;
+};
+
+static void init_hash() __attribute__((constructor));
+static void init_hash()
+{
+       int i;
+       for(i=0;i<elemof(hashtbl);i++) list_init(&hashtbl[i]);
+}
+
+int he_for(u32 ip, struct he **ret, int alloc)
+{
+       struct list *h, *l;
+       struct he *he;
+       int v = 1;
+       h = &hashtbl[ip & elemof(hashtbl)-1];
+       for(l=h->next; l!=h; l=l->next) {
+               he = list_entry(l, struct he, hash);
+               if(he->ip == ip)
+                       goto ret;
+               if(he->ip > ip)
+                       break;
+       }
+       v = 0;
+       if(alloc) {
+               he = (struct he*)malloc(sizeof *he);
+               he->ip = ip;
+               list_add(l->prev, &he->hash);
+ret:
+               if(ret) *ret = he;
+       }
+       return v;
+}
+
+/* INTERFACE */
+
+static int net;
+
+static void my__ioctl(int i, struct ifreq *r, char *t)
+{
+       if(ioctl(net, i, r) < 0)
+               err(1, "ioctl(%s,%s)", t, r->ifr_name);
+}
+#define my_ioctl(I,R) my__ioctl(I,R,#I)
+
+void fill_ifinfo(char *name)
+{
+       struct ifreq ir;
+       int flags;
+
+       ifinfo.index = if_nametoindex(name);
+       if(!ifinfo.index) errx(1, "No such interface: %s", name);
+       ifinfo.name = name;
+
+       net = socket(PF_INET, SOCK_DGRAM, 0);
+       if(net<0) err(1, "socket(PF_INET)");
+       strcpy(ir.ifr_name, ifinfo.name);
+       my_ioctl(SIOCGIFFLAGS, &ir);
+       flags = ir.ifr_flags;
+       if(flags & IFF_NOARP) errx(1, "%s: ARP not supported.", name);
+       my_ioctl(SIOCGIFADDR, &ir);
+       ifinfo.ip = ip_from_sa(&ir.ifr_addr);
+       if(flags & IFF_POINTOPOINT) {
+               my_ioctl(SIOCGIFDSTADDR, &ir);
+               ifinfo.net = ip_from_sa(&ir.ifr_dstaddr);
+               ifinfo.mask = (u32)~0;
+               ifinfo.bcast = 0; /* none */
+       } else {
+               my_ioctl(SIOCGIFNETMASK, &ir);
+               ifinfo.mask = ip_from_sa(&ir.ifr_netmask);
+               my_ioctl(SIOCGIFBRDADDR, &ir);
+               ifinfo.bcast = ip_from_sa(&ir.ifr_broadaddr);
+               ifinfo.net = ifinfo.ip & ifinfo.mask;
+       }
+       close(net);
+}
+
+static inline char *str_ip(u32 ip)
+{
+       struct in_addr n;
+       n.s_addr = htonl(ip);
+       return inet_ntoa(n);
+}
+
+char *str_hw(u8 *a, int l)
+{
+       static char buf[3*HWMAX];
+       char *d = buf;
+       if(!l) return "*";
+       if(l>HWMAX) l=HWMAX;
+       for(;;) {
+               d += sprintf(d, "%02X", *a++);
+               if(--l <= 0) break;
+               *d++ = ':';
+       }
+       *d = 0;
+       return buf;
+}
+
+static char *str_addr(union addr *addr)
+{
+       switch(addr->sa.sa_family) {
+               case AF_INET: return inet_ntoa(addr->in.sin_addr);
+               case AF_PACKET: return str_hw(addr->ll.sll_addr, addr->ll.sll_halen);
+               default: return "???";
+       }
+}
+
+static inline void setup_socket()
+{
+       union addr addr;
+       socklen_t l;
+
+       sock = socket(PF_PACKET, SOCK_DGRAM, 0);
+       if(sock < 0) err(1, "socket(PF_PACKET)");
+
+       memset(&addr.ll, 0, sizeof addr.ll);
+       addr.sa.sa_family = AF_PACKET;
+       addr.ll.sll_protocol = ARP;
+       addr.ll.sll_ifindex = ifinfo.index;
+
+       if(bind(sock, &addr.sa, sizeof addr.ll)<0)
+               err(1, "bind");
+       l = sizeof addr.ll;
+       if(getsockname(sock, &addr.sa, &l)<0)
+               err(1, "getsockname");
+
+       if(addr.ll.sll_halen > HWMAX)
+               errx(1, "hardware address too long (%d)", addr.ll.sll_halen);
+       ifinfo.hw.len = addr.ll.sll_halen;
+       memcpy(ifinfo.hw.addr, addr.ll.sll_addr, sizeof ifinfo.hw.addr);
+       ifinfo.hw_type = addr.ll.sll_hatype;
+}
+
+/* SCAN */
+
+struct arppkt {
+       u16 hrd, pro;
+       u8 hln, pln;
+       u16 op;
+       u8 a[2*HWMAX+2*4];
+/*     u8 sha[6];
+       u8 sip[4];
+       u8 tha[6];
+       u8 tip[4];*/
+};
+
+static inline u8 *get_sha(struct arppkt *pkt) {return pkt->a;}
+static inline u8 *get_tha(struct arppkt *pkt) {return pkt->a+pkt->hln+4;}
+static inline u32 get_sip(struct arppkt *pkt) {return ntohl(*(u32*)(pkt->a+pkt->hln));}
+static inline u32 get_tip(struct arppkt *pkt) {return ntohl(*(u32*)(pkt->a+2*pkt->hln+4));}
+
+#if 0
+void print_arp(struct arppkt *arp)
+{
+       u8 *p = arp->a;
+       printf("hrd:%04X pro:%04X ", ntohs(arp->hrd), ntohs(arp->pro));
+       printf("hln:%d pln:%d op:%d ", arp->hln, arp->pln, ntohs(arp->op));
+       printf("sha:%s ", str_hw(p, arp->hln)); p+=arp->hln;
+       printf("sip:%s ", str_ip(ntohl(*(u32*)p))); p+=arp->pln;
+       printf("tha:%s ", str_hw(p, arp->hln)); p+=arp->hln;
+       printf("tip:%s\n", str_ip(ntohl(*(u32*)p)));
+}
+#endif
+
+static struct scan {
+       u32 ip, start, end;
+} scan;
+
+#define IN_RANGE(I) ((I) >= scan.start && (I) <= (u32)(scan.end-1))
+
+int sendscan()
+{
+       struct arppkt arp;
+       int ns;
+       u8 *p;
+
+       arp.hrd = htons(ifinfo.hw_type);
+       arp.pro = IP;
+       arp.hln = ifinfo.hw.len;
+       arp.pln = 4;
+       arp.op = htons(1);
+       p = arp.a;
+       memcpy(p, ifinfo.hw.addr, ifinfo.hw.len); p += ifinfo.hw.len;
+       *(u32*)p = htonl(ifinfo.ip); p += 4;
+       memset(p, 0, ifinfo.hw.len); p += ifinfo.hw.len;
+
+       ns = 0;
+       while(scan.ip != scan.end) {
+               int v;
+               if(scan.ip == ifinfo.bcast || he_for(scan.ip, 0, 0)) {
+                       scan.ip++;
+                       continue;
+               }
+               *(u32*)p = htonl(scan.ip);
+               v = sendto(sock, &arp, p+4-(u8*)&arp, 0, &bcast.sa, sizeof bcast.ll);
+               if(v<0) {
+                       if(errno != ENOBUFS || opts.nsend <= 1)
+                               err(1, "send(%s)", str_addr(&bcast));
+                       opts.nsend--;
+                       return -1;
+               }
+               scan.ip++;
+               if(++ns >= opts.nsend) break;
+       }
+       return ns;
+}
+
+void compare_resp(struct he *he, union addr *src, int hln, u8 *sha)
+{
+       if(hw_eq(&he->hw, hln, sha)
+        && hw_eq(&he->from, src->ll.sll_halen, src->ll.sll_addr))
+               return;
+
+       fprintf(stderr, "%s: ", str_ip(he->ip));
+       fprintf(stderr, "inconsistency: %s", str_hw(sha, hln));
+       if(src->ll.sll_halen != hln || memcmp(src->ll.sll_addr, sha, hln))
+               fprintf(stderr, " from %s",
+                str_hw(src->ll.sll_addr, src->ll.sll_halen));
+       fprintf(stderr, ", was %s\n", str_hw(he->hw.addr, he->hw.len));
+       if(!hw_eq(&he->hw, he->from.len, he->from.addr))
+               fprintf(stderr, " from %s",
+                str_hw(he->from.addr, he->from.len));
+}
+
+int arp_recv(struct arppkt *pkt, union addr *src)
+{
+       socklen_t l = sizeof *src;
+       int v = recvfrom(sock, pkt, sizeof *pkt, 0, &src->sa, &l);
+       if(v < 0) err(1, "recvfrom");
+       if(v < offsetof(struct arppkt, a))
+               return 0;
+       if(pkt->pro != IP)
+               return 0;
+       if(pkt->hrd != htons(ifinfo.hw_type) || pkt->hln != ifinfo.hw.len)
+               return 0;
+       if(v < offsetof(struct arppkt, a) + 2*pkt->hln + 2*4)
+               return 0;
+       return 1;
+}
+
+void receive()
+{
+       union addr addr;
+       struct arppkt arp;
+       struct he *he;
+       u32 ip;
+
+       if(!arp_recv(&arp, &addr))
+               return;
+       if(arp.op != htons(2)) /* only responses */
+               return;
+
+       ip = get_sip(&arp);
+
+       if(!he_for(ip, &he, 1)) {
+               hw_set(&he->hw, arp.hln, get_sha(&arp));
+               hw_set(&he->from, addr.ll.sll_halen, addr.ll.sll_addr);
+               if(opts.sort) return;
+               if(opts.isrange && !IN_RANGE(ip)) return;
+               print_he(he);
+       } else
+               compare_resp(he, &addr, arp.hln, get_sha(&arp));
+}
+
+/**/
+
+void passive()
+{
+       for(;;) {
+               struct arppkt arp;
+               union addr src;
+               if(!arp_recv(&arp, &src))
+                       continue;
+               printf("%s: ", str_addr(&src));
+               printf("%s %-15s ", str_hw(get_sha(&arp),arp.hln),
+                       str_ip(get_sip(&arp)));
+               switch(htons(arp.op)) {
+                       case 1:
+                               printf("Q %s", str_ip(get_tip(&arp)));
+                               break;
+                       case 2:
+                               printf("A %s %s", str_hw(get_tha(&arp),arp.hln),
+                                       str_ip(get_tip(&arp)));
+                               break;
+                       default:
+                               printf("%X", htons(arp.op));
+               }
+               putchar('\n');
+       }
+}
+
+/**/
+
+int waitsock(int n)
+{
+       int v;
+       struct pollfd pollfd;
+       pollfd.fd = sock;
+       pollfd.events = POLLIN;
+       v = poll(&pollfd, 1, n);
+       if(v < 0) {
+               if(errno != EINTR)
+                       err(1, "poll");
+               v = 0;
+       }
+       return v;
+}
+
+void print_he(struct he *he)
+{
+       int l, w;
+       if(opts.noown && he->ip == ifinfo.ip)
+               return;
+       printf("%s,", str_hw(he->hw.addr, he->hw.len));
+       l = 15 - printf("%s", str_ip(he->ip));
+       w = 0;
+       if(!opts.proui && !hw_eq(&he->from, he->hw.len, he->hw.addr))
+               w = 1, l = 1;
+
+       if(opts.proui)
+               print_oui(l, he->hw.addr);
+       else if(!opts.noethn) {
+#if !defined __dietlibc_ && !defined __UCLIBC__
+               char nm[1024];
+               if(!ether_ntohost(nm, (struct ether_addr*)he->hw.addr))
+                       printf("%*s%s", l, "", nm);
+#endif
+       }
+       if(w)
+               printf(" from %s", str_hw(he->from.addr, he->from.len));
+       putchar('\n');
+}
+
+static int parse_iprange(char *p)
+{
+       char *e;
+       u32 ip=0;
+       int sh;
+
+       for(sh = 24;; sh -= 8) {
+               unsigned long v;
+
+               v = strtoul(p, &e, 10);
+               if(p == e || v > 255)
+                       return 0;
+
+               ip |= v << sh;
+
+               p = e + 1;
+               if(*e == '/') {
+                       v = strtoul(p, &e, 10);
+                       if(p == e || *e || v > 32)
+                               return 0;
+                       if(v) {
+                               v = 32 - v;
+                               if(sh > v)
+                                       return 0;
+mask:
+                               v = ~0 << v;
+                       }
+                       scan.start = ip & v;
+                       scan.end = scan.start - v;
+                       return 1;
+               }
+
+               if(!sh) break;
+
+               v = sh;
+               if(!*e)
+                       goto mask;
+
+               if(*e != '.')
+                       return 0;
+
+               if(!*p || *p == '*' && !p[1])
+                       goto mask;
+       }
+
+       scan.start = ip;
+       scan.end = ip + 1;
+
+       if(*e == '-') {
+               u32 end = 0, m = ~0;
+
+               do {
+                       unsigned long v = strtoul(p, &e, 10);
+                       if(p == e || v > 255)
+                               return 0;
+                       p = e + 1;
+                       end = end<<8 | v;
+                       m <<= 8;
+               } while(m && *e);
+
+               if(*e)
+                       return 0;
+
+               end |= ip & m;
+               if(end < ip)
+                       return 0;
+
+               scan.end = end + 1;
+               return 1;
+       }
+       return *e == 0;
+}
+
+int main(int argc, char **argv)
+{
+       for(;;) switch(getopt(argc, argv, "fsaepwlh")) {
+               case 'f': opts.sort=0; break;
+               case 's': opts.sort=1; break;
+               case 'a': opts.noown=1; break;
+               case 'e': opts.noethn=1; break;
+               case 'p': opts.proui=1; break;
+               case 'w': opts.nsend=2; opts.wait=1000; break;
+               case 'l': opts.passive=1; break;
+               case 'h':
+                       printf(
+                       "wioscan [-faep] [interface] [ip-range]\n"
+                       "\t-s  sort responses\n"
+                       "\t-a  do not list interface's own address\n"
+#if !defined __dietlibc_ && !defined __UCLIBC__
+                       "\t-e  do not include info from /etc/ethers\n"
+#endif
+                       "\t-p  print vendor names\n"
+                       "\t-w  slow operation\n"
+                       "\t-l  listen only (not promiscuous)\n"
+                       "ip-range: ip ip/bits ip-ip\n"
+                       );
+                       return 0;
+               case EOF:
+                       goto endopt;
+       }
+endopt:
+
+       {
+               char *dev = "eth0";
+               if(optind<argc && (*argv[optind] < '0' || *argv[optind] > '9'))
+                       dev = argv[optind++];
+               fill_ifinfo(dev);
+               setup_socket();
+       }
+
+       if(optind>=argc) {
+               scan.start = ifinfo.net;
+               scan.end = (ifinfo.net | ~ifinfo.mask) + 1;
+       } else {
+               if(!parse_iprange(argv[optind]))
+                       errx(1, "%s: bad IP range", argv[optind]);
+               opts.isrange = 1;
+       }
+
+       if(ifinfo.hw_type != ARPHRD_ETHER)
+               opts.proui = 0, opts.noethn = 1;
+
+       if(opts.passive)
+               passive();
+
+       /* hw broadcast address is Linux's secret, this works with Ethernet */
+       bcast.sa.sa_family = AF_PACKET;
+       bcast.ll.sll_protocol = ARP;
+       bcast.ll.sll_ifindex = ifinfo.index;
+       bcast.ll.sll_hatype = ifinfo.hw_type;
+       bcast.ll.sll_pkttype = PACKET_BROADCAST; /* unused :-( */
+       bcast.ll.sll_halen = ifinfo.hw.len;
+       memset(bcast.ll.sll_addr, 0xFF, ifinfo.hw.len);
+
+       if(IN_RANGE(ifinfo.ip)) {
+               /* XXX we should add all our arpable addresses on the interface */
+               struct he *he;
+               he_for(ifinfo.ip, &he, 1);
+               hw_set(&he->hw, ifinfo.hw.len, ifinfo.hw.addr);
+               hw_set(&he->from, ifinfo.hw.len, ifinfo.hw.addr);
+               if(!opts.sort)
+                       print_he(he);
+       }
+
+       /* 1st scan */
+       scan.ip = scan.start;
+       while(sendscan()) {
+               while(waitsock(10))
+                       receive();
+       }
+       /* 2nd scan */
+       scan.ip = scan.start;
+       while(sendscan()) {
+               while(waitsock(10))
+                       receive();
+       }
+       while(waitsock(opts.wait))
+               receive();
+
+       if(opts.sort) for(scan.ip = ifinfo.net; scan.ip != scan.end; scan.ip++) {
+               struct he *he;
+               if(he_for(scan.ip, &he, 0))
+                       print_he(he);
+       }
+       return 0;
+}
+
+
+typedef uint8_t u8;
+static int fd = -2;
+static char *ouiptr, *ouiend;
+
+static void open_oui()
+{
+       struct stat st;
+       fd = open("oui", O_RDONLY);
+       if(fd < 0) {
+               fd = open(STR(OUI), O_RDONLY);
+               if(fd < 0) goto err;
+       }
+       if(fstat(fd, &st) < 0 || st.st_size == 0) goto err_cl;
+       ouiptr = mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+       ouiend = ouiptr + st.st_size;
+       if(ouiptr == MAP_FAILED) {
+err_cl:
+               close(fd); fd=-1;
+err:
+               warnx("Can't open OUI database");
+               return;
+       }
+#ifdef MADV_SEQUENTIAL
+       madvise(ouiptr, st.st_size, MADV_SEQUENTIAL);
+#endif
+}
+
+void print_oui(int sp, u8 a[6])
+{
+       char addr[7], *p, *q;
+       if(fd < 0) {
+               if(fd == -2)
+                       open_oui();
+               if(fd < 0)
+                       return;
+       }
+       sprintf(addr, "%02X%02X%02X", a[0], a[1], a[2]);
+
+       for(p=ouiptr; p<ouiend; p=q+1) {
+               q = memchr(p, '\n', ouiend-p);
+               if(!q) q=ouiend;
+               if(q-p < 8 || memcmp(p, addr, 6))
+                       continue;
+
+               p += 7;
+print:
+               printf("%*s%.*s", sp, "", (int)(q-p), p);
+               return;
+       }
+       if(a[0]==0 && a[1]==0xFF) {
+               p = "(generated)";
+               q = p + 11;
+               goto print;
+       }
+}
\ No newline at end of file
diff --git a/src/paks/wio/install.sh b/src/paks/wio/install.sh
new file mode 100644 (file)
index 0000000..f46ae35
--- /dev/null
@@ -0,0 +1,37 @@
+#!/bin/bash
+############################################################################
+#                                                                          #
+# This file is part of the IPFire Firewall.                                #
+#                                                                          #
+# IPFire 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.                                      #
+#                                                                          #
+# IPFire 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 IPFire; if not, write to the Free Software                    #
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA #
+#                                                                          #
+# Copyright (C) 2009 IPFire-Team <info@ipfire.org>.                        #
+#                                                                          #
+############################################################################
+#
+. /opt/pakfire/lib/functions.sh
+extract_files
+restore_backup ${NAME}
+
+chown -R nobody.nobody /var/ipfire/wio
+chown -R nobody.nobody /var/log/rrd/wio
+chown -R nobody.nobody /var/log/wio
+chown root.nobody /usr/local/bin/wioscan
+chown root.nobody /usr/local/bin/wiohelper
+
+chmod 4750 /usr/local/bin/wioscan
+chmod 4750 /usr/local/bin/wiohelper
+
+/usr/local/bin/update-lang-cache
diff --git a/src/paks/wio/uninstall.sh b/src/paks/wio/uninstall.sh
new file mode 100644 (file)
index 0000000..6be522d
--- /dev/null
@@ -0,0 +1,28 @@
+#!/bin/bash
+############################################################################
+#                                                                          #
+# This file is part of the IPFire Firewall.                                #
+#                                                                          #
+# IPFire 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.                                      #
+#                                                                          #
+# IPFire 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 IPFire; if not, write to the Free Software                    #
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA #
+#                                                                          #
+# Copyright (C) 2014 IPFire-Team <alexander.marx@ipfire.org>               #
+#                                                                          #
+############################################################################
+
+. /opt/pakfire/lib/functions.sh
+make_backup ${NAME}
+remove_files
+
+/usr/local/bin/update-lang-cache
diff --git a/src/paks/wio/update.sh b/src/paks/wio/update.sh
new file mode 100644 (file)
index 0000000..89c40d0
--- /dev/null
@@ -0,0 +1,26 @@
+#!/bin/bash
+############################################################################
+#                                                                          #
+# This file is part of the IPFire Firewall.                                #
+#                                                                          #
+# IPFire 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.                                      #
+#                                                                          #
+# IPFire 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 IPFire; if not, write to the Free Software                    #
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA #
+#                                                                          #
+# Copyright (C) 2007 IPFire-Team <info@ipfire.org>.                        #
+#                                                                          #
+############################################################################
+#
+. /opt/pakfire/lib/functions.sh
+./uninstall.sh
+./install.sh
diff --git a/src/wio/EX-wio.menu b/src/wio/EX-wio.menu
new file mode 100644 (file)
index 0000000..33a785e
--- /dev/null
@@ -0,0 +1,6 @@
+       $substatus->{'55.wio'} = {
+                               'caption' => "$Lang::tr{'wio'}",
+                               'uri' => '/cgi-bin/wio.cgi',
+                               'title' => "$Lang::tr{'wio'}",
+                               'enabled' => 1,
+                         };
diff --git a/src/wio/config/backup/includes/wio b/src/wio/config/backup/includes/wio
new file mode 100644 (file)
index 0000000..688b819
--- /dev/null
@@ -0,0 +1,2 @@
+/var/ipfire/wio/wio.conf
+/var/log/wio
diff --git a/src/wio/images/add.png b/src/wio/images/add.png
new file mode 100644 (file)
index 0000000..d894689
Binary files /dev/null and b/src/wio/images/add.png differ
diff --git a/src/wio/images/back.png b/src/wio/images/back.png
new file mode 100644 (file)
index 0000000..66921af
Binary files /dev/null and b/src/wio/images/back.png differ
diff --git a/src/wio/images/blue.png b/src/wio/images/blue.png
new file mode 100644 (file)
index 0000000..84d570e
Binary files /dev/null and b/src/wio/images/blue.png differ
diff --git a/src/wio/images/fqdn.png b/src/wio/images/fqdn.png
new file mode 100644 (file)
index 0000000..2db5ff7
Binary files /dev/null and b/src/wio/images/fqdn.png differ
diff --git a/src/wio/images/graph.png b/src/wio/images/graph.png
new file mode 100644 (file)
index 0000000..ac86b8c
Binary files /dev/null and b/src/wio/images/graph.png differ
diff --git a/src/wio/images/green.png b/src/wio/images/green.png
new file mode 100644 (file)
index 0000000..44838ec
Binary files /dev/null and b/src/wio/images/green.png differ
diff --git a/src/wio/images/http.png b/src/wio/images/http.png
new file mode 100644 (file)
index 0000000..851e400
Binary files /dev/null and b/src/wio/images/http.png differ
diff --git a/src/wio/images/https.png b/src/wio/images/https.png
new file mode 100644 (file)
index 0000000..823126a
Binary files /dev/null and b/src/wio/images/https.png differ
diff --git a/src/wio/images/ip.png b/src/wio/images/ip.png
new file mode 100644 (file)
index 0000000..da0e8a2
Binary files /dev/null and b/src/wio/images/ip.png differ
diff --git a/src/wio/images/mailgreenoff.png b/src/wio/images/mailgreenoff.png
new file mode 100644 (file)
index 0000000..041c9e7
Binary files /dev/null and b/src/wio/images/mailgreenoff.png differ
diff --git a/src/wio/images/mailgreenon.png b/src/wio/images/mailgreenon.png
new file mode 100644 (file)
index 0000000..9acc358
Binary files /dev/null and b/src/wio/images/mailgreenon.png differ
diff --git a/src/wio/images/mailredoff.png b/src/wio/images/mailredoff.png
new file mode 100644 (file)
index 0000000..0dbf075
Binary files /dev/null and b/src/wio/images/mailredoff.png differ
diff --git a/src/wio/images/mailredon.png b/src/wio/images/mailredon.png
new file mode 100644 (file)
index 0000000..668ba7d
Binary files /dev/null and b/src/wio/images/mailredon.png differ
diff --git a/src/wio/images/no_graph.png b/src/wio/images/no_graph.png
new file mode 100644 (file)
index 0000000..073ccc5
Binary files /dev/null and b/src/wio/images/no_graph.png differ
diff --git a/src/wio/images/none.png b/src/wio/images/none.png
new file mode 100644 (file)
index 0000000..fa0c3f3
Binary files /dev/null and b/src/wio/images/none.png differ
diff --git a/src/wio/images/orange.png b/src/wio/images/orange.png
new file mode 100644 (file)
index 0000000..9504469
Binary files /dev/null and b/src/wio/images/orange.png differ
diff --git a/src/wio/images/ovpn.png b/src/wio/images/ovpn.png
new file mode 100644 (file)
index 0000000..407a868
Binary files /dev/null and b/src/wio/images/ovpn.png differ
diff --git a/src/wio/images/ovpnn2n.png b/src/wio/images/ovpnn2n.png
new file mode 100644 (file)
index 0000000..038d6ed
Binary files /dev/null and b/src/wio/images/ovpnn2n.png differ
diff --git a/src/wio/images/ovpnrw.png b/src/wio/images/ovpnrw.png
new file mode 100644 (file)
index 0000000..a17a622
Binary files /dev/null and b/src/wio/images/ovpnrw.png differ
diff --git a/src/wio/images/red.png b/src/wio/images/red.png
new file mode 100644 (file)
index 0000000..e15dfb1
Binary files /dev/null and b/src/wio/images/red.png differ
diff --git a/src/wio/images/refresh.png b/src/wio/images/refresh.png
new file mode 100644 (file)
index 0000000..60a5ddd
Binary files /dev/null and b/src/wio/images/refresh.png differ
diff --git a/src/wio/images/vpn.png b/src/wio/images/vpn.png
new file mode 100644 (file)
index 0000000..d68f08e
Binary files /dev/null and b/src/wio/images/vpn.png differ
diff --git a/src/wio/images/vpnn2n.png b/src/wio/images/vpnn2n.png
new file mode 100644 (file)
index 0000000..2aa96df
Binary files /dev/null and b/src/wio/images/vpnn2n.png differ
diff --git a/src/wio/images/vpnrw.png b/src/wio/images/vpnrw.png
new file mode 100644 (file)
index 0000000..ca99367
Binary files /dev/null and b/src/wio/images/vpnrw.png differ
diff --git a/src/wio/images/white.png b/src/wio/images/white.png
new file mode 100644 (file)
index 0000000..20546bc
Binary files /dev/null and b/src/wio/images/white.png differ
diff --git a/src/wio/lang/wio.de.pl b/src/wio/lang/wio.de.pl
new file mode 100644 (file)
index 0000000..430284e
--- /dev/null
@@ -0,0 +1,156 @@
+%tr = (%tr,
+'wio' => 'Who Is Online?',
+'wio stat' => 'Status:',
+'wio checked' => 'zuletzt Ã¼berprüft',
+'wio name' => 'Hostname / FQDN',
+'wio ipadress' => 'IP-Adresse',
+'wio image' => 'Zustand',
+'wio up' => 'AKTIV',
+'wio down' => 'INAKTIV',
+'wio err' => 'Fehler',
+'wio warn' => 'Warnung',
+'wio_import_csv' => 'CSV Datei',
+'wio_import_hosts' => 'Hosts Datei (var/ipfire/main/hosts)',
+'wio_import_data' => 'Einstellungen für ',
+'wio_import_data1' => ' bearbeiten:',
+'wio_import_data2' => ' importieren:',
+'wio_import' => 'Importieren',
+'wio_import_info' => 'Mitteilung:',
+'wio_import_file' => 'Client(s) importieren aus:',
+'wio_import_info_csv' => 'Es gibt keine neuen Einstellungen zu importieren!',
+'wio settings' => 'Konfiguration:',
+'wio enabled' => 'aktivieren?',
+'wio min' => 'Minute(n)',
+'wio cron' => 'Zeitintervall für die Ãœberprüfung:',
+'wio_ovpn_cron' => 'Zeitintervall für die Ãœberprüfung des OpenVPN RW und IPSec Status:',
+'wio_save' => 'speichern',
+'wio_error' => 'Fehlermeldung:',
+'wio_info' => 'Meldung:',
+'wio_back' => 'zurück',
+'wio_use' => 'Diese Einstellungen importieren?',
+'wio_ip_error' => 'Ungültige IP-Adresse!',
+'wio_host_error' => 'Ungültiger Hostname!',
+'wio_host_exists' => 'Hostname wird schon benutzt!',
+'wio_host_empty' => 'Es wurde kein Hostname eingetragen!',
+'wio_ip_exists' => 'IP-Adresse wird schon benutzt!',
+'wio_ip_empty' => 'Es wurde keine IP-Adresse eingetragen!',
+'wio_import_fixleases' => 'DHCP Datei (var/ipfire/dhcp/fixleases)',
+'wio_import_leases' => 'Einstellungen importieren:',
+'wio network' => 'Netzwerk',
+'wio_refresh' => 'alle Clients aktualisieren',
+'wio_fqdn_error' => 'Ungültiger Fully Qualified Domain Name (FQDN)! Bitte keine Sonderzeichen, Umlaute oder Leerzeichen beim FQDN verwenden.',
+'wio_edit' => 'Einstellungen bearbeiten:',
+'wio_dyndns' => 'DynDNS',
+'wio_dyndns_hosts' => 'DynDNS Name(n)',
+'wio_dyndns_refresh' => 'DynDNS IP aktualisieren',
+'wio_dyndns_on' => 'DynDNS Host aktiviert (klicken, um zu deaktivieren)',
+'wio_dyndns_off' => 'DynDNS Host deaktiviert (klicken, um zu aktivieren)',
+'wio_dyndns_info' => 'Keine IP eingetragen, da scheinbar keine Verbindung ins Internet besteht. Bei der nächsten Verbindung ins Internet wird eine Aktualisierung der IP des DynDNS Hostes durchgeführt.',
+'wio_no_csv' => 'Die Datei hat nicht die Erweiterung .csv',
+'wio_no_csv_error' => 'Bitte keine Sonderzeichen, Umlaute oder Leerzeichen im Dateinamen verwenden.',
+'wio_no_file_selected' => 'Es wurde keine Datei ausgewählt!',
+'wio_import_infos' => 'Einstellungen importieren:',
+'wio_import_infos_csv' => 'ACHTUNG: Es werden nur die Datensätze importiert, bei denen die Option "Diese Einstellungen importieren?" aktiviert ist! Sollten Datensätze mit doppelten IP-Adressen oder Hostnamen vorkommen, wird der zu erst aufgeführte Datensatz importiert und die anderen Datensätze (mit den doppelten IP-Adressen oder Hostnamen) werden nicht berücksichtigt!',
+'enable disable dyndns' => 'DynDNS Host aktivieren oder deaktivieren',
+'wio_msg' => 'Zustand (aktiv/inaktiv) des Clients / der Clients wird aktualisiert ...',
+'wio_lanname' => 'LAN Hostname',
+'wio_wanname' => 'WAN Hostname',
+'wio_wancheck' => 'verbunden seit',
+'wio_sc_refresh' => 'Client aktualisieren',
+'wio_edit_settings' => 'Client hinzufügen:',
+'wio_edit_client' => 'Client bearbeiten:',
+'wio_graphs' => 'Graphen anzeigen',
+'wio_no_graphs' => 'keine Graphen vorhanden',
+'wio_graphs_stat' => 'Diagramme für',
+'wio_vpn_con' => 'VPN - Verbindung(en):',
+'wio_wan_con' => 'WAN - Verbindung:',
+'wio_clients' => 'Clients:',
+'wio click to disable' => 'Aktiviert',
+'wio click to enable' => 'Deaktiviert',
+'wio_net_scan' => 'Netzwerk(e) durchsuchen:',
+'wio_net_scan_vl' => '',
+'wio_net_scan_l' => 'Netzwerk an',
+'wio_net_scan_r' => 'durchsuchen:',
+'wio_net_scan_green' => 'grünes',
+'wio_net_scan_blue' => 'blaues',
+'wio_net_scan_orange' => 'oranges',
+'wio_net_scan_run' => 'starten',
+'wio_sort_host' => 'nach Hostnamen (FQDN) sortieren',
+'wio_sort_ip' => 'nach IP Adressen sortieren',
+'wio_logging' => 'Logging (/var/log/messages) aktivieren?',
+'wio_no_image' => 'KEIN STATUS',
+'wio_ovpn_con' => 'OpenVPN - Verbindung(en):',
+'wio_ovpn_connected' => 'verbunden seit',
+'wio_wan_up' => 'VERBUNDEN',
+'wio_wan_down' => 'GETRENNT',
+'wio_n2n' => 'Netz-zu-Netz Verbindung',
+'wio_rw' => 'Host-zu-Netz Verbindung',
+'wio_mailremark_enabled' => 'Anmerkung des Clients mit in Mailtext Ã¼bernehmen?',
+'wio_mail_online_on' => 'Online-E-Mail aktiviert (klicken, um zu deaktivieren)',
+'wio_mail_online_off' => 'Online-E-Mail deaktiviert (klicken, um zu aktivieren)',
+'wio_mail_offline_on' => 'Offline-E-Mail aktiviert (klicken, um zu deaktivieren)',
+'wio_mail_offline_off' => 'Offline-E-Mail deaktiviert (klicken, um zu aktivieren)',
+'wio_mail_online' => 'Online E-Mail aktivieren oder deaktivieren',
+'wio_mail_offline' => 'Offline E-Mail aktivieren oder deaktivieren',
+'wio_sendemail' => 'E-Mail senden wenn',
+'wio_hwaddress' => 'HW-Adresse',
+'wio_iface' => 'Schnittstelle',
+'wio_client_enable' => 'Client aktivieren?',
+'wio_ping_send' => 'überprüfen per',
+'enable disable client' => 'Client aktivieren oder deaktivieren',
+'wio_client_on' => 'Ãœberwachung aktiviert (klicken, um zu deaktivieren)',
+'wio_client_off' => 'Ãœberwachung deaktiviert (klicken, um zu aktivieren)',
+'wio_webinterface' => 'LINK',
+'wio_webinterface_link' => 'Link Ã¶ffnen',
+'wio_ip' => 'überprüfen per IP aktiviert',
+'wio_fqdn' => 'überprüfen per FQDN aktiviert',
+'wio_ip_on' => 'überprüfen per IP aktiviert (klicken, um per FQDN zu aktivieren)',
+'wio_fqdn_on' => 'überprüfen per FQDN aktiviert (klicken, um per IP zu aktivieren)',
+'wio_client_add' => 'Eingaben anwenden',
+'wio_config' => 'Client(s) konfigurieren:',
+'wio_settings_msg' => 'Einstellungen bearbeiten:',
+'wio_settings_msg_hint' => 'Um Who Is Online? benutzen zu können, müssen hier grundsätzliche Einstellungen vorgenommen werden.',
+'wio_sub' => 'WIO Client-Status-Mail',
+'wio timeout' => 'Ping Timeout:',
+'wio sec' => 'Sekunde(n)',
+'wio_add' => 'Client hinzufügen:',
+'wio_no_add' => 'Client ist vorhanden',
+'wio_id' => '#',
+'wio_online' => 'online',
+'wio_offline' => 'offline',
+'wio_status' => 'WIO Client-Status',
+'wio_mail_style' => 'WIO Client Statusmails versenden als',
+'wio_mail_smail' => 'Sammelmail',
+'wio_mail_email' => 'Einzelmails',
+'wio_mail_ovpnrw' => 'OpenVPN RW und IPSec Statusmails aktivieren?',
+'wio_edit_set' => 'Konfiguration',
+'wio_service' => 'Service:',
+'wio_dyndns_success' => 'DynDNS IP ermittelt und eingetragen!',
+'wio_remove_all' => 'alle Clients löschen',
+'wio_remove_all_hint' => 'Möchten Sie wirklich alle Clients löschen?',
+'wio_remove_client' => 'Client löschen',
+'wio_remove_client_hint' => 'Möchten Sie den Client wirklich löschen?',
+'wio_arp_table_entries' => 'Client aus der ARP-Tabelle hinzufügen:',
+'wio_activ' => 'aktiv',
+'wio_check' => 'prüfen',
+'wio_common_name' => 'Remote Host / IP',
+'wio_msg_left' => 'Das',
+'wio_msg_green' => 'grüne',
+'wio_msg_blue' => 'blaue',
+'wio_msg_orange' => 'orange',
+'wio_msg_center' => 'Netzwerk an',
+'wio_msg_right' => 'wird durchsucht.',
+'wio_msg_hint' => 'Einen Moment bitte ...',
+'wio_last_update' => 'zuletzt aktualisiert',
+'wio_disable_hint' => 'Achtung! Es werden alle Einstellungen incl. der zu Ã¼berprüfenden Clients zurückgesetzt!',
+'wio_clientremark' => 'Anmerkung anzeigen?',
+'wio_already_running' => 'Die Prüfung wird bereits durchgeführt!',
+'wio_error_function' => 'Diese Funktion kann im Moment nicht ausgeführt werden, da im Hintergrund gerade der Zustand (aktiv/inaktiv) der Clients aktualisiert wird.',
+'wio_shutdown' => 'Herunterfahren, wenn alle Clients "offline" sind?',
+'wio_unknown_lan' => 'UNBEKANNT',
+'wio_red_lan' => 'ROT',
+'wio_search' => 'Suche im lokalen Netzwerk nach aktiven Hosts ...',
+'wio_answer' => 'Antwort',
+'wio_answer_time' => 'Antwortzeit',
+'wio_scriptruntime' => 'Scriptlaufzeit',
+);
diff --git a/src/wio/lang/wio.en.pl b/src/wio/lang/wio.en.pl
new file mode 100644 (file)
index 0000000..154e64f
--- /dev/null
@@ -0,0 +1,156 @@
+%tr = (%tr,
+'wio' => 'Who Is Online?',
+'wio stat' => 'Current condition(s):',
+'wio checked' => 'Last checked',
+'wio name' => 'Hostname or FQDN',
+'wio ipadress' => 'IP-Address',
+'wio image' => 'Condition',
+'wio up' => 'Active',
+'wio down' => 'Inactive',
+'wio err' => 'Error',
+'wio warn' => 'Warning',
+'wio_import_csv' => 'CSV file:',
+'wio_import_hosts' => 'hosts configuration (var/ipfire/main/hosts) ?',
+'wio_import_data' => 'import settings for ',
+'wio_import_data1' => ' correct:',
+'wio_import_data2' => ' import:',
+'wio_import' => 'Importing',
+'wio_import_info' => 'message:',
+'wio_import_file' => 'Import settings from:',
+'wio_import_info_csv' => 'There are no new settings to import!',
+'wio settings' => 'configuration:',
+'wio enabled' => 'enable ?',
+'wio min' => 'Minute(s)',
+'wio cron' => 'Time interval for checking:',
+'wio_ovpn_cron' => 'Time interval for checking the OpenVPN RW and IPSec Status:',
+'wio_save' => 'save',
+'wio_error' => 'errormessage:',
+'wio_info' => 'message:',
+'wio_back' => 'back',
+'wio_use' => 'Import these settings ?',
+'wio_ip_error' => 'Invalid IP Address.',
+'wio_host_error' => 'Invalid Hostname.',
+'wio_host_exists' => 'Hostname is already used.',
+'wio_host_empty' => 'No Hostname was registered!',
+'wio_ip_exists' => 'IP Address is already used.',
+'wio_ip_empty' => 'No IP Address was registered!',
+'wio_import_fixleases' => 'DHCP configuration (var/ipfire/dhcp/fixleases) ?',
+'wio_import_leases' => 'Import settings:',
+'wio network' => 'Network',
+'wio_refresh' => 'update all clients now',
+'wio_fqdn_error' => 'Invalid Fully Qualified Domain Name (FQDN)! Please do not use special characters or blanks in the FQDN.',
+'wio_edit' => 'change settings:',
+'wio_dyndns' => 'DynDNS',
+'wio_dyndns_hosts' => 'DynDNS Name(s)',
+'wio_dyndns_refresh' => 'DynDNS Host IP update',
+'wio_dyndns_on' => 'DynDNS Host enabled (click to disable)',
+'wio_dyndns_off' => 'DynDNS Host disabled (click to enable)',
+'wio_dyndns_info' => 'None IP registered, since apparently no connection exists in Internet. With the next connection in Internet is accomplished an actualization of the IP of the DynDNS Hostes.',
+'wio_no_csv' => 'File has not the extension .csv',
+'wio_no_csv_error' => 'Please do not use special characters or blanks in the filename.',
+'wio_no_file_selected' => 'No File selected!',
+'wio_import_infos' => 'Import settings:',
+'wio_import_infos_csv' => 'NOTE: Only Data records with marked "Import these settings ?" are considered by importing! If data records with double IP-Addresses or Hostnames should occur, only the first data record will be imported and the other data records (with the double IP-Addresses or Hostnames) will not be considered!',
+'enable disable dyndns' => 'enable or disable DynDNS Host',
+'wio_msg' => 'Condition of the examining Client(s) are updated ...',
+'wio_lanname' => 'LAN Hostname',
+'wio_wanname' => 'WAN Hostname',
+'wio_wancheck' => 'connected since',
+'wio_sc_refresh' => 'update client now',
+'wio_edit_settings' => 'add client:',
+'wio_edit_client' => 'edit client:',
+'wio_graphs' => 'show graphs',
+'wio_no_graphs' => 'no graphs available',
+'wio_graphs_stat' => 'Diagramm for',
+'wio_vpn_con' => 'VPN - Connection(s):',
+'wio_wan_con' => 'WAN - Connection:',
+'wio_clients' => 'clients:',
+'wio click to disable' => 'Activated',
+'wio click to enable' => 'Deactivated',
+'wio_net_scan' => 'Scan Network(s):',
+'wio_net_scan_vl' => 'scan',
+'wio_net_scan_l' => 'Network on',
+'wio_net_scan_r' => '',
+'wio_net_scan_green' => 'green',
+'wio_net_scan_blue' => 'blue',
+'wio_net_scan_orange' => 'orange',
+'wio_net_scan_run' => 'start',
+'wio_sort_host' => 'sort Hostnames (FQDN)',
+'wio_sort_ip' => 'sort IP-Adresses',
+'wio_logging' => 'activate Logging (/var/log/messages) ?',
+'wio_no_image' => 'NO STATUS',
+'wio_ovpn_con' => 'OpenVPN - Connection(s):',
+'wio_ovpn_connected' => 'connected since',
+'wio_wan_up' => 'CONNECTED',
+'wio_wan_down' => 'NOT CONNECTED',
+'wio_n2n' => 'Net-to-Net Connection',
+'wio_rw' => 'Host-to-Net Connection',
+'wio_mailremark_enabled' => 'Add Remark from client to mailbody ?',
+'wio_mail_online_on' => 'online email enabled (click to disable)',
+'wio_mail_online_off' => 'online email disabled (click to enable)',
+'wio_mail_offline_on' => 'offline email enabled (click to disable)',
+'wio_mail_offline_off' => 'offline emaildisabled (click to enable)',
+'wio_mail_online' => 'enable or disable online email',
+'wio_mail_offline' => 'enable or disable offline email',
+'wio_sendemail' => 'send email',
+'wio_hwaddress' => 'HW-Adresse',
+'wio_iface' => 'Interface',
+'wio_client_enable' => 'enable Host ?',
+'wio_ping_send' => 'send ping to',
+'enable disable client' => 'enable or disable client',
+'wio_client_on' => 'Client enabled (click to disable)',
+'wio_client_off' => 'Client disabled (click to enable)',
+'wio_webinterface' => 'LINK',
+'wio_webinterface_link' => 'follow link',
+'wio_ip' => 'send ping to IP enabled',
+'wio_fqdn' => 'send ping to FQDN enabled',
+'wio_ip_on' => 'send ping to IP enabled (click to enable FQDN)',
+'wio_fqdn_on' => 'send ping to FQDN enabled (click to enable IP)',
+'wio_client_add' => 'use settings',
+'wio_config' => 'configurate Client(s):',
+'wio_settings_msg' => 'configurate settings:',
+'wio_settings_msg_hint' => 'Here you have to set some values to get the addon started.',
+'wio_sub' => 'WIO Client-Status-Mail',
+'wio timeout' => 'Ping Timeout:',
+'wio sec' => 'Second(s)',
+'wio_add' => 'add Client:',
+'wio_no_add' => 'Client is available',
+'wio_id' => '#',
+'wio_online' => 'online',
+'wio_offline' => 'offline',
+'wio_status' => 'WIO Client-Status',
+'wio_mail_style' => 'send WIO Client Statusmails as',
+'wio_mail_smail' => 'collected mail',
+'wio_mail_email' => 'single mails',
+'wio_mail_ovpnrw' => 'enable OpenVPN RW and IPSec Statusmails ?',
+'wio_edit_set' => 'configuration',
+'wio_service' => 'Service:',
+'wio_dyndns_success' => 'DynDNS IP identified and registered!',
+'wio_remove_all' => 'remove all clients',
+'wio_remove_all_hint' => 'Are you sure to delete all the clients?',
+'wio_remove_client' => 'remove client',
+'wio_remove_client_hint' => 'Are you sure to delete the client?',
+'wio_arp_table_entries' => 'add client from ARP-Table:',
+'wio_activ' => 'activ',
+'wio_check' => 'check',
+'wio_common_name' => 'Remote Host/IP',
+'wio_msg_left' => 'Searching on the',
+'wio_msg_green' => 'green',
+'wio_msg_blue' => 'blue',
+'wio_msg_orange' => 'orange',
+'wio_msg_center' => 'Interface on',
+'wio_msg_right' => 'is being examined.',
+'wio_msg_hint' => 'One moment please ...',
+'wio_last_update' => 'last update',
+'wio_disable_hint' => 'Attention! It will reset all settings including the client to be checked!',
+'wio_clientremark' => 'show remark?',
+'wio_already_running' => 'This check is already running!',
+'wio_error_function' => 'This function is temporarily unavailable, because in the background client states are being updated (active/inactive).',
+'wio_shutdown' => 'Shutdown when all clients are "offline"?',
+'wio_unknown_lan' => 'UNKNOWN',
+'wio_red_lan' => 'RED',
+'wio_search' => 'Searching for active hosts in the local network ...',
+'wio_answer' => 'Answer',
+'wio_answer_time' => 'Response Time',
+'wio_scriptruntime' => 'Script Execution Time',
+);
diff --git a/src/wio/main/wio.conf b/src/wio/main/wio.conf
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/wio/main/wio.pl b/src/wio/main/wio.pl
new file mode 100644 (file)
index 0000000..985900d
--- /dev/null
@@ -0,0 +1,385 @@
+#!/usr/bin/perl
+#
+###############################################################################
+#                                                                             #
+# IPFire.org - A linux based firewall                                         #
+# Copyright (C) 2017 Stephan Feddersen <addons@h-loit.de>                     #
+# All Rights Reserved.                                                        #
+#                                                                             #
+# 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 3 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, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+###############################################################################
+#
+# id: wio.pl, v1.3.1 2017/07/11 21:31:16 sfeddersen
+#
+# This wio.pl is based on the Code from the IPCop WIO Addon
+# and is extremly adapted to work with IPFire.
+#
+# Autor: Stephan Feddersen
+# Co-Autor: Alexander Marx
+# Co-Autor: Frank Mainz
+#
+
+# enable only the following on debugging purpose
+#use warnings;
+
+use strict;
+use POSIX qw(strftime);
+use Time::HiRes qw(gettimeofday tv_interval);
+use Net::Ping;
+use RRDs;
+use Fatal qw/ open /;
+
+require '/var/ipfire/general-functions.pl';
+require '/var/ipfire/lang.pl';
+require '/usr/lib/wio/wio-lib.pl';
+
+my ( $debug, $i, $t, $ib, $tb, $ivpn, $tvpn ) = '';
+my $logdir    = "/var/log/wio";
+my $owner     = getpwnam "nobody";
+my $group     = getgrnam "nobody";
+my $ipadrfile = "$logdir/wioips";
+
+unless ( -e $ipadrfile ) { print ( "The file $ipadrfile doesn't exist!\n" ); exit; }
+
+foreach (@ARGV) {
+  if ( $_ eq '-d' || $_ eq '--debug') { $debug = 1; }
+  if ( $_ eq '-h' || $_ eq '--help' ) { die help(); }
+}
+
+my ( %wiosettings, %mainsettings, %mailsettings, %netsettings ) = ();
+
+&General::readhash('/var/ipfire/main/settings', \%mainsettings);
+&General::readhash('/var/ipfire/ethernet/settings', \%netsettings);
+&General::readhash('/var/ipfire/dma/mail.conf', \%mailsettings);
+&General::readhash("/var/ipfire/wio/wio.conf", \%wiosettings);
+
+my $now        = strftime "%a, %d.%m.%Y %H:%M:%S", localtime;
+my $logging    = $wiosettings{'LOGGING'};
+my $mailstyle  = $wiosettings{'MAILSTYLE'};
+my $mailremark = $wiosettings{'MAILREMARK'};
+my $timeout    = $wiosettings{'TIMEOUT'};
+my $shutdown   = $wiosettings{'SHUTDOWN'};
+my $rrddir     = "/var/log/rrd/wio";
+my $onoffip    = "$logdir/wioscip";
+my $hostname   = "$mainsettings{'HOSTNAME'}.$mainsettings{'DOMAINNAME'}";
+my $redactive  = "/var/ipfire/red/active";
+my $rediface   = "/var/ipfire/red/iface";
+my $reddev     = '';
+
+if ( -e $rediface ) {
+       $reddev = &General::get_red_interface;
+}
+
+my $redip      = $hostname;
+my $vpnpid     = ( -e "/var/run/charon.pid" ? `awk '{print $1}' /var/run/charon.pid`: '');
+my $ovpnpid    = ( -e  "/var/run/openvpn.pid" ? `awk '{print $1}' /var/run/openvpn.pid`: '');
+
+my $steptime = $wiosettings{'CRON'} *= 60;
+my $i_ping   = 'icmp';
+my $t_ping   = 'tcp';
+
+my $nr = 1;
+my $poweroff = 0;
+
+my ( $togglestat, $arp, $time, $start, $timestamp ) = 0;
+my ( $id, $ipadr, $ipadrnew, $host, $hostnew, $enable, $remark, $dyndns, $dyndnsip ) = '';
+my ( $mail, $mailon, $mailoff, $ping, $on, $httphost, $mailen ) = '';
+my ( $msg, $logmsg, $mailmsg, $smailtxt, $infomsg, $client, $mode, $onbak, $arpclient ) = '';
+my ( $ping_i, $ping_t, $ping_ib, $ping_tb, $ping_iv, $ping_tv, $pingmode ) = '';
+my ( @tmp, @arptmp, @myarray, @status, @arpclients ) = '';
+my @ifaces = ('GREEN','BLUE','ORANGE');
+
+
+if ( $mailsettings{'USEMAIL'} eq 'on' ) { $mailen = 'on'; }
+else { $mailen = 'off'; }
+
+if ( -e $redactive ) {
+       open(IPADDR, "/var/ipfire/red/local-ipaddress");
+       $redip = <IPADDR>;
+       close IPADDR;
+       chomp($redip);
+}
+
+if ($debug) {
+       $start = [gettimeofday];
+       startdebug();
+}
+
+foreach (@ifaces) {
+       if ( $netsettings{"${_}_DEV"} ne '' && $netsettings{"${_}_DEV"} ne 'disabled' ) {
+               my $output = `ifconfig $netsettings{"${_}_DEV"}`;
+
+               if ( grep (/RX bytes:0/, $output) ) { next; }
+               else {
+                       @arptmp = `/usr/local/bin/wioscan -s $netsettings{"${_}_DEV"}`;
+
+                       foreach $arpclient (@arptmp) {
+                               push (@arpclients, (split (/\,/,$arpclient))[1]);
+                       }
+               }
+               $output = '';
+               undef(@arptmp);
+       }
+}
+
+if ( -e "$onoffip" ) { open( FILE, "< $onoffip" ); }
+else { open( FILE, "< $ipadrfile" ); }
+@myarray = <FILE>;
+close(FILE);
+
+# ping all clients
+
+foreach (@myarray) {
+       chomp;
+       @tmp = split( /\,/, $_ );
+
+       ($id,$timestamp,$ipadr,$host,$enable,$remark,$dyndns,$mailon,$mailoff,$ping,$on,$httphost) = @tmp;
+
+       $timestamp = strftime "%d.%m.%Y - %H:%M:%S", localtime;
+
+       if ( $enable ne 'on' ) {
+               push (@status, "$id,$timestamp,$ipadr,$host,$enable,$remark,$dyndns,$mailon,$mailoff,$ping,$on,$httphost\n");
+               next;
+       }
+
+       if ( defined($dyndns) && ( $dyndns =~ 'on' ) ) {
+               ($dyndnsip, $infomsg) = &WIO::getdyndnsip($host, @myarray);
+               if ($dyndnsip ne $ipadr) { $ipadr = $dyndnsip; }
+       }
+
+       $ping_i = $ping_t = $ping_ib = $ping_tb = $ping_iv =  $ping_tv = $pingmode = $arp = 0;
+
+       foreach (@arpclients) {
+               chomp;
+               unless ( $ipadr eq $_ )
+               {
+                       $i = Net::Ping->new( $i_ping, $timeout );
+                       unless ( defined $i ) { die "Can't create Net::Ping object $!"; }
+
+                       $t = Net::Ping->new( $t_ping, $timeout );
+                       unless ( defined $t ) { die "Can't create Net::Ping object $!"; }
+
+                       $ib = Net::Ping->new( $i_ping, $timeout );
+                       unless ( defined $ib ) { die "Can't create Net::Ping object $!"; }
+                       $ib->bind($redip);
+
+                       $tb = Net::Ping->new( $t_ping, $timeout );
+                       unless ( defined $tb ) { die "Can't create Net::Ping object $!"; }
+                       $tb->bind($redip);
+
+                       if ($ovpnpid || $vpnpid)
+                       {
+                               $ivpn = Net::Ping->new( $i_ping, $timeout );
+                               unless ( defined $ivpn ) { die "Can't create Net::Ping object $!"; }
+                               $ivpn->bind($hostname);
+
+                               $tvpn = Net::Ping->new( $t_ping, $timeout );
+                               unless ( defined $tvpn ) { die "Can't create Net::Ping object $!"; }
+                               $tvpn->bind($hostname);
+                       }
+               }
+               else { $arp = 1 }
+       }
+
+       $client = ( ( $dyndns eq 'on' || $ping eq 'fqdn' ) ? $host : $ipadr );
+
+       if ($debug) {
+               printf "%2s   %15s", $nr++,  ($client ne $ipadr ? $ipadr : $client );
+               $time = [gettimeofday];
+       }
+
+       if ( $arp == 1 
+               || ($ping_i = $i->ping($client))
+               || ($ping_t = $t->ping($client))
+               || ($ping_ib = $ib->ping($client))
+               || ($ping_tb = $tb->ping($client))
+               || ($ovpnpid?($ping_iv = $ivpn->ping($client)) : 0)
+               || ($vpnpid?($ping_tv = $tvpn->ping($client)) : 0) )
+       {
+               $mode       = 100;
+               $msg        = "$Lang::tr{'wio up'}";
+               $onbak      = $on;
+               $togglestat = ( $on ne 'on' ) ? 1 : 0;
+               $on         = 'on';
+       }
+       else {
+               $mode       = 0;
+               $msg        = "$Lang::tr{'wio down'}";
+               $onbak      = $on;
+               $togglestat = ( $on ne 'off' ) ? 1 : 0;
+               $on         = 'off';
+       }
+
+       push (@status, "$id,$timestamp,$ipadr,$host,$enable,$remark,$dyndns,$mailon,$mailoff,$ping,$on,$httphost\n");
+
+       if ($debug) {
+               $mail = '----';
+               if ( $mailon eq 'on' && $togglestat == 1 && $mode == 100 ) { $mail = 'Online'; }
+               if ( $mailoff eq 'on' && $togglestat == 1 && $mode == 0 ) { $mail = 'Offline'; }
+               if ( $dyndns ne 'on' ) { $dyndns = 'off'; }
+
+               $pingmode = $arp ? 'ARPSCAN' : $ping_i ? 'ICMP' : $ping_t ? 'TCP' : $ping_ib ? 'ICMP+BIND' : $ping_tb ? 'TCP+BIND' : $ping_iv ? 'VPN ICMP' : $ping_tv ? 'VPN TCP' : 'NO ECHO';  
+               printf "%7s%8s%9s%10s     %.4f sek%12s\n", $ping, $dyndns, $msg, $mail, tv_interval($time), $pingmode;
+       }
+
+       if ( $host eq '' ) { $hostnew = 'n/a'; } else { $hostnew = $host; }
+       if ( $ipadr eq '' ) { $ipadrnew = 'n/a'; } else { $ipadrnew = $ipadr; }
+
+       if ( $logging eq 'on' ) {
+               $logmsg = "Client: $hostnew - IP: $ipadrnew - Status: $msg";
+               &General::log("wio","$logmsg");
+       }
+
+       if ( $mailen eq 'on' && $togglestat == 1 && ($mailon eq 'on' || $mailoff eq 'on')) {
+       
+               if ( $mailstyle eq 'email' || ($mailstyle eq 'smail' && $smailtxt eq '') ) { $mailmsg .= "Date\t : $now\n\n"; }
+
+               $mailmsg .= "Client\t : $hostnew\nIP\t : $ipadrnew\nStatus\t : $msg\n";
+
+               if ( $mailremark eq 'on' && $remark ne '' ) {
+                       $mailmsg .= "Remark : $remark\n\n";
+               }
+
+               if ( $mailstyle eq 'email' ) {
+                       &WIO::mailsender("WIO - $host - $msg", $mailmsg);
+                       undef ($mailmsg);
+               }
+               elsif ( $mailstyle eq 'smail'  ) {
+                       $smailtxt .= $mailmsg."\n";
+                       undef ($mailmsg);
+               }
+       }
+
+       if ( $ping ne 'fqdn' ) { $client = $host; }
+       if ( $host eq '' ) { $client = $ipadr; }
+
+       updatewiodata("$id");
+
+       if ( $arp == 0 ) {
+               $i->close();
+               $t->close();
+               $ib->close();
+               $tb->close();
+       }
+
+       if ( ( -e $ovpnpid || -e $vpnpid ) && $arp == 0 ) {
+               $ivpn->close();
+               $tvpn->close();
+       }
+}
+
+# write adressfile new
+
+if ( !-e $onoffip ) {
+       open( FILE, "> $ipadrfile" );
+       print FILE @status;
+       close(FILE);
+}
+else {
+       system("/bin/sed -i 's#$tmp[0],$tmp[1],$tmp[2],$tmp[3],$tmp[4],$tmp[5],$tmp[6],$tmp[7],$tmp[8],$tmp[9],$tmp[10],$tmp[11]#$id,$timestamp,$ipadr,$host,$enable,$remark,$dyndns,$mailon,$mailoff,$ping,$on,$httphost#g' $ipadrfile");
+       chmod ( 0644, $ipadrfile ); 
+       chown ( $owner, $group, $ipadrfile );
+}
+
+if ($debug) {
+       printf ("\n$Lang::tr{'wio_scriptruntime'}:  %.4f $Lang::tr{'age ssecond'}\n\n", tv_interval($start));
+}
+
+if ( $smailtxt ne '' ) { &WIO::mailsender($Lang::tr{'wio_sub'}, $smailtxt); }
+
+if ($shutdown eq 'on') {
+       foreach (@status) {
+               chomp;
+               @tmp = split( /\,/, $_ );
+
+               ($id,$timestamp,$ipadr,$host,$enable,$remark,$dyndns,$mailon,$mailoff,$ping,$on,$httphost) = @tmp;
+               
+               if ( $on eq 'on' ) {
+                       $poweroff = 0;
+                       last;
+               }
+               else {
+                       $poweroff = 1;
+                       next;
+               }
+       }
+
+       if ($poweroff == 1) {
+               if ($debug) {
+                       printf "$Lang::tr{'shutting down ipfire'}!\n\n";
+               }
+
+               &General::log("wio","$Lang::tr{'shutting down ipfire'}!");
+               system '/usr/local/bin/ipfirereboot down';
+       }
+}
+
+undef (@tmp);
+undef (@myarray);
+undef (@status);
+undef (@arptmp);
+undef (@arpclients);
+
+if ( -e $onoffip ) { unlink($onoffip); }
+
+sub updatewiodata {
+       my $id = $_[0];
+
+       if ( !-e "$rrddir/$id.rrd" ) {
+               RRDs::create(
+                       "$rrddir/$id.rrd",      "--step=$steptime",
+                       "DS:mode:GAUGE:3600:0:100", "RRA:AVERAGE:0.5:1:576",
+                       "RRA:AVERAGE:0.5:6:672",    "RRA:AVERAGE:0.5:24:732",
+                       "RRA:AVERAGE:0.5:144:1460"
+               );
+               my $ERROR = RRDs::error;
+               print "Error in RRD::create for Who Is Online: $ERROR\n" if $ERROR;
+       }
+
+       RRDs::update( "$rrddir/$id.rrd", "-t", "mode", "N:$mode" );
+
+       my $error = RRDs::error;
+
+       if ($error) { &General::log("wio","$error"); }
+}
+
+sub startdebug {
+
+printf "
+HOSTNAME    : $hostname
+TIMEOUT     : $timeout $Lang::tr{'age ssecond'}
+MAILSTYLE   : $mailstyle
+RED TYPE    : $netsettings{'RED_TYPE'}
+RED DEVICE  : $reddev
+RED ADDRESS : $redip
+SHUTDOWN    : $shutdown
+";
+       if ($ovpnpid) {printf "OVPN PID    : $ovpnpid"}
+       if ($vpnpid) {printf "VPN PID     : $vpnpid"}
+printf  "
+$Lang::tr{'wio_search'}
+
+%3s%17s%7s%8s%9s%10s%15s%12s
+---------------------------------------------------------------------------------
+","ID ", "$Lang::tr{'wio ipadress'}", "Ping", "DynDNS", "Status", "Mail", "$Lang::tr{'wio_answer_time'}", "$Lang::tr{'wio_answer'}";
+}
+
+sub help {
+       return "
+Who Is Online? for IPFire
+
+use option -d for debugging
+use option -h for help\n\n";
+}
diff --git a/src/wio/main/wiovpn.pl b/src/wio/main/wiovpn.pl
new file mode 100644 (file)
index 0000000..f22bd7a
--- /dev/null
@@ -0,0 +1,293 @@
+#!/usr/bin/perl
+#
+###############################################################################
+#                                                                             #
+# IPFire.org - A linux based firewall                                         #
+# Copyright (C) 2017 Stephan Feddersen <addons@h-loit.de>                     #
+# All Rights Reserved.                                                        #
+#                                                                             #
+# 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 3 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, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+###############################################################################
+#
+# id: wioovpn.pl, v1.3.1 2017/07/11 21:31:16 sfeddersen
+#
+# This wioovpn.pl is based on the Code from the IPCop WIO Addon
+# and is extremly adapted to work with IPFire.
+#
+# Autor: Stephan Feddersen
+# Co-Autor: Alexander Marx
+# Co-Autor: Frank Mainz
+#
+
+# enable only the following on debugging purpose
+#use warnings;
+
+use strict;
+use POSIX qw(strftime);
+
+my $logdir = "/var/log/wio";
+
+require '/var/ipfire/general-functions.pl';
+require '/var/ipfire/lang.pl';
+require '/usr/lib/wio/wio-lib.pl';
+
+my %wiosettings = ();
+
+&General::readhash( "/var/ipfire/wio/wio.conf", \%wiosettings );
+
+my $mailremark = $wiosettings{'MAILREMARK'};
+my $logging    = $wiosettings{'LOGGING'};
+
+my ( @ovpnstatus, @ovpncfg, @ovpncache, @ovpnarray, @ovpnmatch, @ovpnwrite );
+
+my $now         = strftime "%a, %d.%m.%Y %H:%M:%S", localtime;
+my $ovpnpid     = "/var/run/openvpn.pid";
+my $ovpnmailmsg = '';
+my $ovpncache   = "$logdir/.ovpncache";
+my $ovpnconfig  = "/var/ipfire/ovpn/ovpnconfig";
+
+my ( $name, $nameul, $ovpnclt, $ovpncltip, $realipadr, $connected )  = '';
+my ( $ovpnmailsub, $ovpnrwlogin, $ovpnrwstatus, $status, $remark, $logmsg ) = '';
+
+my ( @vpnstatus, @vpncfg, @vpncache, @vpnarray, @vpnwrite );
+
+my $vpnpid       = "/var/run/charon.pid";
+my $vpnmailmsg   = '';
+my $vpncache     = "$logdir/.vpncache";
+my $vpnconfig    = "/var/ipfire/vpn/config";
+
+my ( $activ, $vpnmailsub, $vpnrwstatus, $status,)  = '';
+
+my $togglestat = 0;
+
+if ( ! -e "$ovpnpid" ) {
+       unlink "$ovpncache";
+}
+else {
+
+@ovpnstatus = `cat /var/run/ovpnserver.log`;
+
+open(FILE, "$ovpnconfig");
+@ovpncfg = <FILE>;
+close (FILE);
+
+unless ( -e "$ovpncache" ) {
+       open(FILE, ">$ovpncache");
+       close (FILE);
+}
+else {
+       open(FILE, "$ovpncache");
+       @ovpncache = <FILE>;
+       close (FILE);
+}
+
+foreach (@ovpncfg)
+{
+       chomp;
+
+       if ( $_ =~ "server" ) { next; }
+
+       ( $name, $remark ) = (split (/\,/, $_))[3, 26];
+
+       $status = 'off';
+
+       unless ( grep (/$name/, @ovpncache) ) { push (@ovpncache, "$name,$remark,$status\n"); }
+}
+
+foreach (@ovpncache)
+{
+       chomp;
+
+       ( $name, $remark, $status ) = split (/\,/, $_);
+
+       if ( grep (/,$name,/, @ovpncfg) ) { push (@ovpnarray, "$name,$remark,$status\n"); }
+}
+
+foreach (@ovpnarray)
+{
+       chomp;
+       ( $name, $remark, $status ) = split (/\,/, $_);
+
+       if ( $name =~ m/_/ ) { $nameul = $name; }
+       else { ($nameul = $name) =~ s/ /_/g; }
+
+       if ( grep (/$name/, @ovpnstatus) || grep (/$nameul/, @ovpnstatus) )
+       {
+               foreach (@ovpnstatus)
+               {
+                       chomp;
+
+                       if ( $_ =~ "ROUTING TABLE" ) { last; }
+
+                       @ovpnmatch = split (/\,/, $_);
+
+                       if ( @ovpnmatch != 5 || $_ =~ "Common Name" ) { next; }
+
+                       ( $ovpnclt, $realipadr, undef, undef, $connected ) = @ovpnmatch;
+
+                       ( $ovpncltip, undef ) = split (/:/, $realipadr);
+
+                       $ovpnrwlogin  = &WIO::statustime($connected);
+
+                       if ( $nameul eq $ovpnclt || $name eq $ovpnclt ) {
+                               $ovpnrwstatus = "$Lang::tr{'wio up'}";
+                               $togglestat   = ( $status ne 'on' ) ? 1 : 0;
+                               $status       = 'on';
+                       }
+
+                       if ( ! $name =~ m/_/ ) { $ovpnclt =~ s/_/ /g; }
+
+                       if ( $nameul eq $ovpnclt || $name eq $ovpnclt ) { push (@ovpnwrite, "$name,$remark,$status\n"); }
+
+                       if ( $togglestat == 1 && ($name eq $ovpnclt || $nameul eq $ovpnclt) )
+                       {
+                               $ovpnmailsub = "WIO OVPN - $name - $ovpnrwstatus - $now";
+                               $logmsg = "Client: WIO OVPN $name - IP: $ovpncltip - Status: $ovpnrwstatus";
+                               $ovpnmailmsg = "Client : $name\nLogin  : $ovpnrwlogin\nIP     : $ovpncltip\nStatus : $ovpnrwstatus\n";
+
+                               if ( $mailremark eq 'on' ) {
+                                       $ovpnmailmsg .= "Remark : $remark\n\n";
+                               }
+
+                               &WIO::mailsender($ovpnmailsub, $ovpnmailmsg);
+                               if ( $logging eq 'on' ) { &General::log("wio","$logmsg"); }
+                               undef ($ovpnmailsub);
+                               undef ($ovpnmailmsg);
+                               $togglestat = 0;
+                       }
+               }
+       }
+       else {
+               if ( $status eq 'on' ) {
+                       $ovpnrwstatus = "$Lang::tr{'wio down'}";
+                       $status = 'off';
+                       $ovpnmailsub  = "WIO OVPN - $name - $ovpnrwstatus - $now";
+                       $logmsg = "Client: WIO OVPN $name - Status: $ovpnrwstatus";
+                       $ovpnmailmsg = "Client : $name\nLogout : $now\nStatus : $ovpnrwstatus\n";
+
+                       if ( $mailremark eq 'on' ) {
+                               $ovpnmailmsg .= "Remark : $remark\n\n";
+                       }
+
+                       &WIO::mailsender($ovpnmailsub, $ovpnmailmsg);
+                       if ( $logging eq 'on' ) { &General::log("wio","$logmsg"); }
+                       undef ($ovpnmailsub);
+                       undef ($ovpnmailmsg);
+               }
+
+               push (@ovpnwrite, "$name,$remark,$status\n");
+       }
+}
+
+open( FILE, "> $ovpncache" );
+print FILE @ovpnwrite;
+close(FILE);
+
+}
+
+if ( ! -e "$vpnpid" ) {
+       unlink "$vpncache";
+}
+else {
+
+if ( -e "$vpnpid" ) {
+       @vpnstatus = `/usr/local/bin/ipsecctrl I`;
+}
+
+open(FILE, "$vpnconfig");
+@vpncfg = <FILE>;
+close (FILE);
+
+if ( ! -e "$vpncache" ) {
+       open(FILE, ">$vpncache");
+       close (FILE);
+}
+else {
+       open(FILE, "$vpncache");
+       @vpncache = <FILE>;
+       close (FILE);
+}
+
+foreach (@vpncfg)
+{
+       chomp;
+
+       ( $activ, $name, $remark ) = (split (/\,/, $_))[1, 2, 25];
+
+       if ( $remark eq 'off' ) { $remark = '-'; }
+
+       $status = 'off';
+
+       if ( $activ eq "off" ) { next; }
+
+       unless ( grep (/$name/, @vpncache) ) { push (@vpncache, "$name,$remark,$status\n"); }
+}
+
+foreach (@vpncache)
+{
+       chomp;
+
+       ( $name, $remark, $status ) = split (/\,/, $_);
+       
+       if ( grep (/,$name,/, @vpncfg) ) { push (@vpnarray, "$name,$remark,$status\n"); }
+}
+
+foreach (@vpnarray)
+{
+       chomp;
+       
+       ( $name, $remark, $status ) = split (/\,/, $_);
+
+       if ( grep (/$name\{.*INSTALLED/ , @vpnstatus) )
+       {
+               $vpnrwstatus = "$Lang::tr{'wio up'}";
+               $togglestat   = ( $status ne 'on' ) ? 1 : 0;
+               $status       = 'on';
+       }
+       else {
+               $vpnrwstatus = "$Lang::tr{'wio down'}";
+               $togglestat   = ( $status ne 'off' ) ? 1 : 0;
+               $status       = 'off';
+       }
+
+       push (@vpnwrite, "$name,$remark,$status\n");
+
+       if ( $togglestat == 1 )
+       {
+               $vpnmailsub  = "WIO VPN - $name - $vpnrwstatus - $now";
+               $logmsg = "Client: WIO VPN $name - Status: $vpnrwstatus $now";
+
+               if ( $mailremark eq 'on' ) {
+                       if ( $status eq 'on' ) { $vpnmailmsg = "Client : $name\nLogin  : $now\nStatus : $vpnrwstatus\nRemark : $remark\n"; }
+                       else { $vpnmailmsg = "Client : $name\nLogout : $now\nStatus : $vpnrwstatus\nRemark : $remark\n"; }
+               }
+               else {
+                       if ( $status eq 'on' ) { $vpnmailmsg = "Client : $name\nLogin  : $now\nStatus : $vpnrwstatus\n"; }
+                       else { $vpnmailmsg = "Client : $name\nLogout : $now\nStatus : $vpnrwstatus\n"; }
+               }
+
+               &WIO::mailsender($vpnmailsub, $vpnmailmsg);
+               if ( $logging eq 'on' ) { &General::log("wio","$logmsg"); }
+               undef ($vpnmailsub);
+               undef ($vpnmailmsg);
+               $togglestat = 0;
+       }
+}
+
+open( FILE, "> $vpncache" );
+print FILE @vpnwrite;
+close(FILE);
+
+}
diff --git a/src/wio/wio b/src/wio/wio
new file mode 100644 (file)
index 0000000..dea5e57
--- /dev/null
@@ -0,0 +1,24 @@
+#!/bin/bash
+#
+# Script to run wio helpers
+#
+. /var/ipfire/wio/wio.conf
+
+MINUTE=`date +%M`
+
+if [ $ENABLE == on ]; then
+
+       if [ $(($MINUTE%$CRON)) == 0 ]; then
+               /var/ipfire/wio/wio.pl > /dev/null
+       fi
+
+       if [ $OVPNRWMAIL == on ]; then
+               if [ $(($MINUTE%$OVPNCRON)) == 0 ]; then
+                       /var/ipfire/wio/wiovpn.pl > /dev/null
+               fi
+       else
+               rm -f /var/log/wio/.vpncache
+               rm -f /var/log/wio/.ovpncache
+       fi
+
+fi
diff --git a/src/wio/wio-graphs.pl b/src/wio/wio-graphs.pl
new file mode 100644 (file)
index 0000000..a5a58b4
--- /dev/null
@@ -0,0 +1,127 @@
+#!/usr/bin/perl
+#
+###############################################################################
+#                                                                             #
+# IPFire.org - A linux based firewall                                         #
+# Copyright (C) 2017 Stephan Feddersen <addons@h-loit.de>                     #
+# All Rights Reserved.                                                        #
+#                                                                             #
+# 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 3 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, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+###############################################################################
+#
+# id: wio-graphs.pl, v1.3.1 2017/07/11 21:31:16 sfeddersen
+#
+# This wio-graphs.pl is based on the Code from the IPCop WIO Addon
+# and is extremly adapted to work with IPFire.
+#
+# Autor: Stephan Feddersen
+# Co-Autor: Alexander Marx
+#
+
+package WIOGraphs;
+
+use strict;
+
+# enable only the following on debugging purpose
+#use warnings;
+
+use RRDs;
+
+require '/var/ipfire/general-functions.pl';
+require '/var/ipfire/lang.pl';
+
+my ( %mainsettings, %color ) = ();
+
+&General::readhash('/var/ipfire/main/settings', \%mainsettings);
+&General::readhash("/srv/web/ipfire/html/themes/".$mainsettings{'THEME'}."/include/colors.txt", \%color);
+
+sub wio {
+       my $hostid   = $_[0];
+       my $hostname = $_[1];
+       my $period   = $_[2];
+
+       my @rrd = ();
+
+       push @rrd, ("-");
+       push @rrd, @{&header($period, "$hostname ($Lang::tr{$period})")};
+       push @rrd, @{&body($hostid)};
+
+       RRDs::graph (@rrd);
+
+       my $error = RRDs::error;
+       print "Error in RRD::graph for Who Is Online: $error\n" if $error;
+}
+
+sub body {
+       my $hostid = shift;
+       my $result = [];
+
+       push @$result, "DEF:mode=/var/log/rrd/wio/$hostid.rrd:mode:AVERAGE";
+       push @$result, "CDEF:online=mode,UN,0,mode,IF,50,GT,100,0,IF";
+       push @$result, "CDEF:offline=mode,UN,100,mode,IF,50,LT,100,0,IF";
+       push @$result, "AREA:online".$color{"color12"}.":$Lang::tr{'wio up'}\\j";
+       push @$result, "AREA:offline".$color{"color13"}.":$Lang::tr{'wio down'}\\j";
+       push @$result, "COMMENT:\r<span size='smaller'>$Lang::tr{'wio_last_update'}\\: ". lastupdate(scalar localtime()) ."</span>\\r";
+
+       return $result;
+}
+
+sub lastupdate {
+    my $text = shift;
+
+    return undef if not defined $text;
+    $text =~ s/\\/\\\\/g;
+    $text =~ s/:/\\:/g;
+
+    return $text;
+}
+
+sub header {
+       my $period = shift;
+       my $title  = shift;
+       my $result = [];
+
+       push @$result, ("--title", "$title");
+       push @$result, ("--start", "-1$period", "-aPNG", "-i", "-z");
+       push @$result, ("--border", "0");
+       push @$result, ("--full-size-mode");
+       push @$result, ("--slope-mode");
+       push @$result, ("--pango-markup");
+       push @$result, ("--alt-y-grid", "-w 910", "-h 300");
+       if ( $period eq 'day' ) { push @$result, ("--x-grid", "MINUTE:30:HOUR:1:HOUR:2:0:%H:%M"); }
+       push @$result, ("--color", "SHADEA".$color{"color19"});
+       push @$result, ("--color", "SHADEB".$color{"color19"});
+       push @$result, ("--color", "BACK".$color{"color21"});
+
+       return $result;
+}
+
+sub wiographbox {
+       print "<center>";
+       print "<table width='100%' cellspacing='0'>";
+       print "<tr>";
+       print "<td align='center' bgcolor='".$color{"color20"}."'><a href='".$_[0]."?".$_[1]."?hour?".$_[3]."' target='".$_[1]."box'><b>".$Lang::tr{'hour'}."</b></a></td>";
+       print "<td align='center' bgcolor='".$color{"color20"}."'><a href='".$_[0]."?".$_[1]."?day?".$_[3]."' target='".$_[1]."box'><b>".$Lang::tr{'day'}."</b></a></td>";
+       print "<td align='center' bgcolor='".$color{"color20"}."'><a href='".$_[0]."?".$_[1]."?week?".$_[3]."' target='".$_[1]."box'><b>".$Lang::tr{'week'}."</b></a></td>";
+       print "<td align='center' bgcolor='".$color{"color20"}."'><a href='".$_[0]."?".$_[1]."?month?".$_[3]."' target='".$_[1]."box'><b>".$Lang::tr{'month'}."</b></a></td>";
+       print "<td align='center' bgcolor='".$color{"color20"}."'><a href='".$_[0]."?".$_[1]."?year?".$_[3]."' target='".$_[1]."box'><b>".$Lang::tr{'year'}."</b></a></td>";
+       print "</tr>";
+       print "</table>";
+       print "<table width='100%' cellspacing='0'>";
+       print "<tr><td align='center' colspan='8'>&nbsp;</td></tr>";
+       print "<tr><td align='center' colspan='8'><iframe class='graph' src='".$_[0]."?".$_[1]."?".$_[2]."?".$_[3]."' scrolling='no' marginheight='0' frameborder='no' name='".$_[1]."box'></iframe></td></tr>";
+       print "</table>";
+       print "</center>";
+}
diff --git a/src/wio/wio-lib.pl b/src/wio/wio-lib.pl
new file mode 100644 (file)
index 0000000..2f23c1d
--- /dev/null
@@ -0,0 +1,206 @@
+#!/usr/bin/perl
+#
+###############################################################################
+#                                                                             #
+# IPFire.org - A linux based firewall                                         #
+# Copyright (C) 2017 Stephan Feddersen <addons@h-loit.de>                     #
+# All Rights Reserved.                                                        #
+#                                                                             #
+# 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 3 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, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+###############################################################################
+#
+# id: wio-lib.pl, v1.3.1 2017/07/11 21:31:16 sfeddersen
+#
+# This wio-lib.pl is based on the Code from the IPCop WIO Addon
+# and is extremly adapted to work with IPFire.
+#
+# Autor: Stephan Feddersen
+# Co-Autor: Alexander Marx
+# Co-Autor: Frank Mainz
+#
+
+package WIO;
+
+# enable only the following on debugging purpose
+#use warnings;
+
+use strict;
+use Socket;
+use Time::Local;
+use MIME::Lite;
+
+require '/var/ipfire/general-functions.pl';
+require '/var/ipfire/header.pl';
+require '/var/ipfire/lang.pl';
+
+my $mailfile = "${General::swroot}/dma/mail.conf";
+my %mail = ();
+&General::readhash($mailfile, \%mail);
+
+my $redactive = "/var/ipfire/red/active";
+my $msg = '';
+
+############################################################################################################################
+
+sub getdyndnsip {
+       my $ipadr = $_[0];
+       my $host = $_[1];
+       my @fetchip = ();
+
+       if ( -e $redactive ) {
+               @fetchip = gethostbyname($host);
+
+               if ( defined($fetchip[0]) ) {
+                       @fetchip = map ( &Socket::inet_ntoa($_), @fetchip[4..$#fetchip]);
+                       return ($fetchip[0], $Lang::tr{'wio_dyndns_success'});
+               }
+       }
+       else {
+               return ($ipadr, $Lang::tr{'wio_dyndns_info'});
+       }
+}
+
+############################################################################################################################
+
+sub contime {
+       my $str = $_[0];
+       my %m = ();
+       @m{qw/Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec/} = (0 .. 11);
+
+       if ( $str =~ /^\w{3}\ ([a-zA-Z]+)\ (\d{1,2})\ (\d{2})\:(\d{2})\:(\d{2}) (\d{4})$/ ||
+                $str =~ /^\w{3}\ ([a-zA-Z]+)\  (\d{1})\ (\d{2})\:(\d{2})\:(\d{2}) (\d{4})$/ ) 
+       {
+               my $past = timelocal($5, $4, $3, $2, $m{$1}, $6);
+               my $now  = time;
+
+               my $totalsecs = $now - $past;
+               my $days = int($totalsecs / 86400);
+               my $totalhours = int($totalsecs / 3600);
+               my $hours = $totalhours % 24;
+               my $totalmins = int($totalsecs / 60);
+               my $mins = $totalmins % 60;
+               my $secs = $totalsecs % 60;
+
+               return "${days}d ${hours}h ${mins}m ${secs}s";
+       }
+       else {
+               return;
+       }
+}
+
+############################################################################################################################
+
+sub statustime {
+       my $str = $_[0];
+       my ( $day, $mon ) = '';
+
+       my %m = qw ( Jan 01 Feb 02 Mar 03 Apr 04 May 05 Jun 06 Jul 07 Aug 08 Sep 09 Oct 10 Nov 11 Dec 12 );
+
+       if ( $str =~ /^\w{3}\ ([a-zA-Z]+)\ (\d{1,2})\ (\d{2})\:(\d{2})\:(\d{2}) (\d{4})$/ ||
+                $str =~ /^\w{3}\ ([a-zA-Z]+)\  (\d{1})\ (\d{2})\:(\d{2})\:(\d{2}) (\d{4})$/ )
+       {
+               $mon = $m{$1};
+
+               if (length $2 < 2) { $day = "0$2"; }
+               else { $day = $2; }
+
+               return "$day.$mon.$6 - $3:$4:$5";
+       }
+       else {
+               return;
+       }
+}
+
+############################################################################################################################
+
+sub mailsender {
+       $msg = MIME::Lite->new(
+               From    => $mail{'SENDER'},
+               To              => $mail{'RECIPIENT'},
+               Subject => $_[0],
+               Type    => 'multipart/mixed'
+       );
+
+       $msg->attach(
+               Type    => 'TEXT',
+               Data    => $_[1]
+       );
+
+       $msg->send_by_sendmail;
+}
+
+############################################################################################################################
+
+sub checkinto {
+       my ($checkip, $checkhost, @checkfile) = @_;
+
+       if ( $checkip ne '' ) {
+               foreach (@checkfile) {
+                       chomp;
+                       if ( (split (/\,/, $_))[2] eq $checkip ) { return $Lang::tr{'wio_ip_exists'}; last; }
+               }
+       }
+
+       if ( $checkhost ne '' ) {
+               foreach (@checkfile) {
+                       chomp;
+                       if ( (split (/\,/, $_))[3] eq $checkhost ) {
+                               if ( $checkip ne '' ) {
+                                       my $fileip = (split (/\,/, $_))[2];
+
+                                       $fileip =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/;
+
+                                       my $fileip1 = $1;
+                                       my $fileip2 = $2;
+                                       my $fileip3 = $3;
+                                       my $fileip4 = $4;
+                                       
+                                       $checkip =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/;
+
+                                       if ( $fileip1 == $1 && $fileip2 == $2 && $fileip3 == $3 ) {
+                                               return $Lang::tr{'wio_host_exists'}; last; }
+                               }
+                               else { return $Lang::tr{'wio_host_exists'}; last; }
+                       }
+               }
+       }
+
+       return;
+}
+
+############################################################################################################################
+
+sub clearfile {
+       my $file = $_[0];
+
+       open(FILE, "> $file");
+       close(FILE);
+}
+
+############################################################################################################################
+
+sub color_devices() {
+       my $output = shift;
+
+       if ( uc($output) eq "GREEN0" ) { $output = "<b><font color ='$Header::colourgreen'>$output</b>";}
+       elsif ( uc($output) eq "BLUE0" ) { $output = "<b><font color ='$Header::colourblue'>$output</b>"; }
+       elsif ( uc($output) eq "ORANGE0" ) { $output = "<b><font color ='$Header::colourorange'>$output</b>"; }
+       elsif ( uc($output) eq "RED0" ) { $output = "<b><font color ='$Header::colourred'>$output</b>"; }
+       else { return $output = "<b><font color ='#696565'>$output</b>"; }
+
+       return $output;
+}
+
+return 1;
diff --git a/src/wio/wio.cgi b/src/wio/wio.cgi
new file mode 100644 (file)
index 0000000..e7bf7e2
--- /dev/null
@@ -0,0 +1,2143 @@
+#!/usr/bin/perl
+#
+###############################################################################
+#                                                                             #
+# IPFire.org - A linux based firewall                                         #
+# Copyright (C) 2017 Stephan Feddersen <addons@h-loit.de>                     #
+# All Rights Reserved.                                                        #
+#                                                                             #
+# 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 3 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, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+###############################################################################
+#
+# id: wio.cgi, v1.3.1 2017/07/11 21:31:16 sfeddersen
+#
+# This wio.cgi is based on the Code from the IPCop WIO Addon
+# and is extremly adapted to work with IPFire.
+#
+# Autor: Stephan Feddersen
+# Co-Autor: Alexander Marx
+# Co-Autor: Frank Mainz
+#
+
+use strict;
+
+# enable only the following on debugging purpose
+#use warnings;
+#no warnings 'once';
+#use CGI::Carp 'fatalsToBrowser';
+
+my $debug = 0;
+
+use Socket;
+use POSIX qw(strftime);
+use File::Copy;
+use Fatal qw/ open /;
+use Net::Telnet;
+
+require '/var/ipfire/general-functions.pl';
+require '/var/ipfire/lang.pl';
+require '/var/ipfire/header.pl';
+require '/usr/lib/wio/wio-lib.pl';
+require '/usr/lib/wio/wio-graphs.pl';
+
+my $logdir = "/var/log/wio";
+
+my ( %mainsettings, %mailsettings, %wiosettings, %cgiparams, %netsettings, %ipshash,
+        %vpnconfighash, %ovpnconfighash, %ovpnccdconfhash, %ovpnsettings, %checked, %selected, %color ) = ();
+
+&General::readhash('/var/ipfire/main/settings', \%mainsettings);
+&General::readhash('/var/ipfire/ethernet/settings', \%netsettings);
+&General::readhash('/var/ipfire/dma/mail.conf', \%mailsettings);
+&General::readhash('/var/ipfire/wio/wio.conf', \%wiosettings);
+&General::readhash("/srv/web/ipfire/html/themes/".$mainsettings{'THEME'}."/include/colors.txt", \%color);
+&General::readhasharray('/var/ipfire/ovpn/ovpnconfig', \%ovpnconfighash);
+&General::readhash('/var/ipfire/ovpn/settings', \%ovpnsettings);
+&General::readhasharray('/var/ipfire/ovpn/ccd.conf', \%ovpnccdconfhash);
+&General::readhasharray('/var/ipfire/vpn/config', \%vpnconfighash);
+
+my $ipadrfile    = "$logdir/wioips";
+my $onoffip      = "$logdir/wioscip";
+my $wiosettings  = "/var/ipfire/wio/wio.conf";
+my $dyndnsconfig = "/var/ipfire/ddns/config";
+my $importfile   = "$logdir/importfile";
+my $wiofile      = "$logdir/wiofile";
+my $editfile     = "$logdir/editfile";
+my $hostfile     = "/var/ipfire/main/hosts";
+my $dhcpfile     = "/var/ipfire/dhcp/fixleases";
+my $imgstatic    = "/images/wio";
+my $rrddir       = "/var/log/rrd/wio";
+my $refreshbox   = '<meta http-equiv="refresh" content="0;url=/cgi-bin/wio.cgi">';
+my $sortstring   = '^IPADR|^HOST';
+my $ovpnaddon    = "/var/ipfire/ovpn";
+my $ovpnpid      = "/var/run/openvpn.pid";
+my $vpnpid       = "/var/run/charon.pid";
+my $redactive    = "/var/ipfire/red/active";
+my $redip        = '-';
+my $now          = strftime "%Y-%m-%d", localtime;
+
+if ( -e $redactive ) {
+       open(IPADDR, "/var/ipfire/red/local-ipaddress");
+       $redip = <IPADDR>;
+       close IPADDR;
+       chomp($redip);
+}
+
+my $i = 0;
+my $idarp = 0;
+my $iddyndns = 0;
+my $idvpn = 0;
+my $idovpn = 0;
+my $idsort = 0;
+my $nr = 0;
+my $count = 0;
+my $showcount = 0;
+
+my ( $infomessage, $errormessage, $importmessage, $message ) = '';
+
+my ( $buttontext, $host, $timestamp, $ipadr, $on, $remark, $dyndns, $dyndnsip, $sendemailon, $net, $dev, $iprange, $output, $write, $webinterface,
+        $sendemailoff, $pingmethode, $online, $color, $bgcolor, $exitcode, $id, $line, $interface, $counter, $vpnn2nip, $vpnn2nmask, $ddns, $edc,
+        $edd, $wmon, $wmoff, $ipfqdn, $http, $wioscan, $statustxt, $status, $key, $ic, $text, $image ) = (); 
+
+my ( @temp, @dates, @ipaddresses, @names, @remark, @sendemailon, @sendemailoff, @current, @ddns, @match, @webinterface, @arpcache, @arpadd, @line,
+        @hosts, @vpnstatus, @ovpnstatus, @activ, @dyndns, @pingmethode, @status, @id, @write, @log );
+
+my @nosaved = ('ACTION','ID','CLIENTID','TIMESTAMP','IPADR','HOST','REMARK','DYNDNS','SENDEMAILON','SENDEMAILOFF','PINGMETHODE','ONLINE','WEBINTERFACE');
+
+my @devs_color = ('GREEN','BLUE','ORANGE','RED');
+my @devs_net   = ('green0','blue0','orange0','red0');
+my @devs_img   = ('green.png','blue.png','orange.png','red.png');
+my @devs_alt   = ('green','blue','orange','red');
+
+my %ifacecolor = ( GREEN => 'wio_run_green', BLUE => 'wio_run_blue', ORANGE => 'wio_run_orange');
+
+&loadips();
+
+## some wio settings
+
+$wiosettings{'ACTION'} = '';
+$wiosettings{'COUNT'} = '';
+$wiosettings{'ID'} = '';
+$wiosettings{'CLIENTID'} = '';
+$wiosettings{'SORT'} = 'IPADR';
+$wiosettings{'HOST'} = '';
+$wiosettings{'IPADR'} = '';
+$wiosettings{'EN'} = 'on';
+$wiosettings{'REMARK'} = '';
+$wiosettings{'DYNDNS'} = '';
+$wiosettings{'CLIENTREMARK'} = '';
+$wiosettings{'SENDEMAILON'} = '';
+$wiosettings{'SENDEMAILOFF'} = '';
+$wiosettings{'PINGMETHODE'} = 'ip';
+$wiosettings{'WEBINTERFACE'} = '----';
+$wiosettings{'TIMEOUT'} = '1';
+$wiosettings{'TIMESTAMP'} = '';
+$wiosettings{'ONLINE'} = 'off';
+$wiosettings{'CRON'} = '15';
+$wiosettings{'OVPNCRON'} = '5';
+$wiosettings{'ENABLE'} = 'off';
+$wiosettings{'LOGGING'} = 'off';
+$wiosettings{'MAILREMARK'} = 'off';
+$wiosettings{'MAILSTYLE'} = 'email';
+$wiosettings{'OVPNRWMAIL'} = 'off';
+$wiosettings{'SHUTDOWN'} = 'off';
+
+&Header::getcgihash(\%wiosettings);
+&Header::getcgihash(\%mainsettings);
+&Header::getcgihash(\%mailsettings);
+&Header::getcgihash(\%netsettings);
+
+if ( $mailsettings{'USEMAIL'} eq 'on' ) { $wiosettings{'SENDEMAIL'} = 'on'; }
+else { $wiosettings{'SENDEMAIL'} = 'off'; }
+
+if ( -e $wiofile ) { goto WIOSCAN; }
+
+## get network ips
+foreach (@devs_color) {
+       if ( $netsettings{"${_}_DEV"} ne '' ) {
+
+               $wiosettings{"${_}_IPLOW"} = inet_ntoa pack q/N/, (unpack (q/N/, inet_aton ($netsettings{"${_}_NETADDRESS"}))+1);
+               my @addrarr = split(/\./,$netsettings{"${_}_ADDRESS"});
+               my $ipaddress = unpack( "N", pack( "C4",@addrarr ) );
+
+               my @maskarr = split(/\./,$netsettings{"${_}_NETMASK"});
+               my $netmask = unpack( "N", pack( "C4",@maskarr ) );
+
+               my $bcast = ( $ipaddress & $netmask ) + ( ~ $netmask );
+               my @bcastarr = inet_ntoa pack q/N/, (unpack (q/N/, inet_aton ($bcast))-1);
+
+               $wiosettings{"${_}_IPHIGH"} = join(".",@bcastarr);
+       }
+}
+
+## save wio settings
+
+if ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_save'}.'1' ) {
+       unless ( `ps -A | grep wio.pl` ) {
+               $cgiparams{'SORT'} = $wiosettings{'SORT'};
+               $cgiparams{'CRON'} = $wiosettings{'CRON'};
+               $cgiparams{'OVPNCRON'} = $wiosettings{'OVPNCRON'};
+               $cgiparams{'ENABLE'} = $wiosettings{'ENABLE'};
+               $cgiparams{'LOGGING'} = $wiosettings{'LOGGING'};
+               $cgiparams{'TIMEOUT'} = $wiosettings{'TIMEOUT'};
+               $cgiparams{'ACTION'} = $wiosettings{'ACTION'};
+               $cgiparams{'CLIENTREMARK'} = $wiosettings{'CLIENTREMARK'};
+               $cgiparams{'MAILREMARK'} = $wiosettings{'MAILREMARK'};
+               $cgiparams{'MAILSTYLE'} = $wiosettings{'MAILSTYLE'};
+               $cgiparams{'OVPNRWMAIL'} = $wiosettings{'OVPNRWMAIL'};
+               $cgiparams{'SHUTDOWN'} = $wiosettings{'SHUTDOWN'};
+
+               &General::writehash($wiosettings, \%cgiparams);
+               &General::readhash($wiosettings, \%wiosettings);
+
+               if ( $wiosettings{'ENABLE'} eq 'off' ) {
+                       &WIO::clearfile($ipadrfile);
+                       unlink glob "$rrddir/*";
+               }
+       }
+       else {
+               $infomessage = "$Lang::tr{'wio_error_function'}";
+       }
+}
+
+## save imported clients
+
+if ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_save'}.'2' ) {
+       unless ( `ps -A | grep wio.pl` ) {
+               while ( $count < $wiosettings{'COUNT'} ) {
+                       if ( defined($wiosettings{"USE$count"}) && $wiosettings{"USE$count"} eq 'on' ) {
+                               $wiosettings{'CLIENTID'} = $wiosettings{'CLIENTID$count'};
+                               $wiosettings{'TIMESTAMP'} = $wiosettings{"TIMESTAMP$count"};
+                               $wiosettings{'IPADR'} = $wiosettings{"IPADR$count"};
+                               $wiosettings{'HOST'} = $wiosettings{"HOST$count"};
+                               $wiosettings{'EN'} = $wiosettings{"EN$count"};
+                               $wiosettings{'REMARK'} = $wiosettings{"REMARK$count"};
+                               $wiosettings{'DYNDNS'} = $wiosettings{"DYNDNS$count"};
+                               $wiosettings{'SENDEMAILON'} = $wiosettings{"SENDEMAILON$count"};
+                               $wiosettings{'SENDEMAILOFF'} = $wiosettings{"SENDEMAILOFF$count"};
+                               $wiosettings{'PINGMETHODE'} = $wiosettings{"PINGMETHODE$count"};
+                               $wiosettings{'ONLINE'} = $wiosettings{"ONLINE$count"};
+                               $wiosettings{'WEBINTERFACE'} = $wiosettings{"WEBINTERFACE$count"};
+
+                               &validSave();
+
+                               if ($errormessage) {
+                                       open(FILE, ">> $editfile");
+                                       print FILE "$wiosettings{'CLIENTID'},$wiosettings{'TIMESTAMP'},$wiosettings{'IPADR'},$wiosettings{'HOST'},$wiosettings{'EN'},$wiosettings{'REMARK'},$wiosettings{'DYNDNS'},$wiosettings{'SENDEMAILON'},$wiosettings{'SENDEMAILOFF'},$wiosettings{'PINGMETHODE'},$wiosettings{'ONLINE'},$wiosettings{'WEBINTERFACE'}\n";
+                                       close(FILE);
+                                       $importmessage = $errormessage;
+                               }
+                               else {
+                                       $wiosettings{'CLIENTID'} = &General::findhasharraykey (\%ipshash);
+                                       unshift (@current, "$wiosettings{'CLIENTID'},$wiosettings{'TIMESTAMP'},$wiosettings{'IPADR'},$wiosettings{'HOST'},$wiosettings{'EN'},$wiosettings{'REMARK'},$wiosettings{'DYNDNS'},$wiosettings{'SENDEMAILON'},$wiosettings{'SENDEMAILOFF'},$wiosettings{'PINGMETHODE'},$wiosettings{'ONLINE'},$wiosettings{'WEBINTERFACE'}\n");
+                                       &SortDataFile('',@current);
+                               }
+                       }
+                       $count++;
+               }
+
+               map ($wiosettings{$_} = '' ,@nosaved);
+               unlink ($importfile);
+               if ( -e "$editfile" ) { goto EDIT; }
+       }
+       else {
+               $infomessage = "$Lang::tr{'wio_error_function'}";
+       }
+}
+
+## add or update client
+
+if ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_client_add'} ) {
+       unless ( `ps -A | grep wio.pl` ) {
+               &validSave();
+
+               unless ($errormessage) {
+                       if ( $wiosettings{'ID'} eq '' && $wiosettings{'ACTION'} ne $Lang::tr{'edit'} ) {
+                               $wiosettings{'CLIENTID'} = &General::findhasharraykey (\%ipshash);
+                               unshift (@current, "$wiosettings{'CLIENTID'},$wiosettings{'TIMESTAMP'},$wiosettings{'IPADR'},$wiosettings{'HOST'},$wiosettings{'EN'},$wiosettings{'REMARK'},$wiosettings{'DYNDNS'},$wiosettings{'SENDEMAILON'},$wiosettings{'SENDEMAILOFF'},$wiosettings{'PINGMETHODE'},$wiosettings{'ONLINE'},$wiosettings{'WEBINTERFACE'}\n");
+                       }
+                       else {
+                               @current[$wiosettings{'ID'}] = "$wiosettings{'CLIENTID'},$wiosettings{'TIMESTAMP'},$wiosettings{'IPADR'},$wiosettings{'HOST'},$wiosettings{'EN'},$wiosettings{'REMARK'},$wiosettings{'DYNDNS'},$wiosettings{'SENDEMAILON'},$wiosettings{'SENDEMAILOFF'},$wiosettings{'PINGMETHODE'},$wiosettings{'ONLINE'},$wiosettings{'WEBINTERFACE'}\n";
+                       }
+               }
+               else { goto ERROR; }
+
+               map ($wiosettings{$_} = '' ,@nosaved);
+               &SortDataFile('',@current);
+       }
+       else {
+               $infomessage = "$Lang::tr{'wio_error_function'}";
+       }
+}
+
+## add arp client
+
+if ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_add'} ) {
+       unless ( `ps -A | grep wio.pl` ) {
+               open(FILE, "$logdir/.arpcache");
+               @arpadd = <FILE>;
+               close (FILE);
+
+               chomp(@arpadd[$wiosettings{'ID'}]);
+               @temp = split (/\,/, @arpadd[$wiosettings{'ID'}]);
+
+               $wiosettings{'CLIENTID'} = &General::findhasharraykey (\%ipshash);
+               $wiosettings{'IPADR'} = $temp[1];
+               $wiosettings{'HOST'} = $temp[2];
+               $wiosettings{'EN'} = 'on';
+
+               $wiosettings{'PINGMETHODE'} = 'ip';
+               $wiosettings{'ONLINE'} = 'off';
+
+               open(FILE, ">> $editfile");
+               print FILE "$wiosettings{'CLIENTID'},$wiosettings{'TIMESTAMP'},$wiosettings{'IPADR'},$wiosettings{'HOST'},$wiosettings{'EN'},$wiosettings{'REMARK'},$wiosettings{'DYNDNS'},$wiosettings{'SENDEMAILON'},$wiosettings{'SENDEMAILOFF'},$wiosettings{'PINGMETHODE'},$wiosettings{'ONLINE'},$wiosettings{'WEBINTERFACE'}\n";
+               close(FILE);
+
+               goto EDIT;
+       }
+       else {
+               undef($wiosettings{'ID'});
+               $infomessage = "$Lang::tr{'wio_error_function'}";
+       }
+}
+
+## enable / disabel client || enable / disable dyndns || enable / disable sendemailon || enable / disable sendemailoff || change ip / fqdn
+
+if ( $wiosettings{'ACTION'} eq $Lang::tr{'enable disable client'} ) { $edc = 'on'; }
+if ( $wiosettings{'ACTION'} eq $Lang::tr{'enable disable dyndns'} ) { $edd = 'on'; }
+if ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_mail_online'} ) { $wmon = 'on'; }
+if ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_mail_offline'} ) { $wmoff = 'on'; }
+if (( $wiosettings{'ACTION'} eq $Lang::tr{'wio_ip_on'} ) || ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_fqdn_on'} )) { $ipfqdn = 'on'; }
+
+if ( defined($edc) || defined($edd) || defined($wmon) || defined($wmoff) || defined($ipfqdn) ) {
+       unless ( `ps -A | grep wio.pl` ) {
+               chomp(@current[$wiosettings{'ID'}]);
+               @temp = split (/\,/, @current[$wiosettings{'ID'}]);
+
+               if ( $edc eq 'on' ) {
+                       $temp[4] = $temp[4] ne '' ? '' : 'on';
+                       $temp[10] = '';
+                       $temp[11] = '';
+                       $temp[1] = '';
+                       unlink "$rrddir/$temp[0].rrd";
+               }
+               elsif ( $edd eq 'on' ) { $temp[6] = $temp[6] ne '' ? '' : 'on'; }
+               elsif ( $wmon eq 'on' ) { $temp[7] = $temp[7] ne '' ? '' : 'on'; }
+               elsif ( $wmoff eq 'on' ) { $temp[8] = $temp[8] ne '' ? '' : 'on'; }
+               elsif ( $ipfqdn eq 'on' ) { $temp[9] = $temp[9] eq 'fqdn' ? 'ip' : 'fqdn'; }
+
+               @current[$wiosettings{'ID'}] = join (',', @temp)."\n";
+               undef($wiosettings{'ID'});
+
+               &writeips();
+       }
+       else {
+               undef($wiosettings{'ID'});
+               $infomessage = "$Lang::tr{'wio_error_function'}";
+       }
+}
+
+## refresh wio status || refresh single client status
+
+if ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_refresh'} || $wiosettings{'ACTION'} eq $Lang::tr{'wio_sc_refresh'} ) {
+
+       if ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_sc_refresh'} ) {
+               open(FILE, "> $onoffip");
+               print FILE @current[$wiosettings{'ID'}];
+               close(FILE);
+
+               undef($wiosettings{'ID'});
+       }
+
+unless ( `ps -A | grep wio.pl` ) {
+
+&Header::showhttpheaders();
+&Header::openpage($Lang::tr{'wio'}, 1, $refreshbox);
+&Header::openbigbox('100%', 'left', '');
+&Header::openbox('100%', 'left', $Lang::tr{'wio_info'});
+
+print"
+<table align='center' width='100%'>
+       <tr><td align='center'>$Lang::tr{'wio_msg'}</td></tr>
+       <tr><td>&nbsp;</td></tr>
+       <tr><td align='center'><img align='middle' src='/images/indicator.gif' /></td></tr>
+</table>
+";
+
+&Header::closebox();
+&Header::closebigbox();
+&Header::closepage();
+
+while ( system("/usr/local/bin/wiohelper", "&") ) {}
+
+exit 0;                
+}
+else {
+       $infomessage = "$Lang::tr{'wio_already_running'}";
+}
+
+}
+
+## refresh dyndns ip
+
+if ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_dyndns_refresh'} ) {
+       unless ( `ps -A | grep wio.pl` ) {
+               chomp(@current[$wiosettings{'ID'}]);
+               @temp = split (/\,/, @current[$wiosettings{'ID'}]);
+
+               ($temp[2], $infomessage) = &WIO::getdyndnsip($temp[2], $temp[3]);
+
+               @current[$wiosettings{'ID'}] = join (',', @temp)."\n";
+
+               &writeips();
+
+               undef($wiosettings{'ID'});
+       }
+       else {
+               $infomessage = "$Lang::tr{'wio_error_function'}";
+       }
+}
+
+## edit client
+
+if ( $wiosettings{'ACTION'} eq $Lang::tr{'edit'} ) {
+       unless ( `ps -A | grep wio.pl` ) {
+               chomp(@current[$wiosettings{'ID'}]);
+               @temp = split (/\,/, @current[$wiosettings{'ID'}]);
+
+               $wiosettings{'CLIENTID'} = $temp[0];
+               $wiosettings{'TIMESTAMP'} = $temp[1];
+               $wiosettings{'IPADR'} = $temp[2];
+               $wiosettings{'HOST'} = $temp[3];
+               $wiosettings{'EN'} = $temp[4];
+               $wiosettings{'REMARK'} = $temp[5];
+               $wiosettings{'DYNDNS'} = $temp[6];
+               $wiosettings{'SENDEMAILON'} = $temp[7];
+               $wiosettings{'SENDEMAILOFF'} = $temp[8];
+               $wiosettings{'PINGMETHODE'} = $temp[9];
+               $wiosettings{'ONLINE'} = $temp[10];
+               $wiosettings{'WEBINTERFACE'} = $temp[11];
+       }
+       else {
+               undef($wiosettings{'ACTION'});
+               $infomessage = "$Lang::tr{'wio_error_function'}";
+       }
+}
+
+## remove client
+
+if ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_remove_client'} ) {
+       unless ( `ps -A | grep wio.pl` ) {
+               chomp(@current[$wiosettings{'ID'}]);
+
+               @temp = split (/\,/, @current[$wiosettings{'ID'}]);
+
+               unlink "$rrddir/$temp[0].rrd";
+
+               splice (@current,$wiosettings{'ID'},1);
+
+               &writeips();
+
+               undef($wiosettings{'ID'});
+       }
+       else {
+               undef($wiosettings{'ID'});
+               $infomessage = "$Lang::tr{'wio_error_function'}";
+       }
+}
+
+## remove all clients
+
+if ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_remove_all'} ) {
+       unless ( `ps -A | grep wio.pl` ) {
+               &WIO::clearfile($ipadrfile);
+               unlink glob "$rrddir/*";
+               undef(@current);
+       }
+       else {
+               $infomessage = "$Lang::tr{'wio_error_function'}";
+       }
+}
+
+## back function
+
+if ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_back'} ) {
+       if ( -e "$importfile" ) { unlink ($importfile); }
+       map ($wiosettings{$_} = '' ,@nosaved);
+       undef($errormessage);
+}
+
+## import hosts, fixleases or csv file || scan networks (green/blue/orange)
+
+if ( $wiosettings{'ACTION'} eq 'wio_run_green'  ||
+        $wiosettings{'ACTION'} eq 'wio_run_blue'   ||
+        $wiosettings{'ACTION'} eq 'wio_run_orange') { $wioscan = 'on'; }
+
+if ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_import'}.'1' ||
+        $wiosettings{'ACTION'} eq $Lang::tr{'wio_import'}.'2' ||
+        $wiosettings{'ACTION'} eq $Lang::tr{'wio_import'}.'3' ||
+        defined($wioscan) || defined($importmessage) ) {
+
+unless ( `ps -A | grep wio.pl` ) {
+       if ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_import'}.'1' && $importmessage eq '' ) {
+
+               &Header::getcgihash(\%wiosettings, {'wantfile' => 1, 'filevar' => 'CSVFILE'});
+
+               if ( $wiosettings{'CSVFILE'} eq '' ) {
+                       $errormessage = $Lang::tr{'wio_no_file_selected'};
+                       $message = 2; goto ERROR;
+               }
+
+               if ( $wiosettings{'CSVFILE'} =~ /[^a-z0-9A-Z\ \.\-\_\:\\]+/ ) {
+                       $errormessage = $Lang::tr{'wio_no_csv_error'};
+                       $message = 2; goto ERROR;
+               }
+
+               if ( !($wiosettings{'CSVFILE'} =~ /.csv$/) ) {
+                       $errormessage = $Lang::tr{'wio_no_csv'};
+                       $message = 2; goto ERROR;
+               }
+
+               if (copy($wiosettings{'CSVFILE'}, "$logdir/importfile") != 1) {
+                       $errormessage = $!;
+                       $message = 2; goto ERROR;
+               }
+       }
+
+EDIT:
+
+&General::readhash($wiosettings, \%wiosettings);
+
+&Header::showhttpheaders();
+&Header::openpage($Lang::tr{'wio'}, 1, '');
+&Header::openbigbox('100%', 'left');
+
+if ($importmessage) {
+       &Header::openbox('100%', 'left', $Lang::tr{'wio_error'}, 'error');
+               print" <table width='100%'><tr><td><font class='base'>$importmessage</font></td></tr></table>";
+       &Header::closebox();
+}
+
+if ( -e "$editfile" ) {
+       open(FILE, "< $editfile" ); }
+elsif ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_import'}.'1' ) {
+       open(FILE, "< $importfile" ); }
+elsif ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_import'}.'2' ) {
+       open(FILE, "< $hostfile" ); }
+elsif ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_import'}.'3' ) {
+       open(FILE, "< $dhcpfile" ); }
+elsif ( $wioscan eq 'on' ) {
+
+       foreach (keys(%ifacecolor)) {
+               if ( $netsettings{"${_}_DEV"} eq $wiosettings{'ID'} ) {
+                       $dev = $netsettings{"${_}_DEV"};
+                       $iprange = $wiosettings{"${_}_IPLOW"} . "-" . $wiosettings{"${_}_IPHIGH"};
+
+                       if ( $_ eq 'GREEN' ) { $color = "$Header::colourgreen"; $net = $Lang::tr{'wio_msg_green'}; }
+                       elsif ( $_ eq 'BLUE' ) { $color = "$Header::colourblue"; $net = $Lang::tr{'wio_msg_blue'}; }
+                       else { $color = "$Header::colourorange"; $net = $Lang::tr{'wio_msg_orange'}; }
+               }
+       }
+
+&Header::openbox('100%', 'left', $Lang::tr{'wio_info'});
+       print"<table width='100%'>
+                 <tr><td align='center'><font class='base'>$Lang::tr{'wio_msg_left'} </font><font class='base' color='$color'><b>$net</b></font> $Lang::tr{'wio_msg_center'} <font class='base' color='$color'><b>$dev</b></font><font class='base'> $Lang::tr{'wio_msg_right'} $Lang::tr{'wio_msg_hint'}</font></td></tr>
+                 <tr><td>&nbsp;</td></tr>
+                 <tr><td align='center'><img align='middle' src='/images/indicator.gif' /></td></tr>
+                 </table>";
+&Header::closebox();
+&Header::closebigbox();
+
+       open(FILE, "/usr/local/bin/wioscan -wsa $dev $iprange |" );
+
+}
+
+@hosts = <FILE>;
+close(FILE);
+
+if ( $wioscan ne 'on' && ! -e $wiofile ) { @hosts = sort @hosts; }
+else {
+       open(FILE, "> $wiofile");
+       print FILE @hosts;
+       close(FILE);
+
+       print"<meta http-equiv=\"refresh\" content=\"0; URL=$ENV{'SCRIPT_NAME'}\">";
+       exit 0;
+}
+
+WIOSCAN:
+
+if ( -e $wiofile ) {
+       open(FILE, "< $wiofile");
+       @hosts = <FILE>;
+       close (FILE);
+
+       &General::readhash($wiosettings, \%wiosettings);
+
+       &Header::showhttpheaders();
+       &Header::openpage($Lang::tr{'wio'}, 1, '');
+       &Header::openbigbox('100%', 'left');
+}
+
+foreach (@hosts) {
+       chomp;
+
+       @line = split (/\,/, $_);
+
+       if ( -e $editfile || -e $importfile ) {
+               $wiosettings{'CLIENTID$count'} = $line[0];
+               $wiosettings{'TIMESTAMP$count'} = $line[1];
+               $wiosettings{'IPADR$count'} = $line[2];
+               $wiosettings{'HOST$count'} = $line[3];
+               $wiosettings{'EN$count'} = $line[4];
+               $wiosettings{'REMARK$count'} = $line[5];
+               $wiosettings{'DYNDNS$count'} = $line[6];
+               $wiosettings{'SENDEMAILON$count'} = $line[7];
+               $wiosettings{'SENDEMAILOFF$count'} = $line[8];
+               $wiosettings{'PINGMETHODE$count'} = $line[9];
+               $wiosettings{'ONLINE$count'} = $line[10];
+               $wiosettings{'WEBINTERFACE$count'} = $line[11];
+               $wiosettings{'USE$count'} = 'on';
+       }
+       else {
+               $wiosettings{'IPADR$count'} = $line[1];
+               $wiosettings{'EN$count'} = 'on';
+               $wiosettings{'PINGMETHODE$count'} = 'ip';
+               $wiosettings{'USE$count'} = 'on';
+
+               if ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_import'}.'2' ) {
+                       $wiosettings{'HOST$count'} = $line[2];
+                       $wiosettings{'DOM$count'} = $line[3];
+                       $wiosettings{'REMARK$count'} = '';
+               }
+               elsif ( $wioscan eq 'on' || -e $wiofile ) {
+                       $wiosettings{'HOST$count'} = gethostbyaddr(inet_aton($line[1]), AF_INET);
+                       if ($wiosettings{'HOST$count'} eq '') { $wiosettings{'HOST$count'} = $line[1]; }
+                       $wiosettings{'REMARK$count'} = '';
+                       $wiosettings{'WEBINTERFACE$count'} = '';
+               }
+               else {
+                       $wiosettings{'HOST$count'} = $line[7];
+                       $wiosettings{'REMARK$count'} = $line[6];
+               }
+       }
+
+       $checked{'EN$count'}{'on'} = ($wiosettings{'EN$count'} eq '' ) ? '' : "checked='checked'";
+
+       $checked{'DYNDNS$count'}{'on'} = ($wiosettings{'DYNDNS$count'} eq '' ) ? '' : "checked='checked'";
+       $checked{'SENDEMAILON$count'}{'on'} = ($wiosettings{'SENDEMAILON$count'} eq '' ) ? '' : "checked='checked'";
+       $checked{'SENDEMAILOFF$count'}{'on'} = ($wiosettings{'SENDEMAILOFF$count'} eq '' ) ? '' : "checked='checked'";
+
+       $checked{'PINGMETHODE$count'}{'ip'} = $checked{'PINGMETHODE$count'}{'fqdn'} = '';
+       $checked{'PINGMETHODE$count'}{$wiosettings{'PINGMETHODE$count'}} = "checked='checked'";
+
+       $checked{'USE$count'}{'on'} = ($wiosettings{'USE$count'} eq '' ) ? '' : "checked='checked'";
+       
+       $selected{'WEBINTERFACE$count'}{'----'} = '';
+       $selected{'WEBINTERFACE$count'}{'HTTP'} = '';
+       $selected{'WEBINTERFACE$count'}{'HTTPS'} = '';
+       $selected{'WEBINTERFACE$count'}{$wiosettings{'WEBINTERFACE$count'}} = "selected='selected'";
+
+if (! &WIO::checkinto($wiosettings{'IPADR$count'}, $wiosettings{'HOST$count'}, @current) ) {
+
+if ( $importmessage ) {
+       &Header::openbox('100%', 'left', "$Lang::tr{'wio_import_data'}'$wiosettings{'HOST$count'}'$Lang::tr{'wio_import_data1'}");
+} 
+elsif ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_import'}.'1' || $wioscan eq 'on' || -e $wiofile || -e $editfile ) {
+       &Header::openbox('100%', 'left', "$Lang::tr{'wio_import_data'}'$wiosettings{'HOST$count'}'$Lang::tr{'wio_import_data2'}");
+}
+elsif ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_import'}.'2' ) {
+       &Header::openbox('100%', 'left', "$Lang::tr{'wio_import_data'}'$wiosettings{'HOST$count'}.$wiosettings{'DOM$count'}'$Lang::tr{'wio_import_data2'}");
+}
+else {
+       &Header::openbox('100%', 'left', $Lang::tr{'wio_import_leases'});
+}
+
+print"
+<form method='post' action='$ENV{'SCRIPT_NAME'}' enctype='multipart/form-data'>
+<input type='hidden' name='ONLINE$count' value='$wiosettings{'ONLINE$count'}' />
+
+<table width='100%'>
+<tr>
+       <td>$Lang::tr{'wio_use'}</td>
+       <td><input type='checkbox' name='USE$count' $checked{'USE$count'}{'on'} /></td>
+</tr>
+<tr>
+       <td>$Lang::tr{'wio_client_enable'}</td>
+       <td><input type='checkbox' name='EN$count' $checked{'EN$count'}{'on'} /></td>
+</tr>
+<tr>
+       <td>$Lang::tr{'host ip'}:</td>
+       <td><input type='text' name='IPADR$count' value='$wiosettings{'IPADR$count'}' size='18' /></td>
+       <td>$Lang::tr{'hostname'}:</td>
+";
+
+if ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_import'}.'2' ) {
+       print"<td><input type='text' name='HOST$count' size='18' value='$wiosettings{'HOST$count'}.$wiosettings{'DOM$count'}' /></td>";
+}
+else {
+       print"<td><input type='text' name='HOST$count' size='18' value='$wiosettings{'HOST$count'}' /></td>";
+}
+
+print"
+       <td>$Lang::tr{'remark'}:</td>
+       <td><input type='text' name='REMARK$count' value='$wiosettings{'REMARK$count'}' size='18' /></td>
+</tr>
+<tr>
+       <td class='base'>$Lang::tr{'wio_ping_send'}:</td>
+       <td align='left'><input type='radio' name='PINGMETHODE$count' value='ip' $checked{'PINGMETHODE$count'}{'ip'} />&nbsp;IP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type='radio' name='PINGMETHODE$count' value='fqdn' $checked{'PINGMETHODE$count'}{'fqdn'} />&nbsp;FQDN</td>
+       <td>$Lang::tr{'wio_dyndns'}:</td>
+       <td><input type='checkbox' name='DYNDNS$count' $checked{'DYNDNS$count'}{'on'} /></td>
+";
+
+if ( $wiosettings{'SENDEMAIL'} eq 'on' ) {
+       print"<td>$Lang::tr{'wio_sendemail'}:</td>
+                 <td><input type='checkbox' name='SENDEMAILON$count' $checked{'SENDEMAILON$count'}{'on'} />&nbsp;$Lang::tr{'wio_online'}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type='checkbox' name='SENDEMAILOFF$count' $checked{'SENDEMAILOFF$count'}{'on'} />&nbsp;$Lang::tr{'wio_offline'}</td>";
+}
+else {
+       print"<td colspan='2'>&nbsp;</td>";
+}
+
+print"
+</tr>
+<tr>
+       <td height='30'>$Lang::tr{'wio_ping_send'}:</td>
+       <td align='left' colspan='5'>
+               <select size='1' name='WEBINTERFACE$count' width='80' style='width: 80px'>
+               <option value='----' $selected{'WEBINTERFACE$count'}{'----'}>----</option>
+               <option value='HTTP' $selected{'WEBINTERFACE$count'}{'HTTP'}>HTTP</option>
+               <option value='HTTPS' $selected{'WEBINTERFACE$count'}{'HTTPS'}>HTTPS</option>
+               </select>
+       </td>
+</tr>
+</table>
+";
+
+&Header::closebox();
+$showcount++;
+}
+$count++;
+}
+
+if ( $showcount gt 0 ) {
+&Header::openbox('100%', 'left', $Lang::tr{'wio_import_infos'});
+
+print"
+<table width='100%'>
+<tr>
+";
+
+if ($importmessage) { print"<td>&nbsp;</td>"; }
+else { print"<td><font color='$color{'color11'}'>$Lang::tr{'wio_import_infos_csv'}</font></td>"; }
+
+print"
+</tr>
+<tr><td colspan='4'>&nbsp;</td></tr>
+</table>
+<table width='100%'>
+<tr>
+       <td width='25%'>&nbsp;</td>
+       <td width='25%'><input type='hidden' name='COUNT' value='$count' /><input type='hidden' name='ACTION' value='$Lang::tr{'wio_save'}2' /><input type='submit' name='SUBMIT' value='$Lang::tr{'wio_save'}' /></form></td>
+       <td width='25%'><form method='post' action='$ENV{'SCRIPT_NAME'}' enctype='multipart/form-data'><input type='submit' name='ACTION' value='$Lang::tr{'wio_back'}' /></form></td>
+       <td width='25%'>&nbsp;</td>
+</tr>
+</table>
+";
+
+&Header::closebox();
+&Header::closebigbox();
+&Header::closepage();
+}
+else {
+       print"<meta http-equiv=\"refresh\" content=\"0; URL=$ENV{'SCRIPT_NAME'}?INFO\">";
+}
+
+if ( -e "$editfile" ) { unlink ($editfile); }
+if ( -e "$wiofile" ) { unlink($wiofile); }
+exit 0;
+}
+else {
+       $infomessage = "$Lang::tr{'wio_error_function'}";
+}
+}
+
+## skript function
+
+if ($ENV{'QUERY_STRING'} =~ /$sortstring/ ) {
+       my $string = $ENV{'QUERY_STRING'};
+
+       if ( $string eq 'INFO' ) {
+               $infomessage = $Lang::tr{'wio_import_info_csv'};
+       }
+       else {
+               &General::readhash($wiosettings, \%wiosettings);
+
+               my $actual = $wiosettings{'SORT'};
+
+               if ($actual =~ $string) {
+                       my $Rev = '';
+                       if ($actual !~ 'Rev') { $Rev = 'Rev'; }
+                       $string.=$Rev;
+               }
+
+               system("/bin/sed -i 's#$wiosettings{'SORT'}#$string#g' $wiosettings");
+
+               $wiosettings{'SORT'} = $string;
+               map ($wiosettings{$_} = '' ,@nosaved);
+               &SortDataFile('',@current);
+       }
+}
+
+## main part
+
+ERROR:
+
+unless($message == 1) { &General::readhash($wiosettings, \%wiosettings); }
+
+for ($i=5; $i<=60; $i+=5) { $selected{'CRON'}{$i} = ''; }
+
+$selected{'CRON'}{$wiosettings{'CRON'}} = "selected='selected'";
+       
+for ($i=1; $i<=15; $i++) {
+       $selected{'TIMEOUT'}{$i} = '';
+       $selected{'OVPNCRON'}{$i} = '';
+}
+
+$selected{'TIMEOUT'}{$wiosettings{'TIMEOUT'}} = "selected='selected'";
+$selected{'OVPNCRON'}{$wiosettings{'OVPNCRON'}} = "selected='selected'";
+
+$checked{'ENABLE'}{'off'} = $checked{'ENABLE'}{'on'} = '';
+$checked{'ENABLE'}{$wiosettings{'ENABLE'}} = "checked='checked'";
+
+$checked{'LOGGING'}{'off'} = $checked{'LOGGING'}{'on'} = '';
+$checked{'LOGGING'}{$wiosettings{'LOGGING'}} = "checked='checked'";
+
+$checked{'CLIENTREMARK'}{'off'} = $checked{'CLIENTREMARK'}{'on'} = '';
+$checked{'CLIENTREMARK'}{$wiosettings{'CLIENTREMARK'}} = "checked='checked'";
+
+$checked{'MAILREMARK'}{'off'} = $checked{'MAILREMARK'}{'on'} = '';
+$checked{'MAILREMARK'}{$wiosettings{'MAILREMARK'}} = "checked='checked'";
+
+$checked{'OVPNRWMAIL'}{'off'} = $checked{'OVPNRWMAIL'}{'on'} = '';
+$checked{'OVPNRWMAIL'}{$wiosettings{'OVPNRWMAIL'}} = "checked='checked'";
+
+$checked{'SHUTDOWN'}{'off'} = $checked{'SHUTDOWN'}{'on'} = '';
+$checked{'SHUTDOWN'}{$wiosettings{'SHUTDOWN'}} = "checked='checked'";
+
+$checked{'MAILSTYLE'}{'smail'} = $checked{'MAILSTYLE'}{'email'} = '';
+$checked{'MAILSTYLE'}{$wiosettings{'MAILSTYLE'}} = "checked='checked'";
+
+&Header::showhttpheaders();
+&Header::openpage($Lang::tr{'wio'}, 1, "<meta http-equiv='expires' content='-1'><meta http-equiv='cache-control' content='no-store, no-cache, must-revalidate'><meta http-equiv='pragma' content='no-cache'>");
+&Header::openbigbox('100%', 'left', '');
+
+## DEBUG / ERROR / INFO / UPDATE
+
+if ( $debug ) {
+       &Header::openbox('100%', 'left', 'DEBUG', 'warning');
+
+               print"errormessage: $errormessage<br />\n";
+               print"infomessage: $infomessage<br />\n";
+
+               &hrline();
+               
+               my $wiodebug = 0;
+               foreach (sort keys %wiosettings) {
+                       print"$_ = $wiosettings{$_}<br />\n";
+                       $wiodebug++;
+               }
+
+               &hrline();
+
+               my $netdebug = 0;
+               foreach (sort keys %netsettings) {
+                       print"$_ = $netsettings{$_}<br />\n";
+                       $netdebug++;
+               }
+       &Header::closebox();
+}
+
+if ( $errormessage ) {
+       &Header::openbox('100%', 'left', $Lang::tr{'wio_error'}, 'error');
+               print"<table width='100%'><tr><td><font class='base'><b>$errormessage</b></font></td></tr></table>";
+       &Header::closebox();
+}
+
+if ( $infomessage ) {
+       &Header::openbox('100%', 'left', $Lang::tr{'wio_info'}, 'warning');
+               print"<table width='100%'><tr><td><font class='base'><b>$infomessage</b></font></td></tr></table>";
+       &Header::closebox();
+}
+
+## wio configuration
+
+if ( $wiosettings{'ACTION'} eq $Lang::tr{'edit'}.'1' || $message == 1 || $wiosettings{'ENABLE'} eq 'off' ) {
+
+&Header::openbox('100%', 'left', $Lang::tr{'wio settings'});
+
+print"
+<form method='post' action='$ENV{'SCRIPT_NAME'}' enctype='multipart/form-data'>
+<table width='100%'>
+<tr>
+       <td width='45%' bgcolor='$color{'color20'}' align='left' height='20'><b>&nbsp;$Lang::tr{'wio_settings_msg'}</b></td>
+       <td width='2%'>&nbsp;</td>
+       <td width='53%'>&nbsp;</td>
+</tr>
+<tr><td colspan='3'>&nbsp;</td></tr>
+<tr>
+       <td colspan='3'>$Lang::tr{'wio_settings_msg_hint'}</td>
+</tr>
+<tr><td colspan='3'>&nbsp;</td></tr>
+<tr>
+       <td align='right'>$Lang::tr{'wio enabled'}</td>
+";
+
+print"<td>&nbsp;</td>";
+
+if ( $wiosettings{'ENABLE'} eq 'on' ) {
+       print"<td align='left'><input type='checkbox' onClick=\"return confirm('$Lang::tr{'wio_disable_hint'}')\" name='ENABLE' $checked{'ENABLE'}{'on'} /></td>";
+}
+else {
+       print"<td align='left'><input type='checkbox' name='ENABLE' $checked{'ENABLE'}{'on'} /></td>";
+}
+print"
+</tr>
+<tr><td colspan='3'>&nbsp;</td></tr>
+<tr>
+       <td align='right'>$Lang::tr{'wio_shutdown'}</td>
+       <td>&nbsp;</td>
+       <td align='left'><input type='checkbox' name='SHUTDOWN' $checked{'SHUTDOWN'}{'on'} /></td>
+</tr>
+<tr><td colspan='3'>&nbsp;</td></tr>
+<tr>
+       <td align='right'>$Lang::tr{'wio cron'}</td>
+       <td>&nbsp;</td>
+       <td align='left'><select size='1' name='CRON' size='5'>
+";
+
+for ($i=5; $i<=60; $i+=5) { printf("<option %s>%02s</option>\n",$selected{'CRON'}{$i},$i); }
+
+print"
+       </select>&nbsp;$Lang::tr{'wio min'}</td>
+</tr>
+<tr><td colspan='3'>&nbsp;</td></tr>
+<tr>
+       <td align='right'>$Lang::tr{'wio timeout'}</td>
+       <td>&nbsp;</td>
+       <td align='left'><select size='1' name='TIMEOUT' size='5'>
+";
+
+for ($i=1; $i<=15; $i++) { printf("<option %s>%02s</option>\n",$selected{'TIMEOUT'}{$i},$i); }
+
+print" 
+       </select>&nbsp;$Lang::tr{'wio sec'}</td>
+</tr>
+<tr><td colspan='3'>&nbsp;</td></tr>
+<tr>
+       <td align='right'>$Lang::tr{'wio_logging'}</td>
+       <td>&nbsp;</td>
+       <td align='left'><input type='checkbox' name='LOGGING' $checked{'LOGGING'}{'on'} /></td>
+</tr>
+<tr><td colspan='3'>&nbsp;</td></tr>
+<tr>
+       <td align='right'>$Lang::tr{'wio_clientremark'}</td>
+       <td>&nbsp;</td>
+       <td align='left'><input type='checkbox' name='CLIENTREMARK' $checked{'CLIENTREMARK'}{'on'} /></td>
+</tr>
+<tr><td colspan='3'>&nbsp;</td></tr>
+
+";
+
+if ( $wiosettings{'SENDEMAIL'} eq 'on' ) {
+print"
+<tr>
+       <td align='right'>$Lang::tr{'wio_mail_style'}:</td>
+       <td>&nbsp;</td>
+       <td align='left'><input type='radio' name='MAILSTYLE' value='smail' $checked{'MAILSTYLE'}{'smail'} />&nbsp;$Lang::tr{'wio_mail_smail'}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type='radio' name='MAILSTYLE' value='email' $checked{'MAILSTYLE'}{'email'} />&nbsp;$Lang::tr{'wio_mail_email'}</td>
+</tr>
+<tr><td colspan='3'>&nbsp;</td></tr>
+<tr>
+       <td align='right'>$Lang::tr{'wio_mailremark_enabled'}</td>
+       <td>&nbsp;</td>
+       <td align='left'><input type='checkbox' name='MAILREMARK' $checked{'MAILREMARK'}{'on'}></td>
+</tr>
+<tr><td colspan='3'>&nbsp;</td></tr>
+";
+}
+if ( -e "$ovpnaddon" || ! -z "/var/ipfire/vpn/config" ) {
+print"
+<tr>
+       <td align='right'>$Lang::tr{'wio_mail_ovpnrw'}</td>
+       <td>&nbsp;</td>
+       <td align='left'><input type='checkbox' name='OVPNRWMAIL' $checked{'OVPNRWMAIL'}{'on'}></td>
+</tr>
+<tr><td colspan='3'>&nbsp;</td></tr>
+<tr>
+       <td align='right'>$Lang::tr{'wio_ovpn_cron'}</td>
+       <td>&nbsp;</td>
+       <td align='left'><select size='1' name='OVPNCRON' size='5'>
+";
+
+for ($i=1; $i<=15; $i++) { printf("<option %s>%02s</option>\n",$selected{'OVPNCRON'}{$i},$i); }
+
+print"
+       </select>&nbsp;$Lang::tr{'wio min'}</td>
+</tr>
+<tr><td colspan='3'>&nbsp;</td></tr>
+";
+}
+print"
+<tr><td colspan='3'>&nbsp;</td></tr>
+<tr>
+       <td colspan='2'>&nbsp;</td>
+       <td align='left'><input type='hidden' name='ACTION' value='$Lang::tr{'wio_save'}1' /><input type='submit' name='submit' value='$Lang::tr{'wio_save'}' />"
+       .($wiosettings{'ENABLE'} ne 'off' ? "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type='button' onClick='location.href=\"/cgi-bin/wio.cgi\"' value='$Lang::tr{'wio_back'}'>" : "")
+       ."</td>
+</tr>
+</table>
+</form>
+";
+
+&Header::closebox();
+&Header::closebigbox();
+&Header::closepage();
+exit 0;
+}
+
+## wio client status
+
+if ( $wiosettings{'ENABLE'} eq 'on') {
+       if ( !$errormessage && $wiosettings{'ACTION'} ne $Lang::tr{'edit'} || $message == 2 ) {
+               &Header::openbox('100%', 'left', $Lang::tr{'wio stat'});
+
+               foreach (@current) {
+                       chomp;
+
+                       ($id,$timestamp,$ipadr,$host,$on,$remark,$dyndns,$sendemailon,$sendemailoff,$pingmethode,$online,$webinterface) = split (/\,/, $_);
+
+                       if ( defined($dyndns) && ( $dyndns =~ 'on' ) ) {
+                               ($dyndnsip, $infomessage) = &WIO::getdyndnsip($ipadr, $host);
+
+                               if ( $dyndnsip ne $ipadr  ) {
+                                       $ipadr = $dyndnsip;
+                                       $write = 'on';
+                               }
+                       }
+
+                       push (@id,($id));
+
+                       if ( $on eq 'on' ) { push (@dates,($timestamp)); }
+                       else { push (@dates,('-')); }
+
+                       push (@ipaddresses,($ipadr));
+                       push (@names,($host));
+                       push (@activ,($on));
+                       push (@remark,($remark));
+                       push (@dyndns,($dyndns));
+                       push (@sendemailon,($sendemailon));
+                       push (@sendemailoff,($sendemailoff));
+                       push (@pingmethode,($pingmethode));
+                       push (@status,($online));
+                       push (@webinterface,($webinterface));
+
+                       push (@write, "$id,$timestamp,$ipadr,$host,$on,$remark,$dyndns,$sendemailon,$sendemailoff,$pingmethode,$online,$webinterface\n");
+
+                       $nr++;
+               }
+
+               if ( defined($write) ) { &writeips(); }
+
+## wan connection
+
+print"
+<table border='0' width='100%' bordercolor='$Header::bordercolour' cellspacing='0' cellpadding='0' style='border-collapse: collapse'>
+<tr height='20'>
+       <td width='28%' bgcolor='$color{'color20'}' align='left'><b>&nbsp;$Lang::tr{'wio_wan_con'}</b></td>
+       <td width='72%' align='right'>&nbsp;</td>
+</tr>
+<tr><td colspan='2'>&nbsp;</td></tr>
+</table>
+
+<table border='0' width='100%' bordercolor='$Header::bordercolour' cellspacing='0' cellpadding='0' style='border-collapse: collapse'>
+<tr bgcolor='$color{'color20'}' height='20'>
+       <td width='3%' align='center'><b>$Lang::tr{'wio_id'}</b></td>
+       <td width='15%' align='center'><b>$Lang::tr{'wio ipadress'}</b></td>
+       <td width='3%' align='center'><b>$Lang::tr{'wio network'}</b></td>
+       <td width='15%' align='center'><b>$Lang::tr{'wio_lanname'}</b></td>
+       <td width='15%' align='center'><b>$Lang::tr{'wio_wanname'}</b></td>
+       <td width='24%' align='center'><b>$Lang::tr{'wio_dyndns_hosts'}</b></td>
+       <td width='11%' align='center'><b>$Lang::tr{'wio image'}</b></td>
+       <td width='14%' align='center'><b>$Lang::tr{'wio_wancheck'}</b></td>
+</tr>
+<tr bgcolor='$color{'color22'}' height='20'>
+       <td align='center'>01</td>
+       <td align='center'><font color='$Header::colourred'>$redip</b></font></td>
+       <td align='center'><img align='middle' src='$imgstatic/red.png' alt='$Lang::tr{'internet'}' title='$Lang::tr{'internet'}' /></td>
+       <td align='center'><font color='$Header::colourgreen'>".$mainsettings{'HOSTNAME'}.".".$mainsettings{'DOMAINNAME'}."</font></td>
+       <td align='center'><font color='$Header::colourred'>".( $redip ne '-' ? (gethostbyaddr(pack("C4", split (/\./, $redip)), 2))[0] : '-' )."</font></td>
+       <td align='center'>
+";
+
+if ( -s "$dyndnsconfig" ) {
+
+open(FILE, "< $dyndnsconfig");
+@ddns = <FILE>;
+close (FILE);
+
+$ddns = @ddns;
+$bgcolor = "blue";
+
+       foreach (@ddns) {
+               chomp;
+
+               @temp = split (/\,/, $_);
+
+               if ( $temp[7] eq "on" ) { $bgcolor = ( &General::DyndnsServiceSync (&General::GetDyndnsRedIP,$temp[1],$temp[2]) ? "$Header::colourgreen" : "$Header::colourred" ); }
+
+               print"<font color='$bgcolor'>$temp[1].$temp[2]</font>";
+
+               if ( $iddyndns++ ne ($ddns-1) ) { print"<b>, </b>"; }
+       }
+}
+else { print"<b> - </b>"; }
+
+print"
+       </td>
+       <td align='center'>
+               <table bgcolor='".( -e $redactive ? "${Header::colourgreen}" : "${Header::colourred}" )."' cellpadding='2' cellspacing='0' width='100%'>
+                       <tr height='20'>
+                               <td align='center'><font color='white'><b>".( -e $redactive ? $Lang::tr{'wio_wan_up'} : $Lang::tr{'wio_wan_down'} )."</b></font></td>
+                       </tr>
+               </table>
+       </td>
+       <td align='center'><font color='$Header::colourred'>".( -e "$redactive" ? &General::age("$redactive") : '-' )."</font></td>
+</tr>
+<tr height='1'><td colspan='9' bgcolor='#696565'></td></tr>
+</table>
+";
+
+&hrline();
+
+## vpn connection(s)
+
+if ( -e "$vpnpid" ) {
+
+@vpnstatus = `/usr/local/bin/ipsecctrl I`;
+
+print"
+<table border='0' width='100%' bordercolor='$Header::bordercolour' cellspacing='0' cellpadding='0' style='border-collapse: collapse'>
+<tr height='20'>
+       <td width='28%' bgcolor='$color{'color20'}' align='left'><b>&nbsp;$Lang::tr{'wio_vpn_con'}</b></td>
+       <td width='72%'>&nbsp;</td>
+</tr>
+<tr><td colspan='2'>&nbsp;</td></tr>
+</table>
+<table border='0' width='100%' bordercolor='$Header::bordercolour' cellspacing='0' cellpadding='0' style='border-collapse: collapse'>
+<tr bgcolor='$color{'color20'}' height='20'>
+       <td width='3%' align='center'><b>$Lang::tr{'wio_id'}</b></td>
+       <td width='19%' align='center'><b>$Lang::tr{'wio checked'}</b></td>
+       <td width='20%' align='center'><b>$Lang::tr{'name'}</b></td>
+       <td width='8%' align='center'><b>$Lang::tr{'type'}</b></td>
+       <td width='25%' align='center'><b>$Lang::tr{'wio_common_name'}</b></td>
+       <td width='11%' align='center'><b>$Lang::tr{'wio image'}</b></td>
+       <td width='14%' align='center'><b>$Lang::tr{'wio_ovpn_connected'}</b></td>
+</tr>
+";
+
+foreach $key (sort SortByTunnelName (keys(%vpnconfighash))) {
+
+my $vpncheck = '';
+
+if ( -e '/var/log/wio/.vpncache' ) {
+       $vpncheck = strftime("%d.%m.%Y - %H:%M:%S",localtime(((stat('/var/log/wio/.vpncache'))[9])));
+}
+
+$status = "bgcolor='${Header::colourred}'";
+$statustxt = "$Lang::tr{'capsclosed'}";
+
+       if ($vpnconfighash{$key}[0] eq 'off') {
+               $status = "bgcolor='${Header::colourblue}'";
+               $statustxt = "$Lang::tr{'capsclosed'}";
+       }
+
+       foreach (@vpnstatus) {
+               if ($_ =~ /$vpnconfighash{$key}[1]\{.*INSTALLED/) {
+                       $status = "bgcolor='${Header::colourgreen}'";
+                       $statustxt = "$Lang::tr{'capsopen'}";
+                       last;
+               }
+       }
+
+       print"<tr".($idvpn % 2?" bgcolor='$color{'color20'}'":" bgcolor='$color{'color22'}'")." height='20'>";
+
+       my $vpnnr = $idvpn+1;
+
+       printf ("<td align='center'> %02d</td>", $vpnnr);
+
+       print"<td align='center'>$vpncheck</td>
+                 <td align='center'>$vpnconfighash{$key}[1]</td>
+                 <td align='center'><img align='middle' src='$imgstatic/".( $vpnconfighash{$key}[3] eq 'host' ? "vpnrw.png' alt='$Lang::tr{'wio_rw'}' title='$Lang::tr{'wio_rw'}'" : "vpnn2n.png' alt='$Lang::tr{'wio_n2n'}' title='$Lang::tr{'wio_n2n'}'")." /></td>
+                 <td align='center'>".($vpnconfighash{$key}[2] eq '%auth-dn' ? "$vpnconfighash{$key}[9]" : ($vpnconfighash{$key}[4] eq 'cert' ? "$vpnconfighash{$key}[2]" : ($vpnconfighash{$key}[8] ne '' ? "$vpnconfighash{$key}[10]" : "&nbsp;")))."</td>
+                 <td align='center'>
+                       <table $status cellpadding='2' cellspacing='0' width='100%'>
+                               <tr height='20'>
+                                       <td align='center'><font color='white'><b>$statustxt</b></font></td>
+                               </tr>
+                       </table>
+                 </td>
+                 <td align='center' height='20'>&nbsp;</td>
+                 </tr>
+";
+if ($vpnconfighash{$key}[25] && $wiosettings{'CLIENTREMARK'} eq 'on') {
+       print"<tr".($idvpn % 2?" bgcolor='$color{'color20'}'":" bgcolor='$color{'color22'}'")." height='20'><td>&nbsp;</td><td colspan='16' align='left'>$vpnconfighash{$key}[25]</td></tr>";
+}
+       print"<tr height='1'><td colspan='7' bgcolor='#696565'></td></tr>";
+       $idvpn++
+}
+
+print"</table>";
+&hrline();
+}
+
+## openvpn connection(s)
+
+if ( -e "$ovpnpid" ) {
+
+@ovpnstatus = `cat /var/run/ovpnserver.log`;
+
+print"
+<table border='0' width='100%' bordercolor='$Header::bordercolour' cellspacing='0' cellpadding='0' style='border-collapse: collapse'>
+<tr height='20'>
+       <td width='28%' bgcolor='$color{'color20'}' align='left'><b>&nbsp;$Lang::tr{'wio_ovpn_con'}</b></td>
+       <td width='72%'>&nbsp;</td>
+</tr>
+<tr><td colspan='2'>&nbsp;</td></tr>
+</table>
+<table border='0' width='100%' bordercolor='$Header::bordercolour' cellspacing='0' cellpadding='0' style='border-collapse: collapse'>
+<tr bgcolor='$color{'color20'}' height='20'>
+       <td width='3%' align='center'><b>$Lang::tr{'wio_id'}</b></td>
+       <td width='19%' align='center'><b>$Lang::tr{'wio checked'}</b></td>
+       <td width='20%' align='center'><b>$Lang::tr{'wio ipadress'}</b></td>
+       <td width='8%' align='center'><b>$Lang::tr{'type'}</b></td>
+       <td width='25%' align='center'><b>$Lang::tr{'common name'}</b></td>
+       <td width='11%' align='center'><b>$Lang::tr{'wio image'}</b></td>
+       <td width='14%' align='center'><b>$Lang::tr{'wio_ovpn_connected'}</b></td>
+</tr>
+";
+
+       foreach $key (keys %ovpnconfighash) {
+
+               my ( $ovpnclt, $ovpntime, $ovpnrwip, $ovpncheck ) = '';
+
+               if ( -e '/var/log/wio/.ovpncache' ) {
+                       $ovpncheck = strftime("%d.%m.%Y - %H:%M:%S",localtime(((stat('/var/log/wio/.ovpncache'))[9])));
+               }
+
+               print"<tr".($idovpn % 2?" bgcolor='$color{'color20'}'":" bgcolor='$color{'color22'}'")." height='20'>";
+
+               my $ovpnnr = $idovpn+1;
+
+               printf ("<td align='center' height='20'> %02d</td>", $ovpnnr);
+
+               if ($ovpnconfighash{$key}[3] eq 'net') {
+                       $image = "$imgstatic/ovpnn2n.png";
+                       $text = "$Lang::tr{'wio_n2n'}";
+               }
+               else {
+                       $image = "$imgstatic/ovpnrw.png";
+                       $text = "$Lang::tr{'wio_rw'}";
+               }
+
+               if ( $ovpnconfighash{$key}[0] eq 'off' ) {
+                       $status = "${Header::colourblue}";
+                       $statustxt = "$Lang::tr{'capsclosed'}";
+               }
+               else {
+                       
+                       if ($ovpnconfighash{$key}[3] eq 'net') {
+                               if (-e "/var/run/$ovpnconfighash{$key}[1]n2n.pid") {
+                                       my @output = "";
+                                       my @tustate = "";
+                                       my $tport = $ovpnconfighash{$key}[22];
+                                       my $tnet = new Net::Telnet ( Timeout=>5, Errmode=>'return', Port=>$tport); 
+                                       if ($tport ne '') {
+                                               $tnet->open('127.0.0.1');
+                                               @output = $tnet->cmd(String => 'state', Prompt => '/(END.*\n|ERROR:.*\n)/');
+                                               @tustate = split(/\,/, $output[1]);
+                                               $ovpntime = &WIO::contime(scalar localtime($tustate[0]));
+                                               
+                                               if (($tustate[1] eq 'CONNECTED')) {
+                                                       $status = "${Header::colourgreen}";
+                                                       $statustxt = "$Lang::tr{'capsopen'}";
+                                               }else {
+                                                       $status = "${Header::colourred}";
+                                                       $statustxt = "$tustate[1]";
+                                               }
+                                       }
+                               }
+                       }
+                       else {
+                               foreach (@ovpnstatus) {
+                                       if ( $_ =~ /^(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(\d+),(\d+),(.+)/ ) {
+                                               @match = split (m/^(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(\d+),(\d+),(.+)/, $_);
+                                               $match[1] =~ s/[_]/ /g;
+                                       }
+
+                                       if ( $match[1] ne "Common Name" && ($match[1] eq $ovpnconfighash{$key}[2]) ) {
+                                               $ovpnclt = $match[1];
+                                               $ovpntime = &WIO::contime($match[5]);
+                                       }
+
+                                       if ( $_ =~ /^(\d+\.\d+\.\d+\.\d+),(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(.+)/ ) {
+                                               @match = split(m/^(\d+\.\d+\.\d+\.\d+),(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(.+)/, $_);
+                                       }
+
+                                       if ( $match[1] ne "Virtual Address" && $match[2] eq $ovpnclt ) {
+                                                       $ovpnrwip = $match[1];
+                                                       $ovpncheck = &WIO::statustime($match[4]);
+                                       }
+
+                                       if ( $ovpnclt eq $ovpnconfighash{$key}[2] ) {
+                                               $status = "${Header::colourgreen}";
+                                               $statustxt = "$Lang::tr{'capsopen'}";
+                                       }
+                                       else {
+                                               $status = "${Header::colourred}";
+                                               $statustxt = "$Lang::tr{'capsclosed'}";
+                                       }
+                               }
+                       }
+}
+
+       print"
+       <td align='center'>$ovpncheck</td>
+       <td align='center'>".( defined($ovpnrwip)? "$ovpnrwip" : "&nbsp;")."</td>
+       <td align='center'><img align='middle' src='$image' alt='$text' title='$text' /></td>
+       <td align='center'>".($ovpnconfighash{$key}[2] eq '%auth-dn' ? "$ovpnconfighash{$key}[9]" : ($ovpnconfighash{$key}[4] eq 'cert' ? "$ovpnconfighash{$key}[2]": "&nbsp;"))."</td>
+       <td align='center'><table bgcolor='$status' cellpadding='2' cellspacing='0' width='100%'><tr height='20'><td align='center'><font color='white'><b>$statustxt</b></font></td></tr></table></td>
+       <td align='center'>".(defined($ovpntime)? "$ovpntime" : "&nbsp;")."</td>
+</tr>
+";
+               if ($ovpnconfighash{$key}[25] && $wiosettings{'CLIENTREMARK'} eq 'on') {
+                       print"<tr".($idovpn % 2?" bgcolor='$color{'color20'}'":" bgcolor='$color{'color22'}'")." height='20'><td>&nbsp;</td><td colspan='16' align='left'>$ovpnconfighash{$key}[25]</td></tr>";
+               }
+               
+               print"<tr height='1'><td colspan='17' bgcolor='#696565'></td></tr>";
+               $idovpn++
+       }
+               print"</table>";
+               &hrline();
+}
+#}
+
+## client status
+
+print"
+<table border='0' width='100%' bordercolor='$Header::bordercolour' cellspacing='0' cellpadding='0' style='border-collapse: collapse'>
+<tr height='20'>
+       <td width='28%' bgcolor='$color{'color20'}' align='left'><b>&nbsp;$Lang::tr{'wio_clients'}</b></td>
+       <td width='72%'>&nbsp;</td>
+</tr>
+<tr><td colspan='2'>&nbsp;</td></tr>
+</table>
+
+<table border='0' width='100%' bordercolor='$Header::bordercolour' cellspacing='0' cellpadding='0' style='border-collapse: collapse'>
+<tr bgcolor='$color{'color20'}' height='20'>
+       <td width='3%' align='center'><b>$Lang::tr{'wio_id'}</b></td>
+       <td width='4%' align='center'><b>$Lang::tr{'wio_activ'}</b></td>
+       <td width='5%' align='center'><b>$Lang::tr{'wio_check'}</b></td>
+       <td width='15%' align='center'><b>$Lang::tr{'wio checked'}</b></td>
+       <td width='4%' align='center'><b>$Lang::tr{'wio_webinterface'}</b></td>
+       <td width='11%' align='center'><a href='$ENV{'SCRIPT_NAME'}?IPADR'><b>$Lang::tr{'wio ipadress'}</b></a></td>
+       <td width='5%' align='center'><b>$Lang::tr{'wio network'}</b></td>
+       <td width='20%' align='center'><a href='$ENV{'SCRIPT_NAME'}?HOST'><b>$Lang::tr{'wio name'}</b></a></td>
+       <td width='11%' align='center'><b>$Lang::tr{'wio image'}</b></td>
+       <td width='4%' align='center'><form method='post' action='$ENV{'SCRIPT_NAME'}' enctype='multipart/form-data'><input type='hidden' name='ACTION' value='$Lang::tr{'wio_refresh'}' /><input type='image' name='$Lang::tr{'wio_refresh'}' src='$imgstatic/refresh.png' align='middle' alt='$Lang::tr{'wio_refresh'}' title='$Lang::tr{'wio_refresh'}' /></form></td>
+       <td width='4%' colspan='2' align='center'><b>$Lang::tr{'wio_dyndns'}</b></td>
+       <td width='12%' colspan='4' align='center'><b>$Lang::tr{'action'}</b></td>
+       <td width='3%' align='center'><form method='post' action='$ENV{'SCRIPT_NAME'}' enctype='multipart/form-data'><input type='hidden' name='ACTION' value='$Lang::tr{'wio_remove_all'}' /><input type='image' name='$Lang::tr{'wio_remove_all'}' src='/images/delete.gif' align='middle' alt='$Lang::tr{'wio_remove_all'}' title='$Lang::tr{'wio_remove_all'}' onClick=\"return confirm('$Lang::tr{'wio_remove_all_hint'}')\"/></form></td>
+</tr>
+";
+
+for (my $a=0; $a<$nr; $a++) {
+
+my $gif = 'off.gif';
+my $gdesc = $Lang::tr{'wio_client_off'};
+my $dyndnsimg = 'on.gif';
+my $dyndnsimgtxt = $Lang::tr{'wio_dyndns_on'};
+my $mailonimg = 'wio/mailgreenon.png';
+my $mailonimgtxt = $Lang::tr{'wio_mail_online_on'};
+my $mailoffimg = 'wio/mailredon.png';
+my $mailoffimgtxt = $Lang::tr{'wio_mail_offline_on'};
+my $pingimg = '';
+my $pingtxt = '';
+my $webimg = '';
+
+if ( $activ[$a] eq 'on' ) {
+       $gif = 'on.gif';
+       $gdesc = $Lang::tr{'wio_client_on'};
+}
+
+if ( $dyndns[$a] ne 'on' ) {
+       $dyndnsimg = 'off.gif';
+       $dyndnsimgtxt = $Lang::tr{'wio_dyndns_off'};
+}
+
+if ( $sendemailon[$a] ne 'on' ) {
+       $mailonimg = 'wio/mailgreenoff.png';
+       $mailonimgtxt = $Lang::tr{'wio_mail_online_off'};
+}
+
+if ( $sendemailoff[$a] ne 'on' ) {
+       $mailoffimg = 'wio/mailredoff.png';
+       $mailoffimgtxt = $Lang::tr{'wio_mail_offline_off'};
+}
+
+if ( $webinterface[$a] eq 'HTTP' ) {
+       $webimg = 'wio/http.png';
+}
+elsif ( $webinterface[$a] eq 'HTTPS' ) {
+       $webimg = 'wio/https.png';
+}
+else {
+       $webimg = 'wio/none.png';
+}
+
+$bgcolor = $status[$a] eq "on" ? "${Header::colourgreen}" : ($status[$a] eq "off" && $dates[$a] eq "") ? "${Header::colourblue}" : "${Header::colourred}";
+$statustxt = $status[$a] eq "on" ? "$Lang::tr{'wio up'}" : ($status[$a] eq "off" && $dates[$a] eq "") ? "$Lang::tr{'wio_no_image'}" : "$Lang::tr{'wio down'}";
+
+print"<tr".($a % 2?" bgcolor='$color{'color20'}'":" bgcolor='$color{'color22'}'")." height='20'>";
+printf ("<td align='center'> %02d</td>", $a+1);
+
+print"<td align='center'><form method='post' action='$ENV{'SCRIPT_NAME'}' enctype='multipart/form-data'>
+         <input type='hidden' name='ACTION' value='$Lang::tr{'enable disable client'}' />
+         <input type='image' name='$Lang::tr{'enable disable client'}' src='/images/$gif' align='middle' alt='$gdesc' title='$gdesc' />
+         <input type='hidden' name='ID' value='$a' /></form></td>";
+
+if ( $pingmethode[$a] eq 'ip') {
+       print"<td align='center'><form method='post' action='$ENV{'SCRIPT_NAME'}' enctype='multipart/form-data'>
+               <input type='hidden' name='ACTION' value='$Lang::tr{'wio_ip_on'}' />
+               <input type='image' name='$Lang::tr{'wio_ip_on'}' src='/images/wio/ip.png' align='middle' alt='$Lang::tr{'wio_ip_on'}' title='$Lang::tr{'wio_ip_on'}' />
+               <input type='hidden' name='ID' value='$a' /></form></td>";
+}
+else {
+       print"<td align='center'><form method='post' action='$ENV{'SCRIPT_NAME'}' enctype='multipart/form-data'>
+               <input type='hidden' name='ACTION' value='$Lang::tr{'wio_fqdn_on'}' />
+               <input type='image' name='$Lang::tr{'wio_fqdn_on'}' src='/images/wio/fqdn.png' align='middle' alt='$Lang::tr{'wio_fqdn_on'}' title='$Lang::tr{'wio_fqdn_on'}' />
+               <input type='hidden' name='ID' value='$a' /></form></td>";
+}
+
+print"<td align='center'>$dates[$a]</td>";
+
+print"<td align='center'><img align='middle' src='/images/$webimg' /></td>";
+
+if ( $webinterface[$a] eq 'HTTP' ) {
+       print"<td align='center'><a title=\"$Lang::tr{'wio_webinterface_link'}\" href=\"http://$ipaddresses[$a]\" target=\"_blank\">$ipaddresses[$a]</a></td>";
+}
+elsif ( $webinterface[$a] eq 'HTTPS' ) {
+       print"<td align='center'><a title=\"$Lang::tr{'wio_webinterface_link'}\" href=\"https://$ipaddresses[$a]\" target=\"_blank\">$ipaddresses[$a]</a></td>";
+}
+else {
+       print"<td align='center'>$ipaddresses[$a]</td>";
+}
+
+my $dotip = length($ipaddresses[$a]) - rindex($ipaddresses[$a],'.');
+       SWITCH: {
+               foreach (@devs_color) {
+                       my $in = 0;
+                       $ic = "${_}";
+
+                       foreach $interface (@devs_net) {
+                       next if ( $netsettings{"$ic"."_DEV"} eq 'red0' && ($netsettings{"RED_TYPE"} eq 'DHCP' || $netsettings{"RED_TYPE"} eq 'PPPOE'));
+                               if ( $netsettings{"$ic"."_DEV"} eq $interface ) {
+                                       if ( &General::IpInSubnet($ipaddresses[$a], $netsettings{"$ic"."_NETADDRESS"}, $netsettings{"$ic"."_NETMASK"}) ) {
+                                               print"<td align='center' height='20'><img src='$imgstatic/$devs_img[$in]' alt='$Lang::tr{$devs_alt[$in]}' title='$Lang::tr{$devs_alt[$in]}' /></td>";
+                                               last SWITCH;
+                                       }
+                               }
+                       $in++;
+                       }
+               }
+
+               if ($netsettings{"RED_TYPE"} eq 'DHCP' || $netsettings{"RED_TYPE"} eq 'PPPOE') {
+                       my $redipadr = qx'ip addr | grep red0 | grep inet | awk "{print \$2}"';
+                       my @rednet = split ("/", $redipadr);
+                       chomp ($rednet[1]);
+                       my $red_netmask = General::iporsubtodec($rednet[1]);
+                       my $red_netaddress = Network::get_netaddress("$rednet[0]/$red_netmask");
+                                               
+                       if ( &General::IpInSubnet($ipaddresses[$a], $red_netaddress, $red_netmask) ) {
+                               print"<td align='center' height='20'><img src='$imgstatic/red.png' alt='$Lang::tr{'wio_red_lan'}' title='$Lang::tr{'wio_red_lan'}' /></td>";
+                               last SWITCH;
+                       }
+                       else {
+                               print"<td align='center'><img align='middle' src='$imgstatic/white.png' alt='$Lang::tr{'wio_unknown_lan'}' title='$Lang::tr{'wio_unknown_lan'}' /></td>";
+                               last SWITCH;
+                       }
+               }
+
+               if ( -e "$vpnpid" ) {
+                       foreach $key (keys(%vpnconfighash)) {
+                               next unless ($vpnconfighash{$key}[3] eq 'net');
+                               
+                               my $convertip = &General::ipcidr2msk($vpnconfighash{$key}[11]);
+                                                       
+                               my @net = split ("/", $convertip);
+
+                                       $vpnn2nip = $net[0];
+                                       $vpnn2nmask = length($net[1]) - rindex($net[1],'.');
+
+                                       if (substr($ipaddresses[$a],0,length($ipaddresses[$a])-$dotip) eq substr($vpnn2nip,0,length($vpnn2nip)-$vpnn2nmask)) {
+                                               print"<td align='center'><img align='middle' src='$imgstatic/vpn.png' alt='IPSec' title='IPSec' /></td>";
+                                               last SWITCH;
+                                       }
+                       }
+               }
+
+               if ( $ovpnsettings{'DOVPN_SUBNET'} ne '' ) {
+                       @match = split ("/", $ovpnsettings{'DOVPN_SUBNET'});
+
+                       if ( &General::IpInSubnet($ipaddresses[$a], $match[0], $match[1]) ) {
+                               print"<td align='center'><img src='$imgstatic/ovpn.png' alt='OpenVPN' title='OpenVPN' /></td>"; 
+                               last SWITCH; 
+                       }
+               }
+
+               if ( %ovpnccdconfhash ne '' ) {
+                       foreach $key (keys(%ovpnccdconfhash)) {
+                                                               
+                               my $convertip = &General::ipcidr2msk($ovpnccdconfhash{$key}[1]);
+                                                       
+                               my @net = split ("/", $convertip);
+
+                               $vpnn2nip = $net[0];
+                               $vpnn2nmask = length($net[1]) - rindex($net[1],'.');
+
+                               if (substr($ipaddresses[$a],0,length($ipaddresses[$a])-$dotip) eq substr($vpnn2nip,0,length($vpnn2nip)-$vpnn2nmask)) {
+                                       print"<td align='center'><img align='middle' src='$imgstatic/ovpn.png' alt='OpenVPN' title='OpenVPN' /></td>";
+                                       last SWITCH;
+                               }
+                                       
+                       }
+               }
+       }
+
+if ( $webinterface[$a] eq 'HTTP' ) {
+       print"<td align='center'><a title=\"$Lang::tr{'wio_webinterface_link'}\" href=\"http://$names[$a]\" target=\"_blank\">$names[$a]</a></td>";
+}
+elsif ( $webinterface[$a] eq 'HTTPS' ) {
+       print"<td align='center'><a title=\"$Lang::tr{'wio_webinterface_link'}\" href=\"https://$names[$a]\" target=\"_blank\">$names[$a]</a></td>";
+}
+else {
+       print"<td align='center'>$names[$a]</td>";
+}
+
+print"
+       <td>
+               <table bgcolor='$bgcolor' cellpadding='2' cellspacing='0' width='100%'>
+                       <tr height='20'>
+                               <td align='center'><font color='$color{'color21'}'><b>$statustxt</b></font></td>
+                       </tr>
+               </table>
+       </td>
+
+       <td width='3%' align='center'><form method='post' action='$ENV{'SCRIPT_NAME'}' enctype='multipart/form-data'>
+       <input type='hidden' name='ACTION' value='$Lang::tr{'wio_sc_refresh'}' />
+       <input type='image' name='$Lang::tr{'wio_sc_refresh'}' src='$imgstatic/refresh.png' align='middle' alt='$Lang::tr{'wio_sc_refresh'}' title='$Lang::tr{'wio_sc_refresh'}' />
+       <input type='hidden' name='ID' value='$a' /></form></td>
+
+       <td width='3%' align='center'><form method='post' action='$ENV{'SCRIPT_NAME'}' enctype='multipart/form-data'>
+       <input type='hidden' name='ACTION' value='$Lang::tr{'enable disable dyndns'}' />
+       <input type='image' name='$Lang::tr{'enable disable dyndns'}' src='/images/$dyndnsimg' align='middle' alt='$dyndnsimgtxt' title='$dyndnsimgtxt' />
+       <input type='hidden' name='ID' value='$a' /></form></td>";
+
+if ( defined($dyndns[$a]) && ($dyndns[$a] eq 'on') ) {
+       print"<td width='3%' align='center'><form method='post' action='$ENV{'SCRIPT_NAME'}' enctype='multipart/form-data'>
+                 <input type='hidden' name='ACTION' value='$Lang::tr{'wio_dyndns_refresh'}' />
+                 <input type='image' name='$Lang::tr{'wio_dyndns_refresh'}' src='/images/reload.gif' align='middle' alt='$Lang::tr{'wio_dyndns_refresh'}' title='$Lang::tr{'wio_dyndns_refresh'}' />
+                 <input type='hidden' name='ID' value='$a' /></form></td>";
+}
+else {
+       print"<td width='3%' align='center'>-</td>";
+}
+
+if ( -e "/var/log/rrd/wio/$id[$a].rrd" ) {
+       print"
+               <td width='3%' align='center'><form method='post' action='/cgi-bin/wiographs.cgi' enctype='multipart/form-data'>
+               <input type='image' name='$Lang::tr{'wio_graphs'}' src='$imgstatic/graph.png' align='middle' alt='$Lang::tr{'wio_graphs'}' title='$Lang::tr{'wio_graphs'}' />
+               <input type='hidden' name='HOSTID' value='$id[$a]' /><input type='hidden' name='HOSTNAME' value='$names[$a]' /></form></td>
+       ";
+}
+else {
+       print "<td width='3%' align='center'><img src='$imgstatic/no_graph.png' align='middle' alt='$Lang::tr{'wio_no_graphs'}' title='$Lang::tr{'wio_no_graphs'}' /></td>";
+}
+
+if ( $wiosettings{'SENDEMAIL'} eq 'on') {
+       print"<td width='3%' align='center'><form method='post' action='$ENV{'SCRIPT_NAME'}' enctype='multipart/form-data'>
+                 <input type='hidden' name='ACTION' value='$Lang::tr{'wio_mail_online'}' />
+                 <input type='image' name='$Lang::tr{'wio_mail_online'}' src='/images/$mailonimg' align='middle' alt='$mailonimgtxt' title='$mailonimgtxt' />
+                 <input type='hidden' name='ID' value='$a' /></form></td>
+                 <td width='3%' align='center'><form method='post' action='$ENV{'SCRIPT_NAME'}' enctype='multipart/form-data'>
+                 <input type='hidden' name='ACTION' value='$Lang::tr{'wio_mail_offline'}' />
+                 <input type='image' name='$Lang::tr{'wio_mail_offline'}' src='/images/$mailoffimg' align='middle' alt='$mailoffimgtxt' title='$mailoffimgtxt' />
+                 <input type='hidden' name='ID' value='$a' /></form></td>";
+}
+else {
+       print"<td width='3%' align='center'>-</td>
+                 <td width='3%' align='center'>-</td>";
+}
+
+print"
+         <td width='3%' align='center'><form method='post' action='$ENV{'SCRIPT_NAME'}' enctype='multipart/form-data'>
+         <input type='hidden' name='ACTION' value='$Lang::tr{'edit'}' />
+         <input type='image' name='$Lang::tr{'edit'}' src='/images/edit.gif' align='middle' alt='$Lang::tr{'edit'}' title='$Lang::tr{'edit'}' />
+         <input type='hidden' name='ID' value='$a' /></form></td>
+
+         <td width='3%' align='center'><form method='post' action='$ENV{'SCRIPT_NAME'}' enctype='multipart/form-data'>
+         <input type='hidden' name='ACTION' value='$Lang::tr{'wio_remove_client'}' />
+         <input type='image' name='$Lang::tr{'wio_remove_client'}' src='/images/delete.gif' align='middle' alt='$Lang::tr{'wio_remove_client'}' title='$Lang::tr{'wio_remove_client'}' onClick=\"return confirm('$Lang::tr{'wio_remove_client_hint'}')\" />
+         <input type='hidden' name='ID' value='$a' /></form></td></tr>
+";
+
+if ($remark[$a] && $wiosettings{'CLIENTREMARK'} eq 'on') {
+       print"<tr".($a % 2?" bgcolor='$color{'color20'}'":" bgcolor='$color{'color22'}'")." height='20'><td>&nbsp;</td><td colspan='16' align='left'>$remark[$a]</td></tr>";
+}
+       print"<tr height='1'><td colspan='17' bgcolor='#696565'></td></tr>";
+}
+
+print"</table>";
+
+&Header::closebox();
+
+}
+
+## add / modify client
+
+$checked{'EN'}{'on'} = ($wiosettings{'EN'} eq '' ) ? '' : "checked='checked'";
+
+$checked{'DYNDNS'}{'off'} = $checked{'DYNDNS'}{'on'} = '';
+$checked{'DYNDNS'}{$wiosettings{'DYNDNS'}} = "checked='checked'";
+
+$checked{'SENDEMAILON'}{'off'} = $checked{'SENDEMAILON'}{'on'} = '';
+$checked{'SENDEMAILON'}{$wiosettings{'SENDEMAILON'}} = "checked='checked'";
+
+$checked{'SENDEMAILOFF'}{'off'} = $checked{'SENDEMAILOFF'}{'on'} = '';
+$checked{'SENDEMAILOFF'}{$wiosettings{'SENDEMAILOFF'}} = "checked='checked'";
+
+if (! defined($errormessage) && $wiosettings{'ACTION'} ne $Lang::tr{'edit'} ) {
+       $wiosettings{'PINGMETHODE'} = 'ip';
+}
+
+$checked{'PINGMETHODE'}{'ip'} = $checked{'PINGMETHODE'}{'fqdn'} = '';
+$checked{'PINGMETHODE'}{$wiosettings{'PINGMETHODE'}} = "checked='checked'";
+
+$selected{'WEBINTERFACE'}{'----'} = '';
+$selected{'WEBINTERFACE'}{'HTTP'} = '';
+$selected{'WEBINTERFACE'}{'HTTPS'} = '';
+$selected{'WEBINTERFACE'}{$wiosettings{'WEBINTERFACE'}} = "selected='selected'";
+
+$buttontext = $Lang::tr{'wio_client_add'};
+
+if ( $wiosettings{'ACTION'} eq $Lang::tr{'edit'} || defined($errormessage)  && ! defined($message) ) {
+       &Header::openbox('100%', 'left', $Lang::tr{'wio_edit_client'});
+       $buttontext = $Lang::tr{'update'};
+}
+else {
+       &Header::openbox('100%', 'left', $Lang::tr{'wio_edit_settings'});
+}
+
+if (! defined($errormessage) && $wiosettings{'ACTION'} ne $Lang::tr{'edit'} ) {
+print"
+<table width='100%' border='0' bordercolor='$Header::bordercolour' cellspacing='0' cellpadding='0' style='border-collapse: collapse'>
+<tr>
+       <td width='28%' bgcolor='$color{'color20'}' align='left' height='20'><b>&nbsp;$Lang::tr{'wio_add'}</b></td>
+       <td width='72%' align='right'>&nbsp;</td>
+</tr>
+<tr>
+       <td>&nbsp;</td>
+</tr>
+</table>
+";
+}
+
+print"
+<form method='post' action='$ENV{'SCRIPT_NAME'}'>
+<input type='hidden' name='ID' value='$wiosettings{'ID'}' />
+<input type='hidden' name='CLIENTID' value='$wiosettings{'CLIENTID'}' />
+<input type='hidden' name='ONLINE' value='$wiosettings{'ONLINE'}' />
+<input type='hidden' name='TIMESTAMP' value='$wiosettings{'TIMESTAMP'}' />
+";
+
+print"
+<table width='100%' border='0' bordercolor='$Header::bordercolour' cellspacing='0' cellpadding='0' style='border-collapse: collapse'>
+<tr>
+       <td height='30'>$Lang::tr{'wio_client_enable'}</td>
+       <td align='left'><input type='checkbox' name='EN' $checked{'EN'}{'on'} /></td>
+       <td colspan='4'>&nbsp;</td>
+</tr>
+<tr>
+       <td height='30'>$Lang::tr{'wio ipadress'}:</td>
+       <td align='left'><input type='text' name='IPADR' value='$wiosettings{'IPADR'}' size='25' /></td>
+       <td>$Lang::tr{'wio name'}:</td>
+       <td align='left'><input type='text' name='HOST' value='$wiosettings{'HOST'}' size='25' /></td>
+       <td>$Lang::tr{'remark'}:</td>
+       <td align='left'><input type='text' name='REMARK' value='$wiosettings{'REMARK'}' size='30'></td>
+</tr>
+<tr>
+       <td height='30'>$Lang::tr{'wio_ping_send'}:</td>
+       <td align='left'><input type='radio' name='PINGMETHODE' value='ip' $checked{'PINGMETHODE'}{'ip'} />&nbsp;IP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type='radio' name='PINGMETHODE' value='fqdn' $checked{'PINGMETHODE'}{'fqdn'} />&nbsp;FQDN</td>
+       <td>$Lang::tr{'wio_dyndns'}:</td>
+       <td align='left'><input type='checkbox' name='DYNDNS' $checked{'DYNDNS'}{'on'} /></td>
+";
+
+if ( $wiosettings{'SENDEMAIL'} eq 'on' ) {
+       print"<td>$Lang::tr{'wio_sendemail'}:</td>
+                 <td><input type='checkbox' name='SENDEMAILON' $checked{'SENDEMAILON'}{'on'} />&nbsp;$Lang::tr{'wio_online'}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type='checkbox' name='SENDEMAILOFF' $checked{'SENDEMAILOFF'}{'on'} />&nbsp;$Lang::tr{'wio_offline'}</td>";
+}
+else {
+       print"<td colspan='2'>&nbsp;</td>";
+}
+
+print"
+</tr>
+<tr>
+       <td height='30'>$Lang::tr{'wio_ping_send'}:</td>
+       <td align='left' colspan='5'>
+               <select size='1' name='WEBINTERFACE' width='80' style='width: 80px'>
+               <option value='----' $selected{'WEBINTERFACE'}{'----'}>----</option>
+               <option value='HTTP' $selected{'WEBINTERFACE'}{'HTTP'}>HTTP</option>
+               <option value='HTTPS' $selected{'WEBINTERFACE'}{'HTTPS'}>HTTPS</option>
+               </select>
+       </td>
+</tr>
+</table>
+<table width='100%' cellspacing='0' cellpadding='0' style='border-collapse: collapse'>
+<tr>
+       <td width='20%' align='center'>&nbsp;</td>
+";
+
+if ( $buttontext eq $Lang::tr{'update'} && ( defined($errormessage) || $wiosettings{'ACTION'} eq $Lang::tr{'edit'}) && ! defined($message) ) {
+       print"<td width='20%' align='center'>&nbsp;</td>
+                 <td width='20%' align='center'>&nbsp;</td>
+                 <td width='20%' align='center'><input type='hidden' name='ACTION' value='$Lang::tr{'wio_client_add'}' /><input type='submit' name='SUBMIT' value='$buttontext' /></td>
+                 <td width='20%' align='center'><input type='button' onClick='location.href=\"/cgi-bin/wio.cgi\"' value='$Lang::tr{'wio_back'}'></form></td>";
+}
+else {
+       print"<td width='20%' align='center'>&nbsp;</td>
+                 <td width='20%' align='center'>&nbsp;</td>
+                 <td width='20%' align='center'>&nbsp;</td>
+                 <td width='20%' align='right'><input type='hidden' name='ACTION' value='$Lang::tr{'wio_client_add'}' /><input type='submit' name='SUBMIT' value='$buttontext' /></form></td>";
+}
+
+print"
+</tr>
+</table>
+";
+
+if ( $wiosettings{'ENABLE'} eq 'on' && !$errormessage && $wiosettings{'ACTION'} ne $Lang::tr{'edit'} || $message == 2 ) {
+
+&hrline();
+
+## arp table entries
+
+print"
+<table border='0' width='100%' bordercolor='$Header::bordercolour' cellspacing='0' cellpadding='0' style='border-collapse: collapse'>
+<tr>
+       <td width='28%' bgcolor='$color{'color20'}' align='left' height='20'><b>&nbsp;$Lang::tr{'wio_arp_table_entries'}</b></td>
+       <td width='72%'>&nbsp;</td>
+</tr>
+<tr><td colspan='2'>&nbsp;</td></tr>
+</table>
+
+<table border='0' width='100%' bordercolor='$Header::bordercolour' cellspacing='0' cellpadding='0' style='border-collapse: collapse'>
+<tr bgcolor='$color{'color20'}'>
+       <td width='5%' align='center' height='20'><b>$Lang::tr{'wio_id'}</b></td>
+       <td width='20%' align='center' height='20'><b>$Lang::tr{'wio_hwaddress'}</b></td>
+       <td width='20%' align='center' height='20'><b>$Lang::tr{'wio ipadress'}</b></td>
+       <td width='15%'  align='center' height='20'><b>$Lang::tr{'wio network'}</b></td>
+       <td width='20%' align='center' height='20'><b>$Lang::tr{'wio name'}</b></td>
+       <td width='15%' align='center' height='20'><b>$Lang::tr{'wio_iface'}</b></td>
+       <td width='5%' align='center' height='20'><b>$Lang::tr{'action'}</b></td>
+</tr>
+";
+
+$output = `/sbin/ip neigh list`;
+$output = &Header::cleanhtml($output,"y");
+
+my $arpcnt = 0;
+
+foreach $line (split(/\n/, $output))
+{
+       if ($line =~ m/^(.*) dev ([^ ]+) lladdr ([0-9a-f:]*) (.*)$/) {
+               my $arphost = gethostbyaddr(inet_aton($1), AF_INET);
+               if ( $arphost eq 'localhost' ) { $arphost = ''; }
+               push (@arpcache, "$3,$1,$arphost,$2\n");
+       }
+       elsif ($line =~ m/^(.*) dev ([^ ]+)  (.*)$/) {
+               my $arphost = gethostbyaddr(inet_aton($1), AF_INET);
+               if ( $arphost eq 'localhost' ) { $arphost = ''; }
+               push (@arpcache, ",$1,$arphost,$2\n");
+       }
+
+       $arpcnt++;
+}
+
+&SortDataFile('arpcache',@arpcache);
+
+foreach (@arpcache) {
+       chomp;
+
+       @line = split (/\,/, $_);
+
+       print"<tr".($idarp % 2?" bgcolor='$color{'color20'}'":" bgcolor='$color{'color22'}'")." height='20'>";
+       printf ("<td align='center'> %02d</td>", $idarp+1);
+       print"<td align='center'>$line[0]</td>
+                 <td align='center'>$line[1]</td>";
+
+SWITCH: {
+
+       foreach (@devs_color) {
+               my $in = 0;
+               $ic = "${_}";
+
+               foreach $interface (@devs_net) {
+                       next if ( $netsettings{"$ic"."_DEV"} eq 'red0' && ($netsettings{"RED_TYPE"} eq 'DHCP' || $netsettings{"RED_TYPE"} eq 'PPPOE'));
+
+                       if ($netsettings{"$ic"."_DEV"} eq $interface) {
+                               if ( &General::IpInSubnet($line[1], $netsettings{"$ic"."_NETADDRESS"}, $netsettings{"$ic"."_NETMASK"}) ) {
+                                       print"<td align='center'><img src='$imgstatic/$devs_img[$in]' alt='$Lang::tr{$devs_alt[$in]}' title='$Lang::tr{$devs_alt[$in]}' /></td>";
+                                       last SWITCH;
+                               }
+                       }
+
+                       $in++;
+               }
+       }
+
+                       if ($netsettings{"RED_TYPE"} eq 'DHCP' || $netsettings{"RED_TYPE"} eq 'PPPOE') {
+                       my $redipadr = qx'ip addr | grep red0 | grep inet | awk "{print \$2}"';
+                       my @rednet = split ("/", $redipadr);
+                       chomp ($rednet[1]);
+                       my $red_netmask = General::iporsubtodec($rednet[1]);
+                       my $red_netaddress = Network::get_netaddress("$rednet[0]/$red_netmask");
+
+                       if ( &General::IpInSubnet($line[1], $red_netaddress, $red_netmask) ) {
+                               print"<td align='center' height='20'><img src='$imgstatic/red.png' alt='$Lang::tr{'wio_red_lan'}' title='$Lang::tr{'wio_red_lan'}' /></td>";
+                               last SWITCH;
+                       }
+                       else {
+                               print"<td align='center'><img align='middle' src='$imgstatic/white.png' alt='$Lang::tr{'wio_unknown_lan'}' title='$Lang::tr{'wio_unknown_lan'}' /></td>";
+                               last SWITCH;
+                       }
+               }
+}
+
+       print"<td align='center'>$line[2]</td>
+                 <td align='center'>".&WIO::color_devices($line[3])."</td>";
+
+       unless (&WIO::checkinto($line[1], '', @current)) {
+               print"<td align='center'><form method='post' action='$ENV{'SCRIPT_NAME'}' enctype='multipart/form-data'>
+                         <input type='hidden' name='ACTION' value='$Lang::tr{'wio_add'}' />
+                         <input type='image' name='$Lang::tr{'wio_add'}' src='/images/add.gif' align='middle' alt='$Lang::tr{'wio_add'}' title='$Lang::tr{'wio_add'}' />
+                         <input type='hidden' name='ID' value='$idarp' /></form></td>";
+       }
+       else {
+               print"<td align='center'><img src='$imgstatic/add.png' align='middle' alt='$Lang::tr{'wio_no_add'}' title='$Lang::tr{'wio_no_add'}' /></td>";
+       }
+
+print"</tr>";
+print"<tr height='1'><td colspan='17' bgcolor='#696565'></td></tr>";
+$idarp++
+}
+
+print"
+</table>
+";
+
+&hrline();
+
+print"
+<table border='0' width='100%' bordercolor='$Header::bordercolour' cellspacing='0' cellpadding='0' style='border-collapse: collapse'>
+<tr>
+       <td width='28%' bgcolor='$color{'color20'}' align='left' height='20'><b>&nbsp;$Lang::tr{'wio_import_file'}</b></td>
+       <td width='72%'>&nbsp;</td>
+</tr>
+<tr><td colspan='2'>&nbsp;</td></tr>
+</table>
+<table width='100%' cellspacing='0' cellpadding='0' style='border-collapse: collapse'>
+<tr bgcolor='$color{'color22'}'>
+       <form method='post' action='/cgi-bin/wio.cgi' enctype='multipart/form-data'>
+       <td width='35%' align='right'>$Lang::tr{'wio_import_csv'}&nbsp;</td>
+       <td width='40%' align='center'><input type='file' name='CSVFILE' size='30' /></td>
+       <td width='25%' align='right'><input type='hidden' name='ACTION' value='$Lang::tr{'wio_import'}1' /><input type='submit' name='SUBMIT' value='$Lang::tr{'wio_import'}' /></td>
+       </form>
+</tr>
+<tr><td colspan='3'>&nbsp;</td></tr>
+<tr bgcolor='$color{'color22'}'>
+       <form method='post' action='/cgi-bin/wio.cgi' enctype='multipart/form-data'>
+       <td width='35%' align='right'>$Lang::tr{'wio_import_hosts'}&nbsp;</td>
+       <td width='40%' align='center'>&nbsp;</td>
+       <td width='25%' align='right'><input type='hidden' name='ACTION' value='$Lang::tr{'wio_import'}2' /><input type='submit' name='SUBMIT' value='$Lang::tr{'wio_import'}' /></td>
+       </form>
+</tr>
+<tr><td colspan='3'>&nbsp;</td></tr>
+<tr bgcolor='$color{'color22'}'>
+       <form method='post' action='/cgi-bin/wio.cgi' enctype='multipart/form-data'>
+       <td width='35%' align='right'>$Lang::tr{'wio_import_fixleases'}&nbsp;</td>
+       <td width='40%' align='center'>&nbsp;</td>
+       <td width='25%' align='right'><input type='hidden' name='ACTION' value='$Lang::tr{'wio_import'}3' /><input type='submit' name='SUBMIT' value='$Lang::tr{'wio_import'}' /></td>
+       </form>
+</tr>
+</table>
+";
+
+&hrline;
+
+print"
+<table border='0' width='100%' bordercolor='$Header::bordercolour' cellspacing='0' cellpadding='0' style='border-collapse: collapse'>
+<tr>
+       <td width='28%' bgcolor='$color{'color20'}' align='left' height='20'><b>&nbsp;$Lang::tr{'wio_net_scan'}</b></td>
+       <td width='72%'>&nbsp;</td>
+</tr>
+</table>
+<table width='100%' cellspacing='0' cellpadding='0' style='border-collapse: collapse'>
+<tr>
+       <td colspan='3'>&nbsp;</td>
+</tr>
+";
+
+foreach (keys(%ifacecolor)) {
+       if ( $_ eq 'GREEN' ) { $color = "$Header::colourgreen"; $net = $Lang::tr{'wio_net_scan_green'}; }
+       elsif ( $_ eq 'BLUE' ) { $color = "$Header::colourblue"; $net = $Lang::tr{'wio_net_scan_blue'}; }
+       else { $color = "$Header::colourorange"; $net = $Lang::tr{'wio_net_scan_orange'}; }
+
+       if ( $netsettings{"${_}_DEV"} eq 'disabled' || $netsettings{"${_}_DEV"} eq '' || $netsettings{"${_}_ADDRESS"} eq '' ) { next; }
+       else {
+               print <<END;
+
+                       <tr bgcolor='$color{'color22'}'>
+                               <td width='35%' align='right'><form method='post' action='$ENV{'SCRIPT_NAME'}' enctype='multipart/form-data'>$Lang::tr{'wio_net_scan_vl'} <font color='$color'><b>$net</b></font> $Lang::tr{'wio_net_scan_l'}<font color='$color'><b> $netsettings{"${_}_DEV"} </b></font>$Lang::tr{'wio_net_scan_r'}</td>
+                               <td width='40%' align='center'><input type='text' name='${_}_IPLOW' value='$wiosettings{"${_}_IPLOW"}' size='14' STYLE='background-color:$color; text-align: center; color:white' /> - <input type='text' name='${_}_IPHIGH' value='$wiosettings{"${_}_IPHIGH"}' size='14' STYLE='background-color:$color; text-align: center; color:white' /></td>
+                               <td width='25%' align='right'><input type='hidden' name='ACTION' value='$ifacecolor{$_}' /><input type='hidden' name='ID' value='$netsettings{"${_}_DEV"}' /><input type='submit' name='SUBMIT' value='$Lang::tr{'wio_net_scan_run'}'></form></td>
+                       </tr>
+                       <tr>
+                               <td colspan='3'>&nbsp;</td>
+                       </tr>
+END
+       }
+}
+
+print"
+</tr>
+</table>
+</form>
+";
+
+&Header::closebox();
+}
+
+if ( $wiosettings{'ENABLE'} eq 'on' && !$errormessage && $wiosettings{'ACTION'} ne $Lang::tr{'edit'} || $message == 2 ) {
+
+&Header::openbox('100%', 'left', $Lang::tr{'wio_service'});
+
+print"
+<table border='0' width='100%' bordercolor='$Header::bordercolour' cellspacing='0' cellpadding='0' style='border-collapse: collapse'>
+<tr bgcolor='$color{'color22'}'>
+       <td colspan='3' align='right'></td>
+       <td width='20%' align='right'><form method='post' action='$ENV{'SCRIPT_NAME'}' enctype='multipart/form-data'><input type='hidden' name='ACTION' value='$Lang::tr{'edit'}1' /><input type='submit' name='SUBMIT' value='$Lang::tr{'wio_edit_set'}' /></form></td>
+       <form method='post' action='$ENV{'SCRIPT_NAME'}' enctype='multipart/form-data'>\n
+</tr>
+</table>
+";
+}
+
+&Header::closebox();
+}
+
+&Header::closebigbox();
+&Header::closepage();
+
+############################################################################################################################
+
+sub SortDataFile {
+my ($data,@checkfile) = @_;
+       my $idsort = 0;
+       our %entries = ();
+
+       sub sortips {
+               my $qs = '';
+
+               if (rindex ($wiosettings{'SORT'},'Rev') != -1) {
+                       $qs = substr ($wiosettings{'SORT'},0,length($wiosettings{'SORT'})-3);
+
+                       if ($qs eq 'IPADR') {
+                               my @a = split (/\./,$entries{$a}->{$qs});
+                               my @b = split (/\./,$entries{$b}->{$qs});
+                               ($b[0]<=>$a[0]) ||
+                               ($b[1]<=>$a[1]) ||
+                               ($b[2]<=>$a[2]) ||
+                               ($b[3]<=>$a[3]);
+                       }
+                       else {
+                               $entries{$b}->{$qs} cmp $entries{$a}->{$qs};
+                       }
+               }
+               else {
+                       $qs = $wiosettings{'SORT'};
+
+                       if ($qs eq 'IPADR') {
+                               my @a = split (/\./,$entries{$a}->{$qs});
+                               my @b = split (/\./,$entries{$b}->{$qs});
+                               ($a[0]<=>$b[0]) ||
+                               ($a[1]<=>$b[1]) ||
+                               ($a[2]<=>$b[2]) ||
+                               ($a[3]<=>$b[3]);
+                       }
+                       else {
+                               $entries{$a}->{$qs} cmp $entries{$b}->{$qs};
+                       }
+               }
+       }
+
+       if ($data eq 'arpcache') {
+               foreach (@checkfile) {
+                       chomp;
+                       @temp = split (',', $_);
+
+                       my @record = ('KEY',$idsort++,'MAC',$temp[0],'IPADR',$temp[1],'HOST',$temp[2],'REMARK',$temp[3],'IFACE',$temp[4]);
+                       my $record = ();
+                       %{$record} = @record; 
+                       $entries{$record->{KEY}} = $record;
+               }
+
+               open(FILE, "> $logdir/.arpcache");
+
+               foreach (sort sortips keys %entries) {
+                       print FILE "$entries{$_}->{MAC},$entries{$_}->{IPADR},$entries{$_}->{HOST},$entries{$_}->{REMARK},$entries{$_}->{IFACE},$entries{$_}->{HW}\n";
+               }
+
+               close(FILE);
+
+               open (FILE, "$logdir/.arpcache");
+               @arpcache = <FILE>;
+               close (FILE);
+       }
+       else {
+               foreach (@checkfile) {
+                       chomp;
+                       @temp = split (',', $_);
+
+                       my @record = ('KEY',$idsort++,'CLIENTID',$temp[0],'TIMESTAMP',$temp[1],'IPADR',$temp[2],'HOST',$temp[3],'EN',$temp[4],'REMARK',$temp[5],'DYNDNS',$temp[6],'SENDEMAILON',$temp[7],'SENDEMAILOFF',$temp[8],'PINGMETHODE',$temp[9],'ONLINE',$temp[10],'WEBINTERFACE',$temp[11]);
+                       my $record = ();
+                       %{$record} = @record; 
+                       $entries{$record->{KEY}} = $record;
+               }
+
+               open(FILE, "> $ipadrfile");
+
+               foreach (sort sortips keys %entries) {
+                       print FILE "$entries{$_}->{CLIENTID},$entries{$_}->{TIMESTAMP},$entries{$_}->{IPADR},$entries{$_}->{HOST},$entries{$_}->{EN},$entries{$_}->{REMARK},$entries{$_}->{DYNDNS},$entries{$_}->{SENDEMAILON},$entries{$_}->{SENDEMAILOFF},$entries{$_}->{PINGMETHODE},$entries{$_}->{ONLINE},$entries{$_}->{WEBINTERFACE}\n";
+               }
+
+               close(FILE);
+
+               &loadips();
+       }
+}
+
+############################################################################################################################
+
+sub hrline { 
+
+print"<table width='100%'><tr><td colspan='2' height='35'><hr></td></tr></table>";
+
+}
+
+############################################################################################################################
+
+sub back {
+
+print"<table width='100%'><tr><td width='10%'><a href='/cgi-bin/wio.cgi'><img src='/images/wio/back.png' alt='$Lang::tr{'wio_back'}' title='$Lang::tr{'wio_back'}' /></a></td><td>&nbsp;</td></tr></table>";
+
+}
+
+############################################################################################################################
+
+sub loadips {
+
+&General::readhasharray($ipadrfile, \%ipshash);
+
+open(FILE, "< $ipadrfile");
+@current = <FILE>;
+close (FILE);
+
+}
+
+############################################################################################################################
+
+sub writeips {
+
+open(FILE, "> $ipadrfile");
+if ( defined($write) ) { print FILE @write; }
+else { print FILE @current; }
+close(FILE);
+
+}
+
+############################################################################################################################
+
+sub SortByTunnelName
+{
+    if ($vpnconfighash{$a}[1] lt $vpnconfighash{$b}[1]) {
+        return -1;
+    }
+    elsif ($vpnconfighash{$a}[1] gt $vpnconfighash{$b}[1]) {
+        return 1;
+    }
+    else {
+        return 0;
+    }
+}
+
+############################################################################################################################
+
+sub validSave
+{
+       if ( $wiosettings{'IPADR'} eq '' && $wiosettings{'PINGMETHODE'} eq 'ip' && $wiosettings{'DYNDNS'} eq '' ) {
+               $errormessage = $Lang::tr{'wio_ip_empty'};
+       }
+
+       if ( $wiosettings{'IPADR'} ne '' && (! &General::validip($wiosettings{'IPADR'})) ) {
+               $errormessage = $Lang::tr{'wio_ip_error'};
+       }
+
+       if ( $wiosettings{'HOST'} eq '' && $wiosettings{'PINGMETHODE'} eq 'fqdn' ) {
+               $errormessage = $Lang::tr{'wio_host_empty'};
+       }
+
+       if ( $wiosettings{'HOST'} ne '' && (! &General::validdomainname($wiosettings{'HOST'})) ) {
+               $errormessage = $Lang::tr{'wio_host_error'};
+       }
+
+       if ( $wiosettings{'DYNDNS'} eq 'on' && (! defined($errormessage)) ) {
+               unless(&General::validfqdn($wiosettings{'HOST'})) { $errormessage = $Lang::tr{'wio_fqdn_error'}; }
+               ( $wiosettings{'IPADR'}, $infomessage ) = &WIO::getdyndnsip($wiosettings{'IPADR'}, $wiosettings{'HOST'});
+               $wiosettings{'PINGMETHODE'} = 'fqdn';
+       }
+
+       if ( $wiosettings{'ID'} eq '' && ! defined($errormessage) ) { $errormessage = &WIO::checkinto($wiosettings{'IPADR'}, $wiosettings{'HOST'}, @current); }
+
+       if ( $wiosettings{'REMARK'} ne '' ) { $wiosettings{'REMARK'} =~ s/,/&#44;/g; }
+}
diff --git a/src/wio/wiographs.cgi b/src/wio/wiographs.cgi
new file mode 100644 (file)
index 0000000..234d287
--- /dev/null
@@ -0,0 +1,73 @@
+#!/usr/bin/perl
+#
+###############################################################################
+#                                                                             #
+# IPFire.org - A linux based firewall                                         #
+# Copyright (C) 2017 Stephan Feddersen <addons@h-loit.de>                     #
+# All Rights Reserved.                                                        #
+#                                                                             #
+# 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 3 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, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+###############################################################################
+#
+# id: wiographs.cgi, v1.3.1 2017/07/11 21:31:16 sfeddersen
+#
+# This wiographs.cgi is based on the Code from the IPCop WIO Addon
+# and is extremly adapted to work with IPFire.
+#
+# Autor: Stephan Feddersen
+# Co-Autor: Alexander Marx
+#
+
+use strict;
+
+# enable only the following on debugging purpose
+#use warnings;
+#no warnings 'once';
+#use CGI::Carp 'fatalsToBrowser';
+
+use CGI;
+my $cgi = new CGI;
+my $hostid  = $cgi->param("HOSTID");
+my $hostname = $cgi->param("HOSTNAME");
+
+require '/var/ipfire/general-functions.pl';
+require '/var/ipfire/header.pl';
+require '/var/ipfire/lang.pl';
+require '/usr/lib/wio/wio-graphs.pl';
+
+my @querry =  split(/\?/,$ENV{'QUERY_STRING'});
+
+$querry[0] = '' unless defined $querry[0]; # hostid
+$querry[1] = '' unless defined $querry[1]; # period
+$querry[2] = '' unless defined $querry[2]; # hostname
+
+if ($querry[0] =~ "$hostid") {
+       print "Content-type: image/png\n\n";
+       binmode(STDOUT);
+       &WIOGraphs::wio($querry[0], $querry[2], $querry[1]);
+}
+else {
+       &Header::showhttpheaders();
+       &Header::openpage("$Lang::tr{'wio'}", 1, '');
+       &Header::openbigbox('100%', 'left');
+       &Header::openbox('100%', 'left', "$Lang::tr{'wio_graphs_stat'} $hostname");
+       &WIOGraphs::wiographbox("wiographs.cgi","$hostid","day","$hostname");
+       print"<table width='100%'><tr><td><a href='/cgi-bin/wio.cgi'><img src='/images/wio/back.png' alt='$Lang::tr{'wio_back'}' title='$Lang::tr{'wio_back'}' /></a></td></tr></table>";
+       &Header::closebox();
+       &Header::closebigbox();
+       &Header::closepage();
+}
+
+1;
diff --git a/src/wio/wioips b/src/wio/wioips
new file mode 100644 (file)
index 0000000..e69de29