Netfilter: Extending iptables

/*
 * This is a module which is used for rejecting packets.  Simply sends
 * back an icmp host unreachable and drops the packet
 */
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <net/icmp.h>
#include "packet-filter/kernel/ip_tables.h"

struct in_device;
#include <net/route.h>

static int ipt_reject_target(struct sk_buff *skb,
			     const char *indev,
			     const char *outdev,
			     const union ipt_targinfo *info,
			     unsigned int pos)
{
	struct iphdr *iph = skb->nh.iph;
	/* Alexey says:
	 *
	 * Generally, routing is THE FIRST thing to make, when packet
	 * enters IP stack. Before packet is routed you cannot call
	 * any service routines from IP stack.
	 */
	if (skb->dst != NULL
	    || ip_route_input(skb, iph->daddr, iph->saddr, iph->tos,
			      dev_get_by_name(indev)) == 0)
		icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);

	return -NF_DROP - 1;
}

static int ipt_reject_checkentry(const union ipt_targinfo *info,
				 unsigned int pos,
				 unsigned int finalpos)
{
    return 1;
}

static struct ipt_target ipt_reject_reg
= { { NULL, NULL }, "REJECT", ipt_reject_target, ipt_reject_checkentry, NULL,
    &__this_module };

int init_module(void)
{
    if (ipt_register_target(&ipt_reject_reg))
	return -EINVAL;

    return 0;
}

void cleanup_module(void)
{
    ipt_unregister_target(&ipt_reject_reg);
}

Connection Tracking...