Move list_cloners to libifconfig

Move list_cloners() from ifconfig(8) to libifconfig(3) where it can be
reused by other consumers.

Reviewed by:	kp
Differential Revision:	https://reviews.freebsd.org/D26858
This commit is contained in:
Ryan Moeller 2020-10-21 05:27:25 +00:00
parent c0b5fcf692
commit 0710ec8cef
3 changed files with 58 additions and 33 deletions

View File

@ -628,3 +628,35 @@ ifconfig_set_vlantag(ifconfig_handle_t *h, const char *name,
}
return (0);
}
int
ifconfig_list_cloners(ifconfig_handle_t *h, char **bufp, size_t *lenp)
{
struct if_clonereq ifcr;
char *buf;
memset(&ifcr, 0, sizeof(ifcr));
*bufp = NULL;
*lenp = 0;
if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCIFGCLONERS, &ifcr) < 0)
return (-1);
buf = malloc(ifcr.ifcr_total * IFNAMSIZ);
if (buf == NULL) {
h->error.errtype = OTHER;
h->error.errcode = ENOMEM;
return (-1);
}
ifcr.ifcr_count = ifcr.ifcr_total;
ifcr.ifcr_buffer = buf;
if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCIFGCLONERS, &ifcr) < 0) {
free(buf);
return (-1);
}
*bufp = buf;
*lenp = ifcr.ifcr_total;
return (0);
}

View File

@ -279,3 +279,13 @@ int ifconfig_create_interface_vlan(ifconfig_handle_t *h, const char *name,
int ifconfig_set_vlantag(ifconfig_handle_t *h, const char *name,
const char *vlandev, const unsigned short vlantag);
/** Gets the names of all interface cloners available on the system
* @param bufp Set to the address of the names buffer on success or NULL
* if an error occurs. This buffer must be freed when done.
* @param lenp Set to the number of names in the returned buffer or 0
* if an error occurs. Each name is contained within an
* IFNAMSIZ length slice of the buffer, for a total buffer
* length of *lenp * IFNAMSIZ bytes.
*/
int ifconfig_list_cloners(ifconfig_handle_t *h, char **bufp, size_t *lenp);

View File

@ -41,6 +41,7 @@ static const char rcsid[] =
#include <net/if.h>
#include <err.h>
#include <libifconfig.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -51,45 +52,27 @@ static const char rcsid[] =
static void
list_cloners(void)
{
struct if_clonereq ifcr;
char *cp, *buf;
int idx;
int s;
ifconfig_handle_t *lifh;
char *cloners;
size_t cloners_count;
s = socket(AF_LOCAL, SOCK_DGRAM, 0);
if (s == -1)
err(1, "socket(AF_LOCAL,SOCK_DGRAM)");
lifh = ifconfig_open();
if (lifh == NULL)
return;
memset(&ifcr, 0, sizeof(ifcr));
if (ifconfig_list_cloners(lifh, &cloners, &cloners_count) < 0)
errc(1, ifconfig_err_errno(lifh), "unable to list cloners");
ifconfig_close(lifh);
if (ioctl(s, SIOCIFGCLONERS, &ifcr) < 0)
err(1, "SIOCIFGCLONERS for count");
buf = malloc(ifcr.ifcr_total * IFNAMSIZ);
if (buf == NULL)
err(1, "unable to allocate cloner name buffer");
ifcr.ifcr_count = ifcr.ifcr_total;
ifcr.ifcr_buffer = buf;
if (ioctl(s, SIOCIFGCLONERS, &ifcr) < 0)
err(1, "SIOCIFGCLONERS for names");
/*
* In case some disappeared in the mean time, clamp it down.
*/
if (ifcr.ifcr_count > ifcr.ifcr_total)
ifcr.ifcr_count = ifcr.ifcr_total;
for (cp = buf, idx = 0; idx < ifcr.ifcr_count; idx++, cp += IFNAMSIZ) {
if (idx > 0)
for (const char *name = cloners;
name < cloners + cloners_count * IFNAMSIZ;
name += IFNAMSIZ) {
if (name > cloners)
putchar(' ');
printf("%s", cp);
printf("%s", name);
}
putchar('\n');
free(buf);
close(s);
free(cloners);
}
struct clone_defcb {