NAT的实现是由 ip_conntrack, iptable_nat组成
1. IP conntrack
a. init
struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 __read_mostly = {
.l3proto = PF_INET,
.name = "ipv4",
.pkt_to_tuple = ipv4_pkt_to_tuple,
.invert_tuple = ipv4_invert_tuple,
.print_tuple = ipv4_print_tuple,
.get_l4proto = ipv4_get_l4proto
};
struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4 __read_mostly =
{
.l3proto = PF_INET,
.l4proto = IPPROTO_TCP,
.name = "tcp",
.pkt_to_tuple = tcp_pkt_to_tuple,
.invert_tuple = tcp_invert_tuple,
.print_tuple = tcp_print_tuple,
.print_conntrack = tcp_print_conntrack,
.packet = tcp_packet,
.get_timeouts = tcp_get_timeouts,
.new = tcp_new,
.error = tcp_error,
};
struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6 __read_mostly =
{
.l3proto = PF_INET6,
.l4proto = IPPROTO_UDP,
.name = "udp",
.pkt_to_tuple = udp_pkt_to_tuple,
.invert_tuple = udp_invert_tuple,
.print_tuple = udp_print_tuple,
.packet = udp_packet,
.get_timeouts = udp_get_timeouts,
.new = udp_new,
.error = udp_error,
};
int nf_conntrack_l3proto_ipv4_init(void)
{
/*register ipv4 tcp handler*/
ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_tcp4);
/*register ipv4 udp handler*/
ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_udp4);
/*register ipv4 icmp handler*/
ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_icmp);
/*register ipv4 handler*/
ret = nf_ct_l3proto_register(&nf_conntrack_l3proto_ipv4);
}