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

📄 daemon_user.c

📁 linux-2.6.15.6
💻 C
字号:
/* * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and  * James Leu (jleu@mindspring.net). * Copyright (C) 2001 by various other people who didn't put their name here. * Licensed under the GPL. */#include <errno.h>#include <unistd.h>#include <stdint.h>#include <sys/socket.h>#include <sys/un.h>#include <sys/time.h>#include "net_user.h"#include "daemon.h"#include "kern_util.h"#include "user_util.h"#include "user.h"#include "os.h"#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)enum request_type { REQ_NEW_CONTROL };#define SWITCH_MAGIC 0xfeedfacestruct request_v3 {	uint32_t magic;	uint32_t version;	enum request_type type;	struct sockaddr_un sock;};static struct sockaddr_un *new_addr(void *name, int len){	struct sockaddr_un *sun;	sun = um_kmalloc(sizeof(struct sockaddr_un));	if(sun == NULL){		printk("new_addr: allocation of sockaddr_un failed\n");		return(NULL);	}	sun->sun_family = AF_UNIX;	memcpy(sun->sun_path, name, len);	return(sun);}static int connect_to_switch(struct daemon_data *pri){	struct sockaddr_un *ctl_addr = pri->ctl_addr;	struct sockaddr_un *local_addr = pri->local_addr;	struct sockaddr_un *sun;	struct request_v3 req;	int fd, n, err;	pri->control = socket(AF_UNIX, SOCK_STREAM, 0);	if(pri->control < 0){		printk("daemon_open : control socket failed, errno = %d\n", 		       errno);				return(-errno);	}	if(connect(pri->control, (struct sockaddr *) ctl_addr, 		   sizeof(*ctl_addr)) < 0){		printk("daemon_open : control connect failed, errno = %d\n",		       errno);		err = -errno;		goto out;	}	fd = socket(AF_UNIX, SOCK_DGRAM, 0);	if(fd < 0){		printk("daemon_open : data socket failed, errno = %d\n", 		       errno);		err = -errno;		goto out;	}	if(bind(fd, (struct sockaddr *) local_addr, sizeof(*local_addr)) < 0){		printk("daemon_open : data bind failed, errno = %d\n", 		       errno);		err = -errno;		goto out_close;	}	sun = um_kmalloc(sizeof(struct sockaddr_un));	if(sun == NULL){		printk("new_addr: allocation of sockaddr_un failed\n");		err = -ENOMEM;		goto out_close;	}	req.magic = SWITCH_MAGIC;	req.version = SWITCH_VERSION;	req.type = REQ_NEW_CONTROL;	req.sock = *local_addr;	n = os_write_file(pri->control, &req, sizeof(req));	if(n != sizeof(req)){		printk("daemon_open : control setup request failed, err = %d\n",		       -n);		err = -ENOTCONN;		goto out_free;	}	n = os_read_file(pri->control, sun, sizeof(*sun));	if(n != sizeof(*sun)){		printk("daemon_open : read of data socket failed, err = %d\n",		       -n);		err = -ENOTCONN;		goto out_free;	}	pri->data_addr = sun;	return(fd); out_free:	kfree(sun); out_close:	os_close_file(fd); out:	os_close_file(pri->control);	return(err);}static void daemon_user_init(void *data, void *dev){	struct daemon_data *pri = data;	struct timeval tv;	struct {		char zero;		int pid;		int usecs;	} name;	if(!strcmp(pri->sock_type, "unix"))		pri->ctl_addr = new_addr(pri->ctl_sock, 					 strlen(pri->ctl_sock) + 1);	name.zero = 0;	name.pid = os_getpid();	gettimeofday(&tv, NULL);	name.usecs = tv.tv_usec;	pri->local_addr = new_addr(&name, sizeof(name));	pri->dev = dev;	pri->fd = connect_to_switch(pri);	if(pri->fd < 0){		kfree(pri->local_addr);		pri->local_addr = NULL;	}}static int daemon_open(void *data){	struct daemon_data *pri = data;	return(pri->fd);}static void daemon_remove(void *data){	struct daemon_data *pri = data;	os_close_file(pri->fd);	os_close_file(pri->control);	kfree(pri->data_addr);	kfree(pri->ctl_addr);	kfree(pri->local_addr);}int daemon_user_write(int fd, void *buf, int len, struct daemon_data *pri){	struct sockaddr_un *data_addr = pri->data_addr;	return(net_sendto(fd, buf, len, data_addr, sizeof(*data_addr)));}static int daemon_set_mtu(int mtu, void *data){	return(mtu);}struct net_user_info daemon_user_info = {	.init		= daemon_user_init,	.open		= daemon_open,	.close	 	= NULL,	.remove	 	= daemon_remove,	.set_mtu	= daemon_set_mtu,	.add_address	= NULL,	.delete_address = NULL,	.max_packet	= MAX_PACKET - ETH_HEADER_OTHER};/* * Overrides for Emacs so that we follow Linus's tabbing style. * Emacs will notice this stuff at the end of the file and automatically * adjust the settings for this buffer only.  This must remain at the end * of the file. * --------------------------------------------------------------------------- * Local variables: * c-file-style: "linux" * End: */

⌨️ 快捷键说明

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