| 639 | } |
| 640 | |
| 641 | static int |
| 642 | pfsync_input(struct mbuf **mp, int *offp __unused, int proto __unused) |
| 643 | { |
| 644 | struct pfsync_softc *sc = V_pfsyncif; |
| 645 | struct pfsync_pkt pkt; |
| 646 | struct mbuf *m = *mp; |
| 647 | struct ip *ip = mtod(m, struct ip *); |
| 648 | struct pfsync_header *ph; |
| 649 | struct pfsync_subheader subh; |
| 650 | |
| 651 | int offset, len; |
| 652 | int rv; |
| 653 | uint16_t count; |
| 654 | |
| 655 | PF_RULES_RLOCK_TRACKER; |
| 656 | |
| 657 | *mp = NULL; |
| 658 | V_pfsyncstats.pfsyncs_ipackets++; |
| 659 | |
| 660 | /* Verify that we have a sync interface configured. */ |
| 661 | if (!sc || !sc->sc_sync_if || !V_pf_status.running || |
| 662 | (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) |
| 663 | goto done; |
| 664 | |
| 665 | /* verify that the packet came in on the right interface */ |
| 666 | if (sc->sc_sync_if != m->m_pkthdr.rcvif) { |
| 667 | V_pfsyncstats.pfsyncs_badif++; |
| 668 | goto done; |
| 669 | } |
| 670 | |
| 671 | if_inc_counter(sc->sc_ifp, IFCOUNTER_IPACKETS, 1); |
| 672 | if_inc_counter(sc->sc_ifp, IFCOUNTER_IBYTES, m->m_pkthdr.len); |
| 673 | /* verify that the IP TTL is 255. */ |
| 674 | if (ip->ip_ttl != PFSYNC_DFLTTL) { |
| 675 | V_pfsyncstats.pfsyncs_badttl++; |
| 676 | goto done; |
| 677 | } |
| 678 | |
| 679 | offset = ip->ip_hl << 2; |
| 680 | if (m->m_pkthdr.len < offset + sizeof(*ph)) { |
| 681 | V_pfsyncstats.pfsyncs_hdrops++; |
| 682 | goto done; |
| 683 | } |
| 684 | |
| 685 | if (offset + sizeof(*ph) > m->m_len) { |
| 686 | if (m_pullup(m, offset + sizeof(*ph)) == NULL) { |
| 687 | V_pfsyncstats.pfsyncs_hdrops++; |
| 688 | return (IPPROTO_DONE); |
| 689 | } |
| 690 | ip = mtod(m, struct ip *); |
| 691 | } |
| 692 | ph = (struct pfsync_header *)((char *)ip + offset); |
| 693 | |
| 694 | /* verify the version */ |
| 695 | if (ph->version != PFSYNC_VERSION) { |
| 696 | V_pfsyncstats.pfsyncs_badver++; |
| 697 | goto done; |
| 698 | } |
nothing calls this directly
no test coverage detected