Bug Summary

File:net/ppp_tty.c
Warning:line 893, column 2
Value stored to 'ilen' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ppp_tty.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -D CONFIG_DRM_AMD_DC_DCN3_0 -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -o /usr/obj/sys/arch/amd64/compile/GENERIC.MP/scan-build/2022-01-12-131800-47421-1 -x c /usr/src/sys/net/ppp_tty.c
1/* $OpenBSD: ppp_tty.c,v 1.54 2022/01/02 22:36:04 jsg Exp $ */
2/* $NetBSD: ppp_tty.c,v 1.12 1997/03/24 21:23:10 christos Exp $ */
3
4/*
5 * ppp_tty.c - Point-to-Point Protocol (PPP) driver for asynchronous
6 * tty devices.
7 *
8 * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 *
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 *
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in
19 * the documentation and/or other materials provided with the
20 * distribution.
21 *
22 * 3. The name "Carnegie Mellon University" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For permission or any legal
25 * details, please contact
26 * Office of Technology Transfer
27 * Carnegie Mellon University
28 * 5000 Forbes Avenue
29 * Pittsburgh, PA 15213-3890
30 * (412) 268-4387, fax: (412) 268-7395
31 * tech-transfer@andrew.cmu.edu
32 *
33 * 4. Redistributions of any form whatsoever must retain the following
34 * acknowledgment:
35 * "This product includes software developed by Computing Services
36 * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
37 *
38 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
39 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
40 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
41 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
42 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
43 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
44 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
45 *
46 * Based on:
47 * @(#)if_sl.c 7.6.1.2 (Berkeley) 2/15/89
48 *
49 * Copyright (c) 1987 Regents of the University of California.
50 * All rights reserved.
51 *
52 * Redistribution and use in source and binary forms are permitted
53 * provided that the above copyright notice and this paragraph are
54 * duplicated in all such forms and that any documentation,
55 * advertising materials, and other materials related to such
56 * distribution and use acknowledge that the software was developed
57 * by the University of California, Berkeley. The name of the
58 * University may not be used to endorse or promote products derived
59 * from this software without specific prior written permission.
60 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
61 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
62 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
63 *
64 * Serial Line interface
65 *
66 * Rick Adams
67 * Center for Seismic Studies
68 * 1300 N 17th Street, Suite 1450
69 * Arlington, Virginia 22209
70 * (703)276-7900
71 * rick@seismo.ARPA
72 * seismo!rick
73 *
74 * Pounded on heavily by Chris Torek (chris@mimsy.umd.edu, umcp-cs!chris).
75 * Converted to 4.3BSD Beta by Chris Torek.
76 * Other changes made at Berkeley, based in part on code by Kirk Smith.
77 *
78 * Converted to 4.3BSD+ 386BSD by Brad Parker (brad@cayman.com)
79 * Added VJ tcp header compression; more unified ioctls
80 *
81 * Extensively modified by Paul Mackerras (paulus@cs.anu.edu.au).
82 * Cleaned up a lot of the mbuf-related code to fix bugs that
83 * caused system crashes and packet corruption. Changed pppstart
84 * so that it doesn't just give up with a collision if the whole
85 * packet doesn't fit in the output ring buffer.
86 *
87 * Added priority queueing for interactive IP packets, following
88 * the model of if_sl.c, plus hooks for bpf.
89 * Paul Mackerras (paulus@cs.anu.edu.au).
90 */
91
92/* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp */
93/* from NetBSD: if_ppp.c,v 1.15.2.2 1994/07/28 05:17:58 cgd Exp */
94
95#include "ppp.h"
96#if NPPP1 > 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/socket.h>
105#include <sys/timeout.h>
106#include <sys/ioctl.h>
107#include <sys/fcntl.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#include <sys/rwlock.h>
114#include <sys/pool.h>
115
116#include <net/if.h>
117#include <net/if_var.h>
118
119#ifdef VJC
120#include <netinet/in.h>
121#include <netinet/ip.h>
122#include <net/slcompress.h>
123#endif
124
125#include <net/bpf.h>
126#include <net/ppp_defs.h>
127#include <net/if_ppp.h>
128#include <net/if_pppvar.h>
129
130int pppstart_internal(struct tty *tp, int);
131
132u_int16_t pppfcs(u_int16_t fcs, u_char *cp, int len);
133void pppasyncstart(struct ppp_softc *);
134void pppasyncctlp(struct ppp_softc *);
135void pppasyncrelinq(struct ppp_softc *);
136void ppp_timeout(void *);
137void ppppkt(struct ppp_softc *sc);
138void pppdumpb(u_char *b, int l);
139void ppplogchar(struct ppp_softc *, int);
140
141struct rwlock ppp_pkt_init = RWLOCK_INITIALIZER("ppppktini"){ 0, "ppppktini" };
142struct pool ppp_pkts;
143
144#define PKT_MAXLEN(_sc)((_sc)->sc_mru + 4 + 2) ((_sc)->sc_mru + PPP_HDRLEN4 + PPP_FCSLEN2)
145
146/*
147 * Does c need to be escaped?
148 */
149#define ESCAPE_P(c)(sc->sc_asyncmap[(c) >> 5] & (1 << ((c) &
0x1F)))
(sc->sc_asyncmap[(c) >> 5] & (1 << ((c) & 0x1F)))
150
151/*
152 * Procedures for using an async tty interface for PPP.
153 */
154
155/* This is a NetBSD-1.0 or later kernel. */
156#define CCOUNT(q)((q)->c_cc) ((q)->c_cc)
157
158/*
159 * Line specific open routine for async tty devices.
160 * Attach the given tty to the first available ppp unit.
161 * Called from device open routine or ttioctl.
162 */
163int
164pppopen(dev_t dev, struct tty *tp, struct proc *p)
165{
166 struct ppp_softc *sc;
167 int error, s;
168
169 if ((error = suser(p)) != 0)
170 return (error);
171
172 rw_enter_write(&ppp_pkt_init);
173 if (ppp_pkts.pr_size == 0) {
174 extern const struct kmem_pa_mode kp_dma_contig;
175
176 pool_init(&ppp_pkts, sizeof(struct ppp_pkt), 0,
177 IPL_TTY0x9, 0, "ppppkts", NULL((void *)0)); /* IPL_SOFTTTY */
178 pool_set_constraints(&ppp_pkts, &kp_dma_contig);
179 }
180 rw_exit_write(&ppp_pkt_init);
181
182 s = spltty()splraise(0x9);
183
184 if (tp->t_line == PPPDISC5) {
185 sc = (struct ppp_softc *) tp->t_sc;
186 if (sc != NULL((void *)0) && sc->sc_devp == (void *) tp) {
187 splx(s)spllower(s);
188 return (0);
189 }
190 }
191
192 if ((sc = pppalloc(p->p_p->ps_pid)) == NULL((void *)0)) {
193 splx(s)spllower(s);
194 return ENXIO6;
195 }
196
197 if (sc->sc_relinq)
198 (*sc->sc_relinq)(sc); /* get previous owner to relinquish the unit */
199
200 timeout_set(&sc->sc_timo, ppp_timeout, sc);
201 sc->sc_ilen = 0;
202 sc->sc_pkt = NULL((void *)0);
203 bzero(sc->sc_asyncmap, sizeof(sc->sc_asyncmap))__builtin_bzero((sc->sc_asyncmap), (sizeof(sc->sc_asyncmap
)))
;
204 sc->sc_asyncmap[0] = 0xffffffff;
205 sc->sc_asyncmap[3] = 0x60000000;
206 sc->sc_rasyncmap = 0;
207 sc->sc_devp = (void *) tp;
208 sc->sc_start = pppasyncstart;
209 sc->sc_ctlp = pppasyncctlp;
210 sc->sc_relinq = pppasyncrelinq;
211 sc->sc_outm = NULL((void *)0);
212 ppppkt(sc);
213 sc->sc_if.if_flags |= IFF_RUNNING0x40;
214 sc->sc_if.if_baudrateif_data.ifi_baudrate = tp->t_ospeedt_termios.c_ospeed;
215
216 tp->t_sc = (caddr_t) sc;
217 ttyflush(tp, FREAD0x0001 | FWRITE0x0002);
218
219 splx(s)spllower(s);
220 return (0);
221}
222
223/*
224 * Line specific close routine, called from device close routine
225 * and from ttioctl.
226 * Detach the tty from the ppp unit.
227 * Mimics part of ttyclose().
228 */
229int
230pppclose(struct tty *tp, int flag, struct proc *p)
231{
232 struct ppp_softc *sc;
233 int s;
234
235 s = spltty()splraise(0x9);
236 ttyflush(tp, FREAD0x0001|FWRITE0x0002);
237 tp->t_line = 0;
238 sc = (struct ppp_softc *) tp->t_sc;
239 if (sc != NULL((void *)0)) {
240 tp->t_sc = NULL((void *)0);
241 if (tp == (struct tty *) sc->sc_devp) {
242 pppasyncrelinq(sc);
243 pppdealloc(sc);
244 }
245 }
246 splx(s)spllower(s);
247 return 0;
248}
249
250/*
251 * Relinquish the interface unit to another device.
252 */
253void
254pppasyncrelinq(struct ppp_softc *sc)
255{
256 int s;
257
258 KERNEL_LOCK()_kernel_lock();
259 s = spltty()splraise(0x9);
260 m_freem(sc->sc_outm);
261 sc->sc_outm = NULL((void *)0);
262
263 if (sc->sc_pkt != NULL((void *)0)) {
264 ppp_pkt_free(sc->sc_pkt);
265 sc->sc_pkt = sc->sc_pktc = NULL((void *)0);
266 }
267 if (sc->sc_flags & SC_TIMEOUT0x00000400) {
268 timeout_del(&sc->sc_timo);
269 sc->sc_flags &= ~SC_TIMEOUT0x00000400;
270 }
271 splx(s)spllower(s);
272 KERNEL_UNLOCK()_kernel_unlock();
273}
274
275/*
276 * Line specific (tty) read routine.
277 */
278int
279pppread(struct tty *tp, struct uio *uio, int flag)
280{
281 struct ppp_softc *sc = (struct ppp_softc *)tp->t_sc;
282 struct mbuf *m, *m0;
283 int s;
284 int error = 0;
285
286 if (sc == NULL((void *)0))
287 return 0;
288 /*
289 * Loop waiting for input, checking that nothing disastrous
290 * happens in the meantime.
291 */
292 s = spltty()splraise(0x9);
293 for (;;) {
294 if (tp != (struct tty *) sc->sc_devp || tp->t_line != PPPDISC5) {
295 splx(s)spllower(s);
296 return 0;
297 }
298 /* Get the packet from the input queue */
299 m0 = mq_dequeue(&sc->sc_inq);
300 if (m0 != NULL((void *)0))
301 break;
302 if ((tp->t_state & TS_CARR_ON0x00008) == 0 && (tp->t_cflagt_termios.c_cflag & CLOCAL0x00008000) == 0
303 && (tp->t_state & TS_ISOPEN0x00020)) {
304 splx(s)spllower(s);
305 return 0; /* end of file */
306 }
307 if (tp->t_state & TS_ASYNC0x00002 || flag & IO_NDELAY0x10) {
308 splx(s)spllower(s);
309 return (EWOULDBLOCK35);
310 }
311 error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI25|PCATCH0x100, ttyin);
312 if (error) {
313 splx(s)spllower(s);
314 return error;
315 }
316 }
317
318 /* Pull place-holder byte out of canonical queue */
319 getc(&tp->t_canq);
320 splx(s)spllower(s);
321
322 for (m = m0; m && uio->uio_resid; m = m->m_nextm_hdr.mh_next)
323 if ((error = uiomove(mtod(m, u_char *)((u_char *)((m)->m_hdr.mh_data)), m->m_lenm_hdr.mh_len, uio)) != 0)
324 break;
325 m_freem(m0);
326 return (error);
327}
328
329/*
330 * Line specific (tty) write routine.
331 */
332int
333pppwrite(struct tty *tp, struct uio *uio, int flag)
334{
335 struct ppp_softc *sc = (struct ppp_softc *)tp->t_sc;
336 struct mbuf *m, *m0, **mp;
337 struct sockaddr dst;
338 u_int len;
339 int error;
340
341 if ((tp->t_state & TS_CARR_ON0x00008) == 0 && (tp->t_cflagt_termios.c_cflag & CLOCAL0x00008000) == 0)
342 return 0; /* wrote 0 bytes */
343 if (tp->t_line != PPPDISC5)
344 return (EINVAL22);
345 if (sc == NULL((void *)0) || tp != (struct tty *) sc->sc_devp)
346 return EIO5;
347 if (uio->uio_resid > sc->sc_if.if_mtuif_data.ifi_mtu + PPP_HDRLEN4 ||
348 uio->uio_resid < PPP_HDRLEN4)
349 return (EMSGSIZE40);
350 for (mp = &m0; uio->uio_resid; mp = &m->m_nextm_hdr.mh_next) {
351 if (mp == &m0) {
352 MGETHDR(m, M_WAIT, MT_DATA)m = m_gethdr((0x0001), (1));
353 m->m_pkthdrM_dat.MH.MH_pkthdr.len = uio->uio_resid - PPP_HDRLEN4;
354 m->m_pkthdrM_dat.MH.MH_pkthdr.ph_ifidx = 0;
355 } else
356 MGET(m, M_WAIT, MT_DATA)m = m_get((0x0001), (1));
357 *mp = m;
358 m->m_lenm_hdr.mh_len = 0;
359 if (uio->uio_resid >= MCLBYTES(1 << 11) / 2)
360 MCLGET(m, M_DONTWAIT)(void) m_clget((m), (0x0002), (1 << 11));
361 len = m_trailingspace(m);
362 if (len > uio->uio_resid)
363 len = uio->uio_resid;
364 if ((error = uiomove(mtod(m, u_char *)((u_char *)((m)->m_hdr.mh_data)), len, uio)) != 0) {
365 m_freem(m0);
366 return (error);
367 }
368 m->m_lenm_hdr.mh_len = len;
369 }
370 dst.sa_family = AF_UNSPEC0;
371 bcopy(mtod(m0, u_char *)((u_char *)((m0)->m_hdr.mh_data)), dst.sa_data, PPP_HDRLEN4);
372 m0->m_datam_hdr.mh_data += PPP_HDRLEN4;
373 m0->m_lenm_hdr.mh_len -= PPP_HDRLEN4;
374 return sc->sc_if.if_output(&sc->sc_if, m0, &dst, NULL((void *)0));
375}
376
377/*
378 * Line specific (tty) ioctl routine.
379 * This discipline requires that tty device drivers call
380 * the line specific l_ioctl routine from their ioctl routines.
381 */
382int
383ppptioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
384{
385 struct ppp_softc *sc = (struct ppp_softc *) tp->t_sc;
386 int error, s;
387
388 if (sc == NULL((void *)0) || tp != (struct tty *) sc->sc_devp)
389 return -1;
390
391 error = 0;
392 switch (cmd) {
393 case PPPIOCSASYNCMAP((unsigned long)0x80000000 | ((sizeof(int) & 0x1fff) <<
16) | ((('t')) << 8) | ((87)))
:
394 if ((error = suser(p)) != 0)
395 break;
396 sc->sc_asyncmap[0] = *(u_int *)data;
397 break;
398
399 case PPPIOCGASYNCMAP((unsigned long)0x40000000 | ((sizeof(int) & 0x1fff) <<
16) | ((('t')) << 8) | ((88)))
:
400 *(u_int *)data = sc->sc_asyncmap[0];
401 break;
402
403 case PPPIOCSRASYNCMAP((unsigned long)0x80000000 | ((sizeof(int) & 0x1fff) <<
16) | ((('t')) << 8) | ((84)))
:
404 if ((error = suser(p)) != 0)
405 break;
406 sc->sc_rasyncmap = *(u_int *)data;
407 break;
408
409 case PPPIOCGRASYNCMAP((unsigned long)0x40000000 | ((sizeof(int) & 0x1fff) <<
16) | ((('t')) << 8) | ((85)))
:
410 *(u_int *)data = sc->sc_rasyncmap;
411 break;
412
413 case PPPIOCSXASYNCMAP((unsigned long)0x80000000 | ((sizeof(ext_accm) & 0x1fff)
<< 16) | ((('t')) << 8) | ((79)))
:
414 if ((error = suser(p)) != 0)
415 break;
416 s = spltty()splraise(0x9);
417 bcopy(data, sc->sc_asyncmap, sizeof(sc->sc_asyncmap));
418 sc->sc_asyncmap[1] = 0; /* mustn't escape 0x20 - 0x3f */
419 sc->sc_asyncmap[2] &= ~0x40000000; /* mustn't escape 0x5e */
420 sc->sc_asyncmap[3] |= 0x60000000; /* must escape 0x7d, 0x7e */
421 splx(s)spllower(s);
422 break;
423
424 case PPPIOCGXASYNCMAP((unsigned long)0x40000000 | ((sizeof(ext_accm) & 0x1fff)
<< 16) | ((('t')) << 8) | ((80)))
:
425 bcopy(sc->sc_asyncmap, data, sizeof(sc->sc_asyncmap));
426 break;
427
428 default:
429 NET_LOCK()do { rw_enter_write(&netlock); } while (0);
430 error = pppioctl(sc, cmd, data, flag, p);
431 NET_UNLOCK()do { rw_exit_write(&netlock); } while (0);
432 if (error == 0 && cmd == PPPIOCSMRU((unsigned long)0x80000000 | ((sizeof(int) & 0x1fff) <<
16) | ((('t')) << 8) | ((82)))
)
433 ppppkt(sc);
434 }
435
436 return error;
437}
438
439/*
440 * FCS lookup table as calculated by genfcstab.
441 */
442static u_int16_t fcstab[256] = {
443 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
444 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
445 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
446 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
447 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
448 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
449 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
450 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
451 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
452 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
453 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
454 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
455 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
456 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
457 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
458 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
459 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
460 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
461 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
462 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
463 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
464 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
465 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
466 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
467 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
468 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
469 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
470 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
471 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
472 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
473 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
474 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
475};
476
477/*
478 * Calculate a new FCS given the current FCS and the new data.
479 */
480u_int16_t
481pppfcs(u_int16_t fcs, u_char *cp, int len)
482{
483 while (len--)
484 fcs = PPP_FCS(fcs, *cp++)(((fcs) >> 8) ^ fcstab[((fcs) ^ (*cp++)) & 0xff]);
485 return (fcs);
486}
487
488/*
489 * This gets called from pppoutput when a new packet is
490 * put on a queue.
491 */
492void
493pppasyncstart(struct ppp_softc *sc)
494{
495 struct tty *tp = (struct tty *) sc->sc_devp;
496 struct mbuf *m;
497 int len;
498 u_char *start, *stop, *cp;
499 int n, ndone, done, idle;
500 struct mbuf *m2;
501 int s;
502
503 KERNEL_LOCK()_kernel_lock();
504 idle = 0;
505 while (CCOUNT(&tp->t_outq)((&tp->t_outq)->c_cc) < tp->t_hiwat) {
506 /*
507 * See if we have an existing packet partly sent.
508 * If not, get a new packet and start sending it.
509 */
510 m = sc->sc_outm;
511 if (m == NULL((void *)0)) {
512 /*
513 * Get another packet to be sent.
514 */
515 m = ppp_dequeue(sc);
516 if (m == NULL((void *)0)) {
517 idle = 1;
518 break;
519 }
520
521 /*
522 * The extra PPP_FLAG will start up a new packet, and thus
523 * will flush any accumulated garbage. We do this whenever
524 * the line may have been idle for some time.
525 */
526 if (CCOUNT(&tp->t_outq)((&tp->t_outq)->c_cc) == 0) {
527 ++sc->sc_stats.ppp_obytes;
528 (void) putc(PPP_FLAG0x7e, &tp->t_outq);
529 }
530
531 /* Calculate the FCS for the first mbuf's worth. */
532 sc->sc_outfcs = pppfcs(PPP_INITFCS0xffff, mtod(m, u_char *)((u_char *)((m)->m_hdr.mh_data)), m->m_lenm_hdr.mh_len);
533 }
534
535 for (;;) {
536 start = mtod(m, u_char *)((u_char *)((m)->m_hdr.mh_data));
537 len = m->m_lenm_hdr.mh_len;
538 stop = start + len;
539 while (len > 0) {
540 /*
541 * Find out how many bytes in the string we can
542 * handle without doing something special.
543 */
544 for (cp = start; cp < stop; cp++)
545 if (ESCAPE_P(*cp)(sc->sc_asyncmap[(*cp) >> 5] & (1 << ((*cp
) & 0x1F)))
)
546 break;
547 n = cp - start;
548 if (n) {
549 /* NetBSD (0.9 or later), 4.3-Reno or similar. */
550 ndone = n - b_to_q(start, n, &tp->t_outq);
551 len -= ndone;
552 start += ndone;
553 sc->sc_stats.ppp_obytes += ndone;
554
555 if (ndone < n)
556 break; /* packet doesn't fit */
557 }
558 /*
559 * If there are characters left in the mbuf,
560 * the first one must be special.
561 * Put it out in a different form.
562 */
563 if (len) {
564 s = spltty()splraise(0x9);
565 if (putc(PPP_ESCAPE0x7d, &tp->t_outq)) {
566 splx(s)spllower(s);
567 break;
568 }
569 if (putc(*start ^ PPP_TRANS0x20, &tp->t_outq)) {
570 (void) unputc(&tp->t_outq);
571 splx(s)spllower(s);
572 break;
573 }
574 splx(s)spllower(s);
575 sc->sc_stats.ppp_obytes += 2;
576 start++;
577 len--;
578 }
579 }
580
581 /*
582 * If we didn't empty this mbuf, remember where we're up to.
583 * If we emptied the last mbuf, try to add the FCS and closing
584 * flag, and if we can't, leave sc_outm pointing to m, but with
585 * m->m_len == 0, to remind us to output the FCS and flag later.
586 */
587 done = len == 0;
588 if (done && m->m_nextm_hdr.mh_next == NULL((void *)0)) {
589 u_char *p, *q;
590 int c;
591 u_char endseq[8];
592
593 /*
594 * We may have to escape the bytes in the FCS.
595 */
596 p = endseq;
597 c = ~sc->sc_outfcs & 0xFF;
598 if (ESCAPE_P(c)(sc->sc_asyncmap[(c) >> 5] & (1 << ((c) &
0x1F)))
) {
599 *p++ = PPP_ESCAPE0x7d;
600 *p++ = c ^ PPP_TRANS0x20;
601 } else
602 *p++ = c;
603 c = (~sc->sc_outfcs >> 8) & 0xFF;
604 if (ESCAPE_P(c)(sc->sc_asyncmap[(c) >> 5] & (1 << ((c) &
0x1F)))
) {
605 *p++ = PPP_ESCAPE0x7d;
606 *p++ = c ^ PPP_TRANS0x20;
607 } else
608 *p++ = c;
609 *p++ = PPP_FLAG0x7e;
610
611 /*
612 * Try to output the FCS and flag. If the bytes
613 * don't all fit, back out.
614 */
615 s = spltty()splraise(0x9);
616 for (q = endseq; q < p; ++q)
617 if (putc(*q, &tp->t_outq)) {
618 done = 0;
619 for (; q > endseq; --q)
620 unputc(&tp->t_outq);
621 break;
622 }
623 splx(s)spllower(s);
624 if (done)
625 sc->sc_stats.ppp_obytes += q - endseq;
626 }
627
628 if (!done) {
629 /* remember where we got to */
630 m->m_datam_hdr.mh_data = start;
631 m->m_lenm_hdr.mh_len = len;
632 break;
633 }
634
635 /* Finished with this mbuf; free it and move on. */
636 m2 = m_free(m);
637 m = m2;
638 if (m == NULL((void *)0)) {
639 /* Finished a packet */
640 break;
641 }
642 sc->sc_outfcs = pppfcs(sc->sc_outfcs, mtod(m, u_char *)((u_char *)((m)->m_hdr.mh_data)), m->m_lenm_hdr.mh_len);
643 }
644
645 /*
646 * If m == NULL, we have finished a packet.
647 * If m != NULL, we've either done as much work this time
648 * as we need to, or else we've filled up the output queue.
649 */
650 sc->sc_outm = m;
651 if (m)
652 break;
653 }
654
655 /* Call pppstart to start output again if necessary. */
656 s = spltty()splraise(0x9);
657 pppstart_internal(tp, 0);
658
659 /*
660 * This timeout is needed for operation on a pseudo-tty,
661 * because the pty code doesn't call pppstart after it has
662 * drained the t_outq.
663 */
664 if (!idle && (sc->sc_flags & SC_TIMEOUT0x00000400) == 0) {
665 timeout_add(&sc->sc_timo, 1);
666 sc->sc_flags |= SC_TIMEOUT0x00000400;
667 }
668
669 splx(s)spllower(s);
670 KERNEL_UNLOCK()_kernel_unlock();
671}
672
673/*
674 * This gets called when a received packet is placed on
675 * the inq.
676 */
677void
678pppasyncctlp(struct ppp_softc *sc)
679{
680 struct tty *tp;
681 int s;
682
683 KERNEL_LOCK()_kernel_lock();
684 /* Put a placeholder byte in canq for ttpoll()/ttnread(). */
685 s = spltty()splraise(0x9);
686 tp = (struct tty *) sc->sc_devp;
687 putc(0, &tp->t_canq);
688 ttwakeup(tp);
689 splx(s)spllower(s);
690 KERNEL_UNLOCK()_kernel_unlock();
691}
692
693/*
694 * Start output on async tty interface. If the transmit queue
695 * has drained sufficiently, arrange for pppasyncstart to be
696 * called later.
697 */
698int
699pppstart_internal(struct tty *tp, int force)
700{
701 struct ppp_softc *sc = (struct ppp_softc *) tp->t_sc;
702
703 /*
704 * If there is stuff in the output queue, send it now.
705 * We are being called in lieu of ttstart and must do what it would.
706 */
707 if (tp->t_oproc != NULL((void *)0))
708 (*tp->t_oproc)(tp);
709
710 /*
711 * If the transmit queue has drained and the tty has not hung up
712 * or been disconnected from the ppp unit, then tell if_ppp.c that
713 * we need more output.
714 */
715 if ((CCOUNT(&tp->t_outq)((&tp->t_outq)->c_cc) < tp->t_lowat || force)
716 && !((tp->t_state & TS_CARR_ON0x00008) == 0 && (tp->t_cflagt_termios.c_cflag & CLOCAL0x00008000) == 0)
717 && sc != NULL((void *)0) && tp == (struct tty *) sc->sc_devp) {
718 ppp_restart(sc);
719 }
720
721 return 0;
722}
723
724int
725pppstart(struct tty *tp)
726{
727 return pppstart_internal(tp, 0);
728}
729
730/*
731 * Timeout routine - try to start some more output.
732 */
733void
734ppp_timeout(void *x)
735{
736 struct ppp_softc *sc = (struct ppp_softc *) x;
737 struct tty *tp = (struct tty *) sc->sc_devp;
738 int s;
739
740 s = spltty()splraise(0x9);
741 sc->sc_flags &= ~SC_TIMEOUT0x00000400;
742 pppstart_internal(tp, 1);
743 splx(s)spllower(s);
744}
745
746/*
747 * Allocate enough mbuf to handle current MRU.
748 */
749void
750ppppkt(struct ppp_softc *sc)
751{
752 struct ppp_pkt **pktp, *pkt;
753 int len;
754 int s;
755
756 s = spltty()splraise(0x9);
757 pktp = &sc->sc_pkt;
758 for (len = PKT_MAXLEN(sc)((sc)->sc_mru + 4 + 2); len > 0; len -= sizeof(pkt->p_buf)) {
759 pkt = *pktp;
760 if (pkt == NULL((void *)0)) {
761 pkt = pool_get(&ppp_pkts, PR_NOWAIT0x0002);
762 if (pkt == NULL((void *)0))
763 break;
764 PKT_NEXT(pkt)((pkt)->p_hdr.ph_next) = NULL((void *)0);
765 PKT_PREV(pkt)((pkt)->p_hdr.ph_pkt) = *pktp;
766 PKT_LEN(pkt)((pkt)->p_hdr.ph_len) = 0;
767 *pktp = pkt;
768 }
769 pktp = &PKT_NEXT(pkt)((pkt)->p_hdr.ph_next);
770 }
771 splx(s)spllower(s);
772}
773
774void
775ppp_pkt_free(struct ppp_pkt *pkt)
776{
777 struct ppp_pkt *next;
778
779 while (pkt != NULL((void *)0)) {
780 next = PKT_NEXT(pkt)((pkt)->p_hdr.ph_next);
781 pool_put(&ppp_pkts, pkt);
782 pkt = next;
783 }
784}
785
786/*
787 * tty interface receiver interrupt.
788 */
789static unsigned int paritytab[8] = {
790 0x96696996, 0x69969669, 0x69969669, 0x96696996,
791 0x69969669, 0x96696996, 0x96696996, 0x69969669
792};
793
794int
795pppinput(int c, struct tty *tp)
796{
797 struct ppp_softc *sc;
798 struct ppp_pkt *pkt;
799 int ilen, s;
800
801 sc = (struct ppp_softc *) tp->t_sc;
802 if (sc == NULL((void *)0) || tp != (struct tty *) sc->sc_devp)
803 return 0;
804
805 ++tk_nin;
806 ++sc->sc_stats.ppp_ibytes;
807
808 if (c & TTY_FE0x01000000) {
809 /* framing error or overrun on this char - abort packet */
810 if (sc->sc_flags & SC_DEBUG0x00010000)
811 printf("%s: bad char %x\n", sc->sc_if.if_xname, c);
812 goto flush;
813 }
814
815 c &= 0xff;
816
817 /*
818 * Handle software flow control of output.
819 */
820 if (tp->t_iflagt_termios.c_iflag & IXON0x00000200) {
821 if (c == tp->t_cct_termios.c_cc[VSTOP13] && tp->t_cct_termios.c_cc[VSTOP13] != _POSIX_VDISABLE(0377)) {
822 if ((tp->t_state & TS_TTSTOP0x00100) == 0) {
823 tp->t_state |= TS_TTSTOP0x00100;
824 (*cdevsw[major(tp->t_dev)(((unsigned)(tp->t_dev) >> 8) & 0xff)].d_stop)(tp, 0);
825 }
826 return 0;
827 }
828 if (c == tp->t_cct_termios.c_cc[VSTART12] && tp->t_cct_termios.c_cc[VSTART12] != _POSIX_VDISABLE(0377)) {
829 tp->t_state &= ~TS_TTSTOP0x00100;
830 if (tp->t_oproc != NULL((void *)0))
831 (*tp->t_oproc)(tp);
832 return 0;
833 }
834 }
835
836 s = spltty()splraise(0x9);
837 if (c & 0x80)
838 sc->sc_flags |= SC_RCV_B7_10x02000000;
839 else
840 sc->sc_flags |= SC_RCV_B7_00x01000000;
841 if (paritytab[c >> 5] & (1 << (c & 0x1F)))
842 sc->sc_flags |= SC_RCV_ODDP0x08000000;
843 else
844 sc->sc_flags |= SC_RCV_EVNP0x04000000;
845 splx(s)spllower(s);
846
847 if (sc->sc_flags & SC_LOG_RAWIN0x00080000)
848 ppplogchar(sc, c);
849
850 if (c == PPP_FLAG0x7e) {
851 ilen = sc->sc_ilen;
852 sc->sc_ilen = 0;
853
854 if (sc->sc_rawin_count > 0)
855 ppplogchar(sc, -1);
856
857 /*
858 * If SC_ESCAPED is set, then we've seen the packet
859 * abort sequence "}~".
860 */
861 if (sc->sc_flags & (SC_FLUSH0x40000000 | SC_ESCAPED0x80000000)
862 || (ilen > 0 && sc->sc_fcs != PPP_GOODFCS0xf0b8)) {
863 s = spltty()splraise(0x9);
864 sc->sc_flags |= SC_PKTLOST0x20000000; /* note the dropped packet */
865 if ((sc->sc_flags & (SC_FLUSH0x40000000 | SC_ESCAPED0x80000000)) == 0){
866 if (sc->sc_flags & SC_DEBUG0x00010000)
867 printf("%s: bad fcs %x\n", sc->sc_if.if_xname,
868 sc->sc_fcs);
869 sc->sc_if.if_ierrorsif_data.ifi_ierrors++;
870 sc->sc_stats.ppp_ierrors++;
871 } else
872 sc->sc_flags &= ~(SC_FLUSH0x40000000 | SC_ESCAPED0x80000000);
873 splx(s)spllower(s);
874 return 0;
875 }
876
877 if (ilen < PPP_HDRLEN4 + PPP_FCSLEN2) {
878 if (ilen) {
879 if (sc->sc_flags & SC_DEBUG0x00010000)
880 printf("%s: too short (%d)\n", sc->sc_if.if_xname, ilen);
881 s = spltty()splraise(0x9);
882 sc->sc_if.if_ierrorsif_data.ifi_ierrors++;
883 sc->sc_stats.ppp_ierrors++;
884 sc->sc_flags |= SC_PKTLOST0x20000000;
885 splx(s)spllower(s);
886 }
887 return 0;
888 }
889
890 /*
891 * Remove FCS trailer.
892 */
893 ilen -= 2;
Value stored to 'ilen' is never read
894 pkt = sc->sc_pktc;
895 if (--PKT_LEN(pkt)((pkt)->p_hdr.ph_len) == 0) {
896 pkt = PKT_PREV(pkt)((pkt)->p_hdr.ph_pkt);
897 sc->sc_pktc = pkt;
898 }
899 PKT_LEN(pkt)((pkt)->p_hdr.ph_len)--;
900
901 /* excise this mbuf chain */
902 pkt = sc->sc_pkt;
903 sc->sc_pkt = sc->sc_pktc = PKT_NEXT(sc->sc_pktc)((sc->sc_pktc)->p_hdr.ph_next);
904 PKT_NEXT(pkt)((pkt)->p_hdr.ph_next) = NULL((void *)0);
905
906 ppppktin(sc, pkt, sc->sc_flags & SC_PKTLOST0x20000000);
907 if (sc->sc_flags & SC_PKTLOST0x20000000) {
908 s = spltty()splraise(0x9);
909 sc->sc_flags &= ~SC_PKTLOST0x20000000;
910 splx(s)spllower(s);
911 }
912
913 ppppkt(sc);
914 return 0;
915 }
916
917 if (sc->sc_flags & SC_FLUSH0x40000000) {
918 if (sc->sc_flags & SC_LOG_FLUSH0x00100000)
919 ppplogchar(sc, c);
920 return 0;
921 }
922
923 if (c < 0x20 && (sc->sc_rasyncmap & (1 << c)))
924 return 0;
925
926 s = spltty()splraise(0x9);
927 if (sc->sc_flags & SC_ESCAPED0x80000000) {
928 sc->sc_flags &= ~SC_ESCAPED0x80000000;
929 c ^= PPP_TRANS0x20;
930 } else if (c == PPP_ESCAPE0x7d) {
931 sc->sc_flags |= SC_ESCAPED0x80000000;
932 splx(s)spllower(s);
933 return 0;
934 }
935 splx(s)spllower(s);
936
937 /*
938 * Initialize buffer on first octet received.
939 * First octet could be address or protocol (when compressing
940 * address/control).
941 * Second octet is control.
942 * Third octet is first or second (when compressing protocol)
943 * octet of protocol.
944 * Fourth octet is second octet of protocol.
945 */
946 if (sc->sc_ilen == 0) {
947 /* reset the first input mbuf */
948 if (sc->sc_pkt == NULL((void *)0)) {
949 ppppkt(sc);
950 if (sc->sc_pkt == NULL((void *)0)) {
951 if (sc->sc_flags & SC_DEBUG0x00010000)
952 printf("%s: no input mbufs!\n", sc->sc_if.if_xname);
953 goto flush;
954 }
955 }
956 pkt = sc->sc_pkt;
957 PKT_LEN(pkt)((pkt)->p_hdr.ph_len) = 0;
958 sc->sc_pktc = pkt;
959 sc->sc_pktp = pkt->p_buf;
960 sc->sc_fcs = PPP_INITFCS0xffff;
961 if (c != PPP_ALLSTATIONS0xff) {
962 if (sc->sc_flags & SC_REJ_COMP_AC0x00000010) {
963 if (sc->sc_flags & SC_DEBUG0x00010000)
964 printf("%s: garbage received: 0x%x (need 0xFF)\n",
965 sc->sc_if.if_xname, c);
966 goto flush;
967 }
968 *sc->sc_pktp++ = PPP_ALLSTATIONS0xff;
969 *sc->sc_pktp++ = PPP_UI0x03;
970 sc->sc_ilen += 2;
971 PKT_LEN(pkt)((pkt)->p_hdr.ph_len) += 2;
972 }
973 }
974 if (sc->sc_ilen == 1 && c != PPP_UI0x03) {
975 if (sc->sc_flags & SC_DEBUG0x00010000)
976 printf("%s: missing UI (0x3), got 0x%x\n",
977 sc->sc_if.if_xname, c);
978 goto flush;
979 }
980 if (sc->sc_ilen == 2 && (c & 1) == 1) {
981 /* a compressed protocol */
982 *sc->sc_pktp++ = 0;
983 sc->sc_ilen++;
984 PKT_LEN(sc->sc_pktc)((sc->sc_pktc)->p_hdr.ph_len)++;
985 }
986 if (sc->sc_ilen == 3 && (c & 1) == 0) {
987 if (sc->sc_flags & SC_DEBUG0x00010000)
988 printf("%s: bad protocol %x\n", sc->sc_if.if_xname,
989 (sc->sc_pktp[-1] << 8) + c);
990 goto flush;
991 }
992
993 /* packet beyond configured mru? */
994 if (++sc->sc_ilen > PKT_MAXLEN(sc)((sc)->sc_mru + 4 + 2)) {
995 if (sc->sc_flags & SC_DEBUG0x00010000)
996 printf("%s: packet too big\n", sc->sc_if.if_xname);
997 goto flush;
998 }
999
1000 /* is this packet full? */
1001 pkt = sc->sc_pktc;
1002 if (PKT_LEN(pkt)((pkt)->p_hdr.ph_len) >= sizeof(pkt->p_buf)) {
1003 if (PKT_NEXT(pkt)((pkt)->p_hdr.ph_next) == NULL((void *)0)) {
1004 ppppkt(sc);
1005 if (PKT_NEXT(pkt)((pkt)->p_hdr.ph_next) == NULL((void *)0)) {
1006 if (sc->sc_flags & SC_DEBUG0x00010000)
1007 printf("%s: too few input packets!\n", sc->sc_if.if_xname);
1008 goto flush;
1009 }
1010 }
1011 sc->sc_pktc = pkt = PKT_NEXT(pkt)((pkt)->p_hdr.ph_next);
1012 PKT_LEN(pkt)((pkt)->p_hdr.ph_len) = 0;
1013 sc->sc_pktp = pkt->p_buf;
1014 }
1015
1016 ++PKT_LEN(pkt)((pkt)->p_hdr.ph_len);
1017 *sc->sc_pktp++ = c;
1018 sc->sc_fcs = PPP_FCS(sc->sc_fcs, c)(((sc->sc_fcs) >> 8) ^ fcstab[((sc->sc_fcs) ^ (c)
) & 0xff])
;
1019 return 0;
1020
1021 flush:
1022 if (!(sc->sc_flags & SC_FLUSH0x40000000)) {
1023 s = spltty()splraise(0x9);
1024 sc->sc_if.if_ierrorsif_data.ifi_ierrors++;
1025 sc->sc_stats.ppp_ierrors++;
1026 sc->sc_flags |= SC_FLUSH0x40000000;
1027 splx(s)spllower(s);
1028 if (sc->sc_flags & SC_LOG_FLUSH0x00100000)
1029 ppplogchar(sc, c);
1030 }
1031 return 0;
1032}
1033
1034#define MAX_DUMP_BYTES128 128
1035
1036void
1037ppplogchar(struct ppp_softc *sc, int c)
1038{
1039 if (c >= 0)
1040 sc->sc_rawin[sc->sc_rawin_count++] = c;
1041 if (sc->sc_rawin_count >= sizeof(sc->sc_rawin)
1042 || (c < 0 && sc->sc_rawin_count > 0)) {
1043 printf("%s input: ", sc->sc_if.if_xname);
1044 pppdumpb(sc->sc_rawin, sc->sc_rawin_count);
1045 sc->sc_rawin_count = 0;
1046 }
1047}
1048
1049void
1050pppdumpb(u_char *b, int l)
1051{
1052 char buf[3*MAX_DUMP_BYTES128+4];
1053 char *bp = buf;
1054 static char digits[] = "0123456789abcdef";
1055
1056 while (l--) {
1057 if (bp >= buf + sizeof(buf) - 3) {
1058 *bp++ = '>';
1059 break;
1060 }
1061 *bp++ = digits[*b >> 4]; /* convert byte to ascii hex */
1062 *bp++ = digits[*b++ & 0xf];
1063 *bp++ = ' ';
1064 }
1065
1066 *bp = 0;
1067 printf("%s\n", buf);
1068}
1069
1070#endif /* NPPP > 0 */