⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rawtx.c.1

📁 实现一个网卡到内存空间的零拷贝程序
💻 1
字号:
/* *  rawtx.c *  Joris van Rantwijk, May 2001. * *  Desperate attempt to implement a quick-and-dirty zero-copy *  networking interface in the Linux kernel. */#define __KERNEL__#define MODULE#include <linux/stddef.h>#include <linux/kernel.h>#include <linux/module.h>#include <linux/errno.h>#include <linux/types.h>#include <linux/skbuff.h>#include <linux/netdevice.h>#include <linux/ip.h>#include <linux/unistd.h>#include <net/route.h>#include <net/dst.h>#include <asm/uaccess.h>#include "rawtx.h"#define MODNAME		"rawtx"#define __NR_invalid	0#define PACKET_MAX_SIZE	1600extern void *sys_call_table[];static int do_raw_tx(u32 saddr, u32 daddr, void *buf, size_t len){	struct rtable *rt;	struct sk_buff *skb;	int hh_len, err;	/* TODO: Check permissions */	/* Check packet length */	if (len >= PACKET_MAX_SIZE)		return -EMSGSIZE;	/* Lookup routing table */	err = ip_route_output(&rt, daddr, saddr, 0, 0);	if (err)		goto out;	printk(KERN_NOTICE "done ip_route_output\n");	/* Allocate sk_buff */	hh_len = (rt->u.dst.dev->hard_header_len + 15) & ~15;	skb = alloc_skb(len+hh_len+15, GFP_KERNEL);	if (skb == NULL) {		err = -ENOBUFS;		goto out;	}	printk(KERN_NOTICE "have skb\n");	skb->sk = NULL;		/* allowed ? */	skb->destructor = NULL;	skb_reserve(skb, hh_len);	skb->priority = 0;	skb->dst = dst_clone(&rt->u.dst);	/* Copy user data */	skb->h.raw = skb_put(skb, len);	if (copy_from_user(skb->h.raw, buf, len)) {		kfree_skb(skb);		return -EFAULT;	}	printk(KERN_NOTICE "data copied\n");	/* Send packet */	err = skb->dst->output(skb);	if (err)		err = net_xmit_errno(err);	printk(KERN_NOTICE "packet sent\n");out:	ip_rt_put(rt);	return err;}static asmlinkage int sys_rawtx(u32 saddr, u32 daddr, void *buf, size_t len){	printk(KERN_NOTICE MODNAME ": sys_rawtx(%x, %x, %p, %u)\n", saddr, daddr, buf, len);	return do_raw_tx(saddr, daddr, buf, len);}int rawtx_init(void){	printk(KERN_INFO MODNAME ": Initializing module.\n");	if (sys_call_table[__NR_rawtx] != sys_call_table[__NR_invalid]) {		printk(KERN_ERR ": ERROR: systemcall %d already used.\n", __NR_rawtx);		return -EBUSY;	}	sys_call_table[__NR_rawtx] = sys_rawtx;	return 0;}void rawtx_cleanup(void){	printk(KERN_INFO MODNAME ": Removing module.\n");	if (sys_call_table[__NR_rawtx] == sys_rawtx)		sys_call_table[__NR_rawtx] = sys_call_table[__NR_invalid];}module_init(rawtx_init);module_exit(rawtx_cleanup);/* end */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -