unsigned int core_4to6(struct sk_buff *skb) { struct iphdr *ip4_header; struct in_addr daddr; enum verdict result; skb_linearize(skb); ip4_header = ip_hdr(skb); daddr.s_addr = ip4_header->daddr; if (!pool4_contains(&daddr)) return NF_ACCEPT; log_debug("==============================================="); log_debug("Catching IPv4 packet: %pI4->%pI4", &ip4_header->saddr, &ip4_header->daddr); result = validate_skb_ipv4(skb); if (result != VER_CONTINUE) return result; return nat64_core(skb, compute_out_tuple_4to6, translating_the_packet_4to6, send_packet_ipv6); }
/* * IPv4 entry function */ unsigned int nat64_tg4(struct sk_buff *skb, const struct xt_action_param *par) { const struct xt_nat64_tginfo *info = par->targinfo; struct iphdr *iph = ip_hdr(skb); __u8 l4_protocol = iph->protocol; /* switch(l4_protocol) { case IPPROTO_TCP: return NF_ACCEPT; case IPPROTO_ICMP: return NF_ACCEPT; case IPPROTO_ICMPV6: return NF_ACCEPT; } */ pr_debug("\n* INCOMING IPV4 PACKET *\n"); pr_debug("PKT SRC=%pI4 \n", &iph->saddr); pr_debug("PKT DST=%pI4 \n", &iph->daddr); pr_debug("RULE DST=%pI4 \n", &info->ipdst.in); pr_debug("RULE DST_MSK=%pI4 \n", &info->ipdst_mask); //ip_masked_addr_cmp(ip_a, ip_mask, ip_b) // Do NOT process the packet if it is destined to an address not in // the pool network. Rob. //~ if(skb->len < sizeof(struct iphdr) || iph->version != 4 || (iph->daddr & ipv4_netmask) != ipv4_addr) if(skb->len < sizeof(struct iphdr) || iph->version != 4 || (iph->daddr & ipv4_netmask) != ipv4_pool_net.s_addr) return NF_ACCEPT; if (l4_protocol & NAT64_IP_ALLWD_PROTOS) { /* * Core functions of the NAT64 implementation. */ return nat64_core(skb, par, NFPROTO_IPV4, l4_protocol); } /* * If the packet is not in the allowed protocol list, it should be * returned to the stack. */ return NF_ACCEPT; }
/* * IPv6 entry function * */ unsigned int nat64_tg6(struct sk_buff *skb, const struct xt_action_param *par) { const struct xt_nat64_tginfo *info = par->targinfo; struct ipv6hdr *iph = ipv6_hdr(skb); __u8 l4_protocol = iph->nexthdr; /* switch(l4_protocol) { case IPPROTO_TCP: return NF_ACCEPT; case IPPROTO_ICMP: return NF_ACCEPT; case IPPROTO_ICMPV6: return NF_ACCEPT; } */ pr_debug("\n* INCOMING IPV6 PACKET *\n"); pr_debug("PKT SRC=%pI6c \n", &iph->saddr); pr_debug("PKT DST=%pI6c \n", &iph->daddr); pr_debug("RULE DST=%pI6c \n", &info->ip6dst.in6); pr_debug("RULE DST_MSK=%pI6c \n", &info->ip6dst_mask); /* * If the packet is not directed towards the NAT64 prefix, * continue through the Netfilter rules. */ if (!nat64_tg6_cmp(&info->ip6dst.in6, &info->ip6dst_mask.in6, &iph->daddr, info->flags)) return NF_ACCEPT; if (l4_protocol & NAT64_IPV6_ALLWD_PROTOS) { /* * Core functions of the NAT64 implementation. */ return nat64_core(skb, par, NFPROTO_IPV6, l4_protocol); } /* * If the packet's protocol is not one of the ones defined for NAT64, * accept it. */ return NF_ACCEPT; }
unsigned int core_6to4(struct sk_buff *skb) { struct ipv6hdr *ip6_header; enum verdict result; skb_linearize(skb); ip6_header = ipv6_hdr(skb); if (!pool6_contains(&ip6_header->daddr)) return NF_ACCEPT; log_debug("==============================================="); log_debug("Catching IPv6 packet: %pI6c->%pI6c", &ip6_header->saddr, &ip6_header->daddr); result = validate_skb_ipv6(skb); if (result != VER_CONTINUE) return result; return nat64_core(skb, compute_out_tuple_6to4, translating_the_packet_6to4, send_packet_ipv4); }