/* * Copyright (c) 1997 Berkeley Software Design, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that this notice is retained, * the conditions in the following notices are met, and terms applying * to contributors in the following notices also apply to Berkeley * Software Design, Inc. * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by * Berkeley Software Design, Inc. * 4. Neither the name of the Berkeley Software Design, Inc. nor the names * of its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN, INC. ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL BERKELEY SOFTWARE DESIGN, INC. BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * BSDI $Id: cnwctl.c,v 1.1.1.1 1997/12/11 14:46:06 itojun Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include void main(int argc, char **argv) { int c, domain, i, key, rate, sflag, Sflag, pflag, skt; char *e, *interface; struct ifreq ifr; struct cnwistats cnwis, onwis; struct cnwstatus cnws; struct cnw_iss iss; struct ttysize ts; domain = -1; key = -1; Sflag = sflag = pflag = 0; rate = 0; interface = "cnw0"; while ((c = getopt(argc, argv, "d:i:k:psS")) != EOF) switch (c) { case 'd': domain = strtol(optarg, &e, 0); if (e == optarg || *e || domain & ~ 0x1ff) errx(1, "%s: invalid domain", optarg); break; case 'i': interface = optarg; break; case 'k': key = strtol(optarg, &e, 0); if (e == optarg || *e || key & ~ 0xffff) errx(1, "%s: invalid scramble key", optarg); break; case 'S': ++Sflag; break; case 's': ++sflag; break; case 'p': ++pflag; break; default: usage: fprintf(stderr, "usage: cnwctl [-i interface] [-d domain] [-k key] [-psS [rate]]\n"); exit(1); } switch (argc - optind) { case 0: break; case 1: if (sflag == 0 && Sflag == 0 && pflag == 0) goto usage; if ((sflag + Sflag + pflag) > 1) errx(1, "only one of -s and -S may be specified with a rate"); rate = strtol(argv[optind], &e, 0); if (e == optarg || *e || rate < 1) errx(1, "%s: invalid rate", optarg); break; default: goto usage; } if ((skt = socket(AF_INET, SOCK_DGRAM, 0)) < 0) err(1, "socket(AF_INET, SOCK_DGRAM)"); if (key >= 0) { memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, interface, sizeof(ifr.ifr_name)); ifr.ifr_key = key; if (ioctl(skt, SIOCSCNWKEY, (caddr_t)&ifr) < 0) err(1, "SIOCSCNWKEY"); } if (domain >= 0) { memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, interface, sizeof(ifr.ifr_name)); ifr.ifr_domain = domain; if (ioctl(skt, SIOCSCNWDOMAIN, (caddr_t)&ifr) < 0) err(1, "SIOCSCNWDOMAIN"); } if (sflag == 0 && Sflag == 0 && pflag == 0) exit (0); if (Sflag) { memset(&cnws, 0, sizeof(cnws)); strncpy(cnws.ifr.ifr_name, interface, sizeof(cnws.ifr.ifr_name)); if (ioctl(skt, SIOCGCNWSTATUS, (caddr_t)&cnws) < 0) err(1, "SIOCGCNWSTATUS"); } if (sflag) { memset(&cnwis, 0, sizeof(cnwis)); strncpy(cnwis.ifr.ifr_name, interface, sizeof(cnwis.ifr.ifr_name)); if (ioctl(skt, SIOCGCNWSTATS, (caddr_t)&cnwis) < 0) err(1, "SIOCGCNWSTATS"); cnwis.stats.nws_txretries[0] = 0; for (i = 1; i < 16; ++i) cnwis.stats.nws_txretries[0] += cnwis.stats.nws_txretries[i] * i; } if (pflag) { memset(&iss, 0, sizeof(iss)); strncpy(iss.ifr.ifr_name, interface, sizeof(iss.ifr.ifr_name)); if (ioctl(skt, SIOCGCNWSS, (caddr_t)&iss) < 0) err(1, "SIOCGCNWSS"); } if (rate == 0 && sflag) { memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, interface, sizeof(ifr.ifr_name)); if (ioctl(skt, SIOCGCNWDOMAIN, (caddr_t)&ifr) < 0) err(1, "SIOCGCNWDOMAIN"); printf("%s:\n 0x%03x domain\n", interface, ifr.ifr_domain); printf("%10d rx\n", cnwis.stats.nws_rx); printf("%10d rxoverflow\n", cnwis.stats.nws_rxoverflow); printf("%10d rxoverrun\n", cnwis.stats.nws_rxoverrun); printf("%10d rxcrcerror\n", cnwis.stats.nws_rxcrcerror); printf("%10d rxframe\n", cnwis.stats.nws_rxframe); printf("%10d rxerrors\n", cnwis.stats.nws_rxerrors); printf("%10d rxavail\n", cnwis.stats.nws_rxavail); printf("%10d tx\n", cnwis.stats.nws_tx); printf("%10d txokay\n", cnwis.stats.nws_txokay); printf("%10d txabort\n", cnwis.stats.nws_txabort); printf("%10d txlostcd\n", cnwis.stats.nws_txlostcd); printf("%10d txerrors\n", cnwis.stats.nws_txerrors); printf("%10d txretries\n", cnwis.stats.nws_txretries[0]); for (i = 1; i < 16; ++i) if (cnwis.stats.nws_txretries[i]) printf("%10s %10d %dx retries\n", "", cnwis.stats.nws_txretries[i], i); } if (rate == 0 && Sflag) { printf(" 0x%02x link integrity field\n", cnws.data[0x4e]); printf(" 0x%02x connection quality\n", cnws.data[0x54]); printf(" 0x%02x spu\n", cnws.data[0x55]); printf(" 0x%02x link quality\n", cnws.data[0x56]); printf(" 0x%02x hhc\n", cnws.data[0x58]); printf(" 0x%02x mhs\n", cnws.data[0x6b]); printf(" %04x %04x revision\n", *(u_short *)&cnws.data[0x66], *(u_short *)&cnws.data[0x68]); printf(" %c%c id\n", cnws.data[0x6e], cnws.data[0x6f]); } if (rate == 0 && pflag) { printf(" 0x%04x length\n", iss.ss.length); printf(" 0x%02x revision\n", iss.ss.Struct_revision); printf(" 0x%02x roaming_state\n", iss.ss.roaming_state); printf(" 0x%02x sp_existsFlag\n", iss.ss.sp_existsFlag); printf(" 0x%02x linkQuality Good fair boundary\n", iss.ss.linkQualityGoodFairBoundary); printf(" 0x%02x linkQuality fair Poor boundary\n", iss.ss.linkQualityFairPoorBoundary); printf(" 0x%02x sp_utilization\n", iss.ss.sp_utilization); printf(" 0x%02x sp_goodness\n", iss.ss.sp_goodness); printf(" 0x%02x sp_hothedcount\n", iss.ss.sp_hothedcount); printf(" 0x%02x roaming_condition\n", iss.ss.roaming_condition); printf(" %02x:%02xx:%02x:%02x:%02x:%02x Current Access Point ID\n", iss.ss.sp.addr48[0], iss.ss.sp.addr48[1], iss.ss.sp.addr48[2], iss.ss.sp.addr48[3], iss.ss.sp.addr48[4], iss.ss.sp.addr48[5]); printf("\n Near by AccessPoints (Number of Access Points = %d)\n", iss.ss.numAPs); for (i=0; i< iss.ss.numAPs; i++) { printf(" %02x:%02x:%02x:%02x:%02x:%02x\n", iss.ss.nearByAccessPoints[i].addr48[0], iss.ss.nearByAccessPoints[i].addr48[1], iss.ss.nearByAccessPoints[i].addr48[2], iss.ss.nearByAccessPoints[i].addr48[3], iss.ss.nearByAccessPoints[i].addr48[4], iss.ss.nearByAccessPoints[i].addr48[5]); } } if (rate == 0) exit (0); if (ioctl(0, TIOCGWINSZ, &ts) < 0) ts.ts_lines = 24; c = 0; if (Sflag) for (;;) { if (c-- == 0) { printf("lif cq spu lq hhc mhs\n"); c = ts.ts_lines - 3; } printf(" %02x %02x %02x %02x %02x %02x\n", cnws.data[0x4e], cnws.data[0x54], cnws.data[0x55], cnws.data[0x56], cnws.data[0x58], cnws.data[0x6b]); fflush(stdout); if (ioctl(skt, SIOCGCNWSTATUS, (caddr_t)&cnws) < 0) err(1, "SIOCGCNWSTATUS"); sleep (rate); } if (sflag) for (;;) { if (c-- == 0) { printf("%10s %10s %10s %10s %10s %10s\n", "tx-request", "tx-okay", "tx-error", "tx-retry", "rx", "rx-error"); c = ts.ts_lines - 3; memset(&onwis, 0, sizeof(onwis)); } printf("%10d ", cnwis.stats.nws_tx - onwis.stats.nws_tx); printf("%10d ", cnwis.stats.nws_txokay - onwis.stats.nws_txokay); printf("%10d ", cnwis.stats.nws_txerrors - onwis.stats.nws_txerrors); printf("%10d ", cnwis.stats.nws_txretries[0] - onwis.stats.nws_txretries[0]); printf("%10d ", cnwis.stats.nws_rx - onwis.stats.nws_rx); printf("%10d\n", cnwis.stats.nws_rxerrors - onwis.stats.nws_rxerrors); fflush(stdout); sleep (rate); onwis = cnwis; if (ioctl(skt, SIOCGCNWSTATS, (caddr_t)&cnwis) < 0) err(1, "SIOCGCNWSTATS"); cnwis.stats.nws_txretries[0] = 0; for (i = 1; i < 16; ++i) cnwis.stats.nws_txretries[0] += cnwis.stats.nws_txretries[i] * i; } for (;;) { if (c-- == 0) { printf("%10s %s\n", "AP Util", " AP ID"); c = ts.ts_lines - 3; } fflush(stdout); sleep(rate); if (ioctl(skt, SIOCGCNWSS, (caddr_t)&iss) < 0) err(1, "SIOCGCNWSS"); printf("%10x", iss.ss.sp_utilization); printf(" %02x:%02xx:%02x:%02x:%02x:%02x", iss.ss.sp.addr48[0], iss.ss.sp.addr48[1], iss.ss.sp.addr48[2], iss.ss.sp.addr48[3], iss.ss.sp.addr48[4], iss.ss.sp.addr48[5]); printf("\n"); } }