Excuse me, but I didn’t get the solution for the RAWNAT issue. Maybe it refers to that I'm not so familiar with the netfilter stuff. Is it possible to realize my issue, or do I have problems with the conntrack? Where can I find the source code for the RAWNAT target. Regards, Manu -------- Original-Nachricht -------- > Datum: Fri, 11 Apr 2008 10:32:05 +0200 (CEST) > Von: Jan Engelhardt <jengelh@xxxxxxxxxxxxxxx> > An: Manu <manuprivat@xxxxxx> > CC: netfilter-devel@xxxxxxxxxxxxxxx > Betreff: Re: Add new target in mangle table > > On Friday 2008-04-11 09:45, Manu wrote: > > >Hi developers, > > > >I encountered difficulties during integrating a new target in mangle > >table (iptables-1.4.0 (from www.netfilter.org), kernel-2.6.23 (from > >www.kernel.org)). > >I have a master from iptables-1.2.9 and kernel-2.6.3. But there were too > >many differences and changes be made. > >The idea behind to add the target is, that a user who has a fix-ip entry > >in his network settings can be handled from a gateway, for which the new > >targets should be implemented. for example: > > > ># iptables -t mangle -I PREROUTING -i eth2 -s 192.168.0.168 -j SADDR > >--to-source 10.0.19.2 > > > This looks pretty much like RAWNAT, as posted in > http://marc.info/?l=netfilter-devel&m=120024054521550&w=2 . Hi developers, I encountered difficulties during integrating a new target in mangle table (iptables-1.4.0 (from www.netfilter.org), kernel-2.6.23 (from www.kernel.org)). I have a master from iptables-1.2.9 and kernel-2.6.3. But there were too many differences and changes be made. The idea behind to add the target is, that a user who has a fix-ip entry in his network settings can be handled from a gateway, for which the new targets should be implemented. for example: # iptables -t mangle -I PREROUTING -i eth2 -s 192.168.0.168 -j SADDR --to-source 10.0.19.2 iptables: Target problem -> dmesg shows: ... SADDR: targinfosize 3290890384 != 4 ... There should be a user request management in the gateway, that nobody should care about the network-settings. It should doesn't matter if a user has dhcp activated or a fix IP entry. It works with the iptables-1.2.9 and kernel-2.6.3: Code posted: kernel-sources 2.6.3: ipt_SADDR.h ipt_SADDR.c iptables-sources 1.2.9: libipt_SADDR.c kernel-sources 2.6.23: ipt_SADDR.h ipt_SADDR.c iptables-sources 1.4.0: libipt_SADDR.c nearly the same for DADDR-target! I have attached all the important files - I think!? Any help would be greatly appreciated! Thanks in advance. Regards Manu kernel-sources 2.6.3: ipt_SADDR.h: ------------------------------ #ifndef _IPT_SADDR_H_target #define _IPT_SADDR_H_target struct ipt_saddr_target_info { u_int32_t saddr; }; #endif /*_IPT_SADDR_H_target*/ ------------------------------ ipt_SADDR.c: ------------------------------ #include <linux/module.h> #include <linux/skbuff.h> #include <linux/ip.h> #include <linux/udp.h> #include <linux/tcp.h> #include <net/tcp.h> #include <net/checksum.h> #include <linux/netfilter_ipv4/ip_tables.h> #include <linux/netfilter_ipv4/ipt_SADDR.h> MODULE_LICENSE("GPL"); MODULE_AUTHOR("Uli Konrad"); MODULE_DESCRIPTION("iptables IP Source Address mangling module"); static unsigned int target(struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, unsigned int hooknum, const void *targinfo, void *userinfo) { const struct ipt_saddr_target_info *saddrinfo = targinfo; if ((*pskb)->nh.iph->saddr != saddrinfo->saddr) { u_int32_t diffs[2]; if (!skb_ip_make_writable(pskb, sizeof(struct iphdr))) return NF_DROP; diffs[0] = ~((*pskb)->nh.iph->saddr); (*pskb)->nh.iph->saddr = saddrinfo->saddr; diffs[1] = saddrinfo->saddr; (*pskb)->nh.iph->check = csum_fold(csum_partial((char *)diffs, sizeof(diffs), (*pskb)->nh.iph->check ^0xFFFF)); if ((*pskb)->nh.iph->protocol == 0x06) { struct iphdr *iph; struct tcphdr *tcph; int datalen; iph = (*pskb)->nh.iph; tcph = (void *)iph + iph->ihl*4; datalen = (*pskb)->len - iph->ihl*4; tcph->check = 0; tcph->check = tcp_v4_check(tcph, datalen, iph->saddr, iph->daddr, csum_partial((char *)tcph, datalen, 0)); } if ((*pskb)->nh.iph->protocol == 0x11) { struct iphdr *iph; struct udphdr *udph; int datalen; iph = (*pskb)->nh.iph; udph = (void *)iph + iph->ihl*4; datalen = (*pskb)->len - iph->ihl * 4; udph->check = 0; udph->check = csum_tcpudp_magic(iph->saddr, iph->daddr, datalen, IPPROTO_UDP, csum_partial((char *)udph, datalen, 0)); } (*pskb)->nfcache |= NFC_ALTERED; } return IPT_CONTINUE; } static int checkentry(const char *tablename, const struct ipt_entry *e, void *targinfo, unsigned int targinfosize, unsigned int hook_mask) { if (targinfosize != IPT_ALIGN(sizeof(struct ipt_saddr_target_info))) { printk(KERN_WARNING "SADDR: targinfosize %u != %Zu\n", targinfosize, IPT_ALIGN(sizeof(struct ipt_saddr_target_info))); return 0; } if (strcmp(tablename, "mangle") != 0) { printk(KERN_WARNING "SADDR: can only be called from \"mangle\" table, not \"%s\"\n", tablename); return 0; } return 1; } static struct ipt_target ipt_saddr_reg = { .name = "SADDR", .target = target, .checkentry = checkentry, .me = THIS_MODULE, }; static int __init init(void) { return ipt_register_target(&ipt_saddr_reg); } static void __exit fini(void) { ipt_unregister_target(&ipt_saddr_reg); } module_init(init); module_exit(fini); ---------------------------- iptables-1.2.9: libipt_SADDR.c: ---------------------------- #include <stdio.h> #include <string.h> #include <stdlib.h> #include <getopt.h> #include <iptables.h> #include <linux/netfilter_ipv4/ip_tables.h> #include <linux/netfilter_ipv4/ipt_SADDR.h> struct saddrinfo { struct ipt_entry_target t; struct ipt_saddr_target_info saddr; }; /* Function which prints out usage message. */ static void help(void) { printf( "SADDR target v%s options:\n" " --to-source ip-address set source address\n", IPTABLES_VERSION); } static struct option opts[] = { { "to-source", 1, 0, '1' }, { 0 } }; /* Initialize the target. */ static void init(struct ipt_entry_target *t, unsigned int *nfcache) { } static void parse_saddr(const unsigned char *s, struct ipt_saddr_target_info *info) { struct in_addr *ip; ip = dotted_to_addr(s); if (!ip) exit_error(PARAMETER_PROBLEM, "Bad IP address `%s'\n", s); info->saddr = ip->s_addr; } /* Function which parses command options; returns true if it ate an option */ static int parse(int c, char **argv, int invert, unsigned int *flags, const struct ipt_entry *entry, struct ipt_entry_target **target) { struct ipt_saddr_target_info *saddrinfo = (struct ipt_saddr_target_info *)(*target)->data; switch (c) { case '1': if (*flags) exit_error(PARAMETER_PROBLEM, "SADDR target: Cant specify --to-source twice"); parse_saddr(optarg, saddrinfo); *flags = 1; break; default: return 0; } return 1; } static void final_check(unsigned int flags) { if (!flags) exit_error(PARAMETER_PROBLEM, "SADDR target: Parameter --to-source is required"); } /* Prints out the targinfo. */ static void print(const struct ipt_ip *ip, const struct ipt_entry_target *target, int numeric) { struct in_addr a; const struct ipt_saddr_target_info *saddrinfo = (const struct ipt_saddr_target_info *)target->data; a.s_addr = saddrinfo->saddr; printf("SADDR set %s ", addr_to_dotted(&a)); } /* Saves the union ipt_targinfo in parsable form to stdout. */ static void save(const struct ipt_ip *ip, const struct ipt_entry_target *target) { struct in_addr a; const struct ipt_saddr_target_info *saddrinfo = (const struct ipt_saddr_target_info *)target->data; a.s_addr = saddrinfo->saddr; printf("--to-source %s ", addr_to_dotted(&a)); } static struct iptables_target saddr = { NULL, "SADDR", IPTABLES_VERSION, IPT_ALIGN(sizeof(struct ipt_saddr_target_info)), IPT_ALIGN(sizeof(struct ipt_saddr_target_info)), &help, &init, &parse, &final_check, &print, &save, opts }; void _init(void) { register_target(&saddr); } -------------------------------- kernel-sources 2.6.23: ipt_SADDR.h -------------------------------- #ifndef _IPT_SADDR_H #define _IPT_SADDR_H struct ipt_saddr_target_info { u_int8_t saddr; }; #endif /*_IPT_SADDR_H*/ ------------------------------- ipt_SADDR.c ------------------------------- #include <linux/module.h> #include <linux/skbuff.h> #include <linux/ip.h> #include <linux/tcp.h> #include <linux/udp.h> #include <linux/in.h> #include <linux/netfilter.h> #include <net/checksum.h> #include <linux/netfilter/x_tables.h> #include <linux/netfilter_ipv4/ipt_SADDR.h> #include <linux/netfilter_ipv4/ip_tables.h> #define NFC_ALTERED 0x8000 MODULE_LICENSE("GPL"); MODULE_AUTHOR("Manuel Scheub"); MODULE_DESCRIPTION("iptables IP Source Address mangling module"); static unsigned int target(struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, unsigned int hooknum, const struct xt_target *target, const void *targinfo) { const struct ipt_saddr_target_info *saddrinfo = targinfo; struct iphdr *iph = ip_hdr(*pskb); if (iph->saddr != saddrinfo->saddr) { u_int32_t diffs[2]; if (!skb_make_writable(pskb, sizeof(struct iphdr))) return NF_DROP; diffs[0] = ~(iph->saddr); iph->saddr = saddrinfo->saddr; diffs[1] = saddrinfo->saddr; iph->check = csum_fold(csum_partial((char *)diffs, sizeof(diffs), iph->check ^0xFFFF)); if (iph->protocol == 0x06) { // struct iphdr *iph; struct tcphdr *tcph; int datalen; // iph = (*pskb)->nh.iph; tcph = (void *)iph + iph->ihl*4; datalen = (*pskb)->len - iph->ihl * 4; tcph->check = 0; tcph->check = csum_tcpudp_magic(iph->saddr, iph->daddr, datalen, IPPROTO_TCP, csum_partial((char *)tcph, datalen, 0)); } if (iph->protocol == 0x11) { // struct iphdr *iph; struct udphdr *udph; int datalen; // iph = (*pskb)->nh.iph; udph = (void *)iph + iph->ihl*4; datalen = (*pskb)->len - iph->ihl * 4; udph->check = 0; udph->check = csum_tcpudp_magic(iph->saddr, iph->daddr, datalen, IPPROTO_UDP, csum_partial((char *)udph, datalen, 0)); } // (*pskb)->nfcache |= NFC_ALTERED; } return XT_CONTINUE; } bool checkentry(const char *tablename, const struct ipt_entry *e, void *targinfo, unsigned int targinfosize, unsigned int hook_mask) { if (targinfosize != IPT_ALIGN(sizeof(struct ipt_saddr_target_info))) { printk(KERN_WARNING "SADDR: targinfosize %u != %Zu\n", targinfosize, IPT_ALIGN(sizeof(struct ipt_saddr_target_info))); return 0; } if (strcmp(tablename, "mangle") != 0) { printk(KERN_WARNING "SADDR: can only be called from \"mangle\" table, not \"%s\"\n", tablename); return 0; } return 1; } static struct xt_target ipt_saddr_reg __read_mostly = { .name = "SADDR", .family = AF_INET, .target = target, .targetsize = sizeof(struct ipt_saddr_target_info), .table = "mangle", .checkentry = checkentry, .me = THIS_MODULE, }; static int __init ipt_saddr_init(void) { return xt_register_target(&ipt_saddr_reg); } static void __exit ipt_saddr_fini(void) { xt_unregister_target(&ipt_saddr_reg); } module_init(ipt_saddr_init); module_exit(ipt_saddr_fini); ----------------------------------- iptables-sources 1.4.0 libipt_SADDR.c: ----------------------------------#include <stdio.h> #include <string.h> #include <stdlib.h> #include <getopt.h> #include <iptables.h> #include <linux/netfilter_ipv4/ip_tables.h> #include <linux/netfilter_ipv4/ipt_SADDR.h> struct saddrinfo { struct xt_entry_target t; struct ipt_saddr_target_info saddr; }; /* Function which prints out usage message. */ static void SADDR_help(void) { printf( "SADDR target v%s options:\n" " --to-source ip-address set source address\n", IPTABLES_VERSION); } static const struct option SADDR_opts[] = { { "to-source", 1, NULL, '1' }, { 0 } }; static void parse_saddr(const char *s, struct ipt_saddr_target_info *info) { struct in_addr *ip; ip = dotted_to_addr(s); if (!ip) exit_error(PARAMETER_PROBLEM, "Bad IP address `%s'\n", s); info->saddr = ip->s_addr; } /* Function which parses command options; returns true if it ate an option */ static int SADDR_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_target **target) { struct ipt_saddr_target_info *saddrinfo = (struct ipt_saddr_target_info *)(*target)->data; switch (c) { case '1': if (*flags) exit_error(PARAMETER_PROBLEM, "SADDR target: Cant specify --to-source twice"); parse_saddr(optarg, saddrinfo); *flags = 1; break; default: return 0; } return 1; } static void SADDR_check(unsigned int flags) { if (!flags) exit_error(PARAMETER_PROBLEM, "SADDR target: Parameter --to-source is required"); } static void print_saddr(u_int8_t saddr, int numeric) { unsigned int i; if (!numeric) { for (i = 0; i<sizeof(SADDR_values)/sizeof(struct SADDR_value); i++) if (SADDR_values[i].SADDR == saddr) { printf("%s ", SADDR_values[i].name); return; } } printf("0x%02x ", saddr); } /* Prints out the targinfo. */ static void SADDR_print(const void *ip, const struct xt_entry_target *target, int numeric) { const struct ipt_saddr_target_info *saddrinfo = (const struct ipt_saddr_target_info *)target->data; printf("SADDR set "); print_saddr(saddrinfo->saddr, numeric); } /* Saves the union ipt_targinfo in parsable form to stdout. */ static void SADDR_save(const void *ip, const struct xt_entry_target *target) { const struct ipt_saddr_target_info *saddrinfo = (const struct ipt_saddr_target_info *)target->data; printf("--to-source 0x%02x ", saddrinfo->saddr); } static struct iptables_target saddr_target = { .name = "SADDR", .version = IPTABLES_VERSION, .size = IPT_ALIGN(sizeof(struct ipt_saddr_target_info)), .userspacesize = IPT_ALIGN(sizeof(struct ipt_saddr_target_info)), .help = SADDR_help, .parse = SADDR_parse, .final_check = SADDR_check, .print = SADDR_print, .save = SADDR_save, .extra_opts = SADDR_opts, }; void _init(void) { register_target(&saddr_target); } ---------------------------------------- -- Psst! Geheimtipp: Online Games kostenlos spielen bei den GMX Free Games! http://games.entertainment.gmx.net/de/entertainment/games/free -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html