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

📄 netiucv.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 4 页
字号:
	l = strlen(sbuf);	p = sbuf;	if (file->f_pos < l) {		p += file->f_pos;		l = strlen(p);		ret = (count > l) ? l : count;		if (copy_to_user(buf, p, ret))			return -EFAULT;	}	file->f_pos += ret;	return ret;}static struct file_operations netiucv_stat_fops = {	read:    netiucv_stat_read,	write:   netiucv_stat_write,	open:    netiucv_stat_open,	release: netiucv_stat_close,};static struct file_operations netiucv_buffer_fops = {	read:    netiucv_buffer_read,	write:   netiucv_buffer_write,	open:    netiucv_buffer_open,	release: netiucv_buffer_close,};static struct file_operations netiucv_user_fops = {	read:    netiucv_user_read,	write:   netiucv_user_write,	open:    netiucv_user_open,	release: netiucv_user_close,};static struct inode_operations netiucv_stat_iops = {#if LINUX_VERSION_CODE < 0x020363	default_file_ops: &netiucv_stat_fops#endif};static struct inode_operations netiucv_buffer_iops = {#if LINUX_VERSION_CODE < 0x020363	default_file_ops: &netiucv_buffer_fops#endif};static struct inode_operations netiucv_user_iops = {#if LINUX_VERSION_CODE < 0x020363	default_file_ops: &netiucv_user_fops#endif};static struct proc_dir_entry stat_entry = {	0,                           /* low_ino */	10,                          /* namelen */	"statistics",                /* name    */	S_IFREG | S_IRUGO | S_IWUSR, /* mode    */	1,                           /* nlink   */	0,                           /* uid     */	0,                           /* gid     */	0,                           /* size    */	&netiucv_stat_iops           /* ops     */};static struct proc_dir_entry buffer_entry = {	0,                           /* low_ino */	10,                          /* namelen */	"buffersize",                /* name    */	S_IFREG | S_IRUSR | S_IWUSR, /* mode    */	1,                           /* nlink   */	0,                           /* uid     */	0,                           /* gid     */	0,                           /* size    */	&netiucv_buffer_iops         /* ops     */};static struct proc_dir_entry user_entry = {	0,                           /* low_ino */	8,                           /* namelen */	"username",                  /* name    */	S_IFREG | S_IRUSR | S_IWUSR, /* mode    */	1,                           /* nlink   */	0,                           /* uid     */	0,                           /* gid     */	0,                           /* size    */	&netiucv_user_iops           /* ops     */};#if LINUX_VERSION_CODE < 0x020363static struct proc_dir_entry netiucv_dir = {	0,                           /* low_ino  */	4,                           /* namelen  */	"iucv",                      /* name     */	S_IFDIR | S_IRUGO | S_IXUGO, /* mode     */	2,                           /* nlink    */	0,                           /* uid      */	0,                           /* gid      */	0,                           /* size     */	0,                           /* ops      */	0,                           /* get_info */	netiucv_fill_inode           /* fill_ino (for locking) */};static struct proc_dir_entry netiucv_template ={	0,                           /* low_ino  */	0,                           /* namelen  */	"",                          /* name     */	S_IFDIR | S_IRUGO | S_IXUGO, /* mode     */	2,                           /* nlink    */	0,                           /* uid      */	0,                           /* gid      */	0,                           /* size     */	0,                           /* ops      */	0,                           /* get_info */	netiucv_fill_inode           /* fill_ino (for locking) */};#elsestatic struct proc_dir_entry *netiucv_dir = NULL;static struct proc_dir_entry *netiucv_template = NULL;#endif/** * Create the driver's main directory /proc/net/iucv */static voidnetiucv_proc_create_main(void){	/**	 * If not registered, register main proc dir-entry now	 */#if LINUX_VERSION_CODE > 0x020362	if (!netiucv_dir)		netiucv_dir = proc_mkdir("iucv", proc_net);#else	if (netiucv_dir.low_ino == 0)		proc_net_register(&netiucv_dir);#endif}#ifdef MODULE/** * Destroy /proc/net/iucv */static voidnetiucv_proc_destroy_main(void){#if LINUX_VERSION_CODE > 0x020362	remove_proc_entry("iucv", proc_net);#else	proc_net_unregister(netiucv_dir.low_ino);#endif}#endif MODULE/** * Create a device specific subdirectory in /proc/net/iucv/ with the * same name like the device. In that directory, create 3 entries * "statistics", "buffersize" and "username". * * @param dev The device for which the subdirectory should be created. * */static voidnetiucv_proc_create_sub(net_device *dev) {	netiucv_priv *privptr = dev->priv;#if LINUX_VERSION_CODE > 0x020362	privptr->proc_dentry = proc_mkdir(dev->name, netiucv_dir);	privptr->proc_stat_entry =		create_proc_entry("statistics",				  S_IFREG | S_IRUSR | S_IWUSR,				  privptr->proc_dentry);	privptr->proc_stat_entry->proc_fops = &netiucv_stat_fops;	privptr->proc_stat_entry->proc_iops = &netiucv_stat_iops;	privptr->proc_buffer_entry =		create_proc_entry("buffersize",				  S_IFREG | S_IRUSR | S_IWUSR,				  privptr->proc_dentry);	privptr->proc_buffer_entry->proc_fops = &netiucv_buffer_fops;	privptr->proc_buffer_entry->proc_iops = &netiucv_buffer_iops;	privptr->proc_user_entry =		create_proc_entry("username",				  S_IFREG | S_IRUSR | S_IWUSR,				  privptr->proc_dentry);	privptr->proc_user_entry->proc_fops = &netiucv_user_fops;	privptr->proc_user_entry->proc_iops = &netiucv_user_iops;#else	privptr->proc_dentry->name = dev->name;	privptr->proc_dentry->namelen = strlen(dev->name);	proc_register(&netiucv_dir, privptr->proc_dentry);	proc_register(privptr->proc_dentry, privptr->proc_stat_entry);	proc_register(privptr->proc_dentry, privptr->proc_buffer_entry);	proc_register(privptr->proc_dentry, privptr->proc_user_entry);#endif	privptr->proc_registered = 1;}/** * Destroy a device specific subdirectory. * * @param privptr Pointer to device private data. */static voidnetiucv_proc_destroy_sub(netiucv_priv *privptr) {	if (!privptr->proc_registered)		return;#if LINUX_VERSION_CODE > 0x020362	remove_proc_entry("statistics", privptr->proc_dentry);	remove_proc_entry("buffersize", privptr->proc_dentry);	remove_proc_entry("username", privptr->proc_dentry);	remove_proc_entry(privptr->proc_dentry->name, netiucv_dir);#else	proc_unregister(privptr->proc_dentry,			privptr->proc_stat_entry->low_ino);	proc_unregister(privptr->proc_dentry,			privptr->proc_buffer_entry->low_ino);	proc_unregister(privptr->proc_dentry,			privptr->proc_user_entry->low_ino);	proc_unregister(&netiucv_dir,			privptr->proc_dentry->low_ino);#endif	privptr->proc_registered = 0;}/** * Allocate and initialize a new connection structure. * Add it to the list of connections; */static iucv_connection *netiucv_new_connection(net_device *dev, char *username){	iucv_connection **clist = &connections;	iucv_connection *conn =		(iucv_connection *)kmalloc(sizeof(iucv_connection), GFP_KERNEL);	if (conn) {		memset(conn, 0, sizeof(iucv_connection));		skb_queue_head_init(&conn->collect_queue);		conn->max_buffsize = NETIUCV_BUFSIZE_DEFAULT;		conn->netdev = dev;		conn->rx_buff = alloc_skb(NETIUCV_BUFSIZE_DEFAULT, GFP_DMA);		if (!conn->rx_buff) {			kfree(conn);			return NULL;		}		conn->tx_buff = alloc_skb(NETIUCV_BUFSIZE_DEFAULT, GFP_DMA);		if (!conn->tx_buff) {			kfree_skb(conn->rx_buff);			kfree(conn);			return NULL;		}		conn->fsm = init_fsm("netiucvconn", conn_state_names,				     conn_event_names, NR_CONN_STATES,				     NR_CONN_EVENTS, conn_fsm, CONN_FSM_LEN,				     GFP_KERNEL);		if (!conn->fsm) {			kfree_skb(conn->tx_buff);			kfree_skb(conn->rx_buff);			kfree(conn);			return NULL;		}		fsm_settimer(conn->fsm, &conn->timer);		fsm_newstate(conn->fsm, CONN_STATE_INVALID);		if (username) {			memcpy(conn->userid, username, 9);			fsm_newstate(conn->fsm, CONN_STATE_STOPPED);		}		conn->next = *clist;		*clist = conn;	}	return conn;}/** * Release a connection structure and remove it from the * list of connections. */static voidnetiucv_remove_connection(iucv_connection *conn){	iucv_connection **clist = &connections;	if (conn == NULL)		return;	while (*clist) {		if (*clist == conn) {			*clist = conn->next;			if (conn->handle != 0) {				iucv_unregister_program(conn->handle);				conn->handle = 0;			}			fsm_deltimer(&conn->timer);			kfree_fsm(conn->fsm);			kfree_skb(conn->rx_buff);			kfree_skb(conn->tx_buff);			return;		}		clist = &((*clist)->next);	}}/** * Allocate and initialize everything of a net device. */static net_device *netiucv_init_netdevice(int ifno, char *username){	netiucv_priv *privptr;	int          priv_size;	net_device *dev = kmalloc(sizeof(net_device)#if LINUX_VERSION_CODE < 0x020300		      + 11 /* name + zero */#endif		      , GFP_KERNEL);	if (!dev)		return NULL;	memset(dev, 0, sizeof(net_device));#if LINUX_VERSION_CODE < 0x020300	dev->name = (char *)dev + sizeof(net_device);#endif	sprintf(dev->name, "iucv%d", ifno);	priv_size = sizeof(netiucv_priv) + sizeof(netiucv_template) +		sizeof(stat_entry) + sizeof(buffer_entry) + sizeof(user_entry);	dev->priv = kmalloc(priv_size, GFP_KERNEL);	if (dev->priv == NULL) {		kfree(dev);		return NULL;	}        memset(dev->priv, 0, priv_size);        privptr = (netiucv_priv *)dev->priv;        privptr->proc_dentry = (struct proc_dir_entry *)		(((char *)privptr) + sizeof(netiucv_priv));        privptr->proc_stat_entry = (struct proc_dir_entry *)		(((char *)privptr) + sizeof(netiucv_priv) +		 sizeof(netiucv_template));        privptr->proc_buffer_entry = (struct proc_dir_entry *)		(((char *)privptr) + sizeof(netiucv_priv) +		 sizeof(netiucv_template) + sizeof(stat_entry));        privptr->proc_user_entry = (struct proc_dir_entry *)		(((char *)privptr) + sizeof(netiucv_priv) +		 sizeof(netiucv_template) + sizeof(stat_entry) +		 sizeof(buffer_entry));	memcpy(privptr->proc_dentry, &netiucv_template,	       sizeof(netiucv_template));	memcpy(privptr->proc_stat_entry, &stat_entry, sizeof(stat_entry));	memcpy(privptr->proc_buffer_entry, &buffer_entry, sizeof(buffer_entry));	memcpy(privptr->proc_user_entry, &user_entry, sizeof(user_entry));	privptr->fsm = init_fsm("netiucvdev", dev_state_names,				dev_event_names, NR_DEV_STATES, NR_DEV_EVENTS,				dev_fsm, DEV_FSM_LEN, GFP_KERNEL);	if (privptr->fsm == NULL) {		kfree(privptr);		kfree(dev);		return NULL;	}	privptr->conn = netiucv_new_connection(dev, username);	if (!privptr->conn) {		kfree_fsm(privptr->fsm);		kfree(privptr);		kfree(dev);		return NULL;	}	fsm_newstate(privptr->fsm, DEV_STATE_STOPPED);	dev->mtu	         = NETIUCV_MTU_DEFAULT;	dev->hard_start_xmit     = netiucv_tx;	dev->open	         = netiucv_open;	dev->stop	         = netiucv_close;	dev->get_stats	         = netiucv_stats;	dev->change_mtu          = netiucv_change_mtu;	dev->hard_header_len     = NETIUCV_HDRLEN;	dev->addr_len            = 0;	dev->type                = ARPHRD_SLIP;	dev->tx_queue_len        = NETIUCV_QUEUELEN_DEFAULT;	dev_init_buffers(dev);	dev->flags	         = IFF_POINTOPOINT | IFF_NOARP;	return dev;}/** * Allocate and initialize everything of a net device. */static voidnetiucv_free_netdevice(net_device *dev){	netiucv_priv *privptr;	if (!dev)		return;	privptr = (netiucv_priv *)dev->priv;	if (privptr) {		if (privptr->conn)			netiucv_remove_connection(privptr->conn);		if (privptr->fsm)			kfree_fsm(privptr->fsm);		netiucv_proc_destroy_sub(privptr);		kfree(privptr);	}	kfree(dev);}static voidnetiucv_banner(void){	char vbuf[] = "$Revision: 1.16 $";	char *version = vbuf;	if ((version = strchr(version, ':'))) {		char *p = strchr(version + 1, '$');		if (p)			*p = '\0';	} else		version = " ??? ";	printk(KERN_INFO "NETIUCV driver Version%s initialized\n", version);}#ifndef MODULE# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0))#  define init_return(a) return astatic int __initiucv_setup(char *param)# else#  define init_return(a) return__initfunc (void iucv_setup(char *param, int *ints))# endif{	/**	* We do not parse parameters here because at the time of	* calling iucv_setup(), the kernel does not yet have	* memory management running. We delay this until probing	* is called.	*/	iucv = param;	init_return(1);}# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0))__setup ("iucv=", iucv_setup);# endif#elsestatic voidnetiucv_exit(void){	while (connections) {		net_device *dev = connections->netdev;		unregister_netdev(dev);		netiucv_free_netdevice(dev);	}	netiucv_proc_destroy_main();	printk(KERN_INFO "NETIUCV driver unloaded\n");	return;}#endifstatic intnetiucv_init(void){	char *p = iucv;	int ifno = 0;	int i = 0;	char username[10];	netiucv_proc_create_main();	while (p) {		if (isalnum(*p)) {			username[i++] = *p++;			username[i] = '\0';			if (i > 8) {				printk(KERN_WARNING				       "netiucv: Invalid user name '%s'\n",				       username);				while (*p && (*p != ':') && (*p != ','))					p++;			}		} else {			if (*p && (*p != ':') && (*p != ',')) {				printk(KERN_WARNING				       "netiucv: Invalid delimiter '%c'\n",				       *p);				while (*p && (*p != ':') && (*p != ','))					p++;			} else {				if (i) {					net_device *dev;					while (i < 9)						username[i++] = ' ';					username[9] = '\0';					dev = netiucv_init_netdevice(ifno,								     username);					if (!dev)						printk(KERN_WARNING						       "netiucv: Could not allocate network device structure for user '%s'\n", netiucv_printname(username));					else {						if (register_netdev(dev)) {							printk(KERN_WARNING							       "netiucv: Could not register '%s'\n", dev->name);							netiucv_free_netdevice(dev);						} else {							printk(KERN_INFO "%s: '%s'\n", dev->name, netiucv_printname(username));							netiucv_proc_create_sub(dev);							ifno++;						}					}										}				if (!(*p))					break;				i = 0;				p++;			}		}	}	netiucv_banner();	return 0;}#ifdef MODULEmodule_init(netiucv_init);module_exit(netiucv_exit);#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,12))MODULE_LICENSE("GPL");#endif#endif

⌨️ 快捷键说明

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