Commit ef4d1e3f authored by 's avatar
Browse files

Major update (MySQL support removed, using scope instead of

individual hosts, a lot of cleanup)


git-svn-id: file:///home/svn/mapi/trunk@689 8d5bb341-7cf1-0310-8cf6-ba355fef3186
parent d06f4c70
CC=gcc
LD=gcc
CFLAGS=-g -O2 -Wall -DDIMAPI
LIBS=/usr/local/mapi/lib/mapi/mapi.so -lmysqlclient -lreadline
LIBS=/usr/local/mapi/lib/libmapi.so -lreadline
AR=/usr/bin/ar
RANLIB=ranlib
INSTALL=/usr/bin/install -c
LIB_DIRS=
RLIB_DIRS=
RLIB_DIRS=/usr/local/mapi/lib
INCLUDE_DIRS=
INSTALL_DIR=/usr/local/abw
TARGETS=abw abw_dummy test_abw_time test_config
# OBJS=abw.o abw_common.o abw_mysql.o abw_time.o abw_dummy.o test_abw_time.o test_config.o abw_conf.o
TARGETS=abw test_abw_time test_config
# OBJS=abw.o abw_common.o abw_time.o test_abw_time.o test_config.o abw_conf.o
all: $(TARGETS)
......@@ -22,17 +22,17 @@ all: $(TARGETS)
# $(AR) rv $@ $(LIBSCAMPI_OBJS)
# $(RANLIB) $@
abw: abw.o abw_common.o abw_mysql.o abw_time.o abw_conf.o abw_rrd.o
$(LD) -o $@ abw.o abw_common.o abw_mysql.o abw_time.o abw_conf.o abw_rrd.o $(LIB_DIRS) $(LIBS) -Wl,-rpath,$(RLIB_DIRS)
abw: abw.o abw_common.o abw_time.o abw_conf.o abw_rrd.o
$(LD) -o $@ abw.o abw_common.o abw_time.o abw_conf.o abw_rrd.o $(LIB_DIRS) $(LIBS) -Wl,-rpath,$(RLIB_DIRS)
abw_dummy: abw_dummy.o
$(LD) -o $@ abw_dummy.o $(LIB_DIRS) $(LIBS) -Wl,-rpath,$(RLIB_DIRS)
#abw_dummy: abw_dummy.o
# $(LD) -o $@ abw_dummy.o $(LIB_DIRS) $(LIBS) -Wl,-rpath,$(RLIB_DIRS)
test_abw_time: test_abw_time.o abw_time.o
$(LD) -o $@ test_abw_time.o abw_time.o $(LIB_DIRS) $(LIBS) -Wl,-rpath,$(RLIB_DIRS)
test_config: test_config.o ../../parseconf.o
$(LD) -o $@ test_config.o ../../parseconf.o
test_config: test_config.o ../../src/common/.libs/parseconf.o
$(LD) -o $@ test_config.o ../../src/common/.libs/parseconf.o
clean:
rm -f *.o *.a $(TARGETS)
......@@ -40,6 +40,7 @@ clean:
install: all
mkdir -p $(INSTALL_DIR)
mkdir -p $(INSTALL_DIR)/.ssh
mkdir -p $(INSTALL_DIR)/bin
mkdir -p $(INSTALL_DIR)/etc
mkdir -p $(INSTALL_DIR)/graph
......@@ -53,3 +54,7 @@ install: all
cp -u abw_const.cfg $(INSTALL_DIR)/etc
cp mapi.sh /usr/local/bin
cp abw.sh /usr/local/bin
chown abw.abw $(INSTALL_DIR) $(INSTALL_DIR)/.ssh $(INSTALL_DIR)/.ssh/authorized_keys $(INSTALL_DIR)/graph
chmod 700 $(INSTALL_DIR)/.ssh
chmod 600 $(INSTALL_DIR)/.ssh/authorized_keys
chmod 770 $(INSTALL_DIR)/graph
- Add more applications protocols to tracking library (skype)
- Check all failure returns, if we could continue with error report
- What if some remote stations are not accessible during mapi_connect() ?
(it appears that the whole mapi_connect() fails and no report is given
about which particular remote stations were not accessible)
- Add monitoring of:
- connect to mapicommd + mapid
- non-zero results (broken connection) and possibly reconnect
- non-negligible results (moved packet source)
- Check if subjects in a scope use mixed MPLS and non-MPLS links
- Check if different parameters request different time intervals
- Remove direct references to files, use configuration
This diff is collapsed.
# [global] section includes parameters for abw application which are common
# to all flows, such as MySQL database access information. If you generate
# this configuration file, you MUST also include this [global] section.
# Optional [global] section includes information common to all flows.
[global]
db=abw
user=abw
passwd=lab10
# [interface] section specifies link-ends where the measurement should be done.
# You MUST specify:
# 1) id
# 2) hostname or ip
# 3) interface
# You CAN optionally specify link_mbps and direction. Default link_mbps is
# 1000 and default direction is in. Multiple [subject] sections CAN be
# specified for several measurements done on diferent link-ends.
# There must be one [subject] section for each monitored link. Each [subject]
# section MUST include id, hostname and interface.
[subject]
id=1
......@@ -26,51 +15,52 @@ id=2
hostname=perfmon1.cesnet.cz
interface=eth2
# [parameters] section specifies measurement parameters. You MUST specify id.
# You CAN specify more parameters (and in most cases you SHOULD):
# 1) header_filter (in libpcap format, default is no header filtering),
# 2) sau_mode (as d, b or p, default is d)
# 3) sau_threshold (default is 1 for d, 3000 for b and 0.5 for p)
# 4) payload_string (can be specified multiple times, default is no payload
# searching),
# 5) interval_sec (default is 1) and interval_usec (default is 0)
# Values CANNOT include spaces except for header_filter, which CAN include
# spaces. Multiple [parameters] sections CAN be specified for several
# measurements done on the same or on different link-ends.
# There must be one [scope] section for each set of one or more monitored links,
# which should be monitored together. Each [subject] section MUST include id
# and subject_ids.
#
# Note that you cannot include in one [scope] subjects that some use MPLS and
# some not. This is because monitoring of MPLS links requires extending
# header filter applied by BPF_FILTER to a [scope]. Use one [scope] for
# MPLS links and one [scope] for non-MPLS links.
[scope]
id=1
subject_ids=1,2
# There must be one [parameters] section for each [scope] section, specifying
# measurement parameters. Each [paramaters] section MUST include id. It CAN
# optionally include header_filter, sau_mode, sau_threshold, payload_string,
# interval_sec and interval_usec.
# sau_mode can be d for deterministic, b for byte-deterministic or
# p for probabilistic, default is d
#
# sau_threshold can be number of packets for d (default is 1), number of
# bytes for b (default is 3000) or pass probability for p (default is 0.5)
#
# payload_string can be specified multiple times
#
# default interval_sec is 1 and default interval_usec is 0
[parameters]
id=1
# header_filter=src net 195.113.0.0/16
header_filter=src net 195.113.0.0/16
sau_mode=d
sau_threshold=1
# payload_string=virus
payload_string=virus
interval_sec=1
interval_usec=0
[parameters]
id=2
# [measurement] section specifies one measurement to be done on some subject
# with some parameters. You MUST specify:
# 1) subject_id
# 2) parameters_id
# You CAN specify id, protocols (can be any combination of all, tcp, udp,
# multicast and ipv6, default is all), start_time_string (default is
# 01.01.1970-01:00:00) end_time_string (default is 01.01.2038-01:00:00),
# characteristics (default is bytes,packets,mbps) and statistics (default
# is average). Multiple [measurement] sections CAN be specified.
# There must be one [measurement] section for each measurement on some
# [subject] with some [parameters]. Each [meadurement] section MUST include
# id, scope_id and parameters_id. It CAN optionally include protocols.
[measurement]
id=1
subject_id=1
scope_id=1
parameters_id=1
start_time_string=01.01.2005-00:00:00
end_time_string=31.12.2037-23:59:59
protocols=all,tcp,udp,ipv6,multicast
characteristics=bytes,packets,mbps
statistics=average
[measurement]
id=2
subject_id=2
parameters_id=2
protocols=all,tcp,udp,ipv6,multicast,http,https
#ifndef __ABW_H
#define __ABW_H
#define _XOPEN_SOURCE /* glibc2 needs this */
#include <time.h>
#include <sys/time.h>
#include <mysql/mysql.h>
#include "../../mapi.h"
#define DEFAULT_LINK_MBPS 1000
#define MAX_HEADER_FILTER 256
#define MAX_PAYLOAD_STRING 16 /* max. length of string */
#define MAX_PAYLOAD_STRINGS 16 /* max. number of strings */
#define MAX_FLOWS 16
#define MAX_PROTOCOLS 16
#define MAX_PROTOCOLS_STRING 128
#define MAX_CHARACTERISTICS 3 /* packets, bytes, mbps */
#define MAX_HOSTNAME 128
#define MAX_QUERY 256
#define MAX_COMMAND 256
typedef struct {
char *protocol;
char *track_function;
} tracked_protocol_t;
/*
* Runtime properties of one MAPI flow. Look first at flow_spec_t structure.
* flow_run_t structure must be defined before flow_spec_t, because flow_spec_t
* refers to flow_run_t.
*/
typedef struct {
int fd; /* flow file descriptor */
char *protocol; /* protocol for which this flow was created */
char *header_filter; /* compiled header filter to select packets of this
protocol */
int tracked_protocol; /* index into tracked_protocols[] increased by 1 */
int bpf_filter_fid; /* fid for BPF_FILTER */
int track_function_fid; /* fid for a tracklib function */
int sample_fid; /* fid for SAMPLE */
int str_search_fid; /* fid for STR_SEARCH */
int pkt_counter_fid; /* fid for PKT_COUNT */
int byte_counter_fid; /* fid for BYTE_COUNT */
struct dmapi_results *pkt_counter_res; /* result of PKT_COUNTER */
struct dmapi_results *byte_counter_res; /* result of BYTE_COUNTER */
unsigned long long pkt_counter; /* number of packets from PKT_COUNTER */
unsigned long long byte_counter; /* number of bytes from BYTE_COUNTER */
unsigned long long old_pkt_counter; /* previous number of packets from PKT_COUNTER */
unsigned long long old_byte_counter; /* previous number of bytes from BYTE_COUNTER */
char *rrd_filename;
struct timeval tv_stop_old; /* time after last mapi_read_result() */
} flow_run_t;
typedef struct {
int id;
char *hostname;
char *ip;
char *interface;
char *direction;
int mpls;
int link_mbps;
} subject_t;
typedef struct {
int id;
char *header_filter;
char sau_mode; /* d, b or p */
double sau_threshold; /* meaning is specific to sau_mode */
char *payload_strings[MAX_PAYLOAD_STRINGS];
struct timeval interval;
/* Alternative representations, conversion done in check_conf() */
int sau_mode_encoded;
/* int sau_packet_threshold;
int sau_byte_threshold;
float sau_pass_probability; */
} parameters_t;
/*
* Specification of one flow. Can be read from command-line, configuration
* file or tMeasurement table. One such flow can imply using multiple MAPI
* flows, one for each protocol to be monitored.
*/
typedef struct {
int id; /* used as flow number when printing results */
int subject_id; /* id field in tSubject table */
int parameters_id; /* id field in tParameters table */
subject_t *subject;
parameters_t *parameters;
time_t start_time_timestamp;
time_t end_time_timestamp;
char *protocols;
char *characteristics;
char *statistics;
/* Alternative representations, conversion done in check_conf() */
char *start_time_string;
char *end_time_string;
struct tm start_time_tm;
struct tm end_time_tm;
/* RRD file to store results */
char *rrd_file;
/* Alternative representation, conversion done in split_protocols() */
char *protocols_array[MAX_PROTOCOLS];
/* Runtime flows created for protocols of this flow specification */
flow_run_t *flow_run[MAX_PROTOCOLS];
} flow_spec_t;
/* Global configuration */
typedef struct {
/* Following configuration can be read from command-line */
char *conf_filename; /* read flow configuration from this file */
int conf_from_mysql; /* if non-zero read flow configuration from MySQL */
int conf_to_mysql; /* if non-zero write flow configuration to MySQL */
int clear_conf; /* if non-zero overwrite and delete unused
configuration in MySQL */
int no_measure; /* if non-zero do not do measurements (only process
configuration or print results) */
int no_results; /* if non-zero do not print results */
int no_stdout; /* if non-zero do not print results to stdout */
int stdout_simple; /* if non-zero print results as numbers only */
/* Following configuration can be read from command-line or conf. file */
char *db; /* MySQL database name, if NULL do not insert results
into MySQL database */
char *user; /* username for MySQL connection */
char *passwd; /* password for MySQL connection */
/* Following configuration is maintained as runtime variables */
MYSQL *mysql; /* MySQL connection handler */
char *hostname; /* local hostname including domain name */
flow_spec_t *flow_spec[MAX_FLOWS];
subject_t *subject[MAX_FLOWS];
parameters_t *parameters[MAX_FLOWS];
} global_spec_t;
int compstr(const void *str1, const void *str2);
flow_spec_t *new_flow_spec(void);
subject_t *new_subject(void);
parameters_t *new_parameters(void);
flow_run_t *new_flow_run(void);
int split_protocols(char *protocols, char *protocols_array[]);
int concat_protocols(char **protocols, char *protocols_array[]);
int protocol_filter(char *header_filter, char *protocol, int mpls,
char **new_header_filter);
int get_local_hostname(char **hostname);
int timestamp_diff(struct timeval *tv_start, struct timeval *tv_stop);
#endif
#!/bin/bash
ABW=/usr/local/abw/bin/abw
ABW_COMMAND="$ABW -f /usr/local/abw/etc/abw.cfg"
test -x $ABW || exit 0
case "$1" in
start)
PROCESSES_ABW=`ps -ef|grep abw|grep -v grep|grep -v abw.sh|wc -l`
echo "PROCESSES_ABW: $PROCESSES_ABW"
if [ $PROCESSES_ABW -eq 0 ]; then
echo starting abw
$ABW_COMMAND 2>&1 > /dev/null &
else
echo abw already running
fi
;;
stop)
PROCESSES_ABW=`ps -ef|grep abw|grep -v grep|grep -v abw.sh|wc -l`
echo "PROCESSES_ABW: $PROCESSES_ABW"
if [ $PROCESSES_ABW -gt 0 ]; then
echo "killall abw"
killall abw
sleep 2
PROCESSES_ABW=`ps -ef|grep "sshd: abw@notty"|grep -v grep|wc -l`
echo "Parrent processes related to old abw: $PROCESSES_ABW"
if [ $PROCESSES_ABW -gt 0 ]; then
PID=`ps -ef|grep "sshd: abw@notty"|grep -v grep|awk '{print $2}'`
kill $PID
sleep 2
fi
PROCESSES_ABW=`ps -ef|grep abw|grep -v grep|grep -v abw.sh|wc -l`
echo "PROCESSES_ABW: $PROCESSES_ABW"
if [ $PROCESSES_ABW -gt 0 ]; then
echo "killall -s 9 abw"
killall -s 9 abw
fi
fi
;;
restart)
/usr/local/bin/abw.sh stop
sleep 1
/usr/local/bin/abw.sh start
;;
*)
echo "Usage: abw.sh {start|stop|restart}"
exit 1
esac
exit 0
......@@ -3,7 +3,7 @@
#include <string.h>
#include <unistd.h>
#include "abw.h"
#include "abw_common.h"
#include "abw_conf.h"
extern int debug;
......@@ -16,44 +16,34 @@ int compstr(const void *str1, const void *str2) {
return strcmp(*p1, *p2);
} /* compstr() */
flow_spec_t *new_flow_spec(void) {
flow_spec_t *p;
subject_t *new_subject(void) {
subject_t *p;
if ((p=malloc(sizeof(flow_spec_t)))==NULL) {
if ((p=malloc(sizeof(subject_t)))==NULL) {
fprintf(stderr, "%s: malloc() failed\n", __func__);
return NULL;
}
memset(p, 0, sizeof(flow_spec_t));
memset(p, 0, sizeof(subject_t));
p->subject_id=1;
p->parameters_id=1;
p->start_time_string=DEFAULT_START_TIME_STRING;
p->end_time_string=DEFAULT_END_TIME_STRING;
p->mpls=0;
p->link_mbps=DEFAULT_LINK_MBPS;
return p;
} /* new_flow_spec() */
} /* new_subject() */
subject_t *new_subject(void) {
subject_t *p;
scope_t *new_scope(void) {
scope_t *p;
if ((p=malloc(sizeof(subject_t)))==NULL) {
if ((p=malloc(sizeof(scope_t)))==NULL) {
fprintf(stderr, "%s: malloc() failed\n", __func__);
return NULL;
}
memset(p, 0, sizeof(subject_t));
p->id=1;
p->interface=DEFAULT_DEVICE;
p->link_mbps=DEFAULT_LINK_MBPS;
/* We also need to set default protocol to "all". It will be done
in check_conf() when no protocol was configured explicitely.
We do not need to free() "all" string when protocol is configured. */
memset(p, 0, sizeof(scope_t));
return p;
} /* new_subject() */
} /* new_scope() */
parameters_t *new_parameters(void) {
parameters_t *p;
......@@ -65,142 +55,39 @@ parameters_t *new_parameters(void) {
memset(p, 0, sizeof(parameters_t));
p->id=1;
p->sau_mode='d';
p->sau_threshold=1;
/* p->sau_byte_threshold=3000;
p->sau_pass_probability=0.5; */
p->interval.tv_sec=1;
p->interval.tv_usec=0;
return p;
} /* new_parameters() */
flow_run_t *new_flow_run(void) {
flow_run_t *p;
measurement_t *new_measurement(void) {
measurement_t *p;
if ((p=malloc(sizeof(flow_run_t)))==NULL) {
fprintf(stderr, "%s: malloc() failed\n", __func__);
return NULL;
}
memset(p, 0, sizeof(flow_run_t));
return p;
} /* new_flow_run() */
int split_protocols(char *protocols, char *protocols_array[]) {
int j, k;
char *chr;
char protocol[MAX_PROTOCOLS+1];
char *protocol_start, *protocol_stop;
if (protocols==NULL || !protocols[0])
return 0;
if (strlen(protocols)>MAX_PROTOCOLS_STRING) {
fprintf(stderr, "%s: protocols string is longer than %d characters\n",
__func__, MAX_PROTOCOLS_STRING);
return -1;
}
j=0;
chr=protocols;
/* go over the whole protocols string */
while (*chr && j<MAX_PROTOCOLS) {
/* copy one protocol, that is until comma ',' or end of string */
k=0;
while (*chr && *chr!=',') {
protocol[k]=*chr;
k++; chr++;
}
protocol[k]='\0';
if (k==0) {
fprintf(stderr, "%s: empty protocol\n", __func__);
return -1;
}
/* remove leading and trailing spaces and tabs */
protocol_start=protocol;
while (*protocol_start==' ' || *protocol_start=='\t')
protocol_start++;
protocol_stop=(protocol+k-1);
while (*protocol_stop==' ' || *protocol_stop=='\t')
protocol_stop--;
if (protocol_stop==protocol_start) {
fprintf(stderr, "%s: empty protocol\n", __func__);
return -1;
}
if ((protocols_array[j]=
malloc(protocol_stop-protocol_start+2))==NULL) {
fprintf(stderr, "%s: malloc() failed\n", __func__);
return -1;
}
strncpy(protocols_array[j], protocol_start,
protocol_stop-protocol_start+1);
protocols_array[j][protocol_stop-protocol_start+1]='\0';
if (*chr)
chr++; /* skip ',' */
j++;
} /* while (*chr && j<MAX_PROTOCOLS) */
if (*chr) {
fprintf(stderr, "%s: more than %d protocols\n", __func__,
MAX_PROTOCOLS);
return -1;
if ((p=malloc(sizeof(measurement_t)))==NULL) {
fprintf(stderr, "%s: malloc() failed\n", __func__);
return NULL;
}
return j;
} /* split_protocols() */
int concat_protocols(char **protocols, char *protocols_array[]) {
memset(p, 0, sizeof(measurement_t));
int size;
int i;
char **chrchr;
return p;
} /* new_measurement() */
/* Calculate number of characters of protocol string */
flow_t *new_flow(void) {
flow_t *p;
size=0;
chrchr=protocols_array;
i=0;
while (i<MAX_PROTOCOLS && *chrchr) {
size+=strlen(*chrchr);
chrchr++;
i++;
}
size+=i-1; /* add space for commas between protocols */
if ((p=malloc(sizeof(flow_t)))==NULL) {
fprintf(stderr, "%s: malloc() failed\n", __func__);
return NULL;
}
if (size>0) {
if ((*protocols=malloc(size+1))==NULL) {
fprintf(stderr, "%s: malloc() failed\n", __func__);
return -1;
}
memset(*protocols, 0, size+1);
/* Concatenate protocol string */