| 451 | } |
| 452 | |
| 453 | void |
| 454 | bstp_input(struct bstp_port *bp, struct ifnet *ifp, struct mbuf *m) |
| 455 | { |
| 456 | struct bstp_state *bs = bp->bp_bs; |
| 457 | struct ether_header *eh; |
| 458 | struct bstp_tbpdu tpdu; |
| 459 | uint16_t len; |
| 460 | |
| 461 | if (bp->bp_active == 0) { |
| 462 | m_freem(m); |
| 463 | return; |
| 464 | } |
| 465 | |
| 466 | BSTP_LOCK(bs); |
| 467 | |
| 468 | eh = mtod(m, struct ether_header *); |
| 469 | |
| 470 | len = ntohs(eh->ether_type); |
| 471 | if (len < sizeof(tpdu)) |
| 472 | goto out; |
| 473 | |
| 474 | m_adj(m, ETHER_HDR_LEN); |
| 475 | |
| 476 | if (m->m_pkthdr.len > len) |
| 477 | m_adj(m, len - m->m_pkthdr.len); |
| 478 | if (m->m_len < sizeof(tpdu) && |
| 479 | (m = m_pullup(m, sizeof(tpdu))) == NULL) |
| 480 | goto out; |
| 481 | |
| 482 | memcpy(&tpdu, mtod(m, caddr_t), sizeof(tpdu)); |
| 483 | |
| 484 | /* basic packet checks */ |
| 485 | if (tpdu.tbu_dsap != LLC_8021D_LSAP || |
| 486 | tpdu.tbu_ssap != LLC_8021D_LSAP || |
| 487 | tpdu.tbu_ctl != LLC_UI) |
| 488 | goto out; |
| 489 | if (tpdu.tbu_protoid != BSTP_PROTO_ID) |
| 490 | goto out; |
| 491 | |
| 492 | /* |
| 493 | * We can treat later versions of the PDU as the same as the maximum |
| 494 | * version we implement. All additional parameters/flags are ignored. |
| 495 | */ |
| 496 | if (tpdu.tbu_protover > BSTP_PROTO_MAX) |
| 497 | tpdu.tbu_protover = BSTP_PROTO_MAX; |
| 498 | |
| 499 | if (tpdu.tbu_protover != bp->bp_protover) { |
| 500 | /* |
| 501 | * Wait for the migration delay timer to expire before changing |
| 502 | * protocol version to avoid flip-flops. |
| 503 | */ |
| 504 | if (bp->bp_flags & BSTP_PORT_CANMIGRATE) |
| 505 | bstp_set_port_proto(bp, tpdu.tbu_protover); |
| 506 | else |
| 507 | goto out; |
| 508 | } |
| 509 | |
| 510 | /* Clear operedge upon receiving a PDU on the port */ |
no test coverage detected