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 *) ¤t_sockaddr, |
|
¤t_sockaddr_len)) { |
|
return -1; |
|
} |
|
struct sockaddr_in *sin_cur = |
|
(struct sockaddr_in *) ¤t_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 *) ¤t_sockaddr, |
if (getsockname(send_socket, (struct sockaddr *) ¤t_sockaddr, |
¤t_sockaddr_len) == 0) { |
¤t_sockaddr_len) == 0) { |
|
struct sockaddr_in6 *sin6_cur = (struct sockaddr_in6 *) ¤t_sockaddr; |
|
|
if (memcmp(¤t_sockaddr, | if (net_state->platform.ip6_socket_raw) { |
src_sockaddr, sizeof(struct sockaddr_in6)) == 0) { | if (memcmp(¤t_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, ¶m->type_of_service, sizeof(int))) { |
IPV6_TCLASS, ¶m->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 { |