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

version 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 70 Line 70
 #endif  #endif
   
   
   char *myname;
   
 const struct fields data_fields[MAXFLD] = {  const struct fields data_fields[MAXFLD] = {
     /* key, Remark, Header, Format, Width, CallBackFunc */      /* key, Remark, Header, Format, Width, CallBackFunc */
     {' ', "<sp>: Space between fields", " ", " ", 1, &net_drop},      {' ', "<sp>: Space between fields", " ", " ", 1, &net_drop},
Line 110  static void __attribute__ ((__noreturn__)) usage(FILE  Line 112  static void __attribute__ ((__noreturn__)) usage(FILE 
           out);            out);
     fputs(" -T, --tcp                  use TCP instead of ICMP echo\n",      fputs(" -T, --tcp                  use TCP instead of ICMP echo\n",
           out);            out);
       fputs(" -I, --interface NAME       use named network interface\n",
            out);
     fputs      fputs
         (" -a, --address ADDRESS      bind the outgoing socket to ADDRESS\n",          (" -a, --address ADDRESS      bind the outgoing socket to ADDRESS\n",
          out);           out);
Line 161  static void __attribute__ ((__noreturn__)) usage(FILE  Line 165  static void __attribute__ ((__noreturn__)) usage(FILE 
 #ifdef HAVE_GTK  #ifdef HAVE_GTK
     fputs(" -g, --gtk                  use GTK+ xwindow interface\n", out);      fputs(" -g, --gtk                  use GTK+ xwindow interface\n", out);
 #endif  #endif
    fputs(" -n, --no-dns               do not resove host names\n", out);    fputs(" -n, --no-dns               do not resolve host names\n", out);
     fputs(" -b, --show-ips             show IP numbers and host names\n",      fputs(" -b, --show-ips             show IP numbers and host names\n",
           out);            out);
     fputs(" -o, --order FIELDS         select output fields\n", out);      fputs(" -o, --order FIELDS         select output fields\n", out);
Line 295  static void init_fld_options( Line 299  static void init_fld_options(
 {  {
     int i;      int i;
   
    memset(ctl->fld_index, -1, FLD_INDEX_SZ);    memset(ctl->fld_index, -1, FLD_INDEX_SZ*sizeof(ctl->fld_index[0]));
   
     for (i = 0; data_fields[i].key != 0; i++) {      for (i = 0; data_fields[i].key != 0; i++) {
         ctl->available_options[i] = data_fields[i].key;          ctl->available_options[i] = data_fields[i].key;
         ctl->fld_index[data_fields[i].key] = i;          ctl->fld_index[data_fields[i].key] = i;
     }      }
       ctl->available_options[i++] = '_';
     ctl->available_options[i] = 0;      ctl->available_options[i] = 0;
 }  }
   
Line 344  static void parse_arg( Line 349  static void parse_arg(
 #endif  #endif
         {"raw", 0, NULL, 'l'},          {"raw", 0, NULL, 'l'},
         {"csv", 0, NULL, 'C'},          {"csv", 0, NULL, 'C'},
   #ifdef HAVE_JANSSON
         {"json", 0, NULL, 'j'},          {"json", 0, NULL, 'j'},
   #endif
         {"displaymode", 1, NULL, OPT_DISPLAYMODE},          {"displaymode", 1, NULL, OPT_DISPLAYMODE},
         {"split", 0, NULL, 'p'},        /* BL */          {"split", 0, NULL, 'p'},        /* BL */
         /* maybe above should change to -d 'x' */          /* maybe above should change to -d 'x' */
Line 363  static void parse_arg( Line 370  static void parse_arg(
         {"bitpattern", 1, NULL, 'B'},   /* overload B>255, ->rand(0,255) */          {"bitpattern", 1, NULL, 'B'},   /* overload B>255, ->rand(0,255) */
         {"tos", 1, NULL, 'Q'},  /* typeof service (0,255) */          {"tos", 1, NULL, 'Q'},  /* typeof service (0,255) */
         {"mpls", 0, NULL, 'e'},          {"mpls", 0, NULL, 'e'},
           {"interface", 1, NULL, 'I'},
         {"address", 1, NULL, 'a'},          {"address", 1, NULL, 'a'},
         {"first-ttl", 1, NULL, 'f'},    /* -f & -m are borrowed from traceroute */          {"first-ttl", 1, NULL, 'f'},    /* -f & -m are borrowed from traceroute */
         {"max-ttl", 1, NULL, 'm'},          {"max-ttl", 1, NULL, 'm'},
Line 439  static void parse_arg( Line 447  static void parse_arg(
         case 'C':          case 'C':
             ctl->DisplayMode = DisplayCSV;              ctl->DisplayMode = DisplayCSV;
             break;              break;
   #ifdef HAVE_JANSSON
         case 'j':          case 'j':
             ctl->DisplayMode = DisplayJSON;              ctl->DisplayMode = DisplayJSON;
             break;              break;
   #endif
         case 'x':          case 'x':
             ctl->DisplayMode = DisplayXML;              ctl->DisplayMode = DisplayXML;
             break;              break;
Line 462  static void parse_arg( Line 472  static void parse_arg(
             ctl->cpacketsize =              ctl->cpacketsize =
                 strtonum_or_err(optarg, "invalid argument", STRTO_INT);                  strtonum_or_err(optarg, "invalid argument", STRTO_INT);
             break;              break;
           case 'I':
               ctl->InterfaceName = optarg;
               break;
         case 'a':          case 'a':
             ctl->InterfaceAddress = optarg;              ctl->InterfaceAddress = optarg;
             break;              break;
Line 476  static void parse_arg( Line 489  static void parse_arg(
             if (ctl->WaitTime <= 0.0) {              if (ctl->WaitTime <= 0.0) {
                 error(EXIT_FAILURE, 0, "wait time must be positive");                  error(EXIT_FAILURE, 0, "wait time must be positive");
             }              }
            if (getuid() != 0 && ctl->WaitTime < 1.0) {            if (!running_as_root() && ctl->WaitTime < 1.0) {
                 error(EXIT_FAILURE, 0,                  error(EXIT_FAILURE, 0,
                       "non-root users cannot request an interval < 1.0 seconds");                        "non-root users cannot request an interval < 1.0 seconds");
             }              }
Line 635  static void parse_arg( Line 648  static void parse_arg(
   
     if (ctl->DisplayMode == DisplayReport ||      if (ctl->DisplayMode == DisplayReport ||
         ctl->DisplayMode == DisplayTXT ||          ctl->DisplayMode == DisplayTXT ||
   #ifdef HAVE_JANSSON
         ctl->DisplayMode == DisplayJSON ||          ctl->DisplayMode == DisplayJSON ||
   #endif
         ctl->DisplayMode == DisplayXML ||          ctl->DisplayMode == DisplayXML ||
         ctl->DisplayMode == DisplayRaw || ctl->DisplayMode == DisplayCSV)          ctl->DisplayMode == DisplayRaw || ctl->DisplayMode == DisplayCSV)
         ctl->Interactive = 0;          ctl->Interactive = 0;
Line 681  static void init_rand( Line 696  static void init_rand(
     srand((getpid() << 16) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec);      srand((getpid() << 16) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec);
 }  }
   
   
   /*
       For historical reasons, we need a hostent structure to represent
       our remote target for probing.  The obsolete way of doing this
       would be to use gethostbyname().  We'll use getaddrinfo() instead
       to generate the hostent.
   */
   static int get_hostent_from_name(
       struct mtr_ctl *ctl,
       struct hostent *host,
       const char *name,
       char **alptr)
   {
       int gai_error;
       struct addrinfo hints, *res;
       struct sockaddr_in *sa4;
   #ifdef ENABLE_IPV6
       struct sockaddr_in6 *sa6;
   #endif
   
       /* gethostbyname2() is deprecated so we'll use getaddrinfo() instead. */
       memset(&hints, 0, sizeof hints);
       hints.ai_family = ctl->af;
       hints.ai_socktype = SOCK_DGRAM;
       gai_error = getaddrinfo(name, NULL, &hints, &res);
       if (gai_error) {
           if (gai_error == EAI_SYSTEM)
               error(0, 0, "Failed to resolve host: %s", name);
           else
               error(0, 0, "Failed to resolve host: %s: %s", name,
                     gai_strerror(gai_error));
   
           return -1;
       }
   
       /* Convert the first addrinfo into a hostent. */
       memset(host, 0, sizeof(struct hostent));
       host->h_name = res->ai_canonname;
       host->h_aliases = NULL;
       host->h_addrtype = res->ai_family;
       ctl->af = res->ai_family;
       host->h_length = res->ai_addrlen;
       host->h_addr_list = alptr;
       switch (ctl->af) {
       case AF_INET:
           sa4 = (struct sockaddr_in *) res->ai_addr;
           alptr[0] = (void *) &(sa4->sin_addr);
           break;
   #ifdef ENABLE_IPV6
       case AF_INET6:
           sa6 = (struct sockaddr_in6 *) res->ai_addr;
           alptr[0] = (void *) &(sa6->sin6_addr);
           break;
   #endif
       default:
           error(0, 0, "unknown address type");
   
           errno = EINVAL;
           return -1;
       }
       alptr[1] = NULL;
   
       return 0;
   }
   
   
 int main(  int main(
     int argc,      int argc,
     char **argv)      char **argv)
 {  {
     struct hostent *host = NULL;      struct hostent *host = NULL;
     struct addrinfo hints, *res;  
     int gai_error;  
     struct hostent trhost;      struct hostent trhost;
     char *alptr[2];      char *alptr[2];
     struct sockaddr_in *sa4;  
 #ifdef ENABLE_IPV6  
     struct sockaddr_in6 *sa6;  
 #endif  
     names_t *names_head = NULL;      names_t *names_head = NULL;
     names_t *names_walk;      names_t *names_walk;
   
       myname = argv[0];
     struct mtr_ctl ctl;      struct mtr_ctl ctl;
     memset(&ctl, 0, sizeof(ctl));      memset(&ctl, 0, sizeof(ctl));
     /* initialize non-null values */      /* initialize non-null values */
Line 761  int main( Line 837  int main(
                      sizeof(ctl.LocalHostname));                       sizeof(ctl.LocalHostname));
         }          }
   
         /* gethostbyname2() is deprecated so we'll use getaddrinfo() instead. */  
         memset(&hints, 0, sizeof hints);  
         hints.ai_family = ctl.af;  
         hints.ai_socktype = SOCK_DGRAM;  
         gai_error = getaddrinfo(ctl.Hostname, NULL, &hints, &res);  
         if (gai_error) {  
             if (gai_error == EAI_SYSTEM)  
                 error(0, 0, "Failed to resolve host: %s", ctl.Hostname);  
             else  
                 error(0, 0, "Failed to resolve host: %s: %s", ctl.Hostname,  
                       gai_strerror(gai_error));  
   
             if (ctl.Interactive)  
                 exit(EXIT_FAILURE);  
             else {  
                 names_walk = names_walk->next;  
                 continue;  
             }  
         }  
         /* Convert the first addrinfo into a hostent. */  
         host = &trhost;          host = &trhost;
        memset(host, 0, sizeof trhost);        if (get_hostent_from_name(&ctl, host, ctl.Hostname, alptr) != 0) {
        host->h_name = res->ai_canonname; 
        host->h_aliases = NULL; 
        host->h_addrtype = res->ai_family; 
        ctl.af = res->ai_family; 
        host->h_length = res->ai_addrlen; 
        host->h_addr_list = alptr; 
        switch (ctl.af) { 
        case AF_INET: 
            sa4 = (struct sockaddr_in *) res->ai_addr; 
            alptr[0] = (void *) &(sa4->sin_addr); 
            break; 
#ifdef ENABLE_IPV6 
        case AF_INET6: 
            sa6 = (struct sockaddr_in6 *) res->ai_addr; 
            alptr[0] = (void *) &(sa6->sin6_addr); 
            break; 
#endif 
        default: 
            error(0, 0, "unknown address type"); 
             if (ctl.Interactive)              if (ctl.Interactive)
                 exit(EXIT_FAILURE);                  exit(EXIT_FAILURE);
             else {              else {
Line 809  int main( Line 846  int main(
                 continue;                  continue;
             }              }
         }          }
         alptr[1] = NULL;  
   
         if (net_open(&ctl, host) != 0) {          if (net_open(&ctl, host) != 0) {
             error(0, 0, "Unable to start net module");              error(0, 0, "Unable to start net module");

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


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