2 * ppp - point-to-point protocol, rfc1331
16 static int nocompress;
17 static int pppframing = 1;
18 static int noipcompress;
21 static int nip; /* number of ip interfaces */
22 static int dying; /* flag to signal to all threads its time to go */
23 static int primary; /* this is the primary IP interface */
24 static char *chatfile;
36 * Calculate FCS - rfc 1331
40 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
41 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
42 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
43 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
44 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
45 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
46 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
47 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
48 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
49 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
50 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
51 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
52 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
53 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
54 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
55 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
56 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
57 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
58 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
59 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
60 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
61 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
62 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
63 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
64 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
65 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
66 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
67 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
68 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
69 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
70 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
71 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
74 static char *snames[] =
84 static void authtimer(PPP*);
85 static void chapinit(PPP*);
86 static void config(PPP*, Pstate*, int);
87 static uchar* escapeuchar(PPP*, ulong, uchar*, ushort*);
88 static void getchap(PPP*, Block*);
89 static Block* getframe(PPP*, int*);
90 static void getlqm(PPP*, Block*);
91 static int getopts(PPP*, Pstate*, Block*);
92 static void getpap(PPP*, Block*);
93 static void init(PPP*);
94 static void invalidate(Ipaddr);
95 static void ipinproc(PPP*);
96 static char* ipopen(PPP*);
97 static void mediainproc(PPP*);
98 static void newstate(PPP*, Pstate*, int);
99 static int nipifcs(char*);
100 static void papinit(PPP*);
101 static void pinit(PPP*, Pstate*);
102 static void ppptimer(PPP*);
103 static void printopts(Pstate*, Block*, int);
104 static void ptimer(PPP*, Pstate*);
105 static int putframe(PPP*, int, Block*);
106 static void putlqm(PPP*);
107 static void putndb(PPP*, char*);
108 static void putpaprequest(PPP*);
109 static void rcv(PPP*, Pstate*, Block*);
110 static void rejopts(PPP*, Pstate*, Block*, int);
111 static void sendechoreq(PPP*, Pstate*);
112 static void sendtermreq(PPP*, Pstate*);
113 static void setphase(PPP*, int);
114 static void terminate(PPP*, int);
115 static int validv4(Ipaddr);
116 static void dmppkt(char *s, uchar *a, int na);
117 static void getauth(PPP*);
120 pppopen(PPP *ppp, int mediain, int mediaout, char *net,
121 Ipaddr ipaddr, Ipaddr remip,
122 int mtu, int framing)
126 invalidate(ppp->remote);
127 invalidate(ppp->local);
128 invalidate(ppp->curremote);
129 invalidate(ppp->curlocal);
130 invalidate(ppp->dns[0]);
131 invalidate(ppp->dns[1]);
132 invalidate(ppp->wins[0]);
133 invalidate(ppp->wins[1]);
135 ppp->mediain = mediain;
136 ppp->mediaout = mediaout;
138 ipmove(ppp->remote, remip);
139 ppp->remotefrozen = 1;
142 ipmove(ppp->local, ipaddr);
143 ppp->localfrozen = 1;
147 ppp->framing = framing;
151 switch(rfork(RFPROC|RFMEM|RFNOWAIT)){
153 sysfatal("forking mediainproc");
164 if(ppp->inbuf == nil){
165 ppp->inbuf = allocb(4096);
166 if(ppp->inbuf == nil)
169 ppp->outbuf = allocb(4096);
170 if(ppp->outbuf == nil)
173 ppp->lcp = mallocz(sizeof(*ppp->lcp), 1);
176 ppp->lcp->proto = Plcp;
177 ppp->lcp->state = Sclosed;
179 ppp->ccp = mallocz(sizeof(*ppp->ccp), 1);
182 ppp->ccp->proto = Pccp;
183 ppp->ccp->state = Sclosed;
185 ppp->ipcp = mallocz(sizeof(*ppp->ipcp), 1);
188 ppp->ipcp->proto = Pipcp;
189 ppp->ipcp->state = Sclosed;
191 ppp->chap = mallocz(sizeof(*ppp->chap), 1);
194 ppp->chap->proto = APmschap;
195 ppp->chap->state = Cunauth;
196 auth_freechal(ppp->chap->cs);
199 switch(rfork(RFPROC|RFMEM|RFNOWAIT)){
201 sysfatal("forking ppptimer");
208 ppp->ctcp = compress_init(ppp->ctcp);
209 pinit(ppp, ppp->lcp);
210 setphase(ppp, Plink);
214 setphase(PPP *ppp, int phase)
218 oldphase = ppp->phase;
223 sysfatal("ppp: unknown phase %d", phase);
225 /* restart or exit? */
226 pinit(ppp, ppp->lcp);
227 setphase(ppp, Plink);
233 auth_freechal(ppp->chap->cs);
235 ppp->chap->state = Cunauth;
238 auth_freechal(ppp->chap->cs);
240 ppp->chap->state = Cunauth;
241 newstate(ppp, ppp->ccp, Sclosed);
242 newstate(ppp, ppp->ipcp, Sclosed);
249 switch (ppp->chap->proto) {
263 pinit(ppp, ppp->ccp);
264 pinit(ppp, ppp->ipcp);
273 pinit(PPP *ppp, Pstate *p)
279 ppp->magic = truerand();
280 ppp->xctlmap = 0xffffffff;
282 p->optmask = 0xffffffff;
284 p->optmask &= ~(Fauth|Fmtu);
286 ppp->ipcp->state = Sclosed;
287 ppp->ipcp->optmask = 0xffffffff;
290 ppp->ipcp->optmask &= ~Fipaddrs;
294 ppp->ipcp->optmask &= ~Fipcompress;
300 memset(&ppp->in, 0, sizeof(ppp->in));
301 memset(&ppp->out, 0, sizeof(ppp->out));
302 memset(&ppp->pin, 0, sizeof(ppp->pin));
303 memset(&ppp->pout, 0, sizeof(ppp->pout));
304 memset(&ppp->sin, 0, sizeof(ppp->sin));
312 if(ppp->ctype != nil)
313 (*ppp->ctype->fini)(ppp->cstate);
319 (*ppp->unctype->fini)(ppp->uncstate);
324 p->optmask = 0xffffffff;
325 ppp->ctcp = compress_init(ppp->ctcp);
328 p->confid = p->rcvdconfid = -1;
330 newstate(ppp, p, Sreqsent);
334 * change protocol to a new state.
337 newstate(PPP *ppp, Pstate *p, int state)
341 netlog("ppp: %ux %s->%s ctlmap %lux/%lux flags %lux mtu %ld mru %ld\n",
342 p->proto, snames[p->state], snames[state], ppp->rctlmap,
343 ppp->xctlmap, p->flags,
345 syslog(0, "ppp", "%ux %s->%s ctlmap %lux/%lux flags %lux mtu %ld mru %ld",
346 p->proto, snames[p->state], snames[state], ppp->rctlmap,
347 ppp->xctlmap, p->flags,
350 if(p->proto == Plcp) {
352 setphase(ppp, noauth? Pnet : Pauth);
353 else if(state == Sclosed)
354 setphase(ppp, Pdead);
355 else if(p->state == Sopened)
356 setphase(ppp, Plink);
359 if(p->proto == Pccp && state == Sopened) {
361 (*ppp->unctype->fini)(ppp->uncstate);
364 if(p->optmask & Fcmppc) {
365 ppp->unctype = &uncmppc;
366 ppp->uncstate = (*uncmppc.init)(ppp);
368 if(p->optmask & Fcthwack){
369 ppp->unctype = &uncthwack;
370 ppp->uncstate = (*uncthwack.init)(ppp);
374 if(p->proto == Pipcp && state == Sopened) {
375 if(server && !noauth && ppp->chap->state != Cauthok)
386 /* returns (protocol, information) */
388 getframe(PPP *ppp, int *protop)
390 uchar *p, *from, *to;
397 if(ppp->framing == 0) {
398 /* assume data is already framed */
400 len = b->lim - b->wptr;
401 n = read(ppp->mediain, b->wptr, len);
402 dmppkt("RX", b->wptr, n);
403 if(n <= 0 || n == len){
410 /* should probably copy to another block if small */
412 if(pppframing && b->rptr[0] == PPP_addr && b->rptr[1] == PPP_ctl)
415 if((proto & 0x1) == 0)
416 proto = (proto<<8) | *b->rptr++;
418 if(b->rptr >= b->wptr){
426 netlog("getframe 0x%x\n", proto);
432 /* read till we hit a frame uchar or run out of room */
433 for(p = buf->rptr; buf->wptr < buf->lim;){
434 for(; p < buf->wptr; p++)
440 len = buf->lim - buf->wptr;
441 n = read(ppp->mediain, buf->wptr, len);
443 syslog(0, LOG, "medium read returns %d: %r", n);
444 buf->wptr = buf->rptr;
447 dmppkt("RX", buf->wptr, n);
451 /* copy into block, undoing escapes, and caculating fcs */
453 b = allocb(p - buf->rptr);
455 for(from = buf->rptr; from != p;){
461 } else if((c < 0x20) && (ppp->rctlmap & (1 << c)))
464 fcs = (fcs >> 8) ^ fcstab[(fcs ^ c) & 0xff];
467 /* copy down what's left in buffer */
469 memmove(buf->rptr, p, buf->wptr - p);
474 /* return to caller if checksum matches */
475 if(fcs == PPP_goodfcs){
476 if(b->rptr[0] == PPP_addr && b->rptr[1] == PPP_ctl)
479 if((proto & 0x1) == 0)
480 proto = (proto<<8) | *b->rptr++;
481 if(b->rptr < b->wptr){
485 netlog("getframe 0x%x\n", proto);
488 } else if(BLEN(b) > 0){
490 compress_error(ppp->ctcp);
492 netlog("ppp: discard len %zd/%zd cksum %ux (%ux %ux %ux %ux)\n",
493 BLEN(b), BLEN(buf), fcs, b->rptr[0],
494 b->rptr[1], b->rptr[2], b->rptr[3]);
501 /* send a PPP frame */
503 putframe(PPP *ppp, int proto, Block *b)
517 ctlmap = ppp->xctlmap;
519 /* make sure we have head room */
520 if(b->rptr - b->base < 4){
525 netlog("ppp: putframe 0x%ux %zd\n", proto, BLEN(b));
527 /* add in the protocol and address, we'd better have left room */
530 if(!(ppp->lcp->flags&Fpc) || proto > 0x100 || proto == Plcp)
532 if(pppframing && (!(ppp->lcp->flags&Fac) || proto == Plcp)){
537 qlock(&ppp->outlock);
540 if(ppp->framing == 0) {
542 for(bp = b; bp; bp = bp->next){
545 memmove(to, from, bp->wptr-from);
549 /* escape and checksum the body */
553 /* add frame marker */
556 for(bp = b; bp; bp = bp->next){
559 for(; from < bp->wptr; from++){
561 if(c == HDLC_frame || c == HDLC_esc
562 || (c < 0x20 && ((1<<c) & ctlmap))){
567 fcs = (fcs >> 8) ^ fcstab[(fcs ^ c) & 0xff];
571 /* add on and escape the checksum */
574 if(c == HDLC_frame || c == HDLC_esc
575 || (c < 0x20 && ((1<<c) & ctlmap))){
581 if(c == HDLC_frame || c == HDLC_esc
582 || (c < 0x20 && ((1<<c) & ctlmap))){
588 /* add frame marker */
594 dmppkt("TX", buf->rptr, BLEN(buf));
595 if(write(ppp->mediaout, buf->rptr, BLEN(buf)) < 0){
596 qunlock(&ppp->outlock);
599 ppp->out.uchars += BLEN(buf);
601 qunlock(&ppp->outlock);
606 alloclcp(int code, int id, int len, Lcpmsg **mp)
612 * leave room for header
616 m = (Lcpmsg*)b->wptr;
627 putlo(Block *b, int type, ulong val)
631 hnputl(b->wptr, val);
636 putv4o(Block *b, int type, Ipaddr val)
640 v6tov4(b->wptr, val);
645 putso(Block *b, int type, ulong val)
649 hnputs(b->wptr, val);
654 puto(Block *b, int type)
661 * send configuration request
664 config(PPP *ppp, Pstate *p, int newid)
673 p->timeout = Timeout;
676 b = alloclcp(Lconfreq, id, 256, &m);
681 if(p->optmask & Fctlmap)
682 putlo(b, Octlmap, 0); /* we don't want anything escaped */
683 if(p->optmask & Fmagic)
684 putlo(b, Omagic, ppp->magic);
685 if(p->optmask & Fmtu)
686 putso(b, Omtu, ppp->mru);
687 if(p->optmask & Fauth) {
690 hnputs(b->wptr, Pchap);
692 *b->wptr++ = ppp->chap->proto;
700 if(p->optmask & Fcthwack)
702 else if(p->optmask & Fcmppc) {
712 if(p->optmask & Fipaddr){
713 syslog(0, "ppp", "requesting %I", ppp->local);
714 putv4o(b, Oipaddr, ppp->local);
716 if(primary && (p->optmask & Fipdns))
717 putv4o(b, Oipdns, ppp->dns[0]);
718 if(primary && (p->optmask & Fipdns2))
719 putv4o(b, Oipdns2, ppp->dns[1]);
720 if(primary && (p->optmask & Fipwins))
721 putv4o(b, Oipwins, ppp->wins[0]);
722 if(primary && (p->optmask & Fipwins2))
723 putv4o(b, Oipwins2, ppp->wins[1]);
725 * don't ask for header compression while data compression is still pending.
726 * perhaps we should restart ipcp negotiation if compression negotiation fails.
728 if(!noipcompress && !ppp->ccp->optmask && (p->optmask & Fipcompress)) {
729 *b->wptr++ = Oipcompress;
731 hnputs(b->wptr, Pvjctcp);
733 *b->wptr++ = MAX_STATES-1;
738 hnputs(m->len, BLEN(b));
740 putframe(ppp, p->proto, b);
752 if(!validv4(ppp->local))
757 sprint(ip, "%I", ppp->local);
758 t = csipinfo(ppp->net, "ip", ip, av, 2);
760 for(nt = t; nt != nil; nt = nt->entry){
761 if(strcmp(nt->attr, "dns") == 0){
763 parseip(ppp->dns[ndns++], nt->val);
764 } else if(strcmp(nt->attr, "wins") == 0){
766 parseip(ppp->wins[nwins++], nt->val);
774 * parse configuration request, sends an ack or reject packet
776 * returns: -1 if request was syntacticly incorrect
777 * 0 if packet was accepted
778 * 1 if packet was rejected
781 getopts(PPP *ppp, Pstate *p, Block *b)
786 ulong rejecting, nacking, flags, proto, chapproto;
787 ulong mtu, ctlmap, period;
805 m = (Lcpmsg*)b->rptr;
806 repb = alloclcp(Lconfack, m->id, BLEN(b), &repm);
808 /* copy options into ack packet */
809 memmove(repm->data, m->data, b->wptr - m->data);
810 repb->wptr += b->wptr - m->data;
812 /* look for options we don't recognize or like */
813 for(cp = m->data; cp < b->wptr; cp += o->len){
815 if(cp + o->len > b->wptr || o->len==0){
817 netlog("ppp: bad option length %ux\n", o->type);
831 mtu = nhgets(o->data);
834 if(ppp->magic == nhgetl(o->data))
835 netlog("ppp: possible loop\n");
838 ctlmap = nhgetl(o->data);
841 proto = nhgets(o->data);
844 x = nhgetl(o->data+2)*10;
845 period = (x+Period-1)/Period;
848 proto = nhgets(o->data);
849 if(proto == Ppasswd && !server){
850 chapproto = APpasswd;
855 if(o->data[2] != APmd5 && o->data[2] != APmschap)
857 chapproto = o->data[2];
874 repb->wptr = repm->data;
875 repm->code = Lconfnak;
877 puto(repb, Octhwack);
888 if((x&0x41) == 0 || ppp->ctries++ > 5) {
890 * turn off requests as well - I don't think this
891 * is needed in the standard
893 p->optmask &= ~Fcmppc;
900 ppp->sendencrypted = (o->data[3]&0x40) == 0x40;
905 repb->wptr = repm->data;
906 repm->code = Lconfnak;
908 *repb->wptr++ = Ocmppc;
913 *repb->wptr++ = 0x41;
920 v4tov6(ipaddr, o->data);
921 if(!validv4(ppp->remote))
923 if(!validv4(ipaddr) && !rejecting){
924 /* other side requesting an address */
927 repb->wptr = repm->data;
928 repm->code = Lconfnak;
930 putv4o(repb, Oipaddr, ppp->remote);
950 v4tov6(ipaddr, o->data);
951 if(!validv4(ipaddr) && !rejecting){
952 /* other side requesting an address */
955 repb->wptr = repm->data;
956 repm->code = Lconfnak;
958 putv4o(repb, o->type, ap);
963 * don't compress tcp header if we've negotiated data compression.
964 * tcp header compression has very poor performance if there is an error.
966 proto = nhgets(o->data);
967 if(noipcompress || proto != Pvjctcp || ppp->ctype != nil)
969 if(compress_negotiate(ppp->ctcp, o->data+2) < 0)
971 flags |= Fipcompress;
977 /* come here if option is not recognized */
980 repb->wptr = repm->data;
981 repm->code = Lconfrej;
983 netlog("ppp: bad %ux option %d\n", p->proto, o->type);
984 memmove(repb->wptr, o, o->len);
985 repb->wptr += o->len;
988 /* permanent changes only after we know that we liked the packet */
989 if(!rejecting && !nacking){
992 ppp->period = period;
993 ppp->xctlmap = ctlmap;
1000 ppp->chap->proto = chapproto;
1004 if(ppp->ctype != nil){
1005 (*ppp->ctype->fini)(ppp->cstate);
1010 ppp->cstate = (*ctype->init)(ppp);
1013 if(validv4(ipaddr) && ppp->remotefrozen == 0)
1014 ipmove(ppp->remote, ipaddr);
1020 hnputs(repm->len, BLEN(repb));
1021 printopts(p, repb, 1);
1022 putframe(ppp, p->proto, repb);
1025 return rejecting || nacking;
1028 dmppkt(char *s, uchar *a, int na)
1036 for(i = 0; i < na; i++)
1037 fprint(2, " %.2ux", a[i]);
1042 dropoption(Pstate *p, Lcpopt *o)
1044 unsigned n = o->type;
1050 p->optmask &= ~Fipdns;
1053 p->optmask &= ~Fipwins;
1056 p->optmask &= ~Fipdns2;
1059 p->optmask &= ~Fipwins2;
1062 if(o->type < 8*sizeof(p->optmask))
1063 p->optmask &= ~(1<<o->type);
1069 * parse configuration rejection, just stop sending anything that they
1070 * don't like (except for ipcp address nak).
1073 rejopts(PPP *ppp, Pstate *p, Block *b, int code)
1077 uchar newip[IPaddrlen];
1079 /* just give up trying what the other side doesn't like */
1080 m = (Lcpmsg*)b->rptr;
1081 for(b->rptr = m->data; b->rptr < b->wptr; b->rptr += o->len){
1082 o = (Lcpopt*)b->rptr;
1083 if(b->rptr + o->len > b->wptr){
1084 netlog("ppp: bad roption length %ux\n", o->type);
1088 if(code == Lconfrej){
1090 netlog("ppp: %ux rejecting %d\n",
1099 ppp->rctlmap = nhgetl(o->data);
1102 /* don't allow client to request no auth */
1103 /* could try different auth protocol here */
1104 fprint(2, "ppp: can not reject CHAP\n");
1108 if(o->type < 8*sizeof(p->optmask))
1109 p->optmask &= ~(1<<o->type);
1123 syslog(0, "ppp", "rejected addr %I with %V", ppp->local, o->data);
1124 /* if we're a server, don't let other end change our addr */
1125 if(ppp->localfrozen){
1130 /* accept whatever server tells us */
1131 if(!validv4(ppp->local)){
1132 v4tov6(ppp->local, o->data);
1137 /* if he didn't like our addr, ask for a generic one */
1138 v4tov6(newip, o->data);
1139 if(!validv4(newip)){
1140 invalidate(ppp->local);
1144 /* if he gives us something different, use it anyways */
1145 v4tov6(ppp->local, o->data);
1149 if (!validv4(ppp->dns[0])){
1150 v4tov6(ppp->dns[0], o->data);
1154 v4tov6(newip, o->data);
1155 if(!validv4(newip)){
1156 invalidate(ppp->dns[0]);
1159 v4tov6(ppp->dns[0], o->data);
1163 if (!validv4(ppp->wins[0])){
1164 v4tov6(ppp->wins[0], o->data);
1168 v4tov6(newip, o->data);
1169 if(!validv4(newip)){
1170 invalidate(ppp->wins[0]);
1173 v4tov6(ppp->wins[0], o->data);
1177 if (!validv4(ppp->dns[1])){
1178 v4tov6(ppp->dns[1], o->data);
1182 v4tov6(newip, o->data);
1183 if(!validv4(newip)){
1184 invalidate(ppp->dns[1]);
1187 v4tov6(ppp->dns[1], o->data);
1191 if (!validv4(ppp->wins[1])){
1192 v4tov6(ppp->wins[1], o->data);
1196 v4tov6(newip, o->data);
1197 if(!validv4(newip)){
1198 invalidate(ppp->wins[1]);
1201 v4tov6(ppp->wins[1], o->data);
1215 * put a messages through the lcp or ipcp state machine. They are
1219 rcv(PPP *ppp, Pstate *p, Block *b)
1227 netlog("ppp: short lcp message\n");
1231 m = (Lcpmsg*)b->rptr;
1232 len = nhgets(m->len);
1234 netlog("ppp: short lcp message\n");
1239 netlog("ppp: %ux rcv %d len %ld id %d/%d/%d\n",
1240 p->proto, m->code, len, m->id, p->confid, p->id);
1242 if(p->proto != Plcp && ppp->lcp->state != Sopened){
1243 netlog("ppp: non-lcp with lcp not open\n");
1252 err = getopts(ppp, p, b);
1256 if(m->id == p->rcvdconfid)
1257 break; /* don't change state for duplicates */
1263 newstate(ppp, p, Sopened);
1269 newstate(ppp, p, Sacksent);
1271 newstate(ppp, p, Sreqsent);
1276 newstate(ppp, p, Sacksent);
1278 newstate(ppp, p, Sreqsent);
1283 if(p->confid != m->id){
1284 /* ignore if it isn't the message we're sending */
1285 netlog("ppp: dropping confack\n");
1288 p->confid = -1; /* ignore duplicates */
1289 p->id++; /* avoid sending duplicates */
1291 netlog("ppp: recv confack\n");
1296 newstate(ppp, p, Sreqsent);
1299 newstate(ppp, p, Sackrcvd);
1302 newstate(ppp, p, Sopened);
1308 if(p->confid != m->id) {
1309 /* ignore if it isn't the message we're sending */
1310 netlog("ppp: dropping confrej or confnak\n");
1313 p->confid = -1; /* ignore duplicates */
1314 p->id++; /* avoid sending duplicates */
1320 newstate(ppp, p, Sreqsent);
1325 rejopts(ppp, p, b, m->code);
1332 putframe(ppp, p->proto, b);
1337 newstate(ppp, p, Sreqsent);
1340 newstate(ppp, p, Sclosing);
1345 if(p->termid != m->id) /* ignore if it isn't the message we're sending */
1348 if(p->proto == Plcp)
1349 ppp->ipcp->state = Sclosed;
1352 newstate(ppp, p, Sclosed);
1355 newstate(ppp, p, Sreqsent);
1359 newstate(ppp, p, Sreqsent);
1364 //newstate(ppp, p, Sclosed);
1365 syslog(0, LOG, "code reject %d", m->data[0]);
1368 proto = nhgets(m->data);
1369 netlog("ppp: proto reject %ux\n", proto);
1371 newstate(ppp, ppp->ccp, Sclosed);
1375 netlog("ppp: short lcp echo request\n");
1380 hnputl(m->data, ppp->magic);
1381 putframe(ppp, p->proto, b);
1390 if(p->proto != Pccp)
1392 ppp->stat.compreset++;
1393 if(ppp->ctype != nil)
1394 b = (*ppp->ctype->resetreq)(ppp->cstate, b);
1396 m = (Lcpmsg*)b->rptr;
1397 m->code = Lresetack;
1398 putframe(ppp, p->proto, b);
1402 if(p->proto != Pccp)
1404 if(ppp->unctype != nil)
1405 (*ppp->unctype->resetack)(ppp->uncstate, b);
1414 * timer for protocol state machine
1417 ptimer(PPP *ppp, Pstate *p)
1419 if(p->state == Sopened || p->state == Sclosed)
1425 sendtermreq(ppp, p);
1430 newstate(ppp, p, Sclosed);
1437 newstate(ppp, p, Sclosed);
1440 newstate(ppp, p, Sreqsent);
1446 /* paptimer -- pap timer event handler
1448 * If PAP authorization hasn't come through, resend an authreqst. If
1449 * the maximum number of requests have been sent (~ 30 seconds), give
1456 if(ppp->chap->proto != APpasswd)
1459 if(ppp->chap->id < 21)
1463 netlog("ppp: pap timed out--not authorized\n");
1478 netlog("ppp: ppptimer\n");
1479 ptimer(ppp, ppp->lcp);
1480 if(ppp->lcp->state == Sopened) {
1483 ptimer(ppp, ppp->ccp);
1484 ptimer(ppp, ppp->ipcp);
1492 /* link quality measurement */
1493 if(ppp->period && --(ppp->timeout) <= 0){
1494 ppp->timeout = ppp->period;
1503 setdefroute(char *net, Ipaddr gate)
1508 snprint(path, sizeof path, "%s/iproute", net);
1509 fd = open(path, ORDWR);
1512 fprint(fd, "add 0 0 %I", gate);
1532 static int ipinprocpid;
1537 if(ipinprocpid <= 0){
1538 snprint(path, sizeof path, "%s/ipifc/clone", ppp->net);
1539 cfd = open(path, ORDWR);
1541 return "can't open ip interface";
1543 n = read(cfd, buf, sizeof(buf) - 1);
1546 return "can't open ip interface";
1550 netlog("ppp: setting up IP interface local %I remote %I (valid %d)\n",
1551 ppp->local, ppp->remote, validv4(ppp->remote));
1552 if(!validv4(ppp->remote))
1553 ipmove(ppp->remote, ppp->local);
1555 snprint(path, sizeof path, "%s/ipifc/%s/data", ppp->net, buf);
1556 fd = open(path, ORDWR);
1559 return "can't open ip interface";
1562 if(fprint(cfd, "bind pkt") < 0)
1563 return "binding pkt to ip interface";
1564 if(fprint(cfd, "add %I 255.255.255.255 %I %lud proxy", ppp->local,
1565 ppp->remote, ppp->mtu-10) < 0){
1567 return "can't set addresses";
1570 setdefroute(ppp->net, ppp->remote);
1574 /* signal main() that ip is configured */
1575 rendezvous((void*)Rmagic, 0);
1577 switch(ipinprocpid = rfork(RFPROC|RFMEM|RFNOWAIT)){
1579 sysfatal("forking ipinproc");
1586 /* we may have changed addresses */
1587 if(ipcmp(ppp->local, ppp->curlocal) != 0 ||
1588 ipcmp(ppp->remote, ppp->curremote) != 0){
1589 snprint(buf, sizeof buf, "remove %I 255.255.255.255 %I",
1590 ppp->curlocal, ppp->curremote);
1591 if(fprint(ppp->ipcfd, "%s", buf) < 0)
1592 syslog(0, "ppp", "can't %s: %r", buf);
1593 snprint(buf, sizeof buf, "add %I 255.255.255.255 %I %lud proxy",
1594 ppp->local, ppp->remote, ppp->mtu-10);
1595 if(fprint(ppp->ipcfd, "%s", buf) < 0)
1596 syslog(0, "ppp", "can't %s: %r", buf);
1598 syslog(0, "ppp", "%I/%I -> %I/%I", ppp->curlocal, ppp->curremote,
1599 ppp->local, ppp->remote);
1601 ipmove(ppp->curlocal, ppp->local);
1602 ipmove(ppp->curremote, ppp->remote);
1607 /* return next input IP packet */
1616 b = getframe(ppp, &proto);
1623 rcv(ppp, ppp->lcp, b);
1626 rcv(ppp, ppp->ccp, b);
1629 rcv(ppp, ppp->ipcp, b);
1632 if(ppp->ipcp->state == Sopened)
1634 netlog("ppp: IP recved: link not up\n");
1648 if(ppp->ipcp->state != Sopened){
1649 netlog("ppp: VJ tcp recved: link not up\n");
1654 b = tcpuncompress(ppp->ctcp, b, proto);
1661 if(ppp->ccp->state != Sopened){
1662 netlog("ppp: compressed data recved: link not up\n");
1666 if(ppp->unctype == nil) {
1667 netlog("ppp: compressed data recved: no compression\n");
1672 b = (*ppp->unctype->uncompress)(ppp, b, &proto, &reply);
1675 ppp->stat.uncompreset++;
1676 putframe(ppp, Pccp, reply);
1681 ppp->stat.uncompin += len;
1682 ppp->stat.uncompout += BLEN(b);
1683 /* netlog("ppp: uncompressed frame %ux %d %d (%d uchars)\n", proto, b->rptr[0], b->rptr[1], BLEN(b)); /* */
1686 syslog(0, LOG, "unknown proto %ux", proto);
1687 if(ppp->lcp->state == Sopened){
1688 /* reject the protocol */
1690 m = (Lcpmsg*)b->rptr;
1691 m->code = Lprotorej;
1692 m->id = ++ppp->lcp->id;
1693 hnputs(m->data, proto);
1694 hnputs(m->len, BLEN(b));
1695 putframe(ppp, Plcp, b);
1704 /* transmit an IP packet */
1706 pppwrite(PPP *ppp, Block *b)
1712 /* can't send ip packets till we're established */
1713 if(ppp->ipcp->state != Sopened) {
1715 syslog(0, LOG, "IP write: link not up");
1724 if(ppp->ipcp->flags & Fipcompress){
1725 b = compress(ppp->ctcp, b, &proto);
1734 if(ppp->ctype != nil) {
1736 b = (*ppp->ctype->compress)(ppp, proto, b, &proto);
1737 if(proto == Pcdata) {
1739 ppp->stat.compin += len;
1740 ppp->stat.compout += blen(b);
1744 if(putframe(ppp, proto, b) < 0) {
1757 terminate(PPP *ppp, int kill)
1763 close(ppp->mediain);
1764 close(ppp->mediaout);
1770 postnote(PNGROUP, getpid(), "die");
1773 typedef struct Iphdr Iphdr;
1776 uchar vihl; /* Version and header length */
1777 uchar tos; /* Type of service */
1778 uchar length[2]; /* packet length */
1779 uchar id[2]; /* Identification */
1780 uchar frag[2]; /* Fragment information */
1781 uchar ttl; /* Time to live */
1782 uchar proto; /* Protocol */
1783 uchar cksum[2]; /* Header checksum */
1784 uchar src[4]; /* Ip source (uchar ordering unimportant) */
1785 uchar dst[4]; /* Ip destination (uchar ordering unimportant) */
1798 n = read(ppp->ipfd, b->wptr, b->lim-b->wptr);
1802 /* trim packet if there's padding (e.g. from ether) */
1803 ip = (Iphdr*)b->rptr;
1804 m = nhgets(ip->length);
1809 if(pppwrite(ppp, b) < 0)
1815 catchdie(void*, char *msg)
1817 if(strstr(msg, "die") != nil)
1824 hexdump(uchar *a, int na)
1829 fprint(2, "dump %p %d\n", a, na);
1831 for(i=0; i<na; i++){
1832 sprint(buf+strlen(buf), " %.2ux", a[i]);
1834 sprint(buf+strlen(buf), " --");
1836 sprint(buf+strlen(buf), "\n");
1837 write(2, buf, strlen(buf));
1842 sprint(buf+strlen(buf), "\n");
1843 write(2, buf, strlen(buf));
1848 mediainproc(PPP *ppp)
1857 syslog(0, LOG, "pppread return nil");
1861 if(ppp->ipcp->state != Sopened) {
1862 ppp->stat.iprecvnotup++;
1868 v4tov6(remote, b->rptr+12);
1869 if(ipcmp(remote, ppp->remote) != 0) {
1870 ppp->stat.iprecvbadsrc++;
1876 netlog("ip write pkt %p %d\n", b->rptr, blen(b));
1877 hexdump(b->rptr, blen(b));
1879 if(write(ppp->ipfd, b->rptr, blen(b)) < 0) {
1880 syslog(0, LOG, "error writing to pktifc");
1888 netlog(": remote=%I: ppp shutting down\n", ppp->remote);
1889 syslog(0, LOG, ": remote=%I: ppp shutting down", ppp->remote);
1890 syslog(0, LOG, "\t\tppp send = %lud/%lud recv= %lud/%lud",
1891 ppp->out.packets, ppp->out.uchars,
1892 ppp->in.packets, ppp->in.uchars);
1893 syslog(0, LOG, "\t\tip send=%lud", ppp->stat.ipsend);
1894 syslog(0, LOG, "\t\tip recv=%lud notup=%lud badsrc=%lud",
1895 ppp->stat.iprecv, ppp->stat.iprecvnotup, ppp->stat.iprecvbadsrc);
1896 syslog(0, LOG, "\t\tcompress=%lud in=%lud out=%lud reset=%lud",
1897 ppp->stat.comp, ppp->stat.compin, ppp->stat.compout, ppp->stat.compreset);
1898 syslog(0, LOG, "\t\tuncompress=%lud in=%lud out=%lud reset=%lud",
1899 ppp->stat.uncomp, ppp->stat.uncompin, ppp->stat.uncompout,
1900 ppp->stat.uncompreset);
1901 syslog(0, LOG, "\t\tvjin=%lud vjout=%lud vjfail=%lud",
1902 ppp->stat.vjin, ppp->stat.vjout, ppp->stat.vjfail);
1906 * link quality management
1909 getlqm(PPP *ppp, Block *b)
1913 p = (Qualpkt*)b->rptr;
1914 if(BLEN(b) == sizeof(Qualpkt)){
1916 ppp->pout.reports = nhgetl(p->peeroutreports);
1917 ppp->pout.packets = nhgetl(p->peeroutpackets);
1918 ppp->pout.uchars = nhgetl(p->peeroutuchars);
1919 ppp->pin.reports = nhgetl(p->peerinreports);
1920 ppp->pin.packets = nhgetl(p->peerinpackets);
1921 ppp->pin.discards = nhgetl(p->peerindiscards);
1922 ppp->pin.errors = nhgetl(p->peerinerrors);
1923 ppp->pin.uchars = nhgetl(p->peerinuchars);
1925 /* save our numbers at time of reception */
1926 memmove(&ppp->sin, &ppp->in, sizeof(Qualstats));
1930 if(ppp->period == 0)
1941 b = allocb(sizeof(Qualpkt));
1942 b->wptr += sizeof(Qualpkt);
1943 p = (Qualpkt*)b->rptr;
1944 hnputl(p->magic, 0);
1946 /* heresay (what he last told us) */
1947 hnputl(p->lastoutreports, ppp->pout.reports);
1948 hnputl(p->lastoutpackets, ppp->pout.packets);
1949 hnputl(p->lastoutuchars, ppp->pout.uchars);
1951 /* our numbers at time of last reception */
1952 hnputl(p->peerinreports, ppp->sin.reports);
1953 hnputl(p->peerinpackets, ppp->sin.packets);
1954 hnputl(p->peerindiscards, ppp->sin.discards);
1955 hnputl(p->peerinerrors, ppp->sin.errors);
1956 hnputl(p->peerinuchars, ppp->sin.uchars);
1958 /* our numbers now */
1959 hnputl(p->peeroutreports, ppp->out.reports+1);
1960 hnputl(p->peeroutpackets, ppp->out.packets+1);
1961 hnputl(p->peeroutuchars, ppp->out.uchars+53/*hack*/);
1963 putframe(ppp, Plqm, b);
1969 * init challenge response dialog
1995 if((c->cs = auth_challenge("proto=%q role=server", aproto)) == nil)
1996 sysfatal("auth_challenge: %r");
1997 syslog(0, LOG, ": remote=%I: sending %d byte challenge", ppp->remote, c->cs->nchal);
1998 len = 4 + 1 + c->cs->nchal + strlen(ppp->chapname);
1999 b = alloclcp(Cchallenge, c->id, len, &m);
2001 *b->wptr++ = c->cs->nchal;
2002 memmove(b->wptr, c->cs->chal, c->cs->nchal);
2003 b->wptr += c->cs->nchal;
2004 memmove(b->wptr, ppp->chapname, strlen(ppp->chapname));
2005 b->wptr += strlen(ppp->chapname);
2006 hnputs(m->len, len);
2007 putframe(ppp, Pchap, b);
2010 c->state = Cchalsent;
2014 * BUG factotum should do this
2023 desencrypt(uchar data[8], uchar key[7])
2027 key_setup(key, ekey);
2028 block_cipher(ekey, data, 0);
2032 nthash(uchar hash[MShashlen], char *passwd)
2037 for(i=0; *passwd && i<sizeof(buf); passwd++) {
2041 memset(hash, 0, 16);
2042 md4(buf, i, hash, 0);
2046 mschalresp(uchar resp[MSresplen], uchar hash[MShashlen], uchar chal[MSchallen])
2051 memset(buf, 0, sizeof(buf));
2052 memcpy(buf, hash, MShashlen);
2054 for(i=0; i<3; i++) {
2055 memmove(resp+i*MSchallen, chal, MSchallen);
2056 desencrypt(resp+i*MSchallen, buf+i*7);
2061 * challenge response dialog
2063 extern int _asrdresp(int, uchar*, int);
2066 getchap(PPP *ppp, Block *b)
2070 int len, vlen, i, id, n, nresp;
2071 char md5buf[512], code;
2076 uchar digest[16], *p, *resp, sdigest[SHA1dlen];
2077 uchar mshash[MShashlen], mshash2[MShashlen];
2079 uchar msresp[2*MSresplen+1];
2081 m = (Lcpmsg*)b->rptr;
2082 len = nhgets(m->len);
2084 syslog(0, LOG, "short chap message");
2096 if(vlen > len - 5) {
2097 netlog("PPP: chap: bad challenge len\n");
2102 switch(ppp->chap->proto){
2106 n = strlen(ppp->secret);
2107 if(n + vlen + 1 > sizeof(md5buf)) {
2108 netlog("PPP: chap: bad challenge len\n");
2112 memcpy(md5buf+1, ppp->secret, n);
2113 memcpy(md5buf+1+n, m->data+1, vlen);
2114 md5((uchar*)md5buf, n + vlen + 1, digest, nil);
2119 nthash(mshash, ppp->secret);
2120 memset(msresp, 0, sizeof msresp);
2121 mschalresp(msresp+MSresplen, mshash, m->data+1);
2123 nresp = sizeof msresp;
2124 nthash(mshash, ppp->secret);
2125 md4(mshash, 16, mshash2, 0);
2126 s = sha1(mshash2, 16, 0, 0);
2127 sha1(mshash2, 16, 0, s);
2128 sha1(m->data+1, 8, sdigest, s);
2129 memmove(ppp->key, sdigest, 16);
2132 len = 4 + 1 + nresp + strlen(ppp->chapname);
2134 b = alloclcp(Cresponse, id, len, &m);
2136 memmove(b->wptr, resp, nresp);
2138 memmove(b->wptr, ppp->chapname, strlen(ppp->chapname));
2139 b->wptr += strlen(ppp->chapname);
2140 hnputs(m->len, len);
2141 netlog("PPP: sending response len %d\n", len);
2142 putframe(ppp, Pchap, b);
2147 if(m->id != c->id) {
2148 netlog("PPP: chap: bad response id\n");
2153 sysfatal("unknown chap protocol: %d", c->proto);
2155 if(vlen > len - 5 || vlen != 16) {
2156 netlog("PPP: chap: bad response len\n");
2161 memmove(cr.resp, m->data+1, 16);
2162 memset(uid, 0, sizeof(uid));
2166 memmove(uid, m->data+1+vlen, n);
2169 c->cs->nresp = sizeof cr;
2172 if(vlen > len - 5 || vlen != 49) {
2173 netlog("PPP: chap: bad response len\n");
2176 memset(&mscr, 0, sizeof(mscr));
2177 memmove(mscr.LMresp, m->data+1, 24);
2178 memmove(mscr.NTresp, m->data+24+1, 24);
2181 /* remove domain name */
2182 for(i=0; i<n; i++) {
2191 memset(uid, 0, sizeof(uid));
2194 c->cs->resp = 𝓂
2195 c->cs->nresp = sizeof mscr;
2199 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);
2200 if((ai = auth_response(c->cs)) == nil || auth_chuid(ai, nil) < 0){
2203 syslog(0, LOG, ": remote=%I: auth failed: %r, uid=%s", ppp->remote, uid);
2207 syslog(0, LOG, ": remote=%I: auth ok: uid=%s nsecret=%d", ppp->remote, uid, ai->nsecret);
2208 if(c->proto == APmschap){
2209 if(ai->nsecret != sizeof(ppp->key))
2210 sysfatal("could not get the encryption key");
2211 memmove(ppp->key, ai->secret, sizeof(ppp->key));
2215 auth_freechal(c->cs);
2221 b = alloclcp(code, c->id, len, &m);
2222 hnputs(m->len, len);
2223 putframe(ppp, Pchap, b);
2225 if(c->state == Cauthok) {
2226 setphase(ppp, Pnet);
2228 /* restart chapp negotiation */
2234 netlog("ppp: chap succeeded\n");
2235 setphase(ppp, Pnet);
2238 netlog("ppp: chap failed\n");
2242 syslog(0, LOG, "chap code %d?", m->code);
2251 putpaprequest(PPP *ppp)
2256 int len, nlen, slen;
2262 netlog("PPP: pap: send authreq %d %s %s\n", c->id, ppp->chapname, "****");
2264 nlen = strlen(ppp->chapname);
2265 slen = strlen(ppp->secret);
2266 len = 4 + 1 + nlen + 1 + slen;
2267 b = alloclcp(Pauthreq, c->id, len, &m);
2270 memmove(b->wptr, ppp->chapname, nlen);
2273 memmove(b->wptr, ppp->secret, slen);
2275 hnputs(m->len, len);
2277 putframe(ppp, Ppasswd, b);
2289 getpap(PPP *ppp, Block *b)
2294 m = (Lcpmsg*)b->rptr;
2296 if(BLEN(b) < 4 || BLEN(b) < (len = nhgets(m->len))){
2297 syslog(0, LOG, "short pap message (%zd < %d)", BLEN(b), len);
2301 if(len < sizeof(Lcpmsg))
2307 netlog("PPP: pap auth request, not supported\n");
2310 if(ppp->phase == Pauth
2311 && ppp->chap->proto == APpasswd
2312 && m->id <= ppp-> chap->id){
2313 netlog("PPP: pap succeeded\n");
2314 setphase(ppp, Pnet);
2318 if(ppp->phase == Pauth
2319 && ppp->chap->proto == APpasswd
2320 && m->id <= ppp-> chap->id){
2321 netlog("PPP: pap failed (%d:%.*s)\n",
2322 m->data[0], m->data[0], (char*)m->data+1);
2327 netlog("PPP: unknown pap messsage %d\n", m->code);
2334 printopts(Pstate *p, Block *b, int send)
2338 int proto, x, period;
2342 m = (Lcpmsg*)b->rptr;
2344 default: code = "<unknown>"; break;
2345 case Lconfreq: code = "confrequest"; break;
2346 case Lconfack: code = "confack"; break;
2347 case Lconfnak: code = "confnak"; break;
2348 case Lconfrej: code = "confreject"; break;
2356 netlog("ppp: %s %s: id=%d\n", dir, code, m->id);
2358 for(cp = m->data; cp < b->wptr; cp += o->len){
2360 if(cp + o->len > b->wptr){
2361 netlog("\tbad option length %ux\n", o->type);
2369 netlog("\tunknown %d len=%d\n", o->type, o->len);
2372 netlog("\tmtu = %d\n", nhgets(o->data));
2375 netlog("\tctlmap = %ux\n", nhgetl(o->data));
2378 netlog("\tauth = %ux", nhgetl(o->data));
2379 proto = nhgets(o->data);
2382 netlog("unknown auth proto %d\n", proto);
2385 netlog("password\n");
2388 netlog("chap %ux\n", o->data[2]);
2393 proto = nhgets(o->data);
2396 netlog("\tunknown quality proto %d\n", proto);
2399 x = nhgetl(o->data+2)*10;
2400 period = (x+Period-1)/Period;
2401 netlog("\tlqm period = %d\n", period);
2405 netlog("\tmagic = %ux\n", nhgetl(o->data));
2408 netlog("\tprotocol compress\n");
2411 netlog("\taddr compress\n");
2418 netlog("\tunknown %d len=%d\n", o->type, o->len);
2424 netlog("\tstac LZS\n");
2427 netlog("\tMicrosoft PPC len=%d %ux\n", o->len, nhgetl(o->data));
2430 netlog("\tThwack\n");
2437 netlog("\tunknown %d len=%d\n", o->type, o->len);
2450 netlog("\tunknown %d len=%d\n", o->type, o->len);
2453 netlog("\tip addrs - deprecated\n");
2456 netlog("\tip compress\n");
2459 netlog("\tip addr %V\n", o->data);
2462 netlog("\tdns addr %V\n", o->data);
2465 netlog("\twins addr %V\n", o->data);
2468 netlog("\tdns2 addr %V\n", o->data);
2471 netlog("\twins2 addr %V\n", o->data);
2480 sendtermreq(PPP *ppp, Pstate *p)
2485 p->termid = ++(p->id);
2486 b = alloclcp(Ltermreq, p->termid, 4, &m);
2488 putframe(ppp, p->proto, b);
2490 newstate(ppp, p, Sclosing);
2494 sendechoreq(PPP *ppp, Pstate *p)
2499 p->termid = ++(p->id);
2500 b = alloclcp(Lechoreq, p->id, 4, &m);
2502 putframe(ppp, p->proto, b);
2524 n = read(fd, xbuf, sizeof(xbuf));
2529 for(i = 0; i < n; i++)
2538 readcr(int fd, char *buf, int nbuf)
2544 while((n=read(fd, &c, 1)) == 1){
2551 sysfatal("line too long in readcr");
2557 connect(int fd, int cfd)
2563 int chatfd, lineno, nb;
2564 char *buf, *p, *s, response[128];
2567 if ((chatfd = open(chatfile, OREAD)) < 0)
2568 sysfatal("cannot open %s: %r", chatfile);
2570 if ((dir = dirfstat(chatfd)) == nil)
2571 sysfatal("cannot fstat %s: %r",chatfile);
2573 buf = (char *)malloc(dir->length + 1);
2576 if ((nb = read(chatfd, buf, dir->length)) < 0)
2577 sysfatal("cannot read chatfile %s: %r", chatfile);
2578 assert(nb == dir->length);
2579 buf[dir->length] = '\0';
2588 if ((s = strchr(p, '\n')) == nil)
2599 if (tokenize(p, _args, 3) != 2)
2600 sysfatal("invalid line %d (line expected: 'send' 'expect')",
2604 print("sending %s, expecting %s\n", _args[0], _args[1]);
2606 if(strlen(_args[0])){
2607 nb = fprint(fd, "%s\r", _args[0]);
2611 if (strlen(_args[1]) > 0) {
2612 if ((nb = readcr(fd, response, sizeof response-1)) < 0)
2613 sysfatal("cannot read response from: %r");
2616 print("response %s\n", response);
2619 sysfatal("eof on input?");
2621 if (cistrstr(response, _args[1]) == nil)
2622 sysfatal("expected %s, got %s", _args[1], response);
2630 print("Connect to file system now, type ctrl-d when done.\n");
2631 print("...(Use the view or down arrow key to send a break)\n");
2632 print("...(Use ctrl-e to set even parity or ctrl-o for odd)\n");
2634 ctl = open("/dev/consctl", OWRITE);
2636 sysfatal("opening consctl");
2637 fprint(ctl, "rawon");
2641 switch(rfork(RFPROC|RFMEM|RFNOWAIT)){
2643 sysfatal("forking xfer");
2651 switch(xbuf[0]&0xff) {
2652 case CtrlD: /* done */
2657 case CtrlE: /* set even parity */
2660 case CtrlO: /* set odd parity */
2663 case View: /* send a break */
2664 fprint(cfd, "k500");
2667 n = write(fd, xbuf, 1);
2669 errstr(xbuf, sizeof(xbuf));
2672 print("[remote write error (%s)]\n", xbuf);
2684 fprint(2, "usage: ppp [-CPSacdfu] [-b baud] [-k keyspec] [-m mtu] "
2685 "[-M chatfile] [-p dev] [-x netmntpt] [-t modemcmd] "
2686 "[local-addr [remote-addr]]\n");
2691 main(int argc, char **argv)
2693 int mtu, baud, framing, user, mediain, mediaout, cfd;
2694 Ipaddr ipaddr, remip;
2695 char *dev, *modemcmd;
2700 rfork(RFREND|RFNOTEG|RFNAMEG);
2702 fmtinstall('I', eipfmt);
2703 fmtinstall('V', eipfmt);
2704 fmtinstall('E', eipfmt);
2714 setnetmtpt(net, sizeof(net), nil);
2723 baud = atoi(EARGF(usage()));
2743 keyspec = EARGF(usage());
2746 mtu = atoi(EARGF(usage()));
2753 chatfile = EARGF(usage());
2756 dev = EARGF(usage());
2765 modemcmd = EARGF(usage());
2771 setnetmtpt(net, sizeof net, EARGF(usage()));
2774 fprint(2, "unknown option %c\n", ARGC());
2780 if (parseip(remip, argv[1]) == -1)
2781 sysfatal("bad remote ip %s", argv[1]);
2783 if (parseip(ipaddr, argv[0]) == -1)
2784 sysfatal("bad ip %s", argv[0]);
2792 if(nip == 0 && !server)
2796 mediain = open(dev, ORDWR);
2798 if(strchr(dev, '!')){
2799 if((mediain = dial(dev, 0, 0, &cfd)) == -1){
2800 fprint(2, "ppp: couldn't dial %s: %r\n", dev);
2804 fprint(2, "ppp: couldn't open %s\n", dev);
2808 snprint(buf, sizeof buf, "%sctl", dev);
2809 cfd = open(buf, ORDWR);
2813 fprint(cfd, "b%d", baud);
2814 fprint(cfd, "m1"); /* cts/rts flow control (and fifo's) on */
2815 fprint(cfd, "q64000"); /* increase q size to 64k */
2816 fprint(cfd, "n1"); /* nonblocking writes on */
2817 fprint(cfd, "r1"); /* rts on */
2818 fprint(cfd, "d1"); /* dtr on */
2819 fprint(cfd, "c1"); /* dcdhup on */
2820 if(user || chatfile)
2821 connect(mediain, cfd);
2824 if(user || chatfile)
2825 connect(mediain, -1);
2829 mediain = open("/fd/0", OREAD);
2831 fprint(2, "ppp: couldn't open /fd/0\n");
2834 mediaout = open("/fd/1", OWRITE);
2836 fprint(2, "ppp: couldn't open /fd/0\n");
2841 if(modemcmd != nil && mediaout >= 0)
2842 fprint(mediaout, "%s\r", modemcmd);
2844 ppp = mallocz(sizeof(*ppp), 1);
2845 pppopen(ppp, mediain, mediaout, net, ipaddr, remip, mtu, framing);
2847 /* wait until ip is configured */
2848 rendezvous((void*)Rmagic, 0);
2851 /* create a /net/ndb entry */
2859 netlog(char *fmt, ...)
2874 m = vsmprint(fmt, arg);
2875 fprint(2, "%ld %s", now-start, m);
2881 * return non-zero if this is a valid v4 address
2884 validv4(Ipaddr addr)
2886 return memcmp(addr, v4prefix, IPv4off) == 0 && memcmp(addr, v4prefix, IPaddrlen) != 0;
2890 invalidate(Ipaddr addr)
2892 ipmove(addr, IPnoaddr);
2896 * return number of networks
2907 ifc = readipifc(net, ifc, -1);
2908 for(nifc = ifc; nifc != nil; nifc = nifc->next)
2909 for(lifc = ifc->lifc; lifc != nil; lifc = lifc->next)
2915 * make an ndb entry and put it into /net/ndb for the servers to see
2918 putndb(PPP *ppp, char *net)
2925 e = buf + sizeof(buf);
2927 p = seprint(p, e, "ip=%I ipmask=255.255.255.255 ipgw=%I\n", ppp->local,
2929 if(validv4(ppp->dns[0]))
2930 p = seprint(p, e, "\tdns=%I\n", ppp->dns[0]);
2931 if(validv4(ppp->dns[1]))
2932 p = seprint(p, e, "\tdns=%I\n", ppp->dns[1]);
2933 if(validv4(ppp->wins[0]))
2934 p = seprint(p, e, "\twins=%I\n", ppp->wins[0]);
2935 if(validv4(ppp->wins[1]))
2936 p = seprint(p, e, "\twins=%I\n", ppp->wins[1]);
2937 seprint(file, file+sizeof file, "%s/ndb", net);
2938 fd = open(file, OWRITE);
2941 write(fd, buf, p-buf);
2943 seprint(file, file+sizeof file, "%s/cs", net);
2944 fd = open(file, OWRITE);
2945 write(fd, "refresh", 7);
2947 seprint(file, file+sizeof file, "%s/dns", net);
2948 fd = open(file, OWRITE);
2949 write(fd, "refresh", 7);
2961 up = auth_getuserpasswd(auth_getkey,"proto=pass service=ppp %s", keyspec);
2963 strcpy(ppp->chapname, up->user);
2964 strcpy(ppp->secret, up->passwd);