so pflog has several issues right now, the worst being that it logs
the "wrong" addresses, as in, before rewriting is apllied.

before we broke it several releases ago pflog kept rewriting the live
mbuf all the time and immediately, and then trying to un-do the
rewriting if needed... horrible, complex, was full of bugs, fortunately
dead.
we don't want an extra copy of the mbuf (-chain) either, just to pass
it to bpf which then copies it into the bpf buffer. so apply the
rewrite to the bpf buffer hiding as data storage behind a fake mbuf ;)
works.

kinda strange sideeffect: if snaplen is smaller then pflog header size
+ ip header size + protocol header size, i cannot do the rewrite. we
need to raise the snaplen for pflog by default since the pflog header
grows a lot (that is mostly preparation for upcomimg work). for now pls
use -s 160 or more on tcpdump. oh and when the snaplen is too small i
don't do the rewrite and pass out the packet unmodified... not sure
what else we could do but dropping, which would be inconsistent with
other pcap stuff.

this touches the regular code patches (aka non-pflog) quite a bit too,
there is some heavy code refactoring. watch you state tables
carefully.

almost completely written at c2k10 in canada and just made work here in
japan ;)

and now quickly senidng out before the super duper net dies again. all
typos to be blamed on latency.

Index: sys/net/bpf.c
===================================================================
RCS file: /cvs/src/sys/net/bpf.c,v
retrieving revision 1.75
diff -u -p -r1.75 bpf.c
--- sys/net/bpf.c       9 Nov 2009 17:53:39 -0000       1.75
+++ sys/net/bpf.c       20 Sep 2010 08:54:41 -0000
@@ -64,6 +64,11 @@
 #include <net/if_vlan_var.h>
 #endif
 
+#include "pflog.h"
+#if NPFLOG > 0
+#include <net/if_pflog.h>
+#endif
+
 #define BPF_BUFSIZE 32768
 
 #define PRINET  26                     /* interruptible */
@@ -1290,6 +1295,45 @@ bpf_mtap_ether(caddr_t arg, struct mbuf 
        m->m_data -= ETHER_HDR_LEN;
 #endif
 }
+
+void
+bpf_mtap_pflog(caddr_t arg, caddr_t data, struct mbuf *m)
+{
+#if NPFLOG > 0
+       struct m_hdr mh;
+       struct bpf_if *bp = (struct bpf_if *)arg;
+       struct bpf_d *d;
+       size_t pktlen, slen;
+       struct mbuf *m0;
+
+       if (m == NULL)
+               return;
+
+       mh.mh_flags = 0;
+       mh.mh_next = m;
+       mh.mh_len = PFLOG_HDRLEN;
+       mh.mh_data = data;
+
+       pktlen = mh.mh_len;
+       for (m0 = m; m0 != 0; m0 = m0->m_next)
+               pktlen += m0->m_len;
+
+       for (d = bp->bif_dlist; d != 0; d = d->bd_next) {
+               ++d->bd_rcount;
+               if ((BPF_DIRECTION_OUT & d->bd_dirfilt) != 0)
+                       slen = 0;
+               else
+                       slen = bpf_filter(d->bd_rfilter, (u_char *)&mh,
+                           pktlen, 0);
+
+               if (slen == 0)
+                   continue;
+
+               bpf_catchpacket(d, (u_char *)&mh, pktlen, slen, pflog_bpfcopy);
+       }
+#endif
+}
+
 
 /*
  * Move the packet data from interface memory (pkt) into the
Index: sys/net/bpf.h
===================================================================
RCS file: /cvs/src/sys/net/bpf.h,v
retrieving revision 1.39
diff -u -p -r1.39 bpf.h
--- sys/net/bpf.h       26 Jun 2010 16:49:01 -0000      1.39
+++ sys/net/bpf.h       20 Sep 2010 08:54:41 -0000
@@ -273,6 +273,7 @@ void         bpf_mtap(caddr_t, struct mbuf *, u
 void    bpf_mtap_hdr(caddr_t, caddr_t, u_int, struct mbuf *, u_int);
 void    bpf_mtap_af(caddr_t, u_int32_t, struct mbuf *, u_int);
 void    bpf_mtap_ether(caddr_t, struct mbuf *, u_int);
+void    bpf_mtap_pflog(caddr_t, caddr_t, struct mbuf *);
 void    bpfattach(caddr_t *, struct ifnet *, u_int, u_int);
 void    bpfdetach(struct ifnet *);
 void    bpfilterattach(int);
Index: sys/net/if_pflog.c
===================================================================
RCS file: /cvs/src/sys/net/if_pflog.c,v
retrieving revision 1.28
diff -u -p -r1.28 if_pflog.c
--- sys/net/if_pflog.c  12 Jan 2010 02:47:07 -0000      1.28
+++ sys/net/if_pflog.c  20 Sep 2010 08:54:41 -0000
@@ -53,6 +53,9 @@
 #include <netinet/in_var.h>
 #include <netinet/in_systm.h>
 #include <netinet/ip.h>
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
+#include <netinet/ip_icmp.h>
 #endif
 
 #ifdef INET6
@@ -60,6 +63,7 @@
 #include <netinet/in.h>
 #endif
 #include <netinet6/nd6.h>
+#include <netinet/icmp6.h>
 #endif /* INET6 */
 
 #include <net/pfvar.h>
@@ -86,6 +90,7 @@ struct if_clone       pflog_cloner =
     IF_CLONE_INITIALIZER("pflog", pflog_clone_create, pflog_clone_destroy);
 
 struct ifnet   *pflogifs[PFLOGIFS_MAX];        /* for fast access */
+struct mbuf    *mfake = NULL;
 
 void
 pflogattach(int npflog)
@@ -94,6 +99,8 @@ pflogattach(int npflog)
        LIST_INIT(&pflogif_list);
        for (i = 0; i < PFLOGIFS_MAX; i++)
                pflogifs[i] = NULL;
+       if (mfake == NULL)
+               mfake = m_get(M_DONTWAIT, MT_HEADER);
        if_clone_attach(&pflog_cloner);
 }
 
