1: /* arping/src/findif_linux.c
2: *
3: * Copyright (C) 2000-2014 Thomas Habets <thomas@habets.se>
4: *
5: * This program is free software; you can redistribute it and/or modify
6: * it under the terms of the GNU General Public License as published by
7: * the Free Software Foundation; either version 2 of the License, or
8: * (at your option) any later version.
9: *
10: * This program is distributed in the hope that it will be useful,
11: * but WITHOUT ANY WARRANTY; without even the implied warranty of
12: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13: * GNU General Public License for more details.
14: *
15: * You should have received a copy of the GNU General Public License along
16: * with this program; if not, write to the Free Software Foundation, Inc.,
17: * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18: */
19: /**
20: * Fallback to ugly solution. This should not actually be used, as
21: * modern systems have getifaddrs().
22: */
23: #if HAVE_CONFIG_H
24: #include "config.h"
25: #endif
26:
27: #include <stdio.h>
28: #include <string.h>
29:
30: #if HAVE_LIBNET_H
31: #include <libnet.h>
32: #endif
33:
34: #include "arping.h"
35:
36: /**
37: * WARNING: non-reentrant
38: */
39: const char *
40: arping_lookupdev(uint32_t srcip,
41: uint32_t dstip,
42: char *ebuf)
43: {
44: FILE *f = NULL;
45: static char buf[1024];
46: char buf1[1024];
47: char buf2[1024];
48: char *p,*p2;
49: int n;
50:
51: *ebuf = 0;
52:
53: do_libnet_init(NULL, 0);
54: libnet_addr2name4_r(dstip,0,buf2,1024);
55: libnet_addr2name4_r(srcip,0,buf1,1024);
56:
57: /*
58: * Construct and run command
59: */
60: snprintf(buf, 1023, "/sbin/ip route get %s from %s 2>&1",
61: buf2, buf1);
62: if (!(f = popen(buf, "r"))) {
63: snprintf(ebuf, LIBNET_ERRBUF_SIZE,
64: "popen(/sbin/ip): %s", strerror(errno));
65: goto failed;
66: }
67: if (0>(n = fread(buf, 1, sizeof(buf)-1, f))) {
68: snprintf(ebuf, LIBNET_ERRBUF_SIZE,
69: "fread(/sbin/ip): %s", strerror(errno));
70: goto failed;
71: }
72: buf[n] = 0;
73: if (-1 == pclose(f)) {
74: snprintf(ebuf, LIBNET_ERRBUF_SIZE,
75: "pclose(/sbin/ip): %s", strerror(errno));
76: goto failed;
77: }
78: f = NULL;
79:
80: /*
81: * Parse interface name
82: */
83: const char* head = "dev ";
84: p = strstr(buf, head);
85: if (!p) {
86: if (verbose) {
87: printf("arping: /sbin/ip output: %s\n", buf);
88: }
89: snprintf(ebuf, LIBNET_ERRBUF_SIZE,
90: "\"dev \" not found in /sbin/ip output.");
91: goto failed;
92: }
93:
94: p += strlen(head);
95:
96: p2 = strchr(p, ' ');
97: if (!p2) {
98: if (verbose) {
99: printf("arping: /sbin/ip output: %s\n", buf);
100: }
101: snprintf(ebuf, LIBNET_ERRBUF_SIZE,
102: "interface not found in /sbin/ip output.");
103: goto failed;
104: }
105: *p2 = 0;
106: return p;
107: failed:
108: if (f) {
109: pclose(f);
110: }
111: return NULL;
112: }
113: /* ---- Emacs Variables ----
114: * Local Variables:
115: * c-basic-offset: 8
116: * indent-tabs-mode: nil
117: * End:
118: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>