/*
mtr -- a network diagnostic tool
Copyright (C) 2016 Matt Kimball
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef PROBE_H
#define PROBE_H
#include "platform.h"
#include <netinet/in.h>
#include <stdbool.h>
#include <sys/socket.h>
#include <sys/time.h>
#include "portability/queue.h"
#ifdef PLATFORM_CYGWIN
#include "probe_cygwin.h"
#else
#include "probe_unix.h"
#endif
#define MAX_PROBES 1024
/* Use the "jumbo" frame size as the max packet size */
#define PACKET_BUFFER_SIZE 9000
/* Parameters for sending a new probe */
struct probe_param_t {
/* The version of the Internet Protocol to use. (4 or 6) */
int ip_version;
/* The command token used to identify a probe when it is completed */
int command_token;
/* The IP address to probe */
const char *remote_address;
/* The local address from which to send probes */
const char *local_address;
/* Protocol for the probe, using the IPPROTO_* defines */
int protocol;
/* The destination port for non-ICMP probes */
int dest_port;
/* The local port number to use when sending probes */
int local_port;
/* The "type of service" field in the IP header */
int type_of_service;
/* The packet "mark" used for mark-based routing on Linux */
int routing_mark;
/* Time to live for the transmitted probe */
int ttl;
/* The packet size (in bytes) including protocol headers */
int packet_size;
/* The value with which to fill the bytes of the packet. */
int bit_pattern;
/* The number of seconds to wait before assuming the probe was lost */
int timeout;
/* true is the probe is to test byte order */
bool is_probing_byte_order;
};
/* Tracking information for an outstanding probe */
struct probe_t {
/* Our entry in the probe list */
LIST_ENTRY(
probe_t) probe_list_entry;
/*
Also the ICMP sequence ID used to identify the probe.
Also used as the port number to use when binding stream protocol
sockets for this probe. (i.e. TCP or SCTP)
*/
int sequence;
/* Command token of the probe request */
int token;
/* The address being probed */
struct sockaddr_storage remote_addr;
/* The local address which was used */
struct sockaddr_storage local_addr;
/* Platform specific probe tracking */
struct probe_platform_t platform;
};
/* Global state for interacting with the network */
struct net_state_t {
/* The number of entries in the outstanding_probes list */
int outstanding_probe_count;
/* Tracking information for in-flight probes */
LIST_HEAD(
probe_list_head_t,
probe_t) outstanding_probes;
/* Platform specific tracking information */
struct net_state_platform_t platform;
};
/* Multiprotocol Label Switching information */
struct mpls_label_t {
uint32_t label;
uint8_t traffic_class;
uint8_t bottom_of_stack;
uint8_t ttl;
};
void init_net_state_privileged(
struct net_state_t *net_state);
void init_net_state(
struct net_state_t *net_state);
bool is_ip_version_supported(
struct net_state_t *net_state,
int ip_version);
bool is_protocol_supported(
struct net_state_t *net_state,
int protocol);
bool get_next_probe_timeout(
const struct net_state_t *net_state,
struct timeval *timeout);
void send_probe(
struct net_state_t *net_state,
const struct probe_param_t *param);
void receive_replies(
struct net_state_t *net_state);
void check_probe_timeouts(
struct net_state_t *net_state);
void respond_to_probe(
struct net_state_t *net_state,
struct probe_t *probe,
int icmp_type,
const struct sockaddr_storage *remote_addr,
unsigned int round_trip_us,
int mpls_count,
const struct mpls_label_t *mpls);
int decode_address_string(
int ip_version,
const char *address_string,
struct sockaddr_storage *address);
int resolve_probe_addresses(
struct net_state_t *net_state,
const struct probe_param_t *param,
struct sockaddr_storage *dest_sockaddr,
struct sockaddr_storage *src_sockaddr);
struct probe_t *alloc_probe(
struct net_state_t *net_state,
int token);
void free_probe(
struct net_state_t *net_state,
struct probe_t *probe);
void platform_alloc_probe(
struct net_state_t *net_state,
struct probe_t *probe);
void platform_free_probe(
struct probe_t *probe);
struct probe_t *find_probe(
struct net_state_t *net_state,
int protocol,
int icmp_id,
int icmp_sequence);
int find_source_addr(
struct sockaddr_storage *srcaddr,
const struct sockaddr_storage *destaddr);
extern char *probe_err;
#endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>