patch-2.3.99-pre2 linux/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
Next file: linux/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
Previous file: linux/net/ipv4/netfilter/ip_conntrack_proto_generic.c
Back to the patch index
Back to the overall index
- Lines: 112
- Date:
Fri Mar 17 10:56:20 2000
- Orig file:
v2.3.99-pre1/linux/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
- Orig date:
Wed Dec 31 16:00:00 1969
diff -u --recursive --new-file v2.3.99-pre1/linux/net/ipv4/netfilter/ip_conntrack_proto_icmp.c linux/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
@@ -0,0 +1,111 @@
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/netfilter.h>
+#include <linux/icmp.h>
+#include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
+
+#define ICMP_TIMEOUT (30*HZ)
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(format, args...)
+#endif
+
+static int icmp_pkt_to_tuple(const void *datah, size_t datalen,
+ struct ip_conntrack_tuple *tuple)
+{
+ const struct icmphdr *hdr = datah;
+
+ tuple->dst.u.icmp.type = hdr->type;
+ tuple->src.u.icmp.id = hdr->un.echo.id;
+ tuple->dst.u.icmp.code = hdr->code;
+
+ return 1;
+}
+
+static int icmp_invert_tuple(struct ip_conntrack_tuple *tuple,
+ const struct ip_conntrack_tuple *orig)
+{
+ /* Add 1; spaces filled with 0. */
+ static u_int8_t invmap[]
+ = { [ICMP_ECHO] = ICMP_ECHOREPLY + 1,
+ [ICMP_ECHOREPLY] = ICMP_ECHO + 1,
+ [ICMP_TIMESTAMP] = ICMP_TIMESTAMPREPLY + 1,
+ [ICMP_TIMESTAMPREPLY] = ICMP_TIMESTAMP + 1,
+ [ICMP_INFO_REQUEST] = ICMP_INFO_REPLY + 1,
+ [ICMP_INFO_REPLY] = ICMP_INFO_REQUEST + 1,
+ [ICMP_ADDRESS] = ICMP_ADDRESSREPLY + 1,
+ [ICMP_ADDRESSREPLY] = ICMP_ADDRESS + 1};
+
+ if (orig->dst.u.icmp.type >= sizeof(invmap)
+ || !invmap[orig->dst.u.icmp.type])
+ return 0;
+
+ tuple->src.u.icmp.id = orig->src.u.icmp.id;
+ tuple->dst.u.icmp.type = invmap[orig->dst.u.icmp.type] - 1;
+ tuple->dst.u.icmp.code = orig->dst.u.icmp.code;
+ return 1;
+}
+
+/* Print out the per-protocol part of the tuple. */
+static unsigned int icmp_print_tuple(char *buffer,
+ const struct ip_conntrack_tuple *tuple)
+{
+ return sprintf(buffer, "type=%u code=%u id=%u ",
+ tuple->dst.u.icmp.type,
+ tuple->dst.u.icmp.code,
+ ntohs(tuple->src.u.icmp.id));
+}
+
+/* Print out the private part of the conntrack. */
+static unsigned int icmp_print_conntrack(char *buffer,
+ const struct ip_conntrack *conntrack)
+{
+ return 0;
+}
+
+/* Returns verdict for packet, or -1 for invalid. */
+static int icmp_packet(struct ip_conntrack *ct,
+ struct iphdr *iph, size_t len,
+ enum ip_conntrack_info ctinfo)
+{
+ /* FIXME: Should keep count of orig - reply packets: if == 0,
+ destroy --RR */
+ /* Delete connection immediately on reply: won't actually
+ vanish as we still have skb */
+ if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) {
+ if (del_timer(&ct->timeout))
+ ct->timeout.function((unsigned long)ct);
+ } else
+ ip_ct_refresh(ct, ICMP_TIMEOUT);
+
+ return NF_ACCEPT;
+}
+
+/* Called when a new connection for this protocol found. */
+static int icmp_new(struct ip_conntrack *conntrack,
+ struct iphdr *iph, size_t len)
+{
+ static u_int8_t valid_new[]
+ = { [ICMP_ECHO] = 1,
+ [ICMP_TIMESTAMP] = 1,
+ [ICMP_INFO_REQUEST] = 1,
+ [ICMP_ADDRESS] = 1 };
+
+ if (conntrack->tuplehash[0].tuple.dst.u.icmp.type >= sizeof(valid_new)
+ || !valid_new[conntrack->tuplehash[0].tuple.dst.u.icmp.type]) {
+ /* Can't create a new ICMP `conn' with this. */
+ DEBUGP("icmp: can't create new conn with type %u\n",
+ conntrack->tuplehash[0].tuple.dst.u.icmp.type);
+ DUMP_TUPLE(&conntrack->tuplehash[0].tuple);
+ return 0;
+ }
+ return 1;
+}
+
+struct ip_conntrack_protocol ip_conntrack_protocol_icmp
+= { { NULL, NULL }, IPPROTO_ICMP, "icmp",
+ icmp_pkt_to_tuple, icmp_invert_tuple, icmp_print_tuple,
+ icmp_print_conntrack, icmp_packet, icmp_new, NULL };
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)