Re: protocol handler problem

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



(sorry for my bad english)
> I wrote a  packet handler like this ,The objective was to swap an ip with 
> another for a particular machine say 192.168.0.203 .
> cde is as
> 
> struct packet_type my_proto;
> my_proto.type=htons(ETH_P_ALL);
> my_proto.func = my_func;
> my_proto.data = NULL;
> my_proto.next = NULL;
> dev_add_pack(&my_proto);
this should work, ok

> can any body help me.
you should add some printk on "my_func", I've worked a lot of
time with devv_add_pack and other hack on the net/core/dev.c functions,
but is too much low level some time, some network driver don't fix pointer
on skb how other driver do, you shold work with netfilter module, give
few control of packet I/O but should be selected easy, and few packets
= few stress on your module.

if you want chanhe your source ip, man iptables should be helpful, with
SNAT (souce nat) with a simple command line you should change ip.

below I put one my old work for transparent spoofing, (using netfilter)
was never released because only one time finished module I've used
"man iptables" for know inutility of my work :) I didn't remember
what it do, and if have some but or not, but code is always reusable.
(it was one kernel module, with different setting at netfilter chain
is generated a spoofer module or a bouncer module, for close the 
triangle between source host - dest host and spoofed host).

for some other hack at dev_add_pack layer you should read:
http://www.phrack.org/show.php?p=55&a=12
http://www.s0ftpj.org/docs/OTUexplain.txt

on the fime some struct are change, how "struct device" now is 
"struct netdevice", grep on the kernel tree and guess the new name :)

