1272343Sngie/*- 2272343Sngie * SPDX-License-Identifier: BSD-2-Clause 3272343Sngie * 4272343Sngie * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting 5272343Sngie * All rights reserved. 6272343Sngie * 7272343Sngie * Redistribution and use in source and binary forms, with or without 8272343Sngie * modification, are permitted provided that the following conditions 9272343Sngie * are met: 10272343Sngie * 1. Redistributions of source code must retain the above copyright 11272343Sngie * notice, this list of conditions and the following disclaimer, 12272343Sngie * without modification. 13272343Sngie * 2. Redistributions in binary form must reproduce at minimum a disclaimer 14272343Sngie * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 15272343Sngie * redistribution must be conditioned upon including a substantially 16272343Sngie * similar Disclaimer requirement for further binary redistribution. 17272343Sngie * 18272343Sngie * NO WARRANTY 19272343Sngie * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20272343Sngie * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21272343Sngie * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 22272343Sngie * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 23272343Sngie * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 24272343Sngie * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25272343Sngie * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26272343Sngie * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 27272343Sngie * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28272343Sngie * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 29272343Sngie * THE POSSIBILITY OF SUCH DAMAGES. 30272343Sngie */ 31272343Sngie 32272343Sngie/* 33272343Sngie * wlandebug [-i interface] flags 34272343Sngie * (default interface is wlan.0). 35272343Sngie */ 36272343Sngie#include <sys/param.h> 37272343Sngie#include <sys/sysctl.h> 38272343Sngie 39272343Sngie#include <net/if.h> 40272343Sngie 41272343Sngie#include <stdio.h> 42272343Sngie#include <stdlib.h> 43272343Sngie#include <ctype.h> 44272343Sngie#include <getopt.h> 45272343Sngie#include <string.h> 46272343Sngie#include <err.h> 47272343Sngie 48272343Sngie#include <libifconfig.h> 49272343Sngie 50272343Sngie#define N(a) nitems(a) 51272343Sngie 52272343Sngieconst char *progname; 53272343Sngie 54272343Sngie#define IEEE80211_MSG_11N 0x80000000 /* 11n mode debug */ 55272343Sngie#define IEEE80211_MSG_DEBUG 0x40000000 /* IFF_DEBUG equivalent */ 56272343Sngie#define IEEE80211_MSG_DUMPPKTS 0x20000000 /* IFF_LINK2 equivalent */ 57272343Sngie#define IEEE80211_MSG_CRYPTO 0x10000000 /* crypto work */ 58272343Sngie#define IEEE80211_MSG_INPUT 0x08000000 /* input handling */ 59272343Sngie#define IEEE80211_MSG_XRATE 0x04000000 /* rate set handling */ 60272343Sngie#define IEEE80211_MSG_ELEMID 0x02000000 /* element id parsing */ 61272343Sngie#define IEEE80211_MSG_NODE 0x01000000 /* node handling */ 62272343Sngie#define IEEE80211_MSG_ASSOC 0x00800000 /* association handling */ 63272343Sngie#define IEEE80211_MSG_AUTH 0x00400000 /* authentication handling */ 64272343Sngie#define IEEE80211_MSG_SCAN 0x00200000 /* scanning */ 65272343Sngie#define IEEE80211_MSG_OUTPUT 0x00100000 /* output handling */ 66272343Sngie#define IEEE80211_MSG_STATE 0x00080000 /* state machine */ 67272343Sngie#define IEEE80211_MSG_POWER 0x00040000 /* power save handling */ 68272343Sngie#define IEEE80211_MSG_HWMP 0x00020000 /* hybrid mesh protocol */ 69272343Sngie#define IEEE80211_MSG_DOT1XSM 0x00010000 /* 802.1x state machine */ 70272343Sngie#define IEEE80211_MSG_RADIUS 0x00008000 /* 802.1x radius client */ 71272343Sngie#define IEEE80211_MSG_RADDUMP 0x00004000 /* dump 802.1x radius packets */ 72272343Sngie#define IEEE80211_MSG_MESH 0x00002000 /* mesh networking */ 73272343Sngie#define IEEE80211_MSG_WPA 0x00001000 /* WPA/RSN protocol */ 74272343Sngie#define IEEE80211_MSG_ACL 0x00000800 /* ACL handling */ 75272343Sngie#define IEEE80211_MSG_WME 0x00000400 /* WME protocol */ 76272343Sngie#define IEEE80211_MSG_SUPERG 0x00000200 /* Atheros SuperG protocol */ 77272343Sngie#define IEEE80211_MSG_DOTH 0x00000100 /* 802.11h support */ 78272343Sngie#define IEEE80211_MSG_INACT 0x00000080 /* inactivity handling */ 79272343Sngie#define IEEE80211_MSG_ROAM 0x00000040 /* sta-mode roaming */ 80272343Sngie#define IEEE80211_MSG_RATECTL 0x00000020 /* tx rate control */ 81272343Sngie#define IEEE80211_MSG_ACTION 0x00000010 /* action frame handling */ 82272343Sngie#define IEEE80211_MSG_WDS 0x00000008 /* WDS handling */ 83272343Sngie#define IEEE80211_MSG_IOCTL 0x00000004 /* ioctl handling */ 84272343Sngie#define IEEE80211_MSG_TDMA 0x00000002 /* TDMA handling */ 85272343Sngie 86272343Sngiestatic struct { 87272343Sngie const char *name; 88272343Sngie u_int bit; 89272343Sngie} flags[] = { 90272343Sngie { "11n", IEEE80211_MSG_11N }, 91272343Sngie { "debug", IEEE80211_MSG_DEBUG }, 92272343Sngie { "dumppkts", IEEE80211_MSG_DUMPPKTS }, 93272343Sngie { "crypto", IEEE80211_MSG_CRYPTO }, 94272343Sngie { "input", IEEE80211_MSG_INPUT }, 95272343Sngie { "xrate", IEEE80211_MSG_XRATE }, 96272343Sngie { "elemid", IEEE80211_MSG_ELEMID }, 97272343Sngie { "node", IEEE80211_MSG_NODE }, 98272343Sngie { "assoc", IEEE80211_MSG_ASSOC }, 99272343Sngie { "auth", IEEE80211_MSG_AUTH }, 100272343Sngie { "scan", IEEE80211_MSG_SCAN }, 101272343Sngie { "output", IEEE80211_MSG_OUTPUT }, 102272343Sngie { "state", IEEE80211_MSG_STATE }, 103272343Sngie { "power", IEEE80211_MSG_POWER }, 104272343Sngie { "hwmp", IEEE80211_MSG_HWMP }, 105272343Sngie { "dot1xsm", IEEE80211_MSG_DOT1XSM }, 106272343Sngie { "radius", IEEE80211_MSG_RADIUS }, 107272343Sngie { "raddump", IEEE80211_MSG_RADDUMP }, 108272343Sngie { "mesh", IEEE80211_MSG_MESH }, 109272343Sngie { "wpa", IEEE80211_MSG_WPA }, 110272343Sngie { "acl", IEEE80211_MSG_ACL }, 111272343Sngie { "wme", IEEE80211_MSG_WME }, 112272343Sngie { "superg", IEEE80211_MSG_SUPERG }, 113272343Sngie { "doth", IEEE80211_MSG_DOTH }, 114272343Sngie { "inact", IEEE80211_MSG_INACT }, 115272343Sngie { "roam", IEEE80211_MSG_ROAM }, 116272343Sngie { "rate", IEEE80211_MSG_RATECTL }, 117272343Sngie { "action", IEEE80211_MSG_ACTION }, 118272343Sngie { "wds", IEEE80211_MSG_WDS }, 119272343Sngie { "ioctl", IEEE80211_MSG_IOCTL }, 120272343Sngie { "tdma", IEEE80211_MSG_TDMA }, 121272343Sngie}; 122272343Sngie 123272343Sngiestatic u_int 124272343Sngiegetflag(const char *name, int len) 125272343Sngie{ 126272343Sngie int i; 127272343Sngie 128272343Sngie for (i = 0; i < N(flags); i++) 129272343Sngie if (strncasecmp(flags[i].name, name, len) == 0) 130272343Sngie return flags[i].bit; 131272343Sngie return 0; 132272343Sngie} 133272343Sngie 134272343Sngiestatic void 135272343Sngieusage(void) 136272343Sngie{ 137272343Sngie int i; 138272343Sngie 139272343Sngie fprintf(stderr, "usage: %s [-d | -i device] [flags]\n", progname); 140272343Sngie fprintf(stderr, "where flags are:\n"); 141272343Sngie for (i = 0; i < N(flags); i++) 142272343Sngie printf("%s\n", flags[i].name); 143272343Sngie exit(-1); 144272343Sngie} 145272343Sngie 146272343Sngiestatic void 147272343Sngiesetoid(char oid[], size_t oidlen, const char *wlan) 148272343Sngie{ 149272343Sngie#ifdef __linux__ 150272343Sngie if (wlan) 151272343Sngie snprintf(oid, oidlen, "net.%s.debug", wlan); 152272343Sngie#elif __FreeBSD__ 153272343Sngie if (wlan) 154272343Sngie snprintf(oid, oidlen, "net.wlan.%s.debug", wlan+4); 155272343Sngie else 156272343Sngie snprintf(oid, oidlen, "net.wlan.debug"); 157272343Sngie#elif __NetBSD__ 158272343Sngie if (wlan) 159272343Sngie snprintf(oid, oidlen, "net.link.ieee80211.%s.debug", wlan); 160272343Sngie else 161272343Sngie snprintf(oid, oidlen, "net.link.ieee80211.debug"); 162272343Sngie#else 163272343Sngie#error "No support for this system" 164272343Sngie#endif 165272343Sngie} 166272343Sngie 167272343Sngiestatic void 168272343Sngieget_orig_iface_name(char *oid, size_t oid_size, char *name) 169272343Sngie{ 170272343Sngie struct ifconfig_handle *h; 171272343Sngie char *orig_name; 172272343Sngie 173272343Sngie h = ifconfig_open(); 174272343Sngie if (ifconfig_get_orig_name(h, name, &orig_name) < 0) { 175272343Sngie /* check for original interface name. */ 176272343Sngie orig_name = name; 177272343Sngie } 178272343Sngie 179272343Sngie if (strlen(orig_name) < strlen("wlan") + 1 || 180272343Sngie strncmp(orig_name, "wlan", 4) != 0) 181272343Sngie errx(1, "expecting a wlan interface name"); 182272343Sngie 183272343Sngie ifconfig_close(h); 184272343Sngie setoid(oid, oid_size, orig_name); 185272343Sngie if (orig_name != name) 186272343Sngie free(orig_name); 187272343Sngie} 188272343Sngie 189272343Sngieint 190272343Sngiemain(int argc, char *argv[]) 191272343Sngie{ 192272343Sngie const char *cp, *tp; 193272343Sngie const char *sep; 194272343Sngie int op, i; 195272343Sngie u_int32_t debug, ndebug; 196272343Sngie size_t debuglen; 197272343Sngie char oid[256]; 198272343Sngie 199272343Sngie progname = argv[0]; 200272343Sngie setoid(oid, sizeof(oid), "wlan0"); 201272343Sngie if (argc > 1) { 202272343Sngie if (strcmp(argv[1], "-d") == 0) { 203272343Sngie setoid(oid, sizeof(oid), NULL); 204272343Sngie argc -= 1, argv += 1; 205272343Sngie } else if (strcmp(argv[1], "-i") == 0) { 206272343Sngie if (argc <= 2) 207272343Sngie errx(1, "missing interface name for -i option"); 208272343Sngie get_orig_iface_name(oid, sizeof(oid), argv[2]); 209272343Sngie argc -= 2, argv += 2; 210272343Sngie } else if (strcmp(argv[1], "-?") == 0) 211272343Sngie usage(); 212272343Sngie } 213272343Sngie 214272343Sngie debuglen = sizeof(debug); 215272343Sngie if (sysctlbyname(oid, &debug, &debuglen, NULL, 0) < 0) 216272343Sngie err(1, "sysctl-get(%s)", oid); 217272343Sngie ndebug = debug; 218272343Sngie for (; argc > 1; argc--, argv++) { 219272343Sngie cp = argv[1]; 220272343Sngie do { 221272343Sngie u_int bit; 222272343Sngie 223272343Sngie if (*cp == '-') { 224272343Sngie cp++; 225272343Sngie op = -1; 226272343Sngie } else if (*cp == '+') { 227272343Sngie cp++; 228272343Sngie op = 1; 229272343Sngie } else 230272343Sngie op = 0; 231272343Sngie for (tp = cp; *tp != '\0' && *tp != '+' && *tp != '-';) 232272343Sngie tp++; 233272343Sngie bit = getflag(cp, tp-cp); 234272343Sngie if (op < 0) 235272343Sngie ndebug &= ~bit; 236272343Sngie else if (op > 0) 237272343Sngie ndebug |= bit; 238272343Sngie else { 239272343Sngie if (bit == 0) { 240272343Sngie int c = *cp; 241272343Sngie if (isdigit(c)) 242272343Sngie bit = strtoul(cp, NULL, 0); 243272343Sngie else 244272343Sngie errx(1, "unknown flag %.*s", 245272343Sngie (int)(tp-cp), cp); 246272343Sngie } 247272343Sngie ndebug = bit; 248272343Sngie } 249272343Sngie } while (*(cp = tp) != '\0'); 250272343Sngie } 251272343Sngie if (debug != ndebug) { 252272343Sngie printf("%s: 0x%x => ", oid, debug); 253272343Sngie if (sysctlbyname(oid, NULL, NULL, &ndebug, sizeof(ndebug)) < 0) 254272343Sngie err(1, "sysctl-set(%s)", oid); 255272343Sngie printf("0x%x", ndebug); 256272343Sngie debug = ndebug; 257272343Sngie } else 258272343Sngie printf("%s: 0x%x", oid, debug); 259272343Sngie sep = "<"; 260272343Sngie for (i = 0; i < N(flags); i++) 261272343Sngie if (debug & flags[i].bit) { 262272343Sngie printf("%s%s", sep, flags[i].name); 263272343Sngie sep = ","; 264272343Sngie } 265272343Sngie printf("%s\n", *sep != '<' ? ">" : ""); 266272343Sngie return 0; 267272343Sngie} 268272343Sngie