Diff for /embedaddon/mtr/ui/report.c between versions 1.1 and 1.1.1.3

version 1.1, 2019/10/21 14:25:31 version 1.1.1.3, 2023/09/27 11:18:58
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 35 Line 43
 #include "utils.h"  #include "utils.h"
   
 #define MAXLOADBAL 5  #define MAXLOADBAL 5
#define MAX_FORMAT_STR 81#define MAX_FORMAT_STR 320
   
   
 void report_open(  void report_open(
Line 57  static size_t snprint_addr( Line 65  static size_t snprint_addr(
         struct hostent *host =          struct hostent *host =
             ctl->dns ? addr2host((void *) addr, ctl->af) : NULL;              ctl->dns ? addr2host((void *) addr, ctl->af) : NULL;
         if (!host)          if (!host)
            return snprintf(dst, dst_len, "%s", strlongip(ctl, addr));            return snprintf(dst, dst_len, "%s", strlongip(ctl->af, addr));
         else if (ctl->dns && ctl->show_ips)          else if (ctl->dns && ctl->show_ips)
             return snprintf(dst, dst_len, "%s (%s)", host->h_name,              return snprintf(dst, dst_len, "%s (%s)", host->h_name,
                            strlongip(ctl, addr));                            strlongip(ctl->af, addr));
         else          else
             return snprintf(dst, dst_len, "%s", host->h_name);              return snprintf(dst, dst_len, "%s", host->h_name);
     } else      } else
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 162  void report_close( Line 170  void report_close(
             if (j < 0)              if (j < 0)
                 continue;                  continue;
   
            /* 1000.0 is a temporay hack for stats usec to ms, impacted net_loss. */            /* 1000.0 is a temporary hack for stats usec to ms, impacted net_loss. */
             if (strchr(data_fields[j].format, 'f')) {              if (strchr(data_fields[j].format, 'f')) {
                 snprintf(buf + len, sizeof(buf), data_fields[j].format,                  snprintf(buf + len, sizeof(buf), data_fields[j].format,
                          data_fields[j].net_xxx(at) / 1000.0);                           data_fields[j].net_xxx(at) / 1000.0);
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 197  void report_close( Line 215  void report_close(
             if (!found) {              if (!found) {
   
 #ifdef HAVE_IPINFO  #ifdef HAVE_IPINFO
                   if (mpls->labels && z == 1 && ctl->enablempls)
                       print_mpls(mpls);
                 if (is_printii(ctl)) {                  if (is_printii(ctl)) {
                     if (mpls->labels && z == 1 && ctl->enablempls)  
                         print_mpls(mpls);  
                     snprint_addr(ctl, name, sizeof(name), addr2);                      snprint_addr(ctl, name, sizeof(name), addr2);
                     printf("     %s%s\n", fmt_ipinfo(ctl, addr2), name);                      printf("     %s%s\n", fmt_ipinfo(ctl, addr2), name);
                     if (ctl->enablempls)  
                         print_mpls(mplss);  
                 }                  }
                   if (ctl->enablempls)
                       print_mpls(mplss);
 #else  #else
                 int k;                  int k;
                 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]);
                     }                      }
                 }                  }
   
                 if (z == 1) {                  if (z == 1) {
                    printf("    |  `|-- %s\n", strlongip(ctl, addr2));                    printf("    |  `|-- %s\n", strlongip(ctl->af, 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->af, 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 prompt 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(
     void)      void)
 {  {
Line 428  void xml_close( Line 447  void xml_close(
                 title = "Loss";                  title = "Loss";
             }              }
   
            /* 1000.0 is a temporay hack for stats usec to ms, impacted net_loss. */            /* 1000.0 is a temporary hack for stats usec to ms, impacted net_loss. */
             if (strchr(data_fields[j].format, 'f')) {              if (strchr(data_fields[j].format, 'f')) {
                 printf(name,                  printf(name,
                        title, data_fields[j].net_xxx(at) / 1000.0, title);                         title, data_fields[j].net_xxx(at) / 1000.0, title);
Line 451  void csv_close( Line 470  void csv_close(
     struct mtr_ctl *ctl,      struct mtr_ctl *ctl,
     time_t now)      time_t now)
 {  {
    int i, j, at, max;    int i, j, at, max, z, w;
     ip_t *addr;      ip_t *addr;
       ip_t *addr2 = NULL;
     char name[MAX_FORMAT_STR];      char name[MAX_FORMAT_STR];
   
     for (i = 0; i < MAXFLD; i++) {      for (i = 0; i < MAXFLD; i++) {
Line 499  void csv_close( Line 519  void csv_close(
             if (j < 0)              if (j < 0)
                 continue;                  continue;
   
            /* 1000.0 is a temporay hack for stats usec to ms, impacted net_loss. */            /* 1000.0 is a temporary hack for stats usec to ms, impacted net_loss. */
             if (strchr(data_fields[j].format, 'f')) {              if (strchr(data_fields[j].format, 'f')) {
                 printf(",%.2f",                  printf(",%.2f",
                        (double) (data_fields[j].net_xxx(at) / 1000.0));                         (double) (data_fields[j].net_xxx(at) / 1000.0));
Line 508  void csv_close( Line 528  void csv_close(
             }              }
         }          }
         printf("\n");          printf("\n");
           if (ctl->reportwide == 0)
               continue;
           
           for (z = 0; z < MAX_PATH; z++) {
               int found = 0;
               addr2 = net_addrs(at, z);
               snprint_addr(ctl, name, sizeof(name), addr2);
               if ((addrcmp
                       ((void *) &ctl->unspec_addr, (void *) addr2,
                        ctl->af)) == 0) {
                   break;
               } else if ((addrcmp
                       ((void *) addr, (void *) addr2,
                        ctl->af)) == 0) {
                   continue; /* Latest Host is already printed */
               } else {
                   for (w = 0; w < z; w++)
                       /* Ok... checking if there are ips repeated on same hop */
                       if ((addrcmp
                               ((void *) addr2, (void *) net_addrs(at, w),
                                ctl->af)) == 0) {
                           found = 1;
                           break;
                       }
   
                   if (!found) {
   #ifdef HAVE_IPINFO
                       if (!ctl->ipinfo_no) {
                           char *fmtinfo = fmt_ipinfo(ctl, addr2);
                           fmtinfo = trim(fmtinfo, '\0');
                           printf("MTR.%s,%lld,%s,%s,%d,%s,%s", PACKAGE_VERSION,
                               (long long) now, "OK", ctl->Hostname, at + 1, name,
                               fmtinfo);
                       } else
   #endif
                           printf("MTR.%s,%lld,%s,%s,%d,%s", PACKAGE_VERSION,
                              (long long) now, "OK", ctl->Hostname, at + 1, name);
   
                       /* Use values associated with the first ip discovered for this hop */
                       for (i = 0; i < MAXFLD; i++) {
                           j = ctl->fld_index[ctl->fld_active[i]];
                           if (j < 0)
                               continue;
   
                           /* 1000.0 is a temporary hack for stats usec to ms, impacted net_loss. */
                           if (strchr(data_fields[j].format, 'f')) {
                               printf(",%.2f",
                                      (double) (data_fields[j].net_xxx(at) / 1000.0));
                           } else {
                               printf(",%d", data_fields[j].net_xxx(at));
                           }
                       }
                       printf("\n");
                   }
               }    
           }
     }      }
 }  }

Removed from v.1.1  
changed lines
  Added in v.1.1.1.3


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>