Ticket #879: 009-random_and_ROUTE.2.patch

File 009-random_and_ROUTE.2.patch, 20.7 KB (added by anonymous, 9 years ago)

package/iptables patch to add random match and ROUTE target support

  • extensions/Makefile

    diff -urN iptables-1.3.8/extensions/Makefile iptables-1.3.8.patched/extensions/Makefile
    old new  
    88PF_EXT_SLIB:=ah addrtype comment connmark conntrack dscp ecn esp hashlimit helper icmp iprange length limit mac mark multiport owner physdev pkttype policy realm sctp standard state tcp tcpmss tos ttl udp unclean CLASSIFY CONNMARK DNAT DSCP ECN LOG MARK MASQUERADE MIRROR NETMAP NFQUEUE NOTRACK REDIRECT REJECT SAME SNAT TCPMSS TOS TTL ULOG 
    99PF6_EXT_SLIB:=connmark eui64 hl icmp6 length limit mac mark multiport owner physdev policy standard state tcp udp CONNMARK HL LOG NFQUEUE MARK TCPMSS 
    1010 
     11PF_EXT_SLIB += random ROUTE 
     12PF6_EXT_SLIB += ROUTE 
     13 
    1114ifeq ($(DO_SELINUX), 1) 
    1215PF_EXT_SE_SLIB:=SECMARK CONNSECMARK 
    1316PF6_EXT_SE_SLIB:=SECMARK CONNSECMARK 
  • extensions/libip6t_ROUTE.c

    diff -urN iptables-1.3.8/extensions/libip6t_ROUTE.c iptables-1.3.8.patched/extensions/libip6t_ROUTE.c
    old new  
     1/* Shared library add-on to iptables to add ROUTE v6 target support. 
     2 * Author : Cedric de Launois, <delaunois@info.ucl.ac.be> 
     3 * v 1.1 2004/11/23 
     4 */ 
     5 
     6#include <stdio.h> 
     7#include <string.h> 
     8#include <stdlib.h> 
     9#include <getopt.h> 
     10#include <sys/types.h> 
     11#include <sys/socket.h> 
     12#include <arpa/inet.h> 
     13 
     14#include <ip6tables.h> 
     15#include <linux/netfilter_ipv6/ip6_tables.h> 
     16#include <linux/netfilter_ipv6/ip6t_ROUTE.h> 
     17 
     18/* compile IP6T_ROUTE_TEE support even if kernel headers are unpatched */ 
     19#ifndef IP6T_ROUTE_TEE 
     20#define IP6T_ROUTE_TEE          0x02 
     21#endif 
     22 
     23/* Function which prints out usage message. */ 
     24static void 
     25help(void) 
     26{ 
     27        printf( 
     28"ROUTE target v%s options:\n" 
     29"    --oif   \tifname \t\tRoute the packet through `ifname' network interface\n" 
     30"    --gw    \tip     \t\tRoute the packet via this gateway\n" 
     31"    --continue\t     \t\tRoute packet and continue traversing the\n" 
     32"            \t       \t\trules. Not valid with --iif or --tee.\n" 
     33"    --tee\t  \t\tDuplicate packet, route the duplicate,\n" 
     34"            \t       \t\tcontinue traversing with original packet.\n" 
     35"            \t       \t\tNot valid with --iif or --continue.\n" 
     36"\n", 
     37"1.1"); 
     38} 
     39 
     40static struct option opts[] = { 
     41        { "oif", 1, 0, '1' }, 
     42        { "iif", 1, 0, '2' }, 
     43        { "gw", 1, 0, '3' }, 
     44        { "continue", 0, 0, '4' }, 
     45        { "tee", 0, 0, '5' }, 
     46        { 0 } 
     47}; 
     48 
     49/* Initialize the target. */ 
     50static void 
     51init(struct ip6t_entry_target *t, unsigned int *nfcache) 
     52{ 
     53        struct ip6t_route_target_info *route_info =  
     54                (struct ip6t_route_target_info*)t->data; 
     55 
     56        route_info->oif[0] = '\0'; 
     57        route_info->iif[0] = '\0'; 
     58        route_info->gw[0] = 0; 
     59        route_info->gw[1] = 0; 
     60        route_info->gw[2] = 0; 
     61        route_info->gw[3] = 0; 
     62        route_info->flags = 0; 
     63} 
     64 
     65 
     66#define IP6T_ROUTE_OPT_OIF      0x01 
     67#define IP6T_ROUTE_OPT_IIF      0x02 
     68#define IP6T_ROUTE_OPT_GW       0x04 
     69#define IP6T_ROUTE_OPT_CONTINUE 0x08 
     70#define IP6T_ROUTE_OPT_TEE      0x10 
     71 
     72/* Function which parses command options; returns true if it 
     73   ate an option */ 
     74static int 
     75parse(int c, char **argv, int invert, unsigned int *flags, 
     76      const struct ip6t_entry *entry, 
     77      struct ip6t_entry_target **target) 
     78{ 
     79        struct ip6t_route_target_info *route_info =  
     80                (struct ip6t_route_target_info*)(*target)->data; 
     81 
     82        switch (c) { 
     83        case '1': 
     84                if (*flags & IP6T_ROUTE_OPT_OIF) 
     85                        exit_error(PARAMETER_PROBLEM, 
     86                                   "Can't specify --oif twice"); 
     87 
     88                if (check_inverse(optarg, &invert, NULL, 0)) 
     89                        exit_error(PARAMETER_PROBLEM, 
     90                                   "Unexpected `!' after --oif"); 
     91 
     92                if (strlen(optarg) > sizeof(route_info->oif) - 1) 
     93                        exit_error(PARAMETER_PROBLEM, 
     94                                   "Maximum interface name length %u", 
     95                                   sizeof(route_info->oif) - 1); 
     96 
     97                strcpy(route_info->oif, optarg); 
     98                *flags |= IP6T_ROUTE_OPT_OIF; 
     99                break; 
     100 
     101        case '2': 
     102                exit_error(PARAMETER_PROBLEM, 
     103                           "--iif option not implemented"); 
     104                break; 
     105 
     106        case '3': 
     107                if (*flags & IP6T_ROUTE_OPT_GW) 
     108                        exit_error(PARAMETER_PROBLEM, 
     109                                   "Can't specify --gw twice"); 
     110 
     111                if (check_inverse(optarg, &invert, NULL, 0)) 
     112                        exit_error(PARAMETER_PROBLEM, 
     113                                   "Unexpected `!' after --gw"); 
     114 
     115                if (!inet_pton(AF_INET6, optarg, (struct in6_addr*)&route_info->gw)) { 
     116                        exit_error(PARAMETER_PROBLEM, 
     117                                   "Invalid IPv6 address %s", 
     118                                   optarg); 
     119                } 
     120 
     121                *flags |= IP6T_ROUTE_OPT_GW; 
     122                break; 
     123 
     124        case '4': 
     125                if (*flags & IP6T_ROUTE_OPT_CONTINUE) 
     126                        exit_error(PARAMETER_PROBLEM, 
     127                                   "Can't specify --continue twice"); 
     128                if (*flags & IP6T_ROUTE_OPT_TEE) 
     129                        exit_error(PARAMETER_PROBLEM, 
     130                                   "Can't specify --continue AND --tee"); 
     131 
     132                route_info->flags |= IP6T_ROUTE_CONTINUE; 
     133                *flags |= IP6T_ROUTE_OPT_CONTINUE; 
     134 
     135                break; 
     136 
     137        case '5': 
     138                if (*flags & IP6T_ROUTE_OPT_TEE) 
     139                        exit_error(PARAMETER_PROBLEM, 
     140                                   "Can't specify --tee twice"); 
     141                if (*flags & IP6T_ROUTE_OPT_CONTINUE) 
     142                        exit_error(PARAMETER_PROBLEM, 
     143                                   "Can't specify --tee AND --continue"); 
     144 
     145                route_info->flags |= IP6T_ROUTE_TEE; 
     146                *flags |= IP6T_ROUTE_OPT_TEE; 
     147 
     148                break; 
     149 
     150        default: 
     151                return 0; 
     152        } 
     153 
     154        return 1; 
     155} 
     156 
     157 
     158static void 
     159final_check(unsigned int flags) 
     160{ 
     161        if (!flags) 
     162                exit_error(PARAMETER_PROBLEM, 
     163                           "ROUTE target: oif or gw option required"); 
     164} 
     165 
     166 
     167/* Prints out the targinfo. */ 
     168static void 
     169print(const struct ip6t_ip6 *ip, 
     170      const struct ip6t_entry_target *target, 
     171      int numeric) 
     172{ 
     173        const struct ip6t_route_target_info *route_info 
     174                = (const struct ip6t_route_target_info *)target->data; 
     175 
     176        printf("ROUTE "); 
     177 
     178        if (route_info->oif[0]) 
     179                printf("oif:%s ", route_info->oif); 
     180 
     181        if (route_info->gw[0]  
     182            || route_info->gw[1]  
     183            || route_info->gw[2]  
     184            || route_info->gw[3]) { 
     185                char address[INET6_ADDRSTRLEN]; 
     186                printf("gw:%s ", inet_ntop(AF_INET6, route_info->gw, address, INET6_ADDRSTRLEN)); 
     187        } 
     188 
     189        if (route_info->flags & IP6T_ROUTE_CONTINUE) 
     190                printf("continue"); 
     191 
     192        if (route_info->flags & IP6T_ROUTE_TEE) 
     193                printf("tee"); 
     194 
     195} 
     196 
     197 
     198static void save(const struct ip6t_ip6 *ip,  
     199                 const struct ip6t_entry_target *target) 
     200{ 
     201        const struct ip6t_route_target_info *route_info 
     202                = (const struct ip6t_route_target_info *)target->data; 
     203 
     204        if (route_info->oif[0]) 
     205                printf("--oif %s ", route_info->oif); 
     206 
     207        if (route_info->gw[0]  
     208            || route_info->gw[1]  
     209            || route_info->gw[2]  
     210            || route_info->gw[3]) { 
     211                char address[INET6_ADDRSTRLEN]; 
     212                printf("--gw %s ", inet_ntop(AF_INET6, route_info->gw, address, INET6_ADDRSTRLEN)); 
     213        } 
     214 
     215        if (route_info->flags & IP6T_ROUTE_CONTINUE) 
     216                printf("--continue "); 
     217 
     218        if (route_info->flags & IP6T_ROUTE_TEE) 
     219                printf("--tee "); 
     220} 
     221 
     222 
     223static struct ip6tables_target route = {  
     224        .name           = "ROUTE", 
     225        .version        = IPTABLES_VERSION, 
     226        .size           = IP6T_ALIGN(sizeof(struct ip6t_route_target_info)), 
     227        .userspacesize  = IP6T_ALIGN(sizeof(struct ip6t_route_target_info)), 
     228        .help           = &help, 
     229        .init           = &init, 
     230        .parse          = &parse, 
     231        .final_check    = &final_check, 
     232        .print          = &print, 
     233        .save           = &save, 
     234        .extra_opts     = opts, 
     235}; 
     236 
     237void _init(void) 
     238{ 
     239        register_target6(&route); 
     240} 
  • extensions/libip6t_ROUTE.man

    diff -urN iptables-1.3.8/extensions/libip6t_ROUTE.man iptables-1.3.8.patched/extensions/libip6t_ROUTE.man
    old new  
     1This is used to explicitly override the core network stack's routing decision. 
     2.B mangle 
     3table. 
     4.TP 
     5.BI "--oif " "ifname" 
     6Route the packet through `ifname' network interface 
     7.TP 
     8.BI "--gw " "IPv6_address" 
     9Route the packet via this gateway 
     10.TP 
     11.BI "--continue " 
     12Behave like a non-terminating target and continue traversing the rules. Not valid in combination with `--tee' 
     13.TP 
     14.BI "--tee " 
     15Make a copy of the packet, and route that copy to the given destination. For the original, uncopied packet, behave like a non-terminating target and continue traversing the rules.  Not valid in combination with `--continue' 
  • extensions/libipt_ROUTE.c

    diff -urN iptables-1.3.8/extensions/libipt_ROUTE.c iptables-1.3.8.patched/extensions/libipt_ROUTE.c
    old new  
     1/* Shared library add-on to iptables to add ROUTE target support. 
     2 * Author : Cedric de Launois, <delaunois@info.ucl.ac.be> 
     3 * v 1.11 2004/11/23 
     4 */ 
     5 
     6#include <stdio.h> 
     7#include <string.h> 
     8#include <stdlib.h> 
     9#include <getopt.h> 
     10#include <iptables.h> 
     11#include <net/if.h> 
     12#include <sys/socket.h> 
     13#include <netinet/in.h> 
     14#include <arpa/inet.h> 
     15#include <linux/netfilter_ipv4/ip_tables.h> 
     16#include <linux/netfilter_ipv4/ipt_ROUTE.h> 
     17 
     18/* compile IPT_ROUTE_TEE support even if kernel headers are unpatched */ 
     19#ifndef IPT_ROUTE_TEE 
     20#define IPT_ROUTE_TEE           0x02 
     21#endif 
     22 
     23/* Function which prints out usage message. */ 
     24static void 
     25help(void) 
     26{ 
     27        printf( 
     28"ROUTE target v%s options:\n" 
     29"    --oif   \tifname \t\tRoute packet through `ifname' network interface\n" 
     30"    --iif   \tifname \t\tChange packet's incoming interface to `ifname'\n" 
     31"    --gw    \tip     \t\tRoute packet via this gateway `ip'\n" 
     32"    --continue\t     \t\tRoute packet and continue traversing the\n" 
     33"            \t       \t\trules. Not valid with --iif or --tee.\n" 
     34"    --tee\t  \t\tDuplicate packet, route the duplicate,\n" 
     35"            \t       \t\tcontinue traversing with original packet.\n" 
     36"            \t       \t\tNot valid with --iif or --continue.\n" 
     37"\n", 
     38"1.11"); 
     39} 
     40 
     41static struct option opts[] = { 
     42        { "oif", 1, 0, '1' }, 
     43        { "iif", 1, 0, '2' }, 
     44        { "gw", 1, 0, '3' }, 
     45        { "continue", 0, 0, '4' }, 
     46        { "tee", 0, 0, '5' }, 
     47        { 0 } 
     48}; 
     49 
     50/* Initialize the target. */ 
     51static void 
     52init(struct ipt_entry_target *t, unsigned int *nfcache) 
     53{ 
     54        struct ipt_route_target_info *route_info =  
     55                (struct ipt_route_target_info*)t->data; 
     56 
     57        route_info->oif[0] = '\0'; 
     58        route_info->iif[0] = '\0'; 
     59        route_info->gw = 0; 
     60        route_info->flags = 0; 
     61} 
     62 
     63 
     64#define IPT_ROUTE_OPT_OIF      0x01 
     65#define IPT_ROUTE_OPT_IIF      0x02 
     66#define IPT_ROUTE_OPT_GW       0x04 
     67#define IPT_ROUTE_OPT_CONTINUE 0x08 
     68#define IPT_ROUTE_OPT_TEE      0x10 
     69 
     70/* Function which parses command options; returns true if it 
     71   ate an option */ 
     72static int 
     73parse(int c, char **argv, int invert, unsigned int *flags, 
     74      const struct ipt_entry *entry, 
     75      struct ipt_entry_target **target) 
     76{ 
     77        struct ipt_route_target_info *route_info =  
     78                (struct ipt_route_target_info*)(*target)->data; 
     79 
     80        switch (c) { 
     81        case '1': 
     82                if (*flags & IPT_ROUTE_OPT_OIF) 
     83                        exit_error(PARAMETER_PROBLEM, 
     84                                   "Can't specify --oif twice"); 
     85 
     86                if (*flags & IPT_ROUTE_OPT_IIF) 
     87                        exit_error(PARAMETER_PROBLEM, 
     88                                   "Can't use --oif and --iif together"); 
     89 
     90                if (check_inverse(optarg, &invert, NULL, 0)) 
     91                        exit_error(PARAMETER_PROBLEM, 
     92                                   "Unexpected `!' after --oif"); 
     93 
     94                if (strlen(optarg) > sizeof(route_info->oif) - 1) 
     95                        exit_error(PARAMETER_PROBLEM, 
     96                                   "Maximum interface name length %u", 
     97                                   sizeof(route_info->oif) - 1); 
     98 
     99                strcpy(route_info->oif, optarg); 
     100                *flags |= IPT_ROUTE_OPT_OIF; 
     101                break; 
     102 
     103        case '2': 
     104                if (*flags & IPT_ROUTE_OPT_IIF) 
     105                        exit_error(PARAMETER_PROBLEM, 
     106                                   "Can't specify --iif twice"); 
     107 
     108                if (*flags & IPT_ROUTE_OPT_OIF) 
     109                        exit_error(PARAMETER_PROBLEM, 
     110                                   "Can't use --iif and --oif together"); 
     111 
     112                if (check_inverse(optarg, &invert, NULL, 0)) 
     113                        exit_error(PARAMETER_PROBLEM, 
     114                                   "Unexpected `!' after --iif"); 
     115 
     116                if (strlen(optarg) > sizeof(route_info->iif) - 1) 
     117                        exit_error(PARAMETER_PROBLEM, 
     118                                   "Maximum interface name length %u", 
     119                                   sizeof(route_info->iif) - 1); 
     120 
     121                strcpy(route_info->iif, optarg); 
     122                *flags |= IPT_ROUTE_OPT_IIF; 
     123                break; 
     124 
     125        case '3': 
     126                if (*flags & IPT_ROUTE_OPT_GW) 
     127                        exit_error(PARAMETER_PROBLEM, 
     128                                   "Can't specify --gw twice"); 
     129 
     130                if (check_inverse(optarg, &invert, NULL, 0)) 
     131                        exit_error(PARAMETER_PROBLEM, 
     132                                   "Unexpected `!' after --gw"); 
     133 
     134                if (!inet_aton(optarg, (struct in_addr*)&route_info->gw)) { 
     135                        exit_error(PARAMETER_PROBLEM, 
     136                                   "Invalid IP address %s", 
     137                                   optarg); 
     138                } 
     139 
     140                *flags |= IPT_ROUTE_OPT_GW; 
     141                break; 
     142 
     143        case '4': 
     144                if (*flags & IPT_ROUTE_OPT_CONTINUE) 
     145                        exit_error(PARAMETER_PROBLEM, 
     146                                   "Can't specify --continue twice"); 
     147                if (*flags & IPT_ROUTE_OPT_TEE) 
     148                        exit_error(PARAMETER_PROBLEM, 
     149                                   "Can't specify --continue AND --tee"); 
     150 
     151                route_info->flags |= IPT_ROUTE_CONTINUE; 
     152                *flags |= IPT_ROUTE_OPT_CONTINUE; 
     153 
     154                break; 
     155 
     156        case '5': 
     157                if (*flags & IPT_ROUTE_OPT_TEE) 
     158                        exit_error(PARAMETER_PROBLEM, 
     159                                   "Can't specify --tee twice"); 
     160                if (*flags & IPT_ROUTE_OPT_CONTINUE) 
     161                        exit_error(PARAMETER_PROBLEM, 
     162                                   "Can't specify --tee AND --continue"); 
     163 
     164                route_info->flags |= IPT_ROUTE_TEE; 
     165                *flags |= IPT_ROUTE_OPT_TEE; 
     166 
     167                break; 
     168 
     169        default: 
     170                return 0; 
     171        } 
     172 
     173        return 1; 
     174} 
     175 
     176 
     177static void 
     178final_check(unsigned int flags) 
     179{ 
     180        if (!flags) 
     181                exit_error(PARAMETER_PROBLEM, 
     182                           "ROUTE target: oif, iif or gw option required"); 
     183 
     184        if ((flags & (IPT_ROUTE_OPT_CONTINUE|IPT_ROUTE_OPT_TEE)) && (flags & IPT_ROUTE_OPT_IIF)) 
     185                exit_error(PARAMETER_PROBLEM, 
     186                           "ROUTE target: can't continue traversing the rules with iif option"); 
     187} 
     188 
     189 
     190/* Prints out the targinfo. */ 
     191static void 
     192print(const struct ipt_ip *ip, 
     193      const struct ipt_entry_target *target, 
     194      int numeric) 
     195{ 
     196        const struct ipt_route_target_info *route_info 
     197                = (const struct ipt_route_target_info *)target->data; 
     198 
     199        printf("ROUTE "); 
     200 
     201        if (route_info->oif[0]) 
     202                printf("oif:%s ", route_info->oif); 
     203 
     204        if (route_info->iif[0]) 
     205                printf("iif:%s ", route_info->iif); 
     206 
     207        if (route_info->gw) { 
     208                struct in_addr ip = { route_info->gw }; 
     209                printf("gw:%s ", inet_ntoa(ip)); 
     210        } 
     211 
     212        if (route_info->flags & IPT_ROUTE_CONTINUE) 
     213                printf("continue"); 
     214 
     215        if (route_info->flags & IPT_ROUTE_TEE) 
     216                printf("tee"); 
     217 
     218} 
     219 
     220 
     221static void save(const struct ipt_ip *ip,  
     222                 const struct ipt_entry_target *target) 
     223{ 
     224        const struct ipt_route_target_info *route_info 
     225                = (const struct ipt_route_target_info *)target->data; 
     226 
     227        if (route_info->oif[0]) 
     228                printf("--oif %s ", route_info->oif); 
     229 
     230        if (route_info->iif[0]) 
     231                printf("--iif %s ", route_info->iif); 
     232 
     233        if (route_info->gw) { 
     234                struct in_addr ip = { route_info->gw }; 
     235                printf("--gw %s ", inet_ntoa(ip)); 
     236        } 
     237 
     238        if (route_info->flags & IPT_ROUTE_CONTINUE) 
     239                printf("--continue "); 
     240 
     241        if (route_info->flags & IPT_ROUTE_TEE) 
     242                printf("--tee "); 
     243} 
     244 
     245 
     246static struct iptables_target route = {  
     247        .next           = NULL, 
     248        .name           = "ROUTE", 
     249        .version        = IPTABLES_VERSION, 
     250        .size           = IPT_ALIGN(sizeof(struct ipt_route_target_info)), 
     251        .userspacesize  = IPT_ALIGN(sizeof(struct ipt_route_target_info)), 
     252        .help           = &help, 
     253        .init           = &init, 
     254        .parse          = &parse, 
     255        .final_check    = &final_check, 
     256        .print          = &print, 
     257        .save           = &save, 
     258        .extra_opts     = opts 
     259}; 
     260 
     261void _init(void) 
     262{ 
     263        register_target(&route); 
     264} 
  • extensions/libipt_ROUTE.man

    diff -urN iptables-1.3.8/extensions/libipt_ROUTE.man iptables-1.3.8.patched/extensions/libipt_ROUTE.man
    old new  
     1This is used to explicitly override the core network stack's routing decision. 
     2.B mangle 
     3table. 
     4.TP 
     5.BI "--oif " "ifname" 
     6Route the packet through `ifname' network interface 
     7.TP 
     8.BI "--iif " "ifname" 
     9Change the packet's incoming interface to `ifname' 
     10.TP 
     11.BI "--gw " "IP_address" 
     12Route the packet via this gateway 
     13.TP 
     14.BI "--continue " 
     15Behave like a non-terminating target and continue traversing the rules.  Not valid in combination with `--iif' or `--tee' 
     16.TP 
     17.BI "--tee " 
     18Make a copy of the packet, and route that copy to the given destination. For the original, uncopied packet, behave like a non-terminating target and continue traversing the rules.  Not valid in combination with `--iif' or `--continue' 
  • extensions/libipt_random.c

    diff -urN iptables-1.3.8/extensions/libipt_random.c iptables-1.3.8.patched/extensions/libipt_random.c
    old new  
     1/*  
     2   Shared library add-on to iptables to add match support for random match. 
     3    
     4   This file is distributed under the terms of the GNU General Public 
     5   License (GPL). Copies of the GPL can be obtained from: 
     6   ftp://prep.ai.mit.edu/pub/gnu/GPL 
     7 
     8   2001-10-14 Fabrice MARIE <fabrice@netfilter.org> : initial development. 
     9*/ 
     10 
     11#include <stdio.h> 
     12#include <netdb.h> 
     13#include <string.h> 
     14#include <stdlib.h> 
     15#include <syslog.h> 
     16#include <getopt.h> 
     17#include <iptables.h> 
     18#include <linux/netfilter_ipv4/ip_tables.h> 
     19#include <linux/netfilter_ipv4/ipt_random.h> 
     20 
     21/** 
     22 * The kernel random routing returns numbers between 0 and 255. 
     23 * To ease the task of the user in choosing the probability 
     24 * of matching, we want him to be able to use percentages. 
     25 * Therefore we have to accept numbers in percentage here, 
     26 * turn them into number between 0 and 255 for the kernel module, 
     27 * and turn them back to percentages when we print/save 
     28 * the rule. 
     29 */ 
     30 
     31 
     32/* Function which prints out usage message. */ 
     33static void 
     34help(void) 
     35{ 
     36        printf( 
     37"random v%s options:\n" 
     38"  [--average      percent ]    The probability in percentage of the match\n" 
     39"                               If ommited, a probability of 50%% percent is set.\n" 
     40"                               Percentage must be within : 1 <= percent <= 99.\n\n", 
     41IPTABLES_VERSION); 
     42} 
     43 
     44static struct option opts[] = { 
     45        { "average", 1, 0, '1' }, 
     46        { 0 } 
     47}; 
     48 
     49/* Initialize the target. */ 
     50static void 
     51init(struct ipt_entry_match *m, unsigned int *nfcache) 
     52{ 
     53        struct ipt_rand_info *randinfo = (struct ipt_rand_info *)(m)->data; 
     54 
     55        /* We assign the average to be 50 which is our default value */ 
     56        /* 50 * 2.55 = 128 */ 
     57        randinfo->average = 128; 
     58} 
     59 
     60#define IPT_RAND_OPT_AVERAGE    0x01 
     61 
     62/* Function which parses command options; returns true if it 
     63   ate an option */ 
     64static int 
     65parse(int c, char **argv, int invert, unsigned int *flags, 
     66      const struct ipt_entry *entry, 
     67      unsigned int *nfcache, 
     68      struct ipt_entry_match **match) 
     69{ 
     70        struct ipt_rand_info *randinfo = (struct ipt_rand_info *)(*match)->data; 
     71        unsigned int num; 
     72 
     73        switch (c) { 
     74        case '1': 
     75                /* check for common mistakes... */ 
     76                if (invert) 
     77                        exit_error(PARAMETER_PROBLEM, 
     78                                   "Can't specify ! --average"); 
     79                if (*flags & IPT_RAND_OPT_AVERAGE) 
     80                        exit_error(PARAMETER_PROBLEM, 
     81                                   "Can't specify --average twice"); 
     82 
     83                /* Remember, this function will interpret a leading 0 to be  
     84                   Octal, a leading 0x to be hexdecimal... */ 
     85                if (string_to_number(optarg, 1, 99, &num) == -1 || num < 1) 
     86                        exit_error(PARAMETER_PROBLEM, 
     87                                   "bad --average `%s', must be between 1 and 99", optarg); 
     88 
     89                /* assign the values */ 
     90                randinfo->average = (int)(num * 2.55); 
     91                *flags |= IPT_RAND_OPT_AVERAGE; 
     92                break; 
     93        default: 
     94                return 0; 
     95        } 
     96        return 1; 
     97} 
     98 
     99/* Final check; nothing. */ 
     100static void final_check(unsigned int flags) 
     101{ 
     102} 
     103 
     104/* Prints out the targinfo. */ 
     105static void 
     106print(const struct ipt_ip *ip, 
     107      const struct ipt_entry_match *match, 
     108      int numeric) 
     109{ 
     110        const struct ipt_rand_info *randinfo 
     111                = (const struct ipt_rand_info *)match->data; 
     112        div_t result = div((randinfo->average*100), 255); 
     113        if (result.rem > 127)  /* round up... */ 
     114                ++result.quot; 
     115 
     116        printf(" random %u%% ", result.quot); 
     117} 
     118 
     119/* Saves the union ipt_targinfo in parsable form to stdout. */ 
     120static void 
     121save(const struct ipt_ip *ip, const struct ipt_entry_match *match) 
     122{ 
     123        const struct ipt_rand_info *randinfo 
     124                = (const struct ipt_rand_info *)match->data; 
     125        div_t result = div((randinfo->average *100), 255); 
     126        if (result.rem > 127)  /* round up... */ 
     127                ++result.quot; 
     128 
     129        printf("--average %u ", result.quot); 
     130} 
     131 
     132struct iptables_match rand_match = {  
     133        .next           = NULL, 
     134        .name           = "random", 
     135        .version        = IPTABLES_VERSION, 
     136        .size           = IPT_ALIGN(sizeof(struct ipt_rand_info)), 
     137        .userspacesize  = IPT_ALIGN(sizeof(struct ipt_rand_info)), 
     138        .help           = &help, 
     139        .init           = &init, 
     140        .parse          = &parse, 
     141        .final_check    = &final_check, 
     142        .print          = &print, 
     143        .save           = &save, 
     144        .extra_opts     = opts 
     145}; 
     146 
     147void _init(void) 
     148{ 
     149        register_match(&rand_match); 
     150} 
  • extensions/libipt_random.man

    diff -urN iptables-1.3.8/extensions/libipt_random.man iptables-1.3.8.patched/extensions/libipt_random.man
    old new  
     1This module randomly matches a certain percentage of all packets. 
     2.TP 
     3.BI "--average " "percent" 
     4Matches the given percentage.  If omitted, a probability of 50% is set.