示例#1
0
/*
 * We only need open() and close() routines.  open() calls socreate()
 * to allocate a "real" object behind the stream and mallocs some state
 * info for use by the svr4 emulator;  close() deallocates the state
 * information and passes the underlying object to the normal socket close
 * routine.
 */
static  int
streamsopen(struct cdev *dev, int oflags, int devtype, struct thread *td)
{
	struct filedesc *fdp;
	struct svr4_strm *st;
	struct socket *so;
	struct file *fp;
	int family, type, protocol;
	int error, fd;
	
	if (td->td_dupfd >= 0)
	  return ENODEV;

	switch (dev2unit(dev)) {
	case dev_udp:
	  family = AF_INET;
	  type = SOCK_DGRAM;
	  protocol = IPPROTO_UDP;
	  break;

	case dev_tcp:
	  family = AF_INET;
	  type = SOCK_STREAM;
	  protocol = IPPROTO_TCP;
	  break;

	case dev_ip:
	case dev_rawip:
	  family = AF_INET;
	  type = SOCK_RAW;
	  protocol = IPPROTO_IP;
	  break;

	case dev_icmp:
	  family = AF_INET;
	  type = SOCK_RAW;
	  protocol = IPPROTO_ICMP;
	  break;

	case dev_unix_dgram:
	  family = AF_LOCAL;
	  type = SOCK_DGRAM;
	  protocol = 0;
	  break;

	case dev_unix_stream:
	case dev_unix_ord_stream:
	  family = AF_LOCAL;
	  type = SOCK_STREAM;
	  protocol = 0;
	  break;

	case dev_ptm:
	  return svr4_ptm_alloc(td);

	default:
	  return EOPNOTSUPP;
	}

	fdp = td->td_proc->p_fd;
	if ((error = falloc(td, &fp, &fd, 0)) != 0)
	  return error;
	/* An extra reference on `fp' has been held for us by falloc(). */

	error = socreate(family, &so, type, protocol, td->td_ucred, td);
	if (error) {
	   fdclose(fdp, fp, fd, td);
	   fdrop(fp, td);
	   return error;
	}

	finit(fp, FREAD | FWRITE, DTYPE_SOCKET, so, &svr4_netops);

	/*
	 * Allocate a stream structure and attach it to this socket.
	 * We don't bother locking so_emuldata for SVR4 stream sockets as
	 * its value is constant for the lifetime of the stream once it
	 * is initialized here.
	 */
	st = malloc(sizeof(struct svr4_strm), M_TEMP, M_WAITOK);
	st->s_family = so->so_proto->pr_domain->dom_family;
	st->s_cmd = ~0;
	st->s_afd = -1;
	st->s_eventmask = 0;
	so->so_emuldata = st;

	fdrop(fp, td);
	td->td_dupfd = fd;
	return ENXIO;
}
示例#2
0
文件: streams.c 项目: MarginC/kame
/*
 * We only need open() and close() routines.  open() calls socreate()
 * to allocate a "real" object behind the stream and mallocs some state
 * info for use by the svr4 emulator;  close() deallocates the state
 * information and passes the underlying object to the normal socket close
 * routine.
 */
static  int
streamsopen(dev_t dev, int oflags, int devtype, struct thread *td)
{
	int type, protocol;
	int fd;
	struct file *fp;
	struct socket *so;
	int error;
	int family;
	struct proc *p = td->td_proc;
	
	PROC_LOCK(p);
	if (td->td_dupfd >= 0) {
	  PROC_UNLOCK(p);
	  return ENODEV;
	}
	PROC_UNLOCK(p);

	switch (minor(dev)) {
	case dev_udp:
	  family = AF_INET;
	  type = SOCK_DGRAM;
	  protocol = IPPROTO_UDP;
	  break;

	case dev_tcp:
	  family = AF_INET;
	  type = SOCK_STREAM;
	  protocol = IPPROTO_TCP;
	  break;

	case dev_ip:
	case dev_rawip:
	  family = AF_INET;
	  type = SOCK_RAW;
	  protocol = IPPROTO_IP;
	  break;

	case dev_icmp:
	  family = AF_INET;
	  type = SOCK_RAW;
	  protocol = IPPROTO_ICMP;
	  break;

	case dev_unix_dgram:
	  family = AF_LOCAL;
	  type = SOCK_DGRAM;
	  protocol = 0;
	  break;

	case dev_unix_stream:
	case dev_unix_ord_stream:
	  family = AF_LOCAL;
	  type = SOCK_STREAM;
	  protocol = 0;
	  break;

	case dev_ptm:
	  return svr4_ptm_alloc(td);

	default:
	  return EOPNOTSUPP;
	}

	if ((error = falloc(td, &fp, &fd)) != 0)
	  return error;

	if ((error = socreate(family, &so, type, protocol,
	    td->td_ucred, td)) != 0) {
	  FILEDESC_LOCK(p->p_fd);
	  p->p_fd->fd_ofiles[fd] = 0;
	  FILEDESC_UNLOCK(p->p_fd);
	  ffree(fp);
	  return error;
	}

	FILEDESC_LOCK(p->p_fd);
	fp->f_data = (caddr_t)so;
	fp->f_flag = FREAD|FWRITE;
	fp->f_ops = &svr4_netops;
	fp->f_type = DTYPE_SOCKET;
	FILEDESC_UNLOCK(p->p_fd);

	(void)svr4_stream_get(fp);
	PROC_LOCK(p);
	td->td_dupfd = fd;
	PROC_UNLOCK(p);
	return ENXIO;
}