* Receive incoming synchronous data. */
| 397 | * Receive incoming synchronous data. |
| 398 | */ |
| 399 | static int |
| 400 | nga_rcv_sync(const sc_p sc, item_p item) |
| 401 | { |
| 402 | struct ifnet *rcvif; |
| 403 | int alen, error = 0; |
| 404 | struct timeval time; |
| 405 | u_int16_t fcs, fcs0; |
| 406 | u_int32_t accm; |
| 407 | struct mbuf *m; |
| 408 | |
| 409 | #define ADD_BYTE(x) nga_async_add(sc, &fcs, accm, &alen, (x)) |
| 410 | |
| 411 | /* Check for bypass mode */ |
| 412 | if (!sc->cfg.enabled) { |
| 413 | NG_FWD_ITEM_HOOK(error, item, sc->async ); |
| 414 | return (error); |
| 415 | } |
| 416 | NGI_GET_M(item, m); |
| 417 | |
| 418 | rcvif = m->m_pkthdr.rcvif; |
| 419 | |
| 420 | /* Get ACCM; special case LCP frames, which use full ACCM */ |
| 421 | accm = sc->cfg.accm; |
| 422 | if (m->m_pkthdr.len >= 4) { |
| 423 | static const u_char lcphdr[4] = { |
| 424 | PPP_ALLSTATIONS, |
| 425 | PPP_UI, |
| 426 | (u_char)(PPP_LCP >> 8), |
| 427 | (u_char)(PPP_LCP & 0xff) |
| 428 | }; |
| 429 | u_char buf[4]; |
| 430 | |
| 431 | m_copydata(m, 0, 4, (caddr_t)buf); |
| 432 | if (bcmp(buf, &lcphdr, 4) == 0) |
| 433 | accm = ~0; |
| 434 | } |
| 435 | |
| 436 | /* Check for overflow */ |
| 437 | if (m->m_pkthdr.len > sc->cfg.smru) { |
| 438 | sc->stats.syncOverflows++; |
| 439 | NG_FREE_M(m); |
| 440 | NG_FREE_ITEM(item); |
| 441 | return (EMSGSIZE); |
| 442 | } |
| 443 | |
| 444 | /* Update stats */ |
| 445 | sc->stats.syncFrames++; |
| 446 | sc->stats.syncOctets += m->m_pkthdr.len; |
| 447 | |
| 448 | /* Initialize async encoded version of input mbuf */ |
| 449 | alen = 0; |
| 450 | fcs = PPP_INITFCS; |
| 451 | |
| 452 | /* Add beginning sync flag if it's been long enough to need one */ |
| 453 | getmicrotime(&time); |
| 454 | if (time.tv_sec >= sc->lasttime + 1) { |
| 455 | sc->abuf[alen++] = PPP_FLAG; |
| 456 | sc->lasttime = time.tv_sec; |
no test coverage detected