aboutsummaryrefslogtreecommitdiffstats
path: root/iw_if.c
diff options
context:
space:
mode:
Diffstat (limited to 'iw_if.c')
-rw-r--r--iw_if.c42
1 files changed, 33 insertions, 9 deletions
diff --git a/iw_if.c b/iw_if.c
index 72de7b1..8a4fd0e 100644
--- a/iw_if.c
+++ b/iw_if.c
@@ -51,8 +51,9 @@ bool if_is_up(const char *ifname)
return ret;
}
-/** Bring @ifname up if not already up. Return 0 if ok, < 0 on error. */
-int if_set_up(const char *ifname)
+
+/** Change the up/down state of @ifname according to @up. */
+static int if_set_up_or_down(const char *ifname, bool up)
{
struct ifreq ifr;
int ret, skfd = socket(AF_INET, SOCK_DGRAM, 0);
@@ -64,15 +65,38 @@ int if_set_up(const char *ifname)
strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1);
ifr.ifr_flags = if_get_flags(skfd, ifname);
- if (ifr.ifr_flags & IFF_UP)
- return 0;
-
- ifr.ifr_flags |= IFF_UP;
+ if (up) {
+ ifr.ifr_flags |= IFF_UP;
+ } else {
+ ifr.ifr_flags &= ~IFF_UP;
+ }
ret = ioctl(skfd, SIOCSIFFLAGS, &ifr);
close(skfd);
return ret;
}
+/** Bring @ifname up. */
+int if_set_up(const char *ifname)
+{
+ return if_set_up_or_down(ifname, true);
+}
+
+/** Set @ifname down. */
+int if_set_down(const char *ifname)
+{
+ return if_set_up_or_down(ifname, false);
+}
+
+/** Exit handler to restore interface 'down' state on exit via atexit(3). */
+void if_set_down_on_exit(void)
+{
+ const char *ifname = conf_ifname();
+
+ if (ifname && if_set_down(ifname) < 0) {
+ err_msg("unable to restore %s interface state - set down manually", ifname);
+ }
+}
+
/* Interface information */
void if_getinf(const char *ifname, struct if_info *info)
{
@@ -87,7 +111,7 @@ void if_getinf(const char *ifname, struct if_info *info)
info->flags = if_get_flags(skfd, ifname);
- strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
+ strncpy(ifr.ifr_name, ifname, IFNAMSIZ-1);
if (ioctl(skfd, SIOCGIFMTU, &ifr) == 0)
info->mtu = ifr.ifr_mtu;
@@ -163,7 +187,7 @@ void dyn_info_get(struct iw_dyn_info *info, const char *ifname)
err_sys("%s: can not open socket", __func__);
memset(info, 0, sizeof(*info));
- strncpy(iwr.ifr_name, ifname, IFNAMSIZ);
+ strncpy(iwr.ifr_name, ifname, IFNAMSIZ-1);
if (ioctl(skfd, SIOCGIWNAME, &iwr) < 0)
err_sys("can not open device '%s'", ifname);
@@ -250,7 +274,7 @@ void iw_getinf_range(const char *ifname, struct iw_range *range)
err_sys("%s: can not open socket", __func__);
memset(range, 0, sizeof(struct iw_range));
- strncpy(iwr.ifr_name, ifname, IFNAMSIZ);
+ strncpy(iwr.ifr_name, ifname, IFNAMSIZ-1);
iwr.u.data.pointer = (caddr_t) range;
iwr.u.data.length = sizeof(struct iw_range);