-/* $OpenBSD: pf.c,v 1.980 2016/08/17 03:24:11 procter Exp $ */
+/* $OpenBSD: pf.c,v 1.981 2016/08/20 08:31:36 procter Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
sa_family_t);
static __inline void pf_cksum_fixup(u_int16_t *, u_int16_t, u_int16_t,
u_int8_t);
-void pf_translate_ap(struct pf_pdesc *, struct pf_addr *,
- u_int16_t *, struct pf_addr *, u_int16_t);
void pf_cksum_fixup_a(u_int16_t *, const struct pf_addr *,
const struct pf_addr *, sa_family_t, u_int8_t);
int pf_modulate_sack(struct pf_pdesc *,
*f = v;
}
-void
-pf_translate_ap(struct pf_pdesc *pd, struct pf_addr *a, u_int16_t *p,
- struct pf_addr *an, u_int16_t pn)
-{
- if (pd->af == pd->naf)
- pf_translate_a(pd, a, an);
- if (p != NULL)
- pf_patch_16(pd, p, pn);
-}
-
void
pf_patch_32_unaligned(struct pf_pdesc *pd, void *f, u_int32_t v, bool hi)
{
case IPPROTO_TCP:
if (afto || PF_ANEQ(saddr, pd->src, pd->af) ||
*pd->sport != sport) {
- pf_translate_ap(pd, pd->src, pd->sport, saddr, sport);
+ if (pd->af == pd->naf)
+ pf_translate_a(pd, pd->src, saddr);
+ pf_patch_16(pd, pd->sport, sport);
rewrite = 1;
}
if (afto || PF_ANEQ(daddr, pd->dst, pd->af) ||
*pd->dport != dport) {
- pf_translate_ap(pd, pd->dst, pd->dport, daddr, dport);
+ if (pd->af == pd->naf)
+ pf_translate_a(pd, pd->dst, daddr);
+ pf_patch_16(pd, pd->dport, dport);
rewrite = 1;
}
break;
case IPPROTO_UDP:
if (afto || PF_ANEQ(saddr, pd->src, pd->af) ||
*pd->sport != sport) {
- pf_translate_ap(pd, pd->src, pd->sport, saddr, sport);
+ if (pd->af == pd->naf)
+ pf_translate_a(pd, pd->src, saddr);
+ pf_patch_16(pd, pd->sport, sport);
rewrite = 1;
}
if (afto || PF_ANEQ(daddr, pd->dst, pd->af) ||
*pd->dport != dport) {
- pf_translate_ap(pd, pd->dst, pd->dport, daddr, dport);
+ if (pd->af == pd->naf)
+ pf_translate_a(pd, pd->dst, daddr);
+ pf_patch_16(pd, pd->dport, dport);
rewrite = 1;
}
break;
rewrite = 1;
} else {
if (PF_ANEQ(saddr, pd->src, pd->af)) {
- pf_translate_ap(pd, pd->src, NULL, saddr, 0);
+ pf_translate_a(pd, pd->src, saddr);
rewrite = 1;
}
if (PF_ANEQ(daddr, pd->dst, pd->af)) {
- pf_translate_ap(pd, pd->dst, NULL, daddr, 0);
+ pf_translate_a(pd, pd->dst, daddr);
rewrite = 1;
}
}
#ifdef INET6
case AF_INET6:
if (!afto && PF_ANEQ(saddr, pd->src, pd->af)) {
- pf_translate_ap(pd, pd->src, NULL, saddr, 0);
+ pf_translate_a(pd, pd->src, saddr);
rewrite = 1;
}
if (!afto && PF_ANEQ(daddr, pd->dst, pd->af)) {
- pf_translate_ap(pd, pd->dst, NULL, daddr, 0);
+ pf_translate_a(pd, pd->dst, daddr);
rewrite = 1;
}
break;
#endif /* INET6 */
if (afto || PF_ANEQ(pd->src, &nk->addr[sidx], pd->af) ||
- nk->port[sidx] != pd->osport)
- pf_translate_ap(pd, pd->src, pd->sport,
- &nk->addr[sidx], nk->port[sidx]);
+ nk->port[sidx] != pd->osport) {
+ if (pd->af == pd->naf)
+ pf_translate_a(pd, pd->src, &nk->addr[sidx]);
+ if (pd->sport != NULL)
+ pf_patch_16(pd, pd->sport, nk->port[sidx]);
+ }
if (afto || PF_ANEQ(pd->dst, &nk->addr[didx], pd->af) ||
pd->rdomain != nk->rdomain)
pd->destchg = 1;
if (afto || PF_ANEQ(pd->dst, &nk->addr[didx], pd->af) ||
- nk->port[didx] != pd->odport)
- pf_translate_ap(pd, pd->dst, pd->dport,
- &nk->addr[didx], nk->port[didx]);
+ nk->port[didx] != pd->odport) {
+ if (pd->af == pd->naf)
+ pf_translate_a(pd, pd->dst, &nk->addr[didx]);
+ if (pd->dport != NULL)
+ pf_patch_16(pd, pd->dport, nk->port[didx]);
+ }
pd->m->m_pkthdr.ph_rtableid = nk->rdomain;
copyback = 1;
sidx = afto ? pd->didx : pd->sidx;
didx = afto ? pd->sidx : pd->didx;
iidx = afto ? !iidx : iidx;
-
+#ifdef INET6
+ if (afto) {
+ PF_ACPY(&pd->nsaddr, &nk->addr[sidx], nk->af);
+ PF_ACPY(&pd->ndaddr, &nk->addr[didx], nk->af);
+ pd->naf = nk->af;
+ }
+#endif /* INET6 */
if (pd->rdomain != nk->rdomain)
pd->destchg = 1;
pd->m->m_pkthdr.ph_rtableid = nk->rdomain;
pd->proto = IPPROTO_ICMP;
}
if (!afto && PF_ANEQ(pd->src,
- &nk->addr[sidx], AF_INET6))
- pf_translate_ap(pd, pd->src, NULL,
- &nk->addr[sidx], 0);
+ &nk->addr[sidx], AF_INET6)) {
+ pf_translate_a(pd,
+ pd->src, &nk->addr[sidx]);
+ }
if (!afto && PF_ANEQ(pd->dst,
&nk->addr[didx], AF_INET6)) {
- pf_translate_ap(pd, pd->dst, NULL,
- &nk->addr[didx], 0);
+ pf_translate_a(pd,
+ pd->dst, &nk->addr[didx]);
pd->destchg = 1;
}
#endif /* INET6 */
}
#ifdef INET6
- if (afto) {
- PF_ACPY(&pd->nsaddr, &nk->addr[sidx], nk->af);
- PF_ACPY(&pd->ndaddr, &nk->addr[didx], nk->af);
- pd->naf = nk->af;
+ if (afto)
return (PF_AFRT);
- }
#endif /* INET6 */
}
} else {
pd, &pd2, &nk->addr[sidx],
&nk->addr[didx], pd->af, nk->af))
return (PF_DROP);
- pf_translate_ap(pd,
- pd2.src, &th.th_sport,
- &nk->addr[pd2.sidx],
- nk->port[sidx]);
- pf_translate_ap(pd,
- pd2.dst, &th.th_dport,
- &nk->addr[pd2.didx],
- nk->port[didx]);
+
+ pf_patch_16(pd,
+ &th.th_sport, nk->port[sidx]);
+ pf_patch_16(pd,
+ &th.th_dport, nk->port[didx]);
+
m_copyback(pd2.m, pd2.off, 8, &th,
M_NOWAIT);
return (PF_AFRT);
pd, &pd2, &nk->addr[sidx],
&nk->addr[didx], pd->af, nk->af))
return (PF_DROP);
- pf_translate_ap(pd,
- pd2.src, &uh.uh_sport,
- &nk->addr[pd2.sidx],
- nk->port[sidx]);
- pf_translate_ap(pd,
- pd2.dst, &uh.uh_dport,
- &nk->addr[pd2.didx],
- nk->port[didx]);
+
+ pf_patch_16(pd,
+ &uh.uh_sport, nk->port[sidx]);
+ pf_patch_16(pd,
+ &uh.uh_dport, nk->port[didx]);
+
m_copyback(pd2.m, pd2.off, sizeof(uh),
&uh, M_NOWAIT);
return (PF_AFRT);