version 1.1.1.1, 2019/10/21 14:25:31
|
version 1.1.1.2, 2021/03/17 00:07:30
|
Line 11
|
Line 11
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
GNU General Public License for more details. |
GNU General Public License for more details. |
|
|
You should have received a copy of the GNU General Public License | You should have received a copy of the GNU General Public License along |
along with this program; if not, write to the Free Software | with this program; if not, write to the Free Software Foundation, Inc., |
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
*/ |
*/ |
|
|
#include "config.h" |
#include "config.h" |
Line 26
|
Line 26
|
#include <string.h> |
#include <string.h> |
#include <strings.h> |
#include <strings.h> |
#include <time.h> |
#include <time.h> |
|
#ifdef HAVE_JANSSON |
|
#include <jansson.h> |
|
#endif |
|
#ifdef HAVE_ERROR_H |
|
#include <error.h> |
|
#else |
|
#include "portability/error.h" |
|
#endif |
|
|
#include "mtr.h" |
#include "mtr.h" |
#include "report.h" |
#include "report.h" |
Line 74 static void print_mpls(
|
Line 82 static void print_mpls(
|
{ |
{ |
int k; |
int k; |
for (k = 0; k < mpls->labels; k++) |
for (k = 0; k < mpls->labels; k++) |
printf(" [MPLS: Lbl %lu Exp %u S %cu TTL %u]\n", | printf(" [MPLS: Lbl %lu TC %u S %cu TTL %u]\n", |
mpls->label[k], mpls->exp[k], mpls->s[k], mpls->ttl[k]); | mpls->label[k], mpls->tc[k], mpls->s[k], mpls->ttl[k]); |
} |
} |
#endif |
#endif |
|
|
Line 176 void report_close(
|
Line 184 void report_close(
|
|
|
/* This feature shows 'loadbalances' on routes */ |
/* This feature shows 'loadbalances' on routes */ |
|
|
/* z is starting at 1 because addrs[0] is the same that addr */ | /* Print list of all hosts that have responded from ttl = at + 1 away */ |
for (z = 1; z < MAXPATH; z++) { | for (z = 0; z < MAX_PATH; z++) { |
int found = 0; |
int found = 0; |
addr2 = net_addrs(at, z); |
addr2 = net_addrs(at, z); |
mplss = net_mplss(at, z); |
mplss = net_mplss(at, z); |
if ((addrcmp |
if ((addrcmp |
((void *) &ctl->unspec_addr, (void *) addr2, |
((void *) &ctl->unspec_addr, (void *) addr2, |
ctl->af)) == 0) | ctl->af)) == 0) { |
break; |
break; |
|
} else if ((addrcmp |
|
((void *) addr, (void *) addr2, |
|
ctl->af)) == 0) { |
|
continue; /* Latest Host is already printed */ |
|
} else { |
|
snprint_addr(ctl, name, sizeof(name), addr2); |
|
snprintf(fmt, sizeof(fmt), " %%-%zus", len_hosts); |
|
snprintf(buf, sizeof(buf), fmt, name); |
|
printf("%s\n", buf); |
|
} |
for (w = 0; w < z; w++) |
for (w = 0; w < z; w++) |
/* Ok... checking if there are ips repeated on same hop */ |
/* Ok... checking if there are ips repeated on same hop */ |
if ((addrcmp |
if ((addrcmp |
Line 210 void report_close(
|
Line 228 void report_close(
|
if (mpls->labels && z == 1 && ctl->enablempls) { |
if (mpls->labels && z == 1 && ctl->enablempls) { |
for (k = 0; k < mpls->labels; k++) { |
for (k = 0; k < mpls->labels; k++) { |
printf |
printf |
(" | |+-- [MPLS: Lbl %lu Exp %u S %u TTL %u]\n", | (" | |+-- [MPLS: Lbl %lu TC %u S %u TTL %u]\n", |
mpls->label[k], mpls->exp[k], mpls->s[k], | mpls->label[k], mpls->tc[k], mpls->s[k], |
mpls->ttl[k]); |
mpls->ttl[k]); |
} |
} |
} |
} |
Line 220 void report_close(
|
Line 238 void report_close(
|
printf(" | `|-- %s\n", strlongip(ctl, addr2)); |
printf(" | `|-- %s\n", strlongip(ctl, addr2)); |
for (k = 0; k < mplss->labels && ctl->enablempls; k++) { |
for (k = 0; k < mplss->labels && ctl->enablempls; k++) { |
printf |
printf |
(" | +-- [MPLS: Lbl %lu Exp %u S %u TTL %u]\n", | (" | +-- [MPLS: Lbl %lu TC %u S %u TTL %u]\n", |
mplss->label[k], mplss->exp[k], mplss->s[k], | mplss->label[k], mplss->tc[k], mplss->s[k], |
mplss->ttl[k]); |
mplss->ttl[k]); |
} |
} |
} else { |
} else { |
printf(" | |-- %s\n", strlongip(ctl, addr2)); |
printf(" | |-- %s\n", strlongip(ctl, addr2)); |
for (k = 0; k < mplss->labels && ctl->enablempls; k++) { |
for (k = 0; k < mplss->labels && ctl->enablempls; k++) { |
printf |
printf |
(" | +-- [MPLS: Lbl %lu Exp %u S %u TTL %u]\n", | (" | +-- [MPLS: Lbl %lu TC %u S %u TTL %u]\n", |
mplss->label[k], mplss->exp[k], mplss->s[k], | mplss->label[k], mplss->tc[k], mplss->s[k], |
mplss->ttl[k]); |
mplss->ttl[k]); |
} |
} |
} |
} |
Line 247 void report_close(
|
Line 265 void report_close(
|
if (mpls->labels && z == 1 && ctl->enablempls) { |
if (mpls->labels && z == 1 && ctl->enablempls) { |
int k; |
int k; |
for (k = 0; k < mpls->labels; k++) { |
for (k = 0; k < mpls->labels; k++) { |
printf(" | +-- [MPLS: Lbl %lu Exp %u S %u TTL %u]\n", | printf(" | +-- [MPLS: Lbl %lu TC %u S %u TTL %u]\n", |
mpls->label[k], mpls->exp[k], mpls->s[k], | mpls->label[k], mpls->tc[k], mpls->s[k], |
mpls->ttl[k]); |
mpls->ttl[k]); |
} |
} |
} |
} |
Line 269 void txt_close(
|
Line 287 void txt_close(
|
report_close(ctl); |
report_close(ctl); |
} |
} |
|
|
| #ifdef HAVE_JANSSON |
void json_open( |
void json_open( |
void) |
void) |
{ |
{ |
} |
} |
|
|
| void json_close(struct mtr_ctl *ctl) |
void json_close( | |
struct mtr_ctl *ctl) | |
{ |
{ |
int i, j, at, first, max; | int i, j, at, max; |
| int ret; |
| char buf[128]; |
| json_t *jreport, *jmtr, *jhubs, *jh; |
ip_t *addr; |
ip_t *addr; |
char name[MAX_FORMAT_STR]; |
char name[MAX_FORMAT_STR]; |
|
|
printf("{\n"); | jmtr = json_pack("{ss ss si si}", |
printf(" \"report\": {\n"); | "src", ctl->LocalHostname, |
printf(" \"mtr\": {\n"); | "dst", ctl->Hostname, |
printf(" \"src\": \"%s\",\n", ctl->LocalHostname); | "tos", ctl->tos, |
printf(" \"dst\": \"%s\",\n", ctl->Hostname); | "tests", ctl->MaxPing); |
printf(" \"tos\": \"0x%X\",\n", ctl->tos); | if (!jmtr) |
| goto on_error; |
| |
if (ctl->cpacketsize >= 0) { |
if (ctl->cpacketsize >= 0) { |
printf(" \"psize\": \"%d\",\n", ctl->cpacketsize); | snprintf(buf, sizeof(buf), "%d", ctl->cpacketsize); |
} else { |
} else { |
printf(" \"psize\": \"rand(%d-%d)\",\n", MINPACKET, | snprintf(buf, sizeof(buf), "rand(%d-%d)", MINPACKET, -ctl->cpacketsize); |
-ctl->cpacketsize); | |
} |
} |
|
ret = json_object_set_new(jmtr, "psize", json_string(buf)); |
|
if (ret == -1) |
|
goto on_error; |
|
|
if (ctl->bitpattern >= 0) { |
if (ctl->bitpattern >= 0) { |
printf(" \"bitpattern\": \"0x%02X\",\n", | snprintf(buf, sizeof(buf), "0x%02X", (unsigned char)(ctl->bitpattern)); |
(unsigned char) (ctl->bitpattern)); | |
} else { |
} else { |
printf(" \"bitpattern\": \"rand(0x00-FF)\",\n"); | snprintf(buf, sizeof(buf), "rand(0x00-FF)"); |
} |
} |
printf(" \"tests\": \"%d\"\n", ctl->MaxPing); |
|
printf(" },\n"); |
|
|
|
printf(" \"hubs\": ["); | ret = json_object_set_new(jmtr, "bitpattern", json_string(buf)); |
| if (ret == -1) |
| goto on_error; |
|
|
|
jhubs = json_array(); |
|
if (!jhubs) |
|
goto on_error; |
|
|
max = net_max(ctl); |
max = net_max(ctl); |
at = first = net_min(ctl); | at = net_min(ctl); |
for (; at < max; at++) { |
for (; at < max; at++) { |
addr = net_addr(at); |
addr = net_addr(at); |
snprint_addr(ctl, name, sizeof(name), addr); |
snprint_addr(ctl, name, sizeof(name), addr); |
|
|
if (at == first) { | jh = json_pack("{si ss}", "count", at + 1, "host", name); |
printf("{\n"); | if (!jh) |
} else { | goto on_error; |
printf(" {\n"); | |
} | |
printf(" \"count\": \"%d\",\n", at + 1); | |
printf(" \"host\": \"%s\",\n", name); | |
#ifdef HAVE_IPINFO |
#ifdef HAVE_IPINFO |
if(!ctl->ipinfo_no) { |
if(!ctl->ipinfo_no) { |
char* fmtinfo = fmt_ipinfo(ctl, addr); | char* fmtinfo = fmt_ipinfo(ctl, addr); |
if (fmtinfo != NULL) fmtinfo = trim(fmtinfo, '\0'); | if (fmtinfo != NULL) |
printf(" \"ASN\": \"%s\",\n", fmtinfo); | fmtinfo = trim(fmtinfo, '\0'); |
| |
| ret = json_object_set_new(jh, "ASN", json_string(fmtinfo)); |
| if (ret == -1) |
| goto on_error; |
} |
} |
#endif |
#endif |
for (i = 0; i < MAXFLD; i++) { |
|
const char *format; |
|
|
|
|
for (i = 0; i < MAXFLD; i++) { |
j = ctl->fld_index[ctl->fld_active[i]]; |
j = ctl->fld_index[ctl->fld_active[i]]; |
|
|
/* Commas */ |
|
if (i + 1 == MAXFLD) { |
|
printf("\n"); |
|
} else if (j > 0 && i != 0) { |
|
printf(",\n"); |
|
} |
|
|
|
if (j <= 0) |
if (j <= 0) |
continue; /* Field nr 0, " " shouldn't be printed in this method. */ | continue; /* Field nr 0, " " shouldn't be printed in this method. */ |
|
|
/* Format value */ |
|
format = data_fields[j].format; |
|
if (strchr(format, 'f')) { |
|
format = "%.2f"; |
|
} else { |
|
format = "%d"; |
|
} |
|
|
|
/* Format json line */ |
|
snprintf(name, sizeof(name), "%s%s", " \"%s\": ", format); |
|
|
|
/* Output json line */ |
|
if (strchr(data_fields[j].format, 'f')) { |
if (strchr(data_fields[j].format, 'f')) { |
/* 1000.0 is a temporay hack for stats usec to ms, impacted net_loss. */ | ret = json_object_set_new( |
printf(name, | jh, data_fields[j].title, |
data_fields[j].title, | json_real(data_fields[j].net_xxx(at) / 1000.0)); |
data_fields[j].net_xxx(at) / 1000.0); | |
} else { |
} else { |
printf(name, | ret = json_object_set_new( |
data_fields[j].title, data_fields[j].net_xxx(at)); | jh, data_fields[j].title, |
| json_integer(data_fields[j].net_xxx(at))); |
} |
} |
|
if (ret == -1) |
|
goto on_error; |
} |
} |
if (at + 1 == max) { | |
printf(" }]\n"); | ret = json_array_append_new(jhubs, jh); |
} else { | if (ret == -1) |
printf(" },\n"); | goto on_error; |
} | |
} |
} |
printf(" }\n"); |
|
printf("}\n"); |
|
} |
|
|
|
|
jreport = json_pack("{s{so so}}", "report", "mtr", jmtr, "hubs", jhubs); |
|
|
|
ret = json_dumpf(jreport, stdout, JSON_INDENT(4) | JSON_REAL_PRECISION(5)); |
|
if (ret == -1) |
|
goto on_error; |
|
|
|
printf("\n"); // bash promt should be on new line |
|
json_decref(jreport); |
|
return; |
|
on_error: |
|
error(EXIT_FAILURE, 0, "json_close failed"); |
|
} |
|
#endif |
|
|
|
|
void xml_open( |
void xml_open( |