1 /* $NetBSD: pppoectl.c,v 1.20 2005/06/27 01:00:06 christos Exp $ */ 2 3 /* 4 * Copyright (c) 1997 Joerg Wunsch 5 * 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * From: spppcontrol.c,v 1.3 1998/01/07 07:55:26 charnier Exp 29 * From: ispppcontrol 30 */ 31 #include <sys/cdefs.h> 32 33 #ifndef lint 34 __RCSID("$NetBSD: pppoectl.c,v 1.20 2005/06/27 01:00:06 christos Exp $"); 35 #endif 36 37 38 #include <sys/param.h> 39 #include <sys/callout.h> 40 #include <sys/ioctl.h> 41 #include <sys/mbuf.h> 42 #include <sys/socket.h> 43 #include <sys/time.h> 44 #include <sys/sysctl.h> 45 #include <net/if.h> 46 #include <net/if_sppp.h> 47 #include <net/if_pppoe.h> 48 #include <err.h> 49 #include <stdio.h> 50 #include <stdlib.h> 51 #include <string.h> 52 #include <sysexits.h> 53 #include <unistd.h> 54 55 static void usage(void); 56 static void print_error(const char *ifname, int error, const char * str); 57 static void print_vals(const char *ifname, int phase, struct spppauthcfg *sp, 58 int lcp_timeout, time_t idle_timeout, int authfailures, 59 int max_auth_failures, u_int maxalive, time_t max_noreceive); 60 const char *phase_name(int phase); 61 const char *proto_name(int proto); 62 const char *authflags(int flags); 63 static void pppoectl_argument(char *arg); 64 65 int hz = 0; 66 67 int set_auth, set_lcp, set_idle_to, set_auth_failure, set_dns, 68 clear_auth_failure_count, set_keepalive; 69 int maxalive = -1; 70 int max_noreceive = -1; 71 struct spppauthcfg spr; 72 struct sppplcpcfg lcp; 73 struct spppstatus status; 74 struct spppidletimeout timeout; 75 struct spppauthfailurestats authfailstats; 76 struct spppauthfailuresettings authfailset; 77 struct spppdnssettings dnssettings; 78 struct spppkeepalivesettings keepalivesettings; 79 80 int 81 main(int argc, char **argv) 82 { 83 FILE *fp; 84 int s, c; 85 int errs = 0, verbose = 0, dump = 0, dns1 = 0, dns2 = 0; 86 size_t len; 87 const char *eth_if_name, *access_concentrator, *service; 88 const char *ifname, *configname; 89 char *line; 90 int mib[2]; 91 struct clockinfo clockinfo; 92 setprogname(argv[0]); 93 94 eth_if_name = NULL; 95 access_concentrator = NULL; 96 service = NULL; 97 configname = NULL; 98 while ((c = getopt(argc, argv, "vde:f:s:a:n:")) != -1) 99 switch (c) { 100 case 'v': 101 verbose++; 102 break; 103 104 case 'd': 105 dump++; 106 break; 107 108 case 'e': 109 eth_if_name = optarg; 110 break; 111 112 case 'f': 113 configname = optarg; 114 break; 115 116 case 's': 117 service = optarg; 118 break; 119 120 case 'a': 121 access_concentrator = optarg; 122 break; 123 124 case 'n': 125 if (strcmp(optarg, "1") == 0) 126 dns1 = 1; 127 else if (strcmp(optarg, "2") == 0) 128 dns2 = 1; 129 else { 130 fprintf(stderr, "bad argument \"%s\" to -n (only 1 or two allowed)\n", 131 optarg); 132 errs++; 133 } 134 break; 135 136 default: 137 errs++; 138 break; 139 } 140 argv += optind; 141 argc -= optind; 142 143 if (errs || argc < 1) 144 usage(); 145 146 ifname = argv[0]; 147 148 /* use a random AF to create the socket */ 149 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) 150 err(EX_UNAVAILABLE, "ifconfig: socket"); 151 152 argc--; 153 argv++; 154 155 if (eth_if_name) { 156 struct pppoediscparms parms; 157 int e; 158 159 memset(&parms, 0, sizeof parms); 160 strncpy(parms.ifname, ifname, sizeof(parms.ifname)); 161 strncpy(parms.eth_ifname, eth_if_name, sizeof(parms.eth_ifname)); 162 if (access_concentrator) { 163 parms.ac_name = access_concentrator; 164 parms.ac_name_len = strlen(access_concentrator); 165 } 166 if (service) { 167 parms.service_name = service; 168 parms.service_name_len = strlen(service); 169 } 170 171 e = ioctl(s, PPPOESETPARMS, &parms); 172 if (e) 173 print_error(ifname, e, "PPPOESETPARMS"); 174 return 0; 175 } 176 177 if (dns1 || dns2) { 178 /* print DNS addresses */ 179 int e; 180 struct spppdnsaddrs addrs; 181 memset(&addrs, 0, sizeof addrs); 182 strncpy(addrs.ifname, ifname, sizeof addrs.ifname); 183 e = ioctl(s, SPPPGETDNSADDRS, &addrs); 184 if (e) 185 print_error(ifname, e, "SPPPGETDNSADDRS"); 186 if (dns1) 187 printf("%d.%d.%d.%d\n", 188 (addrs.dns[0] >> 24) & 0xff, 189 (addrs.dns[0] >> 16) & 0xff, 190 (addrs.dns[0] >> 8) & 0xff, 191 addrs.dns[0] & 0xff); 192 if (dns2) 193 printf("%d.%d.%d.%d\n", 194 (addrs.dns[1] >> 24) & 0xff, 195 (addrs.dns[1] >> 16) & 0xff, 196 (addrs.dns[1] >> 8) & 0xff, 197 addrs.dns[1] & 0xff); 198 } 199 200 if (dump) { 201 /* dump PPPoE session state */ 202 struct pppoeconnectionstate state; 203 int e; 204 205 memset(&state, 0, sizeof state); 206 strncpy(state.ifname, ifname, sizeof state.ifname); 207 e = ioctl(s, PPPOEGETSESSION, &state); 208 if (e) 209 print_error(ifname, e, "PPPOEGETSESSION"); 210 211 printf("%s:\tstate = ", ifname); 212 switch(state.state) { 213 case PPPOE_STATE_INITIAL: 214 printf("initial\n"); break; 215 case PPPOE_STATE_PADI_SENT: 216 printf("PADI sent\n"); break; 217 case PPPOE_STATE_PADR_SENT: 218 printf("PADR sent\n"); break; 219 case PPPOE_STATE_SESSION: 220 printf("session\n"); break; 221 case PPPOE_STATE_CLOSING: 222 printf("closing\n"); break; 223 } 224 printf("\tSession ID: 0x%x\n", state.session_id); 225 printf("\tPADI retries: %d\n", state.padi_retry_no); 226 printf("\tPADR retries: %d\n", state.padr_retry_no); 227 228 return 0; 229 } 230 231 232 memset(&spr, 0, sizeof spr); 233 strncpy(spr.ifname, ifname, sizeof spr.ifname); 234 memset(&lcp, 0, sizeof lcp); 235 strncpy(lcp.ifname, ifname, sizeof lcp.ifname); 236 memset(&status, 0, sizeof status); 237 strncpy(status.ifname, ifname, sizeof status.ifname); 238 memset(&timeout, 0, sizeof timeout); 239 strncpy(timeout.ifname, ifname, sizeof timeout.ifname); 240 memset(&authfailstats, 0, sizeof &authfailstats); 241 strncpy(authfailstats.ifname, ifname, sizeof authfailstats.ifname); 242 memset(&authfailset, 0, sizeof authfailset); 243 strncpy(authfailset.ifname, ifname, sizeof authfailset.ifname); 244 memset(&dnssettings, 0, sizeof dnssettings); 245 strncpy(dnssettings.ifname, ifname, sizeof dnssettings.ifname); 246 memset(&keepalivesettings, 0, sizeof keepalivesettings); 247 strncpy(keepalivesettings.ifname, ifname, sizeof keepalivesettings.ifname); 248 249 mib[0] = CTL_KERN; 250 mib[1] = KERN_CLOCKRATE; 251 len = sizeof(clockinfo); 252 if(sysctl(mib, 2, &clockinfo, &len, NULL, 0) == -1) 253 { 254 fprintf(stderr, "error, cannot sysctl kern.clockrate!\n"); 255 exit(1); 256 } 257 258 hz = clockinfo.hz; 259 260 if (argc == 0 && !(dns1||dns2) && !configname) { 261 /* list only mode */ 262 263 /* first pass, get name lengths */ 264 if (ioctl(s, SPPPGETAUTHCFG, &spr) == -1) 265 err(EX_OSERR, "SPPPGETAUTHCFG"); 266 /* now allocate buffers for strings */ 267 if (spr.myname_length) 268 spr.myname = malloc(spr.myname_length); 269 if (spr.hisname_length) 270 spr.hisname = malloc(spr.hisname_length); 271 /* second pass: get names too */ 272 if (ioctl(s, SPPPGETAUTHCFG, &spr) == -1) 273 err(EX_OSERR, "SPPPGETAUTHCFG"); 274 275 if (ioctl(s, SPPPGETLCPCFG, &lcp) == -1) 276 err(EX_OSERR, "SPPPGETLCPCFG"); 277 if (ioctl(s, SPPPGETSTATUS, &status) == -1) 278 err(EX_OSERR, "SPPPGETSTATUS"); 279 if (ioctl(s, SPPPGETIDLETO, &timeout) == -1) 280 err(EX_OSERR, "SPPPGETIDLETO"); 281 if (ioctl(s, SPPPGETAUTHFAILURES, &authfailstats) == -1) 282 err(EX_OSERR, "SPPPGETAUTHFAILURES"); 283 if (ioctl(s, SPPPGETKEEPALIVE, &keepalivesettings) == -1) 284 err(EX_OSERR, "SPPPGETKEEPALIVE"); 285 286 print_vals(ifname, status.phase, &spr, lcp.lcp_timeout, 287 timeout.idle_seconds, authfailstats.auth_failures, 288 authfailstats.max_failures, 289 keepalivesettings.maxalive, 290 keepalivesettings.max_noreceive); 291 292 if (spr.hisname) free(spr.hisname); 293 if (spr.myname) free(spr.myname); 294 return 0; 295 } 296 297 /* first load the config file, then parse command line args */ 298 if (configname && (fp = fopen(configname, "r"))) 299 while ((line = fparseln(fp, NULL, NULL, NULL, 300 FPARSELN_UNESCALL)) != NULL) { 301 if (line[0] != '\0') 302 pppoectl_argument(line); 303 /* 304 * We do not free(line) here, because we 305 * still have references to parts of the 306 * string collected in the various ioctl 307 * argument structures (and need those). 308 * Yes, this is a memory leak. 309 * We could copy the partial strings instead, 310 * and free those later - but this is a one-shot 311 * program and memory will be freed at process 312 * exit time anyway. 313 */ 314 } 315 316 317 while (argc > 0) { 318 pppoectl_argument(argv[0]); 319 320 argv++; 321 argc--; 322 } 323 324 if (set_auth) { 325 if (ioctl(s, SPPPSETAUTHCFG, &spr) == -1) 326 err(EX_OSERR, "SPPPSETAUTHCFG"); 327 } 328 if (set_lcp) { 329 if (ioctl(s, SPPPSETLCPCFG, &lcp) == -1) 330 err(EX_OSERR, "SPPPSETLCPCFG"); 331 } 332 if (set_idle_to) { 333 if (ioctl(s, SPPPSETIDLETO, &timeout) == -1) 334 err(EX_OSERR, "SPPPSETIDLETO"); 335 } 336 if (set_auth_failure) { 337 if (ioctl(s, SPPPSETAUTHFAILURE, &authfailset) == -1) 338 err(EX_OSERR, "SPPPSETAUTHFAILURE"); 339 } 340 if (clear_auth_failure_count && !(set_auth || set_auth_failure)) { 341 /* 342 * We want to clear the auth failure count, but did not 343 * do that implicitly by setting authentication - so 344 * do a zero-effect auth setting change 345 */ 346 if (ioctl(s, SPPPGETAUTHFAILURES, &authfailstats) == -1) 347 err(EX_OSERR, "SPPPGETAUTHFAILURES"); 348 authfailset.max_failures = authfailstats.max_failures; 349 if (ioctl(s, SPPPSETAUTHFAILURE, &authfailset) == -1) 350 err(EX_OSERR, "SPPPSETAUTHFAILURE"); 351 } 352 if (set_dns) { 353 if (ioctl(s, SPPPSETDNSOPTS, &dnssettings) == -1) 354 err(EX_OSERR, "SPPPSETDNSOPTS"); 355 } 356 if (set_keepalive) { 357 if (ioctl(s, SPPPGETKEEPALIVE, &keepalivesettings) == -1) 358 err(EX_OSERR, "SPPPGETKEEPALIVE"); 359 if (max_noreceive >= 0) 360 keepalivesettings.max_noreceive = max_noreceive; 361 if (maxalive >= 0) 362 keepalivesettings.maxalive = maxalive; 363 if (ioctl(s, SPPPSETKEEPALIVE, &keepalivesettings) == -1) 364 err(EX_OSERR, "SPPPSETKEEPALIVE"); 365 } 366 367 if (verbose) { 368 if (ioctl(s, SPPPGETAUTHFAILURES, &authfailstats) == -1) 369 err(EX_OSERR, "SPPPGETAUTHFAILURES"); 370 if (ioctl(s, SPPPGETKEEPALIVE, &keepalivesettings) == -1) 371 err(EX_OSERR, "SPPPGETKEEPALIVE"); 372 print_vals(ifname, status.phase, &spr, lcp.lcp_timeout, 373 timeout.idle_seconds, authfailstats.auth_failures, 374 authfailstats.max_failures, 375 keepalivesettings.maxalive, 376 keepalivesettings.max_noreceive); 377 } 378 379 return 0; 380 } 381 382 static void 383 pppoectl_argument(char *arg) 384 { 385 size_t off; 386 const char *cp; 387 388 #define startswith(a,s) strncmp(a, s, (off = strlen(s))) == 0 389 if (startswith(arg, "authproto=")) { 390 cp = arg + off; 391 if (strcmp(cp, "pap") == 0) 392 spr.myauth = 393 spr.hisauth = SPPP_AUTHPROTO_PAP; 394 else if (strcmp(cp, "chap") == 0) 395 spr.myauth = spr.hisauth = SPPP_AUTHPROTO_CHAP; 396 else if (strcmp(cp, "none") == 0) 397 spr.myauth = spr.hisauth = SPPP_AUTHPROTO_NONE; 398 else 399 errx(EX_DATAERR, "bad auth proto: %s", cp); 400 set_auth = 1; 401 } else if (startswith(arg, "myauthproto=")) { 402 cp = arg + off; 403 if (strcmp(cp, "pap") == 0) 404 spr.myauth = SPPP_AUTHPROTO_PAP; 405 else if (strcmp(cp, "chap") == 0) 406 spr.myauth = SPPP_AUTHPROTO_CHAP; 407 else if (strcmp(cp, "none") == 0) 408 spr.myauth = SPPP_AUTHPROTO_NONE; 409 else 410 errx(EX_DATAERR, "bad auth proto: %s", cp); 411 set_auth = 1; 412 } else if (startswith(arg, "myauthname=")) { 413 spr.myname = arg + off; 414 spr.myname_length = strlen(spr.myname)+1; 415 set_auth = 1; 416 } else if (startswith(arg, "myauthsecret=") || startswith(arg, "myauthkey=")) { 417 spr.mysecret = arg + off; 418 spr.mysecret_length = strlen(spr.mysecret)+1; 419 set_auth = 1; 420 } else if (startswith(arg, "hisauthproto=")) { 421 cp = arg + off; 422 if (strcmp(cp, "pap") == 0) 423 spr.hisauth = SPPP_AUTHPROTO_PAP; 424 else if (strcmp(cp, "chap") == 0) 425 spr.hisauth = SPPP_AUTHPROTO_CHAP; 426 else if (strcmp(cp, "none") == 0) 427 spr.hisauth = SPPP_AUTHPROTO_NONE; 428 else 429 errx(EX_DATAERR, "bad auth proto: %s", cp); 430 set_auth = 1; 431 } else if (startswith(arg, "hisauthname=")) { 432 spr.hisname = arg + off; 433 spr.hisname_length = strlen(spr.hisname)+1; 434 set_auth = 1; 435 } else if (startswith(arg, "hisauthsecret=") || startswith(arg, "hisauthkey=")) { 436 spr.hissecret = arg + off; 437 spr.hissecret_length = strlen(spr.hissecret)+1; 438 set_auth = 1; 439 } else if (startswith(arg, "max-noreceive=")) { 440 max_noreceive = atoi(arg+off); 441 if (max_noreceive < 0) { 442 fprintf(stderr, 443 "max-noreceive value must be at least 0\n"); 444 max_noreceive = -1; 445 } else { 446 set_keepalive = 1; 447 } 448 } else if (startswith(arg, "max-alive-missed=")) { 449 maxalive = atoi(arg+off); 450 if (maxalive < 0) { 451 fprintf(stderr, 452 "max-alive-missed value must be at least 0\n"); 453 maxalive = -1; 454 } else { 455 set_keepalive = 1; 456 } 457 } else if (strcmp(arg, "callin") == 0) 458 spr.hisauthflags |= SPPP_AUTHFLAG_NOCALLOUT; 459 else if (strcmp(arg, "always") == 0) 460 spr.hisauthflags &= ~SPPP_AUTHFLAG_NOCALLOUT; 461 else if (strcmp(arg, "norechallenge") == 0) 462 spr.hisauthflags |= SPPP_AUTHFLAG_NORECHALLENGE; 463 else if (strcmp(arg, "rechallenge") == 0) 464 spr.hisauthflags &= ~SPPP_AUTHFLAG_NORECHALLENGE; 465 #ifndef __NetBSD__ 466 else if (strcmp(arg, "enable-vj") == 0) 467 spr.defs.enable_vj = 1; 468 else if (strcmp(arg, "disable-vj") == 0) 469 spr.defs.enable_vj = 0; 470 #endif 471 else if (startswith(arg, "lcp-timeout=")) { 472 int timeout_arg = atoi(arg+off); 473 if ((timeout_arg > 20000) || (timeout_arg <= 0)) 474 errx(EX_DATAERR, "bad lcp timeout value: %s", 475 arg+off); 476 lcp.lcp_timeout = timeout_arg * hz / 1000; 477 set_lcp = 1; 478 } else if (startswith(arg, "idle-timeout=")) { 479 timeout.idle_seconds = (time_t)atol(arg+off); 480 set_idle_to = 1; 481 } else if (startswith(arg, "max-auth-failure=")) { 482 authfailset.max_failures = atoi(arg+off); 483 set_auth_failure = 1; 484 } else if (strcmp(arg, "clear-auth-failure") == 0) { 485 clear_auth_failure_count = 1; 486 } else if (startswith(arg, "query-dns=")) { 487 dnssettings.query_dns = atoi(arg+off); 488 set_dns = 1; 489 } else 490 errx(EX_DATAERR, "bad parameter: \"%s\"", arg); 491 } 492 493 static void 494 usage(void) 495 { 496 const char * prog = getprogname(); 497 fprintf(stderr, 498 "usage:\n" 499 " %s [-f config] ifname [...]\n" 500 " %s [-v] ifname [{my|his}auth{proto|name|secret}=...] \\\n" 501 " [callin] [always] [{no}rechallenge]\n" 502 " [query-dns=3]\n" 503 " to set authentication names, passwords\n" 504 " and (optional) paramaters\n" 505 " %s [-v] ifname lcp-timeout=ms|idle-timeout=s|\n" 506 " max-noreceive=s|max-alive-missed=cnt|\n" 507 " max-auth-failure=count|clear-auth-failure\n" 508 " to set general parameters\n" 509 " or\n" 510 " %s -e ethernet-ifname ifname\n" 511 " to connect an ethernet interface for PPPoE\n" 512 " %s [-a access-concentrator-name] [-s service-name] ifname\n" 513 " to specify (optional) data for PPPoE sessions\n" 514 " %s -d ifname\n" 515 " to dump the current PPPoE session state\n" 516 " %s -n (1|2) ifname\n" 517 " to print DNS addresses retrieved via query-dns\n" 518 , prog, prog, prog, prog, prog, prog, prog); 519 exit(EX_USAGE); 520 } 521 522 static void 523 print_vals(const char *ifname, int phase, struct spppauthcfg *sp, int lcp_timeout, 524 time_t idle_timeout, int authfailures, int max_auth_failures, 525 u_int maxalive_cnt, time_t max_noreceive_time) 526 { 527 #ifndef __NetBSD__ 528 time_t send, recv; 529 #endif 530 531 printf("%s:\tphase=%s\n", ifname, phase_name(phase)); 532 if (sp->myauth) { 533 printf("\tmyauthproto=%s myauthname=\"%s\"\n", 534 proto_name(sp->myauth), 535 sp->myname); 536 } 537 if (sp->hisauth) { 538 printf("\thisauthproto=%s hisauthname=\"%s\"%s\n", 539 proto_name(sp->hisauth), 540 sp->hisname, 541 authflags(sp->hisauthflags)); 542 } 543 #ifndef __NetBSD__ 544 if (sp->defs.pp_phase > PHASE_DEAD) { 545 send = time(NULL) - sp->defs.pp_last_sent; 546 recv = time(NULL) - sp->defs.pp_last_recv; 547 printf("\tidle_time=%ld\n", (send<recv)? send : recv); 548 } 549 #endif 550 551 printf("\tlcp timeout: %.3f s\n", 552 (double)lcp_timeout / hz); 553 554 if (idle_timeout != 0) 555 printf("\tidle timeout = %lu s\n", (unsigned long)idle_timeout); 556 else 557 printf("\tidle timeout = disabled\n"); 558 559 if (authfailures != 0) 560 printf("\tauthentication failures = %d\n", authfailures); 561 printf("\tmax-auth-failure = %d\n", max_auth_failures); 562 563 printf("\tmax-noreceive = %ld seconds\n", (long)max_noreceive_time); 564 printf("\tmax-alive-missed = %u unanswered echo requests\n", maxalive_cnt); 565 566 #ifndef __NetBSD__ 567 printf("\tenable_vj: %s\n", 568 sp->defs.enable_vj ? "on" : "off"); 569 #endif 570 } 571 572 const char * 573 phase_name(int phase) 574 { 575 switch (phase) { 576 case SPPP_PHASE_DEAD: return "dead"; 577 case SPPP_PHASE_ESTABLISH: return "establish"; 578 case SPPP_PHASE_TERMINATE: return "terminate"; 579 case SPPP_PHASE_AUTHENTICATE: return "authenticate"; 580 case SPPP_PHASE_NETWORK: return "network"; 581 } 582 return "illegal"; 583 } 584 585 const char * 586 proto_name(int proto) 587 { 588 static char buf[12]; 589 switch (proto) { 590 case SPPP_AUTHPROTO_PAP: return "pap"; 591 case SPPP_AUTHPROTO_CHAP: return "chap"; 592 case SPPP_AUTHPROTO_NONE: return "none"; 593 } 594 snprintf(buf, sizeof(buf), "0x%x", (unsigned)proto); 595 return buf; 596 } 597 598 const char * 599 authflags(int flags) 600 { 601 static char buf[32]; 602 buf[0] = '\0'; 603 if (flags & SPPP_AUTHFLAG_NOCALLOUT) 604 strlcat(buf, " callin", sizeof(buf)); 605 if (flags & SPPP_AUTHFLAG_NORECHALLENGE) 606 strlcat(buf, " norechallenge", sizeof(buf)); 607 return buf; 608 } 609 610 static void 611 print_error(const char *ifname, int error, const char * str) 612 { 613 if (error == -1) 614 fprintf(stderr, "%s: interface not found\n", ifname); 615 else 616 fprintf(stderr, "%s: %s: %s\n", ifname, str, strerror(error)); 617 exit(EX_DATAERR); 618 } 619 620 621