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

📄 rawtx.c.2

📁 实现一个网卡到内存空间的零拷贝程序
💻 2
字号:
/* *  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/init.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 <linux/if_ether.h>#include <linux/etherdevice.h>#include <asm/uaccess.h>#include "rawtx.h"#define MODNAME		"rawtx"#define __NR_invalid	0#define DEVICE_NAME	"eth0"extern void *sys_call_table[];struct net_device *dev;static void rawtx_skb_destructor(struct sk_buff *skb){	printk(KERN_NOTICE "releasing skb %p\n", skb);}static int do_raw_tx(unsigned char *usaddr, unsigned char *udaddr,                     void *buf, size_t len){	struct sk_buff *skb;	unsigned char saddr[6], daddr[6];	int err;	/* TODO: Check permissions */	/* Copy source and dest addresses */	if ( copy_from_user(saddr, usaddr, sizeof(saddr)) ||	     copy_from_user(daddr, udaddr, sizeof(daddr)) )		return -EFAULT;	/* Check packet length */	if (len >= dev->mtu)		return -EMSGSIZE;	/* Allocate sk_buff */	skb = alloc_skb(len + dev->hard_header_len + 15, GFP_KERNEL);	if (skb == NULL)		return -ENOBUFS;	printk(KERN_NOTICE "have skb\n");	skb->sk = NULL;		/* allowed ? */	skb->destructor = rawtx_skb_destructor;	skb_reserve(skb, dev->hard_header_len);	skb->priority = 0;	skb->dst = NULL;	/* allowed ? */	skb->dev = dev;	skb->protocol = htons(ETH_P_IP);	skb->ip_summed = CHECKSUM_NONE;	/* 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");	/* Add ethernet header */	err = dev->hard_header(skb, dev, ntohs(skb->protocol), daddr, saddr, len);	if (err < 0) {		kfree_skb(skb);		return err;	}	/* Send packet */	err = dev_queue_xmit(skb);	printk(KERN_NOTICE "packet sent\n");	return err;}static asmlinkage int sys_rawtx(unsigned char * saddr, unsigned char * daddr, void *buf, size_t len){	printk(KERN_NOTICE MODNAME ": sys_rawtx(%p, %p, %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;	}	dev = dev_get_by_name(DEVICE_NAME);	if (dev == NULL) {		printk(KERN_ERR ": ERROR: Cannot find device '%s'.\n", DEVICE_NAME);		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 + -