summaryrefslogtreecommitdiffstats
path: root/usr.sbin
diff options
context:
space:
mode:
authorfjoe <fjoe@FreeBSD.org>2004-03-15 22:24:28 +0000
committerfjoe <fjoe@FreeBSD.org>2004-03-15 22:24:28 +0000
commit988426d9e5e2673a75c07ef74e5913b96ac913f5 (patch)
treea4c8c88d0bf5d52cd5d1fcf24ca0d7a18c2d5917 /usr.sbin
parent6c8e5c543fa1cfd6b4fe816257f119f51eacb285 (diff)
downloadFreeBSD-src-988426d9e5e2673a75c07ef74e5913b96ac913f5.zip
FreeBSD-src-988426d9e5e2673a75c07ef74e5913b96ac913f5.tar.gz
Add arl(4): driver for Aironet Arlan 655 wireless adapters.
MFC after: 2 weeks
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/Makefile2
-rw-r--r--usr.sbin/arlconfig/Makefile11
-rw-r--r--usr.sbin/arlconfig/arlconfig.8236
-rw-r--r--usr.sbin/arlconfig/arlconfig.c612
-rw-r--r--usr.sbin/arlcontrol/arlcontrol.8236
-rw-r--r--usr.sbin/arlcontrol/arlcontrol.c612
6 files changed, 1709 insertions, 0 deletions
diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile
index b48a73b..69b714f 100644
--- a/usr.sbin/Makefile
+++ b/usr.sbin/Makefile
@@ -10,6 +10,7 @@ SUBDIR= ac \
ancontrol \
${_apm} \
${_apmd} \
+ ${_arlconfig} \
arp \
${_asf} \
${_atm} \
@@ -241,6 +242,7 @@ _acpi= acpi
.endif
_apm= apm
_apmd= apmd
+_arlconfig= arlconfig
_asf= asf
.if !defined(NO_BLUETOOTH)
_bluetooth= bluetooth
diff --git a/usr.sbin/arlconfig/Makefile b/usr.sbin/arlconfig/Makefile
new file mode 100644
index 0000000..94a03a3
--- /dev/null
+++ b/usr.sbin/arlconfig/Makefile
@@ -0,0 +1,11 @@
+#
+# $RISS: if_arl/arlconfig/Makefile,v 1.5 2003/01/13 08:05:29 frol Exp $
+# $FreeBSD$
+#
+
+PROG= arlconfig
+SRCS= arlconfig.c
+CFLAGS= -I${.CURDIR}/../../sys
+MAN= arlconfig.8
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/arlconfig/arlconfig.8 b/usr.sbin/arlconfig/arlconfig.8
new file mode 100644
index 0000000..1523bbb
--- /dev/null
+++ b/usr.sbin/arlconfig/arlconfig.8
@@ -0,0 +1,236 @@
+.\" Copyright (c) 1997, 1998, 1999
+.\" Bill Paul <wpaul@ee.columbia.edu> All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 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 Bill Paul.
+.\" 4. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``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 Bill Paul OR THE VOICES IN HIS HEAD
+.\" 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.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd August 25,2003
+.Dt ARLCONTROL 8
+.Os
+.Sh NAME
+.Nm arlconfig
+.Nd configure Aironet Arlan 655 device
+.Sh SYNOPSIS
+.Nm
+.Ar iface Cm name Ar name
+.Nm
+.Ar iface Cm sid Ar SID
+.Nm
+.Ar iface Cm country Ar country ( Cm 9-15 )
+.Nm
+.Ar iface Cm channel Ar channel
+(depend on
+.Ar country )
+.Nm
+.Ar iface Cm freq Ar freq ( Cm 2412, 2427, 2442, 2457, 2465 )
+.Nm
+.Ar iface Cm spread Ar spread Cm ( 354, 500, 1000, 2000 )
+.Nm
+.Ar iface Cm bitrate Ar bitrate ( Cm 0-4)
+.Nm
+.Ar iface Cm mode Ar mode ( Cm 640 | 655 )
+.Nm
+.Ar iface Cm priority Ar priority ( Cm normal, high, highest )
+.Nm
+.Ar iface Cm stat
+.Nm
+.Ar iface Cm quality Ar seconds [ Cm count Ar <count> ]
+.Sh DESCRIPTION
+The
+.Nm
+utility controls the operation of Aironet Arlan 655 wireless networking
+devices via the
+.Xr arl 4
+driver.
+Most of the parameters that can be changed are related to the
+Aironet protocol which the Aironet Arlan 655 card implements.
+The parameters include
+the station name, the station operation mode
+.Ar (point to point or infrastructure) ,
+and the network name of a service
+set to join.
+The
+.Nm
+utility can also be used to view the current NIC status, configuration
+and to dump out the values of the card's statistics counters.
+.Pp
+The
+.Ar iface
+argument given to
+.Nm
+should be the logical interface name associated with the Aironet Arlan 655
+device
+.Li ( arl0 , arl1 ,
+etc.) and must be specified.
+.Sh OPTIONS
+The options are as follows:
+.Bl -tag -width indent
+.It Cm name Ar name
+Set
+.Ar Device Name .
+This
+parameter is used to establish a 15-byte ASCII name
+for the Arlan 655 Client Card. The
+.Ar Device Name
+is optional and may be left blank.
+.Pp
+If you choose to assign a name, while operating in
+.Ar TMA
+mode, the name will appear in the Arlan Access Point's Registration Table.
+Duplicate names are allowed.
+.It Cm sid Ar SID
+Set
+.Ar System Identifier.
+The System Identifier
+.Ar (SID)
+is a 4-byte, hexadecimal digit value that
+is attached to each packet sent out over the radio. Establishing a
+.Ar SID
+allows you to group nodes into a microcelluar network and exclude
+those nodes that are whiting radio range on other networks.
+.Pp
+The
+.Ar SID
+value must be an even number, cannot exceed ts and must start with
+00 or 02. Examples of valid SID values are: 00000102, 0200AA14, 00013A18,
+007F6380. The
+.Ar default
+SID is
+.Cm 00000002 .
+.Pp
+Since nodes will only receive packets from other nodes with a matching SID,
+you must make sure that the Arlan 655 Client Card is set the same SID as
+other nodes on your network.
+.It Cm mode Ar mode ( Cm 640 | 655 )
+Use
+.Ar operating mode
+parameter to specify whether you are operating in
+.Ar TMA , Non-TMA
+or
+.Ar PSP
+mode. The
+.Ar default
+setting is
+.Cm TMA
+mode.
+.Bl -column ".Em Mode" ".Em Regmode" -offset indent indent
+.Em "Mode Registration mode"
+.It 640 Ta TMA
+.It 655 Ta Non-TMA
+.It PSP Ta Power save mode
+.El
+.!!!
+.It Cm country Ar country ( Cm 9-15 )
+.It Cm channel Ar channel
+.It Cm freq Ar freq ( Cm 2412, 2427, 2442, 2457, 2465 )
+Chose
+.Ar country , channel , freq
+ parameters that depend on the
+.Ar contry
+according to the following table:
+.Bl -column ".Em Country" ".Em Channel" ".Em MHz" -offset indent indent
+.Em "Country Ch_Set MHz"
+.It "North America" Ta 9 Ta "2412, 2427, 2442, 2457, 2465"
+.It "U.S.A " Ta 9 Ta "2412, 2427, 2442, 2457, 2465"
+.It "Canada " Ta 9 Ta "2412, 2427, 2442, 2457, 2465"
+.It "Mexico " Ta 9 Ta "2412, 2427, 2442, 2457, 2465"
+.IT "New Zealand " Ta 9 Ta "2412, 2427, 2442, 2457, 2465"
+.It "E.T.S.I " Ta 10 Ta "2412, 2427, 2442, 2457, 2472"
+.It "Japan " Ta 11 Ta "2484"
+.It "France " Ta 12 Ta "2457, 2465, 2475"
+.It "Australia " Ta 13 Ta "2411, 2425, 2439"
+.It "Germany " Ta 14 Ta "2427, 2442, 2457"
+.It "U.K.(MPT1349)" Ta 15 Ta "2460"
+.It "U.K. " Ta 15 Ta "2460"
+.It "Spain " Ta 15 Ta "2460"
+.El
+.It Cm bitrate Ar bitrate ( Cm 0-4)
+.It Cm spread Ar spread Cm ( 354, 500, 1000, 2000 )
+Set device operating bitrate or spread.
+.Bl -column ".Em Rate" ".Em Spread" ".Em kb/s" -offset indent indent
+.Em "Rate Spread kb/s"
+.It 0 Ta - Ta Auto
+.It 1 Ta 354 Ta 354
+.It 2 Ta 512 Ta 512
+.It 3 Ta 1000 Ta 1000
+.It 4 Ta 2000 Ta 2000
+.El
+.It Cm priority Ar priority ( Cm normal, high, highest )
+Use the
+.Ar priority
+parameter to set the priority of the Atlan 655 Radio Media Access Control
+the values are
+.Cm normal , high
+or
+.Cm higest .
+The higher the priority set, the more likely this unit wil be first
+to successfully transmit a packet when multiple units are trying
+to transmit at the same time.
+.Pp
+The percentage of units on your network that you set to other than
+.Dq normal
+should be kept small - 10 percent or less.
+.It Cm stat
+Print internal Arlan 655 statistics block.
+.It Cm quality Ar seconds [ Cm count Ar <count> ]
+Perform link quality test during
+.Ar seconds
+transmitting
+.Ar count
+packets.
+Currently is broken.
+.El
+.Sh EXAMPLES
+.Bd -literal -offset indent
+alrlconfig arl0 name NODE1 sid 4 freq 2442
+arlconfig arl0 quality 10 seconds
+arlconfig arl0 status
+.Pp
+You can configure Arlan 655 card from /etc/start_if.arl0. For example:
+.Pp
+#!/bin/sh
+/sbin/arlconfig arl0 sid 0x000002 freq 2412 spread 2000 mode 640
+.Sh SEE ALSO
+.Xr arl 4 ,
+.Xr "Arlan 655 ISA Wireless LAN Client Card User Guide" .
+.Sh HISTORY
+The
+.Nm
+utility first appeared in
+.Fx 5.3 .
+.Sh BUGS
+Aironet Arlan 640 bridges and Arlan 630 access points don't understand
+country codes other than 9.
+.Sh AUTHORS
+The
+.Nm
+utility was written by
+.Aq ran@styx.aic.net .
+Manpage was written by
+.An Yuri Kurenkov Aq y.kurenkov@init.ru .
diff --git a/usr.sbin/arlconfig/arlconfig.c b/usr.sbin/arlconfig/arlconfig.c
new file mode 100644
index 0000000..4ab5ca9
--- /dev/null
+++ b/usr.sbin/arlconfig/arlconfig.c
@@ -0,0 +1,612 @@
+/*
+ * $RISS: if_arl/arlconfig/arlconfig.c,v 1.3 2003/01/13 07:23:25 count Exp $
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+
+#include <net/if.h>
+#include <net/ethernet.h>
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <limits.h>
+
+#include <dev/arl/if_arlreg.h>
+
+struct freq_list {
+ short fr_no;
+ char* name;
+};
+
+struct freq_list freq_list_1[] = {
+ { 0, "908.50" },
+ { 1, "910.06" },
+ { 2, "915.52" },
+ { 3, "915.00" },
+ { 4, "917.83" },
+ { 5, "919.22" },
+ { 6, "922.26" },
+ { 7, "911.45" },
+ { 8, "915.00" },
+ { 9, "918.55" },
+ { 10,"915.00" },
+ { 11,"915.00" }
+};
+
+struct freq_list freq_list_6[] = {
+ { 0, "920.31" },
+ { 1, "920.33" },
+ { 2, "921.55" },
+ { 3, "922.17" },
+ { 4, "922.79" },
+ { 5, "921.46" },
+ { 6, "921.55" }
+};
+
+struct freq_list freq_list_9[] = {
+ { 0, "Bad" },
+ { 1, "2412" },
+ { 2, "2427" },
+ { 3, "2442" },
+ { 4, "2457" },
+ { 5, "2465" }
+};
+
+
+struct freq_list freq_list_10[] = {
+ { 0, "Bad" },
+ { 1, "2412" },
+ { 2, "2427" },
+ { 3, "2442" },
+ { 4, "2457" },
+ { 5, "2472" }
+};
+
+struct freq_list freq_list_11[] = {
+ { 0, "Bad" },
+ { 1, "2484" }
+};
+
+struct freq_list freq_list_12[] = {
+ { 0, "Bad" },
+ { 1, "2457" },
+ { 2, "2465" },
+ { 3, "2472" },
+};
+
+struct freq_list freq_list_13[] = {
+ { 0, "Bad" },
+ { 1, "2411" },
+ { 2, "2425" },
+ { 3, "2439" }
+};
+
+struct freq_list freq_list_14[] = {
+ { 0, "Bad" },
+ { 1, "2427" },
+ { 2, "2442" },
+ { 3, "2457" }
+};
+
+struct freq_list freq_list_15[] = {
+ { 0, "Bad" },
+ { 1, "2460" }
+};
+
+#define MAXFREQ(a) sizeof(a)/sizeof(struct freq_list)
+
+struct rate_list {
+ short rate_no;
+ char* name;
+};
+
+struct rate_list rate_list_2400[] = {
+ { 0, "Bad" },
+ { 1, "354" },
+ { 2, "512" },
+ { 3, "1000" },
+ { 4, "2000" }
+};
+
+struct radio_type {
+ int id;
+ char* name;
+} radio_type_list [] = {
+ { 0, "No EPROM" },
+ { 1, "092/094" },
+ { 2, "020" },
+ { 3, "092A" },
+ { 4, "020B" },
+ { 5, "095" },
+ { 6, "024" },
+ { 7, "025B" },
+ { 8, "024B" },
+ { 9, "024C" },
+ {10, "025C" },
+ {11, "024-1A" },
+ {12, "025-1A" },
+ {13, "Other" }
+};
+
+static struct ch_list {
+ short chan;
+ char* fr;
+ char* country;
+ struct rate_list* rate;
+ struct freq_list* freq;
+ int max_freq;
+} CHSET[] = {
+ { 0, 0, 0, 0, 0, 0 },
+ { 1, "900 Mhz", "Canada, U.S.A., Mexico", 0, freq_list_1, MAXFREQ(freq_list_1) },
+ { 2, 0, 0, 0, 0, 0 },
+ { 3, 0, 0, 0, 0, 0 },
+ { 4, 0, 0, 0, 0, 0 },
+ { 5, 0, 0, 0, 0, 0 },
+ { 6, "900 Mhz", "Australia", 0, freq_list_6, MAXFREQ(freq_list_6) },
+ { 7, 0, 0, 0, 0, 0 },
+ { 8, 0, 0, 0, 0, 0 },
+ { 9, "2400 Mhz", "North America", rate_list_2400, freq_list_9, MAXFREQ(freq_list_9) },
+ { 10, "2400 Mhz", "E.T.S.I", rate_list_2400, freq_list_10, MAXFREQ(freq_list_10) },
+ { 11, "2400 Mhz", "Japan", rate_list_2400, freq_list_11, MAXFREQ(freq_list_11) },
+ { 12, "2400 Mhz", "France", rate_list_2400, freq_list_12, MAXFREQ(freq_list_12) },
+ { 13, "2400 Mhz", "Australia", rate_list_2400, freq_list_13, MAXFREQ(freq_list_13) },
+ { 14, "2400 Mhz", "Germany", rate_list_2400, freq_list_14, MAXFREQ(freq_list_14) },
+ { 15, "2400 Mhz", "U.K.(MPT1349),Spain", rate_list_2400, freq_list_15, MAXFREQ(freq_list_15) }
+};
+
+char* registrationMode[] = {
+ "NON-TMA",
+ "TMA",
+ "PSP"
+};
+
+char* priorityList[] = {
+ "normal",
+ "high",
+ "highest"
+};
+
+void
+usage()
+{
+ const char *progname = getprogname();
+
+#if 0
+ fprintf(stderr, "\nArlan configuration utility.\n\n");
+#endif
+ fprintf(stderr, "Usage: %s <ifname> [<param> <value> ...]\n", progname);
+ fprintf(stderr, "\t<ifname>\tArlan interface name.\n");
+ fprintf(stderr, "\t<param>\t\tParameter name (see below).\n");
+ fprintf(stderr, "\t<value>\t\tNew value for parameter.\n");
+ fprintf(stderr, "Parameter name:\t\tValue:\n");
+ fprintf(stderr, "\tname\t\tset Name.\n");
+ fprintf(stderr, "\tsid\t\tset System ID.\n");
+ fprintf(stderr, "\tfreq\t\tset Frequency Channel (2412, 2427, 2442, 2457, 2465)\n");
+ fprintf(stderr, "\tspread\t\tset Bitrate (354, 500, 1000, 2000)\n");
+ fprintf(stderr, "\tmode\t\tset Mode (640, 655, PSP).\n");
+ fprintf(stderr, "\tcountry\t\tset Country (9-15)\n");
+ fprintf(stderr, "\tchannel\t\tset Channel (depended on country)\n");
+ fprintf(stderr, "\tbitrate\t\tset Bitrate (0-4)\n");
+ fprintf(stderr, "\tpriority\tset Priority (normal, high, highest)\n");
+#if 0
+ fprintf(stderr, "\tparent\t\tset Arlan parent's MAC.\n");
+ fprintf(stderr, "\taddr\t\tset Arlan MAC.\n");
+#endif
+ fprintf(stderr, "or: %s <ifname> stat\n", progname);
+ fprintf(stderr, "\tprint internal arlan statistics block\n");
+ fprintf(stderr, "or: %s <ifname> quality <seconds> [count <count>]\n",
+ progname);
+ fprintf(stderr, "\tprint receive packet level and quality with interval\n");
+ exit(0);
+}
+
+void
+print_al(struct arl_cfg_param *arl_io)
+{
+ printf("Arlan-655(IC2000) type 0x%x v%d.%d, radio module type %s\n",
+ arl_io->hardwareType,
+ arl_io->majorHardwareVersion,
+ arl_io->minorHardwareVersion,
+ (arl_io->radioModule < 13) ?
+ radio_type_list[arl_io->radioModule].name : "Unknown" );
+ printf("\tname %s, sid 0x%06x, mode %s, num tx retry %d\n",
+ arl_io->name,
+ *(int *)arl_io->sid,
+ (arl_io->registrationMode < 3) ?
+ registrationMode[arl_io->registrationMode]:"Unknown",
+ arl_io->txRetry );
+ printf("\tchannel set %d, %s, %s\n",
+ arl_io->channelSet,
+ CHSET[arl_io->channelSet].fr,
+ CHSET[arl_io->channelSet].country);
+ printf("\tfrequency %s Mhz, bitrate %s kb/s, priority %s, receive mode %d\n",
+ (CHSET[arl_io->channelSet].freq &&
+ CHSET[arl_io->channelSet].max_freq > arl_io->channelNumber) ?
+ CHSET[arl_io->channelSet].freq[arl_io->channelNumber].name :
+ "unknown",
+ (CHSET[arl_io->channelSet].rate) ?
+ CHSET[arl_io->channelSet].rate[arl_io->spreadingCode].name :
+ "unknown",
+ arl_io->priority <= 2 ?
+ priorityList[arl_io->priority] : "unknown",
+ arl_io->receiveMode);
+ printf("\tether %s",
+ (char *)ether_ntoa((struct ether_addr *)arl_io->lanCardNodeId));
+ printf(" registered to %s\n",
+ (char *)ether_ntoa((struct ether_addr *)arl_io->specifiedRouter));
+}
+
+void
+print_stb( struct arl_stats stb )
+{
+ printf("Arlan internal statistics block\n\n");
+ printf("%8u\tdatagrams transmitted\n",
+ stb.numDatagramsTransmitted);
+ printf("%8u\tre-transmitted\n",
+ stb.numReTransmissions);
+ printf("%8u\tframes discarded internally in a router\n",
+ stb.numFramesDiscarded);
+ printf("%8u\tdatagrams received\n",
+ stb.numDatagramsReceived);
+ printf("%8u\tduplicate received frame\n",
+ stb.numDuplicateReceivedFrames);
+ printf("%8u\tdatagrams discarded due to unavailable mail box buffer\n",
+ stb.numDatagramsDiscarded);
+ printf("%8d\tmaximum of re-transmissions datagram\n",
+ stb.maxNumReTransmitDatagram);
+ printf("%8d\tmaximum of re-transmissions frame\n",
+ stb.maxNumReTransmitFrames);
+ printf("%8d\tmaximum of consecutive duplicate received frames\n",
+ stb.maxNumConsecutiveDuplicateFrames);
+ printf("%8u\tbytes transmitted\n",
+ stb.numBytesTransmitted);
+ printf("%8u\tbytes received\n",
+ stb.numBytesReceived);
+ printf("%8u\tCRC errors\n",
+ stb.numCRCErrors);
+ printf("%8u\tlength errors\n",
+ stb.numLengthErrors);
+ printf("%8u\tabort errors\n",
+ stb.numAbortErrors);
+ printf("%8u\tTX underuns\n",
+ stb.numTXUnderruns);
+ printf("%8u\tRX overruns\n",
+ stb.numRXOverruns);
+ printf("%8u\tHold Offs (channel tested busy, tx delayed)\n",
+ stb.numHoldOffs);
+ printf("%8u\tframes transmitted\n",
+ stb.numFramesTransmitted);
+ printf("%8u\tframes received\n",
+ stb.numFramesReceived);
+ printf("%8u\treceive frames lost due unavailable buffer\n",
+ stb.numReceiveFramesLost);
+ printf("%8u\tRX buffer overflows \n",
+ stb.numRXBufferOverflows);
+ printf("%8u\tframes discarded due to Address mismatch\n",
+ stb.numFramesDiscardedAddrMismatch);
+ printf("%8u\tframes discarded due to SID mismatch\n",
+ stb.numFramesDiscardedSIDMismatch);
+ printf("%8u\tpolls transmitted\n",
+ stb.numPollsTransmistted);
+ printf("%8u\tpoll acknowledges received\n",
+ stb.numPollAcknowledges);
+ printf("%8u\tstatus vector timeout\n",
+ stb.numStatusVectorTimeouts);
+ printf("%8u\tNACK packets received\n",
+ stb.numNACKReceived);
+}
+
+#ifdef ARL_QUALITY
+void
+print_qlt(struct arl_quality qlt, int count)
+{
+ int i, s;
+ int v, v1;
+ time_t t;
+ int minLevel, maxLevel, avgLevel;
+ int minQuality, maxQuality, avgQuality;
+
+ t = time(NULL);
+ localtime(&t);
+ printf("#%d Current date-time: %s", count, ctime(&t));
+ printf(" %-39s %s\n","Receive Level","Receive Quality");
+ printf(
+" pkts 0.......10 11............100 > pkts 0.......10 11............100 >\n"\
+" -----+----------+-----------------+--- -----+----------+-----------------+---\n");
+
+ minLevel = 16;
+ maxLevel = 0;
+ avgLevel = 0;
+ minQuality = 16;
+ maxQuality = 0;
+ avgQuality = 0;
+
+ for (i = 0, s = 0; i < ARLAN_MAX_QUALITY; i++) {
+ v = qlt.rxLevel[i];
+ if (v) {
+ if (i < minLevel)
+ minLevel = i;
+ if (i > maxLevel)
+ maxLevel = i;
+ avgLevel += v*i;
+ printf(" %-4d %x", v, i);
+ } else
+ printf(" o %x", i);
+ s += v;
+ if (v < 10)
+ ;
+ else if (v < 100)
+ v = 10 + ((v-10) * 20) / 90;
+ else if (v < 1000)
+ v = 31;
+ else
+ v = 32;
+ v1 = v;
+ while (v) {
+ printf("*");
+ v--;
+ }
+
+ v = 33 - v1;
+ while (v) {
+ printf(" ");
+ v--;
+ }
+
+ v = qlt.rxQuality[i];
+ if (v) {
+ if (i < minQuality)
+ minQuality = i;
+ if (i > maxQuality)
+ maxQuality = i;
+ avgQuality += v*i;
+ printf("%-4d %x", v, i);
+ } else
+ printf("o %x", i);
+
+ if (v < 10)
+ ;
+ else if (v < 100)
+ v = 10 + ((v-10) * 20) / 90;
+ else if (v < 1000)
+ v = 31;
+ else
+ v = 32;
+ }
+ v1 = v;
+ while (v) {
+ printf("*");
+ v--;
+ }
+
+ printf("\n");
+ }
+ printf(" -----+----------+-----------------+--- -----+----------+-----------------+---\n");
+ if (minLevel > 15)
+ minLevel = 0;
+ if (minQuality > 15)
+ minQuality = 0;
+ printf("\tPackets count %-6d\n", s);
+ if (!s)
+ s++;
+ printf("\tLevel min %d/avg %d/max %d\n",
+ minLevel, avgLevel/s, maxLevel);
+ printf("\tQuality min %d/avg %d/max %d\n",
+ minQuality, avgQuality/s, maxQuality);
+}
+#endif /* ARL_QUALITY */
+
+int
+main(int argc, char *argv[])
+{
+ struct ifreq ifr;
+ struct arl_req arl_io;
+ struct ether_addr *ea;
+ struct arl_stats stb;
+ /*static arl_quality qlt;*/
+ int sd, argind, val = -1;
+ long val2;
+ char *param, *value, *value2;
+ /*int end_count, i;*/
+
+ if (argc < 2)
+ usage();
+
+ sd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sd < 0)
+ err(1,"socket");
+ strncpy(ifr.ifr_name, argv[1], sizeof(ifr.ifr_name));
+ ifr.ifr_addr.sa_family = AF_INET;
+ bzero(&arl_io, sizeof(arl_io));
+ ifr.ifr_data = (caddr_t)&arl_io;
+
+ if (argc == 2) {
+ if (ioctl(sd, SIOCGARLALL, (caddr_t)&ifr))
+ err(1,"Get ALL");
+ print_al(&arl_io.cfg);
+ exit(0);
+ }
+
+ if (argc == 3) {
+ if (!strcasecmp(argv[2], "stat")) {
+ strncpy(ifr.ifr_name, argv[1], sizeof(ifr.ifr_name));
+ ifr.ifr_addr.sa_family = AF_INET;
+ ifr.ifr_data = (caddr_t)&stb;
+ if (ioctl(sd, SIOCGARLSTB, (caddr_t)&ifr))
+ err(1,"Get STB");
+ print_stb(stb);
+ exit(0);
+ }
+#ifdef ARL_QUALITY
+ if (!strcasecmp(argv[2],"quality") && argc > 3) {
+ val = atoi(argv[3]);
+ if (val < 0 || val >= 3601)
+ err(1,"Bad time range");
+ end_count = 0;
+ if (argc > 5 && !strcasecmp(argv[4], "count"))
+ end_count = atoi(argv[5]);
+ printf("\n");
+ i = 0;
+ while (i < end_count || !end_count) { /* loop */
+ if (i++)
+ sleep(val);
+ strncpy(ifr.ifr_name,
+ argv[1], sizeof(ifr.ifr_name));
+ ifr.ifr_addr.sa_family = AF_INET;
+ ifr.ifr_data = (caddr_t)&qlt;
+ if (ioctl(sd, SIOCGARLQLT, (caddr_t)&ifr))
+ err(1,"Get QLT");
+ print_qlt(qlt, i);
+ }
+ exit(0);
+ }
+#endif /* ARL_QUALITY */
+ }
+
+ arl_io.what_set = 0;
+
+ for (argind = 2; argind < argc; argind += 2) {
+ param = argv[argind];
+ value = argv[argind+1];
+ val = -1;
+
+ if (!strcasecmp(param, "name")) {
+ bzero(arl_io.cfg.name, 16);
+ strncpy(arl_io.cfg.name, value, 16);
+ arl_io.what_set |= ARLAN_SET_name;
+ }
+
+ if (!strcasecmp(param, "sid")) {
+ val2 = strtol(value, &value2, 0);
+ if (val2 < 0 || val2 > 0xffffff || val2 % 2 ||
+ value == value2)
+ err(1, "Bad SID - %s", value);
+ bcopy(&val2, arl_io.cfg.sid, 4);
+ arl_io.what_set |= ARLAN_SET_sid;
+ }
+
+ if (!strcasecmp (param, "freq")) {
+ if (!strcmp(value, "2412"))
+ val = 1;
+ else if (!strcmp(value, "2427"))
+ val = 2;
+ else if (!strcmp(value, "2442"))
+ val = 3;
+ else if (!strcmp(value, "2457"))
+ val = 4;
+ else if (!strcmp(value, "2465"))
+ val = 5;
+ if (val == -1)
+ err(1, "Bad Frequency - %s", value);
+ arl_io.cfg.channelNumber = val;
+ arl_io.what_set |= ARLAN_SET_channelNumber;
+ }
+
+ if (!strcasecmp(param, "spread")) {
+ if (!strcmp(value, "354"))
+ val = 1;
+ else if (!strcmp(value, "500"))
+ val = 2;
+ else if (!strcmp(value, "1000"))
+ val = 3;
+ else if (!strcmp(value, "2000"))
+ val = 4;
+ if (val == -1)
+ err (1, "Bad Bitrate - %s", value);
+ arl_io.cfg.spreadingCode = val;
+ arl_io.what_set |= ARLAN_SET_spreadingCode;
+ }
+
+ if (!strcasecmp(param, "priority")) {
+ if (!strcasecmp(value, "normal"))
+ val = 0;
+ else if (!strcasecmp(value, "high"))
+ val = 1;
+ else if (!strcasecmp(value, "highest"))
+ val = 2;
+ if (val == -1)
+ err( 1, "Bad priority - %s", value);
+ arl_io.cfg.priority = val;
+ arl_io.what_set |= ARLAN_SET_priority;
+ }
+
+ if (!strcasecmp(param, "mode")) {
+ if (!strcmp(value, "655"))
+ val = 0;
+ else if (!strcmp(value, "640"))
+ val = 1;
+ else if (!strcasecmp (value, "PSP"))
+ val = 2;
+ if (val == -1)
+ err (1, "Bad Mode - %s", value);
+ arl_io.cfg.registrationMode = val;
+ arl_io.what_set |= ARLAN_SET_registrationMode;
+ }
+
+ if (!strcasecmp(param, "parent")) {
+ if ((ea = (struct ether_addr*) ether_aton(value)) == NULL)
+ err (1, "Bad parent's MAC - %s", value);
+ for (val = 0; val < 6; val++) {
+ arl_io.cfg.specifiedRouter[val] =
+ (int) ea->octet[val];
+ }
+ arl_io.what_set |= ARLAN_SET_specifiedRouter;
+ }
+
+ if (!strcasecmp(param, "addr")) {
+ if ((ea = (struct ether_addr*) ether_aton(value)) == NULL)
+ err (1, "Bad MAC - %s", value);
+ for (val = 0; val < 6; val++) {
+ arl_io.cfg.lanCardNodeId[val] =
+ (int) ea->octet[val];
+ }
+ arl_io.what_set |= ARLAN_SET_lanCardNodeId;
+ }
+
+ if (!strcasecmp(param, "country")) {
+ arl_io.cfg.channelSet = atoi(value);
+ arl_io.what_set |= ARLAN_SET_channelSet;
+ }
+
+ if (!strcasecmp(param, "channel")) {
+ arl_io.cfg.channelNumber = atoi(value);
+ arl_io.what_set |= ARLAN_SET_channelNumber;
+ }
+
+ if (!strcasecmp(param, "bitrate")) {
+ arl_io.cfg.spreadingCode = atoi(value);
+ arl_io.what_set |= ARLAN_SET_spreadingCode;
+ }
+
+ if (!strcasecmp(param, "receive")) {
+ arl_io.cfg.receiveMode = atoi(value);
+ arl_io.what_set |= ARLAN_SET_receiveMode;
+ }
+
+ if (!strcasecmp(param, "txretry")) {
+ arl_io.cfg.txRetry = atoi(value);
+ arl_io.what_set |= ARLAN_SET_txRetry;
+ }
+ }
+
+ if (arl_io.what_set) {
+ if (ioctl(sd, SIOCSARLALL, (caddr_t)&ifr))
+ err (1, "Set ALL" );
+ if (ioctl(sd, SIOCGARLALL, (caddr_t)&ifr))
+ err (1, "Get ALL");
+ print_al(&arl_io.cfg);
+ }
+
+ return 0;
+}
diff --git a/usr.sbin/arlcontrol/arlcontrol.8 b/usr.sbin/arlcontrol/arlcontrol.8
new file mode 100644
index 0000000..1523bbb
--- /dev/null
+++ b/usr.sbin/arlcontrol/arlcontrol.8
@@ -0,0 +1,236 @@
+.\" Copyright (c) 1997, 1998, 1999
+.\" Bill Paul <wpaul@ee.columbia.edu> All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 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 Bill Paul.
+.\" 4. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``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 Bill Paul OR THE VOICES IN HIS HEAD
+.\" 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.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd August 25,2003
+.Dt ARLCONTROL 8
+.Os
+.Sh NAME
+.Nm arlconfig
+.Nd configure Aironet Arlan 655 device
+.Sh SYNOPSIS
+.Nm
+.Ar iface Cm name Ar name
+.Nm
+.Ar iface Cm sid Ar SID
+.Nm
+.Ar iface Cm country Ar country ( Cm 9-15 )
+.Nm
+.Ar iface Cm channel Ar channel
+(depend on
+.Ar country )
+.Nm
+.Ar iface Cm freq Ar freq ( Cm 2412, 2427, 2442, 2457, 2465 )
+.Nm
+.Ar iface Cm spread Ar spread Cm ( 354, 500, 1000, 2000 )
+.Nm
+.Ar iface Cm bitrate Ar bitrate ( Cm 0-4)
+.Nm
+.Ar iface Cm mode Ar mode ( Cm 640 | 655 )
+.Nm
+.Ar iface Cm priority Ar priority ( Cm normal, high, highest )
+.Nm
+.Ar iface Cm stat
+.Nm
+.Ar iface Cm quality Ar seconds [ Cm count Ar <count> ]
+.Sh DESCRIPTION
+The
+.Nm
+utility controls the operation of Aironet Arlan 655 wireless networking
+devices via the
+.Xr arl 4
+driver.
+Most of the parameters that can be changed are related to the
+Aironet protocol which the Aironet Arlan 655 card implements.
+The parameters include
+the station name, the station operation mode
+.Ar (point to point or infrastructure) ,
+and the network name of a service
+set to join.
+The
+.Nm
+utility can also be used to view the current NIC status, configuration
+and to dump out the values of the card's statistics counters.
+.Pp
+The
+.Ar iface
+argument given to
+.Nm
+should be the logical interface name associated with the Aironet Arlan 655
+device
+.Li ( arl0 , arl1 ,
+etc.) and must be specified.
+.Sh OPTIONS
+The options are as follows:
+.Bl -tag -width indent
+.It Cm name Ar name
+Set
+.Ar Device Name .
+This
+parameter is used to establish a 15-byte ASCII name
+for the Arlan 655 Client Card. The
+.Ar Device Name
+is optional and may be left blank.
+.Pp
+If you choose to assign a name, while operating in
+.Ar TMA
+mode, the name will appear in the Arlan Access Point's Registration Table.
+Duplicate names are allowed.
+.It Cm sid Ar SID
+Set
+.Ar System Identifier.
+The System Identifier
+.Ar (SID)
+is a 4-byte, hexadecimal digit value that
+is attached to each packet sent out over the radio. Establishing a
+.Ar SID
+allows you to group nodes into a microcelluar network and exclude
+those nodes that are whiting radio range on other networks.
+.Pp
+The
+.Ar SID
+value must be an even number, cannot exceed ts and must start with
+00 or 02. Examples of valid SID values are: 00000102, 0200AA14, 00013A18,
+007F6380. The
+.Ar default
+SID is
+.Cm 00000002 .
+.Pp
+Since nodes will only receive packets from other nodes with a matching SID,
+you must make sure that the Arlan 655 Client Card is set the same SID as
+other nodes on your network.
+.It Cm mode Ar mode ( Cm 640 | 655 )
+Use
+.Ar operating mode
+parameter to specify whether you are operating in
+.Ar TMA , Non-TMA
+or
+.Ar PSP
+mode. The
+.Ar default
+setting is
+.Cm TMA
+mode.
+.Bl -column ".Em Mode" ".Em Regmode" -offset indent indent
+.Em "Mode Registration mode"
+.It 640 Ta TMA
+.It 655 Ta Non-TMA
+.It PSP Ta Power save mode
+.El
+.!!!
+.It Cm country Ar country ( Cm 9-15 )
+.It Cm channel Ar channel
+.It Cm freq Ar freq ( Cm 2412, 2427, 2442, 2457, 2465 )
+Chose
+.Ar country , channel , freq
+ parameters that depend on the
+.Ar contry
+according to the following table:
+.Bl -column ".Em Country" ".Em Channel" ".Em MHz" -offset indent indent
+.Em "Country Ch_Set MHz"
+.It "North America" Ta 9 Ta "2412, 2427, 2442, 2457, 2465"
+.It "U.S.A " Ta 9 Ta "2412, 2427, 2442, 2457, 2465"
+.It "Canada " Ta 9 Ta "2412, 2427, 2442, 2457, 2465"
+.It "Mexico " Ta 9 Ta "2412, 2427, 2442, 2457, 2465"
+.IT "New Zealand " Ta 9 Ta "2412, 2427, 2442, 2457, 2465"
+.It "E.T.S.I " Ta 10 Ta "2412, 2427, 2442, 2457, 2472"
+.It "Japan " Ta 11 Ta "2484"
+.It "France " Ta 12 Ta "2457, 2465, 2475"
+.It "Australia " Ta 13 Ta "2411, 2425, 2439"
+.It "Germany " Ta 14 Ta "2427, 2442, 2457"
+.It "U.K.(MPT1349)" Ta 15 Ta "2460"
+.It "U.K. " Ta 15 Ta "2460"
+.It "Spain " Ta 15 Ta "2460"
+.El
+.It Cm bitrate Ar bitrate ( Cm 0-4)
+.It Cm spread Ar spread Cm ( 354, 500, 1000, 2000 )
+Set device operating bitrate or spread.
+.Bl -column ".Em Rate" ".Em Spread" ".Em kb/s" -offset indent indent
+.Em "Rate Spread kb/s"
+.It 0 Ta - Ta Auto
+.It 1 Ta 354 Ta 354
+.It 2 Ta 512 Ta 512
+.It 3 Ta 1000 Ta 1000
+.It 4 Ta 2000 Ta 2000
+.El
+.It Cm priority Ar priority ( Cm normal, high, highest )
+Use the
+.Ar priority
+parameter to set the priority of the Atlan 655 Radio Media Access Control
+the values are
+.Cm normal , high
+or
+.Cm higest .
+The higher the priority set, the more likely this unit wil be first
+to successfully transmit a packet when multiple units are trying
+to transmit at the same time.
+.Pp
+The percentage of units on your network that you set to other than
+.Dq normal
+should be kept small - 10 percent or less.
+.It Cm stat
+Print internal Arlan 655 statistics block.
+.It Cm quality Ar seconds [ Cm count Ar <count> ]
+Perform link quality test during
+.Ar seconds
+transmitting
+.Ar count
+packets.
+Currently is broken.
+.El
+.Sh EXAMPLES
+.Bd -literal -offset indent
+alrlconfig arl0 name NODE1 sid 4 freq 2442
+arlconfig arl0 quality 10 seconds
+arlconfig arl0 status
+.Pp
+You can configure Arlan 655 card from /etc/start_if.arl0. For example:
+.Pp
+#!/bin/sh
+/sbin/arlconfig arl0 sid 0x000002 freq 2412 spread 2000 mode 640
+.Sh SEE ALSO
+.Xr arl 4 ,
+.Xr "Arlan 655 ISA Wireless LAN Client Card User Guide" .
+.Sh HISTORY
+The
+.Nm
+utility first appeared in
+.Fx 5.3 .
+.Sh BUGS
+Aironet Arlan 640 bridges and Arlan 630 access points don't understand
+country codes other than 9.
+.Sh AUTHORS
+The
+.Nm
+utility was written by
+.Aq ran@styx.aic.net .
+Manpage was written by
+.An Yuri Kurenkov Aq y.kurenkov@init.ru .
diff --git a/usr.sbin/arlcontrol/arlcontrol.c b/usr.sbin/arlcontrol/arlcontrol.c
new file mode 100644
index 0000000..4ab5ca9
--- /dev/null
+++ b/usr.sbin/arlcontrol/arlcontrol.c
@@ -0,0 +1,612 @@
+/*
+ * $RISS: if_arl/arlconfig/arlconfig.c,v 1.3 2003/01/13 07:23:25 count Exp $
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+
+#include <net/if.h>
+#include <net/ethernet.h>
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <limits.h>
+
+#include <dev/arl/if_arlreg.h>
+
+struct freq_list {
+ short fr_no;
+ char* name;
+};
+
+struct freq_list freq_list_1[] = {
+ { 0, "908.50" },
+ { 1, "910.06" },
+ { 2, "915.52" },
+ { 3, "915.00" },
+ { 4, "917.83" },
+ { 5, "919.22" },
+ { 6, "922.26" },
+ { 7, "911.45" },
+ { 8, "915.00" },
+ { 9, "918.55" },
+ { 10,"915.00" },
+ { 11,"915.00" }
+};
+
+struct freq_list freq_list_6[] = {
+ { 0, "920.31" },
+ { 1, "920.33" },
+ { 2, "921.55" },
+ { 3, "922.17" },
+ { 4, "922.79" },
+ { 5, "921.46" },
+ { 6, "921.55" }
+};
+
+struct freq_list freq_list_9[] = {
+ { 0, "Bad" },
+ { 1, "2412" },
+ { 2, "2427" },
+ { 3, "2442" },
+ { 4, "2457" },
+ { 5, "2465" }
+};
+
+
+struct freq_list freq_list_10[] = {
+ { 0, "Bad" },
+ { 1, "2412" },
+ { 2, "2427" },
+ { 3, "2442" },
+ { 4, "2457" },
+ { 5, "2472" }
+};
+
+struct freq_list freq_list_11[] = {
+ { 0, "Bad" },
+ { 1, "2484" }
+};
+
+struct freq_list freq_list_12[] = {
+ { 0, "Bad" },
+ { 1, "2457" },
+ { 2, "2465" },
+ { 3, "2472" },
+};
+
+struct freq_list freq_list_13[] = {
+ { 0, "Bad" },
+ { 1, "2411" },
+ { 2, "2425" },
+ { 3, "2439" }
+};
+
+struct freq_list freq_list_14[] = {
+ { 0, "Bad" },
+ { 1, "2427" },
+ { 2, "2442" },
+ { 3, "2457" }
+};
+
+struct freq_list freq_list_15[] = {
+ { 0, "Bad" },
+ { 1, "2460" }
+};
+
+#define MAXFREQ(a) sizeof(a)/sizeof(struct freq_list)
+
+struct rate_list {
+ short rate_no;
+ char* name;
+};
+
+struct rate_list rate_list_2400[] = {
+ { 0, "Bad" },
+ { 1, "354" },
+ { 2, "512" },
+ { 3, "1000" },
+ { 4, "2000" }
+};
+
+struct radio_type {
+ int id;
+ char* name;
+} radio_type_list [] = {
+ { 0, "No EPROM" },
+ { 1, "092/094" },
+ { 2, "020" },
+ { 3, "092A" },
+ { 4, "020B" },
+ { 5, "095" },
+ { 6, "024" },
+ { 7, "025B" },
+ { 8, "024B" },
+ { 9, "024C" },
+ {10, "025C" },
+ {11, "024-1A" },
+ {12, "025-1A" },
+ {13, "Other" }
+};
+
+static struct ch_list {
+ short chan;
+ char* fr;
+ char* country;
+ struct rate_list* rate;
+ struct freq_list* freq;
+ int max_freq;
+} CHSET[] = {
+ { 0, 0, 0, 0, 0, 0 },
+ { 1, "900 Mhz", "Canada, U.S.A., Mexico", 0, freq_list_1, MAXFREQ(freq_list_1) },
+ { 2, 0, 0, 0, 0, 0 },
+ { 3, 0, 0, 0, 0, 0 },
+ { 4, 0, 0, 0, 0, 0 },
+ { 5, 0, 0, 0, 0, 0 },
+ { 6, "900 Mhz", "Australia", 0, freq_list_6, MAXFREQ(freq_list_6) },
+ { 7, 0, 0, 0, 0, 0 },
+ { 8, 0, 0, 0, 0, 0 },
+ { 9, "2400 Mhz", "North America", rate_list_2400, freq_list_9, MAXFREQ(freq_list_9) },
+ { 10, "2400 Mhz", "E.T.S.I", rate_list_2400, freq_list_10, MAXFREQ(freq_list_10) },
+ { 11, "2400 Mhz", "Japan", rate_list_2400, freq_list_11, MAXFREQ(freq_list_11) },
+ { 12, "2400 Mhz", "France", rate_list_2400, freq_list_12, MAXFREQ(freq_list_12) },
+ { 13, "2400 Mhz", "Australia", rate_list_2400, freq_list_13, MAXFREQ(freq_list_13) },
+ { 14, "2400 Mhz", "Germany", rate_list_2400, freq_list_14, MAXFREQ(freq_list_14) },
+ { 15, "2400 Mhz", "U.K.(MPT1349),Spain", rate_list_2400, freq_list_15, MAXFREQ(freq_list_15) }
+};
+
+char* registrationMode[] = {
+ "NON-TMA",
+ "TMA",
+ "PSP"
+};
+
+char* priorityList[] = {
+ "normal",
+ "high",
+ "highest"
+};
+
+void
+usage()
+{
+ const char *progname = getprogname();
+
+#if 0
+ fprintf(stderr, "\nArlan configuration utility.\n\n");
+#endif
+ fprintf(stderr, "Usage: %s <ifname> [<param> <value> ...]\n", progname);
+ fprintf(stderr, "\t<ifname>\tArlan interface name.\n");
+ fprintf(stderr, "\t<param>\t\tParameter name (see below).\n");
+ fprintf(stderr, "\t<value>\t\tNew value for parameter.\n");
+ fprintf(stderr, "Parameter name:\t\tValue:\n");
+ fprintf(stderr, "\tname\t\tset Name.\n");
+ fprintf(stderr, "\tsid\t\tset System ID.\n");
+ fprintf(stderr, "\tfreq\t\tset Frequency Channel (2412, 2427, 2442, 2457, 2465)\n");
+ fprintf(stderr, "\tspread\t\tset Bitrate (354, 500, 1000, 2000)\n");
+ fprintf(stderr, "\tmode\t\tset Mode (640, 655, PSP).\n");
+ fprintf(stderr, "\tcountry\t\tset Country (9-15)\n");
+ fprintf(stderr, "\tchannel\t\tset Channel (depended on country)\n");
+ fprintf(stderr, "\tbitrate\t\tset Bitrate (0-4)\n");
+ fprintf(stderr, "\tpriority\tset Priority (normal, high, highest)\n");
+#if 0
+ fprintf(stderr, "\tparent\t\tset Arlan parent's MAC.\n");
+ fprintf(stderr, "\taddr\t\tset Arlan MAC.\n");
+#endif
+ fprintf(stderr, "or: %s <ifname> stat\n", progname);
+ fprintf(stderr, "\tprint internal arlan statistics block\n");
+ fprintf(stderr, "or: %s <ifname> quality <seconds> [count <count>]\n",
+ progname);
+ fprintf(stderr, "\tprint receive packet level and quality with interval\n");
+ exit(0);
+}
+
+void
+print_al(struct arl_cfg_param *arl_io)
+{
+ printf("Arlan-655(IC2000) type 0x%x v%d.%d, radio module type %s\n",
+ arl_io->hardwareType,
+ arl_io->majorHardwareVersion,
+ arl_io->minorHardwareVersion,
+ (arl_io->radioModule < 13) ?
+ radio_type_list[arl_io->radioModule].name : "Unknown" );
+ printf("\tname %s, sid 0x%06x, mode %s, num tx retry %d\n",
+ arl_io->name,
+ *(int *)arl_io->sid,
+ (arl_io->registrationMode < 3) ?
+ registrationMode[arl_io->registrationMode]:"Unknown",
+ arl_io->txRetry );
+ printf("\tchannel set %d, %s, %s\n",
+ arl_io->channelSet,
+ CHSET[arl_io->channelSet].fr,
+ CHSET[arl_io->channelSet].country);
+ printf("\tfrequency %s Mhz, bitrate %s kb/s, priority %s, receive mode %d\n",
+ (CHSET[arl_io->channelSet].freq &&
+ CHSET[arl_io->channelSet].max_freq > arl_io->channelNumber) ?
+ CHSET[arl_io->channelSet].freq[arl_io->channelNumber].name :
+ "unknown",
+ (CHSET[arl_io->channelSet].rate) ?
+ CHSET[arl_io->channelSet].rate[arl_io->spreadingCode].name :
+ "unknown",
+ arl_io->priority <= 2 ?
+ priorityList[arl_io->priority] : "unknown",
+ arl_io->receiveMode);
+ printf("\tether %s",
+ (char *)ether_ntoa((struct ether_addr *)arl_io->lanCardNodeId));
+ printf(" registered to %s\n",
+ (char *)ether_ntoa((struct ether_addr *)arl_io->specifiedRouter));
+}
+
+void
+print_stb( struct arl_stats stb )
+{
+ printf("Arlan internal statistics block\n\n");
+ printf("%8u\tdatagrams transmitted\n",
+ stb.numDatagramsTransmitted);
+ printf("%8u\tre-transmitted\n",
+ stb.numReTransmissions);
+ printf("%8u\tframes discarded internally in a router\n",
+ stb.numFramesDiscarded);
+ printf("%8u\tdatagrams received\n",
+ stb.numDatagramsReceived);
+ printf("%8u\tduplicate received frame\n",
+ stb.numDuplicateReceivedFrames);
+ printf("%8u\tdatagrams discarded due to unavailable mail box buffer\n",
+ stb.numDatagramsDiscarded);
+ printf("%8d\tmaximum of re-transmissions datagram\n",
+ stb.maxNumReTransmitDatagram);
+ printf("%8d\tmaximum of re-transmissions frame\n",
+ stb.maxNumReTransmitFrames);
+ printf("%8d\tmaximum of consecutive duplicate received frames\n",
+ stb.maxNumConsecutiveDuplicateFrames);
+ printf("%8u\tbytes transmitted\n",
+ stb.numBytesTransmitted);
+ printf("%8u\tbytes received\n",
+ stb.numBytesReceived);
+ printf("%8u\tCRC errors\n",
+ stb.numCRCErrors);
+ printf("%8u\tlength errors\n",
+ stb.numLengthErrors);
+ printf("%8u\tabort errors\n",
+ stb.numAbortErrors);
+ printf("%8u\tTX underuns\n",
+ stb.numTXUnderruns);
+ printf("%8u\tRX overruns\n",
+ stb.numRXOverruns);
+ printf("%8u\tHold Offs (channel tested busy, tx delayed)\n",
+ stb.numHoldOffs);
+ printf("%8u\tframes transmitted\n",
+ stb.numFramesTransmitted);
+ printf("%8u\tframes received\n",
+ stb.numFramesReceived);
+ printf("%8u\treceive frames lost due unavailable buffer\n",
+ stb.numReceiveFramesLost);
+ printf("%8u\tRX buffer overflows \n",
+ stb.numRXBufferOverflows);
+ printf("%8u\tframes discarded due to Address mismatch\n",
+ stb.numFramesDiscardedAddrMismatch);
+ printf("%8u\tframes discarded due to SID mismatch\n",
+ stb.numFramesDiscardedSIDMismatch);
+ printf("%8u\tpolls transmitted\n",
+ stb.numPollsTransmistted);
+ printf("%8u\tpoll acknowledges received\n",
+ stb.numPollAcknowledges);
+ printf("%8u\tstatus vector timeout\n",
+ stb.numStatusVectorTimeouts);
+ printf("%8u\tNACK packets received\n",
+ stb.numNACKReceived);
+}
+
+#ifdef ARL_QUALITY
+void
+print_qlt(struct arl_quality qlt, int count)
+{
+ int i, s;
+ int v, v1;
+ time_t t;
+ int minLevel, maxLevel, avgLevel;
+ int minQuality, maxQuality, avgQuality;
+
+ t = time(NULL);
+ localtime(&t);
+ printf("#%d Current date-time: %s", count, ctime(&t));
+ printf(" %-39s %s\n","Receive Level","Receive Quality");
+ printf(
+" pkts 0.......10 11............100 > pkts 0.......10 11............100 >\n"\
+" -----+----------+-----------------+--- -----+----------+-----------------+---\n");
+
+ minLevel = 16;
+ maxLevel = 0;
+ avgLevel = 0;
+ minQuality = 16;
+ maxQuality = 0;
+ avgQuality = 0;
+
+ for (i = 0, s = 0; i < ARLAN_MAX_QUALITY; i++) {
+ v = qlt.rxLevel[i];
+ if (v) {
+ if (i < minLevel)
+ minLevel = i;
+ if (i > maxLevel)
+ maxLevel = i;
+ avgLevel += v*i;
+ printf(" %-4d %x", v, i);
+ } else
+ printf(" o %x", i);
+ s += v;
+ if (v < 10)
+ ;
+ else if (v < 100)
+ v = 10 + ((v-10) * 20) / 90;
+ else if (v < 1000)
+ v = 31;
+ else
+ v = 32;
+ v1 = v;
+ while (v) {
+ printf("*");
+ v--;
+ }
+
+ v = 33 - v1;
+ while (v) {
+ printf(" ");
+ v--;
+ }
+
+ v = qlt.rxQuality[i];
+ if (v) {
+ if (i < minQuality)
+ minQuality = i;
+ if (i > maxQuality)
+ maxQuality = i;
+ avgQuality += v*i;
+ printf("%-4d %x", v, i);
+ } else
+ printf("o %x", i);
+
+ if (v < 10)
+ ;
+ else if (v < 100)
+ v = 10 + ((v-10) * 20) / 90;
+ else if (v < 1000)
+ v = 31;
+ else
+ v = 32;
+ }
+ v1 = v;
+ while (v) {
+ printf("*");
+ v--;
+ }
+
+ printf("\n");
+ }
+ printf(" -----+----------+-----------------+--- -----+----------+-----------------+---\n");
+ if (minLevel > 15)
+ minLevel = 0;
+ if (minQuality > 15)
+ minQuality = 0;
+ printf("\tPackets count %-6d\n", s);
+ if (!s)
+ s++;
+ printf("\tLevel min %d/avg %d/max %d\n",
+ minLevel, avgLevel/s, maxLevel);
+ printf("\tQuality min %d/avg %d/max %d\n",
+ minQuality, avgQuality/s, maxQuality);
+}
+#endif /* ARL_QUALITY */
+
+int
+main(int argc, char *argv[])
+{
+ struct ifreq ifr;
+ struct arl_req arl_io;
+ struct ether_addr *ea;
+ struct arl_stats stb;
+ /*static arl_quality qlt;*/
+ int sd, argind, val = -1;
+ long val2;
+ char *param, *value, *value2;
+ /*int end_count, i;*/
+
+ if (argc < 2)
+ usage();
+
+ sd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sd < 0)
+ err(1,"socket");
+ strncpy(ifr.ifr_name, argv[1], sizeof(ifr.ifr_name));
+ ifr.ifr_addr.sa_family = AF_INET;
+ bzero(&arl_io, sizeof(arl_io));
+ ifr.ifr_data = (caddr_t)&arl_io;
+
+ if (argc == 2) {
+ if (ioctl(sd, SIOCGARLALL, (caddr_t)&ifr))
+ err(1,"Get ALL");
+ print_al(&arl_io.cfg);
+ exit(0);
+ }
+
+ if (argc == 3) {
+ if (!strcasecmp(argv[2], "stat")) {
+ strncpy(ifr.ifr_name, argv[1], sizeof(ifr.ifr_name));
+ ifr.ifr_addr.sa_family = AF_INET;
+ ifr.ifr_data = (caddr_t)&stb;
+ if (ioctl(sd, SIOCGARLSTB, (caddr_t)&ifr))
+ err(1,"Get STB");
+ print_stb(stb);
+ exit(0);
+ }
+#ifdef ARL_QUALITY
+ if (!strcasecmp(argv[2],"quality") && argc > 3) {
+ val = atoi(argv[3]);
+ if (val < 0 || val >= 3601)
+ err(1,"Bad time range");
+ end_count = 0;
+ if (argc > 5 && !strcasecmp(argv[4], "count"))
+ end_count = atoi(argv[5]);
+ printf("\n");
+ i = 0;
+ while (i < end_count || !end_count) { /* loop */
+ if (i++)
+ sleep(val);
+ strncpy(ifr.ifr_name,
+ argv[1], sizeof(ifr.ifr_name));
+ ifr.ifr_addr.sa_family = AF_INET;
+ ifr.ifr_data = (caddr_t)&qlt;
+ if (ioctl(sd, SIOCGARLQLT, (caddr_t)&ifr))
+ err(1,"Get QLT");
+ print_qlt(qlt, i);
+ }
+ exit(0);
+ }
+#endif /* ARL_QUALITY */
+ }
+
+ arl_io.what_set = 0;
+
+ for (argind = 2; argind < argc; argind += 2) {
+ param = argv[argind];
+ value = argv[argind+1];
+ val = -1;
+
+ if (!strcasecmp(param, "name")) {
+ bzero(arl_io.cfg.name, 16);
+ strncpy(arl_io.cfg.name, value, 16);
+ arl_io.what_set |= ARLAN_SET_name;
+ }
+
+ if (!strcasecmp(param, "sid")) {
+ val2 = strtol(value, &value2, 0);
+ if (val2 < 0 || val2 > 0xffffff || val2 % 2 ||
+ value == value2)
+ err(1, "Bad SID - %s", value);
+ bcopy(&val2, arl_io.cfg.sid, 4);
+ arl_io.what_set |= ARLAN_SET_sid;
+ }
+
+ if (!strcasecmp (param, "freq")) {
+ if (!strcmp(value, "2412"))
+ val = 1;
+ else if (!strcmp(value, "2427"))
+ val = 2;
+ else if (!strcmp(value, "2442"))
+ val = 3;
+ else if (!strcmp(value, "2457"))
+ val = 4;
+ else if (!strcmp(value, "2465"))
+ val = 5;
+ if (val == -1)
+ err(1, "Bad Frequency - %s", value);
+ arl_io.cfg.channelNumber = val;
+ arl_io.what_set |= ARLAN_SET_channelNumber;
+ }
+
+ if (!strcasecmp(param, "spread")) {
+ if (!strcmp(value, "354"))
+ val = 1;
+ else if (!strcmp(value, "500"))
+ val = 2;
+ else if (!strcmp(value, "1000"))
+ val = 3;
+ else if (!strcmp(value, "2000"))
+ val = 4;
+ if (val == -1)
+ err (1, "Bad Bitrate - %s", value);
+ arl_io.cfg.spreadingCode = val;
+ arl_io.what_set |= ARLAN_SET_spreadingCode;
+ }
+
+ if (!strcasecmp(param, "priority")) {
+ if (!strcasecmp(value, "normal"))
+ val = 0;
+ else if (!strcasecmp(value, "high"))
+ val = 1;
+ else if (!strcasecmp(value, "highest"))
+ val = 2;
+ if (val == -1)
+ err( 1, "Bad priority - %s", value);
+ arl_io.cfg.priority = val;
+ arl_io.what_set |= ARLAN_SET_priority;
+ }
+
+ if (!strcasecmp(param, "mode")) {
+ if (!strcmp(value, "655"))
+ val = 0;
+ else if (!strcmp(value, "640"))
+ val = 1;
+ else if (!strcasecmp (value, "PSP"))
+ val = 2;
+ if (val == -1)
+ err (1, "Bad Mode - %s", value);
+ arl_io.cfg.registrationMode = val;
+ arl_io.what_set |= ARLAN_SET_registrationMode;
+ }
+
+ if (!strcasecmp(param, "parent")) {
+ if ((ea = (struct ether_addr*) ether_aton(value)) == NULL)
+ err (1, "Bad parent's MAC - %s", value);
+ for (val = 0; val < 6; val++) {
+ arl_io.cfg.specifiedRouter[val] =
+ (int) ea->octet[val];
+ }
+ arl_io.what_set |= ARLAN_SET_specifiedRouter;
+ }
+
+ if (!strcasecmp(param, "addr")) {
+ if ((ea = (struct ether_addr*) ether_aton(value)) == NULL)
+ err (1, "Bad MAC - %s", value);
+ for (val = 0; val < 6; val++) {
+ arl_io.cfg.lanCardNodeId[val] =
+ (int) ea->octet[val];
+ }
+ arl_io.what_set |= ARLAN_SET_lanCardNodeId;
+ }
+
+ if (!strcasecmp(param, "country")) {
+ arl_io.cfg.channelSet = atoi(value);
+ arl_io.what_set |= ARLAN_SET_channelSet;
+ }
+
+ if (!strcasecmp(param, "channel")) {
+ arl_io.cfg.channelNumber = atoi(value);
+ arl_io.what_set |= ARLAN_SET_channelNumber;
+ }
+
+ if (!strcasecmp(param, "bitrate")) {
+ arl_io.cfg.spreadingCode = atoi(value);
+ arl_io.what_set |= ARLAN_SET_spreadingCode;
+ }
+
+ if (!strcasecmp(param, "receive")) {
+ arl_io.cfg.receiveMode = atoi(value);
+ arl_io.what_set |= ARLAN_SET_receiveMode;
+ }
+
+ if (!strcasecmp(param, "txretry")) {
+ arl_io.cfg.txRetry = atoi(value);
+ arl_io.what_set |= ARLAN_SET_txRetry;
+ }
+ }
+
+ if (arl_io.what_set) {
+ if (ioctl(sd, SIOCSARLALL, (caddr_t)&ifr))
+ err (1, "Set ALL" );
+ if (ioctl(sd, SIOCGARLALL, (caddr_t)&ifr))
+ err (1, "Get ALL");
+ print_al(&arl_io.cfg);
+ }
+
+ return 0;
+}
OpenPOWER on IntegriCloud