Add interface description capability as inspired by OpenBSD.

MFC after:	3 months
This commit is contained in:
Xin LI 2009-11-11 21:30:58 +00:00
parent f140aad88c
commit 41c8c6e876
11 changed files with 146 additions and 8 deletions

View File

@ -403,22 +403,30 @@ add_addr_to_iflist(pcap_if_t **alldevs, const char *name, u_int flags,
pcap_addr_t *curaddr, *prevaddr, *nextaddr; pcap_addr_t *curaddr, *prevaddr, *nextaddr;
#ifdef SIOCGIFDESCR #ifdef SIOCGIFDESCR
struct ifreq ifrdesc; struct ifreq ifrdesc;
#ifdef __FreeBSD__
#define _IFDESCRSIZE 64
char ifdescr[_IFDESCRSIZE];
#else
char ifdescr[IFDESCRSIZE]; char ifdescr[IFDESCRSIZE];
int s;
#endif #endif
int s;
#ifdef SIOCGIFDESCR
/* /*
* Get the description for the interface. * Get the description for the interface.
*/ */
memset(&ifrdesc, 0, sizeof ifrdesc); memset(&ifrdesc, 0, sizeof ifrdesc);
strlcpy(ifrdesc.ifr_name, name, sizeof ifrdesc.ifr_name); strlcpy(ifrdesc.ifr_name, name, sizeof ifrdesc.ifr_name);
#ifdef __FreeBSD__
ifrdesc.ifr_buffer.buffer = ifdescr;
ifrdesc.ifr_buffer.length = _IFDESCRSIZE;
#else
ifrdesc.ifr_data = (caddr_t)&ifdescr; ifrdesc.ifr_data = (caddr_t)&ifdescr;
#endif
s = socket(AF_INET, SOCK_DGRAM, 0); s = socket(AF_INET, SOCK_DGRAM, 0);
if (s >= 0) { if (s >= 0) {
if (ioctl(s, SIOCGIFDESCR, &ifrdesc) == 0 && if (ioctl(s, SIOCGIFDESCR, &ifrdesc) == 0 &&
strlen(ifrdesc.ifr_data) != 0) strlen(ifdescr) != 0)
description = ifrdesc.ifr_data; description = ifdescr;
close(s); close(s);
} }
#endif #endif

View File

@ -28,7 +28,7 @@
.\" From: @(#)ifconfig.8 8.3 (Berkeley) 1/5/94 .\" From: @(#)ifconfig.8 8.3 (Berkeley) 1/5/94
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd September 23, 2009 .Dd November 11, 2009
.Dt IFCONFIG 8 .Dt IFCONFIG 8
.Os .Os
.Sh NAME .Sh NAME
@ -258,6 +258,12 @@ Disable permanently promiscuous mode.
Another name for the Another name for the
.Fl alias .Fl alias
parameter. parameter.
.It Cm description Ar value
Specify a description of the interface.
This can be used to label interfaces in situations where they may
otherwise be difficult to distinguish.
.It Cm -description
Clear the interface description.
.It Cm down .It Cm down
Mark an interface Mark an interface
.Dq down . .Dq down .
@ -2512,6 +2518,10 @@ Configure the interface
to use 100baseTX, full duplex Ethernet media options: to use 100baseTX, full duplex Ethernet media options:
.Dl # ifconfig xl0 media 100baseTX mediaopt full-duplex .Dl # ifconfig xl0 media 100baseTX mediaopt full-duplex
.Pp .Pp
Label the em0 interface as an uplink:
.Pp
.Dl # ifconfig em0 description \&"Uplink to Gigabit Switch 2\&"
.Pp
Create the software network interface Create the software network interface
.Li gif1 : .Li gif1 :
.Dl # ifconfig gif1 create .Dl # ifconfig gif1 create

View File

@ -83,6 +83,8 @@ static const char rcsid[] =
struct ifreq ifr; struct ifreq ifr;
char name[IFNAMSIZ]; char name[IFNAMSIZ];
char *descr = NULL;
size_t descrlen = 64;
int setaddr; int setaddr;
int setmask; int setmask;
int doalias; int doalias;
@ -822,6 +824,36 @@ setifname(const char *val, int dummy __unused, int s,
free(newname); free(newname);
} }
/* ARGSUSED */
static void
setifdescr(const char *val, int dummy __unused, int s,
const struct afswtch *afp)
{
char *newdescr;
newdescr = strdup(val);
if (newdescr == NULL) {
warn("no memory to set ifdescr");
return;
}
ifr.ifr_buffer.buffer = newdescr;
ifr.ifr_buffer.length = strlen(newdescr);
if (ioctl(s, SIOCSIFDESCR, (caddr_t)&ifr) < 0) {
warn("ioctl (set descr)");
free(newdescr);
return;
}
free(newdescr);
}
/* ARGSUSED */
static void
unsetifdescr(const char *val, int value, int s, const struct afswtch *afp)
{
setifdescr("", 0, s, 0);
}
#define IFFBITS \ #define IFFBITS \
"\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6SMART\7RUNNING" \ "\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6SMART\7RUNNING" \
"\10NOARP\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2" \ "\10NOARP\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2" \
@ -866,6 +898,23 @@ status(const struct afswtch *afp, const struct sockaddr_dl *sdl,
printf(" mtu %d", ifr.ifr_mtu); printf(" mtu %d", ifr.ifr_mtu);
putchar('\n'); putchar('\n');
descr = reallocf(descr, descrlen);
if (descr != NULL) {
do {
ifr.ifr_buffer.buffer = descr;
ifr.ifr_buffer.length = descrlen;
if (ioctl(s, SIOCGIFDESCR, &ifr) == 0) {
if (strlen(descr) > 0)
printf("\tdescription: %s\n", descr);
break;
}
if (errno == ENAMETOOLONG) {
descrlen *= 2;
descr = reallocf(descr, descrlen);
}
} while (errno == ENAMETOOLONG);
}
if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) == 0) { if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) == 0) {
if (ifr.ifr_curcap != 0) { if (ifr.ifr_curcap != 0) {
printb("\toptions", ifr.ifr_curcap, IFCAPBITS); printb("\toptions", ifr.ifr_curcap, IFCAPBITS);
@ -1035,6 +1084,10 @@ static struct cmd basic_cmds[] = {
DEF_CMD("-arp", IFF_NOARP, setifflags), DEF_CMD("-arp", IFF_NOARP, setifflags),
DEF_CMD("debug", IFF_DEBUG, setifflags), DEF_CMD("debug", IFF_DEBUG, setifflags),
DEF_CMD("-debug", -IFF_DEBUG, setifflags), DEF_CMD("-debug", -IFF_DEBUG, setifflags),
DEF_CMD_ARG("description", setifdescr),
DEF_CMD_ARG("descr", setifdescr),
DEF_CMD("-description", 0, unsetifdescr),
DEF_CMD("-descr", 0, unsetifdescr),
DEF_CMD("promisc", IFF_PPROMISC, setifflags), DEF_CMD("promisc", IFF_PPROMISC, setifflags),
DEF_CMD("-promisc", -IFF_PPROMISC, setifflags), DEF_CMD("-promisc", -IFF_PPROMISC, setifflags),
DEF_CMD("add", IFF_UP, notealias), DEF_CMD("add", IFF_UP, notealias),

View File

@ -32,7 +32,7 @@
.\" @(#)netintro.4 8.2 (Berkeley) 11/30/93 .\" @(#)netintro.4 8.2 (Berkeley) 11/30/93
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd June 18, 2004 .Dd November 11, 2009
.Dt NETINTRO 4 .Dt NETINTRO 4
.Os .Os
.Sh NAME .Sh NAME
@ -277,6 +277,25 @@ and
fields of the fields of the
.Vt ifreq .Vt ifreq
structure, respectively. structure, respectively.
.It Dv SIOCGIFDESCR
Get the interface description, returned in the
.Va buffer
field of
.Va ifru_buffer
struct.
The user supplied buffer length should defined in the
.Va length
field of
.Va ifru_buffer
struct passed in as parameter.
.It Dv SIOCSIFDESCR
Set the interface description to the value of the
.Va buffer
field of
.Va ifru_buffer
struct, with
.Va length
field specifying its length.
.It Dv SIOCSIFFLAGS .It Dv SIOCSIFFLAGS
Set interface flags field. Set interface flags field.
If the interface is marked down, If the interface is marked down,

View File

@ -3467,6 +3467,7 @@ prison_priv_check(struct ucred *cred, int priv)
case PRIV_NET_SETIFMTU: case PRIV_NET_SETIFMTU:
case PRIV_NET_SETIFFLAGS: case PRIV_NET_SETIFFLAGS:
case PRIV_NET_SETIFCAP: case PRIV_NET_SETIFCAP:
case PRIV_NET_SETIFDESCR:
case PRIV_NET_SETIFNAME : case PRIV_NET_SETIFNAME :
case PRIV_NET_SETIFMETRIC: case PRIV_NET_SETIFMETRIC:
case PRIV_NET_SETIFPHYS: case PRIV_NET_SETIFPHYS:

View File

@ -463,6 +463,8 @@ if_free_internal(struct ifnet *ifp)
#ifdef MAC #ifdef MAC
mac_ifnet_destroy(ifp); mac_ifnet_destroy(ifp);
#endif /* MAC */ #endif /* MAC */
if (ifp->if_description != NULL)
sbuf_delete(ifp->if_description);
IF_AFDATA_DESTROY(ifp); IF_AFDATA_DESTROY(ifp);
IF_ADDR_LOCK_DESTROY(ifp); IF_ADDR_LOCK_DESTROY(ifp);
ifq_delete(&ifp->if_snd); ifq_delete(&ifp->if_snd);
@ -2090,6 +2092,45 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
ifr->ifr_phys = ifp->if_physical; ifr->ifr_phys = ifp->if_physical;
break; break;
case SIOCGIFDESCR:
IF_AFDATA_RLOCK(ifp);
if (ifp->if_description == NULL)
error = ENOMSG;
else
error = copystr(sbuf_data(ifp->if_description),
ifr->ifr_buffer.buffer,
ifr->ifr_buffer.length, NULL);
IF_AFDATA_RUNLOCK(ifp);
break;
case SIOCSIFDESCR:
error = priv_check(td, PRIV_NET_SETIFDESCR);
if (error)
return (error);
IF_AFDATA_WLOCK(ifp);
if (ifp->if_description == NULL) {
ifp->if_description = sbuf_new_auto();
if (ifp->if_description == NULL) {
error = ENOMEM;
IF_AFDATA_WUNLOCK(ifp);
break;
}
} else
sbuf_clear(ifp->if_description);
if (sbuf_copyin(ifp->if_description, ifr->ifr_buffer.buffer,
ifr->ifr_buffer.length) == -1)
error = EFAULT;
if (error == 0) {
sbuf_finish(ifp->if_description);
getmicrotime(&ifp->if_lastchange);
}
IF_AFDATA_WUNLOCK(ifp);
break;
case SIOCSIFFLAGS: case SIOCSIFFLAGS:
error = priv_check(td, PRIV_NET_SETIFFLAGS); error = priv_check(td, PRIV_NET_SETIFFLAGS);
if (error) if (error)

View File

@ -294,6 +294,7 @@ struct ifreq {
struct sockaddr ifru_addr; struct sockaddr ifru_addr;
struct sockaddr ifru_dstaddr; struct sockaddr ifru_dstaddr;
struct sockaddr ifru_broadaddr; struct sockaddr ifru_broadaddr;
struct { size_t length; caddr_t buffer; } ifru_buffer;
short ifru_flags[2]; short ifru_flags[2];
short ifru_index; short ifru_index;
int ifru_jid; int ifru_jid;
@ -307,6 +308,7 @@ struct ifreq {
#define ifr_addr ifr_ifru.ifru_addr /* address */ #define ifr_addr ifr_ifru.ifru_addr /* address */
#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-to-p link */ #define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-to-p link */
#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */ #define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
#define ifr_buffer ifr_ifru.ifru_buffer /* user supplied buffer with its length */
#define ifr_flags ifr_ifru.ifru_flags[0] /* flags (low 16 bits) */ #define ifr_flags ifr_ifru.ifru_flags[0] /* flags (low 16 bits) */
#define ifr_flagshigh ifr_ifru.ifru_flags[1] /* flags (high 16 bits) */ #define ifr_flagshigh ifr_ifru.ifru_flags[1] /* flags (high 16 bits) */
#define ifr_jid ifr_ifru.ifru_jid /* jail/vnet */ #define ifr_jid ifr_ifru.ifru_jid /* jail/vnet */

View File

@ -198,6 +198,7 @@ struct ifnet {
void *if_pf_kif; void *if_pf_kif;
void *if_lagg; /* lagg glue */ void *if_lagg; /* lagg glue */
u_char if_alloctype; /* if_type at time of allocation */ u_char if_alloctype; /* if_type at time of allocation */
struct sbuf *if_description; /* interface description */
/* /*
* Spare fields are added so that we can modify sensitive data * Spare fields are added so that we can modify sensitive data
@ -205,7 +206,7 @@ struct ifnet {
* be used with care where binary compatibility is required. * be used with care where binary compatibility is required.
*/ */
char if_cspare[3]; char if_cspare[3];
void *if_pspare[8]; void *if_pspare[7];
int if_ispare[4]; int if_ispare[4];
}; };

View File

@ -58,7 +58,7 @@
* in the range 5 to 9. * in the range 5 to 9.
*/ */
#undef __FreeBSD_version #undef __FreeBSD_version
#define __FreeBSD_version 900002 /* Master, propagated to newvers */ #define __FreeBSD_version 900003 /* Master, propagated to newvers */
#ifndef LOCORE #ifndef LOCORE
#include <sys/types.h> #include <sys/types.h>

View File

@ -335,6 +335,7 @@
#define PRIV_NET_LAGG 415 /* Administer lagg interface. */ #define PRIV_NET_LAGG 415 /* Administer lagg interface. */
#define PRIV_NET_GIF 416 /* Administer gif interface. */ #define PRIV_NET_GIF 416 /* Administer gif interface. */
#define PRIV_NET_SETIFVNET 417 /* Move interface to vnet. */ #define PRIV_NET_SETIFVNET 417 /* Move interface to vnet. */
#define PRIV_NET_SETIFDESCR 418 /* Set interface description. */
/* /*
* 802.11-related privileges. * 802.11-related privileges.

View File

@ -82,6 +82,8 @@
#define SIOCGIFMAC _IOWR('i', 38, struct ifreq) /* get IF MAC label */ #define SIOCGIFMAC _IOWR('i', 38, struct ifreq) /* get IF MAC label */
#define SIOCSIFMAC _IOW('i', 39, struct ifreq) /* set IF MAC label */ #define SIOCSIFMAC _IOW('i', 39, struct ifreq) /* set IF MAC label */
#define SIOCSIFNAME _IOW('i', 40, struct ifreq) /* set IF name */ #define SIOCSIFNAME _IOW('i', 40, struct ifreq) /* set IF name */
#define SIOCSIFDESCR _IOW('i', 41, struct ifreq) /* set ifnet descr */
#define SIOCGIFDESCR _IOWR('i', 42, struct ifreq) /* get ifnet descr */
#define SIOCADDMULTI _IOW('i', 49, struct ifreq) /* add m'cast addr */ #define SIOCADDMULTI _IOW('i', 49, struct ifreq) /* add m'cast addr */
#define SIOCDELMULTI _IOW('i', 50, struct ifreq) /* del m'cast addr */ #define SIOCDELMULTI _IOW('i', 50, struct ifreq) /* del m'cast addr */