This source file includes following definitions.
- pppopen
- pppclose
- pppasyncrelinq
- pppread
- pppwrite
- ppptioctl
- pppfcs
- pppasyncstart
- pppasyncctlp
- pppstart
- ppp_timeout
- pppgetm
- pppinput
- ppplogchar
- pppdumpb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95 #include "ppp.h"
96 #if NPPP > 0
97
98 #define VJC
99 #define PPP_COMPRESS
100
101 #include <sys/param.h>
102 #include <sys/proc.h>
103 #include <sys/mbuf.h>
104 #include <sys/dkstat.h>
105 #include <sys/socket.h>
106 #include <sys/ioctl.h>
107 #include <sys/file.h>
108 #include <sys/tty.h>
109 #include <sys/kernel.h>
110 #include <sys/conf.h>
111 #include <sys/vnode.h>
112 #include <sys/systm.h>
113
114 #include <net/if.h>
115 #include <net/if_types.h>
116
117 #ifdef VJC
118 #include <netinet/in.h>
119 #include <netinet/in_systm.h>
120 #include <netinet/ip.h>
121 #include <net/slcompress.h>
122 #endif
123
124 #include <net/bpf.h>
125 #include <net/ppp_defs.h>
126 #include <net/if_ppp.h>
127 #include <net/if_pppvar.h>
128
129 int pppopen(dev_t dev, struct tty *tp);
130 int pppclose(struct tty *tp, int flag);
131 int pppread(struct tty *tp, struct uio *uio, int flag);
132 int pppwrite(struct tty *tp, struct uio *uio, int flag);
133 int ppptioctl(struct tty *tp, u_long cmd, caddr_t data, int flag,
134 struct proc *);
135 int pppinput(int c, struct tty *tp);
136 int pppstart(struct tty *tp, int);
137
138 u_int16_t pppfcs(u_int16_t fcs, u_char *cp, int len);
139 void pppasyncstart(struct ppp_softc *);
140 void pppasyncctlp(struct ppp_softc *);
141 void pppasyncrelinq(struct ppp_softc *);
142 void ppp_timeout(void *);
143 void pppgetm(struct ppp_softc *sc);
144 void pppdumpb(u_char *b, int l);
145 void ppplogchar(struct ppp_softc *, int);
146
147
148
149
150 #define M_IS_CLUSTER(m) ((m)->m_flags & M_EXT)
151
152 #define M_DATASTART(m) \
153 (M_IS_CLUSTER(m) ? (m)->m_ext.ext_buf : \
154 (m)->m_flags & M_PKTHDR ? (m)->m_pktdat : (m)->m_dat)
155
156 #define M_DATASIZE(m) \
157 (M_IS_CLUSTER(m) ? (m)->m_ext.ext_size : \
158 (m)->m_flags & M_PKTHDR ? MHLEN: MLEN)
159
160
161
162
163 #define ESCAPE_P(c) (sc->sc_asyncmap[(c) >> 5] & (1 << ((c) & 0x1F)))
164
165
166
167
168
169
170 #define CCOUNT(q) ((q)->c_cc)
171
172 #define PPP_LOWAT 100
173 #define PPP_HIWAT 400
174
175
176
177
178
179
180
181 int
182 pppopen(dev, tp)
183 dev_t dev;
184 struct tty *tp;
185 {
186 struct proc *p = curproc;
187 struct ppp_softc *sc;
188 int error, s;
189
190 if ((error = suser(p, 0)) != 0)
191 return (error);
192
193 s = spltty();
194
195 if (tp->t_line == PPPDISC) {
196 sc = (struct ppp_softc *) tp->t_sc;
197 if (sc != NULL && sc->sc_devp == (void *) tp) {
198 splx(s);
199 return (0);
200 }
201 }
202
203 if ((sc = pppalloc(p->p_pid)) == NULL) {
204 splx(s);
205 return ENXIO;
206 }
207
208 if (sc->sc_relinq)
209 (*sc->sc_relinq)(sc);
210
211 timeout_set(&sc->sc_timo, ppp_timeout, sc);
212 sc->sc_ilen = 0;
213 sc->sc_m = NULL;
214 bzero(sc->sc_asyncmap, sizeof(sc->sc_asyncmap));
215 sc->sc_asyncmap[0] = 0xffffffff;
216 sc->sc_asyncmap[3] = 0x60000000;
217 sc->sc_rasyncmap = 0;
218 sc->sc_devp = (void *) tp;
219 sc->sc_start = pppasyncstart;
220 sc->sc_ctlp = pppasyncctlp;
221 sc->sc_relinq = pppasyncrelinq;
222 sc->sc_outm = NULL;
223 pppgetm(sc);
224 sc->sc_if.if_flags |= IFF_RUNNING;
225 sc->sc_if.if_baudrate = tp->t_ospeed;
226
227 tp->t_sc = (caddr_t) sc;
228 ttyflush(tp, FREAD | FWRITE);
229
230 splx(s);
231 return (0);
232 }
233
234
235
236
237
238
239
240 int
241 pppclose(tp, flag)
242 struct tty *tp;
243 int flag;
244 {
245 struct ppp_softc *sc;
246 int s;
247
248 s = spltty();
249 ttyflush(tp, FREAD|FWRITE);
250 tp->t_line = 0;
251 sc = (struct ppp_softc *) tp->t_sc;
252 if (sc != NULL) {
253 tp->t_sc = NULL;
254 if (tp == (struct tty *) sc->sc_devp) {
255 pppasyncrelinq(sc);
256 pppdealloc(sc);
257 }
258 }
259 splx(s);
260 return 0;
261 }
262
263
264
265
266 void
267 pppasyncrelinq(sc)
268 struct ppp_softc *sc;
269 {
270 int s;
271
272 s = spltty();
273 if (sc->sc_outm) {
274 m_freem(sc->sc_outm);
275 sc->sc_outm = NULL;
276 }
277 if (sc->sc_m) {
278 m_freem(sc->sc_m);
279 sc->sc_m = NULL;
280 }
281 if (sc->sc_flags & SC_TIMEOUT) {
282 timeout_del(&sc->sc_timo);
283 sc->sc_flags &= ~SC_TIMEOUT;
284 }
285 splx(s);
286 }
287
288
289
290
291 int
292 pppread(tp, uio, flag)
293 struct tty *tp;
294 struct uio *uio;
295 int flag;
296 {
297 struct ppp_softc *sc = (struct ppp_softc *)tp->t_sc;
298 struct mbuf *m, *m0;
299 int s;
300 int error = 0;
301
302 if (sc == NULL)
303 return 0;
304
305
306
307
308 s = spltty();
309 for (;;) {
310 if (tp != (struct tty *) sc->sc_devp || tp->t_line != PPPDISC) {
311 splx(s);
312 return 0;
313 }
314 if (sc->sc_inq.ifq_head != NULL)
315 break;
316 if ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0
317 && (tp->t_state & TS_ISOPEN)) {
318 splx(s);
319 return 0;
320 }
321 if (tp->t_state & TS_ASYNC || flag & IO_NDELAY) {
322 splx(s);
323 return (EWOULDBLOCK);
324 }
325 error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI|PCATCH, ttyin, 0);
326 if (error) {
327 splx(s);
328 return error;
329 }
330 }
331
332
333 getc(&tp->t_canq);
334
335
336 IF_DEQUEUE(&sc->sc_inq, m0);
337 splx(s);
338
339 for (m = m0; m && uio->uio_resid; m = m->m_next)
340 if ((error = uiomove(mtod(m, u_char *), m->m_len, uio)) != 0)
341 break;
342 m_freem(m0);
343 return (error);
344 }
345
346
347
348
349 int
350 pppwrite(tp, uio, flag)
351 struct tty *tp;
352 struct uio *uio;
353 int flag;
354 {
355 struct ppp_softc *sc = (struct ppp_softc *)tp->t_sc;
356 struct mbuf *m, *m0, **mp;
357 struct sockaddr dst;
358 int len, error;
359
360 if ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0)
361 return 0;
362 if (tp->t_line != PPPDISC)
363 return (EINVAL);
364 if (sc == NULL || tp != (struct tty *) sc->sc_devp)
365 return EIO;
366 if (uio->uio_resid > sc->sc_if.if_mtu + PPP_HDRLEN ||
367 uio->uio_resid < PPP_HDRLEN)
368 return (EMSGSIZE);
369 for (mp = &m0; uio->uio_resid; mp = &m->m_next) {
370 if (mp == &m0) {
371 MGETHDR(m, M_WAIT, MT_DATA);
372 m->m_pkthdr.len = uio->uio_resid - PPP_HDRLEN;
373 m->m_pkthdr.rcvif = NULL;
374 } else
375 MGET(m, M_WAIT, MT_DATA);
376 *mp = m;
377 m->m_len = 0;
378 if (uio->uio_resid >= MCLBYTES / 2)
379 MCLGET(m, M_DONTWAIT);
380 len = M_TRAILINGSPACE(m);
381 if (len > uio->uio_resid)
382 len = uio->uio_resid;
383 if ((error = uiomove(mtod(m, u_char *), len, uio)) != 0) {
384 m_freem(m0);
385 return (error);
386 }
387 m->m_len = len;
388 }
389 dst.sa_family = AF_UNSPEC;
390 bcopy(mtod(m0, u_char *), dst.sa_data, PPP_HDRLEN);
391 m0->m_data += PPP_HDRLEN;
392 m0->m_len -= PPP_HDRLEN;
393 return ((*sc->sc_if.if_output)(&sc->sc_if, m0, &dst, (struct rtentry *)0));
394 }
395
396
397
398
399
400
401
402 int
403 ppptioctl(tp, cmd, data, flag, p)
404 struct tty *tp;
405 u_long cmd;
406 caddr_t data;
407 int flag;
408 struct proc *p;
409 {
410 struct ppp_softc *sc = (struct ppp_softc *) tp->t_sc;
411 int error, s;
412
413 if (sc == NULL || tp != (struct tty *) sc->sc_devp)
414 return -1;
415
416 error = 0;
417 switch (cmd) {
418 case PPPIOCSASYNCMAP:
419 if ((error = suser(p, 0)) != 0)
420 break;
421 sc->sc_asyncmap[0] = *(u_int *)data;
422 break;
423
424 case PPPIOCGASYNCMAP:
425 *(u_int *)data = sc->sc_asyncmap[0];
426 break;
427
428 case PPPIOCSRASYNCMAP:
429 if ((error = suser(p, 0)) != 0)
430 break;
431 sc->sc_rasyncmap = *(u_int *)data;
432 break;
433
434 case PPPIOCGRASYNCMAP:
435 *(u_int *)data = sc->sc_rasyncmap;
436 break;
437
438 case PPPIOCSXASYNCMAP:
439 if ((error = suser(p, 0)) != 0)
440 break;
441 s = spltty();
442 bcopy(data, sc->sc_asyncmap, sizeof(sc->sc_asyncmap));
443 sc->sc_asyncmap[1] = 0;
444 sc->sc_asyncmap[2] &= ~0x40000000;
445 sc->sc_asyncmap[3] |= 0x60000000;
446 splx(s);
447 break;
448
449 case PPPIOCGXASYNCMAP:
450 bcopy(sc->sc_asyncmap, data, sizeof(sc->sc_asyncmap));
451 break;
452
453 default:
454 error = pppioctl(sc, cmd, data, flag, p);
455 if (error == 0 && cmd == PPPIOCSMRU)
456 pppgetm(sc);
457 }
458
459 return error;
460 }
461
462
463
464
465 static u_int16_t fcstab[256] = {
466 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
467 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
468 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
469 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
470 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
471 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
472 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
473 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
474 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
475 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
476 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
477 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
478 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
479 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
480 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
481 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
482 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
483 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
484 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
485 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
486 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
487 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
488 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
489 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
490 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
491 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
492 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
493 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
494 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
495 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
496 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
497 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
498 };
499
500
501
502
503 u_int16_t
504 pppfcs(fcs, cp, len)
505 u_int16_t fcs;
506 u_char *cp;
507 int len;
508 {
509 while (len--)
510 fcs = PPP_FCS(fcs, *cp++);
511 return (fcs);
512 }
513
514
515
516
517
518 void
519 pppasyncstart(sc)
520 struct ppp_softc *sc;
521 {
522 struct tty *tp = (struct tty *) sc->sc_devp;
523 struct mbuf *m;
524 int len;
525 u_char *start, *stop, *cp;
526 int n, ndone, done, idle;
527 struct mbuf *m2;
528 int s;
529
530 idle = 0;
531 while (CCOUNT(&tp->t_outq) < PPP_HIWAT) {
532
533
534
535
536 m = sc->sc_outm;
537 if (m == NULL) {
538
539
540
541 m = ppp_dequeue(sc);
542 if (m == NULL) {
543 idle = 1;
544 break;
545 }
546
547
548
549
550
551
552 if (CCOUNT(&tp->t_outq) == 0) {
553 ++sc->sc_stats.ppp_obytes;
554 (void) putc(PPP_FLAG, &tp->t_outq);
555 }
556
557
558 sc->sc_outfcs = pppfcs(PPP_INITFCS, mtod(m, u_char *), m->m_len);
559 }
560
561 for (;;) {
562 start = mtod(m, u_char *);
563 len = m->m_len;
564 stop = start + len;
565 while (len > 0) {
566
567
568
569
570 for (cp = start; cp < stop; cp++)
571 if (ESCAPE_P(*cp))
572 break;
573 n = cp - start;
574 if (n) {
575
576 ndone = n - b_to_q(start, n, &tp->t_outq);
577 len -= ndone;
578 start += ndone;
579 sc->sc_stats.ppp_obytes += ndone;
580
581 if (ndone < n)
582 break;
583 }
584
585
586
587
588
589 if (len) {
590 s = spltty();
591 if (putc(PPP_ESCAPE, &tp->t_outq)) {
592 splx(s);
593 break;
594 }
595 if (putc(*start ^ PPP_TRANS, &tp->t_outq)) {
596 (void) unputc(&tp->t_outq);
597 splx(s);
598 break;
599 }
600 splx(s);
601 sc->sc_stats.ppp_obytes += 2;
602 start++;
603 len--;
604 }
605 }
606
607
608
609
610
611
612
613 done = len == 0;
614 if (done && m->m_next == NULL) {
615 u_char *p, *q;
616 int c;
617 u_char endseq[8];
618
619
620
621
622 p = endseq;
623 c = ~sc->sc_outfcs & 0xFF;
624 if (ESCAPE_P(c)) {
625 *p++ = PPP_ESCAPE;
626 *p++ = c ^ PPP_TRANS;
627 } else
628 *p++ = c;
629 c = (~sc->sc_outfcs >> 8) & 0xFF;
630 if (ESCAPE_P(c)) {
631 *p++ = PPP_ESCAPE;
632 *p++ = c ^ PPP_TRANS;
633 } else
634 *p++ = c;
635 *p++ = PPP_FLAG;
636
637
638
639
640
641 s = spltty();
642 for (q = endseq; q < p; ++q)
643 if (putc(*q, &tp->t_outq)) {
644 done = 0;
645 for (; q > endseq; --q)
646 unputc(&tp->t_outq);
647 break;
648 }
649 splx(s);
650 if (done)
651 sc->sc_stats.ppp_obytes += q - endseq;
652 }
653
654 if (!done) {
655
656 m->m_data = start;
657 m->m_len = len;
658 break;
659 }
660
661
662 MFREE(m, m2);
663 m = m2;
664 if (m == NULL) {
665
666 break;
667 }
668 sc->sc_outfcs = pppfcs(sc->sc_outfcs, mtod(m, u_char *), m->m_len);
669 }
670
671
672
673
674
675
676 sc->sc_outm = m;
677 if (m)
678 break;
679 }
680
681
682 s = spltty();
683 pppstart(tp, 0);
684
685
686
687
688
689
690 if (!idle && (sc->sc_flags & SC_TIMEOUT) == 0) {
691 timeout_add(&sc->sc_timo, 1);
692 sc->sc_flags |= SC_TIMEOUT;
693 }
694
695 splx(s);
696 }
697
698
699
700
701
702 void
703 pppasyncctlp(sc)
704 struct ppp_softc *sc;
705 {
706 struct tty *tp;
707 int s;
708
709
710 s = spltty();
711 tp = (struct tty *) sc->sc_devp;
712 putc(0, &tp->t_canq);
713 ttwakeup(tp);
714 splx(s);
715 }
716
717
718
719
720
721
722 int
723 pppstart(tp, force)
724 struct tty *tp;
725 int force;
726 {
727 struct ppp_softc *sc = (struct ppp_softc *) tp->t_sc;
728
729
730
731
732
733 if (tp->t_oproc != NULL)
734 (*tp->t_oproc)(tp);
735
736 #ifdef ALTQ
737
738
739
740
741
742 if (ALTQ_IS_ENABLED(&sc->sc_if.if_snd))
743 return 0;
744 #endif
745
746
747
748
749
750 if ((CCOUNT(&tp->t_outq) < PPP_LOWAT || force)
751 && !((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0)
752 && sc != NULL && tp == (struct tty *) sc->sc_devp) {
753 ppp_restart(sc);
754 }
755
756 return 0;
757 }
758
759
760
761
762 void
763 ppp_timeout(x)
764 void *x;
765 {
766 struct ppp_softc *sc = (struct ppp_softc *) x;
767 struct tty *tp = (struct tty *) sc->sc_devp;
768 int s;
769
770 s = spltty();
771 sc->sc_flags &= ~SC_TIMEOUT;
772 pppstart(tp, 1);
773 splx(s);
774 }
775
776
777
778
779 void
780 pppgetm(sc)
781 struct ppp_softc *sc;
782 {
783 struct mbuf *m, **mp;
784 int len;
785 int s;
786
787 s = spltty();
788 mp = &sc->sc_m;
789 for (len = sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN; len > 0; ){
790 if ((m = *mp) == NULL) {
791 MGETHDR(m, M_DONTWAIT, MT_DATA);
792 if (m == NULL)
793 break;
794 *mp = m;
795 MCLGET(m, M_DONTWAIT);
796 }
797 len -= M_DATASIZE(m);
798 mp = &m->m_next;
799 }
800 splx(s);
801 }
802
803
804
805
806 static unsigned int paritytab[8] = {
807 0x96696996, 0x69969669, 0x69969669, 0x96696996,
808 0x69969669, 0x96696996, 0x96696996, 0x69969669
809 };
810
811 int
812 pppinput(c, tp)
813 int c;
814 struct tty *tp;
815 {
816 struct ppp_softc *sc;
817 struct mbuf *m;
818 int ilen, s;
819
820 sc = (struct ppp_softc *) tp->t_sc;
821 if (sc == NULL || tp != (struct tty *) sc->sc_devp)
822 return 0;
823
824 ++tk_nin;
825 ++sc->sc_stats.ppp_ibytes;
826
827 if (c & TTY_FE) {
828
829 if (sc->sc_flags & SC_DEBUG)
830 printf("%s: bad char %x\n", sc->sc_if.if_xname, c);
831 goto flush;
832 }
833
834 c &= 0xff;
835
836
837
838
839 if (tp->t_iflag & IXON) {
840 if (c == tp->t_cc[VSTOP] && tp->t_cc[VSTOP] != _POSIX_VDISABLE) {
841 if ((tp->t_state & TS_TTSTOP) == 0) {
842 tp->t_state |= TS_TTSTOP;
843 (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
844 }
845 return 0;
846 }
847 if (c == tp->t_cc[VSTART] && tp->t_cc[VSTART] != _POSIX_VDISABLE) {
848 tp->t_state &= ~TS_TTSTOP;
849 if (tp->t_oproc != NULL)
850 (*tp->t_oproc)(tp);
851 return 0;
852 }
853 }
854
855 s = spltty();
856 if (c & 0x80)
857 sc->sc_flags |= SC_RCV_B7_1;
858 else
859 sc->sc_flags |= SC_RCV_B7_0;
860 if (paritytab[c >> 5] & (1 << (c & 0x1F)))
861 sc->sc_flags |= SC_RCV_ODDP;
862 else
863 sc->sc_flags |= SC_RCV_EVNP;
864 splx(s);
865
866 if (sc->sc_flags & SC_LOG_RAWIN)
867 ppplogchar(sc, c);
868
869 if (c == PPP_FLAG) {
870 ilen = sc->sc_ilen;
871 sc->sc_ilen = 0;
872
873 if (sc->sc_rawin_count > 0)
874 ppplogchar(sc, -1);
875
876
877
878
879
880 if (sc->sc_flags & (SC_FLUSH | SC_ESCAPED)
881 || (ilen > 0 && sc->sc_fcs != PPP_GOODFCS)) {
882 s = spltty();
883 sc->sc_flags |= SC_PKTLOST;
884 if ((sc->sc_flags & (SC_FLUSH | SC_ESCAPED)) == 0){
885 if (sc->sc_flags & SC_DEBUG)
886 printf("%s: bad fcs %x\n", sc->sc_if.if_xname,
887 sc->sc_fcs);
888 sc->sc_if.if_ierrors++;
889 sc->sc_stats.ppp_ierrors++;
890 } else
891 sc->sc_flags &= ~(SC_FLUSH | SC_ESCAPED);
892 splx(s);
893 return 0;
894 }
895
896 if (ilen < PPP_HDRLEN + PPP_FCSLEN) {
897 if (ilen) {
898 if (sc->sc_flags & SC_DEBUG)
899 printf("%s: too short (%d)\n", sc->sc_if.if_xname, ilen);
900 s = spltty();
901 sc->sc_if.if_ierrors++;
902 sc->sc_stats.ppp_ierrors++;
903 sc->sc_flags |= SC_PKTLOST;
904 splx(s);
905 }
906 return 0;
907 }
908
909
910
911
912 ilen -= 2;
913 if (--sc->sc_mc->m_len == 0) {
914 for (m = sc->sc_m; m->m_next != sc->sc_mc; m = m->m_next)
915 ;
916 sc->sc_mc = m;
917 }
918 sc->sc_mc->m_len--;
919
920
921 m = sc->sc_m;
922 sc->sc_m = sc->sc_mc->m_next;
923 sc->sc_mc->m_next = NULL;
924
925 ppppktin(sc, m, sc->sc_flags & SC_PKTLOST);
926 if (sc->sc_flags & SC_PKTLOST) {
927 s = spltty();
928 sc->sc_flags &= ~SC_PKTLOST;
929 splx(s);
930 }
931
932 pppgetm(sc);
933 return 0;
934 }
935
936 if (sc->sc_flags & SC_FLUSH) {
937 if (sc->sc_flags & SC_LOG_FLUSH)
938 ppplogchar(sc, c);
939 return 0;
940 }
941
942 if (c < 0x20 && (sc->sc_rasyncmap & (1 << c)))
943 return 0;
944
945 s = spltty();
946 if (sc->sc_flags & SC_ESCAPED) {
947 sc->sc_flags &= ~SC_ESCAPED;
948 c ^= PPP_TRANS;
949 } else if (c == PPP_ESCAPE) {
950 sc->sc_flags |= SC_ESCAPED;
951 splx(s);
952 return 0;
953 }
954 splx(s);
955
956
957
958
959
960
961
962
963
964
965 if (sc->sc_ilen == 0) {
966
967 if (sc->sc_m == NULL) {
968 pppgetm(sc);
969 if (sc->sc_m == NULL) {
970 if (sc->sc_flags & SC_DEBUG)
971 printf("%s: no input mbufs!\n", sc->sc_if.if_xname);
972 goto flush;
973 }
974 }
975 m = sc->sc_m;
976 m->m_len = 0;
977 m->m_data = M_DATASTART(sc->sc_m);
978 sc->sc_mc = m;
979 sc->sc_mp = mtod(m, char *);
980 sc->sc_fcs = PPP_INITFCS;
981 if (c != PPP_ALLSTATIONS) {
982 if (sc->sc_flags & SC_REJ_COMP_AC) {
983 if (sc->sc_flags & SC_DEBUG)
984 printf("%s: garbage received: 0x%x (need 0xFF)\n",
985 sc->sc_if.if_xname, c);
986 goto flush;
987 }
988 *sc->sc_mp++ = PPP_ALLSTATIONS;
989 *sc->sc_mp++ = PPP_UI;
990 sc->sc_ilen += 2;
991 m->m_len += 2;
992 }
993 }
994 if (sc->sc_ilen == 1 && c != PPP_UI) {
995 if (sc->sc_flags & SC_DEBUG)
996 printf("%s: missing UI (0x3), got 0x%x\n",
997 sc->sc_if.if_xname, c);
998 goto flush;
999 }
1000 if (sc->sc_ilen == 2 && (c & 1) == 1) {
1001
1002 *sc->sc_mp++ = 0;
1003 sc->sc_ilen++;
1004 sc->sc_mc->m_len++;
1005 }
1006 if (sc->sc_ilen == 3 && (c & 1) == 0) {
1007 if (sc->sc_flags & SC_DEBUG)
1008 printf("%s: bad protocol %x\n", sc->sc_if.if_xname,
1009 (sc->sc_mp[-1] << 8) + c);
1010 goto flush;
1011 }
1012
1013
1014 if (++sc->sc_ilen > sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN) {
1015 if (sc->sc_flags & SC_DEBUG)
1016 printf("%s: packet too big\n", sc->sc_if.if_xname);
1017 goto flush;
1018 }
1019
1020
1021 m = sc->sc_mc;
1022 if (M_TRAILINGSPACE(m) <= 0) {
1023 if (m->m_next == NULL) {
1024 pppgetm(sc);
1025 if (m->m_next == NULL) {
1026 if (sc->sc_flags & SC_DEBUG)
1027 printf("%s: too few input mbufs!\n", sc->sc_if.if_xname);
1028 goto flush;
1029 }
1030 }
1031 sc->sc_mc = m = m->m_next;
1032 m->m_len = 0;
1033 m->m_data = M_DATASTART(m);
1034 sc->sc_mp = mtod(m, char *);
1035 }
1036
1037 ++m->m_len;
1038 *sc->sc_mp++ = c;
1039 sc->sc_fcs = PPP_FCS(sc->sc_fcs, c);
1040 return 0;
1041
1042 flush:
1043 if (!(sc->sc_flags & SC_FLUSH)) {
1044 s = spltty();
1045 sc->sc_if.if_ierrors++;
1046 sc->sc_stats.ppp_ierrors++;
1047 sc->sc_flags |= SC_FLUSH;
1048 splx(s);
1049 if (sc->sc_flags & SC_LOG_FLUSH)
1050 ppplogchar(sc, c);
1051 }
1052 return 0;
1053 }
1054
1055 #define MAX_DUMP_BYTES 128
1056
1057 void
1058 ppplogchar(sc, c)
1059 struct ppp_softc *sc;
1060 int c;
1061 {
1062 if (c >= 0)
1063 sc->sc_rawin[sc->sc_rawin_count++] = c;
1064 if (sc->sc_rawin_count >= sizeof(sc->sc_rawin)
1065 || (c < 0 && sc->sc_rawin_count > 0)) {
1066 printf("%s input: ", sc->sc_if.if_xname);
1067 pppdumpb(sc->sc_rawin, sc->sc_rawin_count);
1068 sc->sc_rawin_count = 0;
1069 }
1070 }
1071
1072 void
1073 pppdumpb(b, l)
1074 u_char *b;
1075 int l;
1076 {
1077 char buf[3*MAX_DUMP_BYTES+4];
1078 char *bp = buf;
1079 static char digits[] = "0123456789abcdef";
1080
1081 while (l--) {
1082 if (bp >= buf + sizeof(buf) - 3) {
1083 *bp++ = '>';
1084 break;
1085 }
1086 *bp++ = digits[*b >> 4];
1087 *bp++ = digits[*b++ & 0xf];
1088 *bp++ = ' ';
1089 }
1090
1091 *bp = 0;
1092 printf("%s\n", buf);
1093 }
1094
1095 #endif