예제 #1
0
struct protosw *  
pffindproto(int domain, int protocol, int type)
{
#ifdef IP_RAW
   if (type == SOCK_RAW)
      return(pffindtype(domain, type));
#endif

   switch (protocol)
   {
#ifdef BSD_SOCKETS
   case IPPROTO_TCP:
      if (type == SOCK_STREAM)
         break;
      /* IPPROTO_TCP protocol on non-SOCK_STREAM type socket */
      dtrap();
      return NULL;
   case IPPROTO_UDP:
      if (type == SOCK_DGRAM)
         break;
      /* IPPROTO_UDP protocol on non-SOCK_DGRAM type socket */
      dtrap();
      return NULL;
#endif /* BSD_SOCKETS */
   case 0:
      /* let protocol default based on socket type */
      break;
   default:
      /* unknown/unsupported protocol on socket */
      dtrap();
      return NULL;
   }
   return(pffindtype(domain, type));   /* map to findtype */
}
예제 #2
0
struct socket *   
socreate (int dom, int type, int proto)
{
   struct protosw *prp;
   struct socket *so;
   int   error;
   int rc;

   if (proto)
      prp = pffindproto(dom, proto, type);
   else
      prp = pffindtype(dom, type);
   if (prp == 0)
      return NULL;
   if (prp->pr_type != type)
      return NULL;
   if ((so = SOC_ALLOC (sizeof (*so))) == NULL)
      return NULL;
   so->next = NULL;
   putq(&soq,(qp)so);

   so->so_options = socket_defaults;
   so->so_domain = dom;
   so->so_state = 0;
   so->so_type = (char)type;
   so->so_proto = prp;

#ifdef IP_MULTICAST
   so->inp_moptions = NULL;
#endif   /* IP_MULTICAST */

   so->so_req = PRU_ATTACH;
   error = (*prp->pr_usrreq)(so,(struct mbuf *)0, LONG2MBUF((long)proto));
   if (error) goto bad;

   if (so_evtmap)
   {                       
      rc = (*so_evtmap_create) (so);
      if (rc != 0)
      {
bad:   
         so->so_state |= SS_NOFDREF;
         sofree (so);
         return NULL;   
      }
      /*
       * Altera Niche Stack Nios port modification:
       * Remove (void *) cast since -> owner is now TK_OBJECT
       * to fix build warning.
       */
      so->owner = TK_THIS;
   }

   return so;
}
예제 #3
0
int
socreate(int dom, struct socket **aso, int type,
	int proto, struct thread *td)
{
	struct proc *p = td->td_proc;
	struct protosw *prp;
	struct socket *so;
	struct pru_attach_info ai;
	int error;

	if (proto)
		prp = pffindproto(dom, proto, type);
	else
		prp = pffindtype(dom, type);

	if (prp == 0 || prp->pr_usrreqs->pru_attach == 0)
		return (EPROTONOSUPPORT);

	if (p->p_ucred->cr_prison && jail_socket_unixiproute_only &&
	    prp->pr_domain->dom_family != PF_LOCAL &&
	    prp->pr_domain->dom_family != PF_INET &&
	    prp->pr_domain->dom_family != PF_INET6 &&
	    prp->pr_domain->dom_family != PF_ROUTE) {
		return (EPROTONOSUPPORT);
	}

	if (prp->pr_type != type)
		return (EPROTOTYPE);
	so = soalloc(p != 0);
	if (so == NULL)
		return (ENOBUFS);

	/*
	 * Callers of socreate() presumably will connect up a descriptor
	 * and call soclose() if they cannot.  This represents our so_refs
	 * (which should be 1) from soalloc().
	 */
	soclrstate(so, SS_NOFDREF);

	/*
	 * Set a default port for protocol processing.  No action will occur
	 * on the socket on this port until an inpcb is attached to it and
	 * is able to match incoming packets, or until the socket becomes
	 * available to userland.
	 *
	 * We normally default the socket to the protocol thread on cpu 0.
	 * If PR_SYNC_PORT is set (unix domain sockets) there is no protocol
	 * thread and all pr_*()/pru_*() calls are executed synchronously.
	 */
	if (prp->pr_flags & PR_SYNC_PORT)
		so->so_port = &netisr_sync_port;
	else
		so->so_port = cpu_portfn(0);

	TAILQ_INIT(&so->so_incomp);
	TAILQ_INIT(&so->so_comp);
	so->so_type = type;
	so->so_cred = crhold(p->p_ucred);
	so->so_proto = prp;
	ai.sb_rlimit = &p->p_rlimit[RLIMIT_SBSIZE];
	ai.p_ucred = p->p_ucred;
	ai.fd_rdir = p->p_fd->fd_rdir;

	/*
	 * Auto-sizing of socket buffers is managed by the protocols and
	 * the appropriate flags must be set in the pru_attach function.
	 */
	error = so_pru_attach(so, proto, &ai);
	if (error) {
		sosetstate(so, SS_NOFDREF);
		sofree(so);	/* from soalloc */
		return error;
	}

	/*
	 * NOTE: Returns referenced socket.
	 */
	*aso = so;
	return (0);
}