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