ifieee80211.c revision 127831
177218Sphk/* 277218Sphk * Copyright 2001 The Aerospace Corporation. All rights reserved. 377218Sphk * 477218Sphk * Redistribution and use in source and binary forms, with or without 577218Sphk * modification, are permitted provided that the following conditions 677218Sphk * are met: 777218Sphk * 1. Redistributions of source code must retain the above copyright 877218Sphk * notice, this list of conditions and the following disclaimer. 977218Sphk * 2. Redistributions in binary form must reproduce the above copyright 1077218Sphk * notice, this list of conditions and the following disclaimer in the 1177218Sphk * documentation and/or other materials provided with the distribution. 1291454Sbrooks * 3. The name of The Aerospace Corporation may not be used to endorse or 1391454Sbrooks * promote products derived from this software. 1477218Sphk * 1577218Sphk * THIS SOFTWARE IS PROVIDED BY THE AEROSPACE CORPORATION ``AS IS'' AND 1677218Sphk * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1777218Sphk * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1877218Sphk * ARE DISCLAIMED. IN NO EVENT SHALL THE AEROSPACE CORPORATION BE LIABLE 1977218Sphk * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2077218Sphk * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2177218Sphk * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2277218Sphk * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2377218Sphk * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2477218Sphk * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2577218Sphk * SUCH DAMAGE. 2677218Sphk * 2777218Sphk * $FreeBSD: head/sbin/ifconfig/ifieee80211.c 127831 2004-04-04 07:28:58Z phk $ 2877218Sphk */ 2977218Sphk 3077218Sphk/*- 3177218Sphk * Copyright (c) 1997, 1998, 2000 The NetBSD Foundation, Inc. 3277218Sphk * All rights reserved. 3377218Sphk * 3477218Sphk * This code is derived from software contributed to The NetBSD Foundation 3577218Sphk * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 3677218Sphk * NASA Ames Research Center. 3777218Sphk * 3877218Sphk * Redistribution and use in source and binary forms, with or without 3977218Sphk * modification, are permitted provided that the following conditions 4077218Sphk * are met: 4177218Sphk * 1. Redistributions of source code must retain the above copyright 4277218Sphk * notice, this list of conditions and the following disclaimer. 4377218Sphk * 2. Redistributions in binary form must reproduce the above copyright 4477218Sphk * notice, this list of conditions and the following disclaimer in the 4577218Sphk * documentation and/or other materials provided with the distribution. 4677218Sphk * 3. All advertising materials mentioning features or use of this software 4777218Sphk * must display the following acknowledgement: 4877218Sphk * This product includes software developed by the NetBSD 4977218Sphk * Foundation, Inc. and its contributors. 5077218Sphk * 4. Neither the name of The NetBSD Foundation nor the names of its 5177218Sphk * contributors may be used to endorse or promote products derived 5277218Sphk * from this software without specific prior written permission. 5377218Sphk * 5477218Sphk * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 5577218Sphk * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 5677218Sphk * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 5777218Sphk * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 5877218Sphk * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 5977218Sphk * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 6077218Sphk * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 6177218Sphk * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 6277218Sphk * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 6377218Sphk * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 6477218Sphk * POSSIBILITY OF SUCH DAMAGE. 6577218Sphk */ 6677218Sphk 6777218Sphk#include <sys/param.h> 6877218Sphk#include <sys/ioctl.h> 6977218Sphk#include <sys/socket.h> 7077218Sphk#include <sys/sysctl.h> 7177218Sphk#include <sys/time.h> 7277218Sphk 7377218Sphk#include <net/ethernet.h> 7477218Sphk#include <net/if.h> 7577218Sphk#include <net/if_dl.h> 7677218Sphk#include <net/if_types.h> 7777218Sphk#include <net/route.h> 78116957Ssam#include <net80211/ieee80211.h> 79120178Ssam#include <net80211/ieee80211_crypto.h> 80116957Ssam#include <net80211/ieee80211_ioctl.h> 8177218Sphk 8277218Sphk#include <ctype.h> 8377218Sphk#include <err.h> 8477218Sphk#include <errno.h> 8577218Sphk#include <fcntl.h> 8677218Sphk#include <stdio.h> 8777218Sphk#include <stdlib.h> 8877218Sphk#include <string.h> 8977218Sphk#include <unistd.h> 9077218Sphk 9177218Sphk#include "ifconfig.h" 9277218Sphk 9377218Sphkstatic void set80211(int s, int type, int val, int len, u_int8_t *data); 9477218Sphkstatic const char *get_string(const char *val, const char *sep, 9577218Sphk u_int8_t *buf, int *lenp); 9677218Sphkstatic void print_string(const u_int8_t *buf, int len); 9777218Sphk 9877218Sphkvoid 9977218Sphkset80211ssid(const char *val, int d, int s, const struct afswtch *rafp) 10077218Sphk{ 10177218Sphk int ssid; 10277218Sphk int len; 10377218Sphk u_int8_t data[33]; 10477218Sphk 10577218Sphk ssid = 0; 106121827Sbrooks len = strlen(val); 10788748Sambrisko if (len > 2 && isdigit(val[0]) && val[1] == ':') { 10888748Sambrisko ssid = atoi(val)-1; 10988748Sambrisko val += 2; 11088748Sambrisko } 11177218Sphk 11277218Sphk bzero(data, sizeof(data)); 11377218Sphk len = sizeof(data); 11477218Sphk get_string(val, NULL, data, &len); 11577218Sphk 11677218Sphk set80211(s, IEEE80211_IOC_SSID, ssid, len, data); 11777218Sphk} 11877218Sphk 11977218Sphkvoid 12077218Sphkset80211stationname(const char *val, int d, int s, const struct afswtch *rafp) 12177218Sphk{ 12277218Sphk int len; 12377218Sphk u_int8_t data[33]; 12477218Sphk 12577218Sphk bzero(data, sizeof(data)); 12677218Sphk len = sizeof(data); 12777218Sphk get_string(val, NULL, data, &len); 12877218Sphk 12977218Sphk set80211(s, IEEE80211_IOC_STATIONNAME, 0, len, data); 13077218Sphk} 13177218Sphk 13277218Sphkvoid 13377218Sphkset80211channel(const char *val, int d, int s, const struct afswtch *rafp) 13477218Sphk{ 135116957Ssam if (strcmp(val, "-") == 0) 136116957Ssam set80211(s, IEEE80211_IOC_CHANNEL, IEEE80211_CHAN_ANY, 0, NULL); 137116957Ssam else 138116957Ssam set80211(s, IEEE80211_IOC_CHANNEL, atoi(val), 0, NULL); 13977218Sphk} 14077218Sphk 14177218Sphkvoid 14277218Sphkset80211authmode(const char *val, int d, int s, const struct afswtch *rafp) 14377218Sphk{ 14477218Sphk int mode; 14577218Sphk 14691454Sbrooks if (strcasecmp(val, "none") == 0) { 14777218Sphk mode = IEEE80211_AUTH_NONE; 14891454Sbrooks } else if (strcasecmp(val, "open") == 0) { 14977218Sphk mode = IEEE80211_AUTH_OPEN; 15091454Sbrooks } else if (strcasecmp(val, "shared") == 0) { 15177218Sphk mode = IEEE80211_AUTH_SHARED; 15277218Sphk } else { 15377218Sphk err(1, "unknown authmode"); 15477218Sphk } 15577218Sphk 15677218Sphk set80211(s, IEEE80211_IOC_AUTHMODE, mode, 0, NULL); 15777218Sphk} 15877218Sphk 15977218Sphkvoid 16077218Sphkset80211powersavemode(const char *val, int d, int s, const struct afswtch *rafp) 16177218Sphk{ 16277218Sphk int mode; 16377218Sphk 16491454Sbrooks if (strcasecmp(val, "off") == 0) { 16577218Sphk mode = IEEE80211_POWERSAVE_OFF; 16691454Sbrooks } else if (strcasecmp(val, "on") == 0) { 16777218Sphk mode = IEEE80211_POWERSAVE_ON; 16891454Sbrooks } else if (strcasecmp(val, "cam") == 0) { 16977218Sphk mode = IEEE80211_POWERSAVE_CAM; 17091454Sbrooks } else if (strcasecmp(val, "psp") == 0) { 17177218Sphk mode = IEEE80211_POWERSAVE_PSP; 17291454Sbrooks } else if (strcasecmp(val, "psp-cam") == 0) { 17377218Sphk mode = IEEE80211_POWERSAVE_PSP_CAM; 17477218Sphk } else { 17577218Sphk err(1, "unknown powersavemode"); 17677218Sphk } 17777218Sphk 17877218Sphk set80211(s, IEEE80211_IOC_POWERSAVE, mode, 0, NULL); 17977218Sphk} 18077218Sphk 18177218Sphkvoid 18277218Sphkset80211powersave(const char *val, int d, int s, const struct afswtch *rafp) 18377218Sphk{ 18477218Sphk if (d == 0) 18577218Sphk set80211(s, IEEE80211_IOC_POWERSAVE, IEEE80211_POWERSAVE_OFF, 18677218Sphk 0, NULL); 18777218Sphk else 18877218Sphk set80211(s, IEEE80211_IOC_POWERSAVE, IEEE80211_POWERSAVE_ON, 18977218Sphk 0, NULL); 19077218Sphk} 19177218Sphk 19277218Sphkvoid 19377218Sphkset80211powersavesleep(const char *val, int d, int s, const struct afswtch *rafp) 19477218Sphk{ 19577218Sphk set80211(s, IEEE80211_IOC_POWERSAVESLEEP, atoi(val), 0, NULL); 19677218Sphk} 19777218Sphk 19877218Sphkvoid 19977218Sphkset80211wepmode(const char *val, int d, int s, const struct afswtch *rafp) 20077218Sphk{ 20177218Sphk int mode; 20277218Sphk 20391454Sbrooks if (strcasecmp(val, "off") == 0) { 20477218Sphk mode = IEEE80211_WEP_OFF; 20591454Sbrooks } else if (strcasecmp(val, "on") == 0) { 20677218Sphk mode = IEEE80211_WEP_ON; 20791454Sbrooks } else if (strcasecmp(val, "mixed") == 0) { 20877218Sphk mode = IEEE80211_WEP_MIXED; 20977218Sphk } else { 21077218Sphk err(1, "unknown wep mode"); 21177218Sphk } 21277218Sphk 21377218Sphk set80211(s, IEEE80211_IOC_WEP, mode, 0, NULL); 21477218Sphk} 21577218Sphk 21677218Sphkvoid 21777218Sphkset80211wep(const char *val, int d, int s, const struct afswtch *rafp) 21877218Sphk{ 21977218Sphk set80211(s, IEEE80211_IOC_WEP, d, 0, NULL); 22077218Sphk} 22177218Sphk 22277218Sphkvoid 22377218Sphkset80211weptxkey(const char *val, int d, int s, const struct afswtch *rafp) 22477218Sphk{ 22577218Sphk set80211(s, IEEE80211_IOC_WEPTXKEY, atoi(val)-1, 0, NULL); 22677218Sphk} 22777218Sphk 22877218Sphkvoid 22977218Sphkset80211wepkey(const char *val, int d, int s, const struct afswtch *rafp) 23077218Sphk{ 23177218Sphk int key = 0; 23277218Sphk int len; 233120178Ssam u_int8_t data[IEEE80211_KEYBUF_SIZE]; 23477218Sphk 23591454Sbrooks if (isdigit(val[0]) && val[1] == ':') { 23677218Sphk key = atoi(val)-1; 23777218Sphk val += 2; 23877218Sphk } 23977218Sphk 24077218Sphk bzero(data, sizeof(data)); 24177218Sphk len = sizeof(data); 24277218Sphk get_string(val, NULL, data, &len); 24377218Sphk 24477218Sphk set80211(s, IEEE80211_IOC_WEPKEY, key, len, data); 24577218Sphk} 24677218Sphk 24777218Sphk/* 24877218Sphk * This function is purly a NetBSD compatability interface. The NetBSD 24977218Sphk * iterface is too inflexable, but it's there so we'll support it since 25077218Sphk * it's not all that hard. 25177218Sphk */ 25277218Sphkvoid 25377218Sphkset80211nwkey(const char *val, int d, int s, const struct afswtch *rafp) 25477218Sphk{ 25577218Sphk int txkey; 25677218Sphk int i, len; 257120178Ssam u_int8_t data[IEEE80211_KEYBUF_SIZE]; 25877218Sphk 25977218Sphk set80211(s, IEEE80211_IOC_WEP, IEEE80211_WEP_ON, 0, NULL); 26077218Sphk 26191454Sbrooks if (isdigit(val[0]) && val[1] == ':') { 26277218Sphk txkey = val[0]-'0'-1; 26377218Sphk val += 2; 26477218Sphk 26591454Sbrooks for (i = 0; i < 4; i++) { 26677218Sphk bzero(data, sizeof(data)); 26777218Sphk len = sizeof(data); 26877218Sphk val = get_string(val, ",", data, &len); 26977218Sphk 27077218Sphk set80211(s, IEEE80211_IOC_WEPKEY, i, len, data); 27177218Sphk } 27277218Sphk } else { 27377218Sphk bzero(data, sizeof(data)); 27477218Sphk len = sizeof(data); 27577218Sphk get_string(val, NULL, data, &len); 27677218Sphk txkey = 0; 27777218Sphk 27877218Sphk set80211(s, IEEE80211_IOC_WEPKEY, 0, len, data); 27977218Sphk 28077218Sphk bzero(data, sizeof(data)); 28191454Sbrooks for (i = 1; i < 4; i++) 28277218Sphk set80211(s, IEEE80211_IOC_WEPKEY, i, 0, data); 28377218Sphk } 28477218Sphk 28577218Sphk set80211(s, IEEE80211_IOC_WEPTXKEY, txkey, 0, NULL); 28677218Sphk} 28777218Sphk 28877218Sphkvoid 289127649Ssamset80211rtsthreshold(const char *val, int d, int s, const struct afswtch *rafp) 290127649Ssam{ 291127649Ssam set80211(s, IEEE80211_IOC_RTSTHRESHOLD, atoi(val), 0, NULL); 292127649Ssam} 293127649Ssam 294127649Ssamvoid 295127649Ssamset80211protmode(const char *val, int d, int s, const struct afswtch *rafp) 296127649Ssam{ 297127649Ssam int mode; 298127649Ssam 299127649Ssam if (strcasecmp(val, "off") == 0) { 300127649Ssam mode = IEEE80211_PROTMODE_OFF; 301127649Ssam } else if (strcasecmp(val, "cts") == 0) { 302127649Ssam mode = IEEE80211_PROTMODE_CTS; 303127649Ssam } else if (strcasecmp(val, "rtscts") == 0) { 304127649Ssam mode = IEEE80211_PROTMODE_RTSCTS; 305127649Ssam } else { 306127649Ssam err(1, "unknown protection mode"); 307127649Ssam } 308127649Ssam 309127649Ssam set80211(s, IEEE80211_IOC_PROTMODE, mode, 0, NULL); 310127649Ssam} 311127649Ssam 312127649Ssamvoid 313127649Ssamset80211txpower(const char *val, int d, int s, const struct afswtch *rafp) 314127649Ssam{ 315127649Ssam set80211(s, IEEE80211_IOC_TXPOWER, atoi(val), 0, NULL); 316127649Ssam} 317127649Ssam 318127649Ssamvoid 31995005Simpieee80211_status (int s, struct rt_addrinfo *info __unused) 32077218Sphk{ 32177218Sphk int i; 32277218Sphk int num; 32377218Sphk struct ieee80211req ireq; 32477218Sphk u_int8_t data[32]; 32577218Sphk char spacer; 32677218Sphk 32777218Sphk (void) memset(&ireq, 0, sizeof(ireq)); 32877218Sphk (void) strncpy(ireq.i_name, name, sizeof(ireq.i_name)); 32977218Sphk ireq.i_data = &data; 33077218Sphk 33177218Sphk ireq.i_type = IEEE80211_IOC_SSID; 33277218Sphk ireq.i_val = -1; 33377218Sphk if (ioctl(s, SIOCG80211, &ireq) < 0) { 33477218Sphk /* If we can't get the SSID, the this isn't an 802.11 device. */ 33577218Sphk return; 33677218Sphk } 33777218Sphk printf("\tssid "); 33877218Sphk print_string(data, ireq.i_len); 33988748Sambrisko num = 0; 34088748Sambrisko ireq.i_type = IEEE80211_IOC_NUMSSIDS; 34188748Sambrisko if (ioctl(s, SIOCG80211, &ireq) >= 0) { 34288748Sambrisko num = ireq.i_val; 34388748Sambrisko } 34488748Sambrisko ireq.i_type = IEEE80211_IOC_SSID; 34588748Sambrisko for (ireq.i_val = 0; ireq.i_val < num; ireq.i_val++) { 34688748Sambrisko if (ioctl(s, SIOCG80211, &ireq) >= 0 && ireq.i_len > 0) { 34788748Sambrisko printf(" %d:", ireq.i_val + 1); 34888748Sambrisko print_string(data, ireq.i_len); 34988748Sambrisko } 35088748Sambrisko } 35177218Sphk printf("\n"); 35277218Sphk 35377218Sphk ireq.i_type = IEEE80211_IOC_STATIONNAME; 35477218Sphk if (ioctl(s, SIOCG80211, &ireq) != -1) { 35577218Sphk printf("\tstationname "); 35677218Sphk print_string(data, ireq.i_len); 35777218Sphk printf("\n"); 35877218Sphk } 35977218Sphk 36077218Sphk ireq.i_type = IEEE80211_IOC_CHANNEL; 36177218Sphk if (ioctl(s, SIOCG80211, &ireq) < 0) { 36277218Sphk goto end; 36377218Sphk } 36477218Sphk printf("\tchannel %d", ireq.i_val); 36577218Sphk 36677218Sphk ireq.i_type = IEEE80211_IOC_AUTHMODE; 36777218Sphk if (ioctl(s, SIOCG80211, &ireq) != -1) { 36877218Sphk printf(" authmode"); 36977218Sphk switch (ireq.i_val) { 37077218Sphk case IEEE80211_AUTH_NONE: 37177218Sphk printf(" NONE"); 37277218Sphk break; 37377218Sphk case IEEE80211_AUTH_OPEN: 37477218Sphk printf(" OPEN"); 37577218Sphk break; 37677218Sphk case IEEE80211_AUTH_SHARED: 37777218Sphk printf(" SHARED"); 37877218Sphk break; 37977218Sphk default: 38077218Sphk printf(" UNKNOWN"); 38177218Sphk break; 38277218Sphk } 38377218Sphk } 38477218Sphk 38577218Sphk ireq.i_type = IEEE80211_IOC_POWERSAVE; 38677218Sphk if (ioctl(s, SIOCG80211, &ireq) != -1 && 38777218Sphk ireq.i_val != IEEE80211_POWERSAVE_NOSUP ) { 38877218Sphk printf(" powersavemode"); 38977218Sphk switch (ireq.i_val) { 39077218Sphk case IEEE80211_POWERSAVE_OFF: 39177218Sphk printf(" OFF"); 39277218Sphk break; 39377218Sphk case IEEE80211_POWERSAVE_CAM: 39477218Sphk printf(" CAM"); 39577218Sphk break; 39677218Sphk case IEEE80211_POWERSAVE_PSP: 39777218Sphk printf(" PSP"); 39877218Sphk break; 39977218Sphk case IEEE80211_POWERSAVE_PSP_CAM: 40077218Sphk printf(" PSP-CAM"); 40177218Sphk break; 40277218Sphk } 40377218Sphk 40477218Sphk ireq.i_type = IEEE80211_IOC_POWERSAVESLEEP; 40577218Sphk if (ioctl(s, SIOCG80211, &ireq) != -1) { 40691454Sbrooks if (ireq.i_val) 40777218Sphk printf(" powersavesleep %d", ireq.i_val); 40877218Sphk } 40977218Sphk } 41077218Sphk 41177218Sphk printf("\n"); 41277218Sphk 413127649Ssam spacer = '\t'; 414127649Ssam ireq.i_type = IEEE80211_IOC_RTSTHRESHOLD; 415127649Ssam if (ioctl(s, SIOCG80211, &ireq) != -1) { 416127649Ssam printf("%crtsthreshold %d", spacer, ireq.i_val); 417127649Ssam spacer = ' '; 418127649Ssam } 419127649Ssam 420127649Ssam ireq.i_type = IEEE80211_IOC_PROTMODE; 421127649Ssam if (ioctl(s, SIOCG80211, &ireq) != -1) { 422127649Ssam printf("%cprotmode", spacer); 423127649Ssam switch (ireq.i_val) { 424127649Ssam case IEEE80211_PROTMODE_OFF: 425127649Ssam printf(" OFF"); 426127649Ssam break; 427127649Ssam case IEEE80211_PROTMODE_CTS: 428127649Ssam printf(" CTS"); 429127649Ssam break; 430127649Ssam case IEEE80211_PROTMODE_RTSCTS: 431127649Ssam printf(" RTSCTS"); 432127649Ssam break; 433127649Ssam default: 434127649Ssam printf(" UNKNOWN"); 435127649Ssam break; 436127649Ssam } 437127649Ssam spacer = ' '; 438127649Ssam } 439127649Ssam 440127649Ssam ireq.i_type = IEEE80211_IOC_TXPOWER; 441127649Ssam if (ioctl(s, SIOCG80211, &ireq) != -1) { 442127649Ssam printf("%ctxpower %d", spacer, ireq.i_val); 443127649Ssam spacer = ' '; 444127649Ssam } 445127649Ssam 446127649Ssam if (spacer != '\t') 447127649Ssam printf("\n"); 448127649Ssam 44977218Sphk ireq.i_type = IEEE80211_IOC_WEP; 45080315Sbrooks if (ioctl(s, SIOCG80211, &ireq) != -1 && 45180315Sbrooks ireq.i_val != IEEE80211_WEP_NOSUP) { 45277218Sphk printf("\twepmode"); 45377218Sphk switch (ireq.i_val) { 45477218Sphk case IEEE80211_WEP_OFF: 45577218Sphk printf(" OFF"); 45677218Sphk break; 45777218Sphk case IEEE80211_WEP_ON: 45877218Sphk printf(" ON"); 45977218Sphk break; 46077218Sphk case IEEE80211_WEP_MIXED: 46177218Sphk printf(" MIXED"); 46277218Sphk break; 46377218Sphk default: 46477218Sphk printf(" UNKNOWN"); 46577218Sphk break; 46677218Sphk } 46777218Sphk 46877218Sphk /* 46977218Sphk * If we get here then we've got WEP support so we need 47077218Sphk * to print WEP status. 47191454Sbrooks */ 47277218Sphk 47377218Sphk ireq.i_type = IEEE80211_IOC_WEPTXKEY; 47477218Sphk if (ioctl(s, SIOCG80211, &ireq) < 0) { 47577218Sphk warn("WEP support, but no tx key!"); 47677218Sphk goto end; 47777218Sphk } 47877218Sphk printf(" weptxkey %d", ireq.i_val+1); 47977218Sphk 48077218Sphk ireq.i_type = IEEE80211_IOC_NUMWEPKEYS; 48177218Sphk if (ioctl(s, SIOCG80211, &ireq) < 0) { 48277218Sphk warn("WEP support, but no NUMWEPKEYS support!"); 48377218Sphk goto end; 48477218Sphk } 48577218Sphk num = ireq.i_val; 48677218Sphk 48777218Sphk printf("\n"); 48877218Sphk 48977218Sphk ireq.i_type = IEEE80211_IOC_WEPKEY; 49077218Sphk spacer = '\t'; 49191454Sbrooks for (i = 0; i < num; i++) { 49277218Sphk ireq.i_val = i; 49377218Sphk if (ioctl(s, SIOCG80211, &ireq) < 0) { 49477218Sphk warn("WEP support, but can get keys!"); 49577218Sphk goto end; 49677218Sphk } 497120178Ssam if (ireq.i_len == 0 || 498120178Ssam ireq.i_len > IEEE80211_KEYBUF_SIZE) 49977218Sphk continue; 50077218Sphk printf("%cwepkey %d:%s", spacer, i+1, 501120178Ssam ireq.i_len <= 5 ? "40-bit" : 502120178Ssam ireq.i_len <= 13 ? "104-bit" : "128-bit"); 50391454Sbrooks if (spacer == '\t') 50477218Sphk spacer = ' '; 50577218Sphk } 50680315Sbrooks if (spacer == ' ') 50780315Sbrooks printf("\n"); 50877218Sphk } 50977218Sphk 51077218Sphkend: 51177218Sphk return; 51277218Sphk} 51377218Sphk 51477218Sphkstatic void 51577218Sphkset80211(int s, int type, int val, int len, u_int8_t *data) 51677218Sphk{ 51777218Sphk struct ieee80211req ireq; 51877218Sphk 51977218Sphk (void) memset(&ireq, 0, sizeof(ireq)); 52077218Sphk (void) strncpy(ireq.i_name, name, sizeof(ireq.i_name)); 52177218Sphk ireq.i_type = type; 52277218Sphk ireq.i_val = val; 52377218Sphk ireq.i_len = len; 52477218Sphk ireq.i_data = data; 52591454Sbrooks if (ioctl(s, SIOCS80211, &ireq) < 0) 52677218Sphk err(1, "SIOCS80211"); 52777218Sphk} 52877218Sphk 52977218Sphkstatic const char * 53077218Sphkget_string(const char *val, const char *sep, u_int8_t *buf, int *lenp) 53177218Sphk{ 53277218Sphk int len; 53377218Sphk int hexstr; 53477218Sphk u_int8_t *p; 53577218Sphk 53677218Sphk len = *lenp; 53777218Sphk p = buf; 53877218Sphk hexstr = (val[0] == '0' && tolower((u_char)val[1]) == 'x'); 53977218Sphk if (hexstr) 54077218Sphk val += 2; 54177218Sphk for (;;) { 54277218Sphk if (*val == '\0') 54377218Sphk break; 54477218Sphk if (sep != NULL && strchr(sep, *val) != NULL) { 54577218Sphk val++; 54677218Sphk break; 54777218Sphk } 54877218Sphk if (hexstr) { 549127831Sphk if (!isxdigit((u_char)val[0])) { 55077218Sphk warnx("bad hexadecimal digits"); 55177218Sphk return NULL; 55277218Sphk } 553127831Sphk if (!isxdigit((u_char)val[1])) { 554127831Sphk warnx("odd count hexadecimal digits"); 555127831Sphk return NULL; 556127831Sphk } 55777218Sphk } 558127831Sphk if (p >= buf + len) { 55977218Sphk if (hexstr) 56077218Sphk warnx("hexadecimal digits too long"); 56177218Sphk else 562127831Sphk warnx("string too long"); 56377218Sphk return NULL; 56477218Sphk } 56577218Sphk if (hexstr) { 56677218Sphk#define tohex(x) (isdigit(x) ? (x) - '0' : tolower(x) - 'a' + 10) 56777218Sphk *p++ = (tohex((u_char)val[0]) << 4) | 56877218Sphk tohex((u_char)val[1]); 56977218Sphk#undef tohex 57077218Sphk val += 2; 57177218Sphk } else 57277218Sphk *p++ = *val++; 57377218Sphk } 57477218Sphk len = p - buf; 57577218Sphk /* The string "-" is treated as the empty string. */ 57677218Sphk if (!hexstr && len == 1 && buf[0] == '-') 57777218Sphk len = 0; 57877218Sphk if (len < *lenp) 57977218Sphk memset(p, 0, *lenp - len); 58077218Sphk *lenp = len; 58177218Sphk return val; 58277218Sphk} 58377218Sphk 58477218Sphkstatic void 58577218Sphkprint_string(const u_int8_t *buf, int len) 58677218Sphk{ 58777218Sphk int i; 58877218Sphk int hasspc; 58977218Sphk 59077218Sphk i = 0; 59177218Sphk hasspc = 0; 59291454Sbrooks for (; i < len; i++) { 59377218Sphk if (!isprint(buf[i]) && buf[i] != '\0') 59477218Sphk break; 59577218Sphk if (isspace(buf[i])) 59677218Sphk hasspc++; 59777218Sphk } 59877218Sphk if (i == len) { 59977218Sphk if (hasspc || len == 0 || buf[0] == '\0') 60077218Sphk printf("\"%.*s\"", len, buf); 60177218Sphk else 60277218Sphk printf("%.*s", len, buf); 60377218Sphk } else { 60477218Sphk printf("0x"); 60577218Sphk for (i = 0; i < len; i++) 60677218Sphk printf("%02x", buf[i]); 60777218Sphk } 60877218Sphk} 60977218Sphk 610