LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software > Linux - Kernel
User Name
Password
Linux - Kernel This forum is for all discussion relating to the Linux kernel.

Notices


Reply
  Search this Thread
Old 11-19-2009, 05:57 PM   #1
yaplej
Member
 
Registered: Apr 2009
Distribution: CentOS, Ubuntu, openSuSE
Posts: 165
Blog Entries: 1

Rep: Reputation: 22
Sending a spoofed IP from kernel module?


I am working on a module that detects dead sessions. To do that I need to send TCP keepalive messages to the client/server to determine if they are really dead or just idle.

I am not sure how to create a new packet though. Should I allocate a new sk_buff, or just just a normal buffer? After its allocated how do I send it out?

Thanks.
 
Old 11-20-2009, 09:32 PM   #2
yaplej
Member
 
Registered: Apr 2009
Distribution: CentOS, Ubuntu, openSuSE
Posts: 165

Original Poster
Blog Entries: 1

Rep: Reputation: 22
I was able to get it working, but its pretty rough stage. I hope to clean it up a little better, and make it look pretty. Also it needs a lot more error checking.

The source IP, source port, seq, destionation IP, destination port, and ack seq are all passed into the function. It allocates a new sk_buff, and starts populating the required data. The real trick is that you have to populate the skb->dst structure, and the skb->dev structure or the sk_buff will not send it will actually crash the system is my experiance.

To do that I used ip_route_input(). Only it requires an inbound device to calculate the route. I tried to find something that did not require a device to calculate the route, but could not find anything.

The second function is something I already had that could get a network device by name. I am already using the IP on this device in my module so I just save the device to a global pointer "struct net_device *device", and use this each time I send a keepalive to calculate the route.

This could be modified pretty easily to send TCP packets with data in them, but I just needed it to send keepalive messages.

Code:
void sendkeepalive
(__u32 saddr, __u16 source, __u32 seq,
__u32 daddr, __u16 dest, __u32 ack_seq
){
	struct sk_buff *skb = NULL;
	struct iphdr *iph = NULL;
	struct tcphdr *tcph = NULL;
	
	printk(KERN_ALERT "Device index: %u.\n",
		netdevice->ifindex);

	skb = alloc_skb(sizeof(struct iphdr) + sizeof(struct tcphdr), GFP_ATOMIC); // Allocate a new sk_buff with room for L2 header.
					 
	if (skb == NULL){
		return;
	}
	
	skb->protocol = __constant_htons(ETH_P_IP); // This is an IP packet.
	skb->pkt_type = PACKET_OUTGOING; // Its outgoing.
	skb->ip_summed = CHECKSUM_NONE; // No need to checksum.
	skb->nh.raw = skb->data; // Not sure if this is needed.
				 
	skb_reserve(skb, sizeof(struct iphdr) + sizeof(struct tcphdr)); // Reserve the space for the L3, and L4 headers.
	tcph = (struct tcphdr *)skb_push(skb, sizeof(struct tcphdr)); // Setup pointer for the L4 header.
	iph = (struct iphdr *)skb_push(skb, sizeof(struct iphdr)); // Setup pointer for the L3 header.
	
	iph->ihl = 5; // IP header length.
	iph->version = 4; // IPv4.
	iph->tos = 0; // No TOS.
	iph->tot_len=htons(sizeof(struct iphdr) + sizeof(struct tcphdr)); // L3 + L4 header length.
	iph->id = 0; // What?
	iph->frag_off = 0; // No fragmenting.
	iph->ttl = 64; // Set a TTL.
	iph->protocol = IPPROTO_TCP; // TCP protocol.
	iph->check = 0; // No IP checksum yet.
	iph->saddr = saddr; // Source IP.
	iph->daddr = daddr; // Dest IP.
		 
	tcph->check = 0; // No TCP checksum yet.
	tcph->source = source; // Source TCP Port.
	tcph->dest = dest; // Destination TCP Port.
	tcph->seq = htonl(seq - 1); // Current SEQ minus one is used for TCP keepalives.
	tcph->ack_seq = htonl( ack_seq - 1); // Ummm not sure yet.
	tcph->res1 = 0; // Not sure.
	tcph->doff = 5; // TCP Offset.  At least 5 if there are no TCP options.
	tcph->fin = 0; // FIN flag.
	tcph->syn = 0; // SYN flag.
	tcph->rst = 0; // RST flag.
	tcph->psh = 0; // PSH flag.
	tcph->ack = 1; // ACK flag.
	tcph->urg = 0; // URG flag.
	tcph->ece = 0; // ECE flag? It should be 0.
	tcph->cwr = 0; // CWR flag? It should be 0.

	ip_route_input(skb, daddr, saddr, iph->tos, netdevice); // Populate the skb->dst structure.
	ip_send_check(iph); // Calulcate an IP checksum.
	
	skb->dev = skb->dst->dev; // Populate skb->dev or it wont send.
	
	printk(KERN_ALERT "SKB device index: %u.\n",
		skb->dev->ifindex);
	
	printk(KERN_ALERT "Route device index: %u.\n",
		skb->dst->dev->ifindex);
	
	NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, skb->dst->dev, dst_output); // Sent the packet.
	return;
}


Code:
static inline void
getlocalIP(void){
	struct net_device *eth0;
	struct in_device *in_dev;
	struct in_ifaddr *if_addr;
	char dev_name[20];
	__u32 eth0IP;
	__u8 *addr;
	
	eth0IP = 0;

	sprintf(dev_name,"eth%d",0);
	eth0 = dev_get_by_name(dev_name);
	netdevice = eth0; // Sets the device used to send TCP keepalives.
	in_dev = (struct in_device *)eth0->ip_ptr;
	if_addr = in_dev->ifa_list;
	
	addr = (char *)&if_addr->ifa_local;

	eth0IP += (addr[0] << 24);
	eth0IP += (addr[1] << 16);
	eth0IP += (addr[2] << 8);
	eth0IP += addr[3];
	
	localIP = eth0IP;

	return;
}
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Can a kernel module call the function of another kernel module sceadu Programming 3 05-02-2011 02:22 AM
Compile and load kernel module automatically after boot? (Intel NIC module) touser Linux - Newbie 3 08-29-2009 08:45 PM
[Error] Kernel Module : No kernel module build environment saman007uk Debian 7 09-09-2006 06:34 PM
sending a packet to another machine from a kernel module. Sridhar Kumar K Linux - Networking 0 02-04-2005 12:37 AM
kernel module ignorant newbie looking for any one with kernel module knowledge cpoet Slackware 4 11-24-2003 09:37 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Software > Linux - Kernel

All times are GMT -5. The time now is 11:38 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration