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