On Wednesday 17 April 2002 15:20, Harald Welte wrote: > please feel free to provide us with an implementation that is > fullfilling the above requirements. The current mport.patch in > patch-o-matic doesn't.
And suddenly it's done ;-) I've extended the existing multiport module to support the mport patch semantic. Therefore I've had to change the size of the ipt_mulitport struct, so the new multiport module will only work with the new userspace library, because the module checks the size of the struct. The code compiles and is tested (and unexpectedly it works ;-), so it should be ready for inclusion, if the kernel multiport code hasn't changed between Linux 2.4.9 and the latest version. These patches attached below also obsoletes all mport code. Have a nice day Norbert diff -ru linux-2.4.9-13.orig/include/linux/netfilter_ipv4/ipt_multiport.h linux-2.4.9-13/include/linux/netfilter_ipv4/ipt_multiport.h --- linux-2.4.9-13.orig/include/linux/netfilter_ipv4/ipt_multiport.h Wed Apr 17 22:15:18 2002 +++ linux-2.4.9-13/include/linux/netfilter_ipv4/ipt_multiport.h Wed Apr 17 22:21:06 +2002 @@ -11,11 +11,12 @@ #define IPT_MULTI_PORTS 15 -/* Must fit inside union ipt_matchinfo: 16 bytes */ +/* Carries up to IPT_MULTI_PORTS port ranges */ struct ipt_multiport { u_int8_t flags; /* Type of comparison */ - u_int8_t count; /* Number of ports */ - u_int16_t ports[IPT_MULTI_PORTS]; /* Ports */ + u_int8_t count; /* Number of port ranges */ + u_int16_t ports[IPT_MULTI_PORTS]; /* Port range begin */ + u_int16_t tports[IPT_MULTI_PORTS]; /* Port range end */ }; #endif /*_IPT_MULTIPORT_H*/ diff -ru linux-2.4.9-13.orig/net/ipv4/netfilter/ipt_multiport.c linux-2.4.9-13/net/ipv4/netfilter/ipt_multiport.c --- linux-2.4.9-13.orig/net/ipv4/netfilter/ipt_multiport.c Wed Apr 17 22:16:00 2002 +++ linux-2.4.9-13/net/ipv4/netfilter/ipt_multiport.c Wed Apr 17 22:17:19 2002 @@ -16,17 +16,20 @@ /* Returns 1 if the port is matched by the test, 0 otherwise. */ static inline int -ports_match(const u_int16_t *portlist, enum ipt_multiport_flags flags, - u_int8_t count, u_int16_t src, u_int16_t dst) +ports_match(enum ipt_multiport_flags flags, u_int8_t count, + const u_int16_t range_begin[], const u_int16_t range_end[], + u_int16_t src, u_int16_t dst) { unsigned int i; for (i=0; i<count; i++) { if (flags != IPT_MULTIPORT_DESTINATION - && portlist[i] == src) + && src >= range_begin[i] + && src <= range_end[i]) return 1; if (flags != IPT_MULTIPORT_SOURCE - && portlist[i] == dst) + && dst >= range_begin[i] + && dst <= range_end[i]) return 1; } @@ -58,8 +61,8 @@ /* Must not be a fragment. */ return !offset - && ports_match(multiinfo->ports, - multiinfo->flags, multiinfo->count, + && ports_match(multiinfo->flags, multiinfo->count, + multiinfo->ports, multiinfo->tports, ntohs(udp->source), ntohs(udp->dest)); } diff -ru iptables-1.2.6a.orig/extensions/libipt_multiport.c iptables-1.2.6a/extensions/libipt_multiport.c --- iptables-1.2.6a.orig/extensions/libipt_multiport.c Mon Aug 6 20:50:22 2001 +++ iptables-1.2.6a/extensions/libipt_multiport.c Wed Apr 17 21:40:30 2002 @@ -13,13 +13,13 @@ { printf( "multiport v%s options:\n" -" --source-ports port[,port,port...]\n" +" --source-ports port[,port:port,port...]\n" " --sports ...\n" " match source port(s)\n" -" --destination-ports port[,port,port...]\n" +" --destination-ports port[,port:port,port...]\n" " --dports ...\n" " match destination port(s)\n" -" --ports port[,port,port]\n" +" --ports port[,port:port,port]\n" " match both source and destination port(s)\n", NETFILTER_VERSION); } @@ -58,9 +58,10 @@ } static unsigned int -parse_multi_ports(const char *portstring, u_int16_t *ports, const char *proto) +parse_multi_ports(const char *portstring, const char *proto, + u_int16_t range_begin[], u_int16_t range_end[]) { - char *buffer, *cp, *next; + char *buffer, *cp, *next, *range; unsigned int i; buffer = strdup(portstring); @@ -70,7 +71,16 @@ { next=strchr(cp, ','); if (next) *next++='\0'; - ports[i] = parse_port(cp, proto); + + range = strchr(cp, ':'); + if (range) *range++ = '\0'; + + range_begin[i] = parse_port(cp, proto); + if (range) { + range_end[i] = parse_port(range, proto); + } else { + range_end[i] = range_begin[i]; + } } if (cp) exit_error(PARAMETER_PROBLEM, "too many ports specified"); free(buffer); @@ -113,24 +123,24 @@ switch (c) { case '1': proto = check_proto(entry); - multiinfo->count = parse_multi_ports(argv[optind-1], - multiinfo->ports, proto); + multiinfo->count = parse_multi_ports(argv[optind-1], proto, + multiinfo->ports, +multiinfo->tports); multiinfo->flags = IPT_MULTIPORT_SOURCE; *nfcache |= NFC_IP_SRC_PT; break; case '2': proto = check_proto(entry); - multiinfo->count = parse_multi_ports(argv[optind-1], - multiinfo->ports, proto); + multiinfo->count = parse_multi_ports(argv[optind-1], proto, + multiinfo->ports, +multiinfo->tports); multiinfo->flags = IPT_MULTIPORT_DESTINATION; *nfcache |= NFC_IP_DST_PT; break; case '3': proto = check_proto(entry); - multiinfo->count = parse_multi_ports(argv[optind-1], - multiinfo->ports, proto); + multiinfo->count = parse_multi_ports(argv[optind-1], proto, + multiinfo->ports, +multiinfo->tports); multiinfo->flags = IPT_MULTIPORT_EITHER; *nfcache |= NFC_IP_SRC_PT | NFC_IP_DST_PT; break; @@ -210,6 +220,10 @@ for (i=0; i < multiinfo->count; i++) { printf("%s", i ? "," : ""); print_port(multiinfo->ports[i], ip->proto, numeric); + if (multiinfo->ports[i] != multiinfo->tports[i]) { + printf(":"); + print_port(multiinfo->tports[i], ip->proto, numeric); + } } printf(" "); } @@ -238,6 +252,10 @@ for (i=0; i < multiinfo->count; i++) { printf("%s", i ? "," : ""); print_port(multiinfo->ports[i], ip->proto, 0); + if (multiinfo->ports[i] != multiinfo->tports[i]) { + printf(":"); + print_port(multiinfo->tports[i], ip->proto, 0); + } } printf(" "); }