* Receive incoming asynchronous data * XXX Technically, we should strip out incoming characters * that are in our ACCM. Not sure if this is good or not. */
| 488 | * that are in our ACCM. Not sure if this is good or not. |
| 489 | */ |
| 490 | static int |
| 491 | nga_rcv_async(const sc_p sc, item_p item) |
| 492 | { |
| 493 | struct ifnet *rcvif; |
| 494 | int error; |
| 495 | struct mbuf *m; |
| 496 | |
| 497 | if (!sc->cfg.enabled) { |
| 498 | NG_FWD_ITEM_HOOK(error, item, sc->sync); |
| 499 | return (error); |
| 500 | } |
| 501 | NGI_GET_M(item, m); |
| 502 | rcvif = m->m_pkthdr.rcvif; |
| 503 | while (m) { |
| 504 | struct mbuf *n; |
| 505 | |
| 506 | for (; m->m_len > 0; m->m_data++, m->m_len--) { |
| 507 | u_char ch = *mtod(m, u_char *); |
| 508 | |
| 509 | sc->stats.asyncOctets++; |
| 510 | if (ch == PPP_FLAG) { /* Flag overrides everything */ |
| 511 | int skip = 0; |
| 512 | |
| 513 | /* Check for runts */ |
| 514 | if (sc->slen < 2) { |
| 515 | if (sc->slen > 0) |
| 516 | sc->stats.asyncRunts++; |
| 517 | goto reset; |
| 518 | } |
| 519 | |
| 520 | /* Verify CRC */ |
| 521 | if (sc->fcs != PPP_GOODFCS) { |
| 522 | sc->stats.asyncBadCheckSums++; |
| 523 | goto reset; |
| 524 | } |
| 525 | sc->slen -= 2; |
| 526 | |
| 527 | /* Strip address and control fields */ |
| 528 | if (sc->slen >= 2 |
| 529 | && sc->sbuf[0] == PPP_ALLSTATIONS |
| 530 | && sc->sbuf[1] == PPP_UI) |
| 531 | skip = 2; |
| 532 | |
| 533 | /* Check for frame too big */ |
| 534 | if (sc->slen - skip > sc->cfg.amru) { |
| 535 | sc->stats.asyncOverflows++; |
| 536 | goto reset; |
| 537 | } |
| 538 | |
| 539 | /* OK, ship it out */ |
| 540 | if ((n = m_devget(sc->sbuf + skip, |
| 541 | sc->slen - skip, 0, rcvif, NULL))) { |
| 542 | if (item) { /* sets NULL -> item */ |
| 543 | NG_FWD_NEW_DATA(error, item, |
| 544 | sc->sync, n); |
| 545 | } else { |
| 546 | NG_SEND_DATA_ONLY(error, |
| 547 | sc->sync ,n); |
no test coverage detected