Project

General

Profile

Bug #3306 » 01-if-descr.patch

tuxillo, 11/12/2021 04:49 PM

View differences:

sbin/ifconfig/ifconfig.8
28 28
.\"     From: @(#)ifconfig.8	8.3 (Berkeley) 1/5/94
29 29
.\" $FreeBSD: src/sbin/ifconfig/ifconfig.8,v 1.124 2006/10/10 09:44:08 ru Exp $
30 30
.\"
31
.Dd June 26, 2020
31
.Dd November 13, 2021
32 32
.Dt IFCONFIG 8
33 33
.Os
34 34
.Sh NAME
......
341 341
Another name for the
342 342
.Fl alias
343 343
parameter.
344
.It Cm description Ar value , Cm descr Ar value
345
Specify a description of the interface.
346
This can be used to label interfaces in situations where they may
347
otherwise be difficult to distinguish.
348
.It Cm -description , Cm -descr
349
Clear the interface description.
344 350
.It Cm down
345 351
Mark an interface
346 352
.Dq down .
sbin/ifconfig/ifconfig.c
74 74
struct	ifreq ifr;
75 75

  
76 76
char	name[IFNAMSIZ];
77
char	*descr = NULL;
78
size_t	descrlen = 64;
77 79
int	setaddr;
78 80
int	setmask;
79 81
int	doalias;
......
1166 1168
	setifflags("npolling", IFF_NPOLLING, s, afp);
1167 1169
}
1168 1170

  
1171
/* ARGSUSED */
1172
static void
1173
setifdescr(const char *val, int dummy __unused, int s,
1174
    const struct afswtch *afp)
1175
{
1176
	char *newdescr;
1177

  
1178
	ifr.ifr_buffer.length = strlen(val) + 1;
1179
	if (ifr.ifr_buffer.length == 1) {
1180
		ifr.ifr_buffer.buffer = newdescr = NULL;
1181
		ifr.ifr_buffer.length = 0;
1182
	} else {
1183
		newdescr = strdup(val);
1184
		ifr.ifr_buffer.buffer = newdescr;
1185
		if (newdescr == NULL) {
1186
			warn("no memory to set ifdescr");
1187
			return;
1188
		}
1189
	}
1190

  
1191
	if (ioctl(s, SIOCSIFDESCR, (caddr_t)&ifr) < 0)
1192
		warn("ioctl (set descr)");
1193

  
1194
	free(newdescr);
1195
}
1196

  
1197
/* ARGSUSED */
1198
static void
1199
unsetifdescr(const char *val, int value, int s, const struct afswtch *afp)
1200
{
1201
	setifdescr("", 0, s, 0);
1202
}
1169 1203

  
1170 1204
#define	IFFBITS \
1171 1205
"\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6SMART\7RUNNING" \
......
1210 1244
		printf(" mtu %d", ifr.ifr_mtu);
1211 1245
	putchar('\n');
1212 1246

  
1247
	for (;;) {
1248
		if ((descr = reallocf(descr, descrlen)) != NULL) {
1249
			ifr.ifr_buffer.buffer = descr;
1250
			ifr.ifr_buffer.length = descrlen;
1251
			if (ioctl(s, SIOCGIFDESCR, &ifr) == 0) {
1252
				if (ifr.ifr_buffer.buffer == descr) {
1253
					if (strlen(descr) > 0)
1254
						printf("\tdescription: %s\n",
1255
						    descr);
1256
				} else if (ifr.ifr_buffer.length > descrlen) {
1257
					descrlen = ifr.ifr_buffer.length;
1258
					continue;
1259
				}
1260
			}
1261
		} else
1262
			warn("unable to allocate memory for interface"
1263
			    "description");
1264
		break;
1265
	}
