summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Habets <thomas@habets.se>2014-06-01 18:49:37 +0100
committerThomas Habets <thomas@habets.se>2014-06-01 18:49:37 +0100
commit0d5132d59c3693b602a293b366e7ac46ed5298c7 (patch)
tree63ca9e5989eda80839fd9cff41e00aa80a4f66db
parent0ec21319818b1f9d0831138911401bf1d3a5e90e (diff)
downloadarping-0d5132d59c3693b602a293b366e7ac46ed5298c7.tar.gz
Properly set error message in lookupdev() functions.
Also changes to print it better to the user.
-rw-r--r--src/arping.c8
-rw-r--r--src/findif_bsdroute.c37
-rw-r--r--src/findif_getifaddrs.c17
-rw-r--r--src/findif_linux.c37
-rw-r--r--src/findif_other.c8
-rw-r--r--src/findif_sysctl.c38
6 files changed, 116 insertions, 29 deletions
diff --git a/src/arping.c b/src/arping.c
index d230261..98f10a9 100644
--- a/src/arping.c
+++ b/src/arping.c
@@ -110,6 +110,8 @@
/**
* OS-specific interface finding using routing table. See findif_*.c
+ * ebuf must be called with a size of at least
+ * max(LIBNET_ERRBUF_SIZE, PCAP_ERRBUF_SIZE).
*/
const char *
arping_lookupdev(uint32_t srcip, uint32_t dstip, char *ebuf);
@@ -1348,11 +1350,15 @@ int main(int argc, char **argv)
if (!dont_use_arping_lookupdev) {
ifname = arping_lookupdev(srcip, dstip, ebuf);
strip_newline(ebuf);
+ if (!ifname) {
+ fprintf(stderr, "arping: lookup dev: %s\n",
+ ebuf);
+ }
}
if (!ifname) {
ifname = arping_lookupdev_default(srcip, dstip, ebuf);
strip_newline(ebuf);
- if (!dont_use_arping_lookupdev) {
+ if (ifname && !dont_use_arping_lookupdev) {
fprintf(stderr,
"arping: Unable to automatically find "
"interface to use. Is it on the local "
diff --git a/src/findif_bsdroute.c b/src/findif_bsdroute.c
index db321ff..6372145 100644
--- a/src/findif_bsdroute.c
+++ b/src/findif_bsdroute.c
@@ -1,6 +1,6 @@
/* arping/src/findif_bsdroute.c
*
- * Copyright (C) 2000-2009 Thomas Habets <thomas@habets.se>
+ * Copyright (C) 2000-2014 Thomas Habets <thomas@habets.se>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
@@ -27,6 +27,10 @@
#include <stdio.h>
#include <string.h>
+#if HAVE_LIBNET_H
+#include <libnet.h>
+#endif
+
#include "arping.h"
/**
@@ -37,12 +41,14 @@ arping_lookupdev(uint32_t srcip,
uint32_t dstip,
char *ebuf)
{
- FILE *f;
+ FILE *f = NULL;
static char buf[10240];
char buf1[1024];
char *p,*p2;
int n;
+ *ebuf = 0;
+
do_libnet_init(NULL, 0);
libnet_addr2name4_r(dstip,0,buf1, 1024);
@@ -52,35 +58,54 @@ arping_lookupdev(uint32_t srcip,
snprintf(buf, 1023, "/sbin/route -n get %s 2>&1",
buf1);
if (!(f = popen(buf, "r"))) {
+ snprintf(ebuf, LIBNET_ERRBUF_SIZE,
+ "popen(/sbin/route): %s", strerror(errno));
goto failed;
}
if (0 > (n = fread(buf, 1, sizeof(buf)-1, f))) {
- pclose(f);
+ snprintf(ebuf, LIBNET_ERRBUF_SIZE,
+ "fread(/sbin/route): %s", strerror(errno));
goto failed;
}
buf[n] = 0;
if (-1 == pclose(f)) {
- perror("arping: pclose()");
+ snprintf(ebuf, LIBNET_ERRBUF_SIZE,
+ "pclose(/sbin/route): %s", strerror(errno));
goto failed;
}
+ f = NULL;
/*
* Parse interface name
*/
- p = strstr(buf, "interface: ");
+ const char* head = "interface: ";
+ p = strstr(buf, head);
if (!p) {
+ if (verbose) {
+ printf("arping: /sbin/route output: %s\n", buf);
+ }
+ snprintf(ebuf, LIBNET_ERRBUF_SIZE,
+ "\"interface:\" not found in /sbin/route output.");
goto failed;
}
- p+=11;
+ p += strlen(head);
p2 = strchr(p, '\n');
if (!p2) {
+ if (verbose) {
+ printf("arping: /sbin/route output: %s\n", buf);
+ }
+ snprintf(ebuf, LIBNET_ERRBUF_SIZE,
+ "interface not found in /sbin/route output.");
goto failed;
}
*p2 = 0;
return p;
failed:
+ if (f) {
+ pclose(f);
+ }
return NULL;
}
/* ---- Emacs Variables ----
diff --git a/src/findif_getifaddrs.c b/src/findif_getifaddrs.c
index 714ceea..953289c 100644
--- a/src/findif_getifaddrs.c
+++ b/src/findif_getifaddrs.c
@@ -1,6 +1,6 @@
/* arping/src/findif_getifaddrs.c
*
- * Copyright (C) 2000-2011 Thomas Habets <thomas@habets.se>
+ * Copyright (C) 2000-2014 Thomas Habets <thomas@habets.se>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
@@ -33,6 +33,10 @@
#include <net/if.h>
#include <netinet/in.h>
+#if HAVE_LIBNET_H
+#include <libnet.h>
+#endif
+
#include "arping.h"
const char *
@@ -52,10 +56,14 @@ arping_lookupdev(uint32_t srcip,
/* Results */
static char ifname[IFNAMSIZ];
+ *ebuf = 0;
+
if (getifaddrs(&ifa)) {
if (verbose) {
printf("arping: getifaddrs(): %s\n", strerror(errno));
}
+ snprintf(ebuf, LIBNET_ERRBUF_SIZE,
+ "getifaddrs(): %s", strerror(errno));
goto out;
}
for (cur = ifa; cur; cur = cur->ifa_next) {
@@ -94,9 +102,12 @@ arping_lookupdev(uint32_t srcip,
printf("arping: Autodetected interface %s\n", ret);
}
} else {
- if (verbose) {
- printf("Failed to find iface using getifaddrs().\n");
+ if (verbose > 1) {
+ printf("arping: Failed to find iface using"
+ " getifaddrs().\n");
}
+ snprintf(ebuf, LIBNET_ERRBUF_SIZE,
+ "No matching interface found using getifaddrs().");
}
out:
if (ifa) {
diff --git a/src/findif_linux.c b/src/findif_linux.c
index de5515d..425b6b5 100644
--- a/src/findif_linux.c
+++ b/src/findif_linux.c
@@ -1,6 +1,6 @@
/* arping/src/findif_linux.c
*
- * Copyright (C) 2000-2009 Thomas Habets <thomas@habets.se>
+ * Copyright (C) 2000-2014 Thomas Habets <thomas@habets.se>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
@@ -27,6 +27,10 @@
#include <stdio.h>
#include <string.h>
+#if HAVE_LIBNET_H
+#include <libnet.h>
+#endif
+
#include "arping.h"
/**
@@ -37,13 +41,15 @@ arping_lookupdev(uint32_t srcip,
uint32_t dstip,
char *ebuf)
{
- FILE *f;
+ FILE *f = NULL;
static char buf[1024];
char buf1[1024];
char buf2[1024];
char *p,*p2;
int n;
+ *ebuf = 0;
+
do_libnet_init(NULL, 0);
libnet_addr2name4_r(dstip,0,buf2,1024);
libnet_addr2name4_r(srcip,0,buf1,1024);
@@ -54,35 +60,54 @@ arping_lookupdev(uint32_t srcip,
snprintf(buf, 1023, "/sbin/ip route get %s from %s 2>&1",
buf2, buf1);
if (!(f = popen(buf, "r"))) {
+ snprintf(ebuf, LIBNET_ERRBUF_SIZE,
+ "popen(/sbin/ip): %s", strerror(errno));
goto failed;
}
if (0>(n = fread(buf, 1, sizeof(buf)-1, f))) {
- pclose(f);
+ snprintf(ebuf, LIBNET_ERRBUF_SIZE,
+ "fread(/sbin/ip): %s", strerror(errno));
goto failed;
}
buf[n] = 0;
if (-1 == pclose(f)) {
- perror("arping: pclose()");
+ snprintf(ebuf, LIBNET_ERRBUF_SIZE,
+ "pclose(/sbin/ip): %s", strerror(errno));
goto failed;
}
+ f = NULL;
/*
* Parse interface name
*/
- p = strstr(buf, "dev ");
+ const char* head = "dev ";
+ p = strstr(buf, head);
if (!p) {
+ if (verbose) {
+ printf("arping: /sbin/ip output: %s\n", buf);
+ }
+ snprintf(ebuf, LIBNET_ERRBUF_SIZE,
+ "\"dev \" not found in /sbin/ip output.");
goto failed;
}
- p+=4;
+ p += strlen(head);
p2 = strchr(p, ' ');
if (!p2) {
+ if (verbose) {
+ printf("arping: /sbin/ip output: %s\n", buf);
+ }
+ snprintf(ebuf, LIBNET_ERRBUF_SIZE,
+ "interface not found in /sbin/ip output.");
goto failed;
}
*p2 = 0;
return p;
failed:
+ if (f) {
+ pclose(f);
+ }
return NULL;
}
/* ---- Emacs Variables ----
diff --git a/src/findif_other.c b/src/findif_other.c
index 934be9f..917dbea 100644
--- a/src/findif_other.c
+++ b/src/findif_other.c
@@ -1,6 +1,6 @@
/* arping/src/findif_other.c
*
- * Copyright (C) 2000-2009 Thomas Habets <thomas@habets.se>
+ * Copyright (C) 2000-2014 Thomas Habets <thomas@habets.se>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
@@ -23,6 +23,10 @@
#include <stdio.h>
#include <string.h>
+#if HAVE_LIBNET_H
+#include <libnet.h>
+#endif
+
#include "arping.h"
/**
@@ -31,6 +35,8 @@
const char *
arping_lookupdev(uint32_t srcip, uint32_t dstip, char *ebuf)
{
+ snprintf(ebuf, LIBNET_ERRBUF_SIZE,
+ "arping_lookupdev() not implemented for this system.");
return NULL;
}
/* ---- Emacs Variables ----
diff --git a/src/findif_sysctl.c b/src/findif_sysctl.c
index 7c62aaa..9874156 100644
--- a/src/findif_sysctl.c
+++ b/src/findif_sysctl.c
@@ -1,6 +1,6 @@
/* arping/src/findif_sysctl.c
*
- * Copyright (C) 2000-2011 Thomas Habets <thomas@habets.se>
+ * Copyright (C) 2000-2014 Thomas Habets <thomas@habets.se>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
@@ -72,7 +72,8 @@ arping_lookupdev(uint32_t srcip,
int c;
/* buffer */
- char *buf, *lim;
+ char *buf = NULL;
+ char *lim;
size_t bufsize;
/* Matching interfaces */
@@ -84,26 +85,35 @@ arping_lookupdev(uint32_t srcip,
/* Results */
static char ifName[IFNAMSIZ];
+ *ebuf = 0;
/* Allocate buffer and retrieve data. */
for (c = 0;;) {
if (sysctl(mib, 6, NULL, &bufsize, NULL, 0) < 0) {
- strcpy(ebuf, "sysctl: get buffer size error");
+ snprintf(ebuf, LIBNET_ERRBUF_SIZE,
+ "sysctl: get buffer size error: %s",
+ strerror(errno));
goto failed;
}
if ((buf = malloc(bufsize)) == NULL) {
- strcpy(ebuf, "malloc: error");
+ snprintf(ebuf, LIBNET_ERRBUF_SIZE,
+ "malloc: error: %s", strerror(errno));
goto failed;
}
if (sysctl(mib, 6, buf, &bufsize, NULL, 0) == 0) {
break;
}
if (errno != ENOMEM || ++c >= 10 ) {
- strcpy(ebuf, "sysctl: get ifaces error");
+ snprintf(ebuf, LIBNET_ERRBUF_SIZE,
+ "sysctl: get ifaces error: %s",
+ strerror(errno));
goto failed;
}
- fprintf(stderr, "sysctl: buffer size changed");
+ if (verbose > 2) {
+ printf("sysctl: buffer size changed.");
+ }
free(buf);
+ buf = NULL;
}
lim = buf + bufsize;
@@ -116,7 +126,8 @@ arping_lookupdev(uint32_t srcip,
struct if_msghdr *ifh = (struct if_msghdr *)buf;
if (ifh->ifm_type != RTM_IFINFO) {
- strcpy(ebuf, "Wrong data in NET_RT_IFLIST");
+ snprintf(ebuf, LIBNET_ERRBUF_SIZE,
+ "Wrong data in NET_RT_IFLIST.");
return NULL;
}
sdl = (struct sockaddr_dl *)(buf +
@@ -189,7 +200,7 @@ arping_lookupdev(uint32_t srcip,
match_count++;
- if (verbose) {
+ if (verbose > 1) {
printf("Specified addr matches "
"interface '%s':\n", tmpIfName);
printf(" IP addr %s, ",
@@ -213,24 +224,27 @@ arping_lookupdev(uint32_t srcip,
if (match_count == 0 ) {
if (verbose) {
- strcpy(ebuf,
- "No interface found that matches specified IP");
+ snprintf(ebuf, LIBNET_ERRBUF_SIZE,
+ "No interface found that matches"
+ " specified IP.");
}
goto failed;
}
if (verbose && match_count > 1) {
- printf("Using interface '%s' with src IP %s due to longer "
- "mask.\n", ifName, inet_ntoa(best_addr));
+ printf("arping: Using interface '%s' with src IP %s due "
+ "to longer mask.\n", ifName, inet_ntoa(best_addr));
}
#if 0
if (ifce_ip != 0) {
*ifce_ip = best_addr.s_addr;
}
#endif
+ free(buf);
return ifName;
failed:
+ free(buf);
return NULL;
}