return (n);
}
+#ifndef _WIN32
/*
* Try to get a description for a given device.
* Returns a mallocated description if it could and NULL if it couldn't.
/*
* Look for a given device in the specified list of devices.
*
- * If we find it, return 0 and set *curdev_ret to point to it.
- *
- * If we don't find it, attempt to add an entry for it, with the specified
- * ifnet flags and description, and, if that succeeds, return 0 and set
- * *curdev_ret to point to the new entry, otherwise return PCAP_ERROR
- * and set errbuf to an error message. If we weren't given a description,
- * try to get one.
- */
-int
-add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, const char *name,
- bpf_u_int32 flags, const char *description, char *errbuf)
-{
- pcap_if_t *curdev, *prevdev, *nextdev;
- u_int this_figure_of_merit, nextdev_figure_of_merit;
-
- /*
- * Is there already an entry in the list for this interface?
- */
- for (curdev = *alldevs; curdev != NULL; curdev = curdev->next) {
- if (strcmp(name, curdev->name) == 0)
- break; /* yes, we found it */
- }
-
- if (curdev == NULL) {
- /*
- * No, we didn't find it. Add it to the list of
- * devices.
- */
- curdev = malloc(sizeof(pcap_if_t));
- if (curdev == NULL) {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "malloc: %s", pcap_strerror(errno));
- return (-1);
- }
-
- /*
- * Fill in the entry.
- */
- curdev->next = NULL;
- curdev->name = strdup(name);
- if (curdev->name == NULL) {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "malloc: %s", pcap_strerror(errno));
- free(curdev);
- return (-1);
- }
- if (description == NULL) {
- /*
- * We weren't handed a description for the
- * interface, so see if we can generate one
- * ourselves.
- */
- curdev->description = get_if_description(name);
- } else {
- /*
- * We were handed a description; make a copy.
- */
- curdev->description = strdup(description);
- if (curdev->description == NULL) {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "malloc: %s", pcap_strerror(errno));
- free(curdev->name);
- free(curdev);
- return (-1);
- }
- }
- curdev->addresses = NULL; /* list starts out as empty */
- curdev->flags = flags;
-
- /*
- * Add it to the list, in the appropriate location.
- * First, get the "figure of merit" for this
- * interface.
- */
- this_figure_of_merit = get_figure_of_merit(curdev);
-
- /*
- * Now look for the last interface with an figure of merit
- * less than or equal to the new interface's figure of
- * merit.
- *
- * We start with "prevdev" being NULL, meaning we're before
- * the first element in the list.
- */
- prevdev = NULL;
- for (;;) {
- /*
- * Get the interface after this one.
- */
- if (prevdev == NULL) {
- /*
- * The next element is the first element.
- */
- nextdev = *alldevs;
- } else
- nextdev = prevdev->next;
-
- /*
- * Are we at the end of the list?
- */
- if (nextdev == NULL) {
- /*
- * Yes - we have to put the new entry
- * after "prevdev".
- */
- break;
- }
-
- /*
- * Is the new interface's figure of merit less
- * than the next interface's figure of merit,
- * meaning that the new interface is better
- * than the next interface?
- */
- nextdev_figure_of_merit = get_figure_of_merit(nextdev);
- if (this_figure_of_merit < nextdev_figure_of_merit) {
- /*
- * Yes - we should put the new entry
- * before "nextdev", i.e. after "prevdev".
- */
- break;
- }
-
- prevdev = nextdev;
- }
-
- /*
- * Insert before "nextdev".
- */
- curdev->next = nextdev;
-
- /*
- * Insert after "prevdev" - unless "prevdev" is null,
- * in which case this is the first interface.
- */
- if (prevdev == NULL) {
- /*
- * This is the first interface. Pass back a
- * pointer to it, and put "curdev" before
- * "nextdev".
- */
- *alldevs = curdev;
- } else
- prevdev->next = curdev;
- }
-
- *curdev_ret = curdev;
- return (0);
-}
-
-/*
- * Try to get a description for a given device, and then look for that
- * device in the specified list of devices.
- *
* If we find it, then, if the specified address isn't null, add it to
* the list of addresses for the device and return 0.
*
- * If we don't find it, check whether we can open it:
- *
- * If that fails with PCAP_ERROR_NO_SUCH_DEVICE or
- * PCAP_ERROR_IFACE_NOT_UP, don't attempt to add an entry for
- * it, as that probably means it exists but doesn't support
- * packet capture.
- *
- * Otherwise, attempt to add an entry for it, with the specified
- * ifnet flags, and, if that succeeds, add the specified address
- * to its list of addresses if that address is non-null, set
- * *curdev_ret to point to the new entry, and return 0, otherwise
- * return PCAP_ERROR and set errbuf to an error message.
+ * If we don't find it, attempt to add an entry for it, with the specified
+ * flags and description, and, if that succeeds, add the specified
+ * address to its list of addresses if that address is non-null, and
+ * return 0, otherwise return -1 and set errbuf to an error message.
*
* (We can get called with a null address because we might get a list
* of interface name/address combinations from the underlying OS, with
{
pcap_if_t *curdev;
- if (add_or_find_if(&curdev, alldevs, name, flags, NULL, errbuf) == -1) {
+ /*
+ * Attempt to find an entry for this device; if we don't find one,
+ * attempt to add one.
+ */
+ curdev = find_or_add_dev(alldevs, name, flags, get_if_description(name),
+ errbuf);
+ if (curdev == NULL) {
/*
* Error - give up.
*/
return (-1);
}
- if (curdev == NULL) {
- /*
- * Device wasn't added because it can't be opened.
- * Not a fatal error.
- */
- return (0);
- }
if (addr == NULL) {
/*
netmask_size, broadaddr, broadaddr_size, dstaddr,
dstaddr_size, errbuf));
}
+#endif /* _WIN32 */
/*
* Add an entry to the list of addresses for an interface.
/*
* Look for a given device in the specified list of devices.
*
- * If we find it, return 0.
- *
- * If we don't find it, check whether we can open it:
- *
- * If that fails with PCAP_ERROR_NO_SUCH_DEVICE or
- * PCAP_ERROR_IFACE_NOT_UP, don't attempt to add an entry for
- * it, as that probably means it exists but doesn't support
- * packet capture.
+ * If we find it, return 0 and set *curdev_ret to point to it.
*
- * Otherwise, attempt to add an entry for it, with the specified
- * ifnet flags and description, and, if that succeeds, return 0
- * and set *curdev_ret to point to the new entry, otherwise
- * return PCAP_ERROR and set errbuf to an error message.
+ * If we don't find it, attempt to add an entry for it, with the specified
+ * flags and description, and, if that succeeds, return 0, otherwise
+ * return -1 and set errbuf to an error message.
*/
-int
-pcap_add_if(pcap_if_t **devlist, const char *name, u_int flags,
+pcap_if_t *
+find_or_add_dev(pcap_if_t **alldevs, const char *name, bpf_u_int32 flags,
const char *description, char *errbuf)
{
pcap_if_t *curdev;
- return (add_or_find_if(&curdev, devlist, name, flags, description,
- errbuf));
+ /*
+ * Is there already an entry in the list for this interface?
+ */
+ for (curdev = *alldevs; curdev != NULL; curdev = curdev->next) {
+ if (strcmp(name, curdev->name) == 0) {
+ /*
+ * We found it, so, yes, there is. No need to
+ * add it. Provide the entry we found to our
+ * caller.
+ */
+ return (curdev);
+ }
+ }
+
+ /*
+ * No, we didn't find it. Try to add it to the list of devices.
+ */
+ return (add_dev(alldevs, name, flags, description, errbuf));
}
+/*
+ * Attempt to add an entry for a device, with the specified flags
+ * and description, and, if that succeeds, return 0 and return a pointer
+ * to the new entry, otherwise return NULL and set errbuf to an error
+ * message.
+ *
+ * If we weren't given a description, try to get one.
+ */
+pcap_if_t *
+add_dev(pcap_if_t **alldevs, const char *name, bpf_u_int32 flags,
+ const char *description, char *errbuf)
+{
+ pcap_if_t *curdev, *prevdev, *nextdev;
+ u_int this_figure_of_merit, nextdev_figure_of_merit;
+
+ curdev = malloc(sizeof(pcap_if_t));
+ if (curdev == NULL) {
+ (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "malloc: %s", pcap_strerror(errno));
+ return (NULL);
+ }
+
+ /*
+ * Fill in the entry.
+ */
+ curdev->next = NULL;
+ curdev->name = strdup(name);
+ if (curdev->name == NULL) {
+ (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "malloc: %s", pcap_strerror(errno));
+ free(curdev);
+ return (NULL);
+ }
+ if (description == NULL) {
+ /*
+ * We weren't handed a description for the interface.
+ */
+ curdev->description = NULL;
+ } else {
+ /*
+ * We were handed a description; make a copy.
+ */
+ curdev->description = strdup(description);
+ if (curdev->description == NULL) {
+ (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "malloc: %s", pcap_strerror(errno));
+ free(curdev->name);
+ free(curdev);
+ return (NULL);
+ }
+ }
+ curdev->addresses = NULL; /* list starts out as empty */
+ curdev->flags = flags;
+
+ /*
+ * Add it to the list, in the appropriate location.
+ * First, get the "figure of merit" for this interface.
+ */
+ this_figure_of_merit = get_figure_of_merit(curdev);
+
+ /*
+ * Now look for the last interface with an figure of merit
+ * less than or equal to the new interface's figure of merit.
+ *
+ * We start with "prevdev" being NULL, meaning we're before
+ * the first element in the list.
+ */
+ prevdev = NULL;
+ for (;;) {
+ /*
+ * Get the interface after this one.
+ */
+ if (prevdev == NULL) {
+ /*
+ * The next element is the first element.
+ */
+ nextdev = *alldevs;
+ } else
+ nextdev = prevdev->next;
+
+ /*
+ * Are we at the end of the list?
+ */
+ if (nextdev == NULL) {
+ /*
+ * Yes - we have to put the new entry after "prevdev".
+ */
+ break;
+ }
+
+ /*
+ * Is the new interface's figure of merit less
+ * than the next interface's figure of merit,
+ * meaning that the new interface is better
+ * than the next interface?
+ */
+ nextdev_figure_of_merit = get_figure_of_merit(nextdev);
+ if (this_figure_of_merit < nextdev_figure_of_merit) {
+ /*
+ * Yes - we should put the new entry
+ * before "nextdev", i.e. after "prevdev".
+ */
+ break;
+ }
+
+ prevdev = nextdev;
+ }
+
+ /*
+ * Insert before "nextdev".
+ */
+ curdev->next = nextdev;
+
+ /*
+ * Insert after "prevdev" - unless "prevdev" is null,
+ * in which case this is the first interface.
+ */
+ if (prevdev == NULL) {
+ /*
+ * This is the first interface. Pass back a
+ * pointer to it, and put "curdev" before
+ * "nextdev".
+ */
+ *alldevs = curdev;
+ } else
+ prevdev->next = curdev;
+ return (curdev);
+}
/*
* Free a list of interfaces.
memcpy(name, usbus_prefix, USBUS_PREFIX_LEN);
memcpy(name + USBUS_PREFIX_LEN, usbitem->d_name, busnumlen);
*(name + USBUS_PREFIX_LEN + busnumlen) = '\0';
- err = pcap_add_if(alldevsp, name, PCAP_IF_UP, NULL, errbuf);
- if (err != 0) {
+ if (add_dev(alldevsp, name, PCAP_IF_UP, NULL, errbuf) == NULL) {
free(name);
closedir(usbdir);
- return (err);
+ return (PCAP_ERROR);
}
}
free(name);
pcap_snprintf(dev_name, 20, BT_IFACE"%d", dev_req->dev_id);
pcap_snprintf(dev_descr, 30, "Bluetooth adapter number %d", i);
- if (pcap_add_if(alldevsp, dev_name, 0,
- dev_descr, err_str) < 0)
+ if (add_dev(alldevsp, dev_name, 0, dev_descr, err_str) == NULL)
{
ret = -1;
break;
{
int ret = 0;
- if (pcap_add_if(alldevsp, INTERFACE_NAME, 0,
- "Bluetooth Linux Monitor", err_str) < 0)
+ if (add_dev(alldevsp, INTERFACE_NAME, 0,
+ "Bluetooth Linux Monitor", err_str) == NULL)
{
ret = -1;
}
}
/*
- * Previously we just generated a list of all possible names and let
- * pcap_add_if() attempt to open each one, but with streams this adds up
- * to 81 possibilities which is inefficient.
- *
- * Since we know more about the devices we can prune the tree here.
- * pcap_add_if() will still retest each device but the total number of
- * open attempts will still be much less than the naive approach.
+ * Add all DAG devices.
*/
int
dag_findalldevs(pcap_if_t **devlistp, char *errbuf)
pcap_snprintf(name, 12, "dag%d", c);
if (-1 == dag_parse_name(name, dagname, DAGNAME_BUFSIZE, &dagstream))
{
+ (void) pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "dag: device name %s can't be parsed", name);
return -1;
}
- description = NULL;
if ( (dagfd = dag_open(dagname)) >= 0 ) {
+ description = NULL;
if ((inf = dag_pciinfo(dagfd)))
description = dag_device_name(inf->device_code, 1);
- if (pcap_add_if(devlistp, name, 0, description, errbuf) == -1) {
+ if (add_dev(devlistp, name, 0, description, errbuf) == NULL) {
/*
* Failure.
*/
dag_detach_stream(dagfd, stream);
pcap_snprintf(name, 10, "dag%d:%d", c, stream);
- if (pcap_add_if(devlistp, name, 0, description, errbuf) == -1) {
+ if (add_dev(devlistp, name, 0, description, errbuf) == NULL) {
/*
* Failure.
*/
int
dbus_findalldevs(pcap_if_t **alldevsp, char *err_str)
{
- if (pcap_add_if(alldevsp, "dbus-system", 0, "D-Bus system bus", err_str) < 0)
+ if (add_dev(alldevsp, "dbus-system", 0, "D-Bus system bus", err_str) == NULL)
return -1;
- if (pcap_add_if(alldevsp, "dbus-session", 0, "D-Bus session bus", err_str) < 0)
+ if (add_dev(alldevsp, "dbus-session", 0, "D-Bus session bus", err_str) == NULL)
return -1;
return 0;
}
}
for (i = 0; i < buf.nunits; i++) {
pcap_snprintf(baname, sizeof baname, "ba%u", i);
- if (pcap_add_if(alldevsp, baname, 0, NULL, errbuf) < 0)
+ if (add_dev(alldevsp, baname, 0, NULL, errbuf) == NULL)
return (-1);
}
#endif
broadaddr = (struct sockaddr*) &sa_ll_2;
memset (&sa_ll_2.sin_addr, 0xFF, sizeof(sa_ll_2.sin_addr));
- if (pcap_add_if(&devlist, dev->name, dev->flags,
- dev->long_name, errbuf) < 0)
+ if (add_dev(&devlist, dev->name, dev->flags,
+ dev->long_name, errbuf) == NULL)
{
ret = -1;
break;
}
#if 0 /* Pkt drivers should have no addresses */
- if (add_addr_to_iflist(&devlist, dev->name, dev->flags, addr, addr_size,
- netmask, addr_size, broadaddr, addr_size,
- dstaddr, addr_size, errbuf) < 0)
+ if (add_addr_to_dev(curdev, addr, addr_size,
+ netmask, addr_size, broadaddr, addr_size,
+ dstaddr, addr_size, errbuf) < 0)
{
ret = -1;
break;
int pcap_findalldevs_interfaces(pcap_if_t **, char *,
int (*)(const char *));
#endif
-int add_addr_to_iflist(pcap_if_t **, const char *, bpf_u_int32,
- struct sockaddr *, size_t, struct sockaddr *, size_t,
- struct sockaddr *, size_t, struct sockaddr *, size_t, char *);
+pcap_if_t *find_or_add_dev(pcap_if_t **, const char *, bpf_u_int32,
+ const char *, char *);
+pcap_if_t *add_dev(pcap_if_t **, const char *, bpf_u_int32, const char *,
+ char *);
int add_addr_to_dev(pcap_if_t *, struct sockaddr *, size_t,
struct sockaddr *, size_t, struct sockaddr *, size_t,
struct sockaddr *dstaddr, size_t, char *errbuf);
-int pcap_add_if(pcap_if_t **, const char *, bpf_u_int32, const char *,
- char *);
-int add_or_find_if(pcap_if_t **, pcap_if_t **, const char *, bpf_u_int32,
- const char *, char *);
#ifndef _WIN32
bpf_u_int32 if_flags_to_pcap_flags(const char *, u_int);
+int add_addr_to_iflist(pcap_if_t **, const char *, bpf_u_int32,
+ struct sockaddr *, size_t, struct sockaddr *, size_t,
+ struct sockaddr *, size_t, struct sockaddr *, size_t, char *);
#endif
/*
/* dlpi_walk() for loopback will be added here. */
+ /*
+ * Find all DLPI devices in the current zone.
+ *
+ * XXX - will pcap_findalldevs_interfaces() find any devices
+ * outside the current zone? If not, the only reason to call
+ * it would be to get the interface addresses.
+ */
dlpi_walk(list_interfaces, &lw, 0);
if (lw.lw_err != 0) {
/* Add linkname if it does not exist on the list. */
for (entry = lw.lw_list; entry != NULL; entry = entry->lnl_next) {
- if (pcap_add_if(alldevsp, entry->linkname, 0, NULL, errbuf) < 0)
+ /*
+ * If it isn't already in the list of devices, try to
+ * add it.
+ */
+ if (find_or_add_dev(alldevsp, entry->linkname, 0, NULL, errbuf) == NULL)
retv = -1;
}
done:
}
/*
- * Add an entry for this interface, with no addresses.
+ * Add an entry for this interface, with no addresses, if it's
+ * not already in the list.
*/
- if (pcap_add_if(devlistp, name,
+ if (find_or_add_dev(devlistp, name,
if_flags_to_pcap_flags(name, ifrflags.ifr_flags), NULL,
- errbuf) == -1) {
+ errbuf) == NULL) {
/*
* Failure.
*/
/*
* Add the "any" device.
*/
- if (pcap_add_if(alldevsp, "any", PCAP_IF_UP|PCAP_IF_RUNNING,
- any_descr, errbuf) < 0)
+ if (add_dev(alldevsp, "any", PCAP_IF_UP|PCAP_IF_RUNNING,
+ any_descr, errbuf) == NULL)
return (-1);
return (0);
}
close(sock);
- if (pcap_add_if(alldevsp, NFLOG_IFACE, 0, "Linux netfilter log (NFLOG) interface", err_str) < 0)
+ if (add_dev(alldevsp, NFLOG_IFACE, 0, "Linux netfilter log (NFLOG) interface", err_str) == NULL)
return -1;
- if (pcap_add_if(alldevsp, NFQUEUE_IFACE, 0, "Linux netfilter queue (NFQUEUE) interface", err_str) < 0)
+ if (add_dev(alldevsp, NFQUEUE_IFACE, 0, "Linux netfilter queue (NFQUEUE) interface", err_str) == NULL)
return -1;
return 0;
}
int
septel_findalldevs(pcap_if_t **devlistp, char *errbuf)
{
- return (pcap_add_if(devlistp,"septel",0,
- "Intel/Septel device",errbuf));
+ if (add_dev(devlistp,"septel",0,"Intel/Septel device",errbuf) == NULL)
+ return -1;
+ return 0;
}
pcap_snprintf(dev_name, 10, USB_IFACE"%d", n);
pcap_snprintf(dev_descr, 30, "USB bus number %d", n);
- if (pcap_add_if(alldevsp, dev_name, 0,
- dev_descr, err_str) < 0)
+ if (add_dev(alldevsp, dev_name, 0, dev_descr, err_str) == NULL)
return -1;
return 0;
}
* Yes.
*/
close(fd);
- if (pcap_add_if(alldevsp, "usbmon0", 0, "All USB buses",
- err_str) < 0)
+ if (add_dev(alldevsp, "usbmon0", 0, "All USB buses",
+ err_str) == NULL)
return -1;
} else {
/*
* We found it.
*/
close(fd);
- if (pcap_add_if(alldevsp, "usbmon0", 0, "All USB buses",
- err_str) < 0)
+ if (add_dev(alldevsp, "usbmon0", 0, "All USB buses",
+ err_str) == NULL)
return -1;
}
}
/*
* Add an entry for this interface, with no addresses.
*/
- if (add_or_find_if(&curdev, devlist, name, flags, description,
- errbuf) == -1) {
+ curdev = add_dev(devlist, name, flags, description, errbuf);
+ if (curdev == NULL) {
/*
* Failure.
*/
* "curdev" is an entry for this interface; add an entry for
* this address to its list of addresses.
*/
- if(curdev == NULL)
- break;
res = add_addr_to_dev(curdev,
(struct sockaddr *)&if_addrs[if_addr_size].IPAddress,
sizeof (struct sockaddr_storage),