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
64 #include <sys/ioctl.h>
76 #include "libifconfig.h"
77 #include "libifconfig_internal.h"
83 struct ifconfig_handle *h;
85 h = calloc(1, sizeof(*h));
86 for (int i = 0; i <= AF_MAX; i++) {
93 ifconfig_close(ifconfig_handle_t *h)
96 for (int i = 0; i <= AF_MAX; i++) {
97 if (h->sockets[i] != -1) {
98 (void)close(h->sockets[i]);
105 ifconfig_err_errtype(ifconfig_handle_t *h)
108 return (h->error.errtype);
112 ifconfig_err_errno(ifconfig_handle_t *h)
115 return (h->error.errcode);
119 ifconfig_err_ioctlreq(ifconfig_handle_t *h)
122 return (h->error.ioctl_request);
126 ifconfig_get_description(ifconfig_handle_t *h, const char *name,
135 memset(&ifr, 0, sizeof(ifr));
136 (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
139 if ((descr = reallocf(descr, descrlen)) == NULL) {
140 h->error.errtype = OTHER;
141 h->error.errcode = ENOMEM;
145 ifr.ifr_buffer.buffer = descr;
146 ifr.ifr_buffer.length = descrlen;
147 if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCGIFDESCR, &ifr) != 0) {
151 if (ifr.ifr_buffer.buffer == descr) {
152 if (strlen(descr) > 0) {
153 *description = strdup(descr);
157 } else if (ifr.ifr_buffer.length > descrlen) {
158 descrlen = ifr.ifr_buffer.length;
164 h->error.errtype = OTHER;
165 h->error.errcode = 0;
170 ifconfig_set_description(ifconfig_handle_t *h, const char *name,
171 const char *newdescription)
176 memset(&ifr, 0, sizeof(ifr));
177 desclen = strlen(newdescription);
180 * Unset description if the new description is 0 characters long.
181 * TODO: Decide whether this should be an error condition instead.
184 return (ifconfig_unset_description(h, name));
187 (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
188 ifr.ifr_buffer.length = desclen + 1;
189 ifr.ifr_buffer.buffer = strdup(newdescription);
191 if (ifr.ifr_buffer.buffer == NULL) {
192 h->error.errtype = OTHER;
193 h->error.errcode = ENOMEM;
197 if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCSIFDESCR,
199 free(ifr.ifr_buffer.buffer);
203 free(ifr.ifr_buffer.buffer);
208 ifconfig_unset_description(ifconfig_handle_t *h, const char *name)
212 memset(&ifr, 0, sizeof(ifr));
213 (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
214 ifr.ifr_buffer.length = 0;
215 ifr.ifr_buffer.buffer = NULL;
217 if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCSIFDESCR,
225 ifconfig_set_name(ifconfig_handle_t *h, const char *name, const char *newname)
230 memset(&ifr, 0, sizeof(ifr));
231 tmpname = strdup(newname);
232 if (tmpname == NULL) {
233 h->error.errtype = OTHER;
234 h->error.errcode = ENOMEM;
238 (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
239 ifr.ifr_data = tmpname;
240 if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCSIFNAME,
251 ifconfig_set_mtu(ifconfig_handle_t *h, const char *name, const int mtu)
255 memset(&ifr, 0, sizeof(ifr));
256 (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
259 if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCSIFMTU,
268 ifconfig_get_mtu(ifconfig_handle_t *h, const char *name, int *mtu)
272 memset(&ifr, 0, sizeof(ifr));
273 (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
275 if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCGIFMTU,
285 ifconfig_set_metric(ifconfig_handle_t *h, const char *name, const int mtu)
289 memset(&ifr, 0, sizeof(ifr));
290 (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
293 if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCSIFMETRIC,
302 ifconfig_get_metric(ifconfig_handle_t *h, const char *name, int *metric)
306 memset(&ifr, 0, sizeof(ifr));
307 (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
309 if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCGIFMETRIC,
314 *metric = ifr.ifr_metric;
319 ifconfig_set_capability(ifconfig_handle_t *h, const char *name,
320 const int capability)
323 struct ifconfig_capabilities ifcap;
326 memset(&ifr, 0, sizeof(ifr));
328 if (ifconfig_get_capability(h, name,
334 flags = ifcap.curcap;
341 flags &= ifcap.reqcap;
343 (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
346 * TODO: Verify that it's safe to not have ifr.ifr_curcap
347 * set for this request.
349 ifr.ifr_reqcap = flags;
350 if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCSIFCAP,
358 ifconfig_get_capability(ifconfig_handle_t *h, const char *name,
359 struct ifconfig_capabilities *capability)
363 memset(&ifr, 0, sizeof(ifr));
364 (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
366 if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCGIFCAP,
370 capability->curcap = ifr.ifr_curcap;
371 capability->reqcap = ifr.ifr_reqcap;
376 ifconfig_destroy_interface(ifconfig_handle_t *h, const char *name)
380 memset(&ifr, 0, sizeof(ifr));
381 (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
383 if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCIFDESTROY,
391 ifconfig_create_interface(ifconfig_handle_t *h, const char *name, char **ifname)
395 memset(&ifr, 0, sizeof(ifr));
396 (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
400 * Insert special snowflake handling here. See GitHub issue #12 for details.
401 * In the meantime, hard-nosupport interfaces that need special handling.
403 if ((strncmp(name, "wlan",
404 strlen("wlan")) == 0) ||
405 (strncmp(name, "vlan",
406 strlen("vlan")) == 0) ||
407 (strncmp(name, "vxlan",
408 strlen("vxlan")) == 0)) {
409 h->error.errtype = OTHER;
410 h->error.errcode = ENOSYS;
414 /* No special handling for this interface type. */
415 if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCIFCREATE2, &ifr) < 0) {
419 *ifname = strdup(ifr.ifr_name);