@@ -246,21 +253,88 @@ pflog_packet(struct pfi_kif *kif, struct
        hdr.rule_pid = rm->cpid;
        hdr.dir = dir;
 
-#ifdef INET
-       if (af == AF_INET && dir == PF_OUT) {
-               struct ip *ip;
-
-               ip = mtod(m, struct ip *);
-               ip->ip_sum = 0;
-               ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
-       }
-#endif /* INET */
+       PF_ACPY(&hdr.saddr, &pd->nsaddr, pd->af);
+       PF_ACPY(&hdr.daddr, &pd->ndaddr, pd->af);
+       hdr.sport = pd->nsport;
+       hdr.dport = pd->ndport;
 
        ifn->if_opackets++;
        ifn->if_obytes += m->m_pkthdr.len;
-       bpf_mtap_hdr(ifn->if_bpf, (char *)&hdr, PFLOG_HDRLEN, m,
-           BPF_DIRECTION_OUT);
+
+       bpf_mtap_pflog(ifn->if_bpf, (caddr_t)&hdr, m);
 #endif
 
        return (0);
+}
+
+void
+pflog_bpfcopy(const void *src_arg, void *dst_arg, size_t len)
+{
+       const struct mbuf       *m;
+       struct pfloghdr         *pfloghdr;
+       u_int                    count;
+       u_char                  *dst;
+       u_short                  action, reason;
+       int                      off = 0, hdrlen = 0;
+       union {
+               struct tcphdr           tcp;
+               struct udphdr           udp;
+               struct icmp             icmp;
+#ifdef INET6
+               struct icmp6_hdr        icmp6;
+#endif /* INET6 */
+       } pf_hdrs;
+
+       struct pf_pdesc          pd;
+
+       m = src_arg;
+       dst = dst_arg;
+
+       if (m == NULL)
+               panic("pflog_bpfcopy got no mbuf");
+
+       /* first mbuf holds struct pfloghdr */
+       pfloghdr = mtod(m, struct pfloghdr *);
+       count = min(m->m_len, len);
+       bcopy(pfloghdr, dst, count);
+       dst += count;
+       len -= count;
+       m = m->m_next;
+
+       /* second mbuf is pkthdr */
+       if (len > 0) {
+               if (m == NULL)
+                       panic("no second mbuf");
+               bcopy(m, mfake, sizeof(*mfake));
+               mfake->m_flags &= ~(M_EXT|M_CLUSTER);
+               mfake->m_next = NULL;
+               mfake->m_nextpkt = NULL;
+               mfake->m_data = dst;
+               mfake->m_len = len;
+       } else
+               return;
+
+       while (len > 0) {
+               if (m == 0)
+                       panic("bpf_mcopy");
+               count = min(m->m_len, len);
+               bcopy(mtod(m, caddr_t), (caddr_t)dst, count);
+               m = m->m_next;
+               dst += count;
+               len -= count;
+       }
+
+       if (mfake->m_flags & M_PKTHDR)
+               mfake->m_pkthdr.len = min(mfake->m_pkthdr.len, mfake->m_len);
+
+       /* rewrite addresses if needed */
+       memset(&pd, 0, sizeof(pd));
+       pd.hdr.any = &pf_hdrs;
+       if (pf_setup_pdesc(pfloghdr->af, pfloghdr->dir, &pd, mfake, &action,
+           &reason, NULL, NULL, NULL, NULL, &off, &hdrlen) == -1)
+               return;
+       if (pf_translate(&pd, &pfloghdr->saddr, pfloghdr->sport,
+           &pfloghdr->daddr, pfloghdr->dport, 0, pfloghdr->dir, mfake))
+               m_copyback(mfake, off, min(mfake->m_len - off, hdrlen),
+                   pd.hdr.any, M_NOWAIT);
 }
Index: sys/net/if_pflog.h
===================================================================
RCS file: /cvs/src/sys/net/if_pflog.h,v
retrieving revision 1.15
diff -u -p -r1.15 if_pflog.h
--- sys/net/if_pflog.h  26 Jun 2010 16:49:01 -0000      1.15
+++ sys/net/if_pflog.h  20 Sep 2010 08:54:41 -0000
@@ -27,6 +27,8 @@
 #ifndef _NET_IF_PFLOG_H_
 #define _NET_IF_PFLOG_H_
 
