double latency;
uint32_t dropped;
int recv_ttl;
+ unsigned recv_tos;
char *data;
void *context;
double timeout;
int ttl;
int addrfamily;
+ unsigned tos;
char *data;
struct sockaddr *srcaddr;
ident, seq);
}
- if (ptr != NULL)
+ if (ptr != NULL){
ptr->recv_ttl = ip_hdr->ip_ttl;
-
+ ptr->recv_tos = ip_hdr->ip_tos;
+ }
return (ptr);
}
struct timeval diff;
pinghost_t *host = NULL;
int recv_ttl;
+ unsigned recv_tos;
/*
* Set up the receive buffer..
/* Iterate over all auxiliary data in msghdr */
recv_ttl = -1;
+ recv_tos = 0xffff;
for (cmsg = CMSG_FIRSTHDR (&msghdr); /* {{{ */
cmsg != NULL;
cmsg = CMSG_NXTHDR (&msghdr, cmsg))
if (cmsg->cmsg_level != IPPROTO_IP)
continue;
+ if (cmsg->cmsg_type == IP_TOS)
+ {
+ memcpy (&recv_tos, CMSG_DATA (cmsg),
+ sizeof (recv_tos));
+ dprintf ("TOSv4 = %u;\n", recv_tos);
+ } else
if (cmsg->cmsg_type == IP_TTL)
{
memcpy (&recv_ttl, CMSG_DATA (cmsg),
if (cmsg->cmsg_level != IPPROTO_IPV6)
continue;
+ if (cmsg->cmsg_type == IPV6_RECVTCLASS)
+ {
+ memcpy (&recv_tos, CMSG_DATA (cmsg),
+ sizeof (recv_tos));
+ dprintf ("TOSv6 = %u;\n", recv_tos);
+ } else
if (cmsg->cmsg_type == IPV6_HOPLIMIT)
{
memcpy (&recv_ttl, CMSG_DATA (cmsg),
if (recv_ttl >= 0)
host->recv_ttl = recv_ttl;
+ if (recv_tos != 0xffff)
+ host->recv_tos = recv_tos;
host->latency = ((double) diff.tv_usec) / 1000.0;
host->latency += ((double) diff.tv_sec) * 1000.0;
return (ret);
}
+/*
+ * Set the TOS of a socket protocol independently.
+ */
+static int ping_set_tos (pinghost_t *ph, unsigned tos)
+{
+ int ret = -2;
+
+ if (ph->addrfamily == AF_INET)
+ {
+ dprintf ("Setting TP_TOS to %i\n", ttl);
+ ret = setsockopt (ph->fd, IPPROTO_IP, IP_TOS,
+ &tos, sizeof (tos));
+ }
+ else if (ph->addrfamily == AF_INET6)
+ {
+ dprintf ("Setting IPV6_TCLASS to %i\n", ttl);
+ ret = setsockopt (ph->fd, IPPROTO_IPV6, IPV6_TCLASS,
+ &tos, sizeof (tos));
+ }
+
+ return (ret);
+}
+
static int ping_get_ident (void)
{
int fd;
obj->ttl = PING_DEF_TTL;
obj->addrfamily = PING_DEF_AF;
obj->data = strdup (PING_DEF_DATA);
+ obj->tos = 0;
return (obj);
}
switch (option)
{
+ case PING_OPT_TOS:{
+ obj->tos=*(unsigned *)value;
+ pinghost_t *ph;
+ for (ph = obj->head; ph != NULL; ph = ph->next)
+ ping_set_tos (ph, obj->tos);
+ break;
+ }
case PING_OPT_TIMEOUT:
obj->timeout = *((double *) value);
if (obj->timeout < 0.0)
}
ping_set_ttl (ph, obj->ttl);
+ ping_set_tos (ph, obj->tos);
return (0);
} /* int ping_host_add */
*((int *) buffer) = iter->recv_ttl;
ret = 0;
break;
+
+ case PING_INFO_TOS:
+ ret = ENOMEM;
+ if (*buffer_len>sizeof(unsigned)) *buffer_len=sizeof(unsigned);
+ if (!*buffer_len) *buffer_len=1;
+ if (orig_buffer_len < *buffer_len)
+ break;
+ memcpy(buffer,&iter->recv_tos,*buffer_len);
+ ret = 0;
+ break;
}
return (ret);
static char *opt_filename = NULL;
static int opt_count = -1;
static int opt_send_ttl = 64;
+static unsigned opt_send_tos = 0;
static int host_num = 0;
" -c count number of ICMP packets to send\n"
" -i interval interval with which to send ICMP packets\n"
" -t ttl time to live for each ICMP packet\n"
+ " -z tos Type-of-service/class-of-service for each ICMP packet\n"
" -I srcaddr source address\n"
" -D device outgoing interface name\n"
" -f filename filename to read hosts from\n"
while (1)
{
- optchar = getopt (argc, argv, "46c:hi:I:t:f:D:");
+ optchar = getopt (argc, argv, "46c:hi:I:t:z:f:D:");
if (optchar == -1)
break;
break;
}
+ case 'z':
+ {
+ int new_send_tos;
+ new_send_tos = atoi (optarg);
+ if ((new_send_tos > 0) && (new_send_tos < 256))
+ opt_send_tos = new_send_tos;
+ else
+ fprintf (stderr, "Ignoring invalid TOS argument: %s\n",
+ optarg);
+ break;
+ }
+
case 'h':
usage_exit (argv[0], 0);
break;
double latency;
unsigned int sequence;
int recv_ttl;
+ unsigned recv_tos;
size_t buffer_len;
size_t data_len;
ping_context_t *context;
ping_iterator_get_info (iter, PING_INFO_RECV_TTL,
&recv_ttl, &buffer_len);
+ recv_tos = 0;
+ buffer_len = sizeof (recv_tos);
+ ping_iterator_get_info (iter, PING_INFO_TOS,
+ &recv_tos, &buffer_len);
+
data_len = 0;
ping_iterator_get_info (iter, PING_INFO_DATA,
NULL, &data_len);
|| (latency > (average + stddev)))
color = OPING_YELLOW;
- HOST_PRINTF ("%zu bytes from %s (%s): icmp_seq=%u ttl=%i "
+ HOST_PRINTF ("%zu bytes from %s (%s): icmp_seq=%u ttl=%i tos=%u "
"time=",
data_len, context->host, context->addr,
- sequence, recv_ttl);
+ sequence, recv_ttl, recv_tos);
wattron (main_win, COLOR_PAIR(color));
HOST_PRINTF ("%.2f", latency);
wattroff (main_win, COLOR_PAIR(color));
else
{
#endif
- HOST_PRINTF ("%zu bytes from %s (%s): icmp_seq=%u ttl=%i "
+ HOST_PRINTF ("%zu bytes from %s (%s): icmp_seq=%u ttl=%i tos=%u "
"time=%.2f ms\n",
data_len,
context->host, context->addr,
- sequence, recv_ttl, latency);
+ sequence, recv_ttl, recv_tos, latency);
#if USE_NCURSES
}
#endif
opt_send_ttl, ping_get_error (ping));
}
+ if (ping_setopt (ping, PING_OPT_TOS, &opt_send_tos) != 0)
+ {
+ fprintf (stderr, "Setting TOS to %i failed: %s\n",
+ opt_send_tos, ping_get_error (ping));
+ }
+
{
double temp_sec;
double temp_nsec;
#define PING_OPT_DATA 0x08
#define PING_OPT_SOURCE 0x10
#define PING_OPT_DEVICE 0x20
+#define PING_OPT_TOS 0x40
#define PING_DEF_TIMEOUT 1.0
#define PING_DEF_TTL 255
#define PING_INFO_USERNAME 8
#define PING_INFO_DROPPED 9
#define PING_INFO_RECV_TTL 10
+#define PING_INFO_TOS 11
int ping_iterator_get_info (pingobj_iter_t *iter, int info,
void *buffer, size_t *buffer_len);