2 mtr -- a network diagnostic tool
3 Copyright (C) 2016 Matt Kimball
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License version 2 as
7 published by the Free Software Foundation.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 #include "construct_unix.h"
24 #include <sys/socket.h>
27 #include "protocols.h"
30 /* For Mac OS X and FreeBSD */
32 #define SOL_IP IPPROTO_IP
35 /* A source of data for computing a checksum */
36 struct checksum_source_t
{
41 /* Compute the IP checksum (or ICMP checksum) of a packet. */
43 uint16_t compute_checksum(
47 const uint8_t *packet_bytes
= (uint8_t *) packet
;
51 for (i
= 0; i
< size
; i
++) {
53 sum
+= packet_bytes
[i
] << 8;
55 sum
+= packet_bytes
[i
];
60 Sums which overflow a 16-bit value have the high bits
61 added back into the low 16 bits.
64 sum
= (sum
>> 16) + (sum
& 0xffff);
68 The value stored is the one's complement of the
71 return (~sum
& 0xffff);
74 /* Encode the IP header length field in the order required by the OS. */
76 uint16_t length_byte_swap(
77 const struct net_state_t
*net_state
,
80 if (net_state
->platform
.ip_length_host_order
) {
87 /* Construct a combined sockaddr from a source address and source port */
89 void construct_addr_port(
90 struct sockaddr_storage
*addr_with_port
,
91 const struct sockaddr_storage
*addr
,
94 memcpy(addr_with_port
, addr
, sizeof(struct sockaddr_storage
));
95 *sockaddr_port_offset(addr_with_port
) = htons(port
);
98 /* Construct a header for IP version 4 */
100 void construct_ip4_header(
101 const struct net_state_t
*net_state
,
102 const struct probe_t
*probe
,
105 const struct probe_param_t
*param
)
109 ip
= (struct IPHeader
*) &packet_buffer
[0];
111 memset(ip
, 0, sizeof(struct IPHeader
));
114 ip
->tos
= param
->type_of_service
;
115 ip
->len
= length_byte_swap(net_state
, packet_size
);
116 ip
->ttl
= param
->ttl
;
117 ip
->protocol
= param
->protocol
;
118 // ip->id = htons(getpid());
120 sockaddr_addr_offset(&probe
->local_addr
),
121 sockaddr_addr_size(&probe
->local_addr
));
123 sockaddr_addr_offset(&probe
->remote_addr
),
124 sockaddr_addr_size(&probe
->remote_addr
));
127 /* Construct an ICMP header for IPv4 */
129 void construct_icmp4_header(
130 const struct net_state_t
*net_state
,
131 struct probe_t
*probe
,
134 const struct probe_param_t
*param
)
136 struct ICMPHeader
*icmp
;
139 if (net_state
->platform
.ip4_socket_raw
) {
140 icmp
= (struct ICMPHeader
*) &packet_buffer
[sizeof(struct IPHeader
)];
141 icmp_size
= packet_size
- sizeof(struct IPHeader
);
143 icmp
= (struct ICMPHeader
*) &packet_buffer
[0];
144 icmp_size
= packet_size
;
147 memset(icmp
, 0, sizeof(struct ICMPHeader
));
149 icmp
->type
= ICMP_ECHO
;
150 icmp
->id
= htons(getpid());
151 icmp
->sequence
= htons(probe
->sequence
);
152 icmp
->checksum
= htons(compute_checksum(icmp
, icmp_size
));
155 /* Construct an ICMP header for IPv6 */
157 int construct_icmp6_packet(
158 const struct net_state_t
*net_state
,
159 struct probe_t
*probe
,
162 const struct probe_param_t
*param
)
164 struct ICMPHeader
*icmp
;
166 icmp
= (struct ICMPHeader
*) packet_buffer
;
168 memset(icmp
, 0, sizeof(struct ICMPHeader
));
170 icmp
->type
= ICMP6_ECHO
;
171 icmp
->id
= htons(getpid());
172 icmp
->sequence
= htons(probe
->sequence
);
178 Set the port numbers for an outgoing UDP probe.
179 There is limited space in the header for a sequence number
180 to identify the probe upon return.
182 We store the sequence number in the destination port, the local
183 port, or the checksum. The location chosen depends upon which
184 probe parameters have been requested.
188 struct UDPHeader
*udp
,
189 struct probe_t
*probe
,
190 const struct probe_param_t
*param
)
192 if (param
->dest_port
) {
193 udp
->dstport
= htons(param
->dest_port
);
195 if (param
->local_port
) {
196 udp
->srcport
= htons(param
->local_port
);
197 udp
->checksum
= htons(probe
->sequence
);
199 udp
->srcport
= htons(probe
->sequence
);
203 udp
->dstport
= htons(probe
->sequence
);
205 if (param
->local_port
) {
206 udp
->srcport
= htons(param
->local_port
);
208 udp
->srcport
= htons(getpid());
213 *sockaddr_port_offset(&probe
->local_addr
) = udp
->srcport
;
214 *sockaddr_port_offset(&probe
->remote_addr
) = udp
->dstport
;
217 /* Prepend pseudoheader to the udp datagram and calculate checksum */
219 int udp4_checksum(void *pheader
, void *udata
, int psize
, int dsize
,
222 unsigned int totalsize
= psize
+ dsize
;
223 unsigned char csumpacket
[totalsize
];
225 memcpy(csumpacket
, pheader
, psize
); /* pseudo header */
226 memcpy(csumpacket
+psize
, udata
, dsize
); /* udp header & payload */
228 if (alt_checksum
&& dsize
>= sizeof(struct UDPHeader
) + 2) {
229 csumpacket
[psize
+ sizeof(struct UDPHeader
)] = 0;
230 csumpacket
[psize
+ sizeof(struct UDPHeader
) + 1] = 0;
233 return compute_checksum(csumpacket
, totalsize
);
237 Construct a header for UDP probes, using the port number associated
241 void construct_udp4_header(
242 const struct net_state_t
*net_state
,
243 struct probe_t
*probe
,
246 const struct probe_param_t
*param
)
248 struct UDPHeader
*udp
;
251 if (net_state
->platform
.ip4_socket_raw
) {
252 udp
= (struct UDPHeader
*) &packet_buffer
[sizeof(struct IPHeader
)];
253 udp_size
= packet_size
- sizeof(struct IPHeader
);
255 udp
= (struct UDPHeader
*) &packet_buffer
[0];
256 udp_size
= packet_size
;
259 memset(udp
, 0, sizeof(struct UDPHeader
));
261 set_udp_ports(udp
, probe
, param
);
262 udp
->length
= htons(udp_size
);
264 /* calculate udp checksum */
265 struct UDPPseudoHeader udph
= {
266 .saddr
= *(uint32_t *)sockaddr_addr_offset(&probe
->local_addr
),
267 .daddr
= *(uint32_t *)sockaddr_addr_offset(&probe
->remote_addr
),
273 /* get position to write checksum */
274 uint16_t *checksum_off
= &udp
->checksum
;
276 if (udp
->checksum
!= 0)
277 { /* checksum is sequence number - correct the payload to match the checksum
278 checksum_off is udp payload */
279 checksum_off
= (uint16_t *)&packet_buffer
[packet_size
-
281 sizeof(struct UDPHeader
)];
283 *checksum_off
= htons(udp4_checksum(&udph
, udp
,
284 sizeof(struct UDPPseudoHeader
),
285 udp_size
, udp
->checksum
!= 0));
288 /* Construct a header for UDPv6 probes */
290 int construct_udp6_packet(
291 const struct net_state_t
*net_state
,
292 struct probe_t
*probe
,
295 const struct probe_param_t
*param
)
297 int udp_socket
= net_state
->platform
.udp6_send_socket
;
298 struct UDPHeader
*udp
;
301 udp
= (struct UDPHeader
*) packet_buffer
;
302 udp_size
= packet_size
;
304 memset(udp
, 0, sizeof(struct UDPHeader
));
306 set_udp_ports(udp
, probe
, param
);
307 udp
->length
= htons(udp_size
);
309 struct IP6PseudoHeader udph
= {
314 memcpy(udph
.saddr
, sockaddr_addr_offset(&probe
->local_addr
), 16);
315 memcpy(udph
.daddr
, sockaddr_addr_offset(&probe
->remote_addr
), 16);
317 /* get position to write checksum */
318 uint16_t *checksum_off
= &udp
->checksum
;
320 if (udp
->checksum
!= 0)
321 { /* checksum is sequence number - correct the payload to match the checksum
322 checksum_off is udp payload */
323 checksum_off
= (uint16_t *)&packet_buffer
[sizeof(struct UDPHeader
)];
325 *checksum_off
= htons(udp4_checksum(&udph
, udp
,
326 sizeof(struct IP6PseudoHeader
),
327 udp_size
, udp
->checksum
!= 0));
332 Set the socket options for an outgoing stream protocol socket based on
333 the packet parameters.
336 int set_stream_socket_options(
338 const struct probe_param_t
*param
)
344 /* Allow binding to a local port previously in use */
347 FreeBSD wants SO_REUSEPORT in addition to SO_REUSEADDR to
348 bind to the same port
350 if (setsockopt(stream_socket
, SOL_SOCKET
, SO_REUSEPORT
,
351 &reuse
, sizeof(int)) == -1) {
357 if (setsockopt(stream_socket
, SOL_SOCKET
, SO_REUSEADDR
,
358 &reuse
, sizeof(int)) == -1) {
363 /* Set the number of hops the probe will transit across */
364 if (param
->ip_version
== 6) {
365 level
= IPPROTO_IPV6
;
366 opt
= IPV6_UNICAST_HOPS
;
372 if (setsockopt(stream_socket
, level
, opt
, ¶m
->ttl
, sizeof(int)) ==
378 /* Set the "type of service" field of the IP header */
379 if (param
->ip_version
== 6) {
380 level
= IPPROTO_IPV6
;
387 if (setsockopt(stream_socket
, level
, opt
,
388 ¶m
->type_of_service
, sizeof(int)) == -1) {
393 if (param
->routing_mark
) {
394 if (setsockopt(stream_socket
, SOL_SOCKET
,
395 SO_MARK
, ¶m
->routing_mark
, sizeof(int))) {
401 if (param
->local_device
) {
402 if (setsockopt(stream_socket
, SOL_SOCKET
,
403 SO_BINDTODEVICE
, param
->local_device
, strlen(param
->local_device
))) {
412 Open a TCP or SCTP socket, respecting the probe paramters as much as
413 we can, and use it as an outgoing probe.
416 int open_stream_socket(
417 const struct net_state_t
*net_state
,
420 const struct sockaddr_storage
*src_sockaddr
,
421 const struct sockaddr_storage
*dest_sockaddr
,
422 const struct probe_param_t
*param
)
427 struct sockaddr_storage dest_port_addr
;
428 struct sockaddr_storage src_port_addr
;
430 if (param
->ip_version
== 6) {
431 stream_socket
= socket(AF_INET6
, SOCK_STREAM
, protocol
);
432 addr_len
= sizeof(struct sockaddr_in6
);
433 } else if (param
->ip_version
== 4) {
434 stream_socket
= socket(AF_INET
, SOCK_STREAM
, protocol
);
435 addr_len
= sizeof(struct sockaddr_in
);
441 if (stream_socket
== -1) {
445 set_socket_nonblocking(stream_socket
);
447 if (set_stream_socket_options(stream_socket
, param
)) {
448 close(stream_socket
);
453 Bind to a known local port so we can identify which probe
454 causes a TTL expiration.
456 construct_addr_port(&src_port_addr
, src_sockaddr
, port
);
457 if (bind(stream_socket
, (struct sockaddr
*) &src_port_addr
, addr_len
)) {
458 close(stream_socket
);
462 if (param
->dest_port
) {
463 dest_port
= param
->dest_port
;
465 /* Use http if no port is specified */
466 dest_port
= HTTP_PORT
;
469 /* Attempt a connection */
470 construct_addr_port(&dest_port_addr
, dest_sockaddr
, dest_port
);
472 (stream_socket
, (struct sockaddr
*) &dest_port_addr
, addr_len
)) {
474 /* EINPROGRESS simply means the connection is in progress */
475 if (errno
!= EINPROGRESS
) {
476 close(stream_socket
);
481 return stream_socket
;
485 Determine the size of the constructed packet based on the packet
486 parameters. This is the amount of space the packet *we* construct
487 uses, and doesn't include any headers the operating system tacks
488 onto the packet. (Such as the IPv6 header on non-Linux operating
492 int compute_packet_size(
493 const struct net_state_t
*net_state
,
494 const struct probe_param_t
*param
)
498 if (param
->protocol
== IPPROTO_TCP
) {
502 if (param
->protocol
== IPPROTO_SCTP
) {
507 /* Start by determining the full size, including omitted headers */
508 if (param
->ip_version
== 6) {
509 if (net_state
->platform
.ip6_socket_raw
) {
510 packet_size
+= sizeof(struct IP6Header
);
512 } else if (param
->ip_version
== 4) {
513 if (net_state
->platform
.ip4_socket_raw
) {
514 packet_size
+= sizeof(struct IPHeader
);
521 if (param
->protocol
== IPPROTO_ICMP
) {
522 packet_size
+= sizeof(struct ICMPHeader
);
523 } else if (param
->protocol
== IPPROTO_UDP
) {
524 packet_size
+= sizeof(struct UDPHeader
);
526 /* We may need to put the sequence number in the payload */
527 packet_size
+= sizeof(int);
534 If the requested size from send-probe is greater, extend the
537 if (param
->packet_size
> packet_size
) {
538 packet_size
= param
->packet_size
;
542 Since we don't explicitly construct the IPv6 header, we
543 need to account for it in our transmitted size.
545 if (param
->ip_version
== 6 && net_state
->platform
.ip6_socket_raw
) {
546 packet_size
-= sizeof(struct IP6Header
);
552 /* Construct a packet for an IPv4 probe */
554 int construct_ip4_packet(
555 const struct net_state_t
*net_state
,
557 struct probe_t
*probe
,
560 const struct probe_param_t
*param
)
562 int send_socket
= net_state
->platform
.ip4_send_socket
;
563 bool is_stream_protocol
= false;
564 int tos
, ttl
, socket
;
565 bool bind_send_socket
= false;
566 struct sockaddr_storage current_sockaddr
;
567 int current_sockaddr_len
;
569 if (param
->protocol
== IPPROTO_TCP
) {
570 is_stream_protocol
= true;
572 } else if (param
->protocol
== IPPROTO_SCTP
) {
573 is_stream_protocol
= true;
576 if (net_state
->platform
.ip4_socket_raw
) {
577 construct_ip4_header(net_state
, probe
, packet_buffer
, packet_size
,
580 if (param
->protocol
== IPPROTO_ICMP
) {
581 construct_icmp4_header(net_state
, probe
, packet_buffer
,
583 } else if (param
->protocol
== IPPROTO_UDP
) {
584 construct_udp4_header(net_state
, probe
, packet_buffer
,
592 if (is_stream_protocol
) {
594 open_stream_socket(net_state
, param
->protocol
, probe
->sequence
,
595 &probe
->local_addr
, &probe
->remote_addr
, param
);
597 if (send_socket
== -1) {
601 *packet_socket
= send_socket
;
606 The routing mark requires CAP_NET_ADMIN, as opposed to the
607 CAP_NET_RAW which we are sometimes explicitly given.
608 If we don't have CAP_NET_ADMIN, this will fail, so we'll
609 only set the mark if the user has explicitly requested it.
611 Unfortunately, this means that once the mark is set, it won't
612 be set on the socket again until a new mark is explicitly
616 if (param
->routing_mark
) {
617 if (setsockopt(send_socket
, SOL_SOCKET
,
618 SO_MARK
, ¶m
->routing_mark
, sizeof(int))) {
624 if (param
->local_device
) {
625 if (setsockopt(send_socket
, SOL_SOCKET
,
626 SO_BINDTODEVICE
, param
->local_device
, strlen(param
->local_device
))) {
632 Bind src port when not using raw socket to pass in ICMP id, kernel
633 get ICMP id from src_port when using DGRAM socket.
635 if (!net_state
->platform
.ip4_socket_raw
&&
636 param
->protocol
== IPPROTO_ICMP
&&
637 !param
->is_probing_byte_order
) {
638 current_sockaddr_len
= sizeof(struct sockaddr_in
);
639 bind_send_socket
= true;
640 socket
= net_state
->platform
.ip4_txrx_icmp_socket
;
641 if (getsockname(socket
, (struct sockaddr
*) ¤t_sockaddr
,
642 ¤t_sockaddr_len
)) {
645 struct sockaddr_in
*sin_cur
=
646 (struct sockaddr_in
*) ¤t_sockaddr
;
648 /* avoid double bind */
649 if (sin_cur
->sin_port
) {
650 bind_send_socket
= false;
654 /* Bind to our local address */
655 if (bind_send_socket
&& bind(socket
, (struct sockaddr
*)&probe
->local_addr
,
656 sizeof(struct sockaddr_in
))) {
660 /* set TOS and TTL for non-raw socket */
661 if (!net_state
->platform
.ip4_socket_raw
&& !param
->is_probing_byte_order
) {
662 if (param
->protocol
== IPPROTO_ICMP
) {
663 socket
= net_state
->platform
.ip4_txrx_icmp_socket
;
664 } else if (param
->protocol
== IPPROTO_UDP
) {
665 socket
= net_state
->platform
.ip4_txrx_udp_socket
;
669 tos
= param
->type_of_service
;
670 if (setsockopt(socket
, SOL_IP
, IP_TOS
, &tos
, sizeof(int))) {
674 if (setsockopt(socket
, SOL_IP
, IP_TTL
,
675 &ttl
, sizeof(int)) == -1) {
683 /* Construct a packet for an IPv6 probe */
685 int construct_ip6_packet(
686 const struct net_state_t
*net_state
,
688 struct probe_t
*probe
,
691 const struct probe_param_t
*param
)
694 bool is_stream_protocol
= false;
695 bool bind_send_socket
= true;
696 struct sockaddr_storage current_sockaddr
;
697 int current_sockaddr_len
;
699 if (param
->protocol
== IPPROTO_TCP
) {
700 is_stream_protocol
= true;
702 } else if (param
->protocol
== IPPROTO_SCTP
) {
703 is_stream_protocol
= true;
705 } else if (param
->protocol
== IPPROTO_ICMP
) {
706 if (net_state
->platform
.ip6_socket_raw
) {
707 send_socket
= net_state
->platform
.icmp6_send_socket
;
709 send_socket
= net_state
->platform
.ip6_txrx_icmp_socket
;
712 if (construct_icmp6_packet
713 (net_state
, probe
, packet_buffer
, packet_size
, param
)) {
716 } else if (param
->protocol
== IPPROTO_UDP
) {
717 if (net_state
->platform
.ip6_socket_raw
) {
718 send_socket
= net_state
->platform
.udp6_send_socket
;
720 send_socket
= net_state
->platform
.ip6_txrx_udp_socket
;
723 if (construct_udp6_packet
724 (net_state
, probe
, packet_buffer
, packet_size
, param
)) {
732 if (is_stream_protocol
) {
734 open_stream_socket(net_state
, param
->protocol
, probe
->sequence
,
735 &probe
->local_addr
, &probe
->remote_addr
, param
);
737 if (send_socket
== -1) {
741 *packet_socket
= send_socket
;
746 Check the current socket address, and if it is the same
747 as the source address we intend, we will skip the bind.
748 This is to accommodate Solaris, which, as of Solaris 11.3,
749 will return an EINVAL error on bind if the socket is already
750 bound, even if the same address is used.
752 current_sockaddr_len
= sizeof(struct sockaddr_in6
);
753 if (getsockname(send_socket
, (struct sockaddr
*) ¤t_sockaddr
,
754 ¤t_sockaddr_len
) == 0) {
755 struct sockaddr_in6
*sin6_cur
= (struct sockaddr_in6
*) ¤t_sockaddr
;
757 if (net_state
->platform
.ip6_socket_raw
) {
758 if (memcmp(¤t_sockaddr
,
759 &probe
->local_addr
, sizeof(struct sockaddr_in6
)) == 0) {
760 bind_send_socket
= false;
763 /* avoid double bind for DGRAM socket */
764 if (sin6_cur
->sin6_port
) {
765 bind_send_socket
= false;
770 /* Bind to our local address */
771 if (bind_send_socket
) {
772 if (bind(send_socket
, (struct sockaddr
*) &probe
->local_addr
,
773 sizeof(struct sockaddr_in6
))) {
778 /* The traffic class in IPv6 is analogous to ToS in IPv4 */
779 if (setsockopt(send_socket
, IPPROTO_IPV6
,
780 IPV6_TCLASS
, ¶m
->type_of_service
, sizeof(int))) {
784 /* Set the time-to-live */
785 if (setsockopt(send_socket
, IPPROTO_IPV6
,
786 IPV6_UNICAST_HOPS
, ¶m
->ttl
, sizeof(int))) {
790 if (param
->routing_mark
) {
791 if (setsockopt(send_socket
,
792 SOL_SOCKET
, SO_MARK
, ¶m
->routing_mark
,
799 if (param
->local_device
) {
800 if (setsockopt(send_socket
,
801 SOL_SOCKET
, SO_BINDTODEVICE
, param
->local_device
,
802 strlen(param
->local_device
))) {
810 /* Construct a probe packet based on the probe parameters */
811 int construct_packet(
812 const struct net_state_t
*net_state
,
814 struct probe_t
*probe
,
816 int packet_buffer_size
,
817 const struct probe_param_t
*param
)
821 packet_size
= compute_packet_size(net_state
, param
);
822 if (packet_size
< 0) {
826 if (packet_buffer_size
< packet_size
) {
831 memset(packet_buffer
, param
->bit_pattern
, packet_size
);
833 if (param
->ip_version
== 6) {
834 if (construct_ip6_packet(net_state
, packet_socket
, probe
,
835 packet_buffer
, packet_size
,
839 } else if (param
->ip_version
== 4) {
840 if (construct_ip4_packet(net_state
, packet_socket
, probe
,
841 packet_buffer
, packet_size
,