Initial import from FreeBSD RELENG_4:
[dragonfly.git] / sbin / i386 / cxconfig / cxconfig.c
1 /*
2  * Cronyx-Sigma adapter configuration utility for Unix.
3  *
4  * Copyright (C) 1994 Cronyx Ltd.
5  * Author: Serge Vakulenko, <vak@zebub.msk.su>
6  *
7  * This software is distributed with NO WARRANTIES, not even the implied
8  * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9  *
10  * Authors grant any other persons or organisations permission to use
11  * or modify this software as long as this message is kept with the software,
12  * all derivative works or modified versions.
13  *
14  * Version 1.9, Wed Oct  4 18:58:15 MSK 1995
15  *
16  * Usage:
17  *      cxconfig [-a]
18  *              -- print status of all channels
19  *      cxconfig [-a] <channel>
20  *              -- print status of the channel
21  *      cxconfig <channel> <option>...
22  *              -- set channel options
23  */
24
25 #ifndef lint
26 static const char rcsid[] =
27   "$FreeBSD: src/sbin/i386/cxconfig/cxconfig.c,v 1.4 1999/08/28 00:13:00 peter Exp $";
28 #endif /* not lint */
29
30 #include <err.h>
31 #include <fcntl.h>
32 #include <sys/types.h>
33 #include <sys/socket.h>
34 #include <sys/ioctl.h>
35 #include <machine/cronyx.h>
36 #include <net/if.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <unistd.h>
41
42 #define NBRD    3
43 #define CXDEV   "/dev/cronyx"
44 #define atoi(a) strtol((a), (char**)0, 0)
45
46 cx_options_t o;
47 cx_stat_t st;
48 int aflag;
49 int sflag;
50
51 char *symbol (unsigned char sym)
52 {
53         static char buf[40];
54
55         if (sym < ' ')
56                 sprintf (buf, "^%c", sym+0100);
57         else if (sym == '\\')
58                 strcat (buf, "\\\\");
59         else if (sym < 127)
60                 sprintf (buf, "%c", sym);
61         else
62                 sprintf (buf, "\\%03o", sym);
63         return (buf);
64 }
65
66 unsigned char atosym (char *s)
67 {
68         if (*s == '^')
69                 return (*++s & 037);
70         if (*s == '\\')
71                 return (strtol (++s, 0, 8));
72         return (*s);
73 }
74
75 void usage ()
76 {
77         fprintf (stderr,
78                 "Cronyx-Sigma Adapter Configuration Utility, Version 1.0\n");
79         fprintf (stderr, "Copyright (C) 1994 Cronyx Ltd.\n");
80         fprintf (stderr, "usage: cxconfig [-a] [<channel> [<option>...]]\n");
81         exit (1);
82 }
83
84 char *chantype (int type)
85 {
86         switch (type) {
87         case T_NONE:       return ("none");
88         case T_ASYNC:      return ("RS-232");
89         case T_UNIV_RS232: return ("RS-232");
90         case T_UNIV_RS449: return ("RS-232/RS-449");
91         case T_UNIV_V35:   return ("RS-232/V.35");
92         case T_SYNC_RS232: return ("RS-232");
93         case T_SYNC_V35:   return ("V.35");
94         case T_SYNC_RS449: return ("RS-449");
95         }
96 }
97
98 char *chanmode (int mode)
99 {
100         switch (mode) {
101         case M_ASYNC:   return ("Async");
102         case M_HDLC:    return ("HDLC");
103         case M_BISYNC:  return ("Bisync");
104         case M_X21:     return ("X.21");
105         default:        return ("???");
106         }
107 }
108
109 void getchan (int channel)
110 {
111         int s = open (CXDEV, 0);
112         if (s < 0)
113                 err (1, "%s", CXDEV);
114         o.board = channel/NCHAN;
115         o.channel = channel%NCHAN;
116         if (ioctl (s, CXIOCGETMODE, (caddr_t)&o) < 0)
117                 err (1, "CXIOCGETMODE");
118         close (s);
119         if (o.type == T_NONE)
120                 errx (1, "cx%d: channel %d not configured", o.board,
121                         o.channel);
122 }
123
124 int printstats (int channel, int hflag)
125 {
126         int s, res;
127
128         s = open (CXDEV, 0);
129         if (s < 0)
130                 err (1, "%s", CXDEV);
131         st.board = channel/NCHAN;
132         st.channel = channel%NCHAN;
133         res = ioctl (s, CXIOCGETSTAT, (caddr_t)&st);
134         close (s);
135         if (res < 0)
136                 return (-1);
137
138         if (hflag)
139                 printf ("Chan   Rintr   Tintr   Mintr   Ibytes   Ipkts   Ierrs   Obytes   Opkts   Oerrs\n");
140         printf ("cx%-2d %7ld %7ld %7ld %8ld %7ld %7ld %8ld %7ld %7ld\n",
141                 channel, st.rintr, st.tintr, st.mintr, st.ibytes, st.ipkts,
142                 st.ierrs, st.obytes, st.opkts, st.oerrs);
143         return (0);
144 }
145
146 void printallstats ()
147 {
148         int b, c;
149
150         printf ("Chan   Rintr   Tintr   Mintr   Ibytes   Ipkts   Ierrs   Obytes   Opkts   Oerrs\n");
151         for (b=0; b<NBRD; ++b)
152                 for (c=0; c<NCHAN; ++c)
153                         printstats (b*NCHAN + c, 0);
154 }
155
156 void setchan (int channel)
157 {
158         int s = open (CXDEV, 0);
159         if (s < 0)
160                 err (1, "%s", CXDEV);
161         o.board = channel/NCHAN;
162         o.channel = channel%NCHAN;
163         if (ioctl (s, CXIOCSETMODE, (caddr_t)&o) < 0)
164                 err (1, "CXIOCSETMODE");
165         close (s);
166 }
167
168 void printopt ()
169 {
170         /* Common channel options */
171         /* channel option register 4 */
172         printf ("\t");
173         printf ("fifo=%d ", o.opt.cor4.thr);    /* FIFO threshold */
174         printf ("%cctsdown ", o.opt.cor4.cts_zd ? '+' : '-');   /* detect 1 to 0 transition on the CTS */
175         printf ("%ccddown ", o.opt.cor4.cd_zd ? '+' : '-');     /* detect 1 to 0 transition on the CD */
176         printf ("%cdsrdown ", o.opt.cor4.dsr_zd ? '+' : '-');   /* detect 1 to 0 transition on the DSR */
177         printf ("\n");
178
179         /* channel option register 5 */
180         printf ("\t");
181         printf ("rfifo=%d ", o.opt.cor5.rx_thr);        /* receive flow control FIFO threshold */
182         printf ("%cctsup ", o.opt.cor5.cts_od ? '+' : '-');     /* detect 0 to 1 transition on the CTS */
183         printf ("%ccdup ", o.opt.cor5.cd_od ? '+' : '-');       /* detect 0 to 1 transition on the CD */
184         printf ("%cdsrup ", o.opt.cor5.dsr_od ? '+' : '-');     /* detect 0 to 1 transition on the DSR */
185         printf ("\n");
186
187         /* receive clock option register */
188         printf ("\t");
189         printf ("%s ", o.opt.rcor.encod == ENCOD_NRZ ? "nrz" :  /* signal encoding */
190                 o.opt.rcor.encod == ENCOD_NRZI ? "nrzi" :
191                 o.opt.rcor.encod == ENCOD_MANCHESTER ? "manchester" : "???");
192         printf ("%cdpll ", o.opt.rcor.dpll ? '+' : '-');        /* DPLL enable */
193
194         /* transmit clock option register */
195         printf ("%clloop ", o.opt.tcor.llm ? '+' : '-');        /* local loopback mode */
196         printf ("%cextclock ", o.opt.tcor.ext1x ? '+' : '-');   /* external 1x clock mode */
197         printf ("\n");
198
199         switch (o.mode) {
200         case M_ASYNC:                           /* async mode options */
201                 /* channel option register 1 */
202                 printf ("\t");
203                 printf ("cs%d ", o.aopt.cor1.charlen+1);        /* character length, 5..8 */
204                 printf ("par%s ", o.aopt.cor1.parity ? "odd" : "even"); /* parity */
205                 printf ("%cignpar ", o.aopt.cor1.ignpar ? '+' : '-');   /* ignore parity */
206                 if (o.aopt.cor1.parmode != PARM_NORMAL)                 /* parity mode */
207                         printf ("%s ", o.aopt.cor1.parmode == PARM_NOPAR ? "nopar" :
208                                 o.aopt.cor1.parmode == PARM_FORCE ? "forcepar" : "???");
209                 printf ("\n");
210
211                 /* channel option register 2 */
212                 printf ("\t");
213                 printf ("%cdsr ", o.aopt.cor2.dsrae ? '+' : '-');  /* DSR automatic enable */
214                 printf ("%ccts ", o.aopt.cor2.ctsae ? '+' : '-');  /* CTS automatic enable */
215                 printf ("%crts ", o.aopt.cor2.rtsao ? '+' : '-');  /* RTS automatic output enable */
216                 printf ("%crloop ", o.aopt.cor2.rlm ? '+' : '-');  /* remote loopback mode enable */
217                 printf ("%cetc ", o.aopt.cor2.etc ? '+' : '-');    /* embedded transmitter cmd enable */
218                 printf ("%cxon ", o.aopt.cor2.ixon ? '+' : '-');   /* in-band XON/XOFF enable */
219                 printf ("%cxany ", o.aopt.cor2.ixany ? '+' : '-'); /* XON on any character */
220                 printf ("\n");
221
222                 /* option register 3 */
223                 printf ("\t");
224                 printf ("%s ", o.aopt.cor3.stopb == STOPB_1 ? "stopb1" : /* stop bit length */
225                         o.aopt.cor3.stopb == STOPB_15 ? "stopb1.5" :
226                         o.aopt.cor3.stopb == STOPB_2 ? "stopb2" : "???");
227                 printf ("%csdt ", o.aopt.cor3.scde ? '+' : '-');        /* special char detection enable */
228                 printf ("%cflowct ", o.aopt.cor3.flowct ? '+' : '-');   /* flow control transparency mode */
229                 printf ("%crdt ", o.aopt.cor3.rngde ? '+' : '-');       /* range detect enable */
230                 printf ("%cexdt ", o.aopt.cor3.escde ? '+' : '-');      /* extended spec. char detect enable */
231                 printf ("\n");
232
233                 /* channel option register 6 */
234                 printf ("\t");
235                 printf ("%s ", o.aopt.cor6.parerr == PERR_INTR ? "parintr" : /* parity/framing error actions */
236                         o.aopt.cor6.parerr == PERR_NULL ? "parnull" :
237                         o.aopt.cor6.parerr == PERR_IGNORE ? "parign" :
238                         o.aopt.cor6.parerr == PERR_DISCARD ? "pardisc" :
239                         o.aopt.cor6.parerr == PERR_FFNULL ? "parffnull" : "???");
240                 printf ("%s ", o.aopt.cor6.brk == BRK_INTR ? "brkintr" : /* action on break condition */
241                         o.aopt.cor6.brk == BRK_NULL ? "brknull" :
242                         o.aopt.cor6.brk == BRK_DISCARD ? "brkdisc" : "???");
243                 printf ("%cinlcr ", o.aopt.cor6.inlcr ? '+' : '-');     /* translate NL to CR on input */
244                 printf ("%cicrnl ", o.aopt.cor6.icrnl ? '+' : '-');     /* translate CR to NL on input */
245                 printf ("%cigncr ", o.aopt.cor6.igncr ? '+' : '-');     /* discard CR on input */
246                 printf ("\n");
247
248                 /* channel option register 7 */
249                 printf ("\t");
250                 printf ("%cocrnl ", o.aopt.cor7.ocrnl ? '+' : '-');     /* translate CR to NL on output */
251                 printf ("%conlcr ", o.aopt.cor7.onlcr ? '+' : '-');     /* translate NL to CR on output */
252                 printf ("%cfcerr ", o.aopt.cor7.fcerr ? '+' : '-');     /* process flow ctl err chars enable */
253                 printf ("%clnext ", o.aopt.cor7.lnext ? '+' : '-');     /* LNext option enable */
254                 printf ("%cistrip ", o.aopt.cor7.istrip ? '+' : '-');   /* strip 8-bit on input */
255                 printf ("\n");
256
257                 printf ("\t");
258                 printf ("schr1=%s ", symbol (o.aopt.schr1));    /* special character register 1 (XON) */
259                 printf ("schr2=%s ", symbol (o.aopt.schr2));    /* special character register 2 (XOFF) */
260                 printf ("schr3=%s ", symbol (o.aopt.schr3));    /* special character register 3 */
261                 printf ("schr4=%s ", symbol (o.aopt.schr4));    /* special character register 4 */
262                 printf ("scrl=%s ", symbol (o.aopt.scrl));      /* special character range low */
263                 printf ("scrh=%s ", symbol (o.aopt.scrh));      /* special character range high */
264                 printf ("lnext=%s ", symbol (o.aopt.lnxt));     /* LNext character */
265                 printf ("\n");
266                 break;
267
268         case M_HDLC:                    /* hdlc mode options */
269                 /* hdlc channel option register 1 */
270                 printf ("\t");
271                 printf ("if%d ", o.hopt.cor1.ifflags);  /* number of inter-frame flags sent */
272                 printf ("%s ", o.hopt.cor1.admode == ADMODE_NOADDR ? "noaddr" : /* addressing mode */
273                         o.hopt.cor1.admode == ADMODE_4_1 ? "addr1" :
274                         o.hopt.cor1.admode == ADMODE_2_2 ? "addr2" : "???");
275                 printf ("%cclrdet ", o.hopt.cor1.clrdet ? '+' : '-'); /* clear detect for X.21 data transfer phase */
276                 printf ("addrlen%d ", o.hopt.cor1.aflo + 1);    /* address field length option */
277                 printf ("\n");
278
279                 /* hdlc channel option register 2 */
280                 printf ("\t");
281                 printf ("%cdsr ", o.hopt.cor2.dsrae ? '+' : '-'); /* DSR automatic enable */
282                 printf ("%ccts ", o.hopt.cor2.ctsae ? '+' : '-'); /* CTS automatic enable */
283                 printf ("%crts ", o.hopt.cor2.rtsao ? '+' : '-'); /* RTS automatic output enable */
284                 printf ("%ccrcinv ", o.hopt.cor2.crcninv ? '-' : '+');  /* CRC invertion option */
285                 printf ("%cfcsapd ", o.hopt.cor2.fcsapd ? '+' : '-');   /* FCS append */
286                 printf ("\n");
287
288                 /* hdlc channel option register 3 */
289                 printf ("\t");
290                 printf ("pad%d ", o.hopt.cor3.padcnt);  /* pad character count */
291                 printf ("idle%s ", o.hopt.cor3.idle ? "mark" : "flag"); /* idle mode */
292                 printf ("%cfcs ", o.hopt.cor3.nofcs ? '-' : '+');       /* FCS disable */
293                 printf ("fcs-%s ", o.hopt.cor3.fcspre ? "crc-16" : "v.41"); /* FCS preset */
294                 printf ("syn=%s ", o.hopt.cor3.syncpat ? "0xAA" : "0x00"); /* send sync pattern */
295                 printf ("%csyn ", o.hopt.cor3.sndpad ? '+' : '-');     /* send pad characters before flag enable */
296                 printf ("\n");
297
298                 printf ("\t");
299                 printf ("rfar1=0x%02x ", o.hopt.rfar1); /* receive frame address register 1 */
300                 printf ("rfar2=0x%02x ", o.hopt.rfar2); /* receive frame address register 2 */
301                 printf ("rfar3=0x%02x ", o.hopt.rfar3); /* receive frame address register 3 */
302                 printf ("rfar4=0x%02x ", o.hopt.rfar4); /* receive frame address register 4 */
303                 printf ("crc-%s ", o.hopt.cpsr ? "16" : "v.41"); /* CRC polynomial select */
304                 printf ("\n");
305                 break;
306
307         case M_BISYNC:                  /* bisync mode options */
308                 /* channel option register 1 */
309                 printf ("\t");
310                 printf ("cs%d ", o.bopt.cor1.charlen+1);        /* character length, 5..8 */
311                 printf ("par%s ", o.bopt.cor1.parity ? "odd" : "even"); /* parity */
312                 printf ("%cignpar ", o.bopt.cor1.ignpar ? '+' : '-');   /* ignore parity */
313                 if (o.bopt.cor1.parmode != PARM_NORMAL)                 /* parity mode */
314                         printf ("%s ", o.bopt.cor1.parmode == PARM_NOPAR ? "nopar" :
315                                 o.bopt.cor1.parmode == PARM_FORCE ? "forcepar" : "???");
316                 printf ("\n");
317
318                 /* channel option register 2 */
319                 printf ("\t");
320                 printf ("syn%d ", o.bopt.cor2.syns+2);                  /* number of extra SYN chars before a frame */
321                 printf ("%ccrcinv ", o.bopt.cor2.crcninv ? '-' : '+');  /* CRC invertion option */
322                 printf ("%s ", o.bopt.cor2.ebcdic ? "ebcdic" : "ascii"); /* use EBCDIC as char set (instead of ASCII) */
323                 printf ("%cbccapd ", o.bopt.cor2.bcc ? '+' : '-');      /* BCC append enable */
324                 printf ("%s ", o.bopt.cor2.lrc ? "lrc" : "crc-16");     /* longitudinal redundancy check */
325                 printf ("\n");
326
327                 /* channel option register 3 */
328                 printf ("\t");
329                 printf ("pad%d ", o.bopt.cor3.padcnt);  /* pad character count */
330                 printf ("idle%s ", o.bopt.cor3.idle ? "mark" : "syn"); /* idle mode */
331                 printf ("%cfcs ", o.bopt.cor3.nofcs ? '-' : '+');       /* FCS disable */
332                 printf ("fcs-%s ", o.bopt.cor3.fcspre ? "crc-16" : "v.41"); /* FCS preset */
333                 printf ("syn=%s ", o.bopt.cor3.padpat ? "0x55" : "0xAA"); /* send sync pattern */
334                 printf ("%csyn ", o.bopt.cor3.sndpad ? '+' : '-');     /* send pad characters before flag enable */
335                 printf ("\n");
336
337                 /* channel option register 6 */
338                 printf ("\t");
339                 printf ("specterm=%s ", symbol (o.bopt.cor6.specterm)); /* special termination character */
340
341                 printf ("crc-%s ", o.bopt.cpsr ? "16" : "v.41"); /* CRC polynomial select */
342                 printf ("\n");
343                 break;
344
345         case M_X21:                     /* x.21 mode options */
346                 /* channel option register 1 */
347                 printf ("\t");
348                 printf ("cs%d ", o.xopt.cor1.charlen+1);        /* character length, 5..8 */
349                 printf ("par%s ", o.xopt.cor1.parity ? "odd" : "even"); /* parity */
350                 printf ("%cignpar ", o.xopt.cor1.ignpar ? '+' : '-');   /* ignore parity */
351                 if (o.xopt.cor1.parmode != PARM_NORMAL)                 /* parity mode */
352                         printf ("%s ", o.xopt.cor1.parmode == PARM_NOPAR ? "nopar" :
353                                 o.xopt.cor1.parmode == PARM_FORCE ? "forcepar" : "???");
354                 printf ("\n");
355
356                 /* channel option register 2 */
357                 printf ("\t");
358                 printf ("%cetc ", o.xopt.cor2.etc ? '+' : '-'); /* embedded transmitter cmd enable */
359
360                 /* channel option register 3 */
361                 printf ("%csdt ", o.xopt.cor3.scde ? '+' : '-'); /* special char detection enable */
362                 printf ("%cstripsyn ", o.xopt.cor3.stripsyn ? '+' : '-'); /* treat SYN chars as special condition */
363                 printf ("%cssdt ", o.xopt.cor3.ssde ? '+' : '-'); /* steady state detect enable */
364                 printf ("syn%c ", o.xopt.cor3.syn ? '1' : '2'); /* the number of SYN chars on receive */
365                 printf ("\n");
366
367                 /* channel option register 6 */
368                 printf ("\t");
369                 printf ("syn=%s ", symbol (o.xopt.cor6.synchar)); /* syn character */
370
371                 printf ("schr1=%s ", symbol (o.xopt.schr1));    /* special character register 1 */
372                 printf ("schr2=%s ", symbol (o.xopt.schr2));    /* special character register 2 */
373                 printf ("schr3=%s ", symbol (o.xopt.schr3));    /* special character register 3 */
374                 printf ("\n");
375                 break;
376         }
377 }
378
379 void printchan (int channel)
380 {
381         printf ("cx%d (%s) %s", channel, chantype (o.type), chanmode (o.mode));
382         if (o.txbaud == o.rxbaud)
383                 printf (" %d", o.rxbaud);
384         else
385                 printf (" ospeed=%d ispeed=%d", o.txbaud, o.rxbaud);
386         if ((o.channel == 0 || o.channel == 8) &&
387             (o.type == T_UNIV_V35 || o.type == T_UNIV_RS449))
388                 printf (" port=%s", o.iftype ? (o.type == T_UNIV_V35 ?
389                         "v35" : "rs449") : "rs232");
390         printf (o.sopt.ext ? " ext" : o.sopt.cisco ? " cisco" : " ppp");
391         printf (" %ckeepalive", o.sopt.keepalive ? '+' : '-');
392         printf (" %cautorts", o.sopt.norts ? '-' : '+');
393         if (*o.master)
394                 printf (" master=%s", o.master);
395         printf ("\n");
396         if (aflag)
397                 printopt ();
398 }
399
400 void printall ()
401 {
402         struct ifconf ifc;
403         struct ifreq *ifr;
404         char buf[BUFSIZ], *cp;
405         int s, c;
406
407         s = socket (AF_INET, SOCK_DGRAM, 0);
408         if (s < 0)
409                 err (1, "socket");
410         ifc.ifc_len = sizeof (buf);
411         ifc.ifc_buf = buf;
412         if (ioctl (s, SIOCGIFCONF, (caddr_t)&ifc) < 0)
413                 err (1, "SIOCGIFCONF");
414         close (s);
415         s = open (CXDEV, 0);
416         if (s < 0)
417                 err (1, "%s", CXDEV);
418
419         ifr = ifc.ifc_req;
420 #define max(a,b) ((a)>(b) ? (a) : (b))
421 #define size(p) max((p).sa_len, sizeof(p))
422         for (cp=buf; cp<buf+ifc.ifc_len; cp+=sizeof(ifr->ifr_name)+size(ifr->ifr_addr)) {
423                 ifr = (struct ifreq*) cp;
424                 if (ifr->ifr_addr.sa_family != AF_LINK)
425                         continue;
426                 if (strncmp (ifr->ifr_name, "cx", 2) != 0)
427                         continue;
428                 c = atoi (ifr->ifr_name + 2);
429                 o.board = c/NCHAN;
430                 o.channel = c%NCHAN;
431                 if (ioctl (s, CXIOCGETMODE, (caddr_t)&o) < 0)
432                         err (1, "CXIOCGETMODE");
433                 printchan (c);
434         }
435         close (s);
436 }
437
438 void set_interface_type (char *type)
439 {
440         if (o.channel != 0 && o.channel != 8) {
441                 printf ("interface option is applicable only for channels 0 and 8\n");
442                 exit (1);
443         }
444         if (o.type != T_UNIV_V35 && o.type != T_UNIV_RS449) {
445                 printf ("interface option is applicable only for universal channels\n");
446                 exit (1);
447         }
448         if (! strcasecmp (type, "port=rs232"))
449                 o.iftype = 0;
450         else
451                 o.iftype = 1;
452 }
453
454 void set_master (char *ifname)
455 {
456         if (o.type == T_ASYNC) {
457                 printf ("master option is not applicable for async channels\n");
458                 exit (1);
459         }
460         strcpy (o.master, ifname);
461 }
462
463 void set_async_opt (char *opt)
464 {
465         /* channel option register 1 */
466         if (! strncasecmp (opt, "cs", 2))        o.aopt.cor1.charlen = atoi (opt + 2) - 1;
467         else if (! strcasecmp (opt, "parodd"))   o.aopt.cor1.parity = 1;
468         else if (! strcasecmp (opt, "pareven"))  o.aopt.cor1.parity = 0;
469         else if (! strcasecmp (opt, "-ignpar"))  o.aopt.cor1.ignpar = 0;
470         else if (! strcasecmp (opt, "+ignpar"))  o.aopt.cor1.ignpar = 1;
471         else if (! strcasecmp (opt, "nopar"))    o.aopt.cor1.parmode = PARM_NOPAR;
472         else if (! strcasecmp (opt, "forcepar")) o.aopt.cor1.parmode = PARM_FORCE;
473
474         /* channel option register 2 */
475         else if (! strcasecmp (opt, "-dsr"))   o.aopt.cor2.dsrae = 0;
476         else if (! strcasecmp (opt, "+dsr"))   o.aopt.cor2.dsrae = 1;
477         else if (! strcasecmp (opt, "-cts"))   o.aopt.cor2.ctsae = 0;
478         else if (! strcasecmp (opt, "+cts"))   o.aopt.cor2.ctsae = 1;
479         else if (! strcasecmp (opt, "-rts"))   o.aopt.cor2.rtsao = 0;
480         else if (! strcasecmp (opt, "+rts"))   o.aopt.cor2.rtsao = 1;
481         else if (! strcasecmp (opt, "-rloop")) o.aopt.cor2.rlm = 0;
482         else if (! strcasecmp (opt, "+rloop")) o.aopt.cor2.rlm = 1;
483         else if (! strcasecmp (opt, "-etc"))   o.aopt.cor2.etc = 0;
484         else if (! strcasecmp (opt, "+etc"))   o.aopt.cor2.etc = 1;
485         else if (! strcasecmp (opt, "-ixon"))  o.aopt.cor2.ixon = 0;
486         else if (! strcasecmp (opt, "+ixon"))  o.aopt.cor2.ixon = 1;
487         else if (! strcasecmp (opt, "-ixany")) o.aopt.cor2.ixany = 0;
488         else if (! strcasecmp (opt, "+ixany")) o.aopt.cor2.ixany = 1;
489
490         /* option register 3 */
491         else if (! strcasecmp (opt, "stopb1"))   o.aopt.cor3.stopb = STOPB_1;
492         else if (! strcasecmp (opt, "stopb1.5")) o.aopt.cor3.stopb = STOPB_15;
493         else if (! strcasecmp (opt, "stopb2"))   o.aopt.cor3.stopb = STOPB_2;
494         else if (! strcasecmp (opt, "-sdt"))     o.aopt.cor3.scde = 0;
495         else if (! strcasecmp (opt, "+sdt"))     o.aopt.cor3.scde = 1;
496         else if (! strcasecmp (opt, "-flowct"))  o.aopt.cor3.flowct = 0;
497         else if (! strcasecmp (opt, "+flowct"))  o.aopt.cor3.flowct = 1;
498         else if (! strcasecmp (opt, "-rdt"))     o.aopt.cor3.rngde = 0;
499         else if (! strcasecmp (opt, "+rdt"))     o.aopt.cor3.rngde = 1;
500         else if (! strcasecmp (opt, "-exdt"))    o.aopt.cor3.escde = 0;
501         else if (! strcasecmp (opt, "+exdt"))    o.aopt.cor3.escde = 1;
502
503         /* channel option register 6 */
504         else if (! strcasecmp (opt, "parintr"))   o.aopt.cor6.parerr = PERR_INTR;
505         else if (! strcasecmp (opt, "parnull"))   o.aopt.cor6.parerr = PERR_NULL;
506         else if (! strcasecmp (opt, "parign"))    o.aopt.cor6.parerr = PERR_IGNORE;
507         else if (! strcasecmp (opt, "pardisc"))   o.aopt.cor6.parerr = PERR_DISCARD;
508         else if (! strcasecmp (opt, "parffnull")) o.aopt.cor6.parerr = PERR_FFNULL;
509         else if (! strcasecmp (opt, "brkintr"))   o.aopt.cor6.brk = BRK_INTR;
510         else if (! strcasecmp (opt, "brknull"))   o.aopt.cor6.brk = BRK_NULL;
511         else if (! strcasecmp (opt, "brkdisc"))   o.aopt.cor6.brk = BRK_DISCARD;
512         else if (! strcasecmp (opt, "-inlcr"))    o.aopt.cor6.inlcr = 0;
513         else if (! strcasecmp (opt, "+inlcr"))    o.aopt.cor6.inlcr = 1;
514         else if (! strcasecmp (opt, "-icrnl"))    o.aopt.cor6.icrnl = 0;
515         else if (! strcasecmp (opt, "+icrnl"))    o.aopt.cor6.icrnl = 1;
516         else if (! strcasecmp (opt, "-igncr"))    o.aopt.cor6.igncr = 0;
517         else if (! strcasecmp (opt, "+igncr"))    o.aopt.cor6.igncr = 1;
518
519         /* channel option register 7 */
520         else if (! strcasecmp (opt, "-ocrnl"))    o.aopt.cor7.ocrnl = 0;
521         else if (! strcasecmp (opt, "+ocrnl"))    o.aopt.cor7.ocrnl = 1;
522         else if (! strcasecmp (opt, "-onlcr"))    o.aopt.cor7.onlcr = 0;
523         else if (! strcasecmp (opt, "+onlcr"))    o.aopt.cor7.onlcr = 1;
524         else if (! strcasecmp (opt, "-fcerr"))    o.aopt.cor7.fcerr = 0;
525         else if (! strcasecmp (opt, "+fcerr"))    o.aopt.cor7.fcerr = 1;
526         else if (! strcasecmp (opt, "-lnext"))    o.aopt.cor7.lnext = 0;
527         else if (! strcasecmp (opt, "+lnext"))    o.aopt.cor7.lnext = 1;
528         else if (! strcasecmp (opt, "-istrip"))   o.aopt.cor7.istrip = 0;
529         else if (! strcasecmp (opt, "+istrip"))   o.aopt.cor7.istrip = 1;
530
531         else if (! strncasecmp (opt, "schr1=", 6)) o.aopt.schr1 = atosym (opt+6);
532         else if (! strncasecmp (opt, "schr2=", 6)) o.aopt.schr2 = atosym (opt+6);
533         else if (! strncasecmp (opt, "schr3=", 6)) o.aopt.schr3 = atosym (opt+6);
534         else if (! strncasecmp (opt, "schr4=", 6)) o.aopt.schr4 = atosym (opt+6);
535         else if (! strncasecmp (opt, "scrl=", 5))  o.aopt.scrl = atosym (opt+5);
536         else if (! strncasecmp (opt, "scrh=", 5))  o.aopt.scrh = atosym (opt+5);
537         else if (! strncasecmp (opt, "lnext=", 6)) o.aopt.lnxt = atosym (opt+6);
538         else
539                 usage ();
540 }
541
542 void set_hdlc_opt (char *opt)
543 {
544         /* hdlc channel option register 1 */
545         if (! strncasecmp (opt, "if", 2))        o.hopt.cor1.ifflags = atoi (opt + 2);
546         else if (! strcasecmp (opt, "noaddr"))   o.hopt.cor1.admode = ADMODE_NOADDR;
547         else if (! strcasecmp (opt, "addr1"))    o.hopt.cor1.admode = ADMODE_4_1;
548         else if (! strcasecmp (opt, "addr2"))    o.hopt.cor1.admode = ADMODE_2_2;
549         else if (! strcasecmp (opt, "-clrdet"))  o.hopt.cor1.clrdet = 0;
550         else if (! strcasecmp (opt, "+clrdet"))  o.hopt.cor1.clrdet = 1;
551         else if (! strcasecmp (opt, "addrlen1")) o.hopt.cor1.aflo = 0;
552         else if (! strcasecmp (opt, "addrlen2")) o.hopt.cor1.aflo = 1;
553
554         /* hdlc channel option register 2 */
555         else if (! strcasecmp (opt, "-dsr"))    o.hopt.cor2.dsrae = 0;
556         else if (! strcasecmp (opt, "+dsr"))    o.hopt.cor2.dsrae = 1;
557         else if (! strcasecmp (opt, "-cts"))    o.hopt.cor2.ctsae = 0;
558         else if (! strcasecmp (opt, "+cts"))    o.hopt.cor2.ctsae = 1;
559         else if (! strcasecmp (opt, "-rts"))    o.hopt.cor2.rtsao = 0;
560         else if (! strcasecmp (opt, "+rts"))    o.hopt.cor2.rtsao = 1;
561         else if (! strcasecmp (opt, "-fcsapd")) o.hopt.cor2.fcsapd = 0;
562         else if (! strcasecmp (opt, "+fcsapd")) o.hopt.cor2.fcsapd = 1;
563         else if (! strcasecmp (opt, "-crcinv")) o.hopt.cor2.crcninv = 1;
564         else if (! strcasecmp (opt, "+crcinv")) o.hopt.cor2.crcninv = 0;
565
566         /* hdlc channel option register 3 */
567         else if (! strncasecmp (opt, "pad", 3))    o.hopt.cor3.padcnt = atoi (opt + 3);
568         else if (! strcasecmp (opt, "idlemark"))   o.hopt.cor3.idle = 1;
569         else if (! strcasecmp (opt, "idleflag"))   o.hopt.cor3.idle = 0;
570         else if (! strcasecmp (opt, "-fcs"))       o.hopt.cor3.nofcs = 1;
571         else if (! strcasecmp (opt, "+fcs"))       o.hopt.cor3.nofcs = 0;
572         else if (! strcasecmp (opt, "fcs-crc-16")) o.hopt.cor3.fcspre = 1;
573         else if (! strcasecmp (opt, "fcs-v.41"))   o.hopt.cor3.fcspre = 0;
574         else if (! strcasecmp (opt, "syn=0xaa"))   o.hopt.cor3.syncpat = 1;
575         else if (! strcasecmp (opt, "syn=0x00"))   o.hopt.cor3.syncpat = 0;
576         else if (! strcasecmp (opt, "-syn"))       o.hopt.cor3.sndpad = 0;
577         else if (! strcasecmp (opt, "+syn"))       o.hopt.cor3.sndpad = 1;
578
579         else if (! strncasecmp (opt, "rfar1=", 6)) o.hopt.rfar1 = atoi (opt + 6);
580         else if (! strncasecmp (opt, "rfar2=", 6)) o.hopt.rfar2 = atoi (opt + 6);
581         else if (! strncasecmp (opt, "rfar3=", 6)) o.hopt.rfar3 = atoi (opt + 6);
582         else if (! strncasecmp (opt, "rfar4=", 6)) o.hopt.rfar4 = atoi (opt + 6);
583         else if (! strcasecmp (opt, "crc-16"))     o.hopt.cpsr = 1;
584         else if (! strcasecmp (opt, "crc-v.41"))   o.hopt.cpsr = 0;
585         else usage ();
586 }
587
588 void set_bisync_opt (char *opt)
589 {
590         usage ();
591 }
592
593 void set_x21_opt (char *opt)
594 {
595         usage ();
596 }
597
598 int main (int argc, char **argv)
599 {
600         int channel;
601
602         for (--argc, ++argv; argc>0 && **argv=='-'; --argc, ++argv)
603                 if (! strcasecmp (*argv, "-a"))
604                         ++aflag;
605                 else if (! strcasecmp (*argv, "-s"))
606                         ++sflag;
607                 else
608                         usage ();
609
610         if (argc <= 0) {
611                 if (sflag)
612                         printallstats ();
613                 else
614                         printall ();
615                 return (0);
616         }
617
618         if (argv[0][0]=='c' && argv[0][1]=='x')
619                 *argv += 2;
620         if (**argv<'0' || **argv>'9')
621                 usage ();
622         channel = atoi (*argv);
623         --argc, ++argv;
624
625         if (sflag) {
626                 if (printstats (channel, 1) < 0)
627                         printf ("channel cx%d not available\n", channel);
628                 return (0);
629         }
630
631         getchan (channel);
632
633         if (argc <= 0) {
634                 printchan (channel);
635                 return (0);
636         }
637
638         for (; argc>0; --argc, ++argv)
639                 if (**argv == '(')
640                         continue;
641                 else if (! strncasecmp (*argv, "ispeed=", 7))
642                         o.rxbaud = atoi (*argv+7);
643                 else if (! strncasecmp (*argv, "ospeed=", 7))
644                         o.txbaud = atoi (*argv+7);
645                 else if (! strcasecmp (*argv, "async"))
646                         o.mode = M_ASYNC;
647                 else if (! strcasecmp (*argv, "hdlc"))
648                         o.mode = M_HDLC;
649                 else if (! strcasecmp (*argv, "bisync") ||
650                     ! strcasecmp (*argv, "bsc"))
651                         o.mode = M_BISYNC;
652                 else if (! strcasecmp (*argv, "x.21") ||
653                     ! strcasecmp (*argv, "x21"))
654                         o.mode = M_X21;
655                 else if (**argv>='0' && **argv<='9')
656                         o.txbaud = o.rxbaud = atoi (*argv);
657                 else if (! strcasecmp (*argv, "cisco")) {
658                         o.sopt.cisco = 1;
659                         o.sopt.ext = 0;
660                 } else if (! strcasecmp (*argv, "ppp")) {
661                         o.sopt.cisco = 0;
662                         o.sopt.ext = 0;
663                 } else if (! strcasecmp (*argv, "ext"))
664                         o.sopt.ext = 1;
665                 else if (! strcasecmp (*argv, "+keepalive"))
666                         o.sopt.keepalive = 1;
667                 else if (! strcasecmp (*argv, "-keepalive"))
668                         o.sopt.keepalive = 0;
669                 else if (! strcasecmp (*argv, "+autorts"))
670                         o.sopt.norts = 0;
671                 else if (! strcasecmp (*argv, "-autorts"))
672                         o.sopt.norts = 1;
673                 else if (! strcasecmp (*argv, "port=rs232") ||
674                     ! strcasecmp (*argv, "port=rs449") ||
675                     ! strcasecmp (*argv, "port=v35"))
676                         set_interface_type (*argv);
677                 else if (! strncasecmp (*argv, "master=",7))
678                         set_master (*argv+7);
679
680                 /*
681                  * Common channel options
682                  */
683                 /* channel option register 4 */
684                 else if (! strcasecmp (*argv, "-ctsdown"))
685                         o.opt.cor4.cts_zd = 0;
686                 else if (! strcasecmp (*argv, "+ctsdown"))
687                         o.opt.cor4.cts_zd = 1;
688                 else if (! strcasecmp (*argv, "-cddown"))
689                         o.opt.cor4.cd_zd = 0;
690                 else if (! strcasecmp (*argv, "+cddown"))
691                         o.opt.cor4.cd_zd = 1;
692                 else if (! strcasecmp (*argv, "-dsrdown"))
693                         o.opt.cor4.dsr_zd = 0;
694                 else if (! strcasecmp (*argv, "+dsrdown"))
695                         o.opt.cor4.dsr_zd = 1;
696                 else if (! strncasecmp (*argv, "fifo=", 5))
697                         o.opt.cor4.thr = atoi (*argv + 5);
698
699                 /* channel option register 5 */
700                 else if (! strcasecmp (*argv, "-ctsup"))
701                         o.opt.cor5.cts_od = 0;
702                 else if (! strcasecmp (*argv, "+ctsup"))
703                         o.opt.cor5.cts_od = 1;
704                 else if (! strcasecmp (*argv, "-cdup"))
705                         o.opt.cor5.cd_od = 0;
706                 else if (! strcasecmp (*argv, "+cdup"))
707                         o.opt.cor5.cd_od = 1;
708                 else if (! strcasecmp (*argv, "-dsrup"))
709                         o.opt.cor5.dsr_od = 0;
710                 else if (! strcasecmp (*argv, "+dsrup"))
711                         o.opt.cor5.dsr_od = 1;
712                 else if (! strncasecmp (*argv, "rfifo=", 6))
713                         o.opt.cor5.rx_thr = atoi (*argv + 6);
714
715                 /* receive clock option register */
716                 else if (! strcasecmp (*argv, "nrz"))
717                         o.opt.rcor.encod = ENCOD_NRZ;
718                 else if (! strcasecmp (*argv, "nrzi"))
719                         o.opt.rcor.encod = ENCOD_NRZI;
720                 else if (! strcasecmp (*argv, "manchester"))
721                         o.opt.rcor.encod = ENCOD_MANCHESTER;
722                 else if (! strcasecmp (*argv, "-dpll"))
723                         o.opt.rcor.dpll = 0;
724                 else if (! strcasecmp (*argv, "+dpll"))
725                         o.opt.rcor.dpll = 1;
726
727                 /* transmit clock option register */
728                 else if (! strcasecmp (*argv, "-lloop"))
729                         o.opt.tcor.llm = 0;
730                 else if (! strcasecmp (*argv, "+lloop"))
731                         o.opt.tcor.llm = 1;
732                 else if (! strcasecmp (*argv, "-extclock"))
733                         o.opt.tcor.ext1x = 0;
734                 else if (! strcasecmp (*argv, "+extclock"))
735                         o.opt.tcor.ext1x = 1;
736
737                 /*
738                  * Mode dependent channel options
739                  */
740                 else switch (o.mode) {
741                 case M_ASYNC:  set_async_opt (*argv); break;
742                 case M_HDLC:   set_hdlc_opt (*argv); break;
743                 case M_BISYNC: set_bisync_opt (*argv); break;
744                 case M_X21:    set_x21_opt (*argv); break;
745                 }
746
747         setchan (channel);
748         return (0);
749 }