Mercurial > ecos-v3_0-branch
annotate packages/net/ppp/current/src/ppp_io.c @ 2729:74dbf4c3f2e1 after-copyright-change-20090129
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
| author | jlarmour |
|---|---|
| date | Thu, 29 Jan 2009 17:47:46 +0000 |
| parents | 9ea31f9f2254 |
| children |
| rev | line source |
|---|---|
| 1586 | 1 //========================================================================== |
| 2 // | |
| 3 // src/ppp_io.c | |
| 4 // | |
| 5 //========================================================================== | |
|
2729
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2041
diff
changeset
|
6 // ####BSDCOPYRIGHTBEGIN#### |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2041
diff
changeset
|
7 // ------------------------------------------- |
| 1586 | 8 // This file is part of eCos, the Embedded Configurable Operating System. |
| 9 // | |
|
2729
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2041
diff
changeset
|
10 // Portions of this software may have been derived from FreeBSD, OpenBSD, |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2041
diff
changeset
|
11 // or other sources, and if so are covered by the appropriate copyright |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2041
diff
changeset
|
12 // and license included herein. |
| 1586 | 13 // |
|
2729
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2041
diff
changeset
|
14 // Portions created by the Free Software Foundation are |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2041
diff
changeset
|
15 // Copyright (C) 2003, 2004 Free Software Foundation, Inc. |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2041
diff
changeset
|
16 // ------------------------------------------- |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2041
diff
changeset
|
17 // ####BSDCOPYRIGHTEND#### |
| 1586 | 18 //========================================================================== |
| 19 | |
| 20 /* | |
| 21 * ppp_tty.c - Point-to-Point Protocol (PPP) driver for asynchronous | |
| 22 * tty devices. | |
| 23 * | |
| 24 * Copyright (c) 1989 Carnegie Mellon University. | |
| 25 * All rights reserved. | |
| 26 * | |
| 27 * Redistribution and use in source and binary forms are permitted | |
| 28 * provided that the above copyright notice and this paragraph are | |
| 29 * duplicated in all such forms and that any documentation, | |
| 30 * advertising materials, and other materials related to such | |
| 31 * distribution and use acknowledge that the software was developed | |
| 32 * by Carnegie Mellon University. The name of the | |
| 33 * University may not be used to endorse or promote products derived | |
| 34 * from this software without specific prior written permission. | |
| 35 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | |
| 36 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | |
| 37 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | |
| 38 * | |
| 39 * Drew D. Perkins | |
| 40 * Carnegie Mellon University | |
| 41 * 4910 Forbes Ave. | |
| 42 * Pittsburgh, PA 15213 | |
| 43 * (412) 268-8576 | |
| 44 * ddp@andrew.cmu.edu | |
| 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 * 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 /* $FreeBSD: src/sys/net/ppp_tty.c,v 1.43 2000/01/29 16:56:24 peter Exp $ */ | |
| 93 | |
| 94 #include <pkgconf/system.h> | |
| 95 #include <pkgconf/net.h> | |
| 96 #include <pkgconf/ppp.h> | |
| 97 | |
| 98 #define _KERNEL | |
| 99 | |
| 100 #define VJC /* XXX for ppp_defs.h */ | |
| 101 | |
| 102 #include <sys/param.h> | |
| 103 #define suser(x) 0 | |
| 104 #include <sys/mbuf.h> | |
| 105 #include <sys/socket.h> | |
| 106 #include <sys/uio.h> | |
| 107 | |
| 108 #ifdef PPP_FILTER | |
| 109 #include <net/bpf.h> | |
| 110 #endif | |
| 111 #include <cyg/ppp/net/if_ppp.h> | |
| 112 #include <cyg/ppp/net/if_pppvar.h> | |
| 113 | |
| 114 //========================================================================== | |
| 115 | |
| 116 #ifdef __ECOS | |
| 117 | |
| 118 #include "cyg/ppp/ppp_io.h" | |
| 119 | |
| 120 //#define db_printf diag_printf | |
| 121 #define db_printf(fmt, ... ) | |
| 122 | |
| 123 #define spltty(x) splsoftnet(x) | |
| 124 | |
| 125 #define ENOIOCTL ENOSYS | |
| 126 | |
| 127 #endif | |
| 128 | |
| 129 //========================================================================== | |
| 130 | |
| 131 static u_short pppfcs __P((u_short fcs, u_char *cp, int len)); | |
| 132 static void pppasyncstart __P((struct ppp_softc *)); | |
| 133 static void pppasyncctlp __P((struct ppp_softc *)); | |
| 134 static void pppasyncrelinq __P((struct ppp_softc *)); | |
| 135 static void pppasyncsetmtu __P((struct ppp_softc *)); | |
| 136 static void pppgetm __P((struct ppp_softc *sc)); | |
| 137 static void ppplogchar __P((struct ppp_softc *, int)); | |
| 138 | |
| 139 /* XXX called from if_ppp.c - layering violation */ | |
| 140 void pppasyncattach __P((void *)); | |
| 141 | |
| 142 //========================================================================== | |
| 143 /* | |
| 144 * Some useful mbuf macros not in mbuf.h. | |
| 145 */ | |
| 146 #define M_IS_CLUSTER(m) ((m)->m_flags & M_EXT) | |
| 147 | |
| 148 #define M_DATASTART(m) \ | |
| 149 (M_IS_CLUSTER(m) ? (m)->m_ext.ext_buf : \ | |
| 150 (m)->m_flags & M_PKTHDR ? (m)->m_pktdat : (m)->m_dat) | |
| 151 | |
| 152 #define M_DATASIZE(m) \ | |
| 153 (M_IS_CLUSTER(m) ? (m)->m_ext.ext_size : \ | |
| 154 (m)->m_flags & M_PKTHDR ? MHLEN: MLEN) | |
| 155 | |
| 156 //========================================================================== | |
| 157 /* | |
| 158 * Does c need to be escaped? | |
| 159 */ | |
| 160 #define ESCAPE_P(c) (sc->sc_asyncmap[(c) >> 5] & (1 << ((c) & 0x1F))) | |
| 161 | |
| 162 //========================================================================== | |
| 163 /* | |
| 164 * Procedures for using an async tty interface for PPP. | |
| 165 */ | |
| 166 | |
| 167 /* This is a FreeBSD-2.X kernel. */ | |
| 168 //#define CCOUNT(q) ((q)->c_cc) | |
| 169 //#define PPP_LOWAT 100 /* Process more output when < LOWAT on queue */ | |
| 170 //#define PPP_HIWAT 400 /* Don't start a new packet if HIWAT on que */ | |
| 171 | |
| 172 | |
| 173 //========================================================================== | |
| 174 /* | |
| 175 * Line specific open routine for async tty devices. | |
| 176 * Attach the given tty to the first available ppp unit. | |
| 177 * Called from device open routine or ttioctl() at >= splsofttty() | |
| 178 */ | |
| 179 /* ARGSUSED */ | |
| 180 | |
| 181 int | |
| 182 cyg_ppp_pppopen(tp) | |
| 183 struct tty *tp; | |
| 184 { | |
| 185 register struct ppp_softc *sc; | |
| 186 int error, s; | |
| 187 | |
| 188 if ((error = suser(p)) != 0) | |
| 189 return (error); | |
| 190 | |
| 191 s = spltty(); | |
| 192 | |
| 193 if ((sc = pppalloc(0)) == NULL) { | |
| 194 splx(s); | |
| 195 return ENXIO; | |
| 196 } | |
| 197 | |
| 198 if (sc->sc_relinq) | |
| 199 (*sc->sc_relinq)(sc); /* get previous owner to relinquish the unit */ | |
| 200 | |
| 201 sc->sc_ilen = 0; | |
| 202 sc->sc_m = NULL; | |
| 203 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_setmtu = pppasyncsetmtu; | |
| 212 sc->sc_outm = NULL; | |
| 213 pppgetm(sc); | |
| 214 sc->sc_if.if_flags |= IFF_RUNNING; | |
| 215 getmicrotime(&sc->sc_if.if_lastchange); | |
| 216 tp->t_sc = (caddr_t) sc; | |
| 217 | |
| 218 splx(s); | |
| 219 | |
| 220 return (0); | |
| 221 } | |
| 222 | |
| 223 //========================================================================== | |
| 224 /* | |
| 225 * Line specific close routine, called from device close routine | |
| 226 * and from ttioctl at >= splsofttty(). | |
| 227 * Detach the tty from the ppp unit. | |
| 228 * Mimics part of ttyclose(). | |
| 229 */ | |
| 230 | |
| 231 int | |
| 232 cyg_ppp_pppclose(tp, flag) | |
| 233 struct tty *tp; | |
| 234 int flag; | |
| 235 { | |
| 236 register struct ppp_softc *sc; | |
| 237 int s; | |
| 238 | |
| 239 db_printf("%s called\n", __PRETTY_FUNCTION__); | |
| 240 s = spltty(); | |
| 241 | |
| 242 sc = (struct ppp_softc *) tp->t_sc; | |
| 243 if (sc != NULL) { | |
| 244 tp->t_sc = NULL; | |
| 245 if (tp == (struct tty *) sc->sc_devp) { | |
| 246 pppasyncrelinq(sc); | |
| 247 pppdealloc(sc); | |
| 248 } | |
| 249 } | |
| 250 splx(s); | |
| 251 return 0; | |
| 252 } | |
| 253 | |
| 254 //========================================================================== | |
| 255 /* | |
| 256 * Relinquish the interface unit to another device. | |
| 257 */ | |
| 258 | |
| 259 static void | |
| 260 pppasyncrelinq(sc) | |
| 261 struct ppp_softc *sc; | |
| 262 { | |
| 263 int s; | |
| 264 | |
| 265 s = spltty(); | |
| 266 if (sc->sc_outm) { | |
| 267 m_freem(sc->sc_outm); | |
| 268 sc->sc_outm = NULL; | |
| 269 } | |
| 270 if (sc->sc_m) { | |
| 271 m_freem(sc->sc_m); | |
| 272 sc->sc_m = NULL; | |
| 273 } | |
| 274 if (sc->sc_flags & SC_TIMEOUT) { | |
| 275 sc->sc_flags &= ~SC_TIMEOUT; | |
| 276 } | |
| 277 splx(s); | |
| 278 } | |
| 279 | |
| 280 //========================================================================== | |
| 281 /* | |
| 282 * This gets called from the upper layer to notify a mtu change | |
| 283 */ | |
| 284 | |
| 285 static void | |
| 286 pppasyncsetmtu(sc) | |
| 287 register struct ppp_softc *sc; | |
| 288 { | |
| 289 db_printf("%s called\n", __PRETTY_FUNCTION__); | |
| 290 } | |
| 291 | |
| 1629 | 292 |
| 293 | |
| 294 //========================================================================== | |
| 295 /* | |
| 296 * function to check if data is available | |
| 297 */ | |
| 298 | |
| 299 int | |
| 300 cyg_ppp_pppcheck(tp) | |
| 301 register struct tty *tp; | |
| 302 { | |
| 303 register struct ppp_softc *sc = (struct ppp_softc *)tp->t_sc; | |
| 304 int status = 0; | |
| 305 register int s; | |
| 306 | |
| 307 s = spltty(); | |
| 308 | |
| 309 if (tp != (struct tty *) sc->sc_devp ) { | |
| 310 splx(s); | |
| 311 return 0; | |
| 312 } | |
| 313 if (sc->sc_inq.ifq_head == NULL) | |
| 314 { | |
| 315 splx(s); | |
| 316 return 0; | |
| 317 } | |
| 318 | |
| 319 // if the queue is not empty | |
| 320 if ( IF_IS_EMPTY(&sc->sc_inq) == false) | |
| 321 status = 1; | |
| 322 | |
| 323 splx(s); | |
| 324 | |
| 325 return(status); | |
| 326 } | |
| 327 | |
| 328 | |
| 1586 | 329 //========================================================================== |
| 330 /* | |
| 331 * Line specific (tty) read routine. | |
| 332 * called at zero spl from the device driver in the response to user-level | |
| 333 * reads on the tty file descriptor (ie: pppd). | |
| 334 */ | |
| 335 | |
| 336 int | |
| 337 cyg_ppp_pppread(tp, uio, flag) | |
| 338 register struct tty *tp; | |
| 339 struct uio *uio; | |
| 340 int flag; | |
| 341 { | |
| 342 register struct ppp_softc *sc = (struct ppp_softc *)tp->t_sc; | |
| 343 struct mbuf *m, *m0; | |
| 344 register int s; | |
| 345 int error = 0; | |
| 346 | |
| 347 db_printf("%s called\n", __PRETTY_FUNCTION__); | |
| 348 | |
| 349 if (sc == NULL) | |
| 350 return 0; | |
| 351 | |
| 352 // Look for input. If there is none return EWOULDBLOCK, otherwise | |
| 353 // dequeue the next packet and return it. | |
| 354 | |
| 355 s = spltty(); | |
| 356 | |
| 357 if (tp != (struct tty *) sc->sc_devp ) { | |
| 358 splx(s); | |
| 359 return 0; | |
| 360 } | |
| 361 if (sc->sc_inq.ifq_head == NULL) | |
| 362 { | |
| 363 splx(s); | |
| 364 return EWOULDBLOCK; | |
| 365 } | |
| 366 | |
| 367 /* Get the packet from the input queue */ | |
| 368 IF_DEQUEUE(&sc->sc_inq, m0); | |
| 369 splx(s); | |
| 370 | |
| 371 | |
| 372 for (m = m0; m && uio->uio_resid; m = m->m_next) | |
| 373 { | |
|
2041
9ea31f9f2254
* src/ppp_io.c (cyg_ppp_pppread): caddrt_t to stop compiler warnings.
asl
parents:
1923
diff
changeset
|
374 if ((error = uiomove(mtod(m, caddr_t), m->m_len, uio)) != 0) |
| 1586 | 375 break; |
| 376 } | |
| 377 m_freem(m0); | |
| 378 | |
| 379 return (error); | |
| 380 } | |
| 381 | |
| 382 //========================================================================== | |
| 383 /* | |
| 384 * Line specific (tty) write routine. | |
| 385 * called at zero spl from the device driver in the response to user-level | |
| 386 * writes on the tty file descriptor (ie: pppd). | |
| 387 */ | |
| 388 | |
| 389 int | |
| 390 cyg_ppp_pppwrite(tp, uio, flag) | |
| 391 register struct tty *tp; | |
| 392 struct uio *uio; | |
| 393 int flag; | |
| 394 { | |
| 395 register struct ppp_softc *sc = (struct ppp_softc *)tp->t_sc; | |
| 396 struct mbuf *m, *m0, **mp; | |
| 397 struct sockaddr dst; | |
| 398 int len, error, s; | |
| 399 | |
| 400 s = spltty(); | |
| 401 for (mp = &m0; uio->uio_resid; mp = &m->m_next) { | |
| 402 MGET(m, M_WAIT, MT_DATA); | |
| 403 if ((*mp = m) == NULL) { | |
| 404 m_freem(m0); | |
| 405 splx(s); | |
| 406 return (ENOBUFS); | |
| 407 } | |
| 408 m->m_len = 0; | |
| 409 if (uio->uio_resid >= MCLBYTES / 2) | |
| 410 MCLGET(m, M_DONTWAIT); | |
| 411 len = M_TRAILINGSPACE(m); | |
| 412 if (len > uio->uio_resid) | |
| 413 len = uio->uio_resid; | |
|
2041
9ea31f9f2254
* src/ppp_io.c (cyg_ppp_pppread): caddrt_t to stop compiler warnings.
asl
parents:
1923
diff
changeset
|
414 if ((error = uiomove(mtod(m, caddr_t), len, uio)) != 0) { |
| 1586 | 415 m_freem(m0); |
| 416 splx(s); | |
| 417 return (error); | |
| 418 } | |
| 419 m->m_len = len; | |
| 420 } | |
| 421 dst.sa_family = AF_UNSPEC; | |
| 422 bcopy(mtod(m0, u_char *), dst.sa_data, PPP_HDRLEN); | |
| 423 m0->m_data += PPP_HDRLEN; | |
| 424 m0->m_len -= PPP_HDRLEN; | |
| 425 | |
| 426 /* call the upper layer to "transmit" it... */ | |
| 427 error = pppoutput(&sc->sc_if, m0, &dst, (struct rtentry *)0); | |
| 428 splx(s); | |
| 429 return (error); | |
| 430 } | |
| 431 | |
| 432 //========================================================================== | |
| 433 /* | |
| 434 * Line specific (tty) ioctl routine. | |
| 435 * This discipline requires that tty device drivers call | |
| 436 * the line specific l_ioctl routine from their ioctl routines. | |
| 437 */ | |
| 438 /* ARGSUSED */ | |
| 439 int | |
| 440 cyg_ppp_ppptioctl(tp, cmd, data, flag) | |
| 441 struct tty *tp; | |
| 442 u_long cmd; | |
| 443 caddr_t data; | |
| 444 int flag; | |
| 445 // struct proc *p; | |
| 446 { | |
| 447 struct ppp_softc *sc = (struct ppp_softc *) tp->t_sc; | |
| 448 int error, s; | |
| 449 | |
| 450 if (sc == NULL || tp != (struct tty *) sc->sc_devp) | |
| 451 return (ENOIOCTL); | |
| 452 | |
| 453 error = 0; | |
| 454 switch (cmd) { | |
| 455 case PPPIOCSASYNCMAP: | |
| 456 sc->sc_asyncmap[0] = *(u_int *)data; | |
| 457 break; | |
| 458 | |
| 459 case PPPIOCGASYNCMAP: | |
| 460 *(u_int *)data = sc->sc_asyncmap[0]; | |
| 461 break; | |
| 462 | |
| 463 case PPPIOCSRASYNCMAP: | |
| 464 if ((error = suser(p)) != 0) | |
| 465 break; | |
| 466 sc->sc_rasyncmap = *(u_int *)data; | |
| 467 break; | |
| 468 | |
| 469 case PPPIOCGRASYNCMAP: | |
| 470 *(u_int *)data = sc->sc_rasyncmap; | |
| 471 break; | |
| 472 | |
| 473 case PPPIOCSXASYNCMAP: | |
| 474 s = spltty(); | |
| 475 bcopy(data, sc->sc_asyncmap, sizeof(sc->sc_asyncmap)); | |
| 476 sc->sc_asyncmap[1] = 0; /* mustn't escape 0x20 - 0x3f */ | |
| 477 sc->sc_asyncmap[2] &= ~0x40000000; /* mustn't escape 0x5e */ | |
| 478 sc->sc_asyncmap[3] |= 0x60000000; /* must escape 0x7d, 0x7e */ | |
| 479 splx(s); | |
| 480 break; | |
| 481 | |
| 482 case PPPIOCGXASYNCMAP: | |
| 483 bcopy(sc->sc_asyncmap, data, sizeof(sc->sc_asyncmap)); | |
| 484 break; | |
| 485 | |
| 486 default: | |
| 487 error = pppioctl(sc, cmd, data, flag, 0); | |
| 488 if (error == 0 && cmd == PPPIOCSMRU) | |
| 489 pppgetm(sc); | |
| 490 } | |
| 491 | |
| 492 return error; | |
| 493 } | |
| 494 | |
| 495 //========================================================================== | |
| 496 /* | |
| 497 * FCS lookup table as calculated by genfcstab. | |
| 498 */ | |
| 499 static u_short fcstab[256] = { | |
| 500 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, | |
| 501 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, | |
| 502 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, | |
| 503 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, | |
| 504 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, | |
| 505 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, | |
| 506 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, | |
| 507 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, | |
| 508 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, | |
| 509 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, | |
| 510 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, | |
| 511 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, | |
| 512 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, | |
| 513 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, | |
| 514 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, | |
| 515 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, | |
| 516 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, | |
| 517 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, | |
| 518 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, | |
| 519 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, | |
| 520 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, | |
| 521 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, | |
| 522 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, | |
| 523 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, | |
| 524 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, | |
| 525 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, | |
| 526 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, | |
| 527 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, | |
| 528 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, | |
| 529 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, | |
| 530 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, | |
| 531 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 | |
| 532 }; | |
| 533 | |
| 534 //========================================================================== | |
| 535 /* | |
| 536 * Calculate a new FCS given the current FCS and the new data. | |
| 537 */ | |
| 538 static u_short | |
| 539 pppfcs(u_short fcs, u_char *cp, int len) | |
| 540 { | |
| 541 while (len--) | |
| 542 fcs = PPP_FCS(fcs, *cp++); | |
| 543 return (fcs); | |
| 544 } | |
| 545 | |
| 546 //========================================================================== | |
| 547 | |
| 548 #ifdef __ECOS | |
| 549 | |
| 550 // Call pppasyncstart() to kick transmission into life. | |
| 551 int cyg_ppp_pppstart( struct tty *tp ) | |
| 552 { | |
| 553 struct ppp_softc *sc = (struct ppp_softc *) tp->t_sc; | |
| 554 | |
| 555 while( sc->sc_outm != NULL ) | |
| 556 { | |
| 557 // We wait for the output buffer to drain of all characters | |
| 558 // before we call pppasyncstart(). That way we know there will | |
| 559 // be room for some data. We would really like to just drain | |
| 560 // down to some low water mark, but the drivers don't provide | |
| 561 // that functionality. However, since most devices have | |
| 562 // hardware FIFO's, we have a grace period to get more | |
| 563 // characters into the device, so hopefully there won't be a | |
| 564 // gap on the line. | |
| 565 | |
| 566 cyg_uint32 nb = 0; | |
| 567 cyg_uint32 len = sizeof(nb); | |
| 568 int s; | |
| 569 | |
| 570 cyg_io_get_config( tp->t_handle, | |
| 571 CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN, | |
| 572 &nb, &len); | |
| 573 | |
| 574 s = splsoftnet(); | |
| 575 | |
| 576 pppasyncstart( sc ); | |
| 577 | |
| 578 splx(s); | |
| 579 } | |
| 580 | |
| 581 return 0; | |
| 582 } | |
| 583 | |
| 584 #endif | |
| 585 | |
| 586 | |
| 587 //========================================================================== | |
| 588 /* | |
| 589 * This gets called at splsoftnet from if_ppp.c at various times | |
| 590 * when there is data ready to be sent. | |
| 591 */ | |
| 592 static void | |
| 593 pppasyncstart(sc) | |
| 594 register struct ppp_softc *sc; | |
| 595 { | |
| 596 register struct tty *tp = (struct tty *) sc->sc_devp; | |
| 597 register struct mbuf *m; | |
|
2041
9ea31f9f2254
* src/ppp_io.c (cyg_ppp_pppread): caddrt_t to stop compiler warnings.
asl
parents:
1923
diff
changeset
|
598 register unsigned int len; |
| 1586 | 599 register u_char *start, *stop, *cp; |
|
2041
9ea31f9f2254
* src/ppp_io.c (cyg_ppp_pppread): caddrt_t to stop compiler warnings.
asl
parents:
1923
diff
changeset
|
600 int n, done, idle; |
|
9ea31f9f2254
* src/ppp_io.c (cyg_ppp_pppread): caddrt_t to stop compiler warnings.
asl
parents:
1923
diff
changeset
|
601 cyg_uint32 ndone; |
| 1586 | 602 struct mbuf *m2; |
| 603 int s; | |
| 604 idle = 0; | |
| 1868 | 605 #ifdef CYGPKT_PPP_WORKAROUNDS_START_FLAG |
| 606 char start_flag = PPP_FLAG; | |
| 607 int start_flag_len = sizeof(start_flag); | |
| 608 #endif | |
| 1586 | 609 |
| 610 while (1) { | |
| 611 /* | |
| 612 * See if we have an existing packet partly sent. | |
| 613 * If not, get a new packet and start sending it. | |
| 614 */ | |
| 615 m = sc->sc_outm; | |
| 616 if (m == NULL) { | |
| 617 /* | |
| 618 * Get another packet to be sent. | |
| 619 */ | |
| 620 m = ppp_dequeue(sc); | |
| 621 if (m == NULL) { | |
| 622 idle = 1; | |
| 623 break; | |
| 624 } | |
| 625 | |
| 626 /* Calculate the FCS for the first mbuf's worth. */ | |
| 627 sc->sc_outfcs = pppfcs(PPP_INITFCS, mtod(m, u_char *), m->m_len); | |
| 1868 | 628 getmicrotime(&sc->sc_if.if_lastchange); |
| 629 #ifdef CYGPKT_PPP_WORKAROUNDS_START_FLAG | |
| 630 cyg_io_write(tp->t_handle, &start_flag, &start_flag_len); | |
| 631 #endif | |
| 1586 | 632 } |
| 633 | |
| 634 for (;;) { | |
| 635 start = mtod(m, u_char *); | |
| 636 len = m->m_len; | |
| 637 stop = start + len; | |
| 638 while (len > 0) { | |
| 639 /* | |
| 640 * Find out how many bytes in the string we can | |
| 641 * handle without doing something special. | |
| 642 */ | |
| 643 for (cp = start; cp < stop; cp++) | |
| 644 if (ESCAPE_P(*cp)) | |
| 645 break; | |
| 646 n = cp - start; | |
| 647 if (n) { | |
| 648 #ifndef __ECOS | |
| 649 /* NetBSD (0.9 or later), 4.3-Reno or similar. */ | |
| 650 ndone = n - b_to_q(start, n, &tp->t_outq); | |
| 651 #else | |
| 652 ndone = 0; | |
| 653 // db_printf("send: data %d\n",ndone); | |
| 654 // db_dump_buf(start,ndone); | |
| 655 { | |
| 656 cyg_serial_buf_info_t info; | |
| 657 cyg_uint32 ilen = sizeof(info); | |
| 658 if( cyg_io_get_config( tp->t_handle, CYG_IO_GET_CONFIG_SERIAL_BUFFER_INFO, &info, &ilen ) == 0 ) | |
| 659 { | |
| 660 ndone = info.tx_bufsize-info.tx_count; | |
| 661 if( ndone > n ) | |
| 662 ndone = n; | |
| 663 cyg_io_write( tp->t_handle, start, &ndone); | |
| 664 } | |
| 665 } | |
| 666 #endif | |
| 667 len -= ndone; | |
| 668 start += ndone; | |
| 669 sc->sc_stats.ppp_obytes += ndone; | |
| 670 | |
| 671 if (ndone < n) | |
| 672 break; /* packet doesn't fit */ | |
| 673 } | |
| 674 /* | |
| 675 * If there are characters left in the mbuf, | |
| 676 * the first one must be special. | |
| 677 * Put it out in a different form. | |
| 678 */ | |
| 679 if (len) { | |
| 680 s = spltty(); | |
| 681 #ifndef __ECOS | |
| 682 if (putc(PPP_ESCAPE, &tp->t_outq)) { | |
| 683 splx(s); | |
| 684 break; | |
| 685 } | |
| 686 if (putc(*start ^ PPP_TRANS, &tp->t_outq)) { | |
| 687 (void) unputc(&tp->t_outq); | |
| 688 splx(s); | |
| 689 break; | |
| 690 } | |
| 691 #else | |
| 692 { | |
| 693 cyg_serial_buf_info_t info; | |
| 694 cyg_uint32 ilen = sizeof(info); | |
| 695 if( cyg_io_get_config( tp->t_handle, CYG_IO_GET_CONFIG_SERIAL_BUFFER_INFO, &info, &ilen ) == 0 && | |
| 696 info.tx_bufsize-info.tx_count >= 2 ) | |
| 697 { | |
| 698 char buf[2]; | |
|
2041
9ea31f9f2254
* src/ppp_io.c (cyg_ppp_pppread): caddrt_t to stop compiler warnings.
asl
parents:
1923
diff
changeset
|
699 cyg_uint32 blen = 2; |
| 1586 | 700 buf[0] = PPP_ESCAPE; |
| 701 buf[1] = *start ^ PPP_TRANS; | |
| 702 if( cyg_io_write( tp->t_handle, buf, &blen) != 0 ) { | |
| 703 splx(s); | |
| 704 break; | |
| 705 } | |
| 706 } | |
| 707 else | |
| 708 { | |
| 709 splx(s); | |
| 710 break; | |
| 711 } | |
| 712 } | |
| 713 #endif | |
| 714 splx(s); | |
| 715 sc->sc_stats.ppp_obytes += 2; | |
| 716 start++; | |
| 717 len--; | |
| 718 } // if( len ) | |
| 719 } // while (len > 0) | |
| 720 | |
| 721 /* | |
| 722 * If we didn't empty this mbuf, remember where we're up to. | |
| 723 * If we emptied the last mbuf, try to add the FCS and closing | |
| 724 * flag, and if we can't, leave sc_outm pointing to m, but with | |
| 725 * m->m_len == 0, to remind us to output the FCS and flag later. | |
| 726 */ | |
| 727 done = len == 0; | |
| 728 if (done && m->m_next == NULL) { | |
| 729 u_char *p, *q; | |
| 730 int c; | |
| 731 u_char endseq[8]; | |
| 732 | |
| 733 /* | |
| 734 * We may have to escape the bytes in the FCS. | |
| 735 */ | |
| 736 p = endseq; | |
| 737 c = ~sc->sc_outfcs & 0xFF; | |
| 738 if (ESCAPE_P(c)) { | |
| 739 *p++ = PPP_ESCAPE; | |
| 740 *p++ = c ^ PPP_TRANS; | |
| 741 } else | |
| 742 *p++ = c; | |
| 743 c = (~sc->sc_outfcs >> 8) & 0xFF; | |
| 744 if (ESCAPE_P(c)) { | |
| 745 *p++ = PPP_ESCAPE; | |
| 746 *p++ = c ^ PPP_TRANS; | |
| 747 } else | |
| 748 *p++ = c; | |
| 749 *p++ = PPP_FLAG; | |
| 750 | |
| 751 /* | |
| 752 * Try to output the FCS and flag. If the bytes | |
| 753 * don't all fit, back out. | |
| 754 */ | |
| 755 s = spltty(); | |
| 756 #ifndef __ECOS | |
| 757 for (q = endseq; q < p; ++q) | |
| 758 if (putc(*q, &tp->t_outq)) { | |
| 759 done = 0; | |
| 760 for (; q > endseq; --q) | |
| 761 unputc(&tp->t_outq); | |
| 762 break; | |
| 763 } | |
| 764 #else | |
| 765 { | |
|
2041
9ea31f9f2254
* src/ppp_io.c (cyg_ppp_pppread): caddrt_t to stop compiler warnings.
asl
parents:
1923
diff
changeset
|
766 cyg_uint32 elen = p-endseq; |
| 1586 | 767 cyg_serial_buf_info_t info; |
| 768 cyg_uint32 ilen = sizeof(info); | |
| 769 q = p; | |
| 770 if( (cyg_io_get_config( tp->t_handle, CYG_IO_GET_CONFIG_SERIAL_BUFFER_INFO, &info, &ilen ) == 0) && | |
| 771 ((info.tx_bufsize-info.tx_count) >= elen) ) | |
| 772 { | |
| 773 if( cyg_io_write( tp->t_handle, endseq, &elen) != 0 ) { | |
| 774 done = 0; | |
| 775 } | |
| 776 } | |
| 777 else | |
| 778 { | |
| 779 done = 0; | |
| 780 } | |
| 781 } | |
| 782 #endif | |
| 783 splx(s); | |
| 784 if (done) | |
| 785 sc->sc_stats.ppp_obytes += q - endseq; | |
| 786 } // if (done && m->m_next == NULL) | |
| 787 | |
| 788 if (!done) { | |
| 789 /* remember where we got to */ | |
|
2041
9ea31f9f2254
* src/ppp_io.c (cyg_ppp_pppread): caddrt_t to stop compiler warnings.
asl
parents:
1923
diff
changeset
|
790 m->m_data = (char *)start; |
| 1586 | 791 m->m_len = len; |
| 792 break; | |
| 793 } | |
| 794 | |
| 795 /* Finished with this mbuf; free it and move on. */ | |
| 796 MFREE(m, m2); | |
| 797 m = m2; | |
| 798 if (m == NULL) { | |
| 799 /* Finished a packet */ | |
| 800 break; | |
| 801 } | |
| 802 sc->sc_outfcs = pppfcs(sc->sc_outfcs, mtod(m, u_char *), m->m_len); | |
| 803 } // for(;;) | |
| 804 | |
| 805 /* | |
| 806 * If m == NULL, we have finished a packet. | |
| 807 * If m != NULL, we've either done as much work this time | |
| 808 * as we need to, or else we've filled up the output queue. | |
| 809 */ | |
| 810 sc->sc_outm = m; | |
| 811 if (m) | |
| 812 break; | |
| 813 } | |
| 814 | |
| 815 #ifndef __ECOS | |
| 816 /* Call pppstart to start output again if necessary. */ | |
| 817 s = spltty(); | |
| 818 pppstart(tp); | |
| 819 | |
| 820 /* | |
| 821 * This timeout is needed for operation on a pseudo-tty, | |
| 822 * because the pty code doesn't call pppstart after it has | |
| 823 * drained the t_outq. | |
| 824 */ | |
| 825 if (!idle && (sc->sc_flags & SC_TIMEOUT) == 0) { | |
| 826 sc->sc_ch = timeout(ppp_timeout, (void *) sc, 1); | |
| 827 sc->sc_flags |= SC_TIMEOUT; | |
| 828 } | |
| 829 | |
| 830 splx(s); | |
| 831 | |
| 832 #else | |
| 833 | |
| 834 s = spltty(); | |
| 835 | |
| 836 if( sc->sc_outm != NULL && | |
| 837 cyg_thread_self() != tp->tx_thread ) | |
| 838 { | |
| 839 cyg_semaphore_post( &tp->tx_sem ); | |
| 840 } | |
| 841 | |
| 842 splx(s); | |
| 843 | |
| 844 #endif | |
| 845 | |
| 846 } | |
| 847 | |
| 848 //========================================================================== | |
| 849 /* | |
| 850 * This gets called when a received packet is placed on | |
| 851 * the inq, at splsoftnet. The pppd daemon is to be woken up to do a read(). | |
| 852 */ | |
| 853 static void | |
| 854 pppasyncctlp(sc) | |
| 855 struct ppp_softc *sc; | |
| 856 { | |
| 857 struct tty *tp; | |
| 858 int s; | |
| 859 | |
| 860 s = spltty(); | |
| 861 tp = (struct tty *) sc->sc_devp; | |
| 862 | |
| 863 tp->pppd_wakeup = 1; | |
| 864 if( tp->pppd_thread != cyg_thread_self() ) | |
| 865 cyg_thread_release( tp->pppd_thread ); | |
| 866 | |
| 867 splx(s); | |
| 868 } | |
| 869 | |
| 870 //========================================================================== | |
| 871 /* | |
| 872 * Allocate enough mbuf to handle current MRU. | |
| 873 */ | |
| 874 static void | |
| 875 pppgetm(sc) | |
| 876 register struct ppp_softc *sc; | |
| 877 { | |
| 878 struct mbuf *m, **mp; | |
| 879 int len; | |
| 880 | |
| 881 mp = &sc->sc_m; | |
| 882 for (len = sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN; len > 0; ){ | |
| 883 if ((m = *mp) == NULL) { | |
| 884 MGETHDR(m, M_DONTWAIT, MT_DATA); | |
| 885 if (m == NULL) | |
| 886 break; | |
| 887 *mp = m; | |
| 888 MCLGET(m, M_DONTWAIT); | |
| 889 } | |
| 890 len -= M_DATASIZE(m); | |
| 891 mp = &m->m_next; | |
| 892 } | |
| 893 } | |
| 894 | |
| 895 //========================================================================== | |
| 896 /* | |
| 897 * tty interface receiver interrupt. | |
| 898 */ | |
| 899 | |
| 900 static unsigned paritytab[8] = { | |
| 901 0x96696996, 0x69969669, 0x69969669, 0x96696996, | |
| 902 0x69969669, 0x96696996, 0x96696996, 0x69969669 | |
| 903 }; | |
| 904 | |
| 905 /* | |
| 906 * Called when character is available from device driver. | |
| 907 * Only guaranteed to be at splsofttty() or spltty() | |
| 908 * This is safe to be called while the upper half's netisr is preempted. | |
| 909 */ | |
| 910 int | |
| 911 cyg_ppp_pppinput(c, tp) | |
| 912 int c; | |
| 913 register struct tty *tp; | |
| 914 { | |
| 915 register struct ppp_softc *sc; | |
| 916 struct mbuf *m; | |
| 917 int ilen, s; | |
| 918 | |
| 919 sc = (struct ppp_softc *) tp->t_sc; | |
| 920 if (sc == NULL || tp != (struct tty *) sc->sc_devp) | |
| 921 return 0; | |
| 922 | |
| 923 // ++tk_nin; | |
| 924 ++sc->sc_stats.ppp_ibytes; | |
| 925 | |
| 926 s = spltty(); | |
| 927 if (c & 0x80) | |
| 928 sc->sc_flags |= SC_RCV_B7_1; | |
| 929 else | |
| 930 sc->sc_flags |= SC_RCV_B7_0; | |
| 931 if (paritytab[c >> 5] & (1 << (c & 0x1F))) | |
| 932 sc->sc_flags |= SC_RCV_ODDP; | |
| 933 else | |
| 934 sc->sc_flags |= SC_RCV_EVNP; | |
| 935 splx(s); | |
| 936 | |
| 937 if (sc->sc_flags & SC_LOG_RAWIN) | |
| 938 ppplogchar(sc, c); | |
| 939 | |
| 940 if (c == PPP_FLAG) { | |
| 941 ilen = sc->sc_ilen; | |
| 942 sc->sc_ilen = 0; | |
| 943 if (sc->sc_rawin_count > 0) | |
| 944 ppplogchar(sc, -1); | |
| 945 | |
| 946 /* | |
| 947 * If SC_ESCAPED is set, then we've seen the packet | |
| 948 * abort sequence "}~". | |
| 949 */ | |
| 950 if (sc->sc_flags & (SC_FLUSH | SC_ESCAPED) | |
| 951 || (ilen > 0 && sc->sc_fcs != PPP_GOODFCS)) { | |
| 952 s = spltty(); | |
| 953 sc->sc_flags |= SC_PKTLOST; /* note the dropped packet */ | |
| 954 if ((sc->sc_flags & (SC_FLUSH | SC_ESCAPED)) == 0){ | |
| 955 #if 1 | |
| 956 if (sc->sc_flags & SC_DEBUG) | |
| 957 diag_printf("ppp%d: bad fcs %x, pkt len %d\n", | |
| 958 sc->sc_if.if_unit, sc->sc_fcs, ilen); | |
| 959 #endif | |
| 960 sc->sc_if.if_ierrors++; | |
| 961 sc->sc_stats.ppp_ierrors++; | |
| 962 } else | |
| 963 sc->sc_flags &= ~(SC_FLUSH | SC_ESCAPED); | |
| 964 splx(s); | |
| 965 return 0; | |
| 966 } | |
| 967 | |
| 968 if (ilen < PPP_HDRLEN + PPP_FCSLEN) { | |
| 969 if (ilen) { | |
| 970 if (sc->sc_flags & SC_DEBUG) | |
| 971 diag_printf("ppp%d: too short (%d)\n", sc->sc_if.if_unit, ilen); | |
| 972 s = spltty(); | |
| 973 sc->sc_if.if_ierrors++; | |
| 974 sc->sc_stats.ppp_ierrors++; | |
| 975 sc->sc_flags |= SC_PKTLOST; | |
| 976 splx(s); | |
| 977 } | |
| 978 return 0; | |
| 979 } | |
| 980 | |
| 981 /* | |
| 982 * Remove FCS trailer. Somewhat painful... | |
| 983 */ | |
| 984 ilen -= 2; | |
| 985 if (--sc->sc_mc->m_len == 0) { | |
| 986 for (m = sc->sc_m; m->m_next != sc->sc_mc; m = m->m_next) | |
| 987 ; | |
| 988 sc->sc_mc = m; | |
| 989 } | |
| 990 sc->sc_mc->m_len--; | |
| 991 | |
| 992 /* excise this mbuf chain */ | |
| 993 m = sc->sc_m; | |
| 994 sc->sc_m = sc->sc_mc->m_next; | |
| 995 sc->sc_mc->m_next = NULL; | |
| 996 | |
| 997 ppppktin(sc, m, sc->sc_flags & SC_PKTLOST); | |
| 998 if (sc->sc_flags & SC_PKTLOST) { | |
| 999 s = spltty(); | |
| 1000 sc->sc_flags &= ~SC_PKTLOST; | |
| 1001 splx(s); | |
| 1002 } | |
| 1003 | |
| 1004 pppgetm(sc); | |
| 1005 return 0; | |
| 1006 } | |
| 1007 | |
| 1008 if (sc->sc_flags & SC_FLUSH) { | |
| 1009 if (sc->sc_flags & SC_LOG_FLUSH) | |
| 1010 ppplogchar(sc, c); | |
| 1011 return 0; | |
| 1012 } | |
| 1013 | |
| 1014 if (c < 0x20 && (sc->sc_rasyncmap & (1 << c))) | |
| 1015 return 0; | |
| 1016 | |
| 1017 s = spltty(); | |
| 1018 if (sc->sc_flags & SC_ESCAPED) { | |
| 1019 sc->sc_flags &= ~SC_ESCAPED; | |
| 1020 c ^= PPP_TRANS; | |
| 1021 } else if (c == PPP_ESCAPE) { | |
| 1022 sc->sc_flags |= SC_ESCAPED; | |
| 1023 splx(s); | |
| 1024 return 0; | |
| 1025 } | |
| 1026 splx(s); | |
| 1027 | |
| 1028 /* | |
| 1029 * Initialize buffer on first octet received. | |
| 1030 * First octet could be address or protocol (when compressing | |
| 1031 * address/control). | |
| 1032 * Second octet is control. | |
| 1033 * Third octet is first or second (when compressing protocol) | |
| 1034 * octet of protocol. | |
| 1035 * Fourth octet is second octet of protocol. | |
| 1036 */ | |
| 1037 if (sc->sc_ilen == 0) { | |
| 1038 /* reset the first input mbuf */ | |
| 1039 if (sc->sc_m == NULL) { | |
| 1040 pppgetm(sc); | |
| 1041 if (sc->sc_m == NULL) { | |
| 1042 if (sc->sc_flags & SC_DEBUG) | |
| 1043 diag_printf("ppp%d: no input mbufs!\n", sc->sc_if.if_unit); | |
| 1044 goto flush; | |
| 1045 } | |
| 1046 } | |
| 1047 m = sc->sc_m; | |
| 1048 m->m_len = 0; | |
| 1049 m->m_data = M_DATASTART(sc->sc_m); | |
| 1050 sc->sc_mc = m; | |
| 1051 sc->sc_mp = mtod(m, char *); | |
| 1052 sc->sc_fcs = PPP_INITFCS; | |
| 1053 if (c != PPP_ALLSTATIONS) { | |
| 1054 if (sc->sc_flags & SC_REJ_COMP_AC) { | |
| 1055 if (sc->sc_flags & SC_DEBUG) | |
| 1056 diag_printf("ppp%d: garbage received: 0x%x (need 0xFF)\n", | |
| 1057 sc->sc_if.if_unit, c); | |
| 1058 goto flush; | |
| 1059 } | |
| 1060 *sc->sc_mp++ = PPP_ALLSTATIONS; | |
| 1061 *sc->sc_mp++ = PPP_UI; | |
| 1062 sc->sc_ilen += 2; | |
| 1063 m->m_len += 2; | |
| 1064 } | |
| 1065 } | |
| 1066 if (sc->sc_ilen == 1 && c != PPP_UI) { | |
| 1067 if (sc->sc_flags & SC_DEBUG) | |
| 1068 diag_printf("ppp%d: missing UI (0x3), got 0x%x\n", | |
| 1069 sc->sc_if.if_unit, c); | |
| 1070 goto flush; | |
| 1071 } | |
| 1072 if (sc->sc_ilen == 2 && (c & 1) == 1) { | |
| 1073 /* a compressed protocol */ | |
| 1074 *sc->sc_mp++ = 0; | |
| 1075 sc->sc_ilen++; | |
| 1076 sc->sc_mc->m_len++; | |
| 1077 } | |
| 1078 if (sc->sc_ilen == 3 && (c & 1) == 0) { | |
| 1079 if (sc->sc_flags & SC_DEBUG) | |
| 1080 diag_printf("ppp%d: bad protocol %x\n", sc->sc_if.if_unit, | |
| 1081 (sc->sc_mp[-1] << 8) + c); | |
| 1082 goto flush; | |
| 1083 } | |
| 1084 | |
| 1085 /* packet beyond configured mru? */ | |
| 1086 if (++sc->sc_ilen > sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN) { | |
| 1087 if (sc->sc_flags & SC_DEBUG) | |
| 1088 diag_printf("ppp%d: packet too big\n", sc->sc_if.if_unit); | |
| 1089 goto flush; | |
| 1090 } | |
| 1091 | |
| 1092 /* is this mbuf full? */ | |
| 1093 m = sc->sc_mc; | |
| 1094 if (M_TRAILINGSPACE(m) <= 0) { | |
| 1095 if (m->m_next == NULL) { | |
| 1096 pppgetm(sc); | |
| 1097 if (m->m_next == NULL) { | |
| 1098 if (sc->sc_flags & SC_DEBUG) | |
| 1099 diag_printf("ppp%d: too few input mbufs!\n", sc->sc_if.if_unit); | |
| 1100 goto flush; | |
| 1101 } | |
| 1102 } | |
| 1103 sc->sc_mc = m = m->m_next; | |
| 1104 m->m_len = 0; | |
| 1105 m->m_data = M_DATASTART(m); | |
| 1106 sc->sc_mp = mtod(m, char *); | |
| 1107 } | |
| 1108 | |
| 1109 ++m->m_len; | |
| 1110 *sc->sc_mp++ = c; | |
| 1111 sc->sc_fcs = PPP_FCS(sc->sc_fcs, c); | |
| 1112 | |
| 1113 return 0; | |
| 1114 | |
| 1115 flush: | |
| 1116 if (!(sc->sc_flags & SC_FLUSH)) { | |
| 1117 s = spltty(); | |
| 1118 sc->sc_if.if_ierrors++; | |
| 1119 sc->sc_stats.ppp_ierrors++; | |
| 1120 sc->sc_flags |= SC_FLUSH; | |
| 1121 splx(s); | |
| 1122 if (sc->sc_flags & SC_LOG_FLUSH) | |
| 1123 ppplogchar(sc, c); | |
| 1124 } | |
| 1125 return 0; | |
| 1126 } | |
| 1127 | |
| 1128 //========================================================================== | |
| 1129 | |
| 1130 #define MAX_DUMP_BYTES 128 | |
| 1131 | |
| 1132 static void | |
| 1133 ppplogchar(sc, c) | |
| 1134 struct ppp_softc *sc; | |
| 1135 int c; | |
| 1136 { | |
| 1137 if (c >= 0) | |
| 1138 sc->sc_rawin[sc->sc_rawin_count++] = c; | |
| 1139 if (sc->sc_rawin_count >= sizeof(sc->sc_rawin) | |
| 1140 || (c < 0 && sc->sc_rawin_count > 0)) { | |
|
1923
84f7fdb14fae
* tests/ppp_up.c: Change the prototype of pr_func to match
asl
parents:
1868
diff
changeset
|
1141 diag_printf("ppp%d input:\n",sc->sc_if.if_unit); |
| 1586 | 1142 diag_vdump_buf_with_offset( diag_printf, sc->sc_rawin, sc->sc_rawin_count, sc->sc_rawin ); |
| 1143 sc->sc_rawin_count = 0; | |
| 1144 } | |
| 1145 } | |
| 1146 | |
| 1147 //========================================================================== | |
| 1148 // End of ppp_io.c | |
| 1149 |