+#include <net/pfvar.h>
+
 #define        PFLOGIFS_MAX    16
 
 struct pflog_softc {
@@ -52,13 +54,19 @@ struct pfloghdr {
        pid_t           rule_pid;
        u_int8_t        dir;
        u_int8_t        pad[3];
+       struct pf_addr  saddr;
+       struct pf_addr  daddr;
+       u_int16_t       sport;
+       u_int16_t       dport;
 };
 
 #define PFLOG_HDRLEN           sizeof(struct pfloghdr)
-/* minus pad, also used as a signature */
-#define PFLOG_REAL_HDRLEN      offsetof(struct pfloghdr, pad)
+/* used to be minus pad, also used as a signature */
+#define PFLOG_REAL_HDRLEN      PFLOG_HDRLEN
+#define PFLOG_OLD_HDRLEN       offsetof(struct pfloghdr, pad)
 
 #ifdef _KERNEL
+void   pflog_bpfcopy(const void *, void *, size_t);
 
 #if NPFLOG > 0
 #define        PFLOG_PACKET(i,x,a,b,c,d,e,f,g,h) 
pflog_packet(i,a,b,c,d,e,f,g,h)
Index: sys/net/pf.c
===================================================================
RCS file: /cvs/src/sys/net/pf.c,v
retrieving revision 1.696
diff -u -p -r1.696 pf.c
--- sys/net/pf.c        5 Aug 2010 17:21:19 -0000       1.696
+++ sys/net/pf.c        20 Sep 2010 08:54:41 -0000
@@ -124,6 +124,17 @@ struct pf_anchor_stackframe {
        struct pf_anchor                        *child;
 } pf_anchor_stack[64];
 
+/* cannot fold into pf_pdesc directly, unknown storage size outside pf.c */
+union {
+       struct tcphdr           tcp;
+       struct udphdr           udp;
+       struct icmp             icmp;
+#ifdef INET6
+       struct icmp6_hdr        icmp6;
+#endif /* INET6 */
+} pf_hdrs;
+
+
 struct pool             pf_src_tree_pl, pf_rule_pl;
 struct pool             pf_state_pl, pf_state_key_pl, pf_state_item_pl;
 struct pool             pf_altq_pl, pf_rule_item_pl, pf_sn_item_pl;
@@ -164,7 +175,7 @@ void                         pf_rule_to_actions(struct 
pf_rul
 int                     pf_test_rule(struct pf_rule **, struct pf_state **,
                            int, struct pfi_kif *, struct mbuf *, int,
                            void *, struct pf_pdesc *, struct pf_rule **,
-                           struct pf_ruleset **, struct ifqueue *);
+                           struct pf_ruleset **, struct ifqueue *, int);
 static __inline int     pf_create_state(struct pf_rule *, struct pf_rule *,
                            struct pf_pdesc *, struct pf_state_key **,
                            struct pf_state_key **, struct mbuf *, int,
@@ -173,9 +184,6 @@ static __inline int  pf_create_state(str
                            struct pf_rule_actions *, struct pf_src_node *[]);
 int                     pf_state_key_setup(struct pf_pdesc *, struct
                            pf_state_key **, struct pf_state_key **, int);
-void                    pf_translate(struct pf_pdesc *, struct pf_addr *,
-                           u_int16_t, struct pf_addr *, u_int16_t, u_int16_t,
-                           int, struct mbuf *);
 int                     pf_test_fragment(struct pf_rule **, int,
                            struct pfi_kif *, struct mbuf *, void *,
                            struct pf_pdesc *, struct pf_rule **,
@@ -2767,7 +2775,7 @@ int
 pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction,
     struct pfi_kif *kif, struct mbuf *m, int off, void *h,
     struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm,
-    struct ifqueue *ifq)
+    struct ifqueue *ifq, int hdrlen)
 {
        struct pf_rule          *lastr = NULL;
        sa_family_t              af = pd->af;
@@ -2780,7 +2788,7 @@ pf_test_rule(struct pf_rule **rm, struct
        struct pf_state_key     *skw = NULL, *sks = NULL;
        struct pf_rule_actions   act;
        u_short                  reason;
-       int                      rewrite = 0, hdrlen = 0;
+       int                      rewrite = 0;
        int                      tag = -1;
        int                      asd = 0;
        int                      match = 0;
@@ -2806,18 +2814,15 @@ pf_test_rule(struct pf_rule **rm, struct
        case IPPROTO_TCP:
                pd->nsport = th->th_sport;
                pd->ndport = th->th_dport;
-               hdrlen = sizeof(*th);
                break;
        case IPPROTO_UDP:
                pd->nsport = pd->hdr.udp->uh_sport;
                pd->ndport = pd->hdr.udp->uh_dport;
-               hdrlen = sizeof(*pd->hdr.udp);
                break;
 #ifdef INET
        case IPPROTO_ICMP:
                if (pd->af != AF_INET)
                        break;
-               hdrlen = ICMP_MINLEN;
                icmptype = pd->hdr.icmp->icmp_type;
                icmpcode = pd->hdr.icmp->icmp_code;
                state_icmp = pf_icmp_mapping(pd, icmptype,
@@ -2835,7 +2840,6 @@ pf_test_rule(struct pf_rule **rm, struct
        case IPPROTO_ICMPV6:
                if (af != AF_INET6)
                        break;
-               hdrlen = sizeof(*pd->hdr.icmp6);
                icmptype = pd->hdr.icmp6->icmp6_type;
                icmpcode = pd->hdr.icmp6->icmp6_code;
                state_icmp = pf_icmp_mapping(pd, icmptype,
@@ -2850,7 +2854,7 @@ pf_test_rule(struct pf_rule **rm, struct
                break;
 #endif /* INET6 */
        default:
-               pd->nsport = pd->ndport = hdrlen = 0;
+               pd->nsport = pd->ndport;
                break;
        }
 
@@ -3068,11 +3072,10 @@ pf_test_rule(struct pf_rule **rm, struct
                                sk = sks;
                        else
                                sk = skw;
-                       pf_translate(pd,
+                       rewrite += pf_translate(pd,
                            &sk->addr[pd->sidx], sk->port[pd->sidx],
                            &sk->addr[pd->didx], sk->port[pd->didx],
                            virtual_type, icmp_dir, m);
-                       rewrite = 1;
                }
        } else {
                while ((ri = SLIST_FIRST(&rules))) {
@@ -3302,41 +3305,60 @@ csfailed:
        return (PF_DROP);
 }
 
-void
+int
 pf_translate(struct pf_pdesc *pd, struct pf_addr *saddr, u_int16_t sport,
     struct pf_addr *daddr, u_int16_t dport, u_int16_t virtual_type,
     int icmp_dir, struct mbuf *m)
 {
+       /*
+        * when called from bpf_mtap_pflog, there are extra constraints:
+        * -mbuf is faked, m_data is the bpf buffer
+        * -pd is not fully set up
+        */
+       int     rewrite = 0;
+
        if (PF_ANEQ(daddr, pd->dst, pd->af))
                pd->destchg = 1;
 
        switch (pd->proto) {
        case IPPROTO_TCP:
-               if (PF_ANEQ(saddr, pd->src, pd->af) || *pd->sport != sport)
+               if (PF_ANEQ(saddr, pd->src, pd->af) || *pd->sport != sport) {
                        pf_change_ap(pd->src, pd->sport, pd->ip_sum,
-                           &pd->hdr.tcp->th_sum, saddr, sport, 0, pd->af);
-               if (PF_ANEQ(daddr, pd->dst, pd->af) || *pd->dport != dport)
+                           &pd->hdr.tcp->th_sum, saddr, sport, 0, pd->af);     
+                       rewrite = 1;
+               }
+               if (PF_ANEQ(daddr, pd->dst, pd->af) || *pd->dport != dport) {
                        pf_change_ap(pd->dst, pd->dport, pd->ip_sum,
                            &pd->hdr.tcp->th_sum, daddr, dport, 0, pd->af);
+                       rewrite = 1;
+               }
                break;
 
        case IPPROTO_UDP:
-               if (PF_ANEQ(saddr, pd->src, pd->af) || *pd->sport != sport)
+               if (PF_ANEQ(saddr, pd->src, pd->af) || *pd->sport != sport) {
                        pf_change_ap(pd->src, pd->sport, pd->ip_sum,
                            &pd->hdr.udp->uh_sum, saddr, sport, 1, pd->af);
-               if (PF_ANEQ(daddr, pd->dst, pd->af) || *pd->dport != dport)
+                       rewrite = 1;
+               }
+               if (PF_ANEQ(daddr, pd->dst, pd->af) || *pd->dport != dport) {
                        pf_change_ap(pd->dst, pd->dport, pd->ip_sum,
                            &pd->hdr.udp->uh_sum, daddr, dport, 1, pd->af);
+                       rewrite = 1;
+               }
                break;
 
 #ifdef INET
        case IPPROTO_ICMP:
-               if (PF_ANEQ(saddr, pd->src, pd->af))
+               if (PF_ANEQ(saddr, pd->src, pd->af)) {
                        pf_change_a(&pd->src->v4.s_addr, pd->ip_sum,
                            saddr->v4.s_addr, 0);
-               if (PF_ANEQ(daddr, pd->dst, pd->af))
+                       rewrite = 1;
+               }
+               if (PF_ANEQ(daddr, pd->dst, pd->af)) {
                        pf_change_a(&pd->dst->v4.s_addr, pd->ip_sum,
                            daddr->v4.s_addr, 0);
+                       rewrite = 1;
+               }
                if (virtual_type == htons(ICMP_ECHO)) {
                        u_int16_t icmpid = (icmp_dir == PF_IN) ? sport : dport;
 
@@ -3345,6 +3367,7 @@ pf_translate(struct pf_pdesc *pd, struct
                                    pd->hdr.icmp->icmp_cksum,
                                    pd->hdr.icmp->icmp_id, icmpid, 0);
                                pd->hdr.icmp->icmp_id = icmpid;
+                               rewrite = 1;
                        }
                }
                break;
@@ -3353,12 +3376,16 @@ pf_translate(struct pf_pdesc *pd, struct
 #ifdef INET6
        case IPPROTO_ICMPV6:
                if (pd->af == AF_INET6) {
-                       if (PF_ANEQ(saddr, pd->src, pd->af))
+                       if (PF_ANEQ(saddr, pd->src, pd->af)) {
                                pf_change_a6(pd->src,
                                    &pd->hdr.icmp6->icmp6_cksum, saddr, 0);
-                       if (PF_ANEQ(daddr, pd->dst, pd->af))
+                               rewrite = 1;
+                       }
+                       if (PF_ANEQ(daddr, pd->dst, pd->af)) {
                                pf_change_a6(pd->dst,
                                    &pd->hdr.icmp6->icmp6_cksum, daddr, 0);
+                               rewrite = 1;
+                       }
                        break;
                }
                /* FALLTHROUGH */
@@ -3368,24 +3395,33 @@ pf_translate(struct pf_pdesc *pd, struct
                switch (pd->af) {
 #ifdef INET
                case AF_INET:
-                       if (PF_ANEQ(saddr, pd->src, pd->af))
+                       if (PF_ANEQ(saddr, pd->src, pd->af)) {
                                pf_change_a(&pd->src->v4.s_addr, pd->ip_sum,
                                    saddr->v4.s_addr, 0);
-                       if (PF_ANEQ(daddr, pd->dst, pd->af))
+                               rewrite = 1;
+                       }
+                       if (PF_ANEQ(daddr, pd->dst, pd->af)) {
                                pf_change_a(&pd->dst->v4.s_addr, pd->ip_sum,
                                    daddr->v4.s_addr, 0);
+                               rewrite = 1;
+                       }
                        break;
 #endif /* INET */
 #ifdef INET6
                case AF_INET6:
-                       if (PF_ANEQ(saddr, pd->src, pd->af))
+                       if (PF_ANEQ(saddr, pd->src, pd->af)) {
                                pf_change_a6(pd->src, pd->ip_sum, saddr, 0);
-                       if (PF_ANEQ(daddr, pd->dst, pd->af))
+                               rewrite = 1;
+                       }
+                       if (PF_ANEQ(daddr, pd->dst, pd->af)) {
                                pf_change_a6(pd->dst, pd->ip_sum, daddr, 0);
+                               rewrite = 1;
+                       }
                        break;
 #endif /* INET6 */
                }
        }
+       return (rewrite);
 }
 
 int
@@ -5517,6 +5553,236 @@ pf_get_divert(struct mbuf *m)
        return ((struct pf_divert *)(mtag + 1));
 }
 
+int
+pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf *m,
+    u_short *action, u_short *reason, struct pfi_kif *kif, struct pf_rule **a,
+    struct pf_rule **r, struct pf_ruleset **ruleset, int *off, int *hdrlen)
+{
+       if (pd->hdr.any == NULL)
+               panic("pf_setup_pdesc: no storage for headers provided");
+
+       switch (af) {
+#ifdef INET
+       case AF_INET: {
+               struct ip       *h;
+
+               h = mtod(m, struct ip *);
+               *off = h->ip_hl << 2;
+               if (*off < (int)sizeof(*h)) {
+                       *action = PF_DROP;
+                       REASON_SET(reason, PFRES_SHORT);
+                       return (-1);
+               }
+               pd->src = (struct pf_addr *)&h->ip_src;
+               pd->dst = (struct pf_addr *)&h->ip_dst;
+               pd->sport = pd->dport = NULL;
+               pd->ip_sum = &h->ip_sum;
+               pd->proto_sum = NULL;
+               pd->proto = h->ip_p;
+               pd->dir = dir;
+               pd->sidx = (dir == PF_IN) ? 0 : 1;
+               pd->didx = (dir == PF_IN) ? 1 : 0;
+               pd->af = AF_INET;
+               pd->tos = h->ip_tos;
+               pd->tot_len = ntohs(h->ip_len);
+               pd->rdomain = rtable_l2(m->m_pkthdr.rdomain);
+
+               /* fragments not reassembled handled later */
+               if (h->ip_off & htons(IP_MF | IP_OFFMASK))
+                       return (0);
+
+               switch (h->ip_p) {
+               case IPPROTO_TCP: {
+                       struct tcphdr   *th = pd->hdr.tcp;
+
+                       if (!pf_pull_hdr(m, *off, th, sizeof(*th),
+                           action, reason, AF_INET))
+                               return (-1);
+                       *hdrlen = sizeof(*th);
+                       pd->p_len = pd->tot_len - *off - (th->th_off << 2);
+                       pd->sport = &th->th_sport;
+                       pd->dport = &th->th_dport;
+                       break;
+               }
+               case IPPROTO_UDP: {
+                       struct udphdr   *uh = pd->hdr.udp;
+
+                       if (!pf_pull_hdr(m, *off, uh, sizeof(*uh),
+                           action, reason, AF_INET))
+                               return (-1);
+                       *hdrlen = sizeof(*uh);
+                       if (uh->uh_dport == 0 ||
+                           ntohs(uh->uh_ulen) > m->m_pkthdr.len - *off ||
+                           ntohs(uh->uh_ulen) < sizeof(struct udphdr)) {
+                               *action = PF_DROP;
+                               REASON_SET(reason, PFRES_SHORT);
+                               return (-1);
+                       }
+                       pd->sport = &uh->uh_sport;
+                       pd->dport = &uh->uh_dport;
+                       break;
+               }
+               case IPPROTO_ICMP: {
+                       if (!pf_pull_hdr(m, *off, pd->hdr.icmp, ICMP_MINLEN,
+                           action, reason, AF_INET))
+                               return (-1);
+                       *hdrlen = ICMP_MINLEN;
+                       break;
+               }
+               }
+               break;
+       }
+#endif
+#ifdef INET6
+       case AF_INET6: {
+               struct ip6_hdr  *h;
+               int              terminal = 0;
+
+               h = mtod(m, struct ip6_hdr *);
+               pd->src = (struct pf_addr *)&h->ip6_src;
+               pd->dst = (struct pf_addr *)&h->ip6_dst;
+               pd->sport = pd->dport = NULL;
+               pd->ip_sum = NULL;
+               pd->proto_sum = NULL;
+               pd->dir = dir;
+               pd->sidx = (dir == PF_IN) ? 0 : 1;
+               pd->didx = (dir == PF_IN) ? 1 : 0;
+               pd->af = AF_INET6;
+               pd->tos = 0;
+               pd->tot_len = ntohs(h->ip6_plen) + sizeof(struct ip6_hdr);
+               *off = ((caddr_t)h - m->m_data) + sizeof(struct ip6_hdr);
+               pd->proto = h->ip6_nxt;
+               do {
+                       switch (pd->proto) {
+                       case IPPROTO_FRAGMENT:
+                               if (kif == NULL || r == NULL)   /* pflog */
+                                       *action = PF_DROP;
+                               else
+                                       *action = pf_test_fragment(r, dir, kif,
+                                            m, h, pd, a, ruleset);
+                               if (*action == PF_DROP)
+                                       REASON_SET(reason, PFRES_FRAG);
+                               return (-1);
+                       case IPPROTO_ROUTING: {
+                               struct ip6_rthdr rthdr;
+
+                               if (pd->rh_cnt++) {
+                                       DPFPRINTF(LOG_NOTICE,
+                                           "pf: IPv6 more than one rthdr");
+                                       *action = PF_DROP;
+                                       REASON_SET(reason, PFRES_IPOPTIONS);
+                                       return (-1);
+                               }
+                               if (!pf_pull_hdr(m, *off, &rthdr, sizeof(rthdr),
+                                   NULL, reason, pd->af)) {
+                                       DPFPRINTF(LOG_NOTICE,
+                                           "pf: IPv6 short rthdr");
+                                       *action = PF_DROP;
+                                       REASON_SET(reason, PFRES_SHORT);
+                                       return (-1);
+                               }
+                               if (rthdr.ip6r_type == IPV6_RTHDR_TYPE_0) {
+                                       DPFPRINTF(LOG_NOTICE,
+                                           "pf: IPv6 rthdr0");
+                                       *action = PF_DROP;
+                                       REASON_SET(reason, PFRES_IPOPTIONS);
+                                       return (-1);
+                               }
+                               /* FALLTHROUGH */
+                       }
+                       case IPPROTO_AH:
+                       case IPPROTO_HOPOPTS:
+                       case IPPROTO_DSTOPTS: {
+                               /* get next header and header length */
+                               struct ip6_ext  opt6;
+
+                               if (!pf_pull_hdr(m, *off, &opt6, sizeof(opt6),
+                                   NULL, reason, pd->af)) {
+                                       DPFPRINTF(LOG_NOTICE,
+                                           "pf: IPv6 short opt");
+                                       *action = PF_DROP;
+                                       return (-1);
+                               }
+                               if (pd->proto == IPPROTO_AH)
+                                       *off += (opt6.ip6e_len + 2) * 4;
+                               else
+                                       *off += (opt6.ip6e_len + 1) * 8;
+                               pd->proto = opt6.ip6e_nxt;
+                               /* goto the next header */
+                               break;
+                       }
+                       default:
+                               terminal++;
+                               break;
+                       }
+               } while (!terminal);
+
+               switch (pd->proto) {
+               case IPPROTO_TCP: {
+                       struct tcphdr   *th = pd->hdr.tcp;
+
+                       if (!pf_pull_hdr(m, *off, th, sizeof(*th),
+                           action, reason, AF_INET6))
+                               return (-1);
+                       *hdrlen = sizeof(*th);
+                       pd->p_len = pd->tot_len - *off - (th->th_off << 2);
+                       pd->sport = &th->th_sport;
+                       pd->dport = &th->th_dport;
+                       break;
+               }
+               case IPPROTO_UDP: {
+                       struct udphdr   *uh = pd->hdr.udp;
+
+                       if (!pf_pull_hdr(m, *off, uh, sizeof(*uh),
+                           action, reason, AF_INET6))
+                               return (-1);
+                       *hdrlen = sizeof(*uh);
+                       if (uh->uh_dport == 0 ||
+                           ntohs(uh->uh_ulen) > m->m_pkthdr.len - *off ||
+                           ntohs(uh->uh_ulen) < sizeof(struct udphdr)) {
+                               *action = PF_DROP;
+                               REASON_SET(reason, PFRES_SHORT);
+                               return (-1);
+                       }
+                       pd->sport = &uh->uh_sport;
+                       pd->dport = &uh->uh_dport;
+                       break;
+               }
+               case IPPROTO_ICMPV6: {
+                       size_t  icmp_hlen = sizeof(struct icmp6_hdr);
+
+                       if (!pf_pull_hdr(m, *off, pd->hdr.icmp6, icmp_hlen,
+                           action, reason, AF_INET6))
+                               return (-1);
+                       /* ICMP headers we look further into to match state */
+                       switch (pd->hdr.icmp6->icmp6_type) {
+                       case MLD_LISTENER_QUERY:
+                       case MLD_LISTENER_REPORT:
+                               icmp_hlen = sizeof(struct mld_hdr);
+                               break;
+                       case ND_NEIGHBOR_SOLICIT:
+                       case ND_NEIGHBOR_ADVERT:
+                               icmp_hlen = sizeof(struct nd_neighbor_solicit);
+                               break;
+                       }
+                       if (icmp_hlen > sizeof(struct icmp6_hdr) &&
+                           !pf_pull_hdr(m, *off, pd->hdr.icmp6, icmp_hlen,
+                           action, reason, AF_INET6))
+                               return (-1);
+                       *hdrlen = icmp_hlen;
+                       break;
+               }
+               }
+               break;
+       }
+#endif
+       default:
+               panic("pf_setup_pdesc called with illegal af %u", af);
+
+       }
+       return (0);
+}
+
 #ifdef INET
 int
 pf_test(int dir, struct ifnet *ifp, struct mbuf **m0,
@@ -5530,13 +5796,14 @@ pf_test(int dir, struct ifnet *ifp, stru
        struct pf_state         *s = NULL;
        struct pf_ruleset       *ruleset = NULL;
        struct pf_pdesc          pd;
-       int                      off, dirndx, pqid = 0;
+       int                      off, hdrlen, dirndx, pqid = 0;
        u_int16_t                qid;
 
        if (!pf_status.running)
                return (PF_PASS);
 
        memset(&pd, 0, sizeof(pd));
+       pd.hdr.any = &pf_hdrs;
        if (ifp->if_type == IFT_CARP && ifp->if_carpdev)
                kif = (struct pfi_kif *)ifp->if_carpdev->if_pf_kif;
        else
@@ -5578,28 +5845,13 @@ pf_test(int dir, struct ifnet *ifp, stru
        m = *m0;        /* pf_normalize messes with m0 */
        h = mtod(m, struct ip *);
 
-       off = h->ip_hl << 2;
-       if (off < (int)sizeof(*h)) {
-               action = PF_DROP;
-               REASON_SET(&reason, PFRES_SHORT);
-               pflog |= PF_LOG_FORCE;
+       if (pf_setup_pdesc(AF_INET, dir, &pd, m, &action, &reason, kif, &a, &r,
+           &ruleset, &off, &hdrlen) == -1) {
+               if (action != PF_PASS)
+                       pflog |= PF_LOG_FORCE;
                goto done;
        }
-
-       pd.src = (struct pf_addr *)&h->ip_src;
-       pd.dst = (struct pf_addr *)&h->ip_dst;
-       pd.sport = pd.dport = NULL;
-       pd.ip_sum = &h->ip_sum;
-       pd.proto_sum = NULL;
-       pd.proto = h->ip_p;
-       pd.dir = dir;
-       pd.sidx = (dir == PF_IN) ? 0 : 1;
-       pd.didx = (dir == PF_IN) ? 1 : 0;
-       pd.af = AF_INET;
-       pd.tos = h->ip_tos;
-       pd.tot_len = ntohs(h->ip_len);
        pd.eh = eh;
-       pd.rdomain = rtable_l2(m->m_pkthdr.rdomain);
 
        /* handle fragments that didn't get reassembled by normalization */
        if (h->ip_off & htons(IP_MF | IP_OFFMASK)) {
@@ -5611,20 +5863,8 @@ pf_test(int dir, struct ifnet *ifp, stru
        switch (h->ip_p) {
 
        case IPPROTO_TCP: {
-               struct tcphdr   th;
-
-               pd.hdr.tcp = &th;
-               if (!pf_pull_hdr(m, off, &th, sizeof(th),
-                   &action, &reason, AF_INET)) {
-                       if (action != PF_PASS)
-                               pflog |= PF_LOG_FORCE;
-                       goto done;
-               }
-               pd.p_len = pd.tot_len - off - (th.th_off << 2);
-               if ((th.th_flags & TH_ACK) && pd.p_len == 0)
+               if ((pd.hdr.tcp->th_flags & TH_ACK) && pd.p_len == 0)
                        pqid = 1;
-               pd.sport = &th.th_sport;
-               pd.dport = &th.th_dport;
                action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd);
                if (action == PF_DROP)
                        goto done;
@@ -5639,7 +5879,7 @@ pf_test(int dir, struct ifnet *ifp, stru
                        pflog |= s->log;
                } else if (s == NULL)
                        action = pf_test_rule(&r, &s, dir, kif,
-                           m, off, h, &pd, &a, &ruleset, &ipintrq);
+                           m, off, h, &pd, &a, &ruleset, &ipintrq, hdrlen);
 
                if (s) {
                        if (s->max_mss)
@@ -5651,24 +5891,6 @@ pf_test(int dir, struct ifnet *ifp, stru
        }
 
        case IPPROTO_UDP: {
-               struct udphdr   uh;
-
-               pd.hdr.udp = &uh;
-               if (!pf_pull_hdr(m, off, &uh, sizeof(uh),
-                   &action, &reason, AF_INET)) {
-                       if (action != PF_PASS)
-                               pflog |= PF_LOG_FORCE;
-                       goto done;
-               }
-               if (uh.uh_dport == 0 ||
-                   ntohs(uh.uh_ulen) > m->m_pkthdr.len - off ||
-                   ntohs(uh.uh_ulen) < sizeof(struct udphdr)) {
-                       action = PF_DROP;
-                       REASON_SET(&reason, PFRES_SHORT);
-                       goto done;
-               }
-               pd.sport = &uh.uh_sport;
-               pd.dport = &uh.uh_dport;
                action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd);
                if (action == PF_PASS) {
 #if NPFSYNC > 0
@@ -5679,20 +5901,11 @@ pf_test(int dir, struct ifnet *ifp, stru
                        pflog |= s->log;
                } else if (s == NULL)
                        action = pf_test_rule(&r, &s, dir, kif,
-                           m, off, h, &pd, &a, &ruleset, &ipintrq);
+                           m, off, h, &pd, &a, &ruleset, &ipintrq, hdrlen);
                break;
        }
 
        case IPPROTO_ICMP: {
-               struct icmp     ih;
-
-               pd.hdr.icmp = &ih;
-               if (!pf_pull_hdr(m, off, &ih, ICMP_MINLEN,
-                   &action, &reason, AF_INET)) {
-                       if (action != PF_PASS)
-                               pflog |= PF_LOG_FORCE;
-                       goto done;
-               }
                action = pf_test_state_icmp(&s, dir, kif, m, off, h, &pd,
                    &reason);
                if (action == PF_PASS) {
@@ -5704,7 +5917,7 @@ pf_test(int dir, struct ifnet *ifp, stru
                        pflog |= s->log;
                } else if (s == NULL)
                        action = pf_test_rule(&r, &s, dir, kif,
-                           m, off, h, &pd, &a, &ruleset, &ipintrq);
+                           m, off, h, &pd, &a, &ruleset, &ipintrq, hdrlen);
                break;
        }
 
@@ -5726,7 +5939,7 @@ pf_test(int dir, struct ifnet *ifp, stru
                        pflog |= s->log;
                } else if (s == NULL)
                        action = pf_test_rule(&r, &s, dir, kif, m, off, h,
-                           &pd, &a, &ruleset, &ipintrq);
+                           &pd, &a, &ruleset, &ipintrq, hdrlen);
                break;
        }
 
@@ -5891,12 +6104,13 @@ pf_test6(int dir, struct ifnet *ifp, str
        struct pf_state         *s = NULL;
        struct pf_ruleset       *ruleset = NULL;
        struct pf_pdesc          pd;
-       int                      off, terminal = 0, dirndx, rh_cnt = 0;
+       int                      off, hdrlen, dirndx;
 
        if (!pf_status.running)
                return (PF_PASS);
 
        memset(&pd, 0, sizeof(pd));
+       pd.hdr.any = &pf_hdrs;
        if (ifp->if_type == IFT_CARP && ifp->if_carpdev)
                kif = (struct pfi_kif *)ifp->if_carpdev->if_pf_kif;
        else
@@ -5949,105 +6163,20 @@ pf_test6(int dir, struct ifnet *ifp, str
        }
 #endif
 
-       pd.src = (struct pf_addr *)&h->ip6_src;
-       pd.dst = (struct pf_addr *)&h->ip6_dst;
-       pd.sport = pd.dport = NULL;
-       pd.ip_sum = NULL;
-       pd.proto_sum = NULL;
-       pd.dir = dir;
-       pd.sidx = (dir == PF_IN) ? 0 : 1;
-       pd.didx = (dir == PF_IN) ? 1 : 0;
-       pd.af = AF_INET6;
-       pd.tos = 0;
-       pd.tot_len = ntohs(h->ip6_plen) + sizeof(struct ip6_hdr);
-       pd.eh = eh;
-
-       off = ((caddr_t)h - m->m_data) + sizeof(struct ip6_hdr);
-       pd.proto = h->ip6_nxt;
-       do {
-               switch (pd.proto) {
-               case IPPROTO_FRAGMENT:
-                       action = pf_test_fragment(&r, dir, kif, m, h,
-                           &pd, &a, &ruleset);
-                       if (action == PF_DROP)
-                               REASON_SET(&reason, PFRES_FRAG);
-                       goto done;
-               case IPPROTO_ROUTING: {
-                       struct ip6_rthdr rthdr;
-
-                       if (rh_cnt++) {
-                               DPFPRINTF(LOG_NOTICE,
-                                   "pf: IPv6 more than one rthdr");
-                               action = PF_DROP;
-                               REASON_SET(&reason, PFRES_IPOPTIONS);
-                               pflog |= PF_LOG_FORCE;
-                               goto done;
-                       }
-                       if (!pf_pull_hdr(m, off, &rthdr, sizeof(rthdr), NULL,
-                           &reason, pd.af)) {
-                               DPFPRINTF(LOG_NOTICE,
-                                   "pf: IPv6 short rthdr");
-                               action = PF_DROP;
-                               REASON_SET(&reason, PFRES_SHORT);
-                               pflog |= PF_LOG_FORCE;
-                               goto done;
-                       }
-                       if (rthdr.ip6r_type == IPV6_RTHDR_TYPE_0) {
-                               DPFPRINTF(LOG_NOTICE,
-                                   "pf: IPv6 rthdr0");
-                               action = PF_DROP;
-                               REASON_SET(&reason, PFRES_IPOPTIONS);
-                               pflog |= PF_LOG_FORCE;
-                               goto done;
-                       }
-                       /* FALLTHROUGH */
-               }
-               case IPPROTO_AH:
-               case IPPROTO_HOPOPTS:
-               case IPPROTO_DSTOPTS: {
-                       /* get next header and header length */
-                       struct ip6_ext  opt6;
-
-                       if (!pf_pull_hdr(m, off, &opt6, sizeof(opt6),
-                           NULL, &reason, pd.af)) {
-                               DPFPRINTF(LOG_NOTICE,
-                                   "pf: IPv6 short opt");
-                               action = PF_DROP;
-                               pflog |= PF_LOG_FORCE;
-                               goto done;
-                       }
-                       if (pd.proto == IPPROTO_AH)
-                               off += (opt6.ip6e_len + 2) * 4;
-                       else
-                               off += (opt6.ip6e_len + 1) * 8;
-                       pd.proto = opt6.ip6e_nxt;
-                       /* goto the next header */
-                       break;
-               }
-               default:
-                       terminal++;
-                       break;
-               }
-       } while (!terminal);
-
        /* ptr to original, normalization can get us a new one */
        n = m;
 
+       if (pf_setup_pdesc(AF_INET6, dir, &pd, m, &action, &reason, kif, &a, &r,
+           &ruleset, &off, &hdrlen) == -1) {
+               if (action != PF_PASS)
+                       pflog |= PF_LOG_FORCE;
+               goto done;
+       }
+       pd.eh = eh;
+
        switch (pd.proto) {
 
        case IPPROTO_TCP: {
-               struct tcphdr   th;
-
-               pd.hdr.tcp = &th;
-               if (!pf_pull_hdr(m, off, &th, sizeof(th),
-                   &action, &reason, AF_INET6)) {
-                       if (action != PF_PASS)
-                               pflog |= PF_LOG_FORCE;
-                       goto done;
-               }
-               pd.p_len = pd.tot_len - off - (th.th_off << 2);
-               pd.sport = &th.th_sport;
-               pd.dport = &th.th_dport;
                action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd);
                if (action == PF_DROP)
                        goto done;
@@ -6062,7 +6191,7 @@ pf_test6(int dir, struct ifnet *ifp, str
                        pflog |= s->log;
                } else if (s == NULL)
                        action = pf_test_rule(&r, &s, dir, kif,
-                           m, off, h, &pd, &a, &ruleset, &ip6intrq);
+                           m, off, h, &pd, &a, &ruleset, &ip6intrq, hdrlen);
 
                if (s) {
                        if (s->max_mss)
@@ -6074,24 +6203,6 @@ pf_test6(int dir, struct ifnet *ifp, str
        }
 
        case IPPROTO_UDP: {
-               struct udphdr   uh;
-
-               pd.hdr.udp = &uh;
-               if (!pf_pull_hdr(m, off, &uh, sizeof(uh),
-                   &action, &reason, AF_INET6)) {
-                       if (action != PF_PASS)
-                               pflog |= PF_LOG_FORCE;
-                       goto done;
-               }
-               if (uh.uh_dport == 0 ||
-                   ntohs(uh.uh_ulen) > m->m_pkthdr.len - off ||
-                   ntohs(uh.uh_ulen) < sizeof(struct udphdr)) {
-                       action = PF_DROP;
-                       REASON_SET(&reason, PFRES_SHORT);
-                       goto done;
-               }
-               pd.sport = &uh.uh_sport;
-               pd.dport = &uh.uh_dport;
                action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd);
                if (action == PF_PASS) {
 #if NPFSYNC > 0
@@ -6102,7 +6213,7 @@ pf_test6(int dir, struct ifnet *ifp, str
                        pflog |= s->log;
                } else if (s == NULL)
                        action = pf_test_rule(&r, &s, dir, kif,
-                           m, off, h, &pd, &a, &ruleset, &ip6intrq);
+                           m, off, h, &pd, &a, &ruleset, &ip6intrq, hdrlen);
                break;
        }
 
@@ -6114,38 +6225,6 @@ pf_test6(int dir, struct ifnet *ifp, str
        }
 
        case IPPROTO_ICMPV6: {
-               union {
-                       struct icmp6_hdr                icmp6;
-                       struct mld_hdr                  mld;
-                       struct nd_neighbor_solicit      nd;
-               } ih;
-               size_t  icmp_hlen = sizeof(struct icmp6_hdr);
-
-               pd.hdr.icmp6 = &ih.icmp6;
-               if (!pf_pull_hdr(m, off, &ih, icmp_hlen,
-                   &action, &reason, AF_INET6)) {
-                       if (action != PF_PASS)
-                               pflog |= PF_LOG_FORCE;
-                       goto done;
-               }
-               /* ICMP headers we look further into to match state */
-               switch (ih.icmp6.icmp6_type) {
-               case MLD_LISTENER_QUERY:
-               case MLD_LISTENER_REPORT:
-                       icmp_hlen = sizeof(struct mld_hdr);
-                       break;
-               case ND_NEIGHBOR_SOLICIT:
-               case ND_NEIGHBOR_ADVERT:
-                       icmp_hlen = sizeof(struct nd_neighbor_solicit);
-                       break;
-               }
-               if (icmp_hlen > sizeof(struct icmp6_hdr) &&
-                   !pf_pull_hdr(m, off, &ih, icmp_hlen,
-                   &action, &reason, AF_INET6)) {
-                       if (action != PF_PASS)
-                               pflog |= PF_LOG_FORCE;
-                       goto done;
-               }
                action = pf_test_state_icmp(&s, dir, kif,
                    m, off, h, &pd, &reason);
                if (action == PF_PASS) {
@@ -6157,7 +6236,7 @@ pf_test6(int dir, struct ifnet *ifp, str
                        pflog |= s->log;
                } else if (s == NULL)
                        action = pf_test_rule(&r, &s, dir, kif,
-                           m, off, h, &pd, &a, &ruleset, &ip6intrq);
+                           m, off, h, &pd, &a, &ruleset, &ip6intrq, hdrlen);
                break;
        }
 
@@ -6172,7 +6251,7 @@ pf_test6(int dir, struct ifnet *ifp, str
                        pflog |= s->log;
                } else if (s == NULL)
                        action = pf_test_rule(&r, &s, dir, kif, m, off, h,
-                           &pd, &a, &ruleset, &ip6intrq);
+                           &pd, &a, &ruleset, &ip6intrq, hdrlen);
                break;
        }
 
@@ -6184,7 +6263,7 @@ done:
        }
 
        /* handle dangerous IPv6 extension headers. */
-       if (action == PF_PASS && rh_cnt &&
+       if (action == PF_PASS && pd.rh_cnt &&
            !((s && s->state_flags & PFSTATE_ALLOWOPTS) || r->allow_opts)) {
                action = PF_DROP;
                REASON_SET(&reason, PFRES_IPOPTIONS);
Index: sys/net/pfvar.h
===================================================================
RCS file: /cvs/src/sys/net/pfvar.h,v
retrieving revision 1.311
diff -u -p -r1.311 pfvar.h
--- sys/net/pfvar.h     28 Jun 2010 23:21:41 -0000      1.311
+++ sys/net/pfvar.h     20 Sep 2010 08:54:41 -0000
@@ -1211,6 +1211,7 @@ struct pf_pdesc {
        u_int16_t        ndport;        /* dst port after NAT */
 
        u_int32_t        p_len;         /* total length of payload */
+       u_int32_t        rh_cnt;        /* # of routing headers */
 
        u_int16_t       *ip_sum;
        u_int16_t       *proto_sum;
@@ -1735,6 +1736,11 @@ extern void                       pf_addrcpy(struct 
pf_addr
 void                            pf_rm_rule(struct pf_rulequeue *,
                                    struct pf_rule *);
 struct pf_divert               *pf_find_divert(struct mbuf *);
+int                             pf_setup_pdesc(sa_family_t, int,
+                                   struct pf_pdesc *, struct mbuf *,
+                                   u_short *, u_short *, struct pfi_kif *,
+                                   struct pf_rule **, struct pf_rule **,
+                                   struct pf_ruleset **, int *, int *);
 
 #ifdef INET
 int    pf_test(int, struct ifnet *, struct mbuf **, struct ether_header *);
@@ -1790,6 +1796,8 @@ int       pf_socket_lookup(int, struct pf_pdes
 struct pf_state_key *pf_alloc_state_key(int);
 void   pf_pkt_addr_changed(struct mbuf *);
 int    pf_state_key_attach(struct pf_state_key *, struct pf_state *, int);
+int    pf_translate(struct pf_pdesc *, struct pf_addr *, u_int16_t,
+           struct pf_addr *, u_int16_t, u_int16_t, int, struct mbuf *);
 
 void   pfr_initialize(void);
 int    pfr_match_addr(struct pfr_ktable *, struct pf_addr *, sa_family_t);

Reply via email to