]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - usr.sbin/arlcontrol/arlcontrol.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / usr.sbin / arlcontrol / arlcontrol.c
1 /*
2  * $RISS: if_arl/arlconfig/arlconfig.c,v 1.5 2004/03/16 05:00:21 count Exp $
3  */
4
5 #include <sys/cdefs.h>
6 __FBSDID("$FreeBSD$");
7
8 #include <sys/param.h>
9 #include <sys/socket.h>
10 #include <sys/ioctl.h>
11
12 #include <net/if.h>
13 #include <net/ethernet.h>
14 #include <netinet/in.h>
15 #include <netinet/if_ether.h>
16
17 #include <err.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <time.h>
22 #include <unistd.h>
23 #include <limits.h>
24
25 #include <dev/arl/if_arlreg.h>
26
27 struct freq_list {
28         short   fr_no;
29         char*   name;
30 };
31
32 struct freq_list freq_list_1[] = {
33          { 0, "908.50" },
34          { 1, "910.06" },
35          { 2, "915.52" },
36          { 3, "915.00" },
37          { 4, "917.83" },
38          { 5, "919.22" },
39          { 6, "922.26" },
40          { 7, "911.45" },
41          { 8, "915.00" },
42          { 9, "918.55" },
43          { 10,"915.00" },
44          { 11,"915.00" }
45 };
46
47 struct freq_list freq_list_6[] = {
48         { 0, "920.31" },
49         { 1, "920.33" },
50         { 2, "921.55" },
51         { 3, "922.17" },
52         { 4, "922.79" },
53         { 5, "921.46" },
54         { 6, "921.55" }
55 };
56
57 struct freq_list freq_list_9[] = {
58         { 0, "Bad"  },
59         { 1, "2412" },
60         { 2, "2427" },
61         { 3, "2442" },
62         { 4, "2457" },
63         { 5, "2465" }
64 };
65
66
67 struct freq_list freq_list_10[] = {
68         { 0, "Bad"  },
69         { 1, "2412" },
70         { 2, "2427" },
71         { 3, "2442" },
72         { 4, "2457" },
73         { 5, "2472" }
74 };
75
76 struct freq_list freq_list_11[] = {
77         { 0, "Bad"  },
78         { 1, "2484" }
79 };
80
81 struct freq_list freq_list_12[] = {
82         { 0, "Bad" },
83         { 1, "2457" },
84         { 2, "2465" },
85         { 3, "2472" },
86 };
87
88 struct freq_list freq_list_13[] = {
89         { 0, "Bad" },
90         { 1, "2411" },
91         { 2, "2425" },
92         { 3, "2439" }
93 };
94
95 struct freq_list freq_list_14[] = {
96         { 0, "Bad" },
97         { 1, "2427" },
98         { 2, "2442" },
99         { 3, "2457" }
100 };
101
102 struct freq_list freq_list_15[] = {
103         { 0, "Bad" },
104         { 1, "2460" }
105 };
106
107 #define MAXFREQ(a) sizeof(a)/sizeof(struct freq_list)
108
109 struct rate_list {
110         short   rate_no;
111         char*   name;
112 };
113
114 struct rate_list rate_list_2400[] = {
115         { 0, "Bad" },
116         { 1, "354" },
117         { 2, "512" },
118         { 3, "1000" },
119         { 4, "2000" }
120 };
121
122 struct radio_type {
123         int id;
124         char* name;
125 } radio_type_list []  = {
126         { 0, "No EPROM" },
127         { 1, "092/094"  },
128         { 2, "020"      },
129         { 3, "092A"     },
130         { 4, "020B"     },
131         { 5, "095"      },
132         { 6, "024"      },
133         { 7, "025B"     },
134         { 8, "024B"     },
135         { 9, "024C"     },
136         {10, "025C"     },
137         {11, "024-1A"   },
138         {12, "025-1A"   },
139         {13, "Other"    }
140 };
141
142 static struct ch_list {
143         short   chan;
144         char*   fr;
145         char*   country;
146         struct  rate_list* rate;
147         struct  freq_list* freq;
148         int  max_freq;
149 } CHSET[] = {
150          { 0, 0, 0, 0, 0, 0 },
151          { 1, "900 Mhz",  "Canada, U.S.A., Mexico", 0, freq_list_1, MAXFREQ(freq_list_1) },
152          { 2, 0, 0, 0, 0, 0 },
153          { 3, 0, 0, 0, 0, 0 },
154          { 4, 0, 0, 0, 0, 0 },
155          { 5, 0, 0, 0, 0, 0 },
156          { 6, "900 Mhz",  "Australia", 0, freq_list_6, MAXFREQ(freq_list_6) },
157          { 7, 0, 0, 0, 0, 0 },
158          { 8, 0, 0, 0, 0, 0 },
159          { 9, "2400 Mhz", "North America", rate_list_2400, freq_list_9, MAXFREQ(freq_list_9) },
160         { 10, "2400 Mhz", "E.T.S.I", rate_list_2400, freq_list_10, MAXFREQ(freq_list_10) },
161         { 11, "2400 Mhz", "Japan", rate_list_2400, freq_list_11, MAXFREQ(freq_list_11) },
162         { 12, "2400 Mhz", "France", rate_list_2400, freq_list_12, MAXFREQ(freq_list_12) },
163         { 13, "2400 Mhz", "Australia", rate_list_2400, freq_list_13, MAXFREQ(freq_list_13) },
164         { 14, "2400 Mhz", "Germany", rate_list_2400, freq_list_14, MAXFREQ(freq_list_14) },
165         { 15, "2400 Mhz", "U.K.(MPT1349),Spain", rate_list_2400, freq_list_15, MAXFREQ(freq_list_15) }
166 };
167
168 char* registrationMode[] = {
169         "NON-TMA",
170         "TMA",
171         "PSP"
172 };
173
174 char* priorityList[] = {
175         "normal",
176         "high",
177         "highest"
178 };
179
180 void
181 usage()
182 {
183         const char *progname = getprogname();
184
185 #if 0
186         fprintf(stderr, "\nArlan configuration utility.\n\n");
187 #endif
188         fprintf(stderr, "Usage: %s <ifname> [<param> <value> ...]\n", progname);
189         fprintf(stderr, "\t<ifname>\tArlan interface name.\n");
190         fprintf(stderr, "\t<param>\t\tParameter name (see below).\n");
191         fprintf(stderr, "\t<value>\t\tNew value for parameter.\n");
192         fprintf(stderr, "Parameter name:\t\tValue:\n");
193         fprintf(stderr, "\tcountry\t\tset Country (9-15)\n");
194         fprintf(stderr, "\tpriority\tset Priority (normal, high, highest)\n");
195         fprintf(stderr, "\ttxretry\t\tset Arlan Tx retry.\n");
196         fprintf(stderr, "or: %s <ifname> stat\n", progname);
197         fprintf(stderr, "\tprint internal arlan statistics block\n");
198 #ifdef ARLCACHE
199         fprintf(stderr,"or: %s <ifname> quality\n", progname);
200         fprintf(stderr,"\tprint receive packet level and quality\n");
201 #endif
202         exit(0);
203 }
204
205 void
206 print_al(struct arl_cfg_param *arl_io)
207 {
208         printf("Arlan-655(IC2000) type 0x%x v%d.%d, radio module type %s\n",
209             arl_io->hardwareType,
210             arl_io->majorHardwareVersion,
211             arl_io->minorHardwareVersion,
212             (arl_io->radioModule < 13) ?
213                 radio_type_list[arl_io->radioModule].name : "Unknown" );
214         printf("\tname %s, sid 0x%06x, mode %s, num tx retry %d\n",
215             arl_io->name,
216             *(int *)arl_io->sid,
217             (arl_io->registrationMode < 3) ?
218                 registrationMode[arl_io->registrationMode]:"Unknown",
219             arl_io->txRetry );
220         printf("\tchannel set %d, %s, %s\n",
221             arl_io->channelSet,
222             CHSET[arl_io->channelSet].fr,
223             CHSET[arl_io->channelSet].country);
224         printf("\tfrequency %s Mhz, bitrate %s kb/s, priority %s, receive mode %d\n",
225             (CHSET[arl_io->channelSet].freq &&
226                 CHSET[arl_io->channelSet].max_freq > arl_io->channelNumber) ?
227                 CHSET[arl_io->channelSet].freq[arl_io->channelNumber].name :
228                 "unknown",
229             (CHSET[arl_io->channelSet].rate) ?
230                 CHSET[arl_io->channelSet].rate[arl_io->spreadingCode].name :
231                 "unknown",
232             arl_io->priority <= 2 ?
233                 priorityList[arl_io->priority] : "unknown",
234             arl_io->receiveMode);
235         printf("\tether %s",
236              (char *)ether_ntoa((struct ether_addr *)arl_io->lanCardNodeId));
237         printf(" registered to %s\n",
238              (char *)ether_ntoa((struct ether_addr *)arl_io->specifiedRouter));
239 }
240
241 void
242 print_stb( struct arl_stats stb )
243 {
244         printf("Arlan internal statistics block\n\n");
245         printf("%8u\tdatagrams transmitted\n",
246             stb.numDatagramsTransmitted);
247         printf("%8u\tre-transmitted\n",
248             stb.numReTransmissions);
249         printf("%8u\tframes discarded internally in a router\n",
250             stb.numFramesDiscarded);
251         printf("%8u\tdatagrams received\n",
252             stb.numDatagramsReceived);
253         printf("%8u\tduplicate received frame\n",
254             stb.numDuplicateReceivedFrames);
255         printf("%8u\tdatagrams discarded due to unavailable mail box buffer\n",
256             stb.numDatagramsDiscarded);
257         printf("%8d\tmaximum of re-transmissions datagram\n",
258             stb.maxNumReTransmitDatagram);
259         printf("%8d\tmaximum of re-transmissions frame\n",
260             stb.maxNumReTransmitFrames);
261         printf("%8d\tmaximum of consecutive duplicate received frames\n",
262             stb.maxNumConsecutiveDuplicateFrames);
263         printf("%8u\tbytes transmitted\n",
264             stb.numBytesTransmitted);
265         printf("%8u\tbytes received\n",
266             stb.numBytesReceived);
267         printf("%8u\tCRC errors\n",
268             stb.numCRCErrors);
269         printf("%8u\tlength errors\n",
270             stb.numLengthErrors);
271         printf("%8u\tabort errors\n",
272             stb.numAbortErrors);
273         printf("%8u\tTX underuns\n",
274             stb.numTXUnderruns);
275         printf("%8u\tRX overruns\n",
276             stb.numRXOverruns);
277         printf("%8u\tHold Offs (channel tested busy, tx delayed)\n",
278             stb.numHoldOffs);
279         printf("%8u\tframes transmitted\n",
280             stb.numFramesTransmitted);
281         printf("%8u\tframes received\n",
282             stb.numFramesReceived);
283         printf("%8u\treceive frames lost due unavailable buffer\n",
284             stb.numReceiveFramesLost);
285         printf("%8u\tRX buffer overflows \n",
286             stb.numRXBufferOverflows);
287         printf("%8u\tframes discarded due to Address mismatch\n",
288             stb.numFramesDiscardedAddrMismatch);
289         printf("%8u\tframes discarded due to SID mismatch\n",
290             stb.numFramesDiscardedSIDMismatch);
291         printf("%8u\tpolls transmitted\n",
292             stb.numPollsTransmistted);
293         printf("%8u\tpoll acknowledges received\n",
294             stb.numPollAcknowledges);
295         printf("%8u\tstatus vector timeout\n",
296             stb.numStatusVectorTimeouts);
297         printf("%8u\tNACK packets received\n",
298             stb.numNACKReceived);
299 }
300
301 #ifdef ARLCACHE
302 void
303 print_qlt(struct arl_sigcache *qlt)
304 {
305         int     i;
306         u_int8_t        zero[6] = {0, 0, 0, 0, 0, 0};
307
308         for (i = 0; i < MAXARLCACHE && bcmp(qlt->macsrc, zero, 6); i++) {
309                 printf("[%d]:", i+1);
310                 printf(" %02x:%02x:%02x:%02x:%02x:%02x,",
311                                 qlt->macsrc[0]&0xff,
312                                 qlt->macsrc[1]&0xff,
313                                 qlt->macsrc[2]&0xff,
314                                 qlt->macsrc[3]&0xff,
315                                 qlt->macsrc[4]&0xff,
316                                 qlt->macsrc[5]&0xff);
317                 printf(" rx lvl/qlty: %d/%d,", qlt->level[ARLCACHE_RX],
318                                 qlt->quality[ARLCACHE_RX]);
319                 printf(" tx lvl/qlty: %d/%d", qlt->level[ARLCACHE_TX],
320                                 qlt->quality[ARLCACHE_TX]);
321                 printf("\n");
322                 qlt++;
323         }
324 }
325 #endif
326
327 int
328 main(int argc, char *argv[])
329 {
330         struct ifreq            ifr;
331         struct arl_req          arl_io;
332         struct ether_addr       *ea;
333         struct arl_stats        stb;
334         struct arl_sigcache     qlt[MAXARLCACHE];
335         int                     sd, argind, val = -1;
336         char                    *param, *value;
337
338         if (argc < 2)
339                 usage();
340
341         sd = socket(AF_INET, SOCK_DGRAM, 0);
342         if (sd < 0)
343                 err(1,"socket");
344         strncpy(ifr.ifr_name, argv[1], sizeof(ifr.ifr_name));
345         ifr.ifr_addr.sa_family = AF_INET;
346         bzero(&arl_io, sizeof(arl_io));
347         ifr.ifr_data = (caddr_t)&arl_io;
348
349         if (argc == 2) {
350                 if (ioctl(sd, SIOCGARLALL, (caddr_t)&ifr))
351                         err(1,"Get ALL");
352                 print_al(&arl_io.cfg);
353                 exit(0);
354         }
355
356         if (argc == 3) {
357                 if (!strcasecmp(argv[2], "stat")) {
358                         strncpy(ifr.ifr_name, argv[1], sizeof(ifr.ifr_name));
359                         ifr.ifr_addr.sa_family = AF_INET;
360                         ifr.ifr_data = (caddr_t)&stb;
361                         if (ioctl(sd, SIOCGARLSTB, (caddr_t)&ifr))
362                                 err(1,"Get STB");
363                         print_stb(stb);
364                         exit(0);
365                 }
366 #ifdef ARLCACHE
367                 if (!strcasecmp( argv[2],"quality")) {
368                         printf("\n");
369                         strncpy(ifr.ifr_name, argv[1], sizeof(ifr.ifr_name));
370                         ifr.ifr_addr.sa_family = AF_INET;
371                         ifr.ifr_data = (caddr_t)qlt;
372                         if (ioctl(sd, SIOCGARLQLT, (caddr_t)&ifr))
373                                 err(1,"Get QLT");
374                         print_qlt(qlt);
375                         exit(0);
376                 }
377 #endif
378         }
379
380         arl_io.what_set = 0;
381
382         for (argind = 2; argind < argc; argind += 2) {
383                 param = argv[argind];
384                 value = argv[argind+1];
385                 val = -1;
386
387                 if (!strcasecmp(param, "priority")) {
388                         if (!strcasecmp(value, "normal"))
389                                 val = 0;
390                         else if (!strcasecmp(value, "high"))
391                                 val = 1;
392                         else if (!strcasecmp(value, "highest"))
393                                 val = 2;
394                         if (val == -1)
395                                 err( 1, "Bad priority - %s", value);
396                         arl_io.cfg.priority = val;
397                         arl_io.what_set |= ARLAN_SET_priority;
398                 }
399
400                 if (!strcasecmp(param, "parent")) {
401                         if ((ea = (struct ether_addr*) ether_aton(value)) == NULL)
402                                 err (1, "Bad parent's MAC - %s", value);
403                         for (val = 0; val < 6; val++) {
404                                 arl_io.cfg.specifiedRouter[val] =
405                                     (int) ea->octet[val];
406                         }
407                         arl_io.what_set |= ARLAN_SET_specifiedRouter;
408                 }
409
410                 if (!strcasecmp(param, "country")) {
411                         arl_io.cfg.channelSet = atoi(value);
412                         arl_io.what_set |= ARLAN_SET_channelSet;
413                 }
414
415                 if (!strcasecmp(param, "txretry")) {
416                         arl_io.cfg.txRetry = atoi(value);
417                         arl_io.what_set |= ARLAN_SET_txRetry;
418                 }
419         }
420
421         if (arl_io.what_set) {
422                 if (ioctl(sd, SIOCSARLALL, (caddr_t)&ifr))
423                         err (1, "Set ALL" );
424                 if (ioctl(sd, SIOCGARLALL, (caddr_t)&ifr))
425                         err (1, "Get ALL");
426                 print_al(&arl_io.cfg);
427         }
428
429         return 0;
430 }