Diff for /embedaddon/mtr/packet/construct_unix.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 "construct_unix.h"  #include "construct_unix.h"
Line 25 Line 25
 #include <unistd.h>  #include <unistd.h>
   
 #include "protocols.h"  #include "protocols.h"
   #include "sockaddr.h"
   
   /* For Mac OS X and FreeBSD */
   #ifndef SOL_IP
   #define SOL_IP IPPROTO_IP
   #endif
   
 /*  A source of data for computing a checksum  */  /*  A source of data for computing a checksum  */
 struct checksum_source_t {  struct checksum_source_t {
     const void *data;      const void *data;
Line 85  void construct_addr_port( Line 91  void construct_addr_port(
     const struct sockaddr_storage *addr,      const struct sockaddr_storage *addr,
     int port)      int port)
 {  {
     struct sockaddr_in *addr4;  
     struct sockaddr_in6 *addr6;  
   
     memcpy(addr_with_port, addr, sizeof(struct sockaddr_storage));      memcpy(addr_with_port, addr, sizeof(struct sockaddr_storage));
    *sockaddr_port_offset(addr_with_port) = htons(port);
    if (addr->ss_family == AF_INET6) { 
        addr6 = (struct sockaddr_in6 *) addr_with_port; 
        addr6->sin6_port = htons(port); 
    } else { 
        addr4 = (struct sockaddr_in *) addr_with_port; 
        addr4->sin_port = htons(port); 
    } 
 }  }
   
 /*  Construct a header for IP version 4  */  /*  Construct a header for IP version 4  */
 static  static
 void construct_ip4_header(  void construct_ip4_header(
     const struct net_state_t *net_state,      const struct net_state_t *net_state,
       const struct probe_t *probe,
     char *packet_buffer,      char *packet_buffer,
     int packet_size,      int packet_size,
     const struct sockaddr_storage *srcaddr,  
     const struct sockaddr_storage *destaddr,  
     const struct probe_param_t *param)      const struct probe_param_t *param)
 {  {
     struct IPHeader *ip;      struct IPHeader *ip;
     struct sockaddr_in *srcaddr4 = (struct sockaddr_in *) srcaddr;  
     struct sockaddr_in *destaddr4 = (struct sockaddr_in *) destaddr;  
   
     ip = (struct IPHeader *) &packet_buffer[0];      ip = (struct IPHeader *) &packet_buffer[0];
   
Line 122  void construct_ip4_header( Line 115  void construct_ip4_header(
     ip->len = length_byte_swap(net_state, packet_size);      ip->len = length_byte_swap(net_state, packet_size);
     ip->ttl = param->ttl;      ip->ttl = param->ttl;
     ip->protocol = param->protocol;      ip->protocol = param->protocol;
    memcpy(&ip->saddr, &srcaddr4->sin_addr, sizeof(uint32_t));//    ip->id = htons(getpid());
    memcpy(&ip->daddr, &destaddr4->sin_addr, sizeof(uint32_t));    memcpy(&ip->saddr,
            sockaddr_addr_offset(&probe->local_addr),
            sockaddr_addr_size(&probe->local_addr));
     memcpy(&ip->daddr,
            sockaddr_addr_offset(&probe->remote_addr),
            sockaddr_addr_size(&probe->remote_addr));
 }  }
   
 /*  Construct an ICMP header for IPv4  */  /*  Construct an ICMP header for IPv4  */
 static  static
 void construct_icmp4_header(  void construct_icmp4_header(
     const struct net_state_t *net_state,      const struct net_state_t *net_state,
    int sequence,    struct probe_t *probe,
     char *packet_buffer,      char *packet_buffer,
     int packet_size,      int packet_size,
     const struct probe_param_t *param)      const struct probe_param_t *param)
Line 138  void construct_icmp4_header( Line 136  void construct_icmp4_header(
     struct ICMPHeader *icmp;      struct ICMPHeader *icmp;
     int icmp_size;      int icmp_size;
   
    icmp = (struct ICMPHeader *) &packet_buffer[sizeof(struct IPHeader)];    if (net_state->platform.ip4_socket_raw) {
    icmp_size = packet_size - sizeof(struct IPHeader);        icmp = (struct ICMPHeader *) &packet_buffer[sizeof(struct IPHeader)];
         icmp_size = packet_size - sizeof(struct IPHeader);
     } else {
         icmp = (struct ICMPHeader *) &packet_buffer[0];
         icmp_size = packet_size;
     }
   
     memset(icmp, 0, sizeof(struct ICMPHeader));      memset(icmp, 0, sizeof(struct ICMPHeader));
   
     icmp->type = ICMP_ECHO;      icmp->type = ICMP_ECHO;
     icmp->id = htons(getpid());      icmp->id = htons(getpid());
    icmp->sequence = htons(sequence);    icmp->sequence = htons(probe->sequence);
     icmp->checksum = htons(compute_checksum(icmp, icmp_size));      icmp->checksum = htons(compute_checksum(icmp, icmp_size));
 }  }
   
Line 153  void construct_icmp4_header( Line 156  void construct_icmp4_header(
 static  static
 int construct_icmp6_packet(  int construct_icmp6_packet(
     const struct net_state_t *net_state,      const struct net_state_t *net_state,
    int sequence,    struct probe_t *probe,
     char *packet_buffer,      char *packet_buffer,
     int packet_size,      int packet_size,
     const struct probe_param_t *param)      const struct probe_param_t *param)
Line 166  int construct_icmp6_packet( Line 169  int construct_icmp6_packet(
   
     icmp->type = ICMP6_ECHO;      icmp->type = ICMP6_ECHO;
     icmp->id = htons(getpid());      icmp->id = htons(getpid());
    icmp->sequence = htons(sequence);    icmp->sequence = htons(probe->sequence);
   
     return 0;      return 0;
 }  }
Line 183  int construct_icmp6_packet( Line 186  int construct_icmp6_packet(
 static  static
 void set_udp_ports(  void set_udp_ports(
     struct UDPHeader *udp,      struct UDPHeader *udp,
    int sequence,    struct probe_t *probe,
     const struct probe_param_t *param)      const struct probe_param_t *param)
 {  {
     if (param->dest_port) {      if (param->dest_port) {
Line 191  void set_udp_ports( Line 194  void set_udp_ports(
   
         if (param->local_port) {          if (param->local_port) {
             udp->srcport = htons(param->local_port);              udp->srcport = htons(param->local_port);
            udp->checksum = htons(sequence);            udp->checksum = htons(probe->sequence);
         } else {          } else {
            udp->srcport = htons(sequence);            udp->srcport = htons(probe->sequence);
             udp->checksum = 0;              udp->checksum = 0;
         }          }
     } else {      } else {
        udp->dstport = htons(sequence);        udp->dstport = htons(probe->sequence);
   
         if (param->local_port) {          if (param->local_port) {
             udp->srcport = htons(param->local_port);              udp->srcport = htons(param->local_port);
Line 207  void set_udp_ports( Line 210  void set_udp_ports(
   
         udp->checksum = 0;          udp->checksum = 0;
     }      }
       *sockaddr_port_offset(&probe->local_addr) = udp->srcport;
       *sockaddr_port_offset(&probe->remote_addr) = udp->dstport;
 }  }
   
   /* Prepend pseudoheader to the udp datagram and calculate checksum */
   static
   int udp4_checksum(void *pheader, void *udata, int psize, int dsize,
                     int alt_checksum)
   {
       unsigned int totalsize = psize + dsize;
       unsigned char csumpacket[totalsize];
   
       memcpy(csumpacket, pheader, psize); /* pseudo header */
       memcpy(csumpacket+psize, udata, dsize);   /* udp header & payload */
   
       if (alt_checksum && dsize >= sizeof(struct UDPHeader) + 2) {
           csumpacket[psize + sizeof(struct UDPHeader)] = 0;
           csumpacket[psize + sizeof(struct UDPHeader) + 1] = 0;
       }
   
       return compute_checksum(csumpacket, totalsize);
   }
   
 /*  /*
     Construct a header for UDP probes, using the port number associated      Construct a header for UDP probes, using the port number associated
     with the probe.      with the probe.
Line 216  void set_udp_ports( Line 240  void set_udp_ports(
 static  static
 void construct_udp4_header(  void construct_udp4_header(
     const struct net_state_t *net_state,      const struct net_state_t *net_state,
    int sequence,    struct probe_t *probe,
     char *packet_buffer,      char *packet_buffer,
     int packet_size,      int packet_size,
     const struct probe_param_t *param)      const struct probe_param_t *param)
Line 224  void construct_udp4_header( Line 248  void construct_udp4_header(
     struct UDPHeader *udp;      struct UDPHeader *udp;
     int udp_size;      int udp_size;
   
    udp = (struct UDPHeader *) &packet_buffer[sizeof(struct IPHeader)];    if (net_state->platform.ip4_socket_raw) {
    udp_size = packet_size - sizeof(struct IPHeader);        udp = (struct UDPHeader *) &packet_buffer[sizeof(struct IPHeader)];
         udp_size = packet_size - sizeof(struct IPHeader);
     } else {
         udp = (struct UDPHeader *) &packet_buffer[0];
         udp_size = packet_size;
     }
   
     memset(udp, 0, sizeof(struct UDPHeader));      memset(udp, 0, sizeof(struct UDPHeader));
   
    set_udp_ports(udp, sequence, param);    set_udp_ports(udp, probe, param);
     udp->length = htons(udp_size);      udp->length = htons(udp_size);
   
       /* calculate udp checksum */
       struct UDPPseudoHeader udph = {
           .saddr = *(uint32_t *)sockaddr_addr_offset(&probe->local_addr),
           .daddr = *(uint32_t *)sockaddr_addr_offset(&probe->remote_addr),
           .zero = 0,
           .protocol = 17,
           .len = udp->length
       };
   
       /* get position to write checksum */
       uint16_t *checksum_off = &udp->checksum;
   
       if (udp->checksum != 0)
       { /* checksum is sequence number - correct the payload to match the checksum
            checksum_off is udp payload */
           checksum_off = (uint16_t *)&packet_buffer[packet_size -
                                                     udp_size +
                                                     sizeof(struct UDPHeader)];
       }
       *checksum_off = htons(udp4_checksum(&udph, udp,
                                           sizeof(struct UDPPseudoHeader),
                                           udp_size, udp->checksum != 0));
 }  }
   
 /*  Construct a header for UDPv6 probes  */  /*  Construct a header for UDPv6 probes  */
 static  static
 int construct_udp6_packet(  int construct_udp6_packet(
     const struct net_state_t *net_state,      const struct net_state_t *net_state,
    int sequence,    struct probe_t *probe,
     char *packet_buffer,      char *packet_buffer,
     int packet_size,      int packet_size,
     const struct probe_param_t *param)      const struct probe_param_t *param)
Line 251  int construct_udp6_packet( Line 303  int construct_udp6_packet(
   
     memset(udp, 0, sizeof(struct UDPHeader));      memset(udp, 0, sizeof(struct UDPHeader));
   
    set_udp_ports(udp, sequence, param);    set_udp_ports(udp, probe, param);
     udp->length = htons(udp_size);      udp->length = htons(udp_size);
   
    /*    if (net_state->platform.ip6_socket_raw) {
       Instruct the kernel to put the pseudoheader checksum into the        /*
       UDP header.           Instruct the kernel to put the pseudoheader checksum into the
     */           UDP header, this is only needed when using RAW socket.
    int chksum_offset = (char *) &udp->checksum - (char *) udp;         */
    if (setsockopt(udp_socket, IPPROTO_IPV6,        int chksum_offset = (char *) &udp->checksum - (char *) udp;
                   IPV6_CHECKSUM, &chksum_offset, sizeof(int))) {        if (setsockopt(udp_socket, IPPROTO_IPV6,
        return -1;                       IPV6_CHECKSUM, &chksum_offset, sizeof(int))) {
             return -1;
         }
     }      }
   
     return 0;      return 0;
Line 425  int compute_packet_size( Line 479  int compute_packet_size(
     const struct net_state_t *net_state,      const struct net_state_t *net_state,
     const struct probe_param_t *param)      const struct probe_param_t *param)
 {  {
    int packet_size;    int packet_size = 0;
   
     if (param->protocol == IPPROTO_TCP) {      if (param->protocol == IPPROTO_TCP) {
         return 0;          return 0;
Line 438  int compute_packet_size( Line 492  int compute_packet_size(
   
     /*  Start by determining the full size, including omitted headers  */      /*  Start by determining the full size, including omitted headers  */
     if (param->ip_version == 6) {      if (param->ip_version == 6) {
        packet_size = sizeof(struct IP6Header);        if (net_state->platform.ip6_socket_raw) {
             packet_size += sizeof(struct IP6Header);
         }
     } else if (param->ip_version == 4) {      } else if (param->ip_version == 4) {
        packet_size = sizeof(struct IPHeader);        if (net_state->platform.ip4_socket_raw) {
             packet_size += sizeof(struct IPHeader);
         }
     } else {      } else {
         errno = EINVAL;          errno = EINVAL;
         return -1;          return -1;
Line 470  int compute_packet_size( Line 528  int compute_packet_size(
        Since we don't explicitly construct the IPv6 header, we         Since we don't explicitly construct the IPv6 header, we
        need to account for it in our transmitted size.         need to account for it in our transmitted size.
      */       */
    if (param->ip_version == 6) {    if (param->ip_version == 6 && net_state->platform.ip6_socket_raw) {
         packet_size -= sizeof(struct IP6Header);          packet_size -= sizeof(struct IP6Header);
     }      }
   
Line 482  static Line 540  static
 int construct_ip4_packet(  int construct_ip4_packet(
     const struct net_state_t *net_state,      const struct net_state_t *net_state,
     int *packet_socket,      int *packet_socket,
    int sequence,    struct probe_t *probe,
     char *packet_buffer,      char *packet_buffer,
     int packet_size,      int packet_size,
     const struct sockaddr_storage *src_sockaddr,  
     const struct sockaddr_storage *dest_sockaddr,  
     const struct probe_param_t *param)      const struct probe_param_t *param)
 {  {
     int send_socket = net_state->platform.ip4_send_socket;      int send_socket = net_state->platform.ip4_send_socket;
     bool is_stream_protocol = false;      bool is_stream_protocol = false;
       int tos, ttl, socket;
       bool bind_send_socket = false;
       struct sockaddr_storage current_sockaddr;
       int current_sockaddr_len;
   
     if (param->protocol == IPPROTO_TCP) {      if (param->protocol == IPPROTO_TCP) {
         is_stream_protocol = true;          is_stream_protocol = true;
Line 499  int construct_ip4_packet( Line 559  int construct_ip4_packet(
         is_stream_protocol = true;          is_stream_protocol = true;
 #endif  #endif
     } else {      } else {
        construct_ip4_header(net_state, packet_buffer, packet_size,        if (net_state->platform.ip4_socket_raw) {
                             src_sockaddr, dest_sockaddr, param);            construct_ip4_header(net_state, probe, packet_buffer, packet_size,
                                  param);
         }
         if (param->protocol == IPPROTO_ICMP) {          if (param->protocol == IPPROTO_ICMP) {
            construct_icmp4_header(net_state, sequence, packet_buffer,            construct_icmp4_header(net_state, probe, packet_buffer,
                                    packet_size, param);                                     packet_size, param);
         } else if (param->protocol == IPPROTO_UDP) {          } else if (param->protocol == IPPROTO_UDP) {
            construct_udp4_header(net_state, sequence, packet_buffer,            construct_udp4_header(net_state, probe, packet_buffer,
                                   packet_size, param);                                    packet_size, param);
         } else {          } else {
             errno = EINVAL;              errno = EINVAL;
Line 516  int construct_ip4_packet( Line 577  int construct_ip4_packet(
   
     if (is_stream_protocol) {      if (is_stream_protocol) {
         send_socket =          send_socket =
            open_stream_socket(net_state, param->protocol, sequence,            open_stream_socket(net_state, param->protocol, probe->sequence,
                               src_sockaddr, dest_sockaddr, param);                               &probe->local_addr, &probe->remote_addr, param);
   
         if (send_socket == -1) {          if (send_socket == -1) {
             return -1;              return -1;
Line 546  int construct_ip4_packet( Line 607  int construct_ip4_packet(
     }      }
 #endif  #endif
   
       /*
          Bind src port when not using raw socket to pass in ICMP id, kernel
          get ICMP id from src_port when using DGRAM socket.
        */
       if (!net_state->platform.ip4_socket_raw &&
               param->protocol == IPPROTO_ICMP &&
               !param->is_probing_byte_order) {
           current_sockaddr_len = sizeof(struct sockaddr_in);
           bind_send_socket = true;
           socket = net_state->platform.ip4_txrx_icmp_socket;
           if (getsockname(socket, (struct sockaddr *) &current_sockaddr,
                           &current_sockaddr_len)) {
               return -1;
           }
           struct sockaddr_in *sin_cur =
               (struct sockaddr_in *) &current_sockaddr;
   
           /* avoid double bind */
           if (sin_cur->sin_port) {
               bind_send_socket = false;
           }
       }
   
       /*  Bind to our local address  */
       if (bind_send_socket && bind(socket, (struct sockaddr *)&probe->local_addr,
                   sizeof(struct sockaddr_in))) {
           return -1;
       }
   
       /* set TOS and TTL for non-raw socket */
       if (!net_state->platform.ip4_socket_raw && !param->is_probing_byte_order) {
           if (param->protocol == IPPROTO_ICMP) {
               socket = net_state->platform.ip4_txrx_icmp_socket;
           } else if (param->protocol == IPPROTO_UDP) {
               socket = net_state->platform.ip4_txrx_udp_socket;
           } else {
               return 0;
           }
           tos = param->type_of_service;
           if (setsockopt(socket, SOL_IP, IP_TOS, &tos, sizeof(int))) {
               return -1;
           }
           ttl = param->ttl;
           if (setsockopt(socket, SOL_IP, IP_TTL,
                          &ttl, sizeof(int)) == -1) {
               return -1;
           }
       }
   
     return 0;      return 0;
 }  }
   
Line 554  static Line 664  static
 int construct_ip6_packet(  int construct_ip6_packet(
     const struct net_state_t *net_state,      const struct net_state_t *net_state,
     int *packet_socket,      int *packet_socket,
    int sequence,    struct probe_t *probe,
     char *packet_buffer,      char *packet_buffer,
     int packet_size,      int packet_size,
     const struct sockaddr_storage *src_sockaddr,  
     const struct sockaddr_storage *dest_sockaddr,  
     const struct probe_param_t *param)      const struct probe_param_t *param)
 {  {
     int send_socket;      int send_socket;
Line 574  int construct_ip6_packet( Line 682  int construct_ip6_packet(
         is_stream_protocol = true;          is_stream_protocol = true;
 #endif  #endif
     } else if (param->protocol == IPPROTO_ICMP) {      } else if (param->protocol == IPPROTO_ICMP) {
        send_socket = net_state->platform.icmp6_send_socket;        if (net_state->platform.ip6_socket_raw) {
             send_socket = net_state->platform.icmp6_send_socket;
         } else {
             send_socket = net_state->platform.ip6_txrx_icmp_socket;
         }
   
         if (construct_icmp6_packet          if (construct_icmp6_packet
            (net_state, sequence, packet_buffer, packet_size, param)) {            (net_state, probe, packet_buffer, packet_size, param)) {
             return -1;              return -1;
         }          }
     } else if (param->protocol == IPPROTO_UDP) {      } else if (param->protocol == IPPROTO_UDP) {
        send_socket = net_state->platform.udp6_send_socket;        if (net_state->platform.ip6_socket_raw) {
             send_socket = net_state->platform.udp6_send_socket;
         } else {
             send_socket = net_state->platform.ip6_txrx_udp_socket;
         }
   
         if (construct_udp6_packet          if (construct_udp6_packet
            (net_state, sequence, packet_buffer, packet_size, param)) {            (net_state, probe, packet_buffer, packet_size, param)) {
             return -1;              return -1;
         }          }
     } else {      } else {
Line 594  int construct_ip6_packet( Line 710  int construct_ip6_packet(
   
     if (is_stream_protocol) {      if (is_stream_protocol) {
         send_socket =          send_socket =
            open_stream_socket(net_state, param->protocol, sequence,            open_stream_socket(net_state, param->protocol, probe->sequence,
                               src_sockaddr, dest_sockaddr, param);                               &probe->local_addr, &probe->remote_addr, param);
   
         if (send_socket == -1) {          if (send_socket == -1) {
             return -1;              return -1;
Line 608  int construct_ip6_packet( Line 724  int construct_ip6_packet(
     /*      /*
        Check the current socket address, and if it is the same         Check the current socket address, and if it is the same
        as the source address we intend, we will skip the bind.         as the source address we intend, we will skip the bind.
       This is to accomodate Solaris, which, as of Solaris 11.3,       This is to accommodate Solaris, which, as of Solaris 11.3,
        will return an EINVAL error on bind if the socket is already         will return an EINVAL error on bind if the socket is already
        bound, even if the same address is used.         bound, even if the same address is used.
      */       */
     current_sockaddr_len = sizeof(struct sockaddr_in6);      current_sockaddr_len = sizeof(struct sockaddr_in6);
     if (getsockname(send_socket, (struct sockaddr *) &current_sockaddr,      if (getsockname(send_socket, (struct sockaddr *) &current_sockaddr,
                     &current_sockaddr_len) == 0) {                      &current_sockaddr_len) == 0) {
           struct sockaddr_in6 *sin6_cur = (struct sockaddr_in6 *) &current_sockaddr;
   
        if (memcmp(&current_sockaddr,        if (net_state->platform.ip6_socket_raw) {
                   src_sockaddr, sizeof(struct sockaddr_in6)) == 0) {            if (memcmp(&current_sockaddr,
            bind_send_socket = false;                       &probe->local_addr, sizeof(struct sockaddr_in6)) == 0) {
                 bind_send_socket = false;
             }
         } else {
             /* avoid double bind for DGRAM socket */
             if (sin6_cur->sin6_port) {
                 bind_send_socket = false;
             }
         }          }
     }      }
   
     /*  Bind to our local address  */      /*  Bind to our local address  */
     if (bind_send_socket) {      if (bind_send_socket) {
        if (bind(send_socket, (struct sockaddr *) src_sockaddr,        if (bind(send_socket, (struct sockaddr *) &probe->local_addr,
                  sizeof(struct sockaddr_in6))) {                   sizeof(struct sockaddr_in6))) {
             return -1;              return -1;
         }          }
     }      }
   
    /*  The traffic class in IPv6 is analagous to ToS in IPv4  */    /*  The traffic class in IPv6 is analogous to ToS in IPv4  */
     if (setsockopt(send_socket, IPPROTO_IPV6,      if (setsockopt(send_socket, IPPROTO_IPV6,
                    IPV6_TCLASS, &param->type_of_service, sizeof(int))) {                     IPV6_TCLASS, &param->type_of_service, sizeof(int))) {
         return -1;          return -1;
Line 658  int construct_ip6_packet( Line 782  int construct_ip6_packet(
 int construct_packet(  int construct_packet(
     const struct net_state_t *net_state,      const struct net_state_t *net_state,
     int *packet_socket,      int *packet_socket,
    int sequence,    struct probe_t *probe,
     char *packet_buffer,      char *packet_buffer,
     int packet_buffer_size,      int packet_buffer_size,
     const struct sockaddr_storage *dest_sockaddr,  
     const struct sockaddr_storage *src_sockaddr,  
     const struct probe_param_t *param)      const struct probe_param_t *param)
 {  {
     int packet_size;      int packet_size;
Line 680  int construct_packet( Line 802  int construct_packet(
     memset(packet_buffer, param->bit_pattern, packet_size);      memset(packet_buffer, param->bit_pattern, packet_size);
   
     if (param->ip_version == 6) {      if (param->ip_version == 6) {
        if (construct_ip6_packet(net_state, packet_socket, sequence,        if (construct_ip6_packet(net_state, packet_socket, probe,
                                  packet_buffer, packet_size,                                   packet_buffer, packet_size,
                                 src_sockaddr, dest_sockaddr, param)) {                                 param)) {
             return -1;              return -1;
         }          }
     } else if (param->ip_version == 4) {      } else if (param->ip_version == 4) {
        if (construct_ip4_packet(net_state, packet_socket, sequence,        if (construct_ip4_packet(net_state, packet_socket, probe,
                                  packet_buffer, packet_size,                                   packet_buffer, packet_size,
                                 src_sockaddr, dest_sockaddr, param)) {                                 param)) {
             return -1;              return -1;
         }          }
     } else {      } else {

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


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