Commit 2f9cfb66 authored by 's avatar
Browse files

Initial version of --no_measure


git-svn-id: file:///home/svn/mapi/trunk@369 8d5bb341-7cf1-0310-8cf6-ba355fef3186
parent 5abb19e6
......@@ -35,7 +35,7 @@ int main(int argc, char *argv[])
if ((flow_spec[0]=new_flow_spec())==NULL) {
fprintf(stderr, "%s: new_flow_spec() failed\n", __func__);
exit(-1);
return -1;
}
/* Read command line */
......@@ -56,21 +56,10 @@ int main(int argc, char *argv[])
/* Get local hostname */
if (gethostname(global_spec.hostname, MAX_HOSTNAME+1)<0) {
fprintf(stderr, "%s: gethostname() failed\n", __func__);
exit(-1);
if (get_local_hostname(&(global_spec.hostname))<0) {
fprintf(stderr, "%s: get_local_hostname() failed\n", __func__);
return -1;
}
if (!strchr(global_spec.hostname, ',')) {
char domainname[MAX_HOSTNAME+1];
if (getdomainname(domainname, MAX_HOSTNAME+1)<0) {
fprintf(stderr, "%s: getdomainname() failed\n", __func__);
exit(-1);
}
if (strlen(domainname))
strcat(global_spec.hostname, domainname);
else
fprintf(stderr, "%s: WARNING: could not obtain local domain name, local hostname (without domain name) will be used as subject specification\n", __func__);
}
/* Check if specified values are within acceptable limits */
......@@ -97,6 +86,27 @@ int main(int argc, char *argv[])
}
}
if (global_spec.clear_conf) {
if (abw_mysql_clear_conf(global_spec.mysql)<0) {
fprintf(stderr, "%s: abw_mysql_clear_conf() failed\n", __func__);
return -1;
}
}
if (global_spec.conf_from_mysql) {
if (abw_mysql_read_conf(global_spec.mysql, flow_spec)<0) {
fprintf(stderr, "%s: abw_mysql_read_conf() failed\n", __func__);
return -1;
}
}
if (global_spec.conf_to_mysql) {
if (abw_mysql_write_conf(global_spec.mysql, flow_spec)<0) {
fprintf(stderr, "%s: abw_mysql_write_conf() failed\n", __func__);
return -1;
}
}
/*
* Go over all specified flows and for each flow:
* - find its subject and parameters in database or add them
......@@ -126,7 +136,7 @@ int main(int argc, char *argv[])
abw_mysql_get_parameters_id(&global_spec, p))<0) {
fprintf(stderr, "%s: abw_mysql_get_parameters_id() failed\n",
__func__);
exit(-1);
return -1;
}
p->subject_id=subject_id;
......@@ -148,93 +158,121 @@ int main(int argc, char *argv[])
fprintf(stderr, "%s: new_flow_run() failed\n", __func__);
return -1;
}
q=p->flow_run[j];
/* Prepare header filter for this protocol */
if (!(global_spec.no_measure)) {
q=p->flow_run[j];
if (p->protocols_array[j] && p->protocols_array[j][0]) {
if ((q->protocol=malloc(strlen(p->protocols_array[j])+1))==NULL) {
fprintf(stderr, "%s: malloc() failed\n", __func__);
return -1;
}
strcpy(q->protocol, p->protocols_array[j]);
/* Prepare header filter for this protocol */
if (p->protocols_array[j] && p->protocols_array[j][0]) {
if ((q->protocol=
malloc(strlen(p->protocols_array[j])+1))==NULL) {
fprintf(stderr, "%s: malloc() failed\n", __func__);
return -1;
}
strcpy(q->protocol, p->protocols_array[j]);
if (protocol_filter(p->header_filter, q->protocol,
&(q->header_filter))<0) {
fprintf(stderr, "%s: protocols_filter() failed\n", __func__);
if (protocol_filter(p->header_filter, q->protocol,
&(q->header_filter))<0) {
fprintf(stderr, "%s: protocols_filter() failed\n", __func__);
return -1;
}
}
else
q->header_filter=p->header_filter;
printf("p->header_filter: %s, q->protocol: %s, q->header_filter: %s\n", p->header_filter, q->protocol, q->header_filter);
if ((q->fd=mapi_create_flow(p->device))<0) {
fprintf(stderr, "%s: mapi_create_flow(%s) failed\n", __func__,
p->device);
return -1;
}
}
else
q->header_filter=p->header_filter;
printf("p->header_filter: %s, q->protocol: %s, q->header_filter: %s\n", p->header_filter, q->protocol, q->header_filter);
if ((q->fd=mapi_create_flow(p->device))<0) {
fprintf(stderr, "%s: mapi_create_flow(%s) failed\n", __func__,
p->device);
return -1;
}
/* Note that BPF_FILTER uses compiled header filter string that
selects packets of the given protocol */
if (q->header_filter) {
if ((q->bpf_filter_fid=
mapi_apply_function(q->fd, "BPF_FILTER", q->header_filter))<0) {
fprintf(stderr, "%s: BPF_FILTER for flow %d failed\n",
__func__, i);
return -1;
/* Note that BPF_FILTER uses compiled header filter string that
selects packets of the given protocol */
if (q->header_filter) {
if ((q->bpf_filter_fid=
mapi_apply_function(q->fd, "BPF_FILTER",
q->header_filter))<0) {
fprintf(stderr, "%s: BPF_FILTER for flow %d failed\n",
__func__, i);
return -1;
}
}
}
if (p->sau_mode == 'd' && p->sau_packet_threshold != 1) {
if ((q->sample_fid=
mapi_apply_function(q->fd, "SAMPLE", p->sau_packet_threshold),
PERIODIC)<0) {
fprintf(stderr, "%s: SAMPLE for flow %d failed\n",
__func__, i);
return -1;
if (p->sau_mode == 'd' && p->sau_packet_threshold != 1) {
if ((q->sample_fid=
mapi_apply_function(q->fd, "SAMPLE", p->sau_packet_threshold),
PERIODIC)<0) {
fprintf(stderr, "%s: SAMPLE for flow %d failed\n",
__func__, i);
return -1;
}
}
else if (p->sau_mode == 'p' && p->sau_pass_probability != 1) {
if ((q->sample_fid=
mapi_apply_function(q->fd, "SAMPLE",
(p->sau_pass_probability)*100),
PROBABILISTIC)<0) {
fprintf(stderr, "%s: SAMPLE for flow %d failed\n",
__func__, i);
return -1;
}
}
}
else if (p->sau_mode == 'p' && p->sau_pass_probability != 1) {
if ((q->sample_fid=
mapi_apply_function(q->fd, "SAMPLE",
(p->sau_pass_probability)*100),
PROBABILISTIC)<0) {
fprintf(stderr, "%s: SAMPLE for flow %d failed\n",
__func__, i);
return -1;
}
}
if (p->payload_strings[0]) {
if ((q->str_search_fid=
mapi_apply_function(q->fd, "STR_SEARCH", p->payload_strings[0],
0, 0))<0) {
fprintf(stderr, "%s: STR_SEARCH for flow %d failed\n",
if (p->payload_strings[0]) {
if ((q->str_search_fid=
mapi_apply_function(q->fd, "STR_SEARCH",
p->payload_strings[0], 0, 0))<0) {
fprintf(stderr, "%s: STR_SEARCH for flow %d failed\n",
__func__, i);
return -1;
}
}
if ((q->pkt_counter_fid=
mapi_apply_function(q->fd, "PKT_COUNTER"))<0) {
fprintf(stderr, "%s: PKT_COUNTER for flow %d failed\n",
__func__, i);
return -1;
}
}
return -1;
}
if ((q->pkt_counter_fid=
mapi_apply_function(q->fd, "PKT_COUNTER"))<0) {
fprintf(stderr, "%s: PKT_COUNTER for flow %d failed\n", __func__,
i);
return -1;
}
if ((q->byte_counter_fid=
mapi_apply_function(q->fd, "BYTE_COUNTER"))<0) {
fprintf(stderr, "%s: BYTE_COUNTER for flow %d failed\n",
__func__, i);
return -1;
}
if ((q->byte_counter_fid=
mapi_apply_function(q->fd, "BYTE_COUNTER"))<0) {
fprintf(stderr, "%s: BYTE_COUNTER for flow %d failed\n",
if (mapi_connect(q->fd)<0) {
fprintf(stderr, "%s: mapi_connect() for flow %d failed\n",
__func__, i);
return -1;
}
return -1;
}
} /* if (!(global_spec.no_measure)) */
else {
value_t *values;
if (abw_mysql_select_values(global_spec.mysql, p,
p->protocols_array[j], "bytes", NULL, &values)<0) {
fprintf(stderr, "%s: abw_mysql_select_values() failed\n",
__func__);
return -1;
}
abw_mysql_print_values(values);
abw_mysql_free_values(values);
if (mapi_connect(q->fd)<0) {
fprintf(stderr, "%s: mapi_connect() for flow %d failed\n",
__func__, i);
return -1;
}
if (abw_mysql_select_values(global_spec.mysql, p,
p->protocols_array[j], "packets", NULL, &values)<0) {
fprintf(stderr, "%s: abw_mysql_select_values() failed\n",
__func__);
return -1;
}
abw_mysql_print_values(values);
abw_mysql_free_values(values);
} /* if (!(global_spec.no_measure)) else */
j++;
} /* while (j<MAX_PROTOCOLS && p->protocols_array[j]) */
......@@ -243,90 +281,96 @@ int main(int argc, char *argv[])
i++;
} /* while (i<MAX_FLOWS && *pp) */
while (1) {
if (gettimeofday(&tm, &tz)<0) {
fprintf(stderr, "%s: gettimeofday() failed\n", __func__);
exit(-1);
}
if (!global_spec.no_stdout)
printf("%u.%u", (unsigned int)(tm.tv_sec), (unsigned int)(tm.tv_usec));
if (!(global_spec.no_measure)) {
while (1) {
if (gettimeofday(&tm, &tz)<0) {
fprintf(stderr, "%s: gettimeofday() failed\n", __func__);
exit(-1);
}
pp=flow_spec;
i=0;
pp=flow_spec;
i=0;
while (i<MAX_FLOWS && *pp) {
while (i<MAX_FLOWS && *pp) {
p=*pp;
p=*pp;
if (!global_spec.no_stdout)
printf("%d %u.%u", i, (unsigned int)(tm.tv_sec),
(unsigned int)(tm.tv_usec));
j=0;
while (j<MAX_PROTOCOLS && (q=p->flow_run[j])) {
j=0;
while (j<MAX_PROTOCOLS && (q=p->flow_run[j])) {
if ((q->pkt_counter=
mapi_read_results(q->fd, q->pkt_counter_fid))==NULL) {
fprintf(stderr, "%s: mapi_read_results() for flow %d failed\n",
__func__, i);
return -1;
}
if ((q->pkt_counter=
mapi_read_results(q->fd, q->pkt_counter_fid))==NULL) {
fprintf(stderr, "%s: mapi_read_results() for flow %d failed\n",
__func__, i);
return -1;
}
if ((q->byte_counter=
mapi_read_results(q->fd, q->byte_counter_fid))==NULL) {
fprintf(stderr, "%s: mapi_read_results() for flow %d failed\n",
__func__, i);
return -1;
}
if ((q->byte_counter=
mapi_read_results(q->fd, q->byte_counter_fid))==NULL) {
fprintf(stderr, "%s: mapi_read_results() for flow %d failed\n",
__func__, i);
return -1;
}
if (!global_spec.no_stdout) {
printf(" %u/%u", *(q->pkt_counter)-q->old_pkt_counter,
*(q->byte_counter)-q->old_byte_counter);
}
if (global_spec.db) {
if (abw_mysql_insert_value(&global_spec, p, q,
tm.tv_sec, tm.tv_usec,
"packets", NULL, NULL,
*(q->pkt_counter)-q->old_pkt_counter, 0, NULL)<0) {
fprintf(stderr, "%s: abw_mysql_insert() failed\n", __func__);
return -1;
if (!global_spec.no_stdout) {
printf(" %u/%u", *(q->pkt_counter)-q->old_pkt_counter,
*(q->byte_counter)-q->old_byte_counter);
}
if (abw_mysql_insert_value(&global_spec, p, q,
tm.tv_sec, tm.tv_usec,
"bytes", NULL, NULL,
*(q->byte_counter)-q->old_byte_counter, 0, NULL)<0) {
fprintf(stderr, "%s: abw_mysql_insert() failed\n", __func__);
return -1;
if (global_spec.db) {
if (abw_mysql_insert_value(global_spec.mysql, p, q,
tm.tv_sec, tm.tv_usec,
"packets", NULL, NULL,
*(q->pkt_counter)-q->old_pkt_counter, 0, NULL)<0) {
fprintf(stderr, "%s: abw_mysql_insert() failed\n",
__func__);
return -1;
}
if (abw_mysql_insert_value(global_spec.mysql, p, q,
tm.tv_sec, tm.tv_usec,
"bytes", NULL, NULL,
*(q->byte_counter)-q->old_byte_counter, 0, NULL)<0) {
fprintf(stderr, "%s: abw_mysql_insert() failed\n", __func__);
return -1;
}
}
}
q->old_pkt_counter=*(q->pkt_counter);
q->old_byte_counter=*(q->byte_counter);
q->old_pkt_counter=*(q->pkt_counter);
q->old_byte_counter=*(q->byte_counter);
j++;
j++;
} /* while (j<MAX_PROTOCOLS && (q=p->flow_run[j])) */
} /* while (j<MAX_PROTOCOLS && (q=p->flow_run[j])) */
pp++;
i++;
if (!global_spec.no_stdout)
printf("\n");
} /* while (i<MAX_FLOWS && *pp) */
pp++;
i++;
if (!global_spec.no_stdout)
printf("\n");
/* TODO: wait until next checkpoint (not a fixed delay) of
the flow whose checkpoint is earliest */
} /* while (i<MAX_FLOWS && *pp) */
abw_next_timestamp(&(flow_spec[0]->interval), &next, &wait);
/* printf("next.tv_sec: %d, next.tv_usec: %d, wait.tv_sec: %d, wait.tv_usec: %d\n", (int)(next.tv_sec), (int)(next.tv_usec), (int)(wait.tv_sec), (int)(wait.tv_usec)); */
/* TODO: wait until next checkpoint (not a fixed delay) of
the flow whose checkpoint is earliest */
usleep(wait.tv_sec * 1000000 + wait.tv_usec);
abw_next_timestamp(&(flow_spec[0]->interval), &next, &wait);
/* printf("next.tv_sec: %d, next.tv_usec: %d, wait.tv_sec: %d, wait.tv_usec: %d\n", (int)(next.tv_sec), (int)(next.tv_usec), (int)(wait.tv_sec), (int)(wait.tv_usec)); */
usleep(wait.tv_sec * 1000000 + wait.tv_usec);
/* usleep((flow_spec[0]->interval)*1000000); */
} /* while (1) */
/* usleep((flow_spec[0]->interval)*1000000); */
} /* while (1) */
} /* if (!(global_spec.no_measure)) */
/* TODO: this is never reached, move to interrupt handler */
/* TODO: this is never reached when measuring (--no-measure is not
specified), move to interrupt handler */
if (global_spec.db) {
mysql_close(global_spec.mysql);
mysql_library_end();
......
# [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.
[global]
db=abw
user=abw
passwd=lab10
# [node] section specifies where the measurement should be done. You should
# specify two things: 1) hostname or IP address, 2) device file. Multiple
# [node] sections can be specified for several measurements done on diferent
# nodes.
# [node] section specifies link-ends where the measurement should be done.
# You MUST specify three things: 1) id, 2) hostname or ip_address and 3) device.
# Multiple [node] sections CAN be specified for several measurements done on
# diferent link-ends. You CAN optionally specify link_mbps. If you do not
# specify link_mbps, default is 1000.
[node]
id=1
hostname=jra1-1.cesnet.cz
device=eth0
device=/dev/dag0
# link_mbps is used by abw_print, but not by abw_measure
link_mbps=1000
......@@ -20,13 +25,19 @@ id=2
hostname=jra1-1.cesnet.cz
device=eth0
# [parameters] section specifies measurement parameters. "node_id" must refer
# to "id" of the [node] section where the measurement should be done.
# "characteristics" includes one or more characteristics to be measured,
# separated by commas. These characteristics must be recognized by the used
# measurement tool (e.g., abw). Values should not include spaces except for
# "header_filter", which can include spaces. Multiple [parameters] sections
# can be specified for several measurements done in parallel.
# [parameters] section specifies measurement parameters. You MUST specify two
# things: 1) id and 2) node_id which MUST refer to id of the [node] section
# where the measurement is done. 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), 4) payload_string (can be specified multiple times, default
# is no payload searching), 5) protocols (can be any combination of all, tcp,
# udp, multicast and ipv6, default is all), 6) interval_sec (default is 1),
# 7) interval_usec (default is 0), 8) start_time_string (default is
# 01.01.1970-01:00:00) and 9) end_time_string (default is 01.01.2038-01:00:00).
# 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.
[parameters]
id=1
......@@ -41,6 +52,6 @@ interval_sec=1
start_time_string=01.01.2005-00:00:00
end_time_string=31.12.2037-23:59:59
#[parameters]
#id=2
#node_id=2
[parameters]
id=2
node_id=2
......@@ -97,7 +97,7 @@ typedef struct {
char *user; /* username for MySQL connection */
char *passwd; /* password for MySQL connection */
MYSQL *mysql; /* MySQL connection handler */
char hostname[MAX_HOSTNAME+1]; /* local hostname including domain name */
char *hostname; /* local hostname including domain name */
} global_spec_t;
flow_spec_t *new_flow_spec(void);
......@@ -109,4 +109,6 @@ int split_protocols(char *protocols, char *protocols_array[]);
int protocol_filter(char *header_filter, char *protocol,
char **new_header_filter);
int get_local_hostname(char **hostname);
#endif
......@@ -467,7 +467,7 @@ int check_conf(global_spec_t *global_spec, flow_spec_t **flow_spec) {
}
if (!global_spec->passwd) {
/* Note that readline() uses malloc() to allocate memory */
if ((global_spec->passwd=readline("MySQL password:"))==NULL) {
if ((global_spec->passwd=readline("MySQL password: "))==NULL) {
fprintf(stderr, "%s: Invalid MySQL password\n", __func__);
return -1;
}
......
......@@ -50,7 +50,7 @@ static const struct option long_options[] = {
};
#define DEFAULT_DEVICE "eth0"
#define DEFAULT_START_TIME_STRING "01.01.1970-01:00:00"
#define DEFAULT_START_TIME_STRING "01.01.1970-01:00:01"
#define DEFAULT_END_TIME_STRING "01.01.2038-00:00:00"
/*
* The following was the latest date and time accepted by time processing
......
......@@ -233,15 +233,14 @@ int abw_mysql_get_parameters_id(global_spec_t *global_spec,
}
} /* abw_mysql_get_parameters_id() */
int abw_mysql_insert_value(global_spec_t *global_spec,
flow_spec_t *p, flow_run_t *q,
int abw_mysql_insert_value(MYSQL *mysql, flow_spec_t *p, flow_run_t *q,
int timestamp_sec, int timestamp_usec,
char *characteristics, char *unit, char *statistics,
int value_int, double value_float, char *value_varchar) {
char query[MAX_QUERY+1];
int num;
if (global_spec==NULL || q==NULL || characteristics==NULL ||
if (mysql==NULL || q==NULL || characteristics==NULL ||
q->protocol==NULL) {
fprintf(stderr, "%s: some required arguments were not supplied\n",
__func__);
......@@ -252,16 +251,163 @@ int abw_mysql_insert_value(global_spec_t *global_spec,
sprintf(query+strlen(query), " VALUES ('%d', '%d', '%d', '%d', '%s', '%s', '%s', '%s', '%d', '%f', '%s');", p->subject_id, p->parameters_id, timestamp_sec, timestamp_usec, q->protocol, characteristics?characteristics:"", unit?unit:"", statistics?statistics:"", value_int, value_float, value_varchar?value_varchar:"");
/* printf("%s: query: %s\n", __func__, query); */
if (mysql_query(global_spec->mysql, query)) {
printf("%s: query: %s\n", __func__, query);
if (mysql_query(mysql, query)) {
fprintf(stderr, "%s: mysql_query(%s) failed\n", __func__, query);
return -1;
}
if ((num=mysql_affected_rows(global_spec->mysql))!=1) {
if ((num=mysql_affected_rows(mysql))!=1) {
fprintf(stderr, "%s: mysql_affected_rows() failed\n", __func__);
return -1;
}
return 0;
} /* abw_mysql_insert_value() */
/*
* Differences in arguments from abw_mysql_insert_value():
*
* - flow_run_ *q was removed, because MAPI flow is not created,
* we just read already stored results
*
* - char *protocol was added, because we need to know what protocol
* is the data we should read (one protocol is in each flow_run_t,
* but it was removed, all protocols are in flow_spec_t, but we
* need to read one at a time)
*
* - char unit was removed
*
* - int **values return a sequence of structures with values
*/
int abw_mysql_select_values(MYSQL *mysql, flow_spec_t *p,
char *protocol, char *characteristics, char *statistics,
value_t **values) {
char query[MAX_QUERY+1];
MYSQL_RES *mysql_res=NULL;
MYSQL_ROW mysql_row;
int num;
int i;
value_t **last_value;
if (mysql==NULL || p==NULL || protocol==NULL || !strlen(protocol)) {
fprintf(stderr, "%s: some required arguments were not supplied\n",
__func__);
return -1;
}
sprintf(query, "SELECT * FROM tValue WHERE subject_id='%d' AND parameters_id='%d' AND protocol='%s'", p->subject_id, p->parameters_id, protocol);
if (p->start_time_timestamp)
sprintf(query+strlen(query), " AND timestamp_sec >= '%u'",
(unsigned int)(p->start_time_timestamp));
if (p->end_time_timestamp)
sprintf(query+strlen(query), " AND timestamp_sec <= '%u'",
(unsigned int)(p->end_time_timestamp));
if (characteristics && strlen(characteristics))
sprintf(query+strlen(query), " AND characteristics='%s'",
characteristics);
if (statistics && strlen(statistics))
sprintf(query+strlen(query), " AND statistics='%s'", statistics);