summaryrefslogtreecommitdiff
path: root/inet.c
diff options
context:
space:
mode:
Diffstat (limited to 'inet.c')
-rw-r--r--inet.c99
1 files changed, 73 insertions, 26 deletions
diff --git a/inet.c b/inet.c
index aad87963e786..0b16a659072d 100644
--- a/inet.c
+++ b/inet.c
@@ -34,7 +34,7 @@
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/libpcap/inet.c,v 1.75.2.4 2008-04-20 18:19:24 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/inet.c,v 1.79 2008-04-20 18:19:02 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@@ -366,26 +366,38 @@ add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, const char *name,
* a Cisco 340 or 350, rather than an old Aironet card, it should use
* that in the description.
*
- * Do NetBSD, DragonflyBSD, or OpenBSD support this as well? OpenBSD
- * lets you get a description, but it's not generated by the OS, it's
- * set with another ioctl that ifconfig supports; we use that to get
- * the description in OpenBSD.
+ * Do NetBSD, DragonflyBSD, or OpenBSD support this as well? FreeBSD
+ * and OpenBSD let you get a description, but it's not generated by the OS,
+ * it's set with another ioctl that ifconfig supports; we use that to get
+ * a description in FreeBSD and OpenBSD, but if there is no such
+ * description available, it still might be nice to get some description
+ * string based on the device type or something such as that.
*
* In OS X, the System Configuration framework can apparently return
- * names in 10.4 and later; it also appears that freedesktop.org's HAL
- * offers an "info.product" string, but the HAL specification says
- * it "should not be used in any UI" and "subsystem/capability
- * specific properties" should be used instead. Using that would
- * require that libpcap applications be linked with the frameworks/
- * libraries in question, which would be a bit of a pain unless we
- * offer, for example, a pkg-config:
+ * names in 10.4 and later.
*
- * http://pkg-config.freedesktop.org/wiki/
+ * It also appears that freedesktop.org's HAL offers an "info.product"
+ * string, but the HAL specification says it "should not be used in any
+ * UI" and "subsystem/capability specific properties" should be used
+ * instead and, in any case, I think HAL is being deprecated in
+ * favor of other stuff such as DeviceKit. DeviceKit doesn't appear
+ * to have any obvious product information for devices, but maybe
+ * I haven't looked hard enough.
*
- * script, so applications can just use that script to find out what
- * libraries you need to link with when linking with libpcap.
- * pkg-config is GPLed; I don't know whether that would prevent its
- * use with a BSD-licensed library such as libpcap.
+ * Using the System Configuration framework, or HAL, or DeviceKit, or
+ * whatever, would require that libpcap applications be linked with
+ * the frameworks/libraries in question. That shouldn't be a problem
+ * for programs linking with the shared version of libpcap (unless
+ * you're running on AIX - which I think is the only UN*X that doesn't
+ * support linking a shared library with other libraries on which it
+ * depends, and having an executable linked only with the first shared
+ * library automatically pick up the other libraries when started -
+ * and using HAL or whatever). Programs linked with the static
+ * version of libpcap would have to use pcap-config with the --static
+ * flag in order to get the right linker flags in order to pick up
+ * the additional libraries/frameworks; those programs need that anyway
+ * for libpcap 1.1 and beyond on Linux, as, by default, it requires
+ * -lnl.
*
* Do any other UN*Xes, or desktop environments support getting a
* description?
@@ -402,10 +414,14 @@ add_addr_to_iflist(pcap_if_t **alldevs, const char *name, u_int flags,
char *description = NULL;
pcap_addr_t *curaddr, *prevaddr, *nextaddr;
#ifdef SIOCGIFDESCR
- struct ifreq ifrdesc;
- char ifdescr[IFDESCRSIZE];
int s;
-#endif
+ struct ifreq ifrdesc;
+#ifndef IFDESCRSIZE
+ size_t descrlen = 64;
+#else
+ size_t descrlen = IFDESCRSIZE;
+#endif /* IFDESCRSIZE */
+#endif /* SIOCGIFDESCR */
#ifdef SIOCGIFDESCR
/*
@@ -413,23 +429,45 @@ add_addr_to_iflist(pcap_if_t **alldevs, const char *name, u_int flags,
*/
memset(&ifrdesc, 0, sizeof ifrdesc);
strlcpy(ifrdesc.ifr_name, name, sizeof ifrdesc.ifr_name);
- ifrdesc.ifr_data = (caddr_t)&ifdescr;
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s >= 0) {
- if (ioctl(s, SIOCGIFDESCR, &ifrdesc) == 0 &&
- strlen(ifrdesc.ifr_data) != 0)
- description = ifrdesc.ifr_data;
+ for (;;) {
+ free(description);
+ if ((description = malloc(descrlen)) != NULL) {
+#ifdef __FreeBSD__
+ ifrdesc.ifr_buffer.buffer = description;
+ ifrdesc.ifr_buffer.length = descrlen;
+#else /* __FreeBSD__ */
+ ifrdesc.ifr_data = (caddr_t)description;
+#endif /* __FreeBSD__ */
+ if (ioctl(s, SIOCGIFDESCR, &ifrdesc) == 0)
+ break;
+#ifdef __FreeBSD__
+ else if (errno == ENAMETOOLONG)
+ descrlen = ifrdesc.ifr_buffer.length;
+#endif /* __FreeBSD__ */
+ else
+ break;
+ } else
+ break;
+ }
close(s);
+ if (description != NULL && strlen(description) == 0) {
+ free(description);
+ description = NULL;
+ }
}
-#endif
+#endif /* SIOCGIFDESCR */
if (add_or_find_if(&curdev, alldevs, name, flags, description,
errbuf) == -1) {
+ free(description);
/*
* Error - give up.
*/
return (-1);
}
+ free(description);
if (curdev == NULL) {
/*
* Device wasn't added because it can't be opened.
@@ -669,7 +707,10 @@ pcap_lookupnet(device, netp, maskp, errbuf)
|| strstr(device, "bluetooth") != NULL
#endif
#ifdef PCAP_SUPPORT_USB
- || strstr(device, "usb") != NULL
+ || strstr(device, "usbmon") != NULL
+#endif
+#ifdef HAVE_SNF_API
+ || strstr(device, "snf") != NULL
#endif
) {
*netp = *maskp = 0;
@@ -702,6 +743,12 @@ pcap_lookupnet(device, netp, maskp, errbuf)
}
sin4 = (struct sockaddr_in *)&ifr.ifr_addr;
*netp = sin4->sin_addr.s_addr;
+ memset(&ifr, 0, sizeof(ifr));
+#ifdef linux
+ /* XXX Work around Linux kernel bug */
+ ifr.ifr_addr.sa_family = AF_INET;
+#endif
+ (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifr) < 0) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGIFNETMASK: %s: %s", device, pcap_strerror(errno));