Changeset View
Changeset View
Standalone View
Standalone View
sys/netpfil/ipfw/nat64/nat64stl.c
- This file was copied to sys/netpfil/ipfw/nat64/nat64clat.c.
/*- | /*- | ||||
* Copyright (c) 2015-2016 Yandex LLC | * SPDX-License-Identifier: BSD-2-Clause-FreeBSD | ||||
* Copyright (c) 2015-2016 Andrey V. Elsukov <ae@FreeBSD.org> | |||||
* All rights reserved. | |||||
* | * | ||||
* Copyright (c) 2015-2019 Yandex LLC | |||||
* Copyright (c) 2015-2019 Andrey V. Elsukov <ae@FreeBSD.org> | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
* modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
* are met: | * are met: | ||||
* | * | ||||
* 1. Redistributions of source code must retain the above copyright | * 1. Redistributions of source code must retain the above copyright | ||||
* notice, this list of conditions and the following disclaimer. | * notice, this list of conditions and the following disclaimer. | ||||
* 2. Redistributions in binary form must reproduce the above copyright | * 2. Redistributions in binary form must reproduce the above copyright | ||||
* notice, this list of conditions and the following disclaimer in the | * notice, this list of conditions and the following disclaimer in the | ||||
Show All 24 Lines | |||||
#include <sys/rmlock.h> | #include <sys/rmlock.h> | ||||
#include <sys/rwlock.h> | #include <sys/rwlock.h> | ||||
#include <sys/socket.h> | #include <sys/socket.h> | ||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <net/if.h> | #include <net/if.h> | ||||
#include <net/if_var.h> | #include <net/if_var.h> | ||||
#include <net/if_pflog.h> | #include <net/if_pflog.h> | ||||
#include <net/pfil.h> | |||||
#include <netinet/in.h> | #include <netinet/in.h> | ||||
#include <netinet/ip.h> | #include <netinet/ip.h> | ||||
#include <netinet/ip_icmp.h> | #include <netinet/ip_icmp.h> | ||||
#include <netinet/ip_var.h> | #include <netinet/ip_var.h> | ||||
#include <netinet/ip_fw.h> | #include <netinet/ip_fw.h> | ||||
#include <netinet/ip6.h> | #include <netinet/ip6.h> | ||||
#include <netinet/icmp6.h> | #include <netinet/icmp6.h> | ||||
Show All 39 Lines | if (nat64_check_ip4(ip->ip_src.s_addr) != 0 || | ||||
nat64_check_ip4(ip->ip_dst.s_addr) != 0 || | nat64_check_ip4(ip->ip_dst.s_addr) != 0 || | ||||
nat64_check_private_ip4(&cfg->base, ip->ip_src.s_addr) != 0 || | nat64_check_private_ip4(&cfg->base, ip->ip_src.s_addr) != 0 || | ||||
nat64_check_private_ip4(&cfg->base, ip->ip_dst.s_addr) != 0) | nat64_check_private_ip4(&cfg->base, ip->ip_dst.s_addr) != 0) | ||||
return (NAT64SKIP); | return (NAT64SKIP); | ||||
daddr = TARG_VAL(chain, tablearg, nh6); | daddr = TARG_VAL(chain, tablearg, nh6); | ||||
if (nat64_check_ip6(&daddr) != 0) | if (nat64_check_ip6(&daddr) != 0) | ||||
return (NAT64MFREE); | return (NAT64MFREE); | ||||
nat64_embed_ip4(&cfg->base, ip->ip_src.s_addr, &saddr); | |||||
saddr = cfg->base.plat_prefix; | |||||
nat64_embed_ip4(&saddr, cfg->base.plat_plen, ip->ip_src.s_addr); | |||||
if (cfg->base.flags & NAT64_LOG) { | if (cfg->base.flags & NAT64_LOG) { | ||||
logdata = &loghdr; | logdata = &loghdr; | ||||
nat64stl_log(logdata, m, AF_INET, cfg->no.kidx); | nat64stl_log(logdata, m, AF_INET, cfg->no.kidx); | ||||
} else | } else | ||||
logdata = NULL; | logdata = NULL; | ||||
return (nat64_do_handle_ip4(m, &saddr, &daddr, 0, &cfg->base, | return (nat64_do_handle_ip4(m, &saddr, &daddr, 0, &cfg->base, | ||||
logdata)); | logdata)); | ||||
} | } | ||||
static int | static int | ||||
nat64stl_handle_ip6(struct ip_fw_chain *chain, struct nat64stl_cfg *cfg, | nat64stl_handle_ip6(struct ip_fw_chain *chain, struct nat64stl_cfg *cfg, | ||||
struct mbuf *m, uint32_t tablearg) | struct mbuf *m, uint32_t tablearg) | ||||
{ | { | ||||
struct pfloghdr loghdr, *logdata; | struct pfloghdr loghdr, *logdata; | ||||
struct ip6_hdr *ip6; | struct ip6_hdr *ip6; | ||||
uint32_t aaddr; | uint32_t aaddr; | ||||
aaddr = htonl(TARG_VAL(chain, tablearg, nh4)); | aaddr = htonl(TARG_VAL(chain, tablearg, nh4)); | ||||
if (nat64_check_private_ip4(&cfg->base, aaddr) != 0) { | |||||
NAT64STAT_INC(&cfg->base.stats, dropped); | |||||
return (NAT64MFREE); | |||||
} | |||||
/* | /* | ||||
* NOTE: we expect ipfw_chk() did m_pullup() up to upper level | * NOTE: we expect ipfw_chk() did m_pullup() up to upper level | ||||
* protocol's headers. Also we skip some checks, that ip6_input(), | * protocol's headers. Also we skip some checks, that ip6_input(), | ||||
* ip6_forward(), ip6_fastfwd() and ipfw_chk() already did. | * ip6_forward(), ip6_fastfwd() and ipfw_chk() already did. | ||||
*/ | */ | ||||
ip6 = mtod(m, struct ip6_hdr *); | ip6 = mtod(m, struct ip6_hdr *); | ||||
/* Check ip6_dst matches configured prefix */ | /* Check ip6_dst matches configured prefix */ | ||||
if (bcmp(&ip6->ip6_dst, &cfg->base.prefix6, cfg->base.plen6 / 8) != 0) | if (memcmp(&ip6->ip6_dst, &cfg->base.plat_prefix, | ||||
cfg->base.plat_plen / 8) != 0) | |||||
return (NAT64SKIP); | return (NAT64SKIP); | ||||
if (cfg->base.flags & NAT64_LOG) { | if (cfg->base.flags & NAT64_LOG) { | ||||
logdata = &loghdr; | logdata = &loghdr; | ||||
nat64stl_log(logdata, m, AF_INET6, cfg->no.kidx); | nat64stl_log(logdata, m, AF_INET6, cfg->no.kidx); | ||||
} else | } else | ||||
logdata = NULL; | logdata = NULL; | ||||
return (nat64_do_handle_ip6(m, aaddr, 0, &cfg->base, logdata)); | return (nat64_do_handle_ip6(m, aaddr, 0, &cfg->base, logdata)); | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | nat64stl_handle_icmp6(struct ip_fw_chain *chain, struct nat64stl_cfg *cfg, | ||||
} | } | ||||
/* | /* | ||||
* Use destination address from inner IPv6 header to determine | * Use destination address from inner IPv6 header to determine | ||||
* IPv4 mapped address. | * IPv4 mapped address. | ||||
*/ | */ | ||||
ip6i = mtodo(m, hlen); | ip6i = mtodo(m, hlen); | ||||
if (ipfw_lookup_table(chain, cfg->map64, | if (ipfw_lookup_table(chain, cfg->map64, | ||||
sizeof(struct in6_addr), &ip6i->ip6_dst, &tablearg) == 0) { | sizeof(struct in6_addr), &ip6i->ip6_dst, &tablearg) == 0) { | ||||
m_freem(m); | NAT64STAT_INC(stats, dropped); | ||||
return (NAT64RETURN); | return (NAT64MFREE); | ||||
} | } | ||||
if (cfg->base.flags & NAT64_LOG) { | if (cfg->base.flags & NAT64_LOG) { | ||||
logdata = &loghdr; | logdata = &loghdr; | ||||
nat64stl_log(logdata, m, AF_INET6, cfg->no.kidx); | nat64stl_log(logdata, m, AF_INET6, cfg->no.kidx); | ||||
} else | } else | ||||
logdata = NULL; | logdata = NULL; | ||||
return (nat64_handle_icmp6(m, 0, | return (nat64_handle_icmp6(m, 0, | ||||
htonl(TARG_VAL(chain, tablearg, nh4)), 0, &cfg->base, logdata)); | htonl(TARG_VAL(chain, tablearg, nh4)), 0, &cfg->base, logdata)); | ||||
▲ Show 20 Lines • Show All 52 Lines • ▼ Show 20 Lines | ipfw_nat64stl(struct ip_fw_chain *chain, struct ip_fw_args *args, | ||||
} | } | ||||
if (ret == NAT64SKIP) | if (ret == NAT64SKIP) | ||||
return (0); | return (0); | ||||
*done = 1; /* terminate the search */ | *done = 1; /* terminate the search */ | ||||
if (ret == NAT64MFREE) | if (ret == NAT64MFREE) | ||||
m_freem(args->m); | m_freem(args->m); | ||||
args->m = NULL; | args->m = NULL; | ||||
return (IP_FW_DENY); | return (IP_FW_NAT64); | ||||
} | } | ||||