1266

  
1213 1267
	if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) == 0) {
1214 1268
		if (ifr.ifr_curcap != 0) {
1215 1269
			printb("\toptions", ifr.ifr_curcap, IFCAPBITS);
......
1385 1439
	DEF_CMD("-arp",		IFF_NOARP,	setifflags),
1386 1440
	DEF_CMD("debug",	IFF_DEBUG,	setifflags),
1387 1441
	DEF_CMD("-debug",	-IFF_DEBUG,	setifflags),
1442
	DEF_CMD_ARG("description",		setifdescr),
1443
	DEF_CMD_ARG("descr",			setifdescr),
1444
	DEF_CMD("-description",	0,		unsetifdescr),
1445
	DEF_CMD("-descr",	0,		unsetifdescr),
1388 1446
	DEF_CMD("promisc",	IFF_PPROMISC,	setifflags),
1389 1447
	DEF_CMD("-promisc",	-IFF_PPROMISC,	setifflags),
1390 1448
	DEF_CMD("add",		IFF_UP,		notealias),
share/man/man4/netintro.4
28 28
.\"     @(#)netintro.4	8.2 (Berkeley) 11/30/93
29 29
.\" $FreeBSD: src/share/man/man4/netintro.4,v 1.10.2.6 2002/08/30 14:23:38 sobomax Exp $
30 30
.\"
31
.Dd March 3, 2020
31
.Dd November 13, 2021
32 32
.Dt NETINTRO 4
33 33
.Os
34 34
.Sh NAME
......
188 188
        struct    sockaddr ifru_addr;
189 189
        struct    sockaddr ifru_dstaddr;
190 190
        struct    sockaddr ifru_broadaddr;
191
        struct    ifreq_buffer ifru_buffer;
191 192
        short     ifru_flags[2];
192 193
        int       ifru_metric;
193 194
        int       ifru_mtu;
......
197 198
#define ifr_addr      ifr_ifru.ifru_addr      /* address */
198 199
#define ifr_dstaddr   ifr_ifru.ifru_dstaddr   /* other end of p-to-p link */
199 200
#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
201
#define ifr_buffer    ifr_ifru.ifru_buffer    /* user supplied buffer with its length */
200 202
#define ifr_flags     ifr_ifru.ifru_flags[0]  /* flags (low 16 bits) */
201 203
#define ifr_flagshigh ifr_ifru.ifru_flags[1]  /* flags (high 16 bits) */
202 204
#define ifr_metric    ifr_ifru.ifru_metric    /* metric */
......
231 233
Get point to point address for protocol family and interface.
232 234
.It Dv SIOCGIFBRDADDR
233 235
Get broadcast address for protocol family and interface.
236
.It Dv SIOCGIFDESCR
237
Get the interface description, returned in the
238
.Va buffer
239
field of
240
.Va ifru_buffer
241
struct.
242
The user supplied buffer length should be defined in the
243
.Va length
244
field of
245
.Va ifru_buffer
246
struct passed in as parameter, and the length would include
247
the terminating nul character.
248
If there is not enough space to hold the interface length,
249
no copy would be done and an
250
error would be returned.
251
The kernel will store the buffer length in the
252
.Va length
253
field upon return, regardless whether the buffer itself is
254
sufficient to hold the data.
255
.It Dv SIOCSIFDESCR
256
Set the interface description to the value of the
257
.Va buffer
258
field of
259
.Va ifru_buffer
260
struct, with
261
.Va length
262
field specifying its length (counting the terminating nul).
234 263
.It Dv SIOCSIFFLAGS
235 264
Set interface flags field.  If the interface is marked down,
236 265
any processes currently routing packets through the interface
......
357 386
        char    *ifcr_buffer;   /* buffer for cloner names */
358 387
};
359 388
.Ed
389
.Bd -literal
390
/* Structure used in SIOCGIFDESCR and SIOCSIFDESCR requests */
391
struct ifreq_buffer {
392
        size_t  length;         /* length of the buffer */
393
        void   *buffer;         /* pointer to userland space buffer */
394
};
395
.Ed
360 396
.Sh SEE ALSO
361 397
.Xr ioctl 2 ,
362 398
.Xr socket 2 ,
sys/net/if.c
161 161
SYSCTL_INT(_net_link_ringmap, OID_AUTO, dump_rdr, CTLFLAG_RW,
162 162
    &if_ringmap_dumprdr, 0, "dump redirect table");
163 163

  
164
/* Interface description */
165
static unsigned int ifdescr_maxlen = 1024;
166
SYSCTL_UINT(_net, OID_AUTO, ifdescr_maxlen, CTLFLAG_RW,
167
	&ifdescr_maxlen, 0,
168
	"administrative maximum length for interface description");
169

  
164 170
SYSINIT(interfaces, SI_SUB_PROTO_IF, SI_ORDER_FIRST, ifinit, NULL);
165 171
SYSINIT(ifnet, SI_SUB_PRE_DRIVERS, SI_ORDER_ANY, ifnetinit, NULL);
166 172

  
......
170 176
MALLOC_DEFINE(M_IFADDR, "ifaddr", "interface address");
171 177
MALLOC_DEFINE(M_IFMADDR, "ether_multi", "link-level multicast address");
172 178
MALLOC_DEFINE(M_IFNET, "ifnet", "interface structure");
179
MALLOC_DEFINE(M_IFDESCR, "ifdescr", "ifnet descriptions");
173 180

  
174 181
int			ifqmaxlen = IFQ_MAXLEN;
175 182
struct ifnethead	ifnet = TAILQ_HEAD_INITIALIZER(ifnet);
......
1911 1918
	short oif_flags;
1912 1919
	int new_flags;
1913 1920
	size_t namelen, onamelen;
1921
	size_t descrlen;
1922
	char *descrbuf, *odescrbuf;
1914 1923
	char new_name[IFNAMSIZ];
1915 1924
	struct ifaddr *ifa;
1916 1925
	struct sockaddr_dl *sdl;
......
1999 2008
	case SIOCSIFPOLLCPU:
2000 2009
		break;
2001 2010

  
2011
	case SIOCGIFDESCR:
2012
		error = 0;
2013
		ifnet_lock();
2014
		if (ifp->if_description == NULL) {
2015
			ifr->ifr_buffer.length = 0;
2016
			error = ENOMSG;
2017
		} else {
2018
			/* space for terminating nul */
2019
			descrlen = strlen(ifp->if_description) + 1;
2020
			if (ifr->ifr_buffer.length < descrlen)
2021
				error = ENAMETOOLONG;
2022
			else
2023
				error = copyout(ifp->if_description,
2024
				    ifr->ifr_buffer.buffer, descrlen);
2025
			ifr->ifr_buffer.length = descrlen;
2026
		}
2027
		ifnet_unlock();
2028
		break;
2029

  
2030
	case SIOCSIFDESCR:
2031
		error = priv_check_cred(cred, PRIV_ROOT, 0);
2032
		if (error)
2033
			break;
2034

  
2035
		/*
2036
		 * Copy only (length-1) bytes to make sure that
2037
		 * if_description is always nul terminated.  The
2038
		 * length parameter is supposed to count the
2039
		 * terminating nul in.
2040
		 */
2041
		if (ifr->ifr_buffer.length > ifdescr_maxlen)
2042
			return (ENAMETOOLONG);
2043
		else if (ifr->ifr_buffer.length == 0)
2044
			descrbuf = NULL;
2045
		else {
2046
			descrbuf = kmalloc(ifr->ifr_buffer.length, M_IFDESCR,
2047
			    M_WAITOK | M_ZERO);
2048
			error = copyin(ifr->ifr_buffer.buffer, descrbuf,
2049
			    ifr->ifr_buffer.length - 1);
2050
			if (error) {
2051
				kfree(descrbuf, M_IFDESCR);
2052
				break;
2053
			}
2054
		}
2055

  
2056
		ifnet_lock();
2057
		odescrbuf = ifp->if_description;
2058
		ifp->if_description = descrbuf;
2059
		ifnet_unlock();
2060

  
2061
		if (odescrbuf)
2062
			kfree(odescrbuf, M_IFDESCR);
2063

  
2002 2064
	case SIOCSIFFLAGS:
2003 2065
		error = priv_check_cred(cred, PRIV_ROOT, 0);
2004 2066
		if (error)
......
2929 2991
void
2930 2992
if_free(struct ifnet *ifp)
2931 2993
{
2994
	if (ifp->if_description != NULL)
2995
		kfree(ifp->if_description, M_IFDESCR);
2932 2996
	kfree(ifp, M_IFNET);
2933 2997
}
2934 2998

  
sys/net/if.h
220 220
#define	IFAN_ARRIVAL	0	/* interface arrival */
221 221
#define	IFAN_DEPARTURE	1	/* interface departure */
222 222

  
223
/*
224
 * Buffer with length to be used in SIOCGIFDESCR/SIOCSIFDESCR requests
225
 */
226
struct ifreq_buffer {
227
	size_t  length;
228
	void    *buffer;
229
};
230

  
223 231
/*
224 232
 * Interface request structure used for socket
225 233
 * ioctl's.  All interface ioctl's must have parameter
......
232 240
		struct	sockaddr ifru_addr;
233 241
		struct	sockaddr ifru_dstaddr;
234 242
		struct	sockaddr ifru_broadaddr;
243
		struct  ifreq_buffer ifru_buffer;
235 244
		short	ifru_flags[2];
236 245
		short	ifru_index;
237 246
		int	ifru_metric;
......
246 255
#define	ifr_addr	ifr_ifru.ifru_addr	/* address */
247 256
#define	ifr_dstaddr	ifr_ifru.ifru_dstaddr	/* other end of p-to-p link */
248 257
#define	ifr_broadaddr	ifr_ifru.ifru_broadaddr	/* broadcast address */
258
#define ifr_buffer	ifr_ifru.ifru_buffer	/* user supplied buffer with its length */
249 259
#define	ifr_flags	ifr_ifru.ifru_flags[0]	/* flags (low 16 bits) */
250 260
#define	ifr_flagshigh	ifr_ifru.ifru_flags[1]	/* flags (high 16 bits) */
251 261
#define	ifr_metric	ifr_ifru.ifru_metric	/* metric */
sys/net/if_var.h
364 364
		(void *);
365 365
	int	(*if_resolvemulti)	/* validate/resolve multicast */
366 366
		(struct ifnet *, struct sockaddr **, struct sockaddr *);
367
	void	*if_unused5;
367
	char	*if_description;	/* interface description */
368 368
	int	(*if_mapsubq)		/* cpuid to if_snd subqueue map */
369 369
		(struct ifaltq *, int);
370 370
	int	if_unused2;
sys/sys/param.h
234 234
 * 600103 - remove the old vmm code
235 235
 * 600104 - add posix_fallocate()
236 236
 * 600105 - add fdatasync()
237
 * 600106 - support set if description
237 238
 */
238 239
#undef __DragonFly_version
239
#define __DragonFly_version 600105	/* propagated to newvers */
240
#define __DragonFly_version 600106	/* propagated to newvers */
240 241

  
241 242
#include <sys/_null.h>
242 243

  
sys/sys/sockio.h
77 77
#define	SIOCGIFDATA	_IOWR('i', 38, struct ifreq)	/* get if_data */
78 78
#define	SIOCSIFNAME	 _IOW('i', 40, struct ifreq)	/* set IF name */
79 79
#define	SIOCGIFALIAS	_IOWR('i', 41, struct ifaliasreq)/* get IF alias */
80
#define SIOCSIFDESCR	 _IOW('i', 42, struct ifreq)    /* set ifnet descr */
81
#define SIOCGIFDESCR	_IOWR('i', 43, struct ifreq)    /* get ifnet descr */
80 82

  
81 83
#define	SIOCADDMULTI	 _IOW('i', 49, struct ifreq)	/* add m'cast addr */
82 84
#define	SIOCDELMULTI	 _IOW('i', 50, struct ifreq)	/* del m'cast addr */
(1-1/2)