diff options
author | Thomas Habets <thomas@habets.se> | 2014-06-01 18:49:37 +0100 |
---|---|---|
committer | Thomas Habets <thomas@habets.se> | 2014-06-01 18:49:37 +0100 |
commit | 0d5132d59c3693b602a293b366e7ac46ed5298c7 (patch) | |
tree | 63ca9e5989eda80839fd9cff41e00aa80a4f66db | |
parent | 0ec21319818b1f9d0831138911401bf1d3a5e90e (diff) | |
download | arping-0d5132d59c3693b602a293b366e7ac46ed5298c7.tar.gz |
Properly set error message in lookupdev() functions.
Also changes to print it better to the user.
-rw-r--r-- | src/arping.c | 8 | ||||
-rw-r--r-- | src/findif_bsdroute.c | 37 | ||||
-rw-r--r-- | src/findif_getifaddrs.c | 17 | ||||
-rw-r--r-- | src/findif_linux.c | 37 | ||||
-rw-r--r-- | src/findif_other.c | 8 | ||||
-rw-r--r-- | src/findif_sysctl.c | 38 |
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; } |