summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Habets <thomas@habets.se>2021-11-05 18:24:27 +0000
committerThomas Habets <thomas@habets.se>2021-11-05 18:32:10 +0000
commit3cad228fddc547637570b7f16090e57e4b507027 (patch)
tree256c6562d976da9d6de5e17e0874e3ec336fb12e
parentcde442eb17e17fdf331de6cd3d336c1418f54f92 (diff)
downloadarping-3cad228fddc547637570b7f16090e57e4b507027.tar.gz
Also try lo0 as a fallback interface. Fixes default use on OpenBSD
Background: Libnet usually needs init before we have searched for the real interface. In that case, first we just give a NULL pointer as the interface. But libnet sometimes fails to find an interface (no idea why), so we try to put in "lo". This commit adds "lo0" as an interface checked, as that is the name on OpenBSD.
-rw-r--r--src/arping.c68
1 files changed, 51 insertions, 17 deletions
diff --git a/src/arping.c b/src/arping.c
index e2c157f..5e21303 100644
--- a/src/arping.c
+++ b/src/arping.c
@@ -626,17 +626,48 @@ strip_newline(char* s) {
/**
* Init libnet with specified ifname. Destroy if already inited.
- * If this function retries with different parameter it will preserve
- * the original error message and print that.
+ *
+ * Libnet usually needs init before we have searched for the real
+ * interface. In that case, first we just give a NULL pointer as the
+ * interface. But libnet sometimes fails to find an interface (no idea
+ * why), so then we try to use "lo" and "lo0" explicitly.
+ *
+ * If even loopback fails, then it'll preserve the original error
+ * message.
+ *
* Call with recursive=0.
*/
void
-do_libnet_init(const char *ifname, int recursive)
+do_libnet_init(const char *inifname, int recursive)
{
+ const char* ifname = inifname;
+ int last = 0;
+ switch (recursive) {
+ case 0:
+ break;
+ case 1:
+ ifname = "lo"; // E.g. Linux.
+ break;
+ case 2:
+ ifname = "lo0"; // E.g. OpenBSD.
+ break;
+ default:
+ last = 1;
+ break;
+ }
+
+ // If we're given an interface name then always use that.
+ // No need to be recursive about it.
+ if (inifname != NULL && recursive == 0) {
+ ifname = inifname;
+ last = 1;
+ }
+
char ebuf[LIBNET_ERRBUF_SIZE];
ebuf[0] = 0;
if (verbose > 1) {
- printf("arping: libnet_init(%s)\n", ifname ? ifname : "<null>");
+ printf("arping: trying libnet_init(LIBNET_LINK, %s)\n",
+ ifname ? ifname : "<null>");
}
if (libnet) {
/* Probably going to switch interface from temp to real. */
@@ -644,28 +675,31 @@ do_libnet_init(const char *ifname, int recursive)
libnet = 0;
}
- /* Try libnet_init() even though we aren't root. We may have
+ /* Try libnet_init() even though we maybe aren't root. We may have
* a capability or something. */
if (!(libnet = libnet_init(LIBNET_LINK,
(char*)ifname,
ebuf))) {
strip_newline(ebuf);
- if (!ifname) {
- /* Sometimes libnet guesses an interface that it then
- * can't use. Work around that by attempting to
- * use "lo". */
- do_libnet_init("lo", 1);
+ if (verbose) {
+ fprintf(stderr,
+ "arping: libnet_init(LIBNET_LINK, %s): %s\n",
+ ifname ? ifname : "<null>",
+ *ebuf ? ebuf : "<no error message>");
+ }
+ if (!last) {
+ do_libnet_init(ifname, recursive+1);
if (libnet != NULL) {
return;
}
- } else if (recursive) {
- /* Continue original execution to get that
- * error message. */
- return;
}
- fprintf(stderr, "arping: libnet_init(LIBNET_LINK, %s): %s\n",
- ifname ? ifname : "<null>",
- *ebuf ? ebuf : "<no error message>");
+ if (!verbose) {
+ // Prevent double-print when verbose.
+ fprintf(stderr,
+ "arping: libnet_init(LIBNET_LINK, %s): %s\n",
+ ifname ? ifname : "<null>",
+ *ebuf ? ebuf : "<no error message>");
+ }
if (getuid() && geteuid()) {
fprintf(stderr,
"arping: you may need to run as root\n");