1 /* 2 * Copyright (c) 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)x25config.c 5.2 (Berkeley) 04/29/91 8 */ 9 /* 10 * Configure X.25 interface 11 * 12 * Copyright (c) 1986 University of British Columbia 13 * 14 * Frank Pronk 15 * February 1986 16 */ 17 18 #include <sys/types.h> 19 #include <sys/socket.h> 20 #include <sys/ioctl.h> 21 22 #include <net/if.h> 23 #include <netccitt/x25.h> 24 25 #include <stdio.h> 26 #include <netdb.h> 27 28 #define IFFBITS \ 29 "\020\1UP\2BROADCAST\3DEBUG\4ROUTE\5POINTOPOINT\6NOTRAILERS\7RUNNING\10NOARP" 30 31 int setifflags (), setdefault (), setnet (), setntn (); 32 int setlproto (), sethdlc (), setlwsize (), setltrace (); 33 int setyear (), setpwsize (), setpacketsize (), setmaxlcn (), setptrace (); 34 35 struct cmd { 36 char *c_name; 37 int c_arg; 38 int (*c_func) (); 39 } cmds[] = { 40 "up", IFF_UP, setifflags, 41 "-up", -IFF_UP, setifflags, 42 "down", -IFF_UP, setifflags, 43 "debug", IFF_DEBUG, setifflags, 44 "-debug", -IFF_DEBUG, setifflags, 45 "default", 0, setdefault, 46 "hdlc", CCITTPROTO_HDLC, setlproto, 47 "ieee802llc", IEEEPROTO_802LLC, setlproto, 48 "lap", HDLCPROTO_LAP, sethdlc, 49 "lapb", HDLCPROTO_LAPB, sethdlc, 50 "lapd", HDLCPROTO_LAPD, sethdlc, 51 "unset", HDLCPROTO_UNSET, sethdlc, 52 "-ltrace", 0, setltrace, 53 "ltrace", 1, setltrace, 54 55 "1976", X25_1976, setyear, 56 "1980", X25_1980, setyear, 57 "1984", X25_1984, setyear, 58 "-ptrace", 0, setptrace, 59 "ptrace", 1, setptrace, 60 61 "-net", 0, setnet, 62 "-ntn", 0, setntn, 63 "-lwsize", 0, setlwsize, 64 "-pwsize", 0, setpwsize, 65 "-psize", 0, setpacketsize, 66 "-maxlcn", 0, setmaxlcn, 67 0, 0, 0 68 }; 69 70 struct ifreq ifr; 71 struct ifreq_x25 ifrx25; 72 #define x25conf ifrx25.ifr_xc 73 74 char *myname; 75 char *ifname; /* interface name */ 76 short ifflags; /* local copy of interface flags */ 77 78 main (argc, argv) 79 register char **argv; 80 int argc; 81 { 82 register int s; 83 84 myname = *argv; 85 if (argc < 2) 86 abort ("usage: x25ifconfig interface [default] [-net net] [-ntn ntn] [-maxlcn maxlcn] [up] [down] [zillions of other options]"); 87 88 if ((s = socket (AF_CCITT, SOCK_STREAM, 0)) < 0) 89 syserr ("socket"); 90 argv[argc] = 0; 91 argv++; 92 93 ifname = *argv; 94 strcpy (ifr.ifr_name, ifname); 95 if (ioctl (s, SIOCGIFFLAGS, (char *)&ifr) < 0) 96 syserr ("ioctl (SIOCGIFFLAGS)"); 97 ifflags = ifr.ifr_flags; 98 strcpy (ifrx25.ifr_name, ifname); 99 if (ioctl (s, SIOCGIFCONF_X25, (char *)&ifrx25) < 0) { 100 x25conf.xc_addr.x25_len = sizeof(x25conf); 101 x25conf.xc_addr.x25_family = AF_CCITT; 102 } 103 if (argc == 2) { 104 status (); 105 exit (0); 106 } 107 argv++; 108 while (*argv) { 109 register struct cmd *cp; 110 register int argneeded; 111 112 argneeded = 0; 113 for (cp = cmds; ; cp++) { 114 if (cp->c_name == 0) 115 abort ("invalid argument: %s", *argv); 116 if (cp->c_func == setnet) 117 argneeded++; 118 if (strcmp (cp->c_name, *argv) == 0) { 119 if (argneeded) { 120 if (argv[1]) { 121 argv++; 122 (*cp->c_func) (*argv); 123 } else 124 abort ("argument expect after %s", *argv); 125 } else 126 (*cp->c_func) (cp->c_arg); 127 break; 128 } 129 } 130 argv++; 131 } 132 ifr.ifr_flags = ifflags; 133 strcpy (ifr.ifr_name, ifname); 134 if (ioctl (s, SIOCSIFFLAGS, (char *)&ifr) < 0) 135 syserr ("ioctl (SIOCSIFFLAGS)"); 136 137 strcpy (ifrx25.ifr_name, ifname); 138 if (ioctl (s, SIOCSIFCONF_X25, (char *)&ifrx25) < 0) 139 syserr ("ioctl (SIOCSIFCONF_X25)"); 140 exit (0); 141 } 142 143 /* VARARGS */ 144 abort (fmt, a1, a2, a3, a4, a5) 145 char *fmt; 146 { 147 char buf[128]; 148 149 sprintf (buf, "%s: %s\n", myname, fmt); 150 fprintf (stderr, buf, a1, a2, a3, a4, a5); 151 exit (1); 152 } 153 154 /* VARARGS */ 155 syserr (fmt, a1, a2, a3, a4, a5) 156 char *fmt; 157 { 158 char buf[128]; 159 extern int errno; 160 extern char *sys_errlist[]; 161 162 sprintf (buf, "%s: %s: %s\n", myname, fmt, sys_errlist[errno]); 163 fprintf (stderr, buf, a1, a2, a3, a4, a5); 164 exit (1); 165 } 166 167 status () 168 { 169 char *addr = x25conf.xc_addr.x25_addr; 170 171 printf ("%s: ", ifname); 172 printb ("interface flags", ifflags, IFFBITS); 173 printf ("link level:\n"); 174 printf ("\twindow size: %d\n", x25conf.xc_lwsize); 175 if (x25conf.xc_ltrace) 176 printf ("\ttracing: on\n"); 177 printf ("\npacket level:\n"); 178 printf ("\taddress: %04d %s\n", x25conf.xc_addr.x25_net, addr); 179 printf ("\twindow size: %d\n", x25conf.xc_pwsize); 180 printf ("\tpacket size: %d\n", 1 << x25conf.xc_psize); 181 printf ("\tmax lcn: %d\n", x25conf.xc_maxlcn); 182 if (x25conf.xc_ptrace) 183 printf ("\ttracing: on\n"); 184 } 185 186 setifflags (value) 187 { 188 189 if (value < 0) { 190 value = -value; 191 ifflags &= ~value; 192 } else 193 ifflags |= value; 194 } 195 196 /* VARARGS */ 197 setdefault (arg) 198 { 199 200 x25conf.xc_addr.x25_family = AF_CCITT; 201 x25conf.xc_lproto = CCITTPROTO_HDLC; 202 x25conf.xc_lptype = HDLCPROTO_LAPB; 203 x25conf.xc_lwsize = 7; 204 205 x25conf.xc_pwsize = 2; 206 x25conf.xc_psize = X25_PS128; 207 x25conf.xc_type = X25_1976; 208 } 209 210 setnet (arg) 211 char *arg; 212 { 213 register int net; 214 register struct netent *np; 215 216 if (*arg < '0' || *arg > '9') { /* lookup name in /etc/networks */ 217 if ((np = getnetbyname (arg)) == 0) 218 abort ("unknown network (%s)", arg); 219 net = np->n_net; 220 } else 221 net = atoi (arg); 222 x25conf.xc_addr.x25_net = net; 223 } 224 225 setntn (arg) 226 register char *arg; 227 { 228 register int l; 229 register char *p; 230 register struct hostent *hp; 231 struct hostent *getx25hostbyname (); 232 233 if (*arg < '0' || *arg > '9') { /* lookup in /etc/x25hosts */ 234 if ((hp = getx25hostbyname (arg)) == 0) 235 abort ("can't find '%s' in /etc/x25hosts", arg); 236 arg = ((struct sockaddr_x25 *)hp->h_addr)->x25_addr; 237 l = strlen (arg) + 1; 238 } else 239 for (l = 1, p = arg; *p; p++) { 240 l++; 241 if (*p < '0' || *p > '9') 242 abort ("invalid character in ntn address"); 243 } 244 if (l > sizeof (x25conf.xc_addr.x25_addr)) 245 abort ("invalid ntn address"); 246 bcopy(arg, x25conf.xc_addr.x25_addr, l); 247 } 248 249 to_bcd (src, dest) 250 register char *src, *dest; 251 { 252 register int i; 253 254 for(i = 0; *src; i++) 255 if (i & 0x01 ) 256 *dest++ |= *src++ & 0x0F; 257 else 258 *dest = *src++ << 4; 259 } 260 261 from_bcd (src, dest, len) 262 char *src, *dest; 263 { 264 register int i; 265 266 for (i = 0; i < len/2; i++) { 267 *dest++ = ((*src & 0xf0) >> 4) + '0'; 268 *dest++ = (*src++ & 0xf) + '0'; 269 } 270 *dest = 0; 271 } 272 273 setlproto (arg) 274 { 275 x25conf.xc_lproto = arg; 276 } 277 278 sethdlc (arg) 279 { 280 x25conf.xc_lptype = arg; 281 } 282 283 setlwsize (arg) 284 char *arg; 285 { 286 register int ws; 287 288 if ((ws = atoi (arg)) <= 0 || ws > 31) 289 abort ("invalid link level window size"); 290 x25conf.xc_lwsize = ws; 291 } 292 293 setltrace (arg) 294 { 295 x25conf.xc_ltrace = arg; 296 } 297 298 setyear (arg) 299 { 300 x25conf.xc_type = arg; 301 switch (arg) { 302 case X25_1976: 303 return; 304 305 case X25_1980: 306 case X25_1984: 307 x25conf.xc_pwsize = 7; 308 x25conf.xc_psize = 12; /* 4096 bytes */ 309 } 310 } 311 312 setpwsize (arg) 313 char *arg; 314 { 315 register int ws; 316 317 if ((ws = atoi (arg)) <= 0 || ws > 7) 318 abort ("invalid packet level window size"); 319 x25conf.xc_pwsize = ws; 320 } 321 322 setpacketsize (arg) 323 char *arg; 324 { 325 register int psize, logpsize = 0; 326 327 if ((psize = atoi (arg)) < 64 || psize > 4096) 328 abort ("invalid packet size"); 329 while (psize > 1) { 330 psize >>= 1; 331 logpsize++; 332 } 333 x25conf.xc_psize = logpsize; 334 } 335 336 setmaxlcn (arg) 337 char *arg; 338 { 339 register int lcn; 340 341 if ((lcn = atoi (arg)) <= 0) 342 abort ("invalid maximum lcn"); 343 x25conf.xc_maxlcn = lcn; 344 } 345 346 setptrace (arg) 347 { 348 x25conf.xc_ptrace = arg; 349 } 350 351 /* 352 * Print a value a la the %b format of the kernel's printf 353 */ 354 355 printb(s, v, bits) 356 char *s; 357 register char *bits; 358 register unsigned short v; 359 { 360 register int i, any = 0; 361 register char c; 362 363 if (bits && *bits == 8) 364 printf("%s=%o", s, v); 365 else 366 printf("%s=%x", s, v); 367 bits++; 368 if (bits) { 369 putchar('<'); 370 while (i = *bits++) { 371 if (v & (1 << (i-1))) { 372 if (any) 373 putchar(','); 374 any = 1; 375 for (; (c = *bits) > 32; bits++) 376 putchar(c); 377 } else 378 for (; *bits > 32; bits++) 379 ; 380 } 381 putchar('>'); 382 putchar('\n'); 383 } 384 } 385