diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-06-19 22:45:37 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-06-19 22:45:37 +0000 |
commit | 6d403070f28cd44860fdb3a53be5da0275c65cf4 (patch) | |
tree | 0d0e7fe7b5fb7568d19e11d7d862b77a866ce081 /net/ipv6 | |
parent | ecf1bf5f6c2e668d03b0a9fb026db7aa41e292e1 (diff) |
Merge with 2.4.0-test1-ac21 + pile of MIPS cleanups to make merging
possible. Chainsawed RM200 kernel to compile again. Jazz machine
status unknown.
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/netfilter/ip6_tables.c | 11 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6t_mac.c | 62 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6t_multiport.c | 101 |
3 files changed, 168 insertions, 6 deletions
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 2d9c356e9..dea475feb 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -736,7 +736,7 @@ check_entry(struct ip6t_entry *e, const char *name, unsigned int size, target = find_target_lock(t->u.user.name, &ret, &ip6t_mutex); if (!target) { // duprintf("check_entry: `%s' not found\n", t->u.name); - return ret; + goto cleanup_matches; } if (target->me) __MOD_INC_USE_COUNT(target->me); @@ -1342,9 +1342,10 @@ ip6t_register_target(struct ip6t_target *target) MOD_INC_USE_COUNT; ret = down_interruptible(&ip6t_mutex); - if (ret != 0) + if (ret != 0) { + MOD_DEC_USE_COUNT; return ret; - + } if (!list_named_insert(&ip6t_target, target)) { duprintf("ip6t_register_target: `%s' already in list!\n", target->name); @@ -1375,9 +1376,7 @@ ip6t_register_match(struct ip6t_match *match) MOD_DEC_USE_COUNT; return ret; } - if (list_named_insert(&ip6t_match, match)) { - ret = 0; - } else { + if (!list_named_insert(&ip6t_match, match)) { duprintf("ip6t_register_match: `%s' already in list!\n", match->name); MOD_DEC_USE_COUNT; diff --git a/net/ipv6/netfilter/ip6t_mac.c b/net/ipv6/netfilter/ip6t_mac.c new file mode 100644 index 000000000..c0e403b50 --- /dev/null +++ b/net/ipv6/netfilter/ip6t_mac.c @@ -0,0 +1,62 @@ +/* Kernel module to match MAC address parameters. */ +#include <linux/module.h> +#include <linux/skbuff.h> +#include <linux/if_ether.h> + +#include <linux/netfilter_ipv6/ip6t_mac.h> +#include <linux/netfilter_ipv6/ip6_tables.h> + +static int +match(const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const void *matchinfo, + int offset, + const void *hdr, + u_int16_t datalen, + int *hotdrop) +{ + const struct ip6t_mac_info *info = matchinfo; + + /* Is mac pointer valid? */ + return (skb->mac.raw >= skb->head + && skb->mac.raw < skb->head + skb->len - ETH_HLEN + /* If so, compare... */ + && ((memcmp(skb->mac.ethernet->h_source, info->srcaddr, ETH_ALEN) + == 0) ^ info->invert)); +} + +static int +ipt_mac_checkentry(const char *tablename, + const struct ip6t_ip6 *ip, + void *matchinfo, + unsigned int matchsize, + unsigned int hook_mask) +{ + if (hook_mask + & ~((1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_IN))) { + printk("ipt_mac: only valid for PRE_ROUTING or LOCAL_IN.\n"); + return 0; + } + + if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_mac_info))) + return 0; + + return 1; +} + +static struct ip6t_match mac_match += { { NULL, NULL }, "mac", &match, &ipt_mac_checkentry, NULL, THIS_MODULE }; + +static int __init init(void) +{ + return ip6t_register_match(&mac_match); +} + +static void __exit fini(void) +{ + ip6t_unregister_match(&mac_match); +} + +module_init(init); +module_exit(fini); diff --git a/net/ipv6/netfilter/ip6t_multiport.c b/net/ipv6/netfilter/ip6t_multiport.c new file mode 100644 index 000000000..5f2902e3b --- /dev/null +++ b/net/ipv6/netfilter/ip6t_multiport.c @@ -0,0 +1,101 @@ +/* Kernel module to match one of a list of TCP/UDP ports: ports are in + the same place so we can treat them as equal. */ +#include <linux/module.h> +#include <linux/types.h> +#include <linux/udp.h> +#include <linux/skbuff.h> +#include <linux/in.h> + +#include <linux/netfilter_ipv6/ip6t_multiport.h> +#include <linux/netfilter_ipv6/ip6_tables.h> + +#if 0 +#define duprintf(format, args...) printk(format , ## args) +#else +#define duprintf(format, args...) +#endif + +/* Returns 1 if the port is matched by the test, 0 otherwise. */ +static inline int +ports_match(const u_int16_t *portlist, enum ip6t_multiport_flags flags, + u_int8_t count, u_int16_t src, u_int16_t dst) +{ + unsigned int i; + for (i=0; i<count; i++) { + if (flags != IP6T_MULTIPORT_DESTINATION + && portlist[i] == src) + return 1; + + if (flags != IP6T_MULTIPORT_SOURCE + && portlist[i] == dst) + return 1; + } + + return 0; +} + +static int +match(const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const void *matchinfo, + int offset, + const void *hdr, + u_int16_t datalen, + int *hotdrop) +{ + const struct udphdr *udp = hdr; + const struct ip6t_multiport *multiinfo = matchinfo; + + /* Must be big enough to read ports. */ + if (offset == 0 && datalen < sizeof(struct udphdr)) { + /* We've been asked to examine this packet, and we + can't. Hence, no choice but to drop. */ + duprintf("ipt_multiport:" + " Dropping evil offset=0 tinygram.\n"); + *hotdrop = 1; + return 0; + } + + /* Must not be a fragment. */ + return !offset + && ports_match(multiinfo->ports, + multiinfo->flags, multiinfo->count, + ntohs(udp->source), ntohs(udp->dest)); +} + +/* Called when user tries to insert an entry of this type. */ +static int +checkentry(const char *tablename, + const struct ip6t_ip6 *ip, + void *matchinfo, + unsigned int matchsize, + unsigned int hook_mask) +{ + const struct ip6t_multiport *multiinfo = matchinfo; + + /* Must specify proto == TCP/UDP, no unknown flags or bad count */ + return (ip->proto == IPPROTO_TCP || ip->proto == IPPROTO_UDP) + && !(ip->flags & IP6T_INV_PROTO) + && matchsize == IP6T_ALIGN(sizeof(struct ip6t_multiport)) + && (multiinfo->flags == IP6T_MULTIPORT_SOURCE + || multiinfo->flags == IP6T_MULTIPORT_DESTINATION + || multiinfo->flags == IP6T_MULTIPORT_EITHER) + && multiinfo->count <= IP6T_MULTI_PORTS; +} + +static struct ip6t_match multiport_match += { { NULL, NULL }, "multiport", &match, &checkentry, NULL, THIS_MODULE }; + +static int __init init(void) +{ + return ip6t_register_match(&multiport_match); +} + +static void __exit fini(void) +{ + ip6t_unregister_match(&multiport_match); +} + +module_init(init); +module_exit(fini); |