aboutsummaryrefslogtreecommitdiffstats
path: root/package/network/utils/wireless-tools
diff options
context:
space:
mode:
Diffstat (limited to 'package/network/utils/wireless-tools')
-rw-r--r--package/network/utils/wireless-tools/Makefile92
-rw-r--r--package/network/utils/wireless-tools/patches/001-debian.patch35
-rw-r--r--package/network/utils/wireless-tools/patches/002-fix-iwconfig-power-argument-parsing.patch13
-rw-r--r--package/network/utils/wireless-tools/patches/003-we_essential_def.patch359
-rw-r--r--package/network/utils/wireless-tools/patches/004-increase_iwlist_buffer.patch46
5 files changed, 545 insertions, 0 deletions
diff --git a/package/network/utils/wireless-tools/Makefile b/package/network/utils/wireless-tools/Makefile
new file mode 100644
index 0000000..67986ba
--- /dev/null
+++ b/package/network/utils/wireless-tools/Makefile
@@ -0,0 +1,92 @@
+#
+# Copyright (C) 2006-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=wireless-tools
+PKG_VERSION:=29
+PKG_MINOR:=
+PKG_RELEASE:=5
+
+PKG_SOURCE:=wireless_tools.$(PKG_VERSION)$(PKG_MINOR).tar.gz
+PKG_SOURCE_URL:=http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux
+PKG_MD5SUM:=e06c222e186f7cc013fd272d023710cb
+TAR_OPTIONS += || true
+
+PKG_MAINTAINER:=Felix Fietkau <nbd@openwrt.org>
+PKG_LICENSE:=GPL-2.0
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/wireless_tools.$(PKG_VERSION)
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/wireless-tools/Default
+ URL:=http://hplabs.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html
+endef
+
+define Package/wireless-tools
+$(call Package/wireless-tools/Default)
+ SECTION:=net
+ CATEGORY:=Base system
+ TITLE:=Tools for manipulating Linux Wireless Extensions
+endef
+
+define Package/wireless-tools/description
+ This package contains a collection of tools for configuring wireless
+ adapters implementing the "Linux Wireless Extensions".
+endef
+
+define Package/libiw
+$(call Package/wireless-tools/Default)
+ SECTION:=libs
+ CATEGORY:=Libraries
+ TITLE:=Library for manipulating Linux Wireless Extensions
+endef
+
+define Package/libiw/description
+ This package contains a library for manipulating
+ "Linux Wireless Extensions".
+endef
+
+define Build/Compile
+ rm -rf $(PKG_INSTALL_DIR)
+ mkdir -p $(PKG_INSTALL_DIR)
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ $(TARGET_CONFIGURE_OPTS) \
+ CFLAGS="$(TARGET_CFLAGS) -I." \
+ BUILD_WE_ESSENTIAL=y \
+ LIBS="-lm -Wl,--gc-sections" \
+ libiw.so.$(PKG_VERSION) iwmulticall
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ PREFIX="$(PKG_INSTALL_DIR)" \
+ INSTALL_DIR="$(PKG_INSTALL_DIR)/usr/sbin" \
+ INSTALL_LIB="$(PKG_INSTALL_DIR)/usr/lib" \
+ install-iwmulticall
+endef
+
+define Build/InstallDev
+ mkdir -p $(1)/usr/include
+ $(CP) $(PKG_BUILD_DIR)/{iwlib,wireless}.h $(1)/usr/include/
+ mkdir -p $(1)/usr/lib
+ $(CP) $(PKG_BUILD_DIR)/libiw.so* $(1)/usr/lib/
+ $(LN) libiw.so.$(PKG_VERSION) $(1)/usr/lib/libiw.so
+endef
+
+define Package/wireless-tools/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/iwconfig $(1)/usr/sbin/
+ $(LN) iwconfig $(1)/usr/sbin/iwlist
+ $(LN) iwconfig $(1)/usr/sbin/iwpriv
+endef
+
+define Package/libiw/install
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_BUILD_DIR)/libiw.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,wireless-tools))
+$(eval $(call BuildPackage,libiw))
diff --git a/package/network/utils/wireless-tools/patches/001-debian.patch b/package/network/utils/wireless-tools/patches/001-debian.patch
new file mode 100644
index 0000000..e00bad2
--- /dev/null
+++ b/package/network/utils/wireless-tools/patches/001-debian.patch
@@ -0,0 +1,35 @@
+--- a/iwlib.c
++++ b/iwlib.c
+@@ -667,6 +667,7 @@ iw_get_basic_config(int skfd,
+ {
+ struct iwreq wrq;
+
++ memset((char *) &wrq, 0, sizeof(struct iwreq));
+ memset((char *) info, 0, sizeof(struct wireless_config));
+
+ /* Get wireless name */
+--- a/Makefile
++++ b/Makefile
+@@ -73,8 +73,8 @@ DYNAMIC_LINK= libiw.so
+ # Install directories
+ INSTALL_DIR= $(PREFIX)/sbin/
+ INSTALL_LIB= $(PREFIX)/lib/
+-INSTALL_INC= $(PREFIX)/include/
+-INSTALL_MAN= $(PREFIX)/man/
++INSTALL_INC= $(PREFIX)/usr/include/
++INSTALL_MAN= $(PREFIX)/usr/share/man/
+
+ # Various commands
+ RM = rm -f
+@@ -102,9 +102,9 @@ ifdef BUILD_WE_ESSENTIAL
+ endif
+
+ # Other flags
+-CFLAGS=-Os -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow \
++#CFLAGS=-Os -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow \
+ -Wpointer-arith -Wcast-qual -Winline -I.
+-#CFLAGS=-O2 -W -Wall -Wstrict-prototypes -I.
++CFLAGS=-O2 -W -Wall -Wstrict-prototypes -I.
+ DEPFLAGS=-MMD
+ XCFLAGS=$(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS) $(WELIB_FLAG) $(WEDEF_FLAG)
+ PICFLAG=-fPIC
diff --git a/package/network/utils/wireless-tools/patches/002-fix-iwconfig-power-argument-parsing.patch b/package/network/utils/wireless-tools/patches/002-fix-iwconfig-power-argument-parsing.patch
new file mode 100644
index 0000000..2b61ef2
--- /dev/null
+++ b/package/network/utils/wireless-tools/patches/002-fix-iwconfig-power-argument-parsing.patch
@@ -0,0 +1,13 @@
+--- a/iwconfig.c
++++ b/iwconfig.c
+@@ -1034,8 +1034,8 @@ set_power_info(int skfd,
+ wrq.u.power.disabled = 0;
+
+ /* Is there any value to grab ? */
+- value = strtod(args[0], &unit);
+- if(unit != args[0])
++ value = strtod(args[i], &unit);
++ if(unit != args[i])
+ {
+ struct iw_range range;
+ int flags;
diff --git a/package/network/utils/wireless-tools/patches/003-we_essential_def.patch b/package/network/utils/wireless-tools/patches/003-we_essential_def.patch
new file mode 100644
index 0000000..8666f3e
--- /dev/null
+++ b/package/network/utils/wireless-tools/patches/003-we_essential_def.patch
@@ -0,0 +1,359 @@
+--- a/iwlist.c
++++ b/iwlist.c
+@@ -58,7 +58,6 @@ typedef struct iw_auth_descr
+ * Maybe this should go in iwlib.c ?
+ */
+
+-#ifndef WE_ESSENTIAL
+ #define IW_ARRAY_LEN(x) (sizeof(x)/sizeof((x)[0]))
+
+ //static const struct iwmask_name iw_enc_mode_name[] = {
+@@ -161,11 +160,8 @@ static const char * iw_ie_key_mgmt_name[
+ };
+ #define IW_IE_KEY_MGMT_NUM IW_ARRAY_LEN(iw_ie_key_mgmt_name)
+
+-#endif /* WE_ESSENTIAL */
+-
+ /************************* WPA SUBROUTINES *************************/
+
+-#ifndef WE_ESSENTIAL
+ /*------------------------------------------------------------------*/
+ /*
+ * Print all names corresponding to a mask.
+@@ -431,7 +427,6 @@ iw_print_gen_ie(unsigned char * buffer,
+ offset += buffer[offset+1] + 2;
+ }
+ }
+-#endif /* WE_ESSENTIAL */
+
+ /***************************** SCANNING *****************************/
+ /*
+@@ -585,12 +580,10 @@ print_scanning_token(struct stream_descr
+ &event->u.qual, iw_range, has_range);
+ printf(" %s\n", buffer);
+ break;
+-#ifndef WE_ESSENTIAL
+ case IWEVGENIE:
+ /* Informations Elements are complex, let's do only some of them */
+ iw_print_gen_ie(event->u.data.pointer, event->u.data.length);
+ break;
+-#endif /* WE_ESSENTIAL */
+ case IWEVCUSTOM:
+ {
+ char custom[IW_CUSTOM_MAX+1];
+@@ -1302,7 +1295,6 @@ print_pm_info(int skfd,
+ return(0);
+ }
+
+-#ifndef WE_ESSENTIAL
+ /************************** TRANSMIT POWER **************************/
+
+ /*------------------------------------------------------------------*/
+@@ -1405,6 +1397,7 @@ print_txpower_info(int skfd,
+ return(0);
+ }
+
++#ifndef WE_ESSENTIAL
+ /*********************** RETRY LIMIT/LIFETIME ***********************/
+
+ /*------------------------------------------------------------------*/
+@@ -2060,8 +2053,8 @@ static const struct iwlist_entry iwlist_
+ { "encryption", print_keys_info, 0, NULL },
+ { "keys", print_keys_info, 0, NULL },
+ { "power", print_pm_info, 0, NULL },
+-#ifndef WE_ESSENTIAL
+ { "txpower", print_txpower_info, 0, NULL },
++#ifndef WE_ESSENTIAL
+ { "retry", print_retry_info, 0, NULL },
+ { "ap", print_ap_info, 0, NULL },
+ { "accesspoints", print_ap_info, 0, NULL },
+--- a/iwconfig.c
++++ b/iwconfig.c
+@@ -106,16 +106,6 @@ get_info(int skfd,
+ if(wrq.u.data.length > 1)
+ info->has_nickname = 1;
+
+- if((info->has_range) && (info->range.we_version_compiled > 9))
+- {
+- /* Get Transmit Power */
+- if(iw_get_ext(skfd, ifname, SIOCGIWTXPOW, &wrq) >= 0)
+- {
+- info->has_txpower = 1;
+- memcpy(&(info->txpower), &(wrq.u.txpower), sizeof(iwparam));
+- }
+- }
+-
+ /* Get sensitivity */
+ if(iw_get_ext(skfd, ifname, SIOCGIWSENS, &wrq) >= 0)
+ {
+@@ -132,6 +122,17 @@ get_info(int skfd,
+ memcpy(&(info->retry), &(wrq.u.retry), sizeof(iwparam));
+ }
+ }
++#endif /* WE_ESSENTIAL */
++
++ if((info->has_range) && (info->range.we_version_compiled > 9))
++ {
++ /* Get Transmit Power */
++ if(iw_get_ext(skfd, ifname, SIOCGIWTXPOW, &wrq) >= 0)
++ {
++ info->has_txpower = 1;
++ memcpy(&(info->txpower), &(wrq.u.txpower), sizeof(iwparam));
++ }
++ }
+
+ /* Get RTS threshold */
+ if(iw_get_ext(skfd, ifname, SIOCGIWRTS, &wrq) >= 0)
+@@ -146,7 +147,6 @@ get_info(int skfd,
+ info->has_frag = 1;
+ memcpy(&(info->frag), &(wrq.u.frag), sizeof(iwparam));
+ }
+-#endif /* WE_ESSENTIAL */
+
+ return(0);
+ }
+@@ -269,7 +269,6 @@ display_info(struct wireless_info * info
+ printf("Bit Rate%c%s ", (info->bitrate.fixed ? '=' : ':'), buffer);
+ }
+
+-#ifndef WE_ESSENTIAL
+ /* Display the Transmit Power */
+ if(info->has_txpower)
+ {
+@@ -286,6 +285,7 @@ display_info(struct wireless_info * info
+ printf("Tx-Power%c%s ", (info->txpower.fixed ? '=' : ':'), buffer);
+ }
+
++#ifndef WE_ESSENTIAL
+ /* Display sensitivity */
+ if(info->has_sens)
+ {
+@@ -340,6 +340,7 @@ display_info(struct wireless_info * info
+ printf(" ");
+ tokens += 5; /* Between 3 and 5, depend on flags */
+ }
++#endif /* WE_ESSENTIAL */
+
+ /* Display the RTS threshold */
+ if(info->has_rts)
+@@ -383,7 +384,6 @@ display_info(struct wireless_info * info
+ /* Formating */
+ if(tokens > 0)
+ printf("\n ");
+-#endif /* WE_ESSENTIAL */
+
+ /* Display encryption information */
+ /* Note : we display only the "current" key, use iwlist to list all keys */
+@@ -1196,6 +1196,7 @@ set_nwid_info(int skfd,
+ /* 1 arg */
+ return(1);
+ }
++#endif /* WE_ESSENTIAL */
+
+ /*------------------------------------------------------------------*/
+ /*
+@@ -1362,6 +1363,7 @@ set_txpower_info(int skfd,
+ return(i);
+ }
+
++#ifndef WE_ESSENTIAL
+ /*------------------------------------------------------------------*/
+ /*
+ * Set Sensitivity
+@@ -1459,6 +1461,7 @@ set_retry_info(int skfd,
+ /* Var args */
+ return(i);
+ }
++#endif /* WE_ESSENTIAL */
+
+ /*------------------------------------------------------------------*/
+ /*
+@@ -1565,6 +1568,7 @@ set_frag_info(int skfd,
+ return(1);
+ }
+
++#ifndef WE_ESSENTIAL
+ /*------------------------------------------------------------------*/
+ /*
+ * Set Modulation
+@@ -1719,21 +1723,21 @@ static const struct iwconfig_entry iwcon
+ "Set Nickname", "NNN" },
+ { "nwid", set_nwid_info, 1, SIOCSIWNWID,
+ "Set NWID", "{NN|on|off}" },
+- { "ap", set_apaddr_info, 1, SIOCSIWAP,
+- "Set AP Address", "{N|off|auto}" },
+- { "txpower", set_txpower_info, 1, SIOCSIWTXPOW,
+- "Set Tx Power", "{NmW|NdBm|off|auto}" },
+ { "sens", set_sens_info, 1, SIOCSIWSENS,
+ "Set Sensitivity", "N" },
++ { "modulation", set_modulation_info, 1, SIOCGIWMODUL,
++ "Set Modulation", "{11g|11a|CCK|OFDMg|...}" },
+ { "retry", set_retry_info, 1, SIOCSIWRETRY,
+ "Set Retry Limit", "{limit N|lifetime N}" },
++#endif /* WE_ESSENTIAL */
++ { "ap", set_apaddr_info, 1, SIOCSIWAP,
++ "Set AP Address", "{N|off|auto}" },
++ { "txpower", set_txpower_info, 1, SIOCSIWTXPOW,
++ "Set Tx Power", "{NmW|NdBm|off|auto}" },
+ { "rts", set_rts_info, 1, SIOCSIWRTS,
+ "Set RTS Threshold", "{N|auto|fixed|off}" },
+ { "frag", set_frag_info, 1, SIOCSIWFRAG,
+ "Set Fragmentation Threshold", "{N|auto|fixed|off}" },
+- { "modulation", set_modulation_info, 1, SIOCGIWMODUL,
+- "Set Modulation", "{11g|11a|CCK|OFDMg|...}" },
+-#endif /* WE_ESSENTIAL */
+ { "commit", set_commit_info, 0, SIOCSIWCOMMIT,
+ "Commit changes", "" },
+ { NULL, NULL, 0, 0, NULL, NULL },
+--- a/iwmulticall.c
++++ b/iwmulticall.c
+@@ -81,7 +81,7 @@ extern int
+ #define main(args...) main_iwspy(args)
+ #include "iwspy.c"
+ #undef main
+-#endif /* WE_ESSENTIAL */
++#endif
+
+ /* Get iwpriv in there. Mandatory for HostAP and some other drivers. */
+ #define main(args...) main_iwpriv(args)
+@@ -90,12 +90,14 @@ extern int
+ #undef iw_usage
+ #undef main
+
++#ifndef WE_ESSENTIAL
+ /* Do we really need iwgetid ? Well, it's not like it's a big one */
+ #define main(args...) main_iwgetid(args)
+ #define iw_usage(args...) iwgetid_usage(args)
+ #include "iwgetid.c"
+ #undef iw_usage
+ #undef main
++#endif
+
+ /* iwevent is useless for most people, don't grab it ? */
+
+@@ -131,11 +133,13 @@ main(int argc,
+ #ifndef WE_ESSENTIAL
+ if(!strcmp(call_name, "iwspy"))
+ return(main_iwspy(argc, argv));
+-#endif /* WE_ESSENTIAL */
++#endif
+ if(!strcmp(call_name, "iwpriv"))
+ return(main_iwpriv(argc, argv));
++#ifndef WE_ESSENTIAL
+ if(!strcmp(call_name, "iwgetid"))
+ return(main_iwgetid(argc, argv));
++#endif
+
+ /* Uh oh... Not supposed to come here. */
+ printf("iwmulticall : you are not supposed to call me this way...\n");
+--- a/iwlib.c
++++ b/iwlib.c
+@@ -113,6 +113,7 @@ const struct iw_modul_descr iw_modul_lis
+ { IW_MODUL_11A, "11a", "IEEE 802.11a (5 GHz, up to 54 Mb/s)" },
+ { IW_MODUL_11B, "11b", "IEEE 802.11b (2.4 GHz, up to 11 Mb/s)" },
+
++#ifndef WE_ESSENTIAL
+ /* Proprietary aggregates */
+ { IW_MODUL_TURBO | IW_MODUL_11A, "turboa",
+ "Atheros turbo mode at 5 GHz (up to 108 Mb/s)" },
+@@ -120,6 +121,7 @@ const struct iw_modul_descr iw_modul_lis
+ "Atheros turbo mode at 2.4 GHz (up to 108 Mb/s)" },
+ { IW_MODUL_PBCC | IW_MODUL_11B, "11+",
+ "TI 802.11+ (2.4 GHz, up to 22 Mb/s)" },
++#endif
+
+ /* Individual modulations */
+ { IW_MODUL_OFDM_G, "OFDMg",
+@@ -129,6 +131,7 @@ const struct iw_modul_descr iw_modul_lis
+ { IW_MODUL_DS, "DS", "802.11 Direct Sequence (2.4 GHz, up to 2 Mb/s)" },
+ { IW_MODUL_FH, "FH", "802.11 Frequency Hopping (2,4 GHz, up to 2 Mb/s)" },
+
++#ifndef WE_ESSENTIAL
+ /* Proprietary modulations */
+ { IW_MODUL_TURBO, "turbo",
+ "Atheros turbo mode, channel bonding (up to 108 Mb/s)" },
+@@ -136,6 +139,7 @@ const struct iw_modul_descr iw_modul_lis
+ "TI 802.11+ higher rates (2.4 GHz, up to 22 Mb/s)" },
+ { IW_MODUL_CUSTOM, "custom",
+ "Driver specific modulation (check driver documentation)" },
++#endif
+ };
+
+ /* Disable runtime version warning in iw_get_range_info() */
+@@ -440,6 +444,7 @@ iw_print_version_info(const char * tooln
+ return -1;
+ }
+
++#ifndef WE_ESSENTIAL
+ /* Information about the tools themselves */
+ if(toolname != NULL)
+ printf("%-8.16s Wireless-Tools version %d\n", toolname, WT_VERSION);
+@@ -452,6 +457,7 @@ iw_print_version_info(const char * tooln
+ if(we_kernel_version > 15)
+ printf("Kernel Currently compiled with Wireless Extension v%d.\n\n",
+ we_kernel_version);
++#endif
+
+ /* Version for each device */
+ iw_enum_devices(skfd, &print_iface_version_info, NULL, 0);
+@@ -501,6 +507,7 @@ iw_get_range_info(int skfd,
+ /* Copy stuff at the right place, ignore extra */
+ memcpy((char *) range, buffer, sizeof(iwrange));
+ }
++#ifndef WE_ESSENTIAL
+ else
+ {
+ /* Zero unknown fields */
+@@ -574,6 +581,7 @@ iw_get_range_info(int skfd,
+ * If the driver source has not been updated to the latest, it doesn't
+ * matter because the new fields are set to zero */
+ }
++#endif
+
+ /* Don't complain twice.
+ * In theory, the test apply to each individual driver, but usually
+@@ -1542,6 +1550,7 @@ iw_print_key(char * buffer,
+ }
+ }
+
++#ifndef WE_ESSENTIAL
+ /*------------------------------------------------------------------*/
+ /*
+ * Convert a passphrase into a key
+@@ -1556,6 +1565,7 @@ iw_pass_key(const char * input,
+ fprintf(stderr, "Error: Passphrase not implemented\n");
+ return(-1);
+ }
++#endif
+
+ /*------------------------------------------------------------------*/
+ /*
+@@ -1578,12 +1588,14 @@ iw_in_key(const char * input,
+ keylen = IW_ENCODING_TOKEN_MAX;
+ memcpy(key, input + 2, keylen);
+ }
++#ifndef WE_ESSENTIAL
+ else
+ if(!strncmp(input, "p:", 2))
+ {
+ /* Second case : as a passphrase (PrismII cards) */
+ return(iw_pass_key(input + 2, key)); /* skip "p:" */
+ }
++#endif
+ else
+ {
+ const char * p;
+--- a/Makefile
++++ b/Makefile
+@@ -195,9 +195,9 @@ install-iwmulticall:: iwmulticall
+ install -m 755 $< $(INSTALL_DIR)/iwconfig
+ ( cd $(INSTALL_DIR) ; \
+ ln -f -s iwconfig iwlist ; \
+- ln -f -s iwconfig iwspy ; \
++ $(if $(BUILD_WE_ESSENTIAL),,ln -f -s iwconfig iwspy ;) \
+ ln -f -s iwconfig iwpriv ; \
+- ln -f -s iwconfig iwgetid )
++ $(if $(BUILD_WE_ESSENTIAL),,ln -f -s iwconfig iwgetid ) )
+
+ clean::
+ $(RM_CMD)
diff --git a/package/network/utils/wireless-tools/patches/004-increase_iwlist_buffer.patch b/package/network/utils/wireless-tools/patches/004-increase_iwlist_buffer.patch
new file mode 100644
index 0000000..f2fdb12
--- /dev/null
+++ b/package/network/utils/wireless-tools/patches/004-increase_iwlist_buffer.patch
@@ -0,0 +1,46 @@
+--- a/iwlist.c
++++ b/iwlist.c
+@@ -792,7 +792,8 @@ print_scanning_info(int skfd,
+ if(iw_get_ext(skfd, ifname, SIOCGIWSCAN, &wrq) < 0)
+ {
+ /* Check if buffer was too small (WE-17 only) */
+- if((errno == E2BIG) && (range.we_version_compiled > 16))
++ if((errno == E2BIG) && (range.we_version_compiled > 16)
++ && (buflen < 0xFFFF))
+ {
+ /* Some driver may return very large scan results, either
+ * because there are many cells, or because they have many
+@@ -808,6 +809,10 @@ print_scanning_info(int skfd,
+ else
+ buflen *= 2;
+
++ /* wrq.u.data.length is 16 bits so max size is 65535 */
++ if(buflen > 0xFFFF)
++ buflen = 0xFFFF;
++
+ /* Try again */
+ goto realloc;
+ }
+@@ -2152,6 +2157,7 @@ main(int argc,
+ char **args; /* Command arguments */
+ int count; /* Number of arguments */
+ const iwlist_cmd *iwcmd;
++ int goterr = 0;
+
+ if(argc < 2)
+ iw_usage(1);
+@@ -2199,12 +2205,12 @@ main(int argc,
+
+ /* do the actual work */
+ if (dev)
+- (*iwcmd->fn)(skfd, dev, args, count);
++ goterr = (*iwcmd->fn)(skfd, dev, args, count);
+ else
+ iw_enum_devices(skfd, iwcmd->fn, args, count);
+
+ /* Close the socket. */
+ iw_sockets_close(skfd);
+
+- return 0;
++ return goterr;
+ }