145189Ssklower /* 2*48848Ssklower * Copyright (c) 1990 The Regents of the University of California. 3*48848Ssklower * All rights reserved. 4*48848Ssklower * 5*48848Ssklower * %sccs.include.redist.c% 6*48848Ssklower * 7*48848Ssklower * @(#)x25config.c 5.2 (Berkeley) 04/29/91 8*48848Ssklower */ 9*48848Ssklower /* 1045189Ssklower * Configure X.25 interface 1145189Ssklower * 1245189Ssklower * Copyright (c) 1986 University of British Columbia 1345189Ssklower * 1445189Ssklower * Frank Pronk 1545189Ssklower * February 1986 1645189Ssklower */ 1745189Ssklower 1845189Ssklower #include <sys/types.h> 1945189Ssklower #include <sys/socket.h> 2045189Ssklower #include <sys/ioctl.h> 2145189Ssklower 2245189Ssklower #include <net/if.h> 2345189Ssklower #include <netccitt/x25.h> 2445189Ssklower 2545189Ssklower #include <stdio.h> 2645189Ssklower #include <netdb.h> 2745189Ssklower 2845189Ssklower #define IFFBITS \ 2945189Ssklower "\020\1UP\2BROADCAST\3DEBUG\4ROUTE\5POINTOPOINT\6NOTRAILERS\7RUNNING\10NOARP" 3045189Ssklower 3145189Ssklower int setifflags (), setdefault (), setnet (), setntn (); 3245189Ssklower int setlproto (), sethdlc (), setlwsize (), setltrace (); 3345189Ssklower int setyear (), setpwsize (), setpacketsize (), setmaxlcn (), setptrace (); 3445189Ssklower 3545189Ssklower struct cmd { 3645189Ssklower char *c_name; 3745189Ssklower int c_arg; 3845189Ssklower int (*c_func) (); 3945189Ssklower } cmds[] = { 4045189Ssklower "up", IFF_UP, setifflags, 4145189Ssklower "-up", -IFF_UP, setifflags, 4245189Ssklower "down", -IFF_UP, setifflags, 4345189Ssklower "debug", IFF_DEBUG, setifflags, 4445189Ssklower "-debug", -IFF_DEBUG, setifflags, 4545189Ssklower "default", 0, setdefault, 4645189Ssklower "hdlc", CCITTPROTO_HDLC, setlproto, 4745189Ssklower "ieee802llc", IEEEPROTO_802LLC, setlproto, 4845189Ssklower "lap", HDLCPROTO_LAP, sethdlc, 4945189Ssklower "lapb", HDLCPROTO_LAPB, sethdlc, 5045189Ssklower "lapd", HDLCPROTO_LAPD, sethdlc, 5145189Ssklower "unset", HDLCPROTO_UNSET, sethdlc, 5245189Ssklower "-ltrace", 0, setltrace, 5345189Ssklower "ltrace", 1, setltrace, 5445189Ssklower 5545189Ssklower "1976", X25_1976, setyear, 5645189Ssklower "1980", X25_1980, setyear, 5745189Ssklower "1984", X25_1984, setyear, 5845189Ssklower "-ptrace", 0, setptrace, 5945189Ssklower "ptrace", 1, setptrace, 6045189Ssklower 6145189Ssklower "-net", 0, setnet, 6245189Ssklower "-ntn", 0, setntn, 6345189Ssklower "-lwsize", 0, setlwsize, 6445189Ssklower "-pwsize", 0, setpwsize, 6545189Ssklower "-psize", 0, setpacketsize, 6645189Ssklower "-maxlcn", 0, setmaxlcn, 6745189Ssklower 0, 0, 0 6845189Ssklower }; 6945189Ssklower 7045189Ssklower struct ifreq ifr; 71*48848Ssklower struct ifreq_x25 ifrx25; 72*48848Ssklower #define x25conf ifrx25.ifr_xc 7345189Ssklower 7445189Ssklower char *myname; 7545189Ssklower char *ifname; /* interface name */ 7645189Ssklower short ifflags; /* local copy of interface flags */ 7745189Ssklower 7845189Ssklower main (argc, argv) 7945189Ssklower register char **argv; 8045189Ssklower int argc; 8145189Ssklower { 8245189Ssklower register int s; 8345189Ssklower 8445189Ssklower myname = *argv; 8545189Ssklower if (argc < 2) 8645189Ssklower abort ("usage: x25ifconfig interface [default] [-net net] [-ntn ntn] [-maxlcn maxlcn] [up] [down] [zillions of other options]"); 8745189Ssklower 8845189Ssklower if ((s = socket (AF_CCITT, SOCK_STREAM, 0)) < 0) 8945189Ssklower syserr ("socket"); 9045189Ssklower argv[argc] = 0; 9145189Ssklower argv++; 9245189Ssklower 9345189Ssklower ifname = *argv; 9445189Ssklower strcpy (ifr.ifr_name, ifname); 9545189Ssklower if (ioctl (s, SIOCGIFFLAGS, (char *)&ifr) < 0) 9645189Ssklower syserr ("ioctl (SIOCGIFFLAGS)"); 9745189Ssklower ifflags = ifr.ifr_flags; 98*48848Ssklower strcpy (ifrx25.ifr_name, ifname); 99*48848Ssklower if (ioctl (s, SIOCGIFCONF_X25, (char *)&ifrx25) < 0) { 100*48848Ssklower x25conf.xc_addr.x25_len = sizeof(x25conf); 101*48848Ssklower x25conf.xc_addr.x25_family = AF_CCITT; 102*48848Ssklower } 10345189Ssklower if (argc == 2) { 10445189Ssklower status (); 10545189Ssklower exit (0); 10645189Ssklower } 10745189Ssklower argv++; 10845189Ssklower while (*argv) { 10945189Ssklower register struct cmd *cp; 11045189Ssklower register int argneeded; 11145189Ssklower 11245189Ssklower argneeded = 0; 11345189Ssklower for (cp = cmds; ; cp++) { 11445189Ssklower if (cp->c_name == 0) 11545189Ssklower abort ("invalid argument: %s", *argv); 11645189Ssklower if (cp->c_func == setnet) 11745189Ssklower argneeded++; 11845189Ssklower if (strcmp (cp->c_name, *argv) == 0) { 11945189Ssklower if (argneeded) { 12045189Ssklower if (argv[1]) { 12145189Ssklower argv++; 12245189Ssklower (*cp->c_func) (*argv); 12345189Ssklower } else 12445189Ssklower abort ("argument expect after %s", *argv); 12545189Ssklower } else 12645189Ssklower (*cp->c_func) (cp->c_arg); 12745189Ssklower break; 12845189Ssklower } 12945189Ssklower } 13045189Ssklower argv++; 13145189Ssklower } 13245189Ssklower ifr.ifr_flags = ifflags; 13345189Ssklower strcpy (ifr.ifr_name, ifname); 13445189Ssklower if (ioctl (s, SIOCSIFFLAGS, (char *)&ifr) < 0) 13545189Ssklower syserr ("ioctl (SIOCSIFFLAGS)"); 13645189Ssklower 137*48848Ssklower strcpy (ifrx25.ifr_name, ifname); 138*48848Ssklower if (ioctl (s, SIOCSIFCONF_X25, (char *)&ifrx25) < 0) 139*48848Ssklower syserr ("ioctl (SIOCSIFCONF_X25)"); 14045189Ssklower exit (0); 14145189Ssklower } 14245189Ssklower 14345189Ssklower /* VARARGS */ 14445189Ssklower abort (fmt, a1, a2, a3, a4, a5) 14545189Ssklower char *fmt; 14645189Ssklower { 14745189Ssklower char buf[128]; 14845189Ssklower 14945189Ssklower sprintf (buf, "%s: %s\n", myname, fmt); 15045189Ssklower fprintf (stderr, buf, a1, a2, a3, a4, a5); 15145189Ssklower exit (1); 15245189Ssklower } 15345189Ssklower 15445189Ssklower /* VARARGS */ 15545189Ssklower syserr (fmt, a1, a2, a3, a4, a5) 15645189Ssklower char *fmt; 15745189Ssklower { 15845189Ssklower char buf[128]; 15945189Ssklower extern int errno; 16045189Ssklower extern char *sys_errlist[]; 16145189Ssklower 16245189Ssklower sprintf (buf, "%s: %s: %s\n", myname, fmt, sys_errlist[errno]); 16345189Ssklower fprintf (stderr, buf, a1, a2, a3, a4, a5); 16445189Ssklower exit (1); 16545189Ssklower } 16645189Ssklower 16745189Ssklower status () 16845189Ssklower { 169*48848Ssklower char *addr = x25conf.xc_addr.x25_addr; 17045189Ssklower 17145189Ssklower printf ("%s: ", ifname); 17245189Ssklower printb ("interface flags", ifflags, IFFBITS); 17345189Ssklower printf ("link level:\n"); 17445189Ssklower printf ("\twindow size: %d\n", x25conf.xc_lwsize); 17545189Ssklower if (x25conf.xc_ltrace) 17645189Ssklower printf ("\ttracing: on\n"); 17745189Ssklower printf ("\npacket level:\n"); 178*48848Ssklower printf ("\taddress: %04d %s\n", x25conf.xc_addr.x25_net, addr); 17945189Ssklower printf ("\twindow size: %d\n", x25conf.xc_pwsize); 18045189Ssklower printf ("\tpacket size: %d\n", 1 << x25conf.xc_psize); 18145189Ssklower printf ("\tmax lcn: %d\n", x25conf.xc_maxlcn); 18245189Ssklower if (x25conf.xc_ptrace) 18345189Ssklower printf ("\ttracing: on\n"); 18445189Ssklower } 18545189Ssklower 18645189Ssklower setifflags (value) 18745189Ssklower { 18845189Ssklower 18945189Ssklower if (value < 0) { 19045189Ssklower value = -value; 19145189Ssklower ifflags &= ~value; 19245189Ssklower } else 19345189Ssklower ifflags |= value; 19445189Ssklower } 19545189Ssklower 19645189Ssklower /* VARARGS */ 19745189Ssklower setdefault (arg) 19845189Ssklower { 19945189Ssklower 200*48848Ssklower x25conf.xc_addr.x25_family = AF_CCITT; 20145189Ssklower x25conf.xc_lproto = CCITTPROTO_HDLC; 20245189Ssklower x25conf.xc_lptype = HDLCPROTO_LAPB; 20345189Ssklower x25conf.xc_lwsize = 7; 20445189Ssklower 20545189Ssklower x25conf.xc_pwsize = 2; 20645189Ssklower x25conf.xc_psize = X25_PS128; 20745189Ssklower x25conf.xc_type = X25_1976; 20845189Ssklower } 20945189Ssklower 21045189Ssklower setnet (arg) 21145189Ssklower char *arg; 21245189Ssklower { 21345189Ssklower register int net; 21445189Ssklower register struct netent *np; 21545189Ssklower 21645189Ssklower if (*arg < '0' || *arg > '9') { /* lookup name in /etc/networks */ 21745189Ssklower if ((np = getnetbyname (arg)) == 0) 21845189Ssklower abort ("unknown network (%s)", arg); 21945189Ssklower net = np->n_net; 22045189Ssklower } else 22145189Ssklower net = atoi (arg); 222*48848Ssklower x25conf.xc_addr.x25_net = net; 22345189Ssklower } 22445189Ssklower 22545189Ssklower setntn (arg) 22645189Ssklower register char *arg; 22745189Ssklower { 22845189Ssklower register int l; 22945189Ssklower register char *p; 23045189Ssklower register struct hostent *hp; 23145189Ssklower struct hostent *getx25hostbyname (); 23245189Ssklower 23345189Ssklower if (*arg < '0' || *arg > '9') { /* lookup in /etc/x25hosts */ 23445189Ssklower if ((hp = getx25hostbyname (arg)) == 0) 23545189Ssklower abort ("can't find '%s' in /etc/x25hosts", arg); 23645189Ssklower arg = ((struct sockaddr_x25 *)hp->h_addr)->x25_addr; 237*48848Ssklower l = strlen (arg) + 1; 23845189Ssklower } else 239*48848Ssklower for (l = 1, p = arg; *p; p++) { 24045189Ssklower l++; 24145189Ssklower if (*p < '0' || *p > '9') 24245189Ssklower abort ("invalid character in ntn address"); 24345189Ssklower } 244*48848Ssklower if (l > sizeof (x25conf.xc_addr.x25_addr)) 24545189Ssklower abort ("invalid ntn address"); 246*48848Ssklower bcopy(arg, x25conf.xc_addr.x25_addr, l); 24745189Ssklower } 24845189Ssklower 24945189Ssklower to_bcd (src, dest) 25045189Ssklower register char *src, *dest; 25145189Ssklower { 25245189Ssklower register int i; 25345189Ssklower 25445189Ssklower for(i = 0; *src; i++) 25545189Ssklower if (i & 0x01 ) 25645189Ssklower *dest++ |= *src++ & 0x0F; 25745189Ssklower else 25845189Ssklower *dest = *src++ << 4; 25945189Ssklower } 26045189Ssklower 26145189Ssklower from_bcd (src, dest, len) 26245189Ssklower char *src, *dest; 26345189Ssklower { 26445189Ssklower register int i; 26545189Ssklower 26645189Ssklower for (i = 0; i < len/2; i++) { 26745189Ssklower *dest++ = ((*src & 0xf0) >> 4) + '0'; 26845189Ssklower *dest++ = (*src++ & 0xf) + '0'; 26945189Ssklower } 27045189Ssklower *dest = 0; 27145189Ssklower } 27245189Ssklower 27345189Ssklower setlproto (arg) 27445189Ssklower { 27545189Ssklower x25conf.xc_lproto = arg; 27645189Ssklower } 27745189Ssklower 27845189Ssklower sethdlc (arg) 27945189Ssklower { 28045189Ssklower x25conf.xc_lptype = arg; 28145189Ssklower } 28245189Ssklower 28345189Ssklower setlwsize (arg) 28445189Ssklower char *arg; 28545189Ssklower { 28645189Ssklower register int ws; 28745189Ssklower 28845189Ssklower if ((ws = atoi (arg)) <= 0 || ws > 31) 28945189Ssklower abort ("invalid link level window size"); 29045189Ssklower x25conf.xc_lwsize = ws; 29145189Ssklower } 29245189Ssklower 29345189Ssklower setltrace (arg) 29445189Ssklower { 29545189Ssklower x25conf.xc_ltrace = arg; 29645189Ssklower } 29745189Ssklower 29845189Ssklower setyear (arg) 29945189Ssklower { 30045189Ssklower x25conf.xc_type = arg; 30145189Ssklower switch (arg) { 30245189Ssklower case X25_1976: 30345189Ssklower return; 30445189Ssklower 30545189Ssklower case X25_1980: 30645189Ssklower case X25_1984: 30745189Ssklower x25conf.xc_pwsize = 7; 30845189Ssklower x25conf.xc_psize = 12; /* 4096 bytes */ 30945189Ssklower } 31045189Ssklower } 31145189Ssklower 31245189Ssklower setpwsize (arg) 31345189Ssklower char *arg; 31445189Ssklower { 31545189Ssklower register int ws; 31645189Ssklower 31745189Ssklower if ((ws = atoi (arg)) <= 0 || ws > 7) 31845189Ssklower abort ("invalid packet level window size"); 31945189Ssklower x25conf.xc_pwsize = ws; 32045189Ssklower } 32145189Ssklower 32245189Ssklower setpacketsize (arg) 32345189Ssklower char *arg; 32445189Ssklower { 32545189Ssklower register int psize, logpsize = 0; 32645189Ssklower 32745189Ssklower if ((psize = atoi (arg)) < 64 || psize > 4096) 32845189Ssklower abort ("invalid packet size"); 32945189Ssklower while (psize > 1) { 33045189Ssklower psize >>= 1; 33145189Ssklower logpsize++; 33245189Ssklower } 33345189Ssklower x25conf.xc_psize = logpsize; 33445189Ssklower } 33545189Ssklower 33645189Ssklower setmaxlcn (arg) 33745189Ssklower char *arg; 33845189Ssklower { 33945189Ssklower register int lcn; 34045189Ssklower 34145189Ssklower if ((lcn = atoi (arg)) <= 0) 34245189Ssklower abort ("invalid maximum lcn"); 34345189Ssklower x25conf.xc_maxlcn = lcn; 34445189Ssklower } 34545189Ssklower 34645189Ssklower setptrace (arg) 34745189Ssklower { 34845189Ssklower x25conf.xc_ptrace = arg; 34945189Ssklower } 35045189Ssklower 35145189Ssklower /* 35245189Ssklower * Print a value a la the %b format of the kernel's printf 35345189Ssklower */ 35445189Ssklower 35545189Ssklower printb(s, v, bits) 35645189Ssklower char *s; 35745189Ssklower register char *bits; 35845189Ssklower register unsigned short v; 35945189Ssklower { 36045189Ssklower register int i, any = 0; 36145189Ssklower register char c; 36245189Ssklower 36345189Ssklower if (bits && *bits == 8) 36445189Ssklower printf("%s=%o", s, v); 36545189Ssklower else 36645189Ssklower printf("%s=%x", s, v); 36745189Ssklower bits++; 36845189Ssklower if (bits) { 36945189Ssklower putchar('<'); 37045189Ssklower while (i = *bits++) { 37145189Ssklower if (v & (1 << (i-1))) { 37245189Ssklower if (any) 37345189Ssklower putchar(','); 37445189Ssklower any = 1; 37545189Ssklower for (; (c = *bits) > 32; bits++) 37645189Ssklower putchar(c); 37745189Ssklower } else 37845189Ssklower for (; *bits > 32; bits++) 37945189Ssklower ; 38045189Ssklower } 38145189Ssklower putchar('>'); 38245189Ssklower putchar('\n'); 38345189Ssklower } 38445189Ssklower } 385