112f961f4SSam Leffler /*- 24d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 31de7b4b8SPedro F. Giffuni * 410ad9a77SSam Leffler * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting 512f961f4SSam Leffler * All rights reserved. 612f961f4SSam Leffler * 712f961f4SSam Leffler * Redistribution and use in source and binary forms, with or without 812f961f4SSam Leffler * modification, are permitted provided that the following conditions 912f961f4SSam Leffler * are met: 1012f961f4SSam Leffler * 1. Redistributions of source code must retain the above copyright 1112f961f4SSam Leffler * notice, this list of conditions and the following disclaimer, 1212f961f4SSam Leffler * without modification. 1312f961f4SSam Leffler * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1412f961f4SSam Leffler * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 1512f961f4SSam Leffler * redistribution must be conditioned upon including a substantially 1612f961f4SSam Leffler * similar Disclaimer requirement for further binary redistribution. 1712f961f4SSam Leffler * 1812f961f4SSam Leffler * NO WARRANTY 1912f961f4SSam Leffler * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2012f961f4SSam Leffler * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2112f961f4SSam Leffler * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 2212f961f4SSam Leffler * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 2312f961f4SSam Leffler * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 2412f961f4SSam Leffler * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2512f961f4SSam Leffler * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2612f961f4SSam Leffler * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 2712f961f4SSam Leffler * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2812f961f4SSam Leffler * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 2912f961f4SSam Leffler * THE POSSIBILITY OF SUCH DAMAGES. 3012f961f4SSam Leffler */ 3112f961f4SSam Leffler 3212f961f4SSam Leffler /* 3312f961f4SSam Leffler * wlandebug [-i interface] flags 3412f961f4SSam Leffler * (default interface is wlan.0). 3512f961f4SSam Leffler */ 36*cbfd42ccSElyes Haouas #include <sys/param.h> 379758983cSSam Leffler #include <sys/sysctl.h> 3812f961f4SSam Leffler 39b1d757bcSAlan Somers #include <net/if.h> 40b1d757bcSAlan Somers 4112f961f4SSam Leffler #include <stdio.h> 42b5720689SSam Leffler #include <stdlib.h> 4312f961f4SSam Leffler #include <ctype.h> 4412f961f4SSam Leffler #include <getopt.h> 4512f961f4SSam Leffler #include <string.h> 46b5720689SSam Leffler #include <err.h> 4712f961f4SSam Leffler 48238c9eb6SAndriy Voskoboinyk #include <libifconfig.h> 49238c9eb6SAndriy Voskoboinyk 50*cbfd42ccSElyes Haouas #define N(a) nitems(a) 5112f961f4SSam Leffler 5212f961f4SSam Leffler const char *progname; 5312f961f4SSam Leffler 54b5720689SSam Leffler #define IEEE80211_MSG_11N 0x80000000 /* 11n mode debug */ 5512f961f4SSam Leffler #define IEEE80211_MSG_DEBUG 0x40000000 /* IFF_DEBUG equivalent */ 561f0cd2d9SElyes Haouas #define IEEE80211_MSG_DUMPPKTS 0x20000000 /* IFF_LINK2 equivalent */ 5712f961f4SSam Leffler #define IEEE80211_MSG_CRYPTO 0x10000000 /* crypto work */ 5812f961f4SSam Leffler #define IEEE80211_MSG_INPUT 0x08000000 /* input handling */ 5912f961f4SSam Leffler #define IEEE80211_MSG_XRATE 0x04000000 /* rate set handling */ 6012f961f4SSam Leffler #define IEEE80211_MSG_ELEMID 0x02000000 /* element id parsing */ 6112f961f4SSam Leffler #define IEEE80211_MSG_NODE 0x01000000 /* node handling */ 6212f961f4SSam Leffler #define IEEE80211_MSG_ASSOC 0x00800000 /* association handling */ 6312f961f4SSam Leffler #define IEEE80211_MSG_AUTH 0x00400000 /* authentication handling */ 6412f961f4SSam Leffler #define IEEE80211_MSG_SCAN 0x00200000 /* scanning */ 6512f961f4SSam Leffler #define IEEE80211_MSG_OUTPUT 0x00100000 /* output handling */ 6612f961f4SSam Leffler #define IEEE80211_MSG_STATE 0x00080000 /* state machine */ 6712f961f4SSam Leffler #define IEEE80211_MSG_POWER 0x00040000 /* power save handling */ 68412c4395SSam Leffler #define IEEE80211_MSG_HWMP 0x00020000 /* hybrid mesh protocol */ 6912f961f4SSam Leffler #define IEEE80211_MSG_DOT1XSM 0x00010000 /* 802.1x state machine */ 7012f961f4SSam Leffler #define IEEE80211_MSG_RADIUS 0x00008000 /* 802.1x radius client */ 7112f961f4SSam Leffler #define IEEE80211_MSG_RADDUMP 0x00004000 /* dump 802.1x radius packets */ 72412c4395SSam Leffler #define IEEE80211_MSG_MESH 0x00002000 /* mesh networking */ 7312f961f4SSam Leffler #define IEEE80211_MSG_WPA 0x00001000 /* WPA/RSN protocol */ 7412f961f4SSam Leffler #define IEEE80211_MSG_ACL 0x00000800 /* ACL handling */ 7512f961f4SSam Leffler #define IEEE80211_MSG_WME 0x00000400 /* WME protocol */ 7612f961f4SSam Leffler #define IEEE80211_MSG_SUPERG 0x00000200 /* Atheros SuperG protocol */ 7712f961f4SSam Leffler #define IEEE80211_MSG_DOTH 0x00000100 /* 802.11h support */ 7812f961f4SSam Leffler #define IEEE80211_MSG_INACT 0x00000080 /* inactivity handling */ 7912f961f4SSam Leffler #define IEEE80211_MSG_ROAM 0x00000040 /* sta-mode roaming */ 80cb3b3332SSam Leffler #define IEEE80211_MSG_RATECTL 0x00000020 /* tx rate control */ 81525de97eSSam Leffler #define IEEE80211_MSG_ACTION 0x00000010 /* action frame handling */ 82525de97eSSam Leffler #define IEEE80211_MSG_WDS 0x00000008 /* WDS handling */ 83525de97eSSam Leffler #define IEEE80211_MSG_IOCTL 0x00000004 /* ioctl handling */ 8410ad9a77SSam Leffler #define IEEE80211_MSG_TDMA 0x00000002 /* TDMA handling */ 8512f961f4SSam Leffler 8612f961f4SSam Leffler static struct { 8712f961f4SSam Leffler const char *name; 8812f961f4SSam Leffler u_int bit; 8912f961f4SSam Leffler } flags[] = { 90b5720689SSam Leffler { "11n", IEEE80211_MSG_11N }, 9112f961f4SSam Leffler { "debug", IEEE80211_MSG_DEBUG }, 9212f961f4SSam Leffler { "dumppkts", IEEE80211_MSG_DUMPPKTS }, 9312f961f4SSam Leffler { "crypto", IEEE80211_MSG_CRYPTO }, 9412f961f4SSam Leffler { "input", IEEE80211_MSG_INPUT }, 9512f961f4SSam Leffler { "xrate", IEEE80211_MSG_XRATE }, 9612f961f4SSam Leffler { "elemid", IEEE80211_MSG_ELEMID }, 9712f961f4SSam Leffler { "node", IEEE80211_MSG_NODE }, 9812f961f4SSam Leffler { "assoc", IEEE80211_MSG_ASSOC }, 9912f961f4SSam Leffler { "auth", IEEE80211_MSG_AUTH }, 10012f961f4SSam Leffler { "scan", IEEE80211_MSG_SCAN }, 10112f961f4SSam Leffler { "output", IEEE80211_MSG_OUTPUT }, 10212f961f4SSam Leffler { "state", IEEE80211_MSG_STATE }, 10312f961f4SSam Leffler { "power", IEEE80211_MSG_POWER }, 104412c4395SSam Leffler { "hwmp", IEEE80211_MSG_HWMP }, 10512f961f4SSam Leffler { "dot1xsm", IEEE80211_MSG_DOT1XSM }, 10612f961f4SSam Leffler { "radius", IEEE80211_MSG_RADIUS }, 10712f961f4SSam Leffler { "raddump", IEEE80211_MSG_RADDUMP }, 108412c4395SSam Leffler { "mesh", IEEE80211_MSG_MESH }, 10912f961f4SSam Leffler { "wpa", IEEE80211_MSG_WPA }, 11012f961f4SSam Leffler { "acl", IEEE80211_MSG_ACL }, 11112f961f4SSam Leffler { "wme", IEEE80211_MSG_WME }, 11212f961f4SSam Leffler { "superg", IEEE80211_MSG_SUPERG }, 11312f961f4SSam Leffler { "doth", IEEE80211_MSG_DOTH }, 11412f961f4SSam Leffler { "inact", IEEE80211_MSG_INACT }, 11512f961f4SSam Leffler { "roam", IEEE80211_MSG_ROAM }, 116cb3b3332SSam Leffler { "rate", IEEE80211_MSG_RATECTL }, 117525de97eSSam Leffler { "action", IEEE80211_MSG_ACTION }, 118525de97eSSam Leffler { "wds", IEEE80211_MSG_WDS }, 119525de97eSSam Leffler { "ioctl", IEEE80211_MSG_IOCTL }, 12010ad9a77SSam Leffler { "tdma", IEEE80211_MSG_TDMA }, 12112f961f4SSam Leffler }; 12212f961f4SSam Leffler 12312f961f4SSam Leffler static u_int 12412f961f4SSam Leffler getflag(const char *name, int len) 12512f961f4SSam Leffler { 12612f961f4SSam Leffler int i; 12712f961f4SSam Leffler 12812f961f4SSam Leffler for (i = 0; i < N(flags); i++) 12912f961f4SSam Leffler if (strncasecmp(flags[i].name, name, len) == 0) 13012f961f4SSam Leffler return flags[i].bit; 13112f961f4SSam Leffler return 0; 13212f961f4SSam Leffler } 13312f961f4SSam Leffler 13412f961f4SSam Leffler static void 13512f961f4SSam Leffler usage(void) 13612f961f4SSam Leffler { 13712f961f4SSam Leffler int i; 13812f961f4SSam Leffler 139433b4c16SAndrew Thompson fprintf(stderr, "usage: %s [-d | -i device] [flags]\n", progname); 14012f961f4SSam Leffler fprintf(stderr, "where flags are:\n"); 14112f961f4SSam Leffler for (i = 0; i < N(flags); i++) 14212f961f4SSam Leffler printf("%s\n", flags[i].name); 14312f961f4SSam Leffler exit(-1); 14412f961f4SSam Leffler } 14512f961f4SSam Leffler 146525de97eSSam Leffler static void 147525de97eSSam Leffler setoid(char oid[], size_t oidlen, const char *wlan) 148525de97eSSam Leffler { 149525de97eSSam Leffler #ifdef __linux__ 150433b4c16SAndrew Thompson if (wlan) 151525de97eSSam Leffler snprintf(oid, oidlen, "net.%s.debug", wlan); 152525de97eSSam Leffler #elif __FreeBSD__ 153433b4c16SAndrew Thompson if (wlan) 154525de97eSSam Leffler snprintf(oid, oidlen, "net.wlan.%s.debug", wlan+4); 155433b4c16SAndrew Thompson else 156433b4c16SAndrew Thompson snprintf(oid, oidlen, "net.wlan.debug"); 157525de97eSSam Leffler #elif __NetBSD__ 158433b4c16SAndrew Thompson if (wlan) 1599758983cSSam Leffler snprintf(oid, oidlen, "net.link.ieee80211.%s.debug", wlan); 160433b4c16SAndrew Thompson else 161433b4c16SAndrew Thompson snprintf(oid, oidlen, "net.link.ieee80211.debug"); 162525de97eSSam Leffler #else 163525de97eSSam Leffler #error "No support for this system" 164525de97eSSam Leffler #endif 165525de97eSSam Leffler } 166525de97eSSam Leffler 167238c9eb6SAndriy Voskoboinyk static void 168238c9eb6SAndriy Voskoboinyk get_orig_iface_name(char *oid, size_t oid_size, char *name) 169238c9eb6SAndriy Voskoboinyk { 170238c9eb6SAndriy Voskoboinyk struct ifconfig_handle *h; 171238c9eb6SAndriy Voskoboinyk char *orig_name; 172238c9eb6SAndriy Voskoboinyk 173238c9eb6SAndriy Voskoboinyk h = ifconfig_open(); 174e989c743SAndriy Voskoboinyk if (ifconfig_get_orig_name(h, name, &orig_name) < 0) { 175e989c743SAndriy Voskoboinyk /* check for original interface name. */ 176e989c743SAndriy Voskoboinyk orig_name = name; 177e989c743SAndriy Voskoboinyk } 178238c9eb6SAndriy Voskoboinyk 179e989c743SAndriy Voskoboinyk if (strlen(orig_name) < strlen("wlan") + 1 || 180e989c743SAndriy Voskoboinyk strncmp(orig_name, "wlan", 4) != 0) 1813ce85fa3SAndriy Voskoboinyk errx(1, "expecting a wlan interface name"); 1823ce85fa3SAndriy Voskoboinyk 183238c9eb6SAndriy Voskoboinyk ifconfig_close(h); 184238c9eb6SAndriy Voskoboinyk setoid(oid, oid_size, orig_name); 185e989c743SAndriy Voskoboinyk if (orig_name != name) 186238c9eb6SAndriy Voskoboinyk free(orig_name); 187238c9eb6SAndriy Voskoboinyk } 188238c9eb6SAndriy Voskoboinyk 18912f961f4SSam Leffler int 19012f961f4SSam Leffler main(int argc, char *argv[]) 19112f961f4SSam Leffler { 19212f961f4SSam Leffler const char *cp, *tp; 19312f961f4SSam Leffler const char *sep; 1949758983cSSam Leffler int op, i; 19512f961f4SSam Leffler u_int32_t debug, ndebug; 1969758983cSSam Leffler size_t debuglen; 197525de97eSSam Leffler char oid[256]; 19812f961f4SSam Leffler 19912f961f4SSam Leffler progname = argv[0]; 200525de97eSSam Leffler setoid(oid, sizeof(oid), "wlan0"); 20112f961f4SSam Leffler if (argc > 1) { 202433b4c16SAndrew Thompson if (strcmp(argv[1], "-d") == 0) { 203433b4c16SAndrew Thompson setoid(oid, sizeof(oid), NULL); 204433b4c16SAndrew Thompson argc -= 1, argv += 1; 205433b4c16SAndrew Thompson } else if (strcmp(argv[1], "-i") == 0) { 2063a1abb4cSHiren Panchasara if (argc <= 2) 20712f961f4SSam Leffler errx(1, "missing interface name for -i option"); 208238c9eb6SAndriy Voskoboinyk get_orig_iface_name(oid, sizeof(oid), argv[2]); 20912f961f4SSam Leffler argc -= 2, argv += 2; 21012f961f4SSam Leffler } else if (strcmp(argv[1], "-?") == 0) 21112f961f4SSam Leffler usage(); 21212f961f4SSam Leffler } 21312f961f4SSam Leffler 21412f961f4SSam Leffler debuglen = sizeof(debug); 21512f961f4SSam Leffler if (sysctlbyname(oid, &debug, &debuglen, NULL, 0) < 0) 21612f961f4SSam Leffler err(1, "sysctl-get(%s)", oid); 21712f961f4SSam Leffler ndebug = debug; 21812f961f4SSam Leffler for (; argc > 1; argc--, argv++) { 21912f961f4SSam Leffler cp = argv[1]; 22012f961f4SSam Leffler do { 22112f961f4SSam Leffler u_int bit; 22212f961f4SSam Leffler 22312f961f4SSam Leffler if (*cp == '-') { 22412f961f4SSam Leffler cp++; 22512f961f4SSam Leffler op = -1; 22612f961f4SSam Leffler } else if (*cp == '+') { 22712f961f4SSam Leffler cp++; 22812f961f4SSam Leffler op = 1; 22912f961f4SSam Leffler } else 23012f961f4SSam Leffler op = 0; 23112f961f4SSam Leffler for (tp = cp; *tp != '\0' && *tp != '+' && *tp != '-';) 23212f961f4SSam Leffler tp++; 23312f961f4SSam Leffler bit = getflag(cp, tp-cp); 23412f961f4SSam Leffler if (op < 0) 23512f961f4SSam Leffler ndebug &= ~bit; 23612f961f4SSam Leffler else if (op > 0) 23712f961f4SSam Leffler ndebug |= bit; 23812f961f4SSam Leffler else { 23912f961f4SSam Leffler if (bit == 0) { 240b5720689SSam Leffler int c = *cp; 241b5720689SSam Leffler if (isdigit(c)) 24212f961f4SSam Leffler bit = strtoul(cp, NULL, 0); 24312f961f4SSam Leffler else 24412f961f4SSam Leffler errx(1, "unknown flag %.*s", 245b5720689SSam Leffler (int)(tp-cp), cp); 24612f961f4SSam Leffler } 24712f961f4SSam Leffler ndebug = bit; 24812f961f4SSam Leffler } 24912f961f4SSam Leffler } while (*(cp = tp) != '\0'); 25012f961f4SSam Leffler } 25112f961f4SSam Leffler if (debug != ndebug) { 25212f961f4SSam Leffler printf("%s: 0x%x => ", oid, debug); 25312f961f4SSam Leffler if (sysctlbyname(oid, NULL, NULL, &ndebug, sizeof(ndebug)) < 0) 25412f961f4SSam Leffler err(1, "sysctl-set(%s)", oid); 25512f961f4SSam Leffler printf("0x%x", ndebug); 25612f961f4SSam Leffler debug = ndebug; 25712f961f4SSam Leffler } else 25812f961f4SSam Leffler printf("%s: 0x%x", oid, debug); 25912f961f4SSam Leffler sep = "<"; 26012f961f4SSam Leffler for (i = 0; i < N(flags); i++) 26112f961f4SSam Leffler if (debug & flags[i].bit) { 26212f961f4SSam Leffler printf("%s%s", sep, flags[i].name); 26312f961f4SSam Leffler sep = ","; 26412f961f4SSam Leffler } 26512f961f4SSam Leffler printf("%s\n", *sep != '<' ? ">" : ""); 26612f961f4SSam Leffler return 0; 26712f961f4SSam Leffler } 268