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

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"
   
 #include <errno.h>  #include <errno.h>
   #include <sys/types.h>
   #include <ifaddrs.h>
 #include <math.h>  #include <math.h>
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
Line 37 Line 39
 #include "display.h"  #include "display.h"
 #include "dns.h"  #include "dns.h"
 #include "utils.h"  #include "utils.h"
   #include "packet/sockaddr.h"
   
 #define MinSequence 33000  #define MinSequence 33000
 #define MaxSequence 65536  #define MaxSequence 65536
   
 static int packetsize;          /* packet size used by ping */  static int packetsize;          /* packet size used by ping */
   
 static void sockaddrtop(  
     struct sockaddr *saddr,  
     char *strptr,  
     size_t len);  
   
 struct nethost {  struct nethost {
    ip_t addr;    ip_t addr;                  /* Latest host to respond */
    ip_t addrs[MAXPATH];        /* for multi paths byMin */    ip_t addrs[MAX_PATH];        /* For Multi paths/Path Changes: List of all hosts that have responded */
     int err;
     int xmit;      int xmit;
     int returned;      int returned;
     int sent;      int sent;
Line 69  struct nethost { Line 68  struct nethost {
     int saved[SAVED_PINGS];      int saved[SAVED_PINGS];
     int saved_seq_offset;      int saved_seq_offset;
     struct mplslen mpls;      struct mplslen mpls;
    struct mplslen mplss[MAXPATH];    struct mplslen mplss[MAX_PATH];
 };  };
   
   
Line 85  static struct nethost host[MaxHost]; Line 84  static struct nethost host[MaxHost];
 static struct sequence sequence[MaxSequence];  static struct sequence sequence[MaxSequence];
 static struct packet_command_pipe_t packet_command_pipe;  static struct packet_command_pipe_t packet_command_pipe;
   
 #ifdef ENABLE_IPV6  
 static struct sockaddr_storage sourcesockaddr_struct;  static struct sockaddr_storage sourcesockaddr_struct;
 static struct sockaddr_storage remotesockaddr_struct;  static struct sockaddr_storage remotesockaddr_struct;
 static struct sockaddr_in6 *ssa6 =  
     (struct sockaddr_in6 *) &sourcesockaddr_struct;  
 static struct sockaddr_in6 *rsa6 =  
     (struct sockaddr_in6 *) &remotesockaddr_struct;  
 #else  
 static struct sockaddr_in sourcesockaddr_struct;  
 static struct sockaddr_in remotesockaddr_struct;  
 #endif  
   
 static struct sockaddr *sourcesockaddr =  static struct sockaddr *sourcesockaddr =
     (struct sockaddr *) &sourcesockaddr_struct;      (struct sockaddr *) &sourcesockaddr_struct;
 static struct sockaddr *remotesockaddr =  static struct sockaddr *remotesockaddr =
     (struct sockaddr *) &remotesockaddr_struct;      (struct sockaddr *) &remotesockaddr_struct;
 static struct sockaddr_in *ssa4 =  
     (struct sockaddr_in *) &sourcesockaddr_struct;  
 static struct sockaddr_in *rsa4 =  
     (struct sockaddr_in *) &remotesockaddr_struct;  
   
 static ip_t *sourceaddress;  static ip_t *sourceaddress;
 static ip_t *remoteaddress;  static ip_t *remoteaddress;
Line 121  static char localaddr[INET_ADDRSTRLEN]; Line 107  static char localaddr[INET_ADDRSTRLEN];
 static int batch_at = 0;  static int batch_at = 0;
 static int numhosts = 10;  static int numhosts = 10;
   
   
   #define host_addr_cmp(index, other, af) \
       addrcmp((void *) &(host[(index)].addr), (void *) (other), (af))
   
   #define host_addrs_cmp(index, path, other, af) \
       addrcmp((void *) &(host[(index)].addrs[path]), (void *) (other), (af))
   
   
 /* return the number of microseconds to wait before sending the next  /* return the number of microseconds to wait before sending the next
    ping */     ping */
 int calc_deltatime(  int calc_deltatime(
Line 181  static void net_send_query( Line 175  static void net_send_query(
     int time_to_live = index + 1;      int time_to_live = index + 1;
   
     send_probe_command(ctl, &packet_command_pipe, remoteaddress,      send_probe_command(ctl, &packet_command_pipe, remoteaddress,
                       sourceaddress, packetsize, seq, time_to_live);                       sourceaddress, packet_size, seq, time_to_live);
 }  }
   
   
/* We got a return on something we sent out.  Record the address and/*
   time.  */    Mark a sequence entry as completed and return the host index
     being probed.
 
     Returns -1 in the case of an invalid sequence number.
 */
 static int mark_sequence_complete(
     int seq)
 {
     if ((seq < 0) || (seq >= MaxSequence)) {
         return -1;
     }
 
     if (!sequence[seq].transit) {
         return -1;
     }
     sequence[seq].transit = 0;
 
     return sequence[seq].index;
 }
 
 
 /*
     A probe has successfully completed.
 
     Record the round trip time and address of the responding host.
 */
 
 static void net_process_ping(  static void net_process_ping(
     struct mtr_ctl *ctl,      struct mtr_ctl *ctl,
     int seq,      int seq,
       int err,
     struct mplslen *mpls,      struct mplslen *mpls,
     ip_t * addr,      ip_t * addr,
     int totusec)      int totusec)
Line 198  static void net_process_ping( Line 219  static void net_process_ping(
     int oldavg;                 /* usedByMin */      int oldavg;                 /* usedByMin */
     int oldjavg;                /* usedByMin */      int oldjavg;                /* usedByMin */
     int i;                      /* usedByMin */      int i;                      /* usedByMin */
       int found = 0;
 #ifdef ENABLE_IPV6  #ifdef ENABLE_IPV6
     char addrcopy[sizeof(struct in6_addr)];      char addrcopy[sizeof(struct in6_addr)];
 #else  #else
     char addrcopy[sizeof(struct in_addr)];      char addrcopy[sizeof(struct in_addr)];
 #endif  #endif
       struct nethost *nh = NULL;
   
    addrcpy((void *) &addrcopy, (char *) addr, ctl->af);    memcpy(&addrcopy, addr, sockaddr_addr_size(sourcesockaddr));
   
    if ((seq < 0) || (seq >= MaxSequence)) {    index = mark_sequence_complete(seq);
     if (index < 0) {
         return;          return;
     }      }
       nh = &host[index];
       nh->err = err;
   
     if (!sequence[seq].transit) {  
         return;  
     }  
     sequence[seq].transit = 0;  
   
     index = sequence[seq].index;  
   
    if (addrcmp((void *) &(host[index].addr),    if (addrcmp(&nh->addr, &addrcopy, ctl->af) != 0) {
                (void *) &ctl->unspec_addr, ctl->af) == 0) {        for (i = 0; i < MAX_PATH;) {
        /* should be out of if as addr can change */            if (addrcmp(&nh->addrs[i], &nh->addr, ctl->af) == 0) {
        addrcpy((void *) &(host[index].addr), addrcopy, ctl->af);                found = 1; /* This host is already in the list */
        host[index].mpls = *mpls; 
        display_rawhost(ctl, index, (void *) &(host[index].addr)); 
 
        /* multi paths */ 
        addrcpy((void *) &(host[index].addrs[0]), addrcopy, ctl->af); 
        host[index].mplss[0] = *mpls; 
    } else { 
        for (i = 0; i < MAXPATH;) { 
            if (addrcmp 
                ((void *) &(host[index].addrs[i]), (void *) &addrcopy, 
                 ctl->af) == 0 
                || addrcmp((void *) &(host[index].addrs[i]), 
                           (void *) &ctl->unspec_addr, ctl->af) == 0) { 
                 break;                  break;
             }              }
               if (addrcmp(&nh->addrs[i], &ctl->unspec_addr, ctl->af) == 0) {
                   break; /* Found first vacant position */
               }
             i++;              i++;
         }          }
   
        if (addrcmp((void *) &(host[index].addrs[i]), addrcopy, ctl->af) !=        if (found == 0 && i < MAX_PATH) {
            0 && i < MAXPATH) {            memcpy(&nh->addrs[i], &nh->addr, sockaddr_addr_size(sourcesockaddr));
            addrcpy((void *) &(host[index].addrs[i]), addrcopy, ctl->af);
            host[index].mplss[i] = *mpls;            nh->mplss[i] = nh->mpls;
            display_rawhost(ctl, index, (void *) &(host[index].addrs[i]));            display_rawhost(ctl, index, (void *)&(nh->addrs[i]), (void *)&(nh->addrs[i]));
         }          }
   
           /* Always save the latest host in nh->addr. This
            * allows maxTTL to change whenever path changes.
            */
           memcpy(&nh->addr, addrcopy, sockaddr_addr_size(sourcesockaddr));
           nh->mpls = *mpls;
           display_rawhost(ctl, index, (void *)&(nh->addr), (void *)&(nh->mpls));
     }      }
   
    host[index].jitter = totusec - host[index].last;    nh->jitter = totusec - nh->last;
    if (host[index].jitter < 0) {    if (nh->jitter < 0) {
        host[index].jitter = -host[index].jitter;        nh->jitter = -nh->jitter;
     }      }
   
    host[index].last = totusec;    nh->last = totusec;
   
    if (host[index].returned < 1) {    if (nh->returned < 1) {
        host[index].best = host[index].worst = host[index].gmean = totusec;        nh->best = nh->worst = nh->gmean = totusec;
        host[index].avg = host[index].ssd = 0;        nh->avg = nh->ssd = 0;
   
        host[index].jitter = host[index].jworst = host[index].jinta = 0;        nh->jitter = nh->jworst = nh->jinta = 0;
     }      }
   
    if (totusec < host[index].best) {    if (totusec < nh->best) {
        host[index].best = totusec;        nh->best = totusec;
     }      }
    if (totusec > host[index].worst) {    if (totusec > nh->worst) {
        host[index].worst = totusec;        nh->worst = totusec;
     }      }
   
    if (host[index].jitter > host[index].jworst) {    if (nh->jitter > nh->jworst) {
        host[index].jworst = host[index].jitter;        nh->jworst = nh->jitter;
     }      }
   
    host[index].returned++;    nh->returned++;
    oldavg = host[index].avg;    oldavg = nh->avg;
    host[index].avg += (totusec - oldavg + .0) / host[index].returned;    nh->avg += (totusec - oldavg + .0) / nh->returned;
    host[index].ssd +=    nh->ssd +=
        (totusec - oldavg + .0) * (totusec - host[index].avg);        (totusec - oldavg + .0) * (totusec - nh->avg);
   
    oldjavg = host[index].javg;    oldjavg = nh->javg;
    host[index].javg +=    nh->javg +=
        (host[index].jitter - oldjavg) / host[index].returned;        (nh->jitter - oldjavg) / nh->returned;
     /* below algorithm is from rfc1889, A.8 */      /* below algorithm is from rfc1889, A.8 */
    host[index].jinta +=    nh->jinta +=
        host[index].jitter - ((host[index].jinta + 8) >> 4);        nh->jitter - ((nh->jinta + 8) >> 4);
   
    if (host[index].returned > 1) {    if (nh->returned > 1) {
        host[index].gmean =        nh->gmean =
            pow((double) host[index].gmean,            pow((double) nh->gmean,
                (host[index].returned - 1.0) / host[index].returned)                (nh->returned - 1.0) / nh->returned)
            * pow((double) totusec, 1.0 / host[index].returned);            * pow((double) totusec, 1.0 / nh->returned);
     }      }
   
    host[index].sent = 0;    nh->sent = 0;
    host[index].up = 1;    nh->up = 1;
    host[index].transit = 0;    nh->transit = 0;
   
     net_save_return(index, sequence[seq].saved_seq, totusec);      net_save_return(index, sequence[seq].saved_seq, totusec);
     display_rawping(ctl, index, totusec, seq);      display_rawping(ctl, index, totusec, seq);
Line 325  ip_t *net_addrs( Line 343  ip_t *net_addrs(
     return (ip_t *) & (host[at].addrs[i]);      return (ip_t *) & (host[at].addrs[i]);
 }  }
   
   /*
       Get the error code corresponding to a host entry.
   */
   int net_err(
       int at)
   {
       return host[at].err;
   }
   
 void *net_mpls(  void *net_mpls(
     int at)      int at)
 {  {
Line 440  int net_max( Line 467  int net_max(
     int max;      int max;
   
     max = 0;      max = 0;
    for (at = 0; at < ctl->maxTTL - 1; at++) {    for (at = 0; at < ctl->maxTTL; at++) {
        if (addrcmp((void *) &(host[at].addr),        if (host_addr_cmp(at , remoteaddress, ctl->af) == 0) {
                    (void *) remoteaddress, ctl->af) == 0) { 
             return at + 1;              return at + 1;
        } else if (addrcmp((void *) &(host[at].addr),        } else if (host[at].err != 0) {
                           (void *) &ctl->unspec_addr, ctl->af) != 0) {            /*
                 If a hop has returned an ICMP error
                 (such as "no route to host") then we'll consider that the
                 final hop.
             */
             return at + 1;
         } else if (host_addr_cmp(at, &ctl->unspec_addr, ctl->af) != 0) {
             max = at + 2;              max = at + 2;
         }          }
     }      }
   
       if (max > ctl->maxTTL)
           max = ctl->maxTTL;
     return max;      return max;
 }  }
   
Line 503  int net_send_batch( Line 537  int net_send_batch(
     struct mtr_ctl *ctl)      struct mtr_ctl *ctl)
 {  {
     int n_unknown = 0, i;      int n_unknown = 0, i;
       int restart = 0;
   
     /* randomized packet size and/or bit pattern if packetsize<0 and/or       /* randomized packet size and/or bit pattern if packetsize<0 and/or 
        bitpattern<0.  abs(packetsize) and/or abs(bitpattern) will be used          bitpattern<0.  abs(packetsize) and/or abs(bitpattern) will be used 
Line 514  int net_send_batch( Line 549  int net_send_batch(
                have a range for "rand()" that runs to 32768, and the                  have a range for "rand()" that runs to 32768, and the 
                destination range is 10000, you end up with 4 out of 32768                  destination range is 10000, you end up with 4 out of 32768 
                0-2768's and only 3 out of 32768 for results 2769 .. 9999.                  0-2768's and only 3 out of 32768 for results 2769 .. 9999. 
               As our detination range (in the example 10000) is much                As our destination range (in the example 10000) is much 
                smaller (reasonable packet sizes), and our rand() range much                  smaller (reasonable packet sizes), and our rand() range much 
                larger, this effect is insignificant. Oh! That other formula                 larger, this effect is insignificant. Oh! That other formula
                didn't work. */                 didn't work. */
Line 532  int net_send_batch( Line 567  int net_send_batch(
     net_send_query(ctl, batch_at, abs(packetsize));      net_send_query(ctl, batch_at, abs(packetsize));
   
     for (i = ctl->fstTTL - 1; i < batch_at; i++) {      for (i = ctl->fstTTL - 1; i < batch_at; i++) {
        if (addrcmp        if (host_addr_cmp(i, &ctl->unspec_addr, ctl->af) == 0)
            ((void *) &(host[i].addr), (void *) &ctl->unspec_addr, 
             ctl->af) == 0) 
             n_unknown++;              n_unknown++;
   
         /* The second condition in the next "if" statement was added in mtr-0.56,           /* The second condition in the next "if" statement was added in mtr-0.56, 
Line 542  int net_send_batch( Line 575  int net_send_batch(
            hosts. Removed in 0.65.              hosts. Removed in 0.65. 
            If the line proves necessary, it should at least NOT trigger that line             If the line proves necessary, it should at least NOT trigger that line
            when host[i].addr == 0 */             when host[i].addr == 0 */
        if ((addrcmp((void *) &(host[i].addr),        if (host_addr_cmp(i, remoteaddress, ctl->af) == 0) {
                     (void *) remoteaddress, ctl->af) == 0))            restart = 1;
            n_unknown = MaxHost;        /* Make sure we drop into "we should restart" */            numhosts = i + 1; /* Saves batch_at - index number of probes in the next round!*/
             break;
         }
     }      }
   
     if (                        /* success in reaching target */      if (                        /* success in reaching target */
           (addrcmp((void *) &(host[batch_at].addr),           (host_addr_cmp(batch_at, remoteaddress, ctl->af) == 0) ||
                    (void *) remoteaddress, ctl->af) == 0) || 
            /* fail in consecutive maxUnknown (firewall?) */             /* fail in consecutive maxUnknown (firewall?) */
            (n_unknown > ctl->maxUnknown) ||             (n_unknown > ctl->maxUnknown) ||
            /* or reach limit  */             /* or reach limit  */
            (batch_at >= ctl->maxTTL - 1)) {             (batch_at >= ctl->maxTTL - 1)) {
           restart = 1;
         numhosts = batch_at + 1;          numhosts = batch_at + 1;
       }
   
       if(restart) {
         batch_at = ctl->fstTTL - 1;          batch_at = ctl->fstTTL - 1;
         return 1;          return 1;
     }      }
Line 582  static void net_validate_interface_address( Line 620  static void net_validate_interface_address(
   
   
 /*  /*
       Given the name of a network interface and a preferred address
       family (IPv4 or IPv6), find the source IP address for sending
       probes from that interface.
   */
   static void net_find_interface_address_from_name(
       struct sockaddr_storage *addr,
       int address_family,
       const char *interface_name)
   {
       struct ifaddrs *ifaddrs;
       struct ifaddrs *interface;
       int found_interface_name = 0;
   
       if (getifaddrs(&ifaddrs) != 0) {
           error(EXIT_FAILURE, errno, "getifaddrs failure");
       }
   
       interface = ifaddrs;
       while (interface != NULL) {
           if (interface->ifa_addr != NULL && !strcmp(interface->ifa_name, interface_name)) {
               found_interface_name = 1;
   
               if (interface->ifa_addr->sa_family == address_family) {
                   if (address_family == AF_INET) {
                       memcpy(addr,
                           interface->ifa_addr, sizeof(struct sockaddr_in));
                       freeifaddrs(ifaddrs);
   
                       return;
                   } else if (address_family == AF_INET6) {
                       memcpy(addr,
                           interface->ifa_addr, sizeof(struct sockaddr_in6));
                       freeifaddrs(ifaddrs);
   
                       return;
                   }
               }
           }
   
           interface = interface->ifa_next;
       }
   
       if (!found_interface_name) {
           error(EXIT_FAILURE, 0, "no such interface");
       } else if (address_family == AF_INET) {
           error(EXIT_FAILURE, 0, "interface missing IPv4 address");
       } else if (address_family == AF_INET6) {
           error(EXIT_FAILURE, 0, "interface missing IPv6 address");
       } else {
           error(EXIT_FAILURE, 0, "interface missing address");
       }
   }
   
   
   /*
   Find the local address we will use to sent to the remote    Find the local address we will use to sent to the remote
   host by connecting a UDP socket and checking the address    host by connecting a UDP socket and checking the address
   the socket is bound to.    the socket is bound to.
Line 592  static void net_find_local_address( Line 685  static void net_find_local_address(
     int udp_socket;      int udp_socket;
     int addr_length;      int addr_length;
     struct sockaddr_storage remote_sockaddr;      struct sockaddr_storage remote_sockaddr;
     struct sockaddr_in *remote4;  
     struct sockaddr_in6 *remote6;  
   
     udp_socket =      udp_socket =
         socket(remotesockaddr->sa_family, SOCK_DGRAM, IPPROTO_UDP);          socket(remotesockaddr->sa_family, SOCK_DGRAM, IPPROTO_UDP);
Line 605  static void net_find_local_address( Line 696  static void net_find_local_address(
        We need to set the port to a non-zero value for the connect         We need to set the port to a non-zero value for the connect
        to succeed.         to succeed.
      */       */
    if (remotesockaddr->sa_family == AF_INET6) {    addr_length = sockaddr_size(&remotesockaddr_struct);
#ifdef ENABLE_IPV6    memcpy(&remote_sockaddr, &remotesockaddr_struct, addr_length);
        addr_length = sizeof(struct sockaddr_in6);    *sockaddr_port_offset(&remote_sockaddr) = htons(1);
   
         memcpy(&remote_sockaddr, rsa6, addr_length);  
         remote6 = (struct sockaddr_in6 *) &remote_sockaddr;  
         remote6->sin6_port = htons(1);  
 #endif  
     } else {  
         addr_length = sizeof(struct sockaddr_in);  
   
         memcpy(&remote_sockaddr, rsa4, addr_length);  
         remote4 = (struct sockaddr_in *) &remote_sockaddr;  
         remote4->sin_port = htons(1);  
     }  
   
     if (connect      if (connect
        (udp_socket, (struct sockaddr *) &remote_sockaddr, addr_length)) {        (udp_socket, (struct sockaddr *) &remote_sockaddr, sockaddr_size(&remote_sockaddr))) {
 #ifdef __linux__
         /* Linux doesn't require source address, so we can support
          * a case when mtr is run against unreachable host (that can become
          * reachable) */
         if (errno == EHOSTUNREACH) {
             close(udp_socket);
             localaddr[0] = '\0';
             return;
         }
 #endif
         error(EXIT_FAILURE, errno, "udp socket connect failed");          error(EXIT_FAILURE, errno, "udp socket connect failed");
     }      }
   
Line 631  static void net_find_local_address( Line 720  static void net_find_local_address(
         error(EXIT_FAILURE, errno, "local address determination failed");          error(EXIT_FAILURE, errno, "local address determination failed");
     }      }
   
    sockaddrtop(sourcesockaddr, localaddr, sizeof(localaddr));    inet_ntop(sourcesockaddr->sa_family, sockaddr_addr_offset(sourcesockaddr), localaddr, sizeof(localaddr));
   
     close(udp_socket);      close(udp_socket);
 }  }
Line 651  int net_open( Line 740  int net_open(
   
     net_reset(ctl);      net_reset(ctl);
   
    remotesockaddr->sa_family = hostent->h_addrtype;    remotesockaddr->sa_family = sourcesockaddr->sa_family = hostent->h_addrtype;
     memcpy(sockaddr_addr_offset(remotesockaddr), hostent->h_addr, sockaddr_addr_size(remotesockaddr));
   
    switch (hostent->h_addrtype) {    sourceaddress = sockaddr_addr_offset(sourcesockaddr);
    case AF_INET:    remoteaddress = sockaddr_addr_offset(remotesockaddr);
        addrcpy((void *) &(rsa4->sin_addr), hostent->h_addr, AF_INET); 
        sourceaddress = (ip_t *) & (ssa4->sin_addr); 
        remoteaddress = (ip_t *) & (rsa4->sin_addr); 
        break; 
#ifdef ENABLE_IPV6 
    case AF_INET6: 
        addrcpy((void *) &(rsa6->sin6_addr), hostent->h_addr, AF_INET6); 
        sourceaddress = (ip_t *) & (ssa6->sin6_addr); 
        remoteaddress = (ip_t *) & (rsa6->sin6_addr); 
        break; 
#endif 
    default: 
        error(EXIT_FAILURE, 0, "net_open bad address type"); 
    } 
   
     if (ctl->InterfaceAddress) {      if (ctl->InterfaceAddress) {
         net_validate_interface_address(ctl->af, ctl->InterfaceAddress);          net_validate_interface_address(ctl->af, ctl->InterfaceAddress);
       } else if (ctl->InterfaceName) {
           net_find_interface_address_from_name(
               &sourcesockaddr_struct, ctl->af, ctl->InterfaceName);
           inet_ntop(sourcesockaddr->sa_family, sockaddr_addr_offset(sourcesockaddr), localaddr, sizeof(localaddr));
     } else {      } else {
         net_find_local_address();          net_find_local_address();
     }      }
Line 691  void net_reopen( Line 771  void net_reopen(
     }      }
   
     remotesockaddr->sa_family = addr->h_addrtype;      remotesockaddr->sa_family = addr->h_addrtype;
    addrcpy((void *) remoteaddress, addr->h_addr, addr->h_addrtype);    memcpy(remoteaddress, addr->h_addr, sockaddr_addr_size(remotesockaddr));
    memcpy(sockaddr_addr_offset(remotesockaddr), addr->h_addr, sockaddr_addr_size(remotesockaddr));
    switch (addr->h_addrtype) { 
    case AF_INET: 
        addrcpy((void *) &(rsa4->sin_addr), addr->h_addr, AF_INET); 
        break; 
#ifdef ENABLE_IPV6 
    case AF_INET6: 
        addrcpy((void *) &(rsa6->sin6_addr), addr->h_addr, AF_INET6); 
        break; 
#endif 
    default: 
        error(EXIT_FAILURE, 0, "net_reopen bad address type"); 
    } 
 
     net_reset(ctl);      net_reset(ctl);
     net_send_batch(ctl);      net_send_batch(ctl);
 }  }
Line 794  void net_save_return( Line 861  void net_save_return(
     host[at].saved[idx] = ms;      host[at].saved[idx] = ms;
 }  }
   
 /* Similar to inet_ntop but uses a sockaddr as it's argument. */  
 static void sockaddrtop(  
     struct sockaddr *saddr,  
     char *strptr,  
     size_t len)  
 {  
     struct sockaddr_in *sa4;  
 #ifdef ENABLE_IPV6  
     struct sockaddr_in6 *sa6;  
 #endif  
   
     switch (saddr->sa_family) {  
     case AF_INET:  
         sa4 = (struct sockaddr_in *) saddr;  
         xstrncpy(strptr, inet_ntoa(sa4->sin_addr), len - 1);  
         strptr[len - 1] = '\0';  
         return;  
 #ifdef ENABLE_IPV6  
     case AF_INET6:  
         sa6 = (struct sockaddr_in6 *) saddr;  
         inet_ntop(sa6->sin6_family, &(sa6->sin6_addr), strptr, len);  
         return;  
 #endif  
     default:  
         error(0, 0, "sockaddrtop unknown address type");  
         strptr[0] = '\0';  
         return;  
     }  
 }  
   
   
 /* Address comparison. */  /* Address comparison. */
 int addrcmp(  int addrcmp(
    char *a,    void *a,
    char *b,    void *b,
     int family)      int family)
 {  {
     int rc = -1;      int rc = -1;
Line 845  int addrcmp( Line 881  int addrcmp(
     }      }
   
     return rc;      return rc;
 }  
   
 /* Address copy. */  
 void addrcpy(  
     char *a,  
     char *b,  
     int family)  
 {  
   
     switch (family) {  
     case AF_INET:  
         memcpy(a, b, sizeof(struct in_addr));  
         break;  
 #ifdef ENABLE_IPV6  
     case AF_INET6:  
         memcpy(a, b, sizeof(struct in6_addr));  
         break;  
 #endif  
     }  
 }  }
   
 /* for GTK frontend */  /* for GTK frontend */

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


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