author | Florian Forster <ff@octo.it> | |
Fri, 13 Feb 2015 12:46:06 +0000 (13:46 +0100) | ||
committer | Florian Forster <ff@octo.it> | |
Fri, 13 Feb 2015 12:46:06 +0000 (13:46 +0100) |
src/liboping.c | patch | blob | history | |
src/mans/ping_setopt.pod | 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 40a0ba21b570bab19fea04fc71d8c69231125173..dd9da461b9baa4efef879367579e56ea956979d2 100644 (file)
--- a/src/liboping.c
+++ b/src/liboping.c
char *device;
+ char set_mark;
+ int mark;
+
char errmsg[PING_ERRMSG_LEN];
pinghost_t *head;
} /* case PING_OPT_DEVICE */
break;
+ case PING_OPT_MARK:
+ {
+#ifdef SO_MARK
+ obj->mark = *(int*)(value);
+ obj->set_mark = 1;
+#else /* SO_MARK */
+ ping_set_errno (obj, ENOTSUP);
+ ret = -1;
+#endif /* !SO_MARK */
+
+ } /* case PING_OPT_MARK */
+ break;
+
default:
ret = -2;
} /* switch (option) */
}
}
#endif /* SO_BINDTODEVICE */
+#ifdef SO_MARK
+ if(obj->set_mark)
+ {
+ if(setsockopt(ph->fd, SOL_SOCKET, SO_MARK, &(obj->mark), sizeof(obj->mark)) != 0)
+ {
+#if WITH_DEBUG
+ char errbuf[PING_ERRMSG_LEN];
+ dprintf ("setsockopt (SO_MARK): %s\n",
+ sstrerror (errno, errbuf, sizeof (errbuf)));
+#endif
+ ping_set_errno (obj, errno);
+ close (ph->fd);
+ ph->fd = -1;
+ continue;
+ }
+ }
+#endif
#ifdef SO_TIMESTAMP
if (1) /* {{{ */
{
index 11c63d8f13b3d454b47ce939a02973be4508d3c6..ba7e44feb3ae2962dbbde019ac0e9620f750c9ae 100644 (file)
--- a/src/mans/ping_setopt.pod
+++ b/src/mans/ping_setopt.pod
responsibility to chose a valid bit combination. For details, read the L<ip(7)>
and L<ipv6(7)> manual pages, as well as I<RFCE<nbsp>2474>.
+=item B<PING_OPT_MARK>
+
+Mark (as in netfilter) outgoing packets using the SO_MARK socket option. Takes
+an int* pointer as a value. Setting this requires CAP_NET_ADMIN under Linux.
+Fails with C<operation not supported> on platforms which don't have SO_MARK.
+
=back
The I<val> argument is a pointer to the new value. It must not be NULL. It is
diff --git a/src/oping.c b/src/oping.c
index 3ae226c6f5e64d25e31d3ab3d960e0e673a8289f..6263a4def36459c7d94c8dbbb362cc89b56a9f6e 100644 (file)
--- a/src/oping.c
+++ b/src/oping.c
static int opt_addrfamily = PING_DEF_AF;
static char *opt_srcaddr = NULL;
static char *opt_device = NULL;
+static char *opt_mark = NULL;
static char *opt_filename = NULL;
static int opt_count = -1;
static int opt_send_ttl = 64;
" Use \"-Q help\" for a list of valid options.\n"
" -I srcaddr source address\n"
" -D device outgoing interface name\n"
+ " -m mark mark to set on outgoing packets\n"
" -f filename filename to read hosts from\n"
#if USE_NCURSES
" -u / -U force / disable UTF-8 output\n"
while (1)
{
- optchar = getopt (argc, argv, "46c:hi:I:t:Q:f:D:Z:P:w:"
+ optchar = getopt (argc, argv, "46c:hi:I:t:Q:f:D:Z:P:m:w:"
#if USE_NCURSES
"uUg:"
#endif
opt_device = optarg;
break;
+ case 'm':
+ opt_mark = optarg;
+ break;
+
case 't':
{
int new_send_ttl;
}
}
+ if(opt_mark != NULL)
+ {
+ char *endp;
+ int mark = strtoul(opt_mark, &endp, 0);
+ if(opt_mark[0] != '\0' && *endp == '\0')
+ {
+ if(ping_setopt(ping, PING_OPT_MARK, (void*)(&mark)) != 0)
+ {
+ fprintf (stderr, "Setting mark failed: %s\n",
+ ping_get_error (ping));
+ }
+ }
+ else{
+ fprintf(stderr, "Ignoring invalid mark: %s\n", optarg);
+ }
+ }
+
if (opt_filename != NULL)
{
FILE *infile;
diff --git a/src/oping.h b/src/oping.h
index 9f8d5e18b25044a6b5f74c91120beabcf881bbc6..e5bc5fa9c284e981d137a17a40751b3e62a55a0e 100644 (file)
--- a/src/oping.h
+++ b/src/oping.h
#define PING_OPT_SOURCE 0x10
#define PING_OPT_DEVICE 0x20
#define PING_OPT_QOS 0x40
+#define PING_OPT_MARK 0x80
#define PING_DEF_TIMEOUT 1.0
#define PING_DEF_TTL 255