summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: c7bfa88)
raw | patch | inline | side by side (parent: c7bfa88)
author | Vladimir Melnikov <wlad.w.m@gmail.com> | |
Tue, 26 Oct 2010 12:20:03 +0000 (14:20 +0200) | ||
committer | Florian Forster <octo@leeloo.lan.home.verplant.org> | |
Tue, 26 Oct 2010 12:20:03 +0000 (14:20 +0200) |
Hello Florian,
I've made some functionality extension to debug QoS in the network -
ability to set tos (present in most standard "pings") and to verify
received tos field (didn't see any ping command with this feature).
May be it will need to someone else.
Best regards,
Vladimir
I've made some functionality extension to debug QoS in the network -
ability to set tos (present in most standard "pings") and to verify
received tos field (didn't see any ping command with this feature).
May be it will need to someone else.
Best regards,
Vladimir
src/liboping.c | patch | blob | history | |
src/oping.c | patch | blob | history | |
src/oping.h | patch | blob | history |
diff --git a/src/liboping.c b/src/liboping.c
index 3c1c92a4a5a1ab7a86dac708f18eb83a2fe36267..2e7f2889ac13077ed4666211a352b15253eff155 100644 (file)
--- a/src/liboping.c
+++ b/src/liboping.c
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);
diff --git a/src/oping.c b/src/oping.c
index 0d7575e1bafb827ebfe8f49e7f7b1d5265be6bcb..b971cb71e1001bcdd85dba2e1544b3f26e9f8dc4 100644 (file)
--- a/src/oping.c
+++ b/src/oping.c
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;
diff --git a/src/oping.h b/src/oping.h
index e2ccf97ef3190632ca72c3472657b904b72fae13..8d858fbc9a5490200bfa84bf758e91ab95783074 100644 (file)
--- a/src/oping.h
+++ b/src/oping.h
#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);