ieee80211_alq.c revision 220908
1220908Sadrian/*- 2220908Sadrian * Copyright (c) 2011 Adrian Chadd, Xenion Lty Ltd 3220908Sadrian * All rights reserved. 4220908Sadrian * 5220908Sadrian * Redistribution and use in source and binary forms, with or without 6220908Sadrian * modification, are permitted provided that the following conditions 7220908Sadrian * are met: 8220908Sadrian * 1. Redistributions of source code must retain the above copyright 9220908Sadrian * notice, this list of conditions and the following disclaimer. 10220908Sadrian * 2. Redistributions in binary form must reproduce the above copyright 11220908Sadrian * notice, this list of conditions and the following disclaimer in the 12220908Sadrian * documentation and/or other materials provided with the distribution. 13220908Sadrian * 14220908Sadrian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15220908Sadrian * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16220908Sadrian * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17220908Sadrian * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18220908Sadrian * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19220908Sadrian * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20220908Sadrian * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21220908Sadrian * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22220908Sadrian * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23220908Sadrian * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24220908Sadrian */ 25220908Sadrian 26220908Sadrian#include <sys/cdefs.h> 27220908Sadrian#ifdef __FreeBSD__ 28220908Sadrian__FBSDID("$FreeBSD: head/sys/net80211/ieee80211_alq.c 220908 2011-04-21 03:59:37Z adrian $"); 29220908Sadrian#endif 30220908Sadrian 31220908Sadrian/* 32220908Sadrian * net80211 fast-logging support, primarily for debugging. 33220908Sadrian * 34220908Sadrian * This implements a single debugging queue which includes 35220908Sadrian * per-device enumeration where needed. 36220908Sadrian */ 37220908Sadrian 38220908Sadrian#include "opt_wlan.h" 39220908Sadrian 40220908Sadrian#include <sys/param.h> 41220908Sadrian#include <sys/systm.h> 42220908Sadrian#include <sys/mbuf.h> 43220908Sadrian#include <sys/malloc.h> 44220908Sadrian#include <sys/endian.h> 45220908Sadrian#include <sys/kernel.h> 46220908Sadrian#include <sys/sysctl.h> 47220908Sadrian#include <sys/pcpu.h> 48220908Sadrian#include <sys/proc.h> 49220908Sadrian#include <sys/ucred.h> 50220908Sadrian#include <sys/alq.h> 51220908Sadrian 52220908Sadrian#include <sys/socket.h> 53220908Sadrian 54220908Sadrian#include <net/if.h> 55220908Sadrian#include <net/if_var.h> 56220908Sadrian#include <net/if_dl.h> 57220908Sadrian#include <net/if_clone.h> 58220908Sadrian#include <net/if_media.h> 59220908Sadrian#include <net/if_types.h> 60220908Sadrian 61220908Sadrian#include <net80211/ieee80211_var.h> 62220908Sadrian#include <net80211/ieee80211_freebsd.h> 63220908Sadrian#include <net80211/ieee80211_alq.h> 64220908Sadrian 65220908Sadrianstatic struct alq *ieee80211_alq; 66220908Sadrianstatic int ieee80211_alq_lost; 67220908Sadrianstatic char ieee80211_alq_logfile[MAXPATHLEN] = "/tmp/net80211.log"; 68220908Sadrianstatic unsigned int ieee80211_alq_qsize = 64*1024; 69220908Sadrian 70220908Sadrianstatic int 71220908Sadrianieee80211_alq_setlogging(int enable) 72220908Sadrian{ 73220908Sadrian int error; 74220908Sadrian 75220908Sadrian if (enable) { 76220908Sadrian if (ieee80211_alq) 77220908Sadrian alq_close(ieee80211_alq); 78220908Sadrian 79220908Sadrian error = alq_open(&ieee80211_alq, 80220908Sadrian ieee80211_alq_logfile, 81220908Sadrian curthread->td_ucred, 82220908Sadrian ALQ_DEFAULT_CMODE, 83220908Sadrian sizeof (struct ieee80211_alq_rec), 84220908Sadrian ieee80211_alq_qsize); 85220908Sadrian ieee80211_alq_lost = 0; 86220908Sadrian printf("net80211: logging to %s enabled\n", ieee80211_alq_logfile); 87220908Sadrian } else { 88220908Sadrian if (ieee80211_alq) 89220908Sadrian alq_close(ieee80211_alq); 90220908Sadrian ieee80211_alq = NULL; 91220908Sadrian printf("net80211: logging disabled\n"); 92220908Sadrian error = 0; 93220908Sadrian } 94220908Sadrian return (error); 95220908Sadrian} 96220908Sadrian 97220908Sadrianstatic int 98220908Sadriansysctl_ieee80211_alq_log(SYSCTL_HANDLER_ARGS) 99220908Sadrian{ 100220908Sadrian int error, enable; 101220908Sadrian 102220908Sadrian enable = (ieee80211_alq != NULL); 103220908Sadrian error = sysctl_handle_int(oidp, &enable, 0, req); 104220908Sadrian if (error || !req->newptr) 105220908Sadrian return (error); 106220908Sadrian else 107220908Sadrian return (ieee80211_alq_setlogging(enable)); 108220908Sadrian} 109220908Sadrian 110220908SadrianSYSCTL_PROC(_net_wlan, OID_AUTO, alq, CTLTYPE_INT|CTLFLAG_RW, 111220908Sadrian 0, 0, sysctl_ieee80211_alq_log, "I", "Enable net80211 alq logging"); 112220908SadrianSYSCTL_INT(_net_wlan, OID_AUTO, alq_size, CTLFLAG_RW, 113220908Sadrian &ieee80211_alq_qsize, 0, "In-memory log size (#records)"); 114220908SadrianSYSCTL_INT(_net_wlan, OID_AUTO, alq_lost, CTLFLAG_RW, 115220908Sadrian &ieee80211_alq_lost, 0, "Debugging operations not logged"); 116220908Sadrian 117220908Sadrianstatic struct ale * 118220908Sadrianieee80211_alq_get(void) 119220908Sadrian{ 120220908Sadrian struct ale *ale; 121220908Sadrian 122220908Sadrian ale = alq_get(ieee80211_alq, ALQ_NOWAIT); 123220908Sadrian if (!ale) 124220908Sadrian ieee80211_alq_lost++; 125220908Sadrian return ale; 126220908Sadrian} 127220908Sadrian 128220908Sadrianvoid 129220908Sadrianieee80211_alq_log(struct ieee80211vap *vap, uint8_t op, u_char *p, int l) 130220908Sadrian{ 131220908Sadrian struct ale *ale; 132220908Sadrian struct ieee80211_alq_rec *r; 133220908Sadrian 134220908Sadrian ale = ieee80211_alq_get(); 135220908Sadrian if (! ale) 136220908Sadrian return; 137220908Sadrian 138220908Sadrian r = (struct ieee80211_alq_rec *) ale; 139220908Sadrian r->r_timestamp = ticks; 140220908Sadrian r->r_version = 1; 141220908Sadrian r->r_wlan = vap->iv_ifp->if_dunit; 142220908Sadrian r->r_op = op; 143220908Sadrian memcpy(&r->r_payload, p, MIN(l, sizeof(r->r_payload))); 144220908Sadrian} 145