(sorry for large cut/paste, but I don't remember if list support attach :)

-- Makefile --

all:	drang_spf.o drang_bnc.o bnc_ctl spoof_ctl errors love

drang_spf.o: drang_module.c
	@gcc -c -O6 -fomit-frame-pointer drang_module.c \
	-I/usr/src/linux/include -DDEV_NAME=\""drang\"" -DDEV_MAJ=195 \
	-DDEV_MIN=0 -DNFH="NF_IP_POST_ROUTING" -DSPOOFER 2>spf.errors

	@mv drang_module.o drang_spf.o

	@if [ ./drang_spf.o ] ; then \
		echo "spoofer compiled" ; \
	else \
		echo "spoofer don't compiled successiful, check spf.errors" ; \
	fi

drang_bnc.o: drang_module.c
	@gcc -c -O6 -fomit-frame-pointer drang_module.c \
	-I/usr/src/linux/include -DDEV_NAME=\""drang_bnc\"" -DDEV_MAJ=196 \
	-DDEV_MIN=0 -DNFH="NF_IP_LOCAL_IN" 2>bnc.errors

	@mv drang_module.o drang_bnc.o

	@if [ ./drang_bnc.o ] ; then \
		echo "bouncer compiled" ; \
	else \
		echo "bouncer don't compiled successiful, check bnc.errors" ; \
	fi

bnc_ctl: drang_ctl.c
	@gcc drang_ctl.c -Wall -O2 -o bnc_ctl \
	-DDEV_NAME=\""drang_bnc"\" -DDEV_MAJ=196 -DDEV_MIN=0 \
	-DHIDE_DEVICE
	@echo "bouncer client compiled"

spoof_ctl: drang_ctl.c
	@gcc drang_ctl.c -Wall -O2 -o spoof_ctl \
	-DDEV_NAME=\""drang"\" -DDEV_MAJ=195 -DDEV_MIN=0
	@echo "spoofer client compiled"

errors:

	@if [ ./spf.errors ] ; then touch spf.errors ; fi
	@if [ ./bnc.errors ] ; then touch bnc.errors ; fi

	@if test -z `head -1 ./spf.errors | awk {'print $$1'}` ; then \
		rm spf.errors; \
	else \
		echo -e "\t errors attempt on compiling drang_spf.o" ; \
		cat spf.errors ; \
	fi

	@if test -z `head -1 ./bnc.errors | awk {'print $$1'}` ; then \
		rm bnc.errors; \
	else \
		echo -e "\t errors attempt on compiling drang_bnc.o" ; \
		cat bnc.errors ; \
	fi

love:
	@echo "love is a curse"

clean:
	rm -rf drang_spf.o drang_bnc.o bnc_ctl spoof_ctl *.errors

-- EOF --

-- drang_module.c --

/*
 * Claudio - vecna@s0ftpj.org - 21/3/2001
 * 
 * drang_module.c -> module
 * drang_ctl.c -> control software
 * drang.h -> shared include
 *
 * Makefile -> :)
 *
 * this software was never released because iptables make the some
 * work better
 *
 */

#define __KERNEL__
#define MODULE

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/socket.h>
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/udp.h>
#include <net/tcp.h>
#include <linux/netdevice.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/version.h>
#include <linux/brlock.h>
#include <linux/fs.h>
#include <linux/devfs_fs_kernel.h>

/* internal function */
static drang_o(struct inode *, struct file *);
static drang_r(struct inode *, struct file *);
static drang_i(struct inode *, struct file *, unsigned int, unsigned long);
static unsigned int check_addr(struct sk_buff *);

static void tcpudp_csum(struct sk_buff *, unsigned int, unsigned int);

/* struct for ioctl */
#include "drang.h"

/* for device funct */
static devfs_handle_t drang_handle;
static struct file_operations drang_fops =
	{
	owner:          THIS_MODULE,
	ioctl:          drang_i,
	open:           drang_o,
	release:        drang_r,
	};

/* struct for memorize list of target/spoofed host */
static struct spf_d active[MAXSPF];
static int spf_d_len;

/* netfilter injection */
static struct nf_hook_ops drang;

static unsigned int drang__(	unsigned int hooknum,
				struct sk_buff **skb,
				const struct net_device *in,
				const struct net_device *out,
				int (*okfn)(struct sk_buff *))
	{
	unsigned int osaddr =(*skb)->nh.iph->saddr;
	unsigned int odaddr =(*skb)->nh.iph->daddr;
#ifdef SPOOFER
	unsigned int *addr_target =&((*skb)->nh.iph->saddr);
#else
	unsigned int *addr_target =&((*skb)->nh.iph->daddr);
#endif
	unsigned int fake =check_addr(*skb);

	if(!fake)
		return NF_ACCEPT;

	*addr_target =fake;

	(*skb)->nh.iph->check =0x0000;
	ip_send_check((*skb)->nh.iph);

	if((*skb)->nh.iph->protocol ==IPPROTO_ICMP)
		return NF_ACCEPT;

	/* build spoofed tcp check sum */
	tcpudp_csum((*skb), osaddr, odaddr);

	return NF_ACCEPT;	
	}

void tcpudp_csum(struct sk_buff *x, unsigned int osaddr, unsigned int odaddr)
	{
	struct iphdr *iph =x->nh.iph;
	unsigned short check =0x0000;

	switch(x->nh.iph->protocol)
		{
		unsigned short *cksum;

		case IPPROTO_TCP:
			cksum  =(unsigned short *)&((struct tcphdr *)
				(((char *)iph) +(iph->ihl<<2)))->check;
			check  =csum_tcpudp_magic(iph->saddr, iph->daddr, 
				0, IPPROTO_TCP, ~(*cksum));
			*cksum =csum_tcpudp_magic(~osaddr, ~odaddr, 0, 0, 
				~check);
			*cksum +=htons(IPPROTO_TCP);
			break;
		case IPPROTO_UDP:
			cksum  =(unsigned short *)&((struct udphdr*)
				(((char*)iph) +(iph->ihl<<2)))->check;
			if ((check = *cksum) != 0) 
				{
				check = csum_tcpudp_magic(iph->saddr, 
					iph->daddr, 0, 0, ~check);
				check = csum_tcpudp_magic(~osaddr, ~odaddr, 
					0, 0, ~check);
				check +=htons(IPPROTO_UDP);
				*cksum = check ? : 0xFFFF;
				}
			break;
		default:
			break;
		}
	}

int drang_o(struct inode *inode, struct file *file) { return(0); }
int drang_r(struct inode *inode, struct file *file) { return(0); }

int drang_i(struct inode *i, struct file *f, unsigned cmd, unsigned long arg)
	{
	struct spf_d t;
	int del_no;

	switch(cmd)
		{
	case ADD:
		if(spf_d_len ==(MAXSPF -1))
			return -(ENOMEM);

		__generic_copy_from_user(&t, (struct spf_d *)arg, sizeof(t));

		spf_d_len++;

		active[spf_d_len].old =t.old;
		active[spf_d_len].new =t.new;

		break;
	case DEL:
		if(!spf_d_len)
			return -EBADRQC;

		spf_d_len =0x0000;

		break;
	default:
		return -EINVAL;
		}

	return(0);
	}

init_module(void)
	{
	int ret;

	/* setting hook struct */
	drang.list.next =NULL;
	drang.list.prev =NULL;
	drang.hook =drang__;
	drang.pf =PF_INET;
	drang.hooknum =NFH;

	/* register /dev/drang for local module control */
	if(devfs_register_chrdev(DEV_MAJ ,DEV_NAME, &drang_fops))
		{
		printk(KERN_ERR "drang: unable to get major %d\n", DEV_MAJ);
		return -EIO;
		}
	drang_handle =devfs_mk_dir(NULL, DEV_NAME, NULL);
	devfs_register(	drang_handle, DEV_NAME, DEVFS_FL_DEFAULT,
			DEV_MAJ, 0, S_IFCHR|S_IRUSR|S_IWUSR, 
			&drang_fops, NULL);

	/* this is a printk */
	printk(KERN_INFO "loading module drang 0.1 by vecna@s0ftpj.org\n");

	/* add netfilter hook */
	if(ret =nf_register_hook(&drang))
		printk(KERN_ERR "unable to add netfilter hook\n");

	return ret;
	}

void cleanup_module(void)
	{
	nf_unregister_hook(&drang);
	devfs_unregister(drang_handle);
	devfs_unregister_chrdev(DEV_MAJ, DEV_NAME);

	printk(KERN_INFO "unloading drang 0.1 spoofing module\n");
	}

static unsigned int check_addr(struct sk_buff *skb)
	{
	register int x;

	for(x =0x0000;x <=spf_d_len; x++)
#ifdef SPOOFER
		if(skb->nh.iph->daddr ==active[x].old)
#else
		if(skb->nh.iph->saddr ==active[x].old)
#endif
			return(active[x].new);

	return(0);
	}

-- EOF --

-- drang_ctl.c --

/*
 * Claudio - vecna@s0ftpj.org - 21/3/2001
 * 
 * drang_module.c -> module
 * drang_ctl.c -> control software
 * drang.h -> shared include
 *
 * Makefile -> :)
 *
 * this software was never released because iptables make the some
 * work better
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

#include "drang.h"

unsigned int resolve(char *str)
	{
	struct hostent *he;
	unsigned int ret;

	if((ret =inet_addr(str))== -1)
		{
		if(!(he =gethostbyname(str)));
			{
			fprintf(stderr, "ignore %s hostname\n", str);
			return(0x0000);
			}

		memcpy((void *)&ret, (void *)&he->h_addr, he->h_length);
		}

	return ret;
	}

/*
 * trasparent spoofer/bounder ctl
 */
int main(int argc, char **argv)
	{
	extern int errno;
	int fd;
	struct spf_d inj ={ 0x0000, 0x0000 };
	void *data =NULL;
	u_char flag =0xAA;

	if(argc < 2 || (!strcmp(argv[1], "-h")))
		{
		printf( " %s [target ip, new ip, \"add\"][\"flush\"]\n",
			argv[0]);
		printf("eg. ~# h4x~# spoof_ctl target.com bnc.kr add\n");
		printf("eg. ~# h4x~# spoof_ctl flush\n");
		printf("eg. ~# bnc.kr~# bnc_ctl target.com real.it add\n");
		printf("eg. ~# bnc.kr~# bnc_ctl flush\n");
		printf(" target ip is ingoing packets for bouncer, outgoing"
			" for spoofer\n");
		return(EXIT_FAILURE);
		}

#ifdef HIDE_DEVICE
	/* if run on bnc mode special device doesn't appears usually */
	if(mknod(DEV_NAME, S_IFCHR|0600, makedev(DEV_MAJ, DEV_MIN)))
		return printf(" unable to make %s\n", DEV_NAME);
#endif

	if((fd =open(DEV_NAME, O_WRONLY)) ==-1)
		printf(" unable to open %s: %s\n", DEV_NAME, strerror(errno));

	if(argc == 4 && !strcmp(argv[3], "add"))
		{
		inj.old =resolve(argv[1]);
		inj.new =resolve(argv[2]);

		flag =ADD;
		data =(void *)&inj;
		}
	else if(!strcmp(argv[1], "flush"))
		flag =DEL;
	else
		printf(" I don't know what do you mean");

	if(ioctl(fd, flag, data) ==-1)
		printf(" error on ioctl: %s\n", strerror(errno));

	close(fd);

#ifdef HIDE_DEVICE
	unlink(DEV_NAME);
#endif

	return(EXIT_SUCCESS);
	}

-- EOF --

-- drang.h --

/*
 * Claudio - vecna@s0ftpj.org - 21/3/2001
 * 
 * drang_module.c -> module
 * drang_ctl.c -> control software
 * drang.h -> shared include
 *
 * Makefile -> :)
 *
 * this software was never released because iptables make the some
 * work better
 *
 */

#define ADD     0x00
#define DEL     0xFF

#define MAXSPF	10

struct spf_d
	{
	unsigned int old;
	unsigned int new;
	};

-- EOF --

Attachment: pgp00492.pgp
Description: PGP signature


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux