2 * Copyright (c) 2016, Marie Helene Kvello-Aune
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * thislist of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation and/or
13 * other materials provided with the distribution.
15 * 3. Neither the name of the copyright holder nor the names of its contributors
16 * may be used to endorse or promote products derived from this software without
17 * specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 * Copyright (c) 1983, 1993
35 * The Regents of the University of California. All rights reserved.
37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions
40 * 1. Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in the
44 * documentation and/or other materials provided with the distribution.
45 * 3. Neither the name of the University nor the names of its contributors
46 * may be used to endorse or promote products derived from this software
47 * without specific prior written permission.
49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
65 * Copyright 1996 Massachusetts Institute of Technology
67 * Permission to use, copy, modify, and distribute this software and
68 * its documentation for any purpose and without fee is hereby
69 * granted, provided that both the above copyright notice and this
70 * permission notice appear in all copies, that both the above
71 * copyright notice and this permission notice appear in all
72 * supporting documentation, and that the name of M.I.T. not be used
73 * in advertising or publicity pertaining to distribution of the
74 * software without specific, written prior permission. M.I.T. makes
75 * no representations about the suitability of this software for any
76 * purpose. It is provided "as is" without express or implied
79 * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
80 * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
81 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
82 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
83 * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
84 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
85 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
86 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
87 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
88 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
89 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
95 #include <sys/types.h>
96 #include <sys/ioctl.h>
97 #include <sys/sysctl.h>
100 #include <net/if_mib.h>
110 #include "libifconfig.h"
111 #include "libifconfig_internal.h"
117 struct ifconfig_handle *h;
119 h = calloc(1, sizeof(*h));
120 for (int i = 0; i <= AF_MAX; i++) {
127 ifconfig_close(ifconfig_handle_t *h)
130 for (int i = 0; i <= AF_MAX; i++) {
131 if (h->sockets[i] != -1) {
132 (void)close(h->sockets[i]);
139 ifconfig_err_errtype(ifconfig_handle_t *h)
142 return (h->error.errtype);
146 ifconfig_err_errno(ifconfig_handle_t *h)
149 return (h->error.errcode);
153 ifconfig_err_ioctlreq(ifconfig_handle_t *h)
156 return (h->error.ioctl_request);
160 ifconfig_get_description(ifconfig_handle_t *h, const char *name,
169 memset(&ifr, 0, sizeof(ifr));
170 (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
173 if ((descr = reallocf(descr, descrlen)) == NULL) {
174 h->error.errtype = OTHER;
175 h->error.errcode = ENOMEM;
179 ifr.ifr_buffer.buffer = descr;
180 ifr.ifr_buffer.length = descrlen;
181 if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCGIFDESCR, &ifr) != 0) {
185 if (ifr.ifr_buffer.buffer == descr) {
186 if (strlen(descr) > 0) {
187 *description = strdup(descr);
191 } else if (ifr.ifr_buffer.length > descrlen) {
192 descrlen = ifr.ifr_buffer.length;
198 h->error.errtype = OTHER;
199 h->error.errcode = 0;
204 ifconfig_set_description(ifconfig_handle_t *h, const char *name,
205 const char *newdescription)
210 memset(&ifr, 0, sizeof(ifr));
211 desclen = strlen(newdescription);
214 * Unset description if the new description is 0 characters long.
215 * TODO: Decide whether this should be an error condition instead.
218 return (ifconfig_unset_description(h, name));
221 (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
222 ifr.ifr_buffer.length = desclen + 1;
223 ifr.ifr_buffer.buffer = strdup(newdescription);
225 if (ifr.ifr_buffer.buffer == NULL) {
226 h->error.errtype = OTHER;
227 h->error.errcode = ENOMEM;
231 if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCSIFDESCR,
233 free(ifr.ifr_buffer.buffer);
237 free(ifr.ifr_buffer.buffer);
242 ifconfig_unset_description(ifconfig_handle_t *h, const char *name)
246 memset(&ifr, 0, sizeof(ifr));
247 (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
248 ifr.ifr_buffer.length = 0;
249 ifr.ifr_buffer.buffer = NULL;
251 if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCSIFDESCR,
259 ifconfig_set_name(ifconfig_handle_t *h, const char *name, const char *newname)
264 memset(&ifr, 0, sizeof(ifr));
265 tmpname = strdup(newname);
266 if (tmpname == NULL) {
267 h->error.errtype = OTHER;
268 h->error.errcode = ENOMEM;
272 (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
273 ifr.ifr_data = tmpname;
274 if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCSIFNAME,
285 ifconfig_get_orig_name(ifconfig_handle_t *h, const char *ifname,
288 struct ifmibdata ifmd;
295 name[2] = NETLINK_GENERIC;
296 name[3] = IFMIB_SYSTEM;
297 name[4] = IFMIB_IFCOUNT;
299 len = sizeof maxifno;
300 if (sysctl(name, 5, &maxifno, &len, 0, 0) < 0) {
301 h->error.errtype = OTHER;
302 h->error.errcode = errno;
306 name[3] = IFMIB_IFDATA;
307 name[5] = IFDATA_GENERAL;
308 for (i = 1; i <= maxifno; i++) {
311 if (sysctl(name, 6, &ifmd, &len, 0, 0) < 0) {
318 if (strncmp(ifmd.ifmd_name, ifname, IFNAMSIZ) != 0)
322 name[5] = IFDATA_DRIVERNAME;
323 if (sysctl(name, 6, NULL, &len, 0, 0) < 0)
326 *orig_name = malloc(len);
327 if (*orig_name == NULL)
330 if (sysctl(name, 6, *orig_name, &len, 0, 0) < 0) {
340 h->error.errtype = OTHER;
341 h->error.errcode = (i <= maxifno) ? errno : ENOENT;
346 ifconfig_set_mtu(ifconfig_handle_t *h, const char *name, const int mtu)
350 memset(&ifr, 0, sizeof(ifr));
351 (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
354 if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCSIFMTU,
363 ifconfig_get_mtu(ifconfig_handle_t *h, const char *name, int *mtu)
367 memset(&ifr, 0, sizeof(ifr));
368 (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
370 if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCGIFMTU,
380 ifconfig_set_metric(ifconfig_handle_t *h, const char *name, const int mtu)
384 memset(&ifr, 0, sizeof(ifr));
385 (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
388 if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCSIFMETRIC,
397 ifconfig_get_metric(ifconfig_handle_t *h, const char *name, int *metric)
401 memset(&ifr, 0, sizeof(ifr));
402 (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
404 if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCGIFMETRIC,
409 *metric = ifr.ifr_metric;
414 ifconfig_set_capability(ifconfig_handle_t *h, const char *name,
415 const int capability)
418 struct ifconfig_capabilities ifcap;
421 memset(&ifr, 0, sizeof(ifr));
423 if (ifconfig_get_capability(h, name,
429 flags = ifcap.curcap;
436 flags &= ifcap.reqcap;
438 (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
441 * TODO: Verify that it's safe to not have ifr.ifr_curcap
442 * set for this request.
444 ifr.ifr_reqcap = flags;
445 if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCSIFCAP,
453 ifconfig_get_capability(ifconfig_handle_t *h, const char *name,
454 struct ifconfig_capabilities *capability)
458 memset(&ifr, 0, sizeof(ifr));
459 (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
461 if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCGIFCAP,
465 capability->curcap = ifr.ifr_curcap;
466 capability->reqcap = ifr.ifr_reqcap;
471 ifconfig_destroy_interface(ifconfig_handle_t *h, const char *name)
475 memset(&ifr, 0, sizeof(ifr));
476 (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
478 if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCIFDESTROY,
486 ifconfig_create_interface(ifconfig_handle_t *h, const char *name, char **ifname)
490 memset(&ifr, 0, sizeof(ifr));
491 (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
495 * Insert special snowflake handling here. See GitHub issue #12 for details.
496 * In the meantime, hard-nosupport interfaces that need special handling.
498 if ((strncmp(name, "wlan",
499 strlen("wlan")) == 0) ||
500 (strncmp(name, "vlan",
501 strlen("vlan")) == 0) ||
502 (strncmp(name, "vxlan",
503 strlen("vxlan")) == 0)) {
504 h->error.errtype = OTHER;
505 h->error.errcode = ENOSYS;
509 /* No special handling for this interface type. */
510 if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCIFCREATE2, &ifr) < 0) {
514 *ifname = strdup(ifr.ifr_name);