1 #include <u.h> 2 #include <libc.h> 3 #include <auth.h> 4 #include <bio.h> 5 #include <ip.h> 6 #include <libsec.h> 7 #include <ndb.h> 8 #include "ppp.h" 9 10 #define PATH 128 11 12 static int baud; 13 static int nocompress; 14 static int pppframing = 1; 15 static int noipcompress; 16 static int server; 17 static int nip; /* number of ip interfaces */ 18 static int dying; /* flag to signal to all threads its time to go */ 19 static int primary; /* this is the primary IP interface */ 20 static char *chatfile; 21 22 int debug; 23 char* LOG = "ppp"; 24 char* keyspec = ""; 25 26 enum 27 { 28 Rmagic= 0x12345 29 }; 30 31 /* 32 * Calculate FCS - rfc 1331 33 */ 34 ushort fcstab[256] = 35 { 36 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 37 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 38 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 39 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, 40 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 41 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 42 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, 43 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, 44 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, 45 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 46 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, 47 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 48 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 49 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, 50 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 51 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, 52 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 53 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, 54 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 55 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 56 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, 57 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 58 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, 59 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 60 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, 61 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 62 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 63 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, 64 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 65 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, 66 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 67 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 68 }; 69 70 static char *snames[] = 71 { 72 "Sclosed", 73 "Sclosing", 74 "Sreqsent", 75 "Sackrcvd", 76 "Sacksent", 77 "Sopened", 78 }; 79 80 static void authtimer(PPP*); 81 static void chapinit(PPP*); 82 static void config(PPP*, Pstate*, int); 83 static uchar* escapeuchar(PPP*, ulong, uchar*, ushort*); 84 static void getchap(PPP*, Block*); 85 static Block* getframe(PPP*, int*); 86 static void getlqm(PPP*, Block*); 87 static int getopts(PPP*, Pstate*, Block*); 88 static void getpap(PPP*, Block*); 89 static void init(PPP*); 90 static void invalidate(Ipaddr); 91 static void ipinproc(PPP*); 92 static char* ipopen(PPP*); 93 static void mediainproc(PPP*); 94 static void newstate(PPP*, Pstate*, int); 95 static int nipifcs(char*); 96 static void papinit(PPP*); 97 static void pinit(PPP*, Pstate*); 98 static void ppptimer(PPP*); 99 static void printopts(Pstate*, Block*, int); 100 static void ptimer(PPP*, Pstate*); 101 static int putframe(PPP*, int, Block*); 102 static void putlqm(PPP*); 103 static void putndb(PPP*, char*); 104 static void putpaprequest(PPP*); 105 static void rcv(PPP*, Pstate*, Block*); 106 static void rejopts(PPP*, Pstate*, Block*, int); 107 static void sendechoreq(PPP*, Pstate*); 108 static void sendtermreq(PPP*, Pstate*); 109 static void setphase(PPP*, int); 110 static void terminate(PPP*, int); 111 static int validv4(Ipaddr); 112 static void dmppkt(char *s, uchar *a, int na); 113 static void getauth(PPP*); 114 115 void 116 pppopen(PPP *ppp, int mediain, int mediaout, char *net, 117 Ipaddr ipaddr, Ipaddr remip, 118 int mtu, int framing) 119 { 120 ppp->ipfd = -1; 121 ppp->ipcfd = -1; 122 invalidate(ppp->remote); 123 invalidate(ppp->local); 124 invalidate(ppp->curremote); 125 invalidate(ppp->curlocal); 126 invalidate(ppp->dns[0]); 127 invalidate(ppp->dns[1]); 128 invalidate(ppp->wins[0]); 129 invalidate(ppp->wins[1]); 130 131 ppp->mediain = mediain; 132 ppp->mediaout = mediaout; 133 if(validv4(remip)){ 134 ipmove(ppp->remote, remip); 135 ppp->remotefrozen = 1; 136 } 137 if(validv4(ipaddr)){ 138 ipmove(ppp->local, ipaddr); 139 ppp->localfrozen = 1; 140 } 141 ppp->mtu = Defmtu; 142 ppp->mru = mtu; 143 ppp->framing = framing; 144 ppp->net = net; 145 146 init(ppp); 147 switch(rfork(RFPROC|RFMEM|RFNOWAIT)){ 148 case -1: 149 sysfatal("forking mediainproc"); 150 case 0: 151 mediainproc(ppp); 152 terminate(ppp, 1); 153 _exits(0); 154 } 155 } 156 157 static void 158 init(PPP* ppp) 159 { 160 if(ppp->inbuf == nil){ 161 ppp->inbuf = allocb(4096); 162 if(ppp->inbuf == nil) 163 abort(); 164 165 ppp->outbuf = allocb(4096); 166 if(ppp->outbuf == nil) 167 abort(); 168 169 ppp->lcp = mallocz(sizeof(*ppp->lcp), 1); 170 if(ppp->lcp == nil) 171 abort(); 172 ppp->lcp->proto = Plcp; 173 ppp->lcp->state = Sclosed; 174 175 ppp->ccp = mallocz(sizeof(*ppp->ccp), 1); 176 if(ppp->ccp == nil) 177 abort(); 178 ppp->ccp->proto = Pccp; 179 ppp->ccp->state = Sclosed; 180 181 ppp->ipcp = mallocz(sizeof(*ppp->ipcp), 1); 182 if(ppp->ipcp == nil) 183 abort(); 184 ppp->ipcp->proto = Pipcp; 185 ppp->ipcp->state = Sclosed; 186 187 ppp->chap = mallocz(sizeof(*ppp->chap), 1); 188 if(ppp->chap == nil) 189 abort(); 190 ppp->chap->proto = APmschap; 191 ppp->chap->state = Cunauth; 192 auth_freechal(ppp->chap->cs); 193 ppp->chap->cs = nil; 194 195 switch(rfork(RFPROC|RFMEM|RFNOWAIT)){ 196 case -1: 197 sysfatal("forking ppptimer"); 198 case 0: 199 ppptimer(ppp); 200 _exits(0); 201 } 202 } 203 204 ppp->ctcp = compress_init(ppp->ctcp); 205 pinit(ppp, ppp->lcp); 206 setphase(ppp, Plink); 207 } 208 209 static void 210 setphase(PPP *ppp, int phase) 211 { 212 int oldphase; 213 214 oldphase = ppp->phase; 215 216 ppp->phase = phase; 217 switch(phase){ 218 default: 219 sysfatal("ppp: unknown phase %d", phase); 220 case Pdead: 221 /* restart or exit? */ 222 pinit(ppp, ppp->lcp); 223 setphase(ppp, Plink); 224 break; 225 case Plink: 226 /* link down */ 227 switch(oldphase) { 228 case Pauth: 229 auth_freechal(ppp->chap->cs); 230 ppp->chap->cs = nil; 231 ppp->chap->state = Cunauth; 232 break; 233 case Pnet: 234 auth_freechal(ppp->chap->cs); 235 ppp->chap->cs = nil; 236 ppp->chap->state = Cunauth; 237 newstate(ppp, ppp->ccp, Sclosed); 238 newstate(ppp, ppp->ipcp, Sclosed); 239 } 240 break; 241 case Pauth: 242 if(server) 243 chapinit(ppp); 244 else if(ppp->chap->proto == APpasswd) 245 papinit(ppp); 246 else 247 setphase(ppp, Pnet); 248 break; 249 case Pnet: 250 pinit(ppp, ppp->ccp); 251 pinit(ppp, ppp->ipcp); 252 break; 253 case Pterm: 254 /* what? */ 255 break; 256 } 257 } 258 259 static void 260 pinit(PPP *ppp, Pstate *p) 261 { 262 p->timeout = 0; 263 264 switch(p->proto){ 265 case Plcp: 266 ppp->magic = truerand(); 267 ppp->xctlmap = 0xffffffff; 268 ppp->period = 0; 269 p->optmask = 0xffffffff; 270 if(!server) 271 p->optmask &= ~(Fauth|Fmtu); 272 ppp->rctlmap = 0; 273 ppp->ipcp->state = Sclosed; 274 ppp->ipcp->optmask = 0xffffffff; 275 276 p->echotimeout = 0; 277 278 /* quality goo */ 279 ppp->timeout = 0; 280 memset(&ppp->in, 0, sizeof(ppp->in)); 281 memset(&ppp->out, 0, sizeof(ppp->out)); 282 memset(&ppp->pin, 0, sizeof(ppp->pin)); 283 memset(&ppp->pout, 0, sizeof(ppp->pout)); 284 memset(&ppp->sin, 0, sizeof(ppp->sin)); 285 break; 286 case Pccp: 287 if(nocompress) 288 p->optmask = 0; 289 else 290 p->optmask = Fcmppc; 291 292 if(ppp->ctype != nil) 293 (*ppp->ctype->fini)(ppp->cstate); 294 ppp->ctype = nil; 295 ppp->ctries = 0; 296 ppp->cstate = nil; 297 298 if(ppp->unctype) 299 (*ppp->unctype->fini)(ppp->uncstate); 300 ppp->unctype = nil; 301 ppp->uncstate = nil; 302 break; 303 case Pipcp: 304 p->optmask = 0xffffffff; 305 ppp->ctcp = compress_init(ppp->ctcp); 306 break; 307 } 308 p->confid = p->rcvdconfid = -1; 309 config(ppp, p, 1); 310 newstate(ppp, p, Sreqsent); 311 } 312 313 /* 314 * change protocol to a new state. 315 */ 316 static void 317 newstate(PPP *ppp, Pstate *p, int state) 318 { 319 char *err; 320 321 netlog("ppp: %ux %s->%s ctlmap %lux/%lux flags %lux mtu %ld mru %ld\n", 322 p->proto, snames[p->state], snames[state], ppp->rctlmap, 323 ppp->xctlmap, p->flags, 324 ppp->mtu, ppp->mru); 325 syslog(0, "ppp", "%ux %s->%s ctlmap %lux/%lux flags %lux mtu %ld mru %ld", 326 p->proto, snames[p->state], snames[state], ppp->rctlmap, 327 ppp->xctlmap, p->flags, 328 ppp->mtu, ppp->mru); 329 330 if(p->proto == Plcp) { 331 if(state == Sopened) 332 setphase(ppp, Pauth); 333 else if(state == Sclosed) 334 setphase(ppp, Pdead); 335 else if(p->state == Sopened) 336 setphase(ppp, Plink); 337 } 338 339 if(p->proto == Pccp && state == Sopened) { 340 if(ppp->unctype) 341 (*ppp->unctype->fini)(ppp->uncstate); 342 ppp->unctype = nil; 343 ppp->uncstate = nil; 344 if(p->optmask & Fcmppc) { 345 ppp->unctype = &uncmppc; 346 ppp->uncstate = (*uncmppc.init)(ppp); 347 } 348 if(p->optmask & Fcthwack){ 349 ppp->unctype = &uncthwack; 350 ppp->uncstate = (*uncthwack.init)(ppp); 351 } 352 } 353 354 if(p->proto == Pipcp && state == Sopened) { 355 if(server && ppp->chap->state != Cauthok) 356 abort(); 357 358 err = ipopen(ppp); 359 if(err != nil) 360 sysfatal("%s", err); 361 } 362 363 p->state = state; 364 } 365 366 /* returns (protocol, information) */ 367 static Block* 368 getframe(PPP *ppp, int *protop) 369 { 370 uchar *p, *from, *to; 371 int n, len, proto; 372 ulong c; 373 ushort fcs; 374 Block *buf, *b; 375 376 *protop = 0; 377 if(ppp->framing == 0) { 378 /* assume data is already framed */ 379 b = allocb(2000); 380 len = b->lim - b->wptr; 381 n = read(ppp->mediain, b->wptr, len); 382 dmppkt("RX", b->wptr, n); 383 if(n <= 0 || n == len){ 384 freeb(b); 385 386 return nil; 387 } 388 b->wptr += n; 389 390 /* should probably copy to another block if small */ 391 392 if(pppframing && b->rptr[0] == PPP_addr && b->rptr[1] == PPP_ctl) 393 b->rptr += 2; 394 proto = *b->rptr++; 395 if((proto & 0x1) == 0) 396 proto = (proto<<8) | *b->rptr++; 397 398 if(b->rptr >= b->wptr){ 399 freeb(b); 400 return nil; 401 } 402 403 ppp->in.uchars += n; 404 ppp->in.packets++; 405 *protop = proto; 406 netlog("getframe 0x%x\n", proto); 407 return b; 408 } 409 410 buf = ppp->inbuf; 411 for(;;){ 412 /* read till we hit a frame uchar or run out of room */ 413 for(p = buf->rptr; buf->wptr < buf->lim;){ 414 for(; p < buf->wptr; p++) 415 if(*p == HDLC_frame) 416 break; 417 if(p != buf->wptr) 418 break; 419 420 len = buf->lim - buf->wptr; 421 n = read(ppp->mediain, buf->wptr, len); 422 if(n <= 0){ 423 syslog(0, LOG, "medium read returns %d: %r", n); 424 buf->wptr = buf->rptr; 425 return nil; 426 } 427 dmppkt("RX", buf->wptr, n); 428 buf->wptr += n; 429 } 430 431 /* copy into block, undoing escapes, and caculating fcs */ 432 fcs = PPP_initfcs; 433 b = allocb(p - buf->rptr); 434 to = b->wptr; 435 for(from = buf->rptr; from != p;){ 436 c = *from++; 437 if(c == HDLC_esc){ 438 if(from == p) 439 break; 440 c = *from++ ^ 0x20; 441 } else if((c < 0x20) && (ppp->rctlmap & (1 << c))) 442 continue; 443 *to++ = c; 444 fcs = (fcs >> 8) ^ fcstab[(fcs ^ c) & 0xff]; 445 } 446 447 /* copy down what's left in buffer */ 448 p++; 449 memmove(buf->rptr, p, buf->wptr - p); 450 n = p - buf->rptr; 451 buf->wptr -= n; 452 b->wptr = to - 2; 453 454 /* return to caller if checksum matches */ 455 if(fcs == PPP_goodfcs){ 456 if(b->rptr[0] == PPP_addr && b->rptr[1] == PPP_ctl) 457 b->rptr += 2; 458 proto = *b->rptr++; 459 if((proto & 0x1) == 0) 460 proto = (proto<<8) | *b->rptr++; 461 if(b->rptr < b->wptr){ 462 ppp->in.uchars += n; 463 ppp->in.packets++; 464 *protop = proto; 465 netlog("getframe 0x%x\n", proto); 466 return b; 467 } 468 } else if(BLEN(b) > 0){ 469 if(ppp->ctcp) 470 compress_error(ppp->ctcp); 471 ppp->in.discards++; 472 netlog("ppp: discard len %ld/%ld cksum %ux (%ux %ux %ux %ux)\n", 473 BLEN(b), BLEN(buf), fcs, b->rptr[0], 474 b->rptr[1], b->rptr[2], b->rptr[3]); 475 } 476 477 freeb(b); 478 } 479 } 480 481 /* send a PPP frame */ 482 static int 483 putframe(PPP *ppp, int proto, Block *b) 484 { 485 Block *buf; 486 uchar *to, *from; 487 ushort fcs; 488 ulong ctlmap; 489 uchar c; 490 Block *bp; 491 492 ppp->out.packets++; 493 494 if(proto == Plcp) 495 ctlmap = 0xffffffff; 496 else 497 ctlmap = ppp->xctlmap; 498 499 /* make sure we have head room */ 500 if(b->rptr - b->base < 4){ 501 b = padb(b, 4); 502 b->rptr += 4; 503 } 504 505 netlog("ppp: putframe 0x%ux %ld\n", proto, b->wptr-b->rptr); 506 507 /* add in the protocol and address, we'd better have left room */ 508 from = b->rptr; 509 *--from = proto; 510 if(!(ppp->lcp->flags&Fpc) || proto > 0x100 || proto == Plcp) 511 *--from = proto>>8; 512 if(pppframing && (!(ppp->lcp->flags&Fac) || proto == Plcp)){ 513 *--from = PPP_ctl; 514 *--from = PPP_addr; 515 } 516 517 qlock(&ppp->outlock); 518 buf = ppp->outbuf; 519 520 if(ppp->framing == 0) { 521 to = buf->rptr; 522 for(bp = b; bp; bp = bp->next){ 523 if(bp != b) 524 from = bp->rptr; 525 memmove(to, from, bp->wptr-from); 526 to += bp->wptr-from; 527 } 528 } else { 529 /* escape and checksum the body */ 530 fcs = PPP_initfcs; 531 to = buf->rptr; 532 533 /* add frame marker */ 534 *to++ = HDLC_frame; 535 536 for(bp = b; bp; bp = bp->next){ 537 if(bp != b) 538 from = bp->rptr; 539 for(; from < bp->wptr; from++){ 540 c = *from; 541 if(c == HDLC_frame || c == HDLC_esc 542 || (c < 0x20 && ((1<<c) & ctlmap))){ 543 *to++ = HDLC_esc; 544 *to++ = c ^ 0x20; 545 } else 546 *to++ = c; 547 fcs = (fcs >> 8) ^ fcstab[(fcs ^ c) & 0xff]; 548 } 549 } 550 551 /* add on and escape the checksum */ 552 fcs = ~fcs; 553 c = fcs; 554 if(c == HDLC_frame || c == HDLC_esc 555 || (c < 0x20 && ((1<<c) & ctlmap))){ 556 *to++ = HDLC_esc; 557 *to++ = c ^ 0x20; 558 } else 559 *to++ = c; 560 c = fcs>>8; 561 if(c == HDLC_frame || c == HDLC_esc 562 || (c < 0x20 && ((1<<c) & ctlmap))){ 563 *to++ = HDLC_esc; 564 *to++ = c ^ 0x20; 565 } else 566 *to++ = c; 567 568 /* add frame marker */ 569 *to++ = HDLC_frame; 570 } 571 572 /* send */ 573 buf->wptr = to; 574 dmppkt("TX", buf->rptr, BLEN(buf)); 575 if(write(ppp->mediaout, buf->rptr, BLEN(buf)) < 0){ 576 qunlock(&ppp->outlock); 577 return -1; 578 } 579 ppp->out.uchars += BLEN(buf); 580 581 qunlock(&ppp->outlock); 582 return 0; 583 } 584 585 Block* 586 alloclcp(int code, int id, int len, Lcpmsg **mp) 587 { 588 Block *b; 589 Lcpmsg *m; 590 591 /* 592 * leave room for header 593 */ 594 b = allocb(len); 595 596 m = (Lcpmsg*)b->wptr; 597 m->code = code; 598 m->id = id; 599 b->wptr += 4; 600 601 *mp = m; 602 return b; 603 } 604 605 606 static void 607 putlo(Block *b, int type, ulong val) 608 { 609 *b->wptr++ = type; 610 *b->wptr++ = 6; 611 hnputl(b->wptr, val); 612 b->wptr += 4; 613 } 614 615 static void 616 putv4o(Block *b, int type, Ipaddr val) 617 { 618 *b->wptr++ = type; 619 *b->wptr++ = 6; 620 v6tov4(b->wptr, val); 621 b->wptr += 4; 622 } 623 624 static void 625 putso(Block *b, int type, ulong val) 626 { 627 *b->wptr++ = type; 628 *b->wptr++ = 4; 629 hnputs(b->wptr, val); 630 b->wptr += 2; 631 } 632 633 static void 634 puto(Block *b, int type) 635 { 636 *b->wptr++ = type; 637 *b->wptr++ = 2; 638 } 639 640 /* 641 * send configuration request 642 */ 643 static void 644 config(PPP *ppp, Pstate *p, int newid) 645 { 646 Block *b; 647 Lcpmsg *m; 648 int id; 649 650 if(newid){ 651 id = p->id++; 652 p->confid = id; 653 p->timeout = Timeout; 654 } else 655 id = p->confid; 656 b = alloclcp(Lconfreq, id, 256, &m); 657 USED(m); 658 659 switch(p->proto){ 660 case Plcp: 661 if(p->optmask & Fctlmap) 662 putlo(b, Octlmap, 0); /* we don't want anything escaped */ 663 if(p->optmask & Fmagic) 664 putlo(b, Omagic, ppp->magic); 665 if(p->optmask & Fmtu) 666 putso(b, Omtu, ppp->mru); 667 if(p->optmask & Fauth) { 668 *b->wptr++ = Oauth; 669 *b->wptr++ = 5; 670 hnputs(b->wptr, Pchap); 671 b->wptr += 2; 672 *b->wptr++ = ppp->chap->proto; 673 } 674 if(p->optmask & Fpc) 675 puto(b, Opc); 676 if(p->optmask & Fac) 677 puto(b, Oac); 678 break; 679 case Pccp: 680 if(p->optmask & Fcthwack) 681 puto(b, Octhwack); 682 else if(p->optmask & Fcmppc) { 683 *b->wptr++ = Ocmppc; 684 *b->wptr++ = 6; 685 *b->wptr++ = 0; 686 *b->wptr++ = 0; 687 *b->wptr++ = 0; 688 *b->wptr++ = 0x41; 689 } 690 break; 691 case Pipcp: 692 if(p->optmask & Fipaddr) 693 {syslog(0, "ppp", "requesting %I", ppp->local); 694 putv4o(b, Oipaddr, ppp->local); 695 } 696 if(primary && (p->optmask & Fipdns)) 697 putv4o(b, Oipdns, ppp->dns[0]); 698 if(primary && (p->optmask & Fipdns2)) 699 putv4o(b, Oipdns2, ppp->dns[1]); 700 if(primary && (p->optmask & Fipwins)) 701 putv4o(b, Oipwins, ppp->wins[0]); 702 if(primary && (p->optmask & Fipwins2)) 703 putv4o(b, Oipwins2, ppp->wins[1]); 704 /* 705 * don't ask for header compression while data compression is still pending. 706 * perhaps we should restart ipcp negotiation if compression negotiation fails. 707 */ 708 if(!noipcompress && !ppp->ccp->optmask && (p->optmask & Fipcompress)) { 709 *b->wptr++ = Oipcompress; 710 *b->wptr++ = 6; 711 hnputs(b->wptr, Pvjctcp); 712 b->wptr += 2; 713 *b->wptr++ = MAX_STATES-1; 714 *b->wptr++ = 1; 715 } 716 break; 717 } 718 hnputs(m->len, BLEN(b)); 719 printopts(p, b, 1); 720 putframe(ppp, p->proto, b); 721 freeb(b); 722 } 723 724 static void 725 getipinfo(PPP *ppp) 726 { 727 char *av[3]; 728 int ndns, nwins; 729 char ip[64]; 730 Ndbtuple *t, *nt; 731 732 if(!validv4(ppp->local)) 733 return; 734 735 av[0] = "dns"; 736 av[1] = "wins"; 737 sprint(ip, "%I", ppp->local); 738 t = csipinfo(ppp->net, "ip", ip, av, 2); 739 ndns = nwins = 0; 740 for(nt = t; nt != nil; nt = nt->entry){ 741 if(strcmp(nt->attr, "dns") == 0){ 742 if(ndns < 2) 743 parseip(ppp->dns[ndns++], nt->val); 744 } else if(strcmp(nt->attr, "wins") == 0){ 745 if(nwins < 2) 746 parseip(ppp->wins[nwins++], nt->val); 747 } 748 } 749 if(t != nil) 750 ndbfree(t); 751 } 752 753 /* 754 * parse configuration request, sends an ack or reject packet 755 * 756 * returns: -1 if request was syntacticly incorrect 757 * 0 if packet was accepted 758 * 1 if packet was rejected 759 */ 760 static int 761 getopts(PPP *ppp, Pstate *p, Block *b) 762 { 763 Lcpmsg *m, *repm; 764 Lcpopt *o; 765 uchar *cp, *ap; 766 ulong rejecting, nacking, flags, proto, chapproto; 767 ulong mtu, ctlmap, period; 768 ulong x; 769 Block *repb; 770 Comptype *ctype; 771 Ipaddr ipaddr; 772 773 rejecting = 0; 774 nacking = 0; 775 flags = 0; 776 777 /* defaults */ 778 invalidate(ipaddr); 779 mtu = ppp->mtu; 780 ctlmap = 0xffffffff; 781 period = 0; 782 ctype = nil; 783 chapproto = 0; 784 785 m = (Lcpmsg*)b->rptr; 786 repb = alloclcp(Lconfack, m->id, BLEN(b), &repm); 787 788 /* copy options into ack packet */ 789 memmove(repm->data, m->data, b->wptr - m->data); 790 repb->wptr += b->wptr - m->data; 791 792 /* look for options we don't recognize or like */ 793 for(cp = m->data; cp < b->wptr; cp += o->len){ 794 o = (Lcpopt*)cp; 795 if(cp + o->len > b->wptr || o->len==0){ 796 freeb(repb); 797 netlog("ppp: bad option length %ux\n", o->type); 798 return -1; 799 } 800 801 switch(p->proto){ 802 case Plcp: 803 switch(o->type){ 804 case Oac: 805 flags |= Fac; 806 continue; 807 case Opc: 808 flags |= Fpc; 809 continue; 810 case Omtu: 811 mtu = nhgets(o->data); 812 continue; 813 case Omagic: 814 if(ppp->magic == nhgetl(o->data)) 815 netlog("ppp: possible loop\n"); 816 continue; 817 case Octlmap: 818 ctlmap = nhgetl(o->data); 819 continue; 820 case Oquality: 821 proto = nhgets(o->data); 822 if(proto != Plqm) 823 break; 824 x = nhgetl(o->data+2)*10; 825 period = (x+Period-1)/Period; 826 continue; 827 case Oauth: 828 proto = nhgets(o->data); 829 if(proto == Ppasswd && !server){ 830 chapproto = APpasswd; 831 continue; 832 } 833 if(proto != Pchap) 834 break; 835 if(o->data[2] != APmd5 && o->data[2] != APmschap) 836 break; 837 chapproto = o->data[2]; 838 continue; 839 } 840 break; 841 case Pccp: 842 if(nocompress) 843 break; 844 switch(o->type){ 845 case Octhwack: 846 break; 847 /* 848 if(o->len == 2){ 849 ctype = &cthwack; 850 continue; 851 } 852 if(!nacking){ 853 nacking = 1; 854 repb->wptr = repm->data; 855 repm->code = Lconfnak; 856 } 857 puto(repb, Octhwack); 858 continue; 859 */ 860 case Ocmppc: 861 x = nhgetl(o->data); 862 863 // hack for Mac 864 // if(x == 0) 865 // continue; 866 867 /* stop ppp loops */ 868 if((x&0x41) == 0 || ppp->ctries++ > 5) { 869 /* 870 * turn off requests as well - I don't think this 871 * is needed in the standard 872 */ 873 p->optmask &= ~Fcmppc; 874 break; 875 } 876 if(rejecting) 877 continue; 878 if(x & 1) { 879 ctype = &cmppc; 880 ppp->sendencrypted = (o->data[3]&0x40) == 0x40; 881 continue; 882 } 883 if(!nacking){ 884 nacking = 1; 885 repb->wptr = repm->data; 886 repm->code = Lconfnak; 887 } 888 *repb->wptr++ = Ocmppc; 889 *repb->wptr++ = 6; 890 *repb->wptr++ = 0; 891 *repb->wptr++ = 0; 892 *repb->wptr++ = 0; 893 *repb->wptr++ = 0x41; 894 continue; 895 } 896 break; 897 case Pipcp: 898 switch(o->type){ 899 case Oipaddr: 900 v4tov6(ipaddr, o->data); 901 if(!validv4(ppp->remote)) 902 continue; 903 if(!validv4(ipaddr) && !rejecting){ 904 /* other side requesting an address */ 905 if(!nacking){ 906 nacking = 1; 907 repb->wptr = repm->data; 908 repm->code = Lconfnak; 909 } 910 putv4o(repb, Oipaddr, ppp->remote); 911 } 912 continue; 913 case Oipdns: 914 ap = ppp->dns[0]; 915 goto ipinfo; 916 case Oipdns2: 917 ap = ppp->dns[1]; 918 goto ipinfo; 919 case Oipwins: 920 ap = ppp->wins[0]; 921 goto ipinfo; 922 case Oipwins2: 923 ap = ppp->wins[1]; 924 goto ipinfo; 925 ipinfo: 926 if(!validv4(ap)) 927 getipinfo(ppp); 928 if(!validv4(ap)) 929 break; 930 v4tov6(ipaddr, o->data); 931 if(!validv4(ipaddr) && !rejecting){ 932 /* other side requesting an address */ 933 if(!nacking){ 934 nacking = 1; 935 repb->wptr = repm->data; 936 repm->code = Lconfnak; 937 } 938 putv4o(repb, o->type, ap); 939 } 940 continue; 941 case Oipcompress: 942 /* 943 * don't compress tcp header if we've negotiated data compression. 944 * tcp header compression has very poor performance if there is an error. 945 */ 946 proto = nhgets(o->data); 947 if(noipcompress || proto != Pvjctcp || ppp->ctype != nil) 948 break; 949 if(compress_negotiate(ppp->ctcp, o->data+2) < 0) 950 break; 951 flags |= Fipcompress; 952 continue; 953 } 954 break; 955 } 956 957 /* come here if option is not recognized */ 958 if(!rejecting){ 959 rejecting = 1; 960 repb->wptr = repm->data; 961 repm->code = Lconfrej; 962 } 963 netlog("ppp: bad %ux option %d\n", p->proto, o->type); 964 memmove(repb->wptr, o, o->len); 965 repb->wptr += o->len; 966 } 967 968 /* permanent changes only after we know that we liked the packet */ 969 if(!rejecting && !nacking){ 970 switch(p->proto){ 971 case Plcp: 972 ppp->period = period; 973 ppp->xctlmap = ctlmap; 974 if(mtu > Maxmtu) 975 mtu = Maxmtu; 976 if(mtu < Minmtu) 977 mtu = Minmtu; 978 ppp->mtu = mtu; 979 if(chapproto) 980 ppp->chap->proto = chapproto; 981 982 break; 983 case Pccp: 984 if(ppp->ctype != nil){ 985 (*ppp->ctype->fini)(ppp->cstate); 986 ppp->cstate = nil; 987 } 988 ppp->ctype = ctype; 989 if(ctype) 990 ppp->cstate = (*ctype->init)(ppp); 991 break; 992 case Pipcp: 993 if(validv4(ipaddr) && ppp->remotefrozen == 0) 994 ipmove(ppp->remote, ipaddr); 995 break; 996 } 997 p->flags = flags; 998 } 999 1000 hnputs(repm->len, BLEN(repb)); 1001 printopts(p, repb, 1); 1002 putframe(ppp, p->proto, repb); 1003 freeb(repb); 1004 1005 return rejecting || nacking; 1006 } 1007 static void 1008 dmppkt(char *s, uchar *a, int na) 1009 { 1010 int i; 1011 1012 if (debug < 3) 1013 return; 1014 1015 fprint(2, "%s", s); 1016 for(i = 0; i < na; i++) 1017 fprint(2, " %.2ux", a[i]); 1018 fprint(2, "\n"); 1019 } 1020 1021 static void 1022 dropoption(Pstate *p, Lcpopt *o) 1023 { 1024 unsigned n = o->type; 1025 1026 switch(n){ 1027 case Oipaddr: 1028 break; 1029 case Oipdns: 1030 p->optmask &= ~Fipdns; 1031 break; 1032 case Oipwins: 1033 p->optmask &= ~Fipwins; 1034 break; 1035 case Oipdns2: 1036 p->optmask &= ~Fipdns2; 1037 break; 1038 case Oipwins2: 1039 p->optmask &= ~Fipwins2; 1040 break; 1041 default: 1042 if(o->type < 8*sizeof(p->optmask)) 1043 p->optmask &= ~(1<<o->type); 1044 break; 1045 } 1046 } 1047 1048 /* 1049 * parse configuration rejection, just stop sending anything that they 1050 * don't like (except for ipcp address nak). 1051 */ 1052 static void 1053 rejopts(PPP *ppp, Pstate *p, Block *b, int code) 1054 { 1055 Lcpmsg *m; 1056 Lcpopt *o; 1057 uchar newip[IPaddrlen]; 1058 1059 /* just give up trying what the other side doesn't like */ 1060 m = (Lcpmsg*)b->rptr; 1061 for(b->rptr = m->data; b->rptr < b->wptr; b->rptr += o->len){ 1062 o = (Lcpopt*)b->rptr; 1063 if(b->rptr + o->len > b->wptr){ 1064 netlog("ppp: bad roption length %ux\n", o->type); 1065 return; 1066 } 1067 1068 if(code == Lconfrej){ 1069 dropoption(p, o); 1070 netlog("ppp: %ux rejecting %d\n", 1071 p->proto, o->type); 1072 continue; 1073 } 1074 1075 switch(p->proto){ 1076 case Plcp: 1077 switch(o->type){ 1078 case Octlmap: 1079 ppp->rctlmap = nhgetl(o->data); 1080 break; 1081 case Oauth: 1082 /* don't allow client to request no auth */ 1083 /* could try different auth protocol here */ 1084 fprint(2, "ppp: can not reject CHAP\n"); 1085 exits("ppp: CHAP"); 1086 break; 1087 default: 1088 if(o->type < 8*sizeof(p->optmask)) 1089 p->optmask &= ~(1<<o->type); 1090 break; 1091 }; 1092 break; 1093 case Pccp: 1094 switch(o->type){ 1095 default: 1096 dropoption(p, o); 1097 break; 1098 } 1099 break; 1100 case Pipcp: 1101 switch(o->type){ 1102 case Oipaddr: 1103 syslog(0, "ppp", "rejected addr %I with %V", ppp->local, o->data); 1104 /* if we're a server, don't let other end change our addr */ 1105 if(ppp->localfrozen){ 1106 dropoption(p, o); 1107 break; 1108 } 1109 1110 /* accept whatever server tells us */ 1111 if(!validv4(ppp->local)){ 1112 v4tov6(ppp->local, o->data); 1113 dropoption(p, o); 1114 break; 1115 } 1116 1117 /* if he didn't like our addr, ask for a generic one */ 1118 v4tov6(newip, o->data); 1119 if(!validv4(newip)){ 1120 invalidate(ppp->local); 1121 break; 1122 } 1123 1124 /* if he gives us something different, use it anyways */ 1125 v4tov6(ppp->local, o->data); 1126 dropoption(p, o); 1127 break; 1128 case Oipdns: 1129 if (!validv4(ppp->dns[0])){ 1130 v4tov6(ppp->dns[0], o->data); 1131 dropoption(p, o); 1132 break; 1133 } 1134 v4tov6(newip, o->data); 1135 if(!validv4(newip)){ 1136 invalidate(ppp->dns[0]); 1137 break; 1138 } 1139 v4tov6(ppp->dns[0], o->data); 1140 dropoption(p, o); 1141 break; 1142 case Oipwins: 1143 if (!validv4(ppp->wins[0])){ 1144 v4tov6(ppp->wins[0], o->data); 1145 dropoption(p, o); 1146 break; 1147 } 1148 v4tov6(newip, o->data); 1149 if(!validv4(newip)){ 1150 invalidate(ppp->wins[0]); 1151 break; 1152 } 1153 v4tov6(ppp->wins[0], o->data); 1154 dropoption(p, o); 1155 break; 1156 case Oipdns2: 1157 if (!validv4(ppp->dns[1])){ 1158 v4tov6(ppp->dns[1], o->data); 1159 dropoption(p, o); 1160 break; 1161 } 1162 v4tov6(newip, o->data); 1163 if(!validv4(newip)){ 1164 invalidate(ppp->dns[1]); 1165 break; 1166 } 1167 v4tov6(ppp->dns[1], o->data); 1168 dropoption(p, o); 1169 break; 1170 case Oipwins2: 1171 if (!validv4(ppp->wins[1])){ 1172 v4tov6(ppp->wins[1], o->data); 1173 dropoption(p, o); 1174 break; 1175 } 1176 v4tov6(newip, o->data); 1177 if(!validv4(newip)){ 1178 invalidate(ppp->wins[1]); 1179 break; 1180 } 1181 v4tov6(ppp->wins[1], o->data); 1182 dropoption(p, o); 1183 break; 1184 default: 1185 dropoption(p, o); 1186 break; 1187 } 1188 break; 1189 } 1190 } 1191 } 1192 1193 1194 /* 1195 * put a messages through the lcp or ipcp state machine. They are 1196 * very similar. 1197 */ 1198 static void 1199 rcv(PPP *ppp, Pstate *p, Block *b) 1200 { 1201 ulong len; 1202 int err; 1203 Lcpmsg *m; 1204 int proto; 1205 1206 if(BLEN(b) < 4){ 1207 netlog("ppp: short lcp message\n"); 1208 freeb(b); 1209 return; 1210 } 1211 m = (Lcpmsg*)b->rptr; 1212 len = nhgets(m->len); 1213 if(BLEN(b) < len){ 1214 netlog("ppp: short lcp message\n"); 1215 freeb(b); 1216 return; 1217 } 1218 1219 netlog("ppp: %ux rcv %d len %ld id %d/%d/%d\n", 1220 p->proto, m->code, len, m->id, p->confid, p->id); 1221 1222 if(p->proto != Plcp && ppp->lcp->state != Sopened){ 1223 netlog("ppp: non-lcp with lcp not open\n"); 1224 freeb(b); 1225 return; 1226 } 1227 1228 qlock(ppp); 1229 switch(m->code){ 1230 case Lconfreq: 1231 printopts(p, b, 0); 1232 err = getopts(ppp, p, b); 1233 if(err < 0) 1234 break; 1235 1236 if(m->id == p->rcvdconfid) 1237 break; /* don't change state for duplicates */ 1238 1239 switch(p->state){ 1240 case Sackrcvd: 1241 if(err) 1242 break; 1243 newstate(ppp, p, Sopened); 1244 break; 1245 case Sclosed: 1246 case Sopened: 1247 config(ppp, p, 1); 1248 if(err == 0) 1249 newstate(ppp, p, Sacksent); 1250 else 1251 newstate(ppp, p, Sreqsent); 1252 break; 1253 case Sreqsent: 1254 case Sacksent: 1255 if(err == 0) 1256 newstate(ppp, p, Sacksent); 1257 else 1258 newstate(ppp, p, Sreqsent); 1259 break; 1260 } 1261 break; 1262 case Lconfack: 1263 if(p->confid != m->id){ 1264 /* ignore if it isn't the message we're sending */ 1265 netlog("ppp: dropping confack\n"); 1266 break; 1267 } 1268 p->confid = -1; /* ignore duplicates */ 1269 p->id++; /* avoid sending duplicates */ 1270 1271 netlog("ppp: recv confack\n"); 1272 switch(p->state){ 1273 case Sopened: 1274 case Sackrcvd: 1275 config(ppp, p, 1); 1276 newstate(ppp, p, Sreqsent); 1277 break; 1278 case Sreqsent: 1279 newstate(ppp, p, Sackrcvd); 1280 break; 1281 case Sacksent: 1282 newstate(ppp, p, Sopened); 1283 break; 1284 } 1285 break; 1286 case Lconfrej: 1287 case Lconfnak: 1288 if(p->confid != m->id) { 1289 /* ignore if it isn't the message we're sending */ 1290 netlog("ppp: dropping confrej or confnak\n"); 1291 break; 1292 } 1293 p->confid = -1; /* ignore duplicates */ 1294 p->id++; /* avoid sending duplicates */ 1295 1296 switch(p->state){ 1297 case Sopened: 1298 case Sackrcvd: 1299 config(ppp, p, 1); 1300 newstate(ppp, p, Sreqsent); 1301 break; 1302 case Sreqsent: 1303 case Sacksent: 1304 printopts(p, b, 0); 1305 rejopts(ppp, p, b, m->code); 1306 config(ppp, p, 1); 1307 break; 1308 } 1309 break; 1310 case Ltermreq: 1311 m->code = Ltermack; 1312 putframe(ppp, p->proto, b); 1313 1314 switch(p->state){ 1315 case Sackrcvd: 1316 case Sacksent: 1317 newstate(ppp, p, Sreqsent); 1318 break; 1319 case Sopened: 1320 newstate(ppp, p, Sclosing); 1321 break; 1322 } 1323 break; 1324 case Ltermack: 1325 if(p->termid != m->id) /* ignore if it isn't the message we're sending */ 1326 break; 1327 1328 if(p->proto == Plcp) 1329 ppp->ipcp->state = Sclosed; 1330 switch(p->state){ 1331 case Sclosing: 1332 newstate(ppp, p, Sclosed); 1333 break; 1334 case Sackrcvd: 1335 newstate(ppp, p, Sreqsent); 1336 break; 1337 case Sopened: 1338 config(ppp, p, 0); 1339 newstate(ppp, p, Sreqsent); 1340 break; 1341 } 1342 break; 1343 case Lcoderej: 1344 //newstate(ppp, p, Sclosed); 1345 syslog(0, LOG, "code reject %d\n", m->data[0]); 1346 break; 1347 case Lprotorej: 1348 proto = nhgets(m->data); 1349 netlog("ppp: proto reject %ux\n", proto); 1350 if(proto == Pccp) 1351 newstate(ppp, ppp->ccp, Sclosed); 1352 break; 1353 case Lechoreq: 1354 if(BLEN(b) < 8){ 1355 netlog("ppp: short lcp echo request\n"); 1356 freeb(b); 1357 return; 1358 } 1359 m->code = Lechoack; 1360 hnputl(m->data, ppp->magic); 1361 putframe(ppp, p->proto, b); 1362 break; 1363 case Lechoack: 1364 p->echoack = 1; 1365 break; 1366 case Ldiscard: 1367 /* nothing to do */ 1368 break; 1369 case Lresetreq: 1370 if(p->proto != Pccp) 1371 break; 1372 ppp->stat.compreset++; 1373 if(ppp->ctype != nil) 1374 b = (*ppp->ctype->resetreq)(ppp->cstate, b); 1375 if(b != nil) { 1376 m = (Lcpmsg*)b->rptr; 1377 m->code = Lresetack; 1378 putframe(ppp, p->proto, b); 1379 } 1380 break; 1381 case Lresetack: 1382 if(p->proto != Pccp) 1383 break; 1384 if(ppp->unctype != nil) 1385 (*ppp->unctype->resetack)(ppp->uncstate, b); 1386 break; 1387 } 1388 1389 qunlock(ppp); 1390 freeb(b); 1391 } 1392 1393 /* 1394 * timer for protocol state machine 1395 */ 1396 static void 1397 ptimer(PPP *ppp, Pstate *p) 1398 { 1399 if(p->state == Sopened || p->state == Sclosed) 1400 return; 1401 1402 p->timeout--; 1403 switch(p->state){ 1404 case Sclosing: 1405 sendtermreq(ppp, p); 1406 break; 1407 case Sreqsent: 1408 case Sacksent: 1409 if(p->timeout <= 0) 1410 newstate(ppp, p, Sclosed); 1411 else { 1412 config(ppp, p, 0); 1413 } 1414 break; 1415 case Sackrcvd: 1416 if(p->timeout <= 0) 1417 newstate(ppp, p, Sclosed); 1418 else { 1419 config(ppp, p, 0); 1420 newstate(ppp, p, Sreqsent); 1421 } 1422 break; 1423 } 1424 } 1425 1426 /* paptimer -- pap timer event handler 1427 * 1428 * If PAP authorization hasn't come through, resend an authreqst. If 1429 * the maximum number of requests have been sent (~ 30 seconds), give 1430 * up. 1431 * 1432 */ 1433 static void 1434 authtimer(PPP* ppp) 1435 { 1436 if(ppp->chap->proto != APpasswd) 1437 return; 1438 1439 if(ppp->chap->id < 21) 1440 putpaprequest(ppp); 1441 else { 1442 terminate(ppp, 0); 1443 netlog("ppp: pap timed out--not authorized\n"); 1444 } 1445 } 1446 1447 1448 /* 1449 * timer for ppp 1450 */ 1451 static void 1452 ppptimer(PPP *ppp) 1453 { 1454 while(!dying){ 1455 sleep(Period); 1456 qlock(ppp); 1457 1458 netlog("ppp: ppptimer\n"); 1459 ptimer(ppp, ppp->lcp); 1460 if(ppp->lcp->state == Sopened) { 1461 switch(ppp->phase){ 1462 case Pnet: 1463 ptimer(ppp, ppp->ccp); 1464 ptimer(ppp, ppp->ipcp); 1465 break; 1466 case Pauth: 1467 authtimer(ppp); 1468 break; 1469 } 1470 } 1471 1472 /* link quality measurement */ 1473 if(ppp->period && --(ppp->timeout) <= 0){ 1474 ppp->timeout = ppp->period; 1475 putlqm(ppp); 1476 } 1477 1478 qunlock(ppp); 1479 } 1480 } 1481 1482 static void 1483 setdefroute(char *net, Ipaddr gate) 1484 { 1485 int fd; 1486 char path[128]; 1487 1488 snprint(path, sizeof path, "%s/iproute", net); 1489 fd = open(path, ORDWR); 1490 if(fd < 0) 1491 return; 1492 fprint(fd, "add 0 0 %I", gate); 1493 close(fd); 1494 } 1495 1496 enum 1497 { 1498 Mofd= 32, 1499 }; 1500 struct 1501 { 1502 Lock; 1503 1504 int fd[Mofd]; 1505 int cfd[Mofd]; 1506 int n; 1507 } old; 1508 1509 static char* 1510 ipopen(PPP *ppp) 1511 { 1512 static int ipinprocpid; 1513 int n, cfd, fd; 1514 char path[128]; 1515 char buf[128]; 1516 1517 if(ipinprocpid <= 0){ 1518 snprint(path, sizeof path, "%s/ipifc/clone", ppp->net); 1519 cfd = open(path, ORDWR); 1520 if(cfd < 0) 1521 return "can't open ip interface"; 1522 1523 n = read(cfd, buf, sizeof(buf) - 1); 1524 if(n <= 0){ 1525 close(cfd); 1526 return "can't open ip interface"; 1527 } 1528 buf[n] = 0; 1529 1530 netlog("ppp: setting up IP interface local %I remote %I (valid %d)\n", 1531 ppp->local, ppp->remote, validv4(ppp->remote)); 1532 if(!validv4(ppp->remote)) 1533 ipmove(ppp->remote, ppp->local); 1534 1535 snprint(path, sizeof path, "%s/ipifc/%s/data", ppp->net, buf); 1536 fd = open(path, ORDWR); 1537 if(fd < 0){ 1538 close(cfd); 1539 return "can't open ip interface"; 1540 } 1541 1542 if(fprint(cfd, "bind pkt") < 0) 1543 return "binding pkt to ip interface"; 1544 if(fprint(cfd, "add %I 255.255.255.255 %I %lud proxy", ppp->local, 1545 ppp->remote, ppp->mtu-10) < 0){ 1546 close(cfd); 1547 return "can't set addresses"; 1548 } 1549 if(primary) 1550 setdefroute(ppp->net, ppp->remote); 1551 ppp->ipfd = fd; 1552 ppp->ipcfd = cfd; 1553 1554 /* signal main() that ip is configured */ 1555 rendezvous((void*)Rmagic, 0); 1556 1557 switch(ipinprocpid = rfork(RFPROC|RFMEM|RFNOWAIT)){ 1558 case -1: 1559 sysfatal("forking ipinproc"); 1560 case 0: 1561 ipinproc(ppp); 1562 terminate(ppp, 1); 1563 _exits(0); 1564 } 1565 } else { 1566 /* we may have changed addresses */ 1567 if(ipcmp(ppp->local, ppp->curlocal) != 0 || 1568 ipcmp(ppp->remote, ppp->curremote) != 0){ 1569 snprint(buf, sizeof buf, "remove %I 255.255.255.255 %I", 1570 ppp->curlocal, ppp->curremote); 1571 if(fprint(ppp->ipcfd, "%s", buf) < 0) 1572 syslog(0, "ppp", "can't %s: %r", buf); 1573 snprint(buf, sizeof buf, "add %I 255.255.255.255 %I %lud proxy", 1574 ppp->local, ppp->remote, ppp->mtu-10); 1575 if(fprint(ppp->ipcfd, "%s", buf) < 0) 1576 syslog(0, "ppp", "can't %s: %r", buf); 1577 } 1578 syslog(0, "ppp", "%I/%I -> %I/%I", ppp->curlocal, ppp->curremote, 1579 ppp->local, ppp->remote); 1580 } 1581 ipmove(ppp->curlocal, ppp->local); 1582 ipmove(ppp->curremote, ppp->remote); 1583 1584 return nil; 1585 } 1586 1587 /* return next input IP packet */ 1588 Block* 1589 pppread(PPP *ppp) 1590 { 1591 Block *b, *reply; 1592 int proto, len; 1593 Lcpmsg *m; 1594 1595 while(!dying){ 1596 b = getframe(ppp, &proto); 1597 if(b == nil) 1598 return nil; 1599 1600 Again: 1601 switch(proto){ 1602 case Plcp: 1603 rcv(ppp, ppp->lcp, b); 1604 break; 1605 case Pccp: 1606 rcv(ppp, ppp->ccp, b); 1607 break; 1608 case Pipcp: 1609 rcv(ppp, ppp->ipcp, b); 1610 break; 1611 case Pip: 1612 if(ppp->ipcp->state == Sopened) 1613 return b; 1614 netlog("ppp: IP recved: link not up\n"); 1615 freeb(b); 1616 break; 1617 case Plqm: 1618 getlqm(ppp, b); 1619 break; 1620 case Pchap: 1621 getchap(ppp, b); 1622 break; 1623 case Ppasswd: 1624 getpap(ppp, b); 1625 break; 1626 case Pvjctcp: 1627 case Pvjutcp: 1628 if(ppp->ipcp->state != Sopened){ 1629 netlog("ppp: VJ tcp recved: link not up\n"); 1630 freeb(b); 1631 break; 1632 } 1633 ppp->stat.vjin++; 1634 b = tcpuncompress(ppp->ctcp, b, proto); 1635 if(b != nil) 1636 return b; 1637 ppp->stat.vjfail++; 1638 break; 1639 case Pcdata: 1640 ppp->stat.uncomp++; 1641 if(ppp->ccp->state != Sopened){ 1642 netlog("ppp: compressed data recved: link not up\n"); 1643 freeb(b); 1644 break; 1645 } 1646 if(ppp->unctype == nil) { 1647 netlog("ppp: compressed data recved: no compression\n"); 1648 freeb(b); 1649 break; 1650 } 1651 len = BLEN(b); 1652 b = (*ppp->unctype->uncompress)(ppp, b, &proto, &reply); 1653 if(reply != nil){ 1654 /* send resetreq */ 1655 ppp->stat.uncompreset++; 1656 putframe(ppp, Pccp, reply); 1657 freeb(reply); 1658 } 1659 if(b == nil) 1660 break; 1661 ppp->stat.uncompin += len; 1662 ppp->stat.uncompout += BLEN(b); 1663 /* netlog("ppp: uncompressed frame %ux %d %d (%d uchars)\n", proto, b->rptr[0], b->rptr[1], BLEN(b)); /* */ 1664 goto Again; 1665 default: 1666 syslog(0, LOG, "unknown proto %ux", proto); 1667 if(ppp->lcp->state == Sopened){ 1668 /* reject the protocol */ 1669 b->rptr -= 6; 1670 m = (Lcpmsg*)b->rptr; 1671 m->code = Lprotorej; 1672 m->id = ++ppp->lcp->id; 1673 hnputs(m->data, proto); 1674 hnputs(m->len, BLEN(b)); 1675 putframe(ppp, Plcp, b); 1676 } 1677 freeb(b); 1678 break; 1679 } 1680 } 1681 return nil; 1682 } 1683 1684 /* transmit an IP packet */ 1685 int 1686 pppwrite(PPP *ppp, Block *b) 1687 { 1688 int proto; 1689 int len; 1690 1691 qlock(ppp); 1692 /* can't send ip packets till we're established */ 1693 if(ppp->ipcp->state != Sopened) { 1694 qunlock(ppp); 1695 syslog(0, LOG, "IP write: link not up"); 1696 len = blen(b); 1697 freeb(b); 1698 return len; 1699 } 1700 1701 proto = Pip; 1702 ppp->stat.ipsend++; 1703 1704 if(ppp->ipcp->flags & Fipcompress){ 1705 b = compress(ppp->ctcp, b, &proto); 1706 if(b == nil){ 1707 qunlock(ppp); 1708 return 0; 1709 } 1710 if(proto != Pip) 1711 ppp->stat.vjout++; 1712 } 1713 1714 if(ppp->ctype != nil) { 1715 len = blen(b); 1716 b = (*ppp->ctype->compress)(ppp, proto, b, &proto); 1717 if(proto == Pcdata) { 1718 ppp->stat.comp++; 1719 ppp->stat.compin += len; 1720 ppp->stat.compout += blen(b); 1721 } 1722 } 1723 1724 if(putframe(ppp, proto, b) < 0) { 1725 qunlock(ppp); 1726 freeb(b); 1727 return -1; 1728 } 1729 qunlock(ppp); 1730 1731 len = blen(b); 1732 freeb(b); 1733 return len; 1734 } 1735 1736 static void 1737 terminate(PPP *ppp, int kill) 1738 { 1739 close(ppp->ipfd); 1740 ppp->ipfd = -1; 1741 close(ppp->ipcfd); 1742 ppp->ipcfd = -1; 1743 close(ppp->mediain); 1744 close(ppp->mediaout); 1745 ppp->mediain = -1; 1746 ppp->mediaout = -1; 1747 dying = 1; 1748 1749 if(kill) 1750 postnote(PNGROUP, getpid(), "die"); 1751 } 1752 1753 typedef struct Iphdr Iphdr; 1754 struct Iphdr 1755 { 1756 uchar vihl; /* Version and header length */ 1757 uchar tos; /* Type of service */ 1758 uchar length[2]; /* packet length */ 1759 uchar id[2]; /* Identification */ 1760 uchar frag[2]; /* Fragment information */ 1761 uchar ttl; /* Time to live */ 1762 uchar proto; /* Protocol */ 1763 uchar cksum[2]; /* Header checksum */ 1764 uchar src[4]; /* Ip source (uchar ordering unimportant) */ 1765 uchar dst[4]; /* Ip destination (uchar ordering unimportant) */ 1766 }; 1767 1768 static void 1769 ipinproc(PPP *ppp) 1770 { 1771 Block *b; 1772 int m, n; 1773 Iphdr *ip; 1774 1775 while(!dying){ 1776 1777 b = allocb(Buflen); 1778 n = read(ppp->ipfd, b->wptr, b->lim-b->wptr); 1779 if(n < 0) 1780 break; 1781 1782 /* trim packet if there's padding (e.g. from ether) */ 1783 ip = (Iphdr*)b->rptr; 1784 m = nhgets(ip->length); 1785 if(m < n && m > 0) 1786 n = m; 1787 b->wptr += n; 1788 1789 if(pppwrite(ppp, b) < 0) 1790 break; 1791 } 1792 } 1793 1794 static void 1795 catchdie(void*, char *msg) 1796 { 1797 if(strstr(msg, "die") != nil) 1798 noted(NCONT); 1799 else 1800 noted(NDFLT); 1801 } 1802 1803 static void 1804 hexdump(uchar *a, int na) 1805 { 1806 int i; 1807 char buf[80]; 1808 1809 fprint(2, "dump %p %d\n", a, na); 1810 buf[0] = '\0'; 1811 for(i=0; i<na; i++){ 1812 sprint(buf+strlen(buf), " %.2ux", a[i]); 1813 if(i%16 == 7) 1814 sprint(buf+strlen(buf), " --"); 1815 if(i%16==15){ 1816 sprint(buf+strlen(buf), "\n"); 1817 write(2, buf, strlen(buf)); 1818 buf[0] = '\0'; 1819 } 1820 } 1821 if(i%16){ 1822 sprint(buf+strlen(buf), "\n"); 1823 write(2, buf, strlen(buf)); 1824 } 1825 } 1826 1827 static void 1828 mediainproc(PPP *ppp) 1829 { 1830 Block *b; 1831 Ipaddr remote; 1832 1833 notify(catchdie); 1834 while(!dying){ 1835 b = pppread(ppp); 1836 if(b == nil){ 1837 syslog(0, LOG, "pppread return nil"); 1838 break; 1839 } 1840 ppp->stat.iprecv++; 1841 if(ppp->ipcp->state != Sopened) { 1842 ppp->stat.iprecvnotup++; 1843 freeb(b); 1844 continue; 1845 } 1846 1847 if(server) { 1848 v4tov6(remote, b->rptr+12); 1849 if(ipcmp(remote, ppp->remote) != 0) { 1850 ppp->stat.iprecvbadsrc++; 1851 freeb(b); 1852 continue; 1853 } 1854 } 1855 if(debug > 1){ 1856 netlog("ip write pkt %p %d\n", b->rptr, blen(b)); 1857 hexdump(b->rptr, blen(b)); 1858 } 1859 if(write(ppp->ipfd, b->rptr, blen(b)) < 0) { 1860 syslog(0, LOG, "error writing to pktifc"); 1861 freeb(b); 1862 break; 1863 } 1864 1865 freeb(b); 1866 } 1867 1868 netlog(": remote=%I: ppp shutting down\n", ppp->remote); 1869 syslog(0, LOG, ": remote=%I: ppp shutting down", ppp->remote); 1870 syslog(0, LOG, "\t\tppp send = %lud/%lud recv= %lud/%lud", 1871 ppp->out.packets, ppp->out.uchars, 1872 ppp->in.packets, ppp->in.uchars); 1873 syslog(0, LOG, "\t\tip send=%lud", ppp->stat.ipsend); 1874 syslog(0, LOG, "\t\tip recv=%lud notup=%lud badsrc=%lud", 1875 ppp->stat.iprecv, ppp->stat.iprecvnotup, ppp->stat.iprecvbadsrc); 1876 syslog(0, LOG, "\t\tcompress=%lud in=%lud out=%lud reset=%lud", 1877 ppp->stat.comp, ppp->stat.compin, ppp->stat.compout, ppp->stat.compreset); 1878 syslog(0, LOG, "\t\tuncompress=%lud in=%lud out=%lud reset=%lud", 1879 ppp->stat.uncomp, ppp->stat.uncompin, ppp->stat.uncompout, 1880 ppp->stat.uncompreset); 1881 syslog(0, LOG, "\t\tvjin=%lud vjout=%lud vjfail=%lud", 1882 ppp->stat.vjin, ppp->stat.vjout, ppp->stat.vjfail); 1883 } 1884 1885 /* 1886 * link quality management 1887 */ 1888 static void 1889 getlqm(PPP *ppp, Block *b) 1890 { 1891 Qualpkt *p; 1892 1893 p = (Qualpkt*)b->rptr; 1894 if(BLEN(b) == sizeof(Qualpkt)){ 1895 ppp->in.reports++; 1896 ppp->pout.reports = nhgetl(p->peeroutreports); 1897 ppp->pout.packets = nhgetl(p->peeroutpackets); 1898 ppp->pout.uchars = nhgetl(p->peeroutuchars); 1899 ppp->pin.reports = nhgetl(p->peerinreports); 1900 ppp->pin.packets = nhgetl(p->peerinpackets); 1901 ppp->pin.discards = nhgetl(p->peerindiscards); 1902 ppp->pin.errors = nhgetl(p->peerinerrors); 1903 ppp->pin.uchars = nhgetl(p->peerinuchars); 1904 1905 /* save our numbers at time of reception */ 1906 memmove(&ppp->sin, &ppp->in, sizeof(Qualstats)); 1907 1908 } 1909 freeb(b); 1910 if(ppp->period == 0) 1911 putlqm(ppp); 1912 1913 } 1914 1915 static void 1916 putlqm(PPP *ppp) 1917 { 1918 Qualpkt *p; 1919 Block *b; 1920 1921 b = allocb(sizeof(Qualpkt)); 1922 b->wptr += sizeof(Qualpkt); 1923 p = (Qualpkt*)b->rptr; 1924 hnputl(p->magic, 0); 1925 1926 /* heresay (what he last told us) */ 1927 hnputl(p->lastoutreports, ppp->pout.reports); 1928 hnputl(p->lastoutpackets, ppp->pout.packets); 1929 hnputl(p->lastoutuchars, ppp->pout.uchars); 1930 1931 /* our numbers at time of last reception */ 1932 hnputl(p->peerinreports, ppp->sin.reports); 1933 hnputl(p->peerinpackets, ppp->sin.packets); 1934 hnputl(p->peerindiscards, ppp->sin.discards); 1935 hnputl(p->peerinerrors, ppp->sin.errors); 1936 hnputl(p->peerinuchars, ppp->sin.uchars); 1937 1938 /* our numbers now */ 1939 hnputl(p->peeroutreports, ppp->out.reports+1); 1940 hnputl(p->peeroutpackets, ppp->out.packets+1); 1941 hnputl(p->peeroutuchars, ppp->out.uchars+53/*hack*/); 1942 1943 putframe(ppp, Plqm, b); 1944 freeb(b); 1945 ppp->out.reports++; 1946 } 1947 1948 /* 1949 * init challenge response dialog 1950 */ 1951 static void 1952 chapinit(PPP *ppp) 1953 { 1954 Block *b; 1955 Lcpmsg *m; 1956 Chap *c; 1957 int len; 1958 char *aproto; 1959 1960 getauth(ppp); 1961 1962 c = ppp->chap; 1963 c->id++; 1964 1965 switch(c->proto){ 1966 default: 1967 abort(); 1968 case APmd5: 1969 aproto = "chap"; 1970 break; 1971 case APmschap: 1972 aproto = "mschap"; 1973 break; 1974 } 1975 if((c->cs = auth_challenge("proto=%q role=server", aproto)) == nil) 1976 sysfatal("auth_challenge: %r"); 1977 syslog(0, LOG, ": remote=%I: sending %d byte challenge", ppp->remote, c->cs->nchal); 1978 len = 4 + 1 + c->cs->nchal + strlen(ppp->chapname); 1979 b = alloclcp(Cchallenge, c->id, len, &m); 1980 1981 *b->wptr++ = c->cs->nchal; 1982 memmove(b->wptr, c->cs->chal, c->cs->nchal); 1983 b->wptr += c->cs->nchal; 1984 memmove(b->wptr, ppp->chapname, strlen(ppp->chapname)); 1985 b->wptr += strlen(ppp->chapname); 1986 hnputs(m->len, len); 1987 putframe(ppp, Pchap, b); 1988 freeb(b); 1989 1990 c->state = Cchalsent; 1991 } 1992 1993 /* 1994 * BUG factotum should do this 1995 */ 1996 enum { 1997 MShashlen = 16, 1998 MSresplen = 24, 1999 MSchallen = 8, 2000 }; 2001 2002 void 2003 desencrypt(uchar data[8], uchar key[7]) 2004 { 2005 ulong ekey[32]; 2006 2007 key_setup(key, ekey); 2008 block_cipher(ekey, data, 0); 2009 } 2010 2011 void 2012 nthash(uchar hash[MShashlen], char *passwd) 2013 { 2014 uchar buf[512]; 2015 int i; 2016 2017 for(i=0; *passwd && i<sizeof(buf); passwd++) { 2018 buf[i++] = *passwd; 2019 buf[i++] = 0; 2020 } 2021 memset(hash, 0, 16); 2022 md4(buf, i, hash, 0); 2023 } 2024 2025 void 2026 mschalresp(uchar resp[MSresplen], uchar hash[MShashlen], uchar chal[MSchallen]) 2027 { 2028 int i; 2029 uchar buf[21]; 2030 2031 memset(buf, 0, sizeof(buf)); 2032 memcpy(buf, hash, MShashlen); 2033 2034 for(i=0; i<3; i++) { 2035 memmove(resp+i*MSchallen, chal, MSchallen); 2036 desencrypt(resp+i*MSchallen, buf+i*7); 2037 } 2038 } 2039 2040 /* 2041 * challenge response dialog 2042 */ 2043 extern int _asrdresp(int, uchar*, int); 2044 2045 static void 2046 getchap(PPP *ppp, Block *b) 2047 { 2048 AuthInfo *ai; 2049 Lcpmsg *m; 2050 int len, vlen, i, id, n, nresp; 2051 char md5buf[512], code; 2052 Chap *c; 2053 Chapreply cr; 2054 MSchapreply mscr; 2055 char uid[PATH]; 2056 uchar digest[16], *p, *resp, sdigest[SHA1dlen]; 2057 uchar mshash[MShashlen], mshash2[MShashlen]; 2058 DigestState *s; 2059 uchar msresp[2*MSresplen+1]; 2060 2061 m = (Lcpmsg*)b->rptr; 2062 len = nhgets(m->len); 2063 if(BLEN(b) < len){ 2064 syslog(0, LOG, "short chap message"); 2065 freeb(b); 2066 return; 2067 } 2068 2069 qlock(ppp); 2070 2071 switch(m->code){ 2072 case Cchallenge: 2073 getauth(ppp); 2074 2075 vlen = m->data[0]; 2076 if(vlen > len - 5) { 2077 netlog("PPP: chap: bad challenge len\n"); 2078 break; 2079 } 2080 2081 id = m->id; 2082 switch(ppp->chap->proto){ 2083 default: 2084 abort(); 2085 case APmd5: 2086 md5buf[0] = m->id; 2087 strcpy(md5buf+1, ppp->secret); 2088 n = strlen(ppp->secret) + 1; 2089 memmove(md5buf+n, m->data+1, vlen); 2090 n += vlen; 2091 md5((uchar*)md5buf, n, digest, nil); 2092 resp = digest; 2093 nresp = 16; 2094 break; 2095 case APmschap: 2096 nthash(mshash, ppp->secret); 2097 memset(msresp, 0, sizeof msresp); 2098 mschalresp(msresp+MSresplen, mshash, m->data+1); 2099 resp = msresp; 2100 nresp = sizeof msresp; 2101 nthash(mshash, ppp->secret); 2102 md4(mshash, 16, mshash2, 0); 2103 s = sha1(mshash2, 16, 0, 0); 2104 sha1(mshash2, 16, 0, s); 2105 sha1(m->data+1, 8, sdigest, s); 2106 memmove(ppp->key, sdigest, 16); 2107 break; 2108 } 2109 len = 4 + 1 + nresp + strlen(ppp->chapname); 2110 freeb(b); 2111 b = alloclcp(Cresponse, id, len, &m); 2112 *b->wptr++ = nresp; 2113 memmove(b->wptr, resp, nresp); 2114 b->wptr += nresp; 2115 memmove(b->wptr, ppp->chapname, strlen(ppp->chapname)); 2116 b->wptr += strlen(ppp->chapname); 2117 hnputs(m->len, len); 2118 netlog("PPP: sending response len %d\n", len); 2119 putframe(ppp, Pchap, b); 2120 break; 2121 case Cresponse: 2122 c = ppp->chap; 2123 vlen = m->data[0]; 2124 if(m->id != c->id) { 2125 netlog("PPP: chap: bad response id\n"); 2126 break; 2127 } 2128 switch(c->proto) { 2129 default: 2130 sysfatal("unknown chap protocol: %d", c->proto); 2131 case APmd5: 2132 if(vlen > len - 5 || vlen != 16) { 2133 netlog("PPP: chap: bad response len\n"); 2134 break; 2135 } 2136 2137 cr.id = m->id; 2138 memmove(cr.resp, m->data+1, 16); 2139 memset(uid, 0, sizeof(uid)); 2140 n = len-5-vlen; 2141 if(n >= PATH) 2142 n = PATH-1; 2143 memmove(uid, m->data+1+vlen, n); 2144 c->cs->user = uid; 2145 c->cs->resp = &cr; 2146 c->cs->nresp = sizeof cr; 2147 break; 2148 case APmschap: 2149 if(vlen > len - 5 || vlen != 49) { 2150 netlog("PPP: chap: bad response len\n"); 2151 break; 2152 } 2153 memset(&mscr, 0, sizeof(mscr)); 2154 memmove(mscr.LMresp, m->data+1, 24); 2155 memmove(mscr.NTresp, m->data+24+1, 24); 2156 n = len-5-vlen; 2157 p = m->data+1+vlen; 2158 /* remove domain name */ 2159 for(i=0; i<n; i++) { 2160 if(p[i] == '\\') { 2161 p += i+1; 2162 n -= i+1; 2163 break; 2164 } 2165 } 2166 if(n >= PATH) 2167 n = PATH-1; 2168 memset(uid, 0, sizeof(uid)); 2169 memmove(uid, p, n); 2170 c->cs->user = uid; 2171 c->cs->resp = 𝓂 2172 c->cs->nresp = sizeof mscr; 2173 break; 2174 } 2175 2176 syslog(0, LOG, ": remote=%I vlen %d proto %d response user %s nresp %d", ppp->remote, vlen, c->proto, c->cs->user, c->cs->nresp); 2177 if((ai = auth_response(c->cs)) == nil || auth_chuid(ai, nil) < 0){ 2178 c->state = Cunauth; 2179 code = Cfailure; 2180 syslog(0, LOG, ": remote=%I: auth failed: %r, uid=%s", ppp->remote, uid); 2181 }else{ 2182 c->state = Cauthok; 2183 code = Csuccess; 2184 syslog(0, LOG, ": remote=%I: auth ok: uid=%s nsecret=%d", ppp->remote, uid, ai->nsecret); 2185 if(c->proto == APmschap){ 2186 if(ai->nsecret != sizeof(ppp->key)) 2187 sysfatal("could not get the encryption key"); 2188 memmove(ppp->key, ai->secret, sizeof(ppp->key)); 2189 } 2190 } 2191 auth_freeAI(ai); 2192 auth_freechal(c->cs); 2193 c->cs = nil; 2194 freeb(b); 2195 2196 /* send reply */ 2197 len = 4; 2198 b = alloclcp(code, c->id, len, &m); 2199 hnputs(m->len, len); 2200 putframe(ppp, Pchap, b); 2201 2202 if(c->state == Cauthok) { 2203 setphase(ppp, Pnet); 2204 } else { 2205 /* restart chapp negotiation */ 2206 chapinit(ppp); 2207 } 2208 2209 break; 2210 case Csuccess: 2211 netlog("ppp: chap succeeded\n"); 2212 break; 2213 case Cfailure: 2214 netlog("ppp: chap failed\n"); 2215 break; 2216 default: 2217 syslog(0, LOG, "chap code %d?\n", m->code); 2218 break; 2219 } 2220 qunlock(ppp); 2221 freeb(b); 2222 } 2223 2224 static void 2225 putpaprequest(PPP *ppp) 2226 { 2227 Block *b; 2228 Lcpmsg *m; 2229 Chap *c; 2230 int len, nlen, slen; 2231 2232 getauth(ppp); 2233 2234 c = ppp->chap; 2235 c->id++; 2236 netlog("PPP: pap: send authreq %d %s %s\n", c->id, ppp->chapname, "****"); 2237 2238 nlen = strlen(ppp->chapname); 2239 slen = strlen(ppp->secret); 2240 len = 4 + 1 + nlen + 1 + slen; 2241 b = alloclcp(Pauthreq, c->id, len, &m); 2242 2243 *b->wptr++ = nlen; 2244 memmove(b->wptr, ppp->chapname, nlen); 2245 b->wptr += nlen; 2246 *b->wptr++ = slen; 2247 memmove(b->wptr, ppp->secret, slen); 2248 b->wptr += slen; 2249 hnputs(m->len, len); 2250 2251 putframe(ppp, Ppasswd, b); 2252 freeb(b); 2253 } 2254 2255 static void 2256 papinit(PPP *ppp) 2257 { 2258 ppp->chap->id = 0; 2259 putpaprequest(ppp); 2260 } 2261 2262 static void 2263 getpap(PPP *ppp, Block *b) 2264 { 2265 Lcpmsg *m; 2266 int len; 2267 2268 m = (Lcpmsg*)b->rptr; 2269 len = 4; 2270 if(BLEN(b) < 4 || BLEN(b) < (len = nhgets(m->len))){ 2271 syslog(0, LOG, "short pap message (%ld < %d)", BLEN(b), len); 2272 freeb(b); 2273 return; 2274 } 2275 if(len < sizeof(Lcpmsg)) 2276 m->data[0] = 0; 2277 2278 qlock(ppp); 2279 switch(m->code){ 2280 case Pauthreq: 2281 netlog("PPP: pap auth request, not supported\n"); 2282 break; 2283 case Pauthack: 2284 if(ppp->phase == Pauth 2285 && ppp->chap->proto == APpasswd 2286 && m->id <= ppp-> chap->id){ 2287 netlog("PPP: pap succeeded\n"); 2288 setphase(ppp, Pnet); 2289 } 2290 break; 2291 case Pauthnak: 2292 if(ppp->phase == Pauth 2293 && ppp->chap->proto == APpasswd 2294 && m->id <= ppp-> chap->id){ 2295 netlog("PPP: pap failed (%d:%.*s)\n", 2296 m->data[0], m->data[0], (char*)m->data+1); 2297 terminate(ppp, 0); 2298 } 2299 break; 2300 default: 2301 netlog("PPP: unknown pap messsage %d\n", m->code); 2302 } 2303 qunlock(ppp); 2304 freeb(b); 2305 } 2306 2307 static void 2308 printopts(Pstate *p, Block *b, int send) 2309 { 2310 Lcpmsg *m; 2311 Lcpopt *o; 2312 int proto, x, period; 2313 uchar *cp; 2314 char *code, *dir; 2315 2316 m = (Lcpmsg*)b->rptr; 2317 switch(m->code) { 2318 default: code = "<unknown>"; break; 2319 case Lconfreq: code = "confrequest"; break; 2320 case Lconfack: code = "confack"; break; 2321 case Lconfnak: code = "confnak"; break; 2322 case Lconfrej: code = "confreject"; break; 2323 } 2324 2325 if(send) 2326 dir = "send"; 2327 else 2328 dir = "recv"; 2329 2330 netlog("ppp: %s %s: id=%d\n", dir, code, m->id); 2331 2332 for(cp = m->data; cp < b->wptr; cp += o->len){ 2333 o = (Lcpopt*)cp; 2334 if(cp + o->len > b->wptr){ 2335 netlog("\tbad option length %ux\n", o->type); 2336 return; 2337 } 2338 2339 switch(p->proto){ 2340 case Plcp: 2341 switch(o->type){ 2342 default: 2343 netlog("\tunknown %d len=%d\n", o->type, o->len); 2344 break; 2345 case Omtu: 2346 netlog("\tmtu = %d\n", nhgets(o->data)); 2347 break; 2348 case Octlmap: 2349 netlog("\tctlmap = %ux\n", nhgetl(o->data)); 2350 break; 2351 case Oauth: 2352 netlog("\tauth = %ux", nhgetl(o->data)); 2353 proto = nhgets(o->data); 2354 switch(proto) { 2355 default: 2356 netlog("unknown auth proto %d\n", proto); 2357 break; 2358 case Ppasswd: 2359 netlog("password\n"); 2360 break; 2361 case Pchap: 2362 netlog("chap %ux\n", o->data[2]); 2363 break; 2364 } 2365 break; 2366 case Oquality: 2367 proto = nhgets(o->data); 2368 switch(proto) { 2369 default: 2370 netlog("\tunknown quality proto %d\n", proto); 2371 break; 2372 case Plqm: 2373 x = nhgetl(o->data+2)*10; 2374 period = (x+Period-1)/Period; 2375 netlog("\tlqm period = %d\n", period); 2376 break; 2377 } 2378 case Omagic: 2379 netlog("\tmagic = %ux\n", nhgetl(o->data)); 2380 break; 2381 case Opc: 2382 netlog("\tprotocol compress\n"); 2383 break; 2384 case Oac: 2385 netlog("\taddr compress\n"); 2386 break; 2387 } 2388 break; 2389 case Pccp: 2390 switch(o->type){ 2391 default: 2392 netlog("\tunknown %d len=%d\n", o->type, o->len); 2393 break; 2394 case Ocoui: 2395 netlog("\tOUI\n"); 2396 break; 2397 case Ocstac: 2398 netlog("\tstac LZS\n"); 2399 break; 2400 case Ocmppc: 2401 netlog("\tMicrosoft PPC len=%d %ux\n", o->len, nhgetl(o->data)); 2402 break; 2403 case Octhwack: 2404 netlog("\tThwack\n"); 2405 break; 2406 } 2407 break; 2408 case Pecp: 2409 switch(o->type){ 2410 default: 2411 netlog("\tunknown %d len=%d\n", o->type, o->len); 2412 break; 2413 case Oeoui: 2414 netlog("\tOUI\n"); 2415 break; 2416 case Oedese: 2417 netlog("\tDES\n"); 2418 break; 2419 } 2420 break; 2421 case Pipcp: 2422 switch(o->type){ 2423 default: 2424 netlog("\tunknown %d len=%d\n", o->type, o->len); 2425 break; 2426 case Oipaddrs: 2427 netlog("\tip addrs - deprecated\n"); 2428 break; 2429 case Oipcompress: 2430 netlog("\tip compress\n"); 2431 break; 2432 case Oipaddr: 2433 netlog("\tip addr %V\n", o->data); 2434 break; 2435 case Oipdns: 2436 netlog("\tdns addr %V\n", o->data); 2437 break; 2438 case Oipwins: 2439 netlog("\twins addr %V\n", o->data); 2440 break; 2441 case Oipdns2: 2442 netlog("\tdns2 addr %V\n", o->data); 2443 break; 2444 case Oipwins2: 2445 netlog("\twins2 addr %V\n", o->data); 2446 break; 2447 } 2448 break; 2449 } 2450 } 2451 } 2452 2453 static void 2454 sendtermreq(PPP *ppp, Pstate *p) 2455 { 2456 Block *b; 2457 Lcpmsg *m; 2458 2459 p->termid = ++(p->id); 2460 b = alloclcp(Ltermreq, p->termid, 4, &m); 2461 hnputs(m->len, 4); 2462 putframe(ppp, p->proto, b); 2463 freeb(b); 2464 newstate(ppp, p, Sclosing); 2465 } 2466 2467 static void 2468 sendechoreq(PPP *ppp, Pstate *p) 2469 { 2470 Block *b; 2471 Lcpmsg *m; 2472 2473 p->termid = ++(p->id); 2474 b = alloclcp(Lechoreq, p->id, 4, &m); 2475 hnputs(m->len, 4); 2476 putframe(ppp, p->proto, b); 2477 freeb(b); 2478 } 2479 2480 enum 2481 { 2482 CtrlD = 0x4, 2483 CtrlE = 0x5, 2484 CtrlO = 0xf, 2485 Cr = 13, 2486 View = 0x80, 2487 }; 2488 2489 int conndone; 2490 2491 static void 2492 xfer(int fd) 2493 { 2494 int i, n; 2495 uchar xbuf[128]; 2496 2497 for(;;) { 2498 n = read(fd, xbuf, sizeof(xbuf)); 2499 if(n < 0) 2500 break; 2501 if(conndone) 2502 break; 2503 for(i = 0; i < n; i++) 2504 if(xbuf[i] == Cr) 2505 xbuf[i] = ' '; 2506 write(1, xbuf, n); 2507 } 2508 close(fd); 2509 } 2510 2511 static int 2512 readcr(int fd, char *buf, int nbuf) 2513 { 2514 char c; 2515 int n, tot; 2516 2517 tot = 0; 2518 while((n=read(fd, &c, 1)) == 1){ 2519 if(c == '\n'){ 2520 buf[tot] = 0; 2521 return tot; 2522 } 2523 buf[tot++] = c; 2524 if(tot == nbuf) 2525 sysfatal("line too long in readcr"); 2526 } 2527 return n; 2528 } 2529 2530 static void 2531 connect(int fd, int cfd) 2532 { 2533 int n, ctl; 2534 char xbuf[128]; 2535 2536 if (chatfile) { 2537 int chatfd, lineno, nb; 2538 char *buf, *p, *s, response[128]; 2539 Dir *dir; 2540 2541 if ((chatfd = open(chatfile, OREAD)) < 0) 2542 sysfatal("cannot open %s: %r", chatfile); 2543 2544 if ((dir = dirfstat(chatfd)) == nil) 2545 sysfatal("cannot fstat %s: %r",chatfile); 2546 2547 buf = (char *)malloc(dir->length + 1); 2548 assert(buf); 2549 2550 if ((nb = read(chatfd, buf, dir->length)) < 0) 2551 sysfatal("cannot read chatfile %s: %r", chatfile); 2552 assert(nb == dir->length); 2553 buf[dir->length] = '\0'; 2554 free(dir); 2555 close(chatfd); 2556 2557 p = buf; 2558 lineno = 0; 2559 for(;;) { 2560 char *_args[3]; 2561 2562 if ((s = strchr(p, '\n')) == nil) 2563 break; 2564 *s++ = '\0'; 2565 2566 lineno++; 2567 2568 if (*p == '#') { 2569 p = s; 2570 continue; 2571 } 2572 2573 if (tokenize(p, _args, 3) != 2) 2574 sysfatal("invalid line %d (line expected: 'send' 'expect')", 2575 lineno); 2576 2577 if (debug) 2578 print("sending %s, expecting %s\n", _args[0], _args[1]); 2579 2580 if(strlen(_args[0])){ 2581 nb = fprint(fd, "%s\r", _args[0]); 2582 assert(nb > 0); 2583 } 2584 2585 if (strlen(_args[1]) > 0) { 2586 if ((nb = readcr(fd, response, sizeof response-1)) < 0) 2587 sysfatal("cannot read response from: %r"); 2588 2589 if (debug) 2590 print("response %s\n", response); 2591 2592 if (nb == 0) 2593 sysfatal("eof on input?\n"); 2594 2595 if (cistrstr(response, _args[1]) == nil) 2596 sysfatal("expected %s, got %s\n", _args[1], response); 2597 } 2598 p = s; 2599 } 2600 free(buf); 2601 return; 2602 } 2603 2604 print("Connect to file system now, type ctrl-d when done.\n"); 2605 print("...(Use the view or down arrow key to send a break)\n"); 2606 print("...(Use ctrl-e to set even parity or ctrl-o for odd)\n"); 2607 2608 ctl = open("/dev/consctl", OWRITE); 2609 if(ctl < 0) 2610 sysfatal("opening consctl"); 2611 fprint(ctl, "rawon"); 2612 2613 fd = dup(fd, -1); 2614 conndone = 0; 2615 switch(rfork(RFPROC|RFMEM|RFNOWAIT)){ 2616 case -1: 2617 sysfatal("forking xfer"); 2618 case 0: 2619 xfer(fd); 2620 _exits(nil); 2621 } 2622 2623 for(;;){ 2624 read(0, xbuf, 1); 2625 switch(xbuf[0]&0xff) { 2626 case CtrlD: /* done */ 2627 conndone = 1; 2628 close(ctl); 2629 print("\n"); 2630 return; 2631 case CtrlE: /* set even parity */ 2632 fprint(cfd, "pe"); 2633 break; 2634 case CtrlO: /* set odd parity */ 2635 fprint(cfd, "po"); 2636 break; 2637 case View: /* send a break */ 2638 fprint(cfd, "k500"); 2639 break; 2640 default: 2641 n = write(fd, xbuf, 1); 2642 if(n < 0) { 2643 errstr(xbuf, sizeof(xbuf)); 2644 conndone = 1; 2645 close(ctl); 2646 print("[remote write error (%s)]\n", xbuf); 2647 return; 2648 } 2649 } 2650 } 2651 } 2652 2653 int interactive; 2654 2655 void 2656 usage(void) 2657 { 2658 fprint(2, "usage: ppp [-cCdfPSu] [-b baud] [-k keyspec] [-m mtu] [-p dev] [-s username] [-x netmntpt] [-t modemcmd] [local-addr [remote-addr]]\n"); 2659 exits("usage"); 2660 } 2661 2662 void 2663 main(int argc, char **argv) 2664 { 2665 int mtu, baud, framing, user, mediain, mediaout, cfd; 2666 Ipaddr ipaddr, remip; 2667 char *dev, *modemcmd; 2668 char net[128]; 2669 PPP *ppp; 2670 char buf[128]; 2671 2672 rfork(RFREND|RFNOTEG|RFNAMEG); 2673 2674 fmtinstall('I', eipfmt); 2675 fmtinstall('V', eipfmt); 2676 fmtinstall('E', eipfmt); 2677 2678 dev = nil; 2679 2680 invalidate(ipaddr); 2681 invalidate(remip); 2682 2683 mtu = Defmtu; 2684 baud = 0; 2685 framing = 0; 2686 setnetmtpt(net, sizeof(net), nil); 2687 user = 0; 2688 modemcmd = nil; 2689 2690 ARGBEGIN{ 2691 case 'b': 2692 baud = atoi(EARGF(usage())); 2693 if(baud < 0) 2694 baud = 0; 2695 break; 2696 case 'c': 2697 nocompress = 1; 2698 break; 2699 case 'C': 2700 noipcompress = 1; 2701 break; 2702 case 'd': 2703 debug++; 2704 break; 2705 case 'f': 2706 framing = 1; 2707 break; 2708 case 'F': 2709 pppframing = 0; 2710 break; 2711 case 'k': 2712 keyspec = EARGF(usage()); 2713 break; 2714 case 'm': 2715 mtu = atoi(EARGF(usage())); 2716 if(mtu < Minmtu) 2717 mtu = Minmtu; 2718 if(mtu > Maxmtu) 2719 mtu = Maxmtu; 2720 break; 2721 case 'M': 2722 chatfile = EARGF(usage()); 2723 break; 2724 case 'p': 2725 dev = EARGF(usage()); 2726 break; 2727 case 'P': 2728 primary = 1; 2729 break; 2730 case 'S': 2731 server = 1; 2732 break; 2733 case 't': 2734 modemcmd = EARGF(usage()); 2735 break; 2736 case 'u': 2737 user = 1; 2738 break; 2739 case 'x': 2740 setnetmtpt(net, sizeof net, EARGF(usage())); 2741 break; 2742 default: 2743 fprint(2, "unknown option %c\n", ARGC()); 2744 usage(); 2745 }ARGEND; 2746 2747 switch(argc){ 2748 case 2: 2749 parseip(remip, argv[1]); 2750 case 1: 2751 parseip(ipaddr, argv[0]); 2752 case 0: 2753 break; 2754 default: 2755 usage(); 2756 } 2757 2758 nip = nipifcs(net); 2759 if(nip == 0 && !server) 2760 primary = 1; 2761 2762 if(dev != nil){ 2763 mediain = open(dev, ORDWR); 2764 if(mediain < 0){ 2765 if(strchr(dev, '!')){ 2766 if((mediain = dial(dev, 0, 0, &cfd)) == -1){ 2767 fprint(2, "ppp: couldn't dial %s: %r\n", dev); 2768 exits(dev); 2769 } 2770 } else { 2771 fprint(2, "ppp: couldn't open %s\n", dev); 2772 exits(dev); 2773 } 2774 } else { 2775 snprint(buf, sizeof buf, "%sctl", dev); 2776 cfd = open(buf, ORDWR); 2777 } 2778 if(cfd > 0){ 2779 if(baud) 2780 fprint(cfd, "b%d", baud); 2781 fprint(cfd, "m1"); /* cts/rts flow control (and fifo's) on */ 2782 fprint(cfd, "q64000"); /* increase q size to 64k */ 2783 fprint(cfd, "n1"); /* nonblocking writes on */ 2784 fprint(cfd, "r1"); /* rts on */ 2785 fprint(cfd, "d1"); /* dtr on */ 2786 fprint(cfd, "c1"); /* dcdhup on */ 2787 if(user || chatfile) 2788 connect(mediain, cfd); 2789 close(cfd); 2790 } else { 2791 if(user || chatfile) 2792 connect(mediain, -1); 2793 } 2794 mediaout = mediain; 2795 } else { 2796 mediain = open("/fd/0", OREAD); 2797 if(mediain < 0){ 2798 fprint(2, "ppp: couldn't open /fd/0\n"); 2799 exits("/fd/0"); 2800 } 2801 mediaout = open("/fd/1", OWRITE); 2802 if(mediaout < 0){ 2803 fprint(2, "ppp: couldn't open /fd/0\n"); 2804 exits("/fd/1"); 2805 } 2806 } 2807 2808 if(modemcmd != nil && mediaout >= 0) 2809 fprint(mediaout, "%s\r", modemcmd); 2810 2811 ppp = mallocz(sizeof(*ppp), 1); 2812 pppopen(ppp, mediain, mediaout, net, ipaddr, remip, mtu, framing); 2813 2814 /* wait until ip is configured */ 2815 rendezvous((void*)Rmagic, 0); 2816 2817 if(primary){ 2818 /* create a /net/ndb entry */ 2819 putndb(ppp, net); 2820 } 2821 2822 exits(0); 2823 } 2824 2825 void 2826 netlog(char *fmt, ...) 2827 { 2828 va_list arg; 2829 char *m; 2830 static long start; 2831 long now; 2832 2833 if(debug == 0) 2834 return; 2835 2836 now = time(0); 2837 if(start == 0) 2838 start = now; 2839 2840 va_start(arg, fmt); 2841 m = vsmprint(fmt, arg); 2842 fprint(2, "%ld %s", now-start, m); 2843 free(m); 2844 va_end(arg); 2845 } 2846 2847 /* 2848 * return non-zero if this is a valid v4 address 2849 */ 2850 static int 2851 validv4(Ipaddr addr) 2852 { 2853 return memcmp(addr, v4prefix, IPv4off) == 0 && memcmp(addr, v4prefix, IPaddrlen) != 0; 2854 } 2855 2856 static void 2857 invalidate(Ipaddr addr) 2858 { 2859 ipmove(addr, IPnoaddr); 2860 } 2861 2862 /* 2863 * return number of networks 2864 */ 2865 static int 2866 nipifcs(char *net) 2867 { 2868 static Ipifc *ifc; 2869 Ipifc *nifc; 2870 Iplifc *lifc; 2871 int n; 2872 2873 n = 0; 2874 ifc = readipifc(net, ifc, -1); 2875 for(nifc = ifc; nifc != nil; nifc = nifc->next) 2876 for(lifc = ifc->lifc; lifc != nil; lifc = lifc->next) 2877 n++; 2878 return n; 2879 } 2880 2881 /* 2882 * make an ndb entry and put it into /net/ndb for the servers to see 2883 */ 2884 static void 2885 putndb(PPP *ppp, char *net) 2886 { 2887 char buf[1024]; 2888 char file[64]; 2889 char *p, *e; 2890 int fd; 2891 2892 e = buf + sizeof(buf); 2893 p = buf; 2894 p = seprint(p, e, "ip=%I ipmask=255.255.255.255 ipgw=%I\n", ppp->local, 2895 ppp->remote); 2896 if(validv4(ppp->dns[0])) 2897 p = seprint(p, e, "\tdns=%I\n", ppp->dns[0]); 2898 if(validv4(ppp->dns[1])) 2899 p = seprint(p, e, "\tdns=%I\n", ppp->dns[1]); 2900 if(validv4(ppp->wins[0])) 2901 p = seprint(p, e, "\twins=%I\n", ppp->wins[0]); 2902 if(validv4(ppp->wins[1])) 2903 p = seprint(p, e, "\twins=%I\n", ppp->wins[1]); 2904 seprint(file, file+sizeof file, "%s/ndb", net); 2905 fd = open(file, OWRITE); 2906 if(fd < 0) 2907 return; 2908 write(fd, buf, p-buf); 2909 close(fd); 2910 seprint(file, file+sizeof file, "%s/cs", net); 2911 fd = open(file, OWRITE); 2912 write(fd, "refresh", 7); 2913 close(fd); 2914 seprint(file, file+sizeof file, "%s/dns", net); 2915 fd = open(file, OWRITE); 2916 write(fd, "refresh", 7); 2917 close(fd); 2918 } 2919 2920 static void 2921 getauth(PPP *ppp) 2922 { 2923 UserPasswd *up; 2924 2925 if(*ppp->chapname) 2926 return; 2927 2928 up = auth_getuserpasswd(auth_getkey,"proto=pass service=ppp %s", keyspec); 2929 if(up != nil){ 2930 strcpy(ppp->chapname, up->user); 2931 strcpy(ppp->secret, up->passwd); 2932 } 2933 } 2934