diff --git a/sys/kern/uipc_domain.c b/sys/kern/uipc_domain.c index c133fcb98d75..59a0d30f0018 100644 --- a/sys/kern/uipc_domain.c +++ b/sys/kern/uipc_domain.c @@ -270,21 +270,31 @@ domainfinalize(void *dummy) callout_reset(&pfslow_callout, 1, pfslowtimo, NULL); } +struct domain * +pffinddomain(int family) +{ + struct domain *dp; + + for (dp = domains; dp != NULL; dp = dp->dom_next) + if (dp->dom_family == family) + return (dp); + return (NULL); +} + struct protosw * pffindtype(int family, int type) { struct domain *dp; struct protosw *pr; - for (dp = domains; dp; dp = dp->dom_next) - if (dp->dom_family == family) - goto found; - return (0); -found: + dp = pffinddomain(family); + if (dp == NULL) + return (NULL); + for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) if (pr->pr_type && pr->pr_type == type) return (pr); - return (0); + return (NULL); } struct protosw * @@ -292,21 +302,22 @@ pffindproto(int family, int protocol, int type) { struct domain *dp; struct protosw *pr; - struct protosw *maybe = 0; + struct protosw *maybe; + maybe = NULL; if (family == 0) - return (0); - for (dp = domains; dp; dp = dp->dom_next) - if (dp->dom_family == family) - goto found; - return (0); -found: + return (NULL); + + dp = pffinddomain(family); + if (dp == NULL) + return (NULL); + for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) { if ((pr->pr_protocol == protocol) && (pr->pr_type == type)) return (pr); if (type == SOCK_RAW && pr->pr_type == SOCK_RAW && - pr->pr_protocol == 0 && maybe == (struct protosw *)0) + pr->pr_protocol == 0 && maybe == NULL) maybe = pr; } return (maybe); @@ -334,12 +345,10 @@ pf_proto_register(int family, struct protosw *npr) return (ENXIO); /* Try to find the specified domain based on the family. */ - for (dp = domains; dp; dp = dp->dom_next) - if (dp->dom_family == family) - goto found; - return (EPFNOSUPPORT); + dp = pffinddomain(family); + if (dp == NULL) + return (EPFNOSUPPORT); -found: /* Initialize backpointer to struct domain. */ npr->pr_domain = dp; fpr = NULL; @@ -405,12 +414,10 @@ pf_proto_unregister(int family, int protocol, int type) return (EPROTOTYPE); /* Try to find the specified domain based on the family type. */ - for (dp = domains; dp; dp = dp->dom_next) - if (dp->dom_family == family) - goto found; - return (EPFNOSUPPORT); + dp = pffinddomain(family); + if (dp == NULL) + return (EPFNOSUPPORT); -found: dpr = NULL; /* Lock out everyone else while we are manipulating the protosw. */ diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index 2d84afedeecd..432ec8007361 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -425,7 +425,16 @@ socreate(int dom, struct socket **aso, int type, int proto, else prp = pffindtype(dom, type); - if (prp == NULL || prp->pr_usrreqs->pru_attach == NULL || + if (prp == NULL) { + /* No support for domain. */ + if (pffinddomain(dom) == NULL) + return (EAFNOSUPPORT); + /* No support for socket type. */ + if (proto == 0 && type != 0) + return (EPROTOTYPE); + return (EPROTONOSUPPORT); + } + if (prp->pr_usrreqs->pru_attach == NULL || prp->pr_usrreqs->pru_attach == pru_attach_notsupp) return (EPROTONOSUPPORT); diff --git a/sys/sys/protosw.h b/sys/sys/protosw.h index b55af4b7dcdb..a74771e8e9ea 100644 --- a/sys/sys/protosw.h +++ b/sys/sys/protosw.h @@ -330,6 +330,7 @@ char *prcorequests[] = { #ifdef _KERNEL void pfctlinput(int, struct sockaddr *); void pfctlinput2(int, struct sockaddr *, void *); +struct domain *pffinddomain(int family); struct protosw *pffindproto(int family, int protocol, int type); struct protosw *pffindtype(int family, int type); int pf_proto_register(int family, struct protosw *npr);