1 /*
2 * Channel configuration utility for Cronyx serial adapters.
3 *
4 * Copyright (C) 1997-2002 Cronyx Engineering.
5 * Author: Serge Vakulenko, <vak@cronyx.ru>
6 *
7 * Copyright (C) 1999-2005 Cronyx Engineering.
8 * Author: Roman Kurakin, <rik@cronyx.ru>
9 *
10 * This software is distributed with NO WARRANTIES, not even the implied
11 * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 *
13 * Authors grant any other persons or organisations permission to use
14 * or modify this software as long as this message is kept with the software,
15 * all derivative works or modified versions.
16 *
17 * Cronyx Id: sconfig.c,v 1.4.2.2 2005/11/09 13:01:35 rik Exp $
18 */
19
20 #include <sys/cdefs.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <fcntl.h>
26 #include <errno.h>
27 #include <ctype.h>
28 #include <sys/ioctl.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <sys/socket.h>
32 #include <net/if.h>
33 #include <machine/cserial.h>
34
35 #define MAXCHAN 128
36
37 int vflag, eflag, sflag, mflag, cflag, fflag, iflag, aflag, xflag;
38 int tflag, uflag;
39 char mask[64];
40 int adapter_type; /* 0-sigma, 1-tau, 2-taupci, 3-tau32 */
41 char chan_name[16];
42
43 static void
usage(void)44 usage (void)
45 {
46 printf(
47 "Serial Adapter Configuration Utility\n"
48 "Copyright (C) 1998-2005 Cronyx Engineering.\n"
49 "See also man sconfig (8)\n"
50 "Usage:\n"
51 "\tsconfig [-aimsxeftuc] [device [parameters ...]]\n"
52 "\n"
53 "Options:\n"
54 "\t<no options>\t\t -- print channel options\n"
55 "\t-a\t\t\t -- print all settings of the channel\n"
56 "\t-i\t\t\t -- print network interface status\n"
57 "\t-m\t\t\t -- print modem signal status\n"
58 "\t-s\t\t\t -- print channel statistics\n"
59 "\t-x\t\t\t -- print extended channel statistics\n"
60 "\t-e\t\t\t -- print short E1/G703 statistics\n"
61 "\t-f\t\t\t -- print full E1/G703 statistics\n"
62 "\t-t\t\t\t -- print short E3/T3/STS-1 statistics\n"
63 "\t-u\t\t\t -- print full E3/T3/STS-1 statistics\n"
64 "\t-c\t\t\t -- clear statistics\n"
65 "\nParameters:\n"
66 "\t<number>\t\t -- baud rate, internal clock\n"
67 "\textclock\t\t -- external clock (default)\n"
68 "\nProtocol options:\n"
69 "\tasync\t\t\t -- asynchronous protocol\n"
70 #ifdef __linux__
71 "\tsync\t\t\t -- synchronous protocol\n"
72 #endif
73 "\tcisco\t\t\t -- Cisco/HDLC protocol\n"
74 "\tfr\t\t\t -- Frame Relay protocol\n"
75 #ifdef __linux__
76 "\t dlci<number>\t -- Add new DLCI\n"
77 #endif
78 "\tppp\t\t\t -- PPP protocol\n"
79 #ifdef __linux__
80 "\trbrg\t\t\t -- Remote bridge\n"
81 "\traw\t\t\t -- raw HDLC protocol\n"
82 "\tpacket\t\t\t -- packetized HDLC protocol\n"
83 "\tidle\t\t\t -- no protocol\n"
84 #else
85 "\t keepalive={on,of}\t -- Enable/disable keepalive\n"
86 #endif
87 "\nInterface options:\n"
88 "\tport={rs232,v35,rs449}\t -- port type (for old models of Sigma)\n"
89 "\tcfg={A,B,C}\t\t -- adapter configuration\n"
90 "\tloop={on,off}\t\t -- internal loopback\n"
91 "\trloop={on,off}\t\t -- remote loopback\n"
92 "\tdpll={on,off}\t\t -- DPLL mode\n"
93 "\tnrzi={on,off}\t\t -- NRZI encoding\n"
94 "\tinvclk={on,off}\t\t -- invert receive and transmit clock\n"
95 "\tinvrclk={on,off}\t -- invert receive clock\n"
96 "\tinvtclk={on,off}\t -- invert transmit clock\n"
97 "\thigain={on,off}\t\t -- E1 high non linear input sensitivity \n\t\t\t\t (long line)\n"
98 "\tmonitor={on,off}\t -- E1 high linear input sensitivity \n\t\t\t\t (interception mode)\n"
99 "\tphony={on,off}\t\t -- E1 telepnony mode\n"
100 "\tunfram={on,off}\t\t -- E1 unframed mode\n"
101 "\tscrambler={on,off}\t -- G.703 scrambling mode\n"
102 "\tuse16={on,off}\t\t -- E1 timeslot 16 usage\n"
103 "\tcrc4={on,off}\t\t -- E1 CRC4 mode\n"
104 #ifdef __linux__
105 "\tami={on,off}\t\t -- E1 AMI or HDB3 line code\n"
106 "\tmtu={size}\t\t -- set MTU in bytes\n"
107 #endif
108 "\tsyn={int,rcv,rcvX}\t -- G.703 transmit clock\n"
109 "\tts=...\t\t\t -- E1 timeslots\n"
110 "\tpass=...\t\t -- E1 subchannel timeslots\n"
111 "\tdir=<num>\t\t -- connect channel to link<num>\n"
112 /*"\trqken={size}\t\t -- set receive queue length in packets\n"*/
113 /*"\tcablen={on,off}\t\t -- T3/STS-1 high transmitter output for long cable\n"*/
114 "\tdebug={0,1,2}\t\t -- enable/disable debug messages\n"
115 );
116 exit (0);
117 }
118
119 static unsigned long
scan_timeslots(char * s)120 scan_timeslots (char *s)
121 {
122 char *e;
123 long v;
124 int i;
125 unsigned long ts, lastv;
126
127 ts = lastv = 0;
128 for (;;) {
129 v = strtol (s, &e, 10);
130 if (e == s)
131 break;
132 if (*e == '-') {
133 lastv = v;
134 s = e+1;
135 continue;
136 }
137 if (*e == ',')
138 ++e;
139
140 if (lastv)
141 for (i=lastv; i<v; ++i)
142 ts |= 1L << i;
143 ts |= 1L << v;
144
145 lastv = 0;
146 s = e;
147 }
148 return ts;
149 }
150
151 static int
ppp_ok(void)152 ppp_ok (void)
153 {
154 #ifdef __linux__
155 int s, p;
156 struct ifreq ifr;
157 char pttyname[32];
158 char *p1, *p2;
159 int i, j;
160 int ppp_disc = N_PPP;
161
162 /*
163 * Open a socket for doing the ioctl operations.
164 */
165 s = socket (AF_INET, SOCK_DGRAM, 0);
166 if (s < 0) {
167 fprintf (stderr, "Error opening socket.\n");
168 return 0;
169 }
170 strncpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
171 if (ioctl (s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0) {
172 /* Ok. */
173 close (s);
174 return 1;
175 }
176 close (s);
177
178 /* open pseudo-tty and try to set PPP discipline */
179 sprintf (pttyname, "/dev/ptyXX");
180 p1 = &pttyname[8];
181 p2 = &pttyname[9];
182 for (i=0; i<16; i++) {
183 struct stat stb;
184
185 *p1 = "pqrstuvwxyzabcde"[i];
186 *p2 = '0';
187 if (stat (pttyname, &stb) < 0)
188 continue;
189 for (j=0; j<16; j++) {
190 *p2 = "0123456789abcdef"[j];
191 p = open (pttyname, 2);
192 if (p > 0) {
193 if (ioctl (p, TIOCSETD, &ppp_disc) < 0) {
194 fprintf (stderr, "No PPP discipline in kernel.\n");
195 close (p);
196 return 0;
197 }
198 close (p);
199 return 1;
200 }
201 }
202 }
203 fprintf (stderr, "Cannot get pseudo-tty.\n");
204 return 0;
205 #else
206 return 1;
207 #endif
208 }
209
210 static char *
format_timeslots(unsigned long s)211 format_timeslots (unsigned long s)
212 {
213 static char buf [100];
214 char *p = buf;
215 int i;
216
217 for (i=1; i<32; ++i)
218 if ((s >> i) & 1) {
219 int prev = (i > 1) & (s >> (i-1));
220 int next = (i < 31) & (s >> (i+1));
221
222 if (prev) {
223 if (next)
224 continue;
225 *p++ = '-';
226 } else if (p > buf)
227 *p++ = ',';
228
229 if (i >= 10)
230 *p++ = '0' + i / 10;
231 *p++ = '0' + i % 10;
232 }
233 *p = 0;
234 return buf;
235 }
236
237 static void
print_modems(int fd,int need_header)238 print_modems (int fd, int need_header)
239 {
240 int status;
241
242 if (ioctl (fd, TIOCMGET, &status) < 0) {
243 perror ("getting modem status");
244 return;
245 }
246 if (need_header)
247 printf ("Channel\tLE\tDTR\tDSR\tRTS\tCTS\tCD\n");
248 printf ("%s\t%s\t%s\t%s\t%s\t%s\t%s\n", chan_name,
249 status & TIOCM_LE ? "On" : "-",
250 status & TIOCM_DTR ? "On" : "-",
251 status & TIOCM_DSR ? "On" : "-",
252 status & TIOCM_RTS ? "On" : "-",
253 status & TIOCM_CTS ? "On" : "-",
254 status & TIOCM_CD ? "On" : "-");
255 }
256
257 static void
258 #ifdef __linux__
print_ifconfig(int fd)259 print_ifconfig (int fd)
260 #else
261 print_ifconfig (int fd __unused)
262 #endif
263 {
264 char buf [64];
265 #ifdef __linux__
266 char protocol [8];
267
268 if (ioctl (fd, SERIAL_GETPROTO, &protocol) >= 0 &&
269 strcmp (protocol, "fr") == 0)
270 sprintf (buf, "ifconfig %sd16 2>/dev/null", chan_name);
271 else
272 #endif
273 sprintf (buf, "ifconfig %s 2>/dev/null", chan_name);
274 system (buf);
275 }
276
277 static void
set_debug_ifconfig(int on)278 set_debug_ifconfig (int on)
279 {
280 char buf [64];
281 sprintf (buf, "ifconfig %s %sdebug 2>/dev/null", chan_name,
282 on ? "" : "-");
283 system (buf);
284 }
285
286 static char *
format_long(unsigned long val)287 format_long (unsigned long val)
288 {
289 static char s[32];
290 int l;
291 l = sprintf (s, "%lu", val);
292 if (l>7 && !sflag) {
293 s[3] = s[2];
294 s[2] = s[1];
295 s[1] = '.';
296 s[4] = 'e';
297 sprintf (s + 5, "%02d", l-1);
298 }
299 return s;
300 }
301
302 static void
print_stats(int fd,int need_header)303 print_stats (int fd, int need_header)
304 {
305 struct serial_statistics st;
306 unsigned long sarr [9];
307 int i;
308
309 if (ioctl (fd, SERIAL_GETSTAT, &st) < 0) {
310 perror ("getting statistics");
311 return;
312 }
313 if (need_header) {
314 if (sflag) {
315 printf (" ------------Receive----------- "
316 "------------Transmit----------\n");
317 printf ("Channel Interrupts Packets Errors "
318 "Interrupts Packets Errors\n");
319 }
320 else {
321 printf (" --------Receive--------------- "
322 "--------Transmit-------------- Modem\n");
323 printf ("Channel Intrs Bytes Packets Errors "
324 "Intrs Bytes Packets Errors Intrs\n");
325 }
326 }
327
328 sarr [0] = st.rintr;
329 sarr [1] = st.ibytes;
330 sarr [2] = st.ipkts;
331 sarr [3] = st.ierrs;
332 sarr [4] = st.tintr;
333 sarr [5] = st.obytes;
334 sarr [6] = st.opkts;
335 sarr [7] = st.oerrs;
336 sarr [8] = st.mintr;
337 printf ("%s", chan_name);
338 if (sflag) {
339 printf ("\t%-12lu%-12lu%-12lu%-12lu%-12lu%-12lu", sarr[0],
340 sarr[2], sarr[3], sarr[4], sarr[6], sarr[7]);
341 } else {
342 for (i = 0; i < 9; i++)
343 printf ("\t%s", format_long (sarr [i]));
344 printf ("\n");
345 }
346 }
347
348 static void
clear_stats(int fd)349 clear_stats (int fd)
350 {
351 if (ioctl (fd, SERIAL_CLRSTAT, 0) < 0) {
352 perror ("clearing statistics");
353 exit (-1);
354 }
355 }
356
357 static char *
format_e1_status(unsigned long status)358 format_e1_status (unsigned long status)
359 {
360 static char buf [80];
361
362 if (status == 0)
363 return "n/a";
364 if (status & E1_NOALARM)
365 return "Ok";
366 buf[0] = 0;
367 if (status & E1_LOS) strcat (buf, ",LOS");
368 if (status & E1_AIS) strcat (buf, ",AIS");
369 if (status & E1_LOF) strcat (buf, ",LOF");
370 if (status & E1_LOMF) strcat (buf, ",LOMF");
371 if (status & E1_CRC4E) strcat (buf, ",CRC4E");
372 if (status & E1_FARLOF) strcat (buf, ",FARLOF");
373 if (status & E1_AIS16) strcat (buf, ",AIS16");
374 if (status & E1_FARLOMF) strcat (buf, ",FARLOMF");
375 /* if (status & E1_TSTREQ) strcat (buf, ",TSTREQ");*/
376 /* if (status & E1_TSTERR) strcat (buf, ",TSTERR");*/
377 if (buf[0] == ',')
378 return buf+1;
379 return "Unknown";
380 }
381
382 static void
print_frac(int leftalign,unsigned long numerator,unsigned long divider)383 print_frac (int leftalign, unsigned long numerator, unsigned long divider)
384 {
385 int n;
386
387 if (numerator < 1 || divider < 1) {
388 printf (leftalign ? "/- " : " -");
389 return;
390 }
391 n = (int) (0.5 + 1000.0 * numerator / divider);
392 if (n < 1000) {
393 printf (leftalign ? "/.%-3d" : " .%03d", n);
394 return;
395 }
396 putchar (leftalign ? '/' : ' ');
397
398 if (n >= 1000000) n = (n+500) / 1000 * 1000;
399 else if (n >= 100000) n = (n+50) / 100 * 100;
400 else if (n >= 10000) n = (n+5) / 10 * 10;
401
402 switch (n) {
403 case 1000: printf (".999"); return;
404 case 10000: n = 9990; break;
405 case 100000: n = 99900; break;
406 case 1000000: n = 999000; break;
407 }
408 if (n < 10000) printf ("%d.%d", n/1000, n/10%100);
409 else if (n < 100000) printf ("%d.%d", n/1000, n/100%10);
410 else if (n < 1000000) printf ("%d.", n/1000);
411 else printf ("%d", n/1000);
412 }
413
414 static void
print_e1_stats(int fd,int need_header)415 print_e1_stats (int fd, int need_header)
416 {
417 struct e1_statistics st;
418 int i, maxi;
419
420 if (need_header)
421 printf ("Chan\t Unav/Degr Bpv/Fsyn CRC/RCRC Err/Lerr Sev/Bur Oof/Slp Status\n");
422
423 if (ioctl (fd, SERIAL_GETESTAT, &st) < 0)
424 return;
425 printf ("%s\t", chan_name);
426
427 /* Unavailable seconds, degraded minutes */
428 print_frac (0, st.currnt.uas, st.cursec);
429 print_frac (1, 60 * st.currnt.dm, st.cursec);
430
431 /* Bipolar violations, frame sync errors */
432 print_frac (0, st.currnt.bpv, st.cursec);
433 print_frac (1, st.currnt.fse, st.cursec);
434
435 /* CRC errors, remote CRC errors (E-bit) */
436 print_frac (0, st.currnt.crce, st.cursec);
437 print_frac (1, st.currnt.rcrce, st.cursec);
438
439 /* Errored seconds, line errored seconds */
440 print_frac (0, st.currnt.es, st.cursec);
441 print_frac (1, st.currnt.les, st.cursec);
442
443 /* Severely errored seconds, bursty errored seconds */
444 print_frac (0, st.currnt.ses, st.cursec);
445 print_frac (1, st.currnt.bes, st.cursec);
446
447 /* Out of frame seconds, controlled slip seconds */
448 print_frac (0, st.currnt.oofs, st.cursec);
449 print_frac (1, st.currnt.css, st.cursec);
450
451 printf (" %s\n", format_e1_status (st.status));
452
453 if (fflag) {
454 /* Print total statistics. */
455 printf ("\t");
456 print_frac (0, st.total.uas, st.totsec);
457 print_frac (1, 60 * st.total.dm, st.totsec);
458
459 print_frac (0, st.total.bpv, st.totsec);
460 print_frac (1, st.total.fse, st.totsec);
461
462 print_frac (0, st.total.crce, st.totsec);
463 print_frac (1, st.total.rcrce, st.totsec);
464
465 print_frac (0, st.total.es, st.totsec);
466 print_frac (1, st.total.les, st.totsec);
467
468 print_frac (0, st.total.ses, st.totsec);
469 print_frac (1, st.total.bes, st.totsec);
470
471 print_frac (0, st.total.oofs, st.totsec);
472 print_frac (1, st.total.css, st.totsec);
473
474 printf (" -- Total\n");
475
476 /* Print 24-hour history. */
477 maxi = (st.totsec - st.cursec) / 900;
478 if (maxi > 48)
479 maxi = 48;
480 for (i=0; i<maxi; ++i) {
481 printf (" ");
482 print_frac (0, st.interval[i].uas, 15*60);
483 print_frac (1, 60 * st.interval[i].dm, 15*60);
484
485 print_frac (0, st.interval[i].bpv, 15*60);
486 print_frac (1, st.interval[i].fse, 15*60);
487
488 print_frac (0, st.interval[i].crce, 15*60);
489 print_frac (1, st.interval[i].rcrce, 15*60);
490
491 print_frac (0, st.interval[i].es, 15*60);
492 print_frac (1, st.interval[i].les, 15*60);
493
494 print_frac (0, st.interval[i].ses, 15*60);
495 print_frac (1, st.interval[i].bes, 15*60);
496
497 print_frac (0, st.interval[i].oofs, 15*60);
498 print_frac (1, st.interval[i].css, 15*60);
499
500 if (i < 3)
501 printf (" -- %dm\n", (i+1)*15);
502 else
503 printf (" -- %dh %dm\n", (i+1)/4, (i+1)%4*15);
504 }
505 }
506 }
507
508 static char *
format_e3_status(unsigned long status)509 format_e3_status (unsigned long status)
510 {
511 static char buf [80];
512
513 buf[0] = 0;
514 if (status & E3_LOS) strcat (buf, ",LOS");
515 if (status & E3_TXE) strcat (buf, ",XMIT");
516 if (buf[0] == ',')
517 return buf+1;
518 return "Ok";
519 }
520
521 static char *
format_e3_cv(unsigned long cv,unsigned long baud,unsigned long atime)522 format_e3_cv (unsigned long cv, unsigned long baud, unsigned long atime)
523 {
524 static char buf[80];
525
526 if (!cv || !baud || !atime)
527 sprintf (buf, " - ");
528 else
529 sprintf (buf, "%10lu (%.1e)", cv, (double)cv/baud/atime);
530 return buf;
531 }
532
533 static void
print_e3_stats(int fd,int need_header)534 print_e3_stats (int fd, int need_header)
535 {
536 struct e3_statistics st;
537 int i, maxi;
538 long baud;
539
540 if (need_header)
541 printf ("Chan\t--Code Violations---\t\t\t\t\t ----Status----\n");
542
543 if (ioctl (fd, SERIAL_GETE3STAT, &st) < 0 ||
544 ioctl (fd, SERIAL_GETBAUD, &baud) < 0)
545 return;
546
547 if (!st.cursec)
548 st.cursec = 1;
549
550 printf ("%s\t%s\t\t\t\t\t", chan_name,
551 format_e3_cv (st.ccv, baud, st.cursec));
552
553 printf (" %s\n", format_e3_status (st.status));
554
555
556 if (uflag) {
557 /* Print total statistics. */
558 printf ("\t%s\t\t\t\t\t",
559 format_e3_cv (st.tcv, baud, st.totsec));
560 printf (" -- Total\n");
561
562 /* Print 24-hour history. */
563 maxi = (st.totsec - st.cursec) / 900;
564 if (maxi > 48)
565 maxi = 48;
566 for (i=0; i<maxi; ++i) {
567 printf ("\t%s\t\t\t\t\t",
568 format_e3_cv (st.icv[i], baud, 15*60));
569 if (i < 3)
570 printf (" -- %2dm\n", (i+1)*15);
571 else
572 printf (" -- %2dh %2dm\n", (i+1)/4, (i+1)%4*15);
573 }
574 }
575 }
576
577 static void
print_chan(int fd)578 print_chan (int fd)
579 {
580 char protocol [8];
581 char cfg;
582 int loop, dpll, nrzi, invclk, clk, higain, phony, use16, crc4;
583 int level, keepalive, debug, port, invrclk, invtclk, unfram, monitor;
584 int cable, dir, scrambler, ami, mtu;
585 int cablen, rloop, rqlen;
586 long baud, timeslots, subchan;
587 int protocol_valid, baud_valid, loop_valid, use16_valid, crc4_valid;
588 int dpll_valid, nrzi_valid, invclk_valid, clk_valid, phony_valid;
589 int timeslots_valid, subchan_valid, higain_valid, level_valid;
590 int keepalive_valid, debug_valid, cfg_valid, port_valid;
591 int invrclk_valid, invtclk_valid, unfram_valid, monitor_valid;
592 int cable_valid, dir_valid, scrambler_valid, ami_valid, mtu_valid;
593 int cablen_valid, rloop_valid, rqlen_valid;
594
595 protocol_valid = ioctl (fd, SERIAL_GETPROTO, &protocol) >= 0;
596 cfg_valid = ioctl (fd, SERIAL_GETCFG, &cfg) >= 0;
597 baud_valid = ioctl (fd, SERIAL_GETBAUD, &baud) >= 0;
598 loop_valid = ioctl (fd, SERIAL_GETLOOP, &loop) >= 0;
599 dpll_valid = ioctl (fd, SERIAL_GETDPLL, &dpll) >= 0;
600 nrzi_valid = ioctl (fd, SERIAL_GETNRZI, &nrzi) >= 0;
601 invclk_valid = ioctl (fd, SERIAL_GETINVCLK, &invclk) >= 0;
602 invrclk_valid = ioctl (fd, SERIAL_GETINVRCLK, &invrclk) >= 0;
603 invtclk_valid = ioctl (fd, SERIAL_GETINVTCLK, &invtclk) >= 0;
604 clk_valid = ioctl (fd, SERIAL_GETCLK, &clk) >= 0;
605 timeslots_valid = ioctl (fd, SERIAL_GETTIMESLOTS, ×lots) >= 0;
606 subchan_valid = ioctl (fd, SERIAL_GETSUBCHAN, &subchan) >= 0;
607 higain_valid = ioctl (fd, SERIAL_GETHIGAIN, &higain) >= 0;
608 phony_valid = ioctl (fd, SERIAL_GETPHONY, &phony) >= 0;
609 unfram_valid = ioctl (fd, SERIAL_GETUNFRAM, &unfram) >= 0;
610 monitor_valid = ioctl (fd, SERIAL_GETMONITOR, &monitor) >= 0;
611 use16_valid = ioctl (fd, SERIAL_GETUSE16, &use16) >= 0;
612 crc4_valid = ioctl (fd, SERIAL_GETCRC4, &crc4) >= 0;
613 ami_valid = ioctl (fd, SERIAL_GETLCODE, &ami) >= 0;
614 level_valid = ioctl (fd, SERIAL_GETLEVEL, &level) >= 0;
615 keepalive_valid = ioctl (fd, SERIAL_GETKEEPALIVE, &keepalive) >= 0;
616 debug_valid = ioctl (fd, SERIAL_GETDEBUG, &debug) >= 0;
617 port_valid = ioctl (fd, SERIAL_GETPORT, &port) >= 0;
618 cable_valid = ioctl (fd, SERIAL_GETCABLE, &cable) >= 0;
619 dir_valid = ioctl (fd, SERIAL_GETDIR, &dir) >= 0;
620 scrambler_valid = ioctl (fd, SERIAL_GETSCRAMBLER, &scrambler) >= 0;
621 cablen_valid = ioctl (fd, SERIAL_GETCABLEN, &cablen) >= 0;
622 rloop_valid = ioctl (fd, SERIAL_GETRLOOP, &rloop) >= 0;
623 mtu_valid = ioctl (fd, SERIAL_GETMTU, &mtu) >= 0;
624 rqlen_valid = ioctl (fd, SERIAL_GETRQLEN, &rqlen) >= 0;
625
626 printf ("%s", chan_name);
627 if (port_valid)
628 switch (port) {
629 case 0: printf (" (rs232)"); break;
630 case 1: printf (" (v35)"); break;
631 case 2: printf (" (rs530)"); break;
632 }
633 else if (cable_valid)
634 switch (cable) {
635 case 0: printf (" (rs232)"); break;
636 case 1: printf (" (v35)"); break;
637 case 2: printf (" (rs530)"); break;
638 case 3: printf (" (x21)"); break;
639 case 4: printf (" (rs485)"); break;
640 case 9: printf (" (no cable)"); break;
641 }
642 if (debug_valid && debug)
643 printf (" debug=%d", debug);
644 if (protocol_valid && *protocol)
645 printf (" %.8s", protocol);
646 else
647 printf (" idle");
648 if (cablen_valid)
649 printf (" cablen=%s", cablen ? "on" : "off");
650 if (keepalive_valid)
651 printf (" keepalive=%s", keepalive ? "on" : "off");
652
653 if (cfg_valid)
654 switch (cfg) {
655 case 'a' : printf (" cfg=A"); break;
656 case 'b' : printf (" cfg=B"); break;
657 case 'c' : printf (" cfg=C"); break;
658 case 'd' : printf (" cfg=D"); break;
659 default : printf (" cfg=unknown");
660 }
661 if (dir_valid)
662 printf (" dir=%d", dir);
663
664 if (baud_valid) {
665 if (baud)
666 printf (" %ld", baud);
667 else
668 printf (" extclock");
669 }
670 if (mtu_valid)
671 printf (" mtu=%d", mtu);
672
673 if (aflag && rqlen_valid)
674 printf (" rqlen=%d", rqlen);
675
676 if (clk_valid)
677 switch (clk) {
678 case E1CLK_INTERNAL: printf (" syn=int"); break;
679 case E1CLK_RECEIVE: printf (" syn=rcv"); break;
680 case E1CLK_RECEIVE_CHAN0: printf (" syn=rcv0"); break;
681 case E1CLK_RECEIVE_CHAN1: printf (" syn=rcv1"); break;
682 case E1CLK_RECEIVE_CHAN2: printf (" syn=rcv2"); break;
683 case E1CLK_RECEIVE_CHAN3: printf (" syn=rcv3"); break;
684 default: printf (" syn=%d", clk); break;
685 }
686
687 if (dpll_valid)
688 printf (" dpll=%s", dpll ? "on" : "off");
689 if (nrzi_valid)
690 printf (" nrzi=%s", nrzi ? "on" : "off");
691 if (invclk_valid)
692 printf (" invclk=%s", invclk ? "on" : "off");
693 if (invrclk_valid)
694 printf (" invrclk=%s", invrclk ? "on" : "off");
695 if (invtclk_valid)
696 printf (" invtclk=%s", invtclk ? "on" : "off");
697 if (unfram_valid)
698 printf (" unfram=%s", unfram ? "on" : "off");
699 if (use16_valid)
700 printf (" use16=%s", use16 ? "on" : "off");
701 if (aflag) {
702 if (crc4_valid)
703 printf (" crc4=%s", crc4 ? "on" : "off");
704 if (higain_valid)
705 printf (" higain=%s", higain ? "on" : "off");
706 if (monitor_valid)
707 printf (" monitor=%s", monitor ? "on" : "off");
708 if (phony_valid)
709 printf (" phony=%s", phony ? "on" : "off");
710 if (scrambler_valid)
711 printf (" scrambler=%s", scrambler ? "on" : "off");
712 if (loop_valid)
713 printf (" loop=%s", loop ? "on" : "off");
714 if (rloop_valid)
715 printf (" rloop=%s", rloop ? "on" : "off");
716 if (ami_valid)
717 printf (" ami=%s", ami ? "on" : "off");
718 }
719 if (timeslots_valid)
720 printf (" ts=%s", format_timeslots (timeslots));
721 if (subchan_valid)
722 printf (" pass=%s", format_timeslots (subchan));
723 if (level_valid)
724 printf (" (level=-%.1fdB)", level / 10.0);
725 printf ("\n");
726 }
727
728 static void
setup_chan(int fd,int argc,char ** argv)729 setup_chan (int fd, int argc, char **argv)
730 {
731 int i, mode, loop, nrzi, dpll, invclk, phony, use16, crc4, unfram, ami;
732 int higain, clk, keepalive, debug, port, dlci, invrclk, invtclk;
733 int monitor, dir, scrambler, rloop, cablen;
734 int mode_valid;
735 long baud, timeslots, mtu, rqlen;
736
737 for (i=0; i<argc; ++i) {
738 if (argv[i][0] >= '0' && argv[i][0] <= '9') {
739 baud = strtol (argv[i], 0, 10);
740 ioctl (fd, SERIAL_SETBAUD, &baud);
741 } else if (strcasecmp ("extclock", argv[i]) == 0) {
742 baud = 0;
743 ioctl (fd, SERIAL_SETBAUD, &baud);
744 } else if (strncasecmp ("cfg=", argv[i], 4) == 0) {
745 if (strncasecmp ("a", argv[i]+4, 1) == 0)
746 ioctl (fd, SERIAL_SETCFG, "a");
747 else if (strncasecmp ("b", argv[i]+4, 1) == 0)
748 ioctl (fd, SERIAL_SETCFG, "b");
749 else if (strncasecmp ("c", argv[i]+4, 1) == 0)
750 ioctl (fd, SERIAL_SETCFG, "c");
751 else if (strncasecmp ("d", argv[i]+4, 1) == 0)
752 ioctl (fd, SERIAL_SETCFG, "d");
753 else {
754 fprintf (stderr, "invalid cfg\n");
755 exit (-1);
756 }
757 } else if (strcasecmp ("idle", argv[i]) == 0)
758 ioctl (fd, SERIAL_SETPROTO, "\0\0\0\0\0\0\0");
759 else if (strcasecmp ("async", argv[i]) == 0) {
760 mode = SERIAL_ASYNC;
761 if (ioctl (fd, SERIAL_SETMODE, &mode) >= 0)
762 ioctl (fd, SERIAL_SETPROTO, "async\0\0");
763 } else if (strcasecmp ("sync", argv[i]) == 0) {
764 mode = SERIAL_HDLC;
765 if (ioctl (fd, SERIAL_SETMODE, &mode) >= 0)
766 ioctl (fd, SERIAL_SETPROTO, "sync\0\0\0");
767 } else if (strcasecmp ("cisco", argv[i]) == 0) {
768 mode = SERIAL_HDLC;
769 ioctl (fd, SERIAL_SETMODE, &mode);
770 ioctl (fd, SERIAL_SETPROTO, "cisco\0\0");
771 } else if (strcasecmp ("rbrg", argv[i]) == 0) {
772 mode = SERIAL_HDLC;
773 ioctl (fd, SERIAL_SETMODE, &mode);
774 ioctl (fd, SERIAL_SETPROTO, "rbrg\0\0\0");
775 } else if (strcasecmp ("raw", argv[i]) == 0) {
776 mode = SERIAL_HDLC;
777 ioctl (fd, SERIAL_SETMODE, &mode);
778 ioctl (fd, SERIAL_SETPROTO, "raw\0\0\0\0");
779 } else if (strcasecmp ("packet", argv[i]) == 0) {
780 mode = SERIAL_HDLC;
781 ioctl (fd, SERIAL_SETMODE, &mode);
782 ioctl (fd, SERIAL_SETPROTO, "packet\0");
783 } else if (strcasecmp ("ppp", argv[i]) == 0) {
784 /* check that ppp line discipline is present */
785 if (ppp_ok ()) {
786 mode = SERIAL_HDLC;
787 ioctl (fd, SERIAL_SETMODE, &mode);
788 ioctl (fd, SERIAL_SETPROTO, "ppp\0\0\0\0");
789 }
790 } else if (strncasecmp ("keepalive=", argv[i], 10) == 0) {
791 keepalive = (strcasecmp ("on", argv[i] + 10) == 0);
792 ioctl (fd, SERIAL_SETKEEPALIVE, &keepalive);
793 } else if (strcasecmp ("fr", argv[i]) == 0) {
794 mode = SERIAL_HDLC;
795 ioctl (fd, SERIAL_SETMODE, &mode);
796 ioctl (fd, SERIAL_SETPROTO, "fr\0\0\0\0\0");
797 } else if (strcasecmp ("zaptel", argv[i]) == 0) {
798 mode = SERIAL_HDLC;
799 ioctl (fd, SERIAL_SETMODE, &mode);
800 ioctl (fd, SERIAL_SETPROTO, "zaptel\0");
801 } else if (strncasecmp ("debug=", argv[i], 6) == 0) {
802 debug = strtol (argv[i]+6, 0, 10);
803 mode_valid = ioctl (fd, SERIAL_GETMODE, &mode) >= 0;
804 if (!mode_valid || mode != SERIAL_ASYNC) {
805 if (debug == 0) {
806 set_debug_ifconfig(0);
807 } else {
808 ioctl (fd, SERIAL_SETDEBUG, &debug);
809 set_debug_ifconfig(1);
810 }
811 } else {
812 ioctl (fd, SERIAL_SETDEBUG, &debug);
813 }
814 } else if (strncasecmp ("loop=", argv[i], 5) == 0) {
815 loop = (strcasecmp ("on", argv[i] + 5) == 0);
816 ioctl (fd, SERIAL_SETLOOP, &loop);
817 } else if (strncasecmp ("rloop=", argv[i], 6) == 0) {
818 rloop = (strcasecmp ("on", argv[i] + 6) == 0);
819 ioctl (fd, SERIAL_SETRLOOP, &rloop);
820 } else if (strncasecmp ("dpll=", argv[i], 5) == 0) {
821 dpll = (strcasecmp ("on", argv[i] + 5) == 0);
822 ioctl (fd, SERIAL_SETDPLL, &dpll);
823 } else if (strncasecmp ("nrzi=", argv[i], 5) == 0) {
824 nrzi = (strcasecmp ("on", argv[i] + 5) == 0);
825 ioctl (fd, SERIAL_SETNRZI, &nrzi);
826 } else if (strncasecmp ("invclk=", argv[i], 7) == 0) {
827 invclk = (strcasecmp ("on", argv[i] + 7) == 0);
828 ioctl (fd, SERIAL_SETINVCLK, &invclk);
829 } else if (strncasecmp ("invrclk=", argv[i], 8) == 0) {
830 invrclk = (strcasecmp ("on", argv[i] + 8) == 0);
831 ioctl (fd, SERIAL_SETINVRCLK, &invrclk);
832 } else if (strncasecmp ("invtclk=", argv[i], 8) == 0) {
833 invtclk = (strcasecmp ("on", argv[i] + 8) == 0);
834 ioctl (fd, SERIAL_SETINVTCLK, &invtclk);
835 } else if (strncasecmp ("higain=", argv[i], 7) == 0) {
836 higain = (strcasecmp ("on", argv[i] + 7) == 0);
837 ioctl (fd, SERIAL_SETHIGAIN, &higain);
838 } else if (strncasecmp ("phony=", argv[i], 6) == 0) {
839 phony = (strcasecmp ("on", argv[i] + 6) == 0);
840 ioctl (fd, SERIAL_SETPHONY, &phony);
841 } else if (strncasecmp ("unfram=", argv[i], 7) == 0) {
842 unfram = (strcasecmp ("on", argv[i] + 7) == 0);
843 ioctl (fd, SERIAL_SETUNFRAM, &unfram);
844 } else if (strncasecmp ("scrambler=", argv[i], 10) == 0) {
845 scrambler = (strcasecmp ("on", argv[i] + 10) == 0);
846 ioctl (fd, SERIAL_SETSCRAMBLER, &scrambler);
847 } else if (strncasecmp ("monitor=", argv[i], 8) == 0) {
848 monitor = (strcasecmp ("on", argv[i] + 8) == 0);
849 ioctl (fd, SERIAL_SETMONITOR, &monitor);
850 } else if (strncasecmp ("use16=", argv[i], 6) == 0) {
851 use16 = (strcasecmp ("on", argv[i] + 6) == 0);
852 ioctl (fd, SERIAL_SETUSE16, &use16);
853 } else if (strncasecmp ("crc4=", argv[i], 5) == 0) {
854 crc4 = (strcasecmp ("on", argv[i] + 5) == 0);
855 ioctl (fd, SERIAL_SETCRC4, &crc4);
856 } else if (strncasecmp ("ami=", argv[i], 4) == 0) {
857 ami = (strcasecmp ("on", argv[i] + 4) == 0);
858 ioctl (fd, SERIAL_SETLCODE, &ami);
859 } else if (strncasecmp ("mtu=", argv[i], 4) == 0) {
860 mtu = strtol (argv[i] + 4, 0, 10);
861 ioctl (fd, SERIAL_SETMTU, &mtu);
862 } else if (strncasecmp ("rqlen=", argv[i], 6) == 0) {
863 rqlen = strtol (argv[i] + 6, 0, 10);
864 ioctl (fd, SERIAL_SETRQLEN, &rqlen);
865 } else if (strcasecmp ("syn=int", argv[i]) == 0) {
866 clk = E1CLK_INTERNAL;
867 ioctl (fd, SERIAL_SETCLK, &clk);
868 } else if (strcasecmp ("syn=rcv", argv[i]) == 0) {
869 clk = E1CLK_RECEIVE;
870 ioctl (fd, SERIAL_SETCLK, &clk);
871 } else if (strcasecmp ("syn=rcv0", argv[i]) == 0) {
872 clk = E1CLK_RECEIVE_CHAN0;
873 ioctl (fd, SERIAL_SETCLK, &clk);
874 } else if (strcasecmp ("syn=rcv1", argv[i]) == 0) {
875 clk = E1CLK_RECEIVE_CHAN1;
876 ioctl (fd, SERIAL_SETCLK, &clk);
877 } else if (strcasecmp ("syn=rcv2", argv[i]) == 0) {
878 clk = E1CLK_RECEIVE_CHAN2;
879 ioctl (fd, SERIAL_SETCLK, &clk);
880 } else if (strcasecmp ("syn=rcv3", argv[i]) == 0) {
881 clk = E1CLK_RECEIVE_CHAN3;
882 ioctl (fd, SERIAL_SETCLK, &clk);
883 } else if (strncasecmp ("ts=", argv[i], 3) == 0) {
884 timeslots = scan_timeslots (argv[i] + 3);
885 ioctl (fd, SERIAL_SETTIMESLOTS, ×lots);
886 } else if (strncasecmp ("pass=", argv[i], 5) == 0) {
887 timeslots = scan_timeslots (argv[i] + 5);
888 ioctl (fd, SERIAL_SETSUBCHAN, ×lots);
889 } else if (strncasecmp ("dlci", argv[i], 4) == 0) {
890 dlci = strtol (argv[i]+4, 0, 10);
891 ioctl (fd, SERIAL_ADDDLCI, &dlci);
892 } else if (strncasecmp ("dir=", argv[i], 4) == 0) {
893 dir = strtol (argv[i]+4, 0, 10);
894 ioctl (fd, SERIAL_SETDIR, &dir);
895 } else if (strncasecmp ("port=", argv[i], 5) == 0) {
896 if (strncasecmp ("rs232", argv[i]+5, 5) == 0) {
897 port = 0;
898 ioctl (fd, SERIAL_SETPORT, &port);
899 } else if (strncasecmp ("v35", argv[i]+5, 3) == 0) {
900 port = 1;
901 ioctl (fd, SERIAL_SETPORT, &port);
902 } else if (strncasecmp ("rs449", argv[i]+5, 5) == 0) {
903 port = 2;
904 ioctl (fd, SERIAL_SETPORT, &port);
905 } else {
906 fprintf (stderr, "invalid port type\n");
907 exit (-1);
908 }
909 #if 1
910 } else if (strcasecmp ("reset", argv[i]) == 0) {
911 ioctl (fd, SERIAL_RESET, 0);
912 } else if (strcasecmp ("hwreset", argv[i]) == 0) {
913 ioctl (fd, SERIAL_HARDRESET, 0);
914 #endif
915 } else if (strncasecmp ("cablen=", argv[i], 7) == 0) {
916 loop = (strcasecmp ("on", argv[i] + 7) == 0);
917 ioctl (fd, SERIAL_SETCABLEN, &cablen);
918 }
919 }
920 }
921
922 static void
get_mask(void)923 get_mask (void)
924 {
925 #ifdef __linux__
926 int fd;
927
928 fd = open ("/dev/serial/ctl0", 0);
929 if (fd < 0) {
930 perror ("/dev/serial/ctl0");
931 exit (-1);
932 }
933 if (ioctl (fd, SERIAL_GETREGISTERED, &mask) < 0) {
934 perror ("getting list of channels");
935 exit (-1);
936 }
937 close (fd);
938 #else
939 int fd, fd1, fd2, fd3, i;
940 char buf [80];
941
942 for (i=0, fd=-1; i<12 && fd<0; i++) {
943 sprintf (buf, "/dev/cx%d", i*4);
944 fd = open (buf, 0);
945 }
946
947 for (i=0, fd1=-1; i<3 && fd1<0; i++) {
948 sprintf (buf, "/dev/ct%d", i*2);
949 fd1 = open (buf, 0);
950 }
951
952 for (i=0, fd2=-1; i<3 && fd2<0; i++) {
953 sprintf (buf, "/dev/cp%d", i*4);
954 fd2 = open (buf, 0);
955 }
956
957 /* Try only one */
958 for (i=0, fd3=-1; i<1 && fd3<0; i++) {
959 sprintf (buf, "/dev/ce%d", i*4);
960 fd3 = open (buf, 0);
961 }
962
963 if ((fd < 0) && (fd1 < 0) && (fd2 < 0) && (fd3 < 0)) {
964 fprintf (stderr, "No Cronyx adapters installed\n");
965 exit (-1);
966 }
967
968 if (fd >= 0) {
969 if (ioctl (fd, SERIAL_GETREGISTERED, &mask) < 0) {
970 perror ("getting list of channels");
971 exit (-1);
972 }
973 close (fd);
974 }
975
976 if (fd1 >= 0) {
977 if (ioctl (fd1, SERIAL_GETREGISTERED, (mask+16)) < 0) {
978 perror ("getting list of channels");
979 exit (-1);
980 }
981 close (fd1);
982 }
983
984 if (fd2 >= 0) {
985 if (ioctl (fd2, SERIAL_GETREGISTERED, (mask+32)) < 0) {
986 perror ("getting list of channels");
987 exit (-1);
988 }
989 close (fd2);
990 }
991
992 if (fd3 >= 0) {
993 if (ioctl (fd3, SERIAL_GETREGISTERED, (mask+48)) < 0) {
994 perror ("getting list of channels");
995 exit (-1);
996 }
997 close (fd3);
998 }
999 #endif
1000 }
1001
1002 static int
open_chan_ctl(int num)1003 open_chan_ctl (int num)
1004 {
1005 char device [80];
1006 int fd;
1007
1008 #ifdef __linux__
1009 sprintf (device, "/dev/serial/ctl%d", num);
1010 #else
1011 switch (adapter_type) {
1012 case 0:
1013 sprintf (device, "/dev/cx%d", num);
1014 break;
1015 case 1:
1016 sprintf (device, "/dev/ct%d", num);
1017 break;
1018 case 2:
1019 sprintf (device, "/dev/cp%d", num);
1020 break;
1021 case 3:
1022 sprintf (device, "/dev/ce%d", num);
1023 break;
1024 }
1025 #endif
1026 fd = open (device, 0);
1027 if (fd < 0) {
1028 if (errno == ENODEV)
1029 fprintf (stderr, "chan%d: not configured\n", num);
1030 else
1031 perror (device);
1032 exit (-1);
1033 }
1034 #ifdef __linux__
1035 if (ioctl (fd, SERIAL_GETNAME, &chan_name) < 0)
1036 sprintf (chan_name, "chan%d", num);
1037 #else
1038 switch (adapter_type) {
1039 case 0: sprintf (chan_name, "cx%d", num); break;
1040 case 1: sprintf (chan_name, "ct%d", num); break;
1041 case 2: sprintf (chan_name, "cp%d", num); break;
1042 case 3: sprintf (chan_name, "ce%d", num); break;
1043 }
1044 #endif
1045 return fd;
1046 }
1047
1048 int
main(int argc,char ** argv)1049 main (int argc, char **argv)
1050 {
1051 char *p;
1052 int fd, need_header, chan_num;
1053
1054 if (argc > 1 && strcmp(argv[1], "help") == 0)
1055 usage();
1056
1057 for (;;) {
1058 switch (getopt (argc, argv, "mseftucviax")) {
1059 case -1:
1060 break;
1061 case 'a':
1062 ++aflag;
1063 continue;
1064 case 'm':
1065 ++mflag;
1066 continue;
1067 case 's':
1068 ++sflag;
1069 continue;
1070 case 'e':
1071 ++eflag;
1072 continue;
1073 case 'f':
1074 ++eflag;
1075 ++fflag;
1076 continue;
1077 case 't':
1078 ++tflag;
1079 continue;
1080 case 'u':
1081 ++tflag;
1082 ++uflag;
1083 continue;
1084 case 'c':
1085 ++cflag;
1086 continue;
1087 case 'v':
1088 ++vflag;
1089 continue;
1090 case 'i':
1091 ++iflag;
1092 continue;
1093 case 'x':
1094 ++xflag;
1095 continue;
1096 default:
1097 usage();
1098 }
1099 break;
1100 }
1101 argc -= optind;
1102 argv += optind;
1103
1104 if (argc <= 0) {
1105 get_mask ();
1106 need_header = 1;
1107 adapter_type = 0;
1108 #ifndef __linux__
1109 for (; adapter_type < 4; ++adapter_type)
1110 #endif
1111 {
1112 for (chan_num=0; chan_num<MAXCHAN; ++chan_num)
1113 if (mask[adapter_type*16+chan_num/8] & 1 << (chan_num & 7)) {
1114 fd = open_chan_ctl (chan_num);
1115 if (vflag) {
1116 #ifdef __linux__
1117 char buf[256];
1118 if (ioctl (fd, SERIAL_GETVERSIONSTRING, &buf) >= 0) {
1119 printf ("Version: %s\n", buf);
1120 close (fd);
1121 return (0);
1122 }
1123 #endif
1124 }
1125 if (iflag) {
1126 print_chan (fd);
1127 print_ifconfig (fd);
1128 } else if (sflag||xflag)
1129 print_stats (fd, need_header);
1130 else if (mflag)
1131 print_modems (fd, need_header);
1132 else if (eflag)
1133 print_e1_stats (fd, need_header);
1134 else if (tflag)
1135 print_e3_stats (fd, need_header);
1136 else if (cflag)
1137 clear_stats (fd);
1138 else
1139 print_chan (fd);
1140 close (fd);
1141 need_header = 0;
1142 }
1143 }
1144 return (0);
1145 }
1146
1147 p = argv[0] + strlen (argv[0]);
1148 while (p > argv[0] && p[-1] >= '0' && p[-1] <= '9')
1149 --p;
1150 chan_num = strtol (p, 0, 10);
1151 #ifndef __linux__
1152 if (strncasecmp ("cx", argv[0], 2)==0)
1153 adapter_type = 0;
1154 else if (strncasecmp ("ct", argv[0], 2)==0)
1155 adapter_type = 1;
1156 else if (strncasecmp ("cp", argv[0], 2)==0)
1157 adapter_type = 2;
1158 else if (strncasecmp ("ce", argv[0], 2)==0)
1159 adapter_type = 3;
1160 else {
1161 fprintf (stderr, "Wrong channel name\n");
1162 exit (-1);
1163 }
1164 #endif
1165 argc--;
1166 argv++;
1167
1168 fd = open_chan_ctl (chan_num);
1169 if (vflag) {
1170 #ifdef __linux__
1171 char buf[256];
1172 if (ioctl (fd, SERIAL_GETVERSIONSTRING, &buf) >= 0)
1173 printf ("Version: %s\n", buf);
1174 #endif
1175 }
1176 if (iflag) {
1177 print_chan (fd);
1178 print_ifconfig (fd);
1179 close (fd);
1180 return (0);
1181 }
1182 if (sflag||xflag) {
1183 print_stats (fd, 1);
1184 close (fd);
1185 return (0);
1186 }
1187 if (mflag) {
1188 print_modems (fd, 1);
1189 close (fd);
1190 return (0);
1191 }
1192 if (eflag) {
1193 print_e1_stats (fd, 1);
1194 close (fd);
1195 return (0);
1196 }
1197 if (tflag) {
1198 print_e3_stats (fd, 1);
1199 close (fd);
1200 return (0);
1201 }
1202 if (cflag) {
1203 clear_stats (fd);
1204 close (fd);
1205 return (0);
1206 }
1207 if (argc > 0)
1208 setup_chan (fd, argc, argv);
1209 else
1210 print_chan (fd);
1211 close (fd);
1212 return (0);
1213 }
1214