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 */ }
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; }
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); }