|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: /* Copyright (C) 1999 Apple Computer, Inc. */ ! 23: ! 24: /* ! 25: * Support for Network Kernel Extensions: Socket Filters ! 26: * ! 27: * Justin C. Walker, 990319 ! 28: */ ! 29: ! 30: #include <sys/types.h> ! 31: #include <sys/queue.h> ! 32: #include <sys/malloc.h> ! 33: #include <sys/param.h> ! 34: #include <sys/mbuf.h> ! 35: #include <sys/domain.h> ! 36: #include <sys/protosw.h> ! 37: #include <sys/socket.h> ! 38: #include <machine/spl.h> ! 39: #include "kext_net.h" ! 40: ! 41: /* List of kernel extensions (networking) known to kernel */ ! 42: struct nf_list nf_list; ! 43: ! 44: /* ! 45: * Register a global filter for the specified protocol ! 46: * Make a few checks and then insert the new descriptor in the ! 47: * filter list and, if global, in its protosw's chain. ! 48: */ ! 49: int ! 50: register_sockfilter(struct NFDescriptor *nfp, struct NFDescriptor *nfp1, ! 51: struct protosw *pr, int flags) ! 52: { int s; ! 53: static int NF_initted = 0; ! 54: ! 55: if (nfp == NULL) ! 56: return(EINVAL); ! 57: ! 58: s = splhigh(); ! 59: if (!NF_initted) ! 60: { NF_initted = 1; ! 61: TAILQ_INIT(&nf_list); ! 62: } ! 63: ! 64: /* ! 65: * Install the extension: ! 66: * First, put it in the global list of all filters ! 67: * Then, if global, install in the protosw's list ! 68: */ ! 69: TAILQ_INSERT_TAIL(&nf_list, nfp, nf_list); ! 70: if (nfp->nf_flags & NFD_GLOBAL) ! 71: { if (flags & NFF_BEFORE) ! 72: { if (nfp1 == NULL) ! 73: { TAILQ_INSERT_HEAD(&pr->pr_sfilter, ! 74: nfp, nf_next); ! 75: } else ! 76: TAILQ_INSERT_BEFORE(nfp1, nfp, nf_next); ! 77: } else /* Default: AFTER */ ! 78: { if (nfp1 == NULL) ! 79: { TAILQ_INSERT_TAIL(&pr->pr_sfilter, ! 80: nfp, nf_next); ! 81: } else ! 82: TAILQ_INSERT_AFTER(&pr->pr_sfilter, nfp1, ! 83: nfp, nf_next); ! 84: } ! 85: } ! 86: splx(s); ! 87: return(0); ! 88: } ! 89: ! 90: unregister_sockfilter(struct NFDescriptor *nfp, struct protosw *pr, int flags) ! 91: { int s; ! 92: ! 93: s = splhigh(); ! 94: TAILQ_REMOVE(&nf_list, nfp, nf_list); ! 95: /* Only globals are attached to the protosw entry */ ! 96: if (nfp->nf_flags & NFD_GLOBAL) ! 97: TAILQ_REMOVE(&pr->pr_sfilter, nfp, nf_next); ! 98: splx(s); ! 99: return(0); ! 100: } ! 101: ! 102: struct NFDescriptor * ! 103: find_nke(int handle) ! 104: { struct NFDescriptor *nfp; ! 105: ! 106: nfp = nf_list.tqh_first; ! 107: while (nfp) ! 108: { if (nfp->nf_handle == handle) ! 109: return(nfp); ! 110: nfp = nfp->nf_next.tqe_next; ! 111: } ! 112: return(NULL); ! 113: } ! 114: ! 115: /* ! 116: * Insert a previously registered, non-global, NKE into the list of ! 117: * active NKEs for this socket. Then invoke its "attach/create" entry. ! 118: * Assumed called with protection in place (spl/mutex/whatever) ! 119: * XXX: How to which extension is not found, on error. ! 120: */ ! 121: int ! 122: nke_insert(struct socket *so, struct so_nke *np) ! 123: { int s, error; ! 124: struct kextcb *kp, *kp1; ! 125: struct NFDescriptor *nf1, *nf2 = NULL; ! 126: ! 127: if (np->nke_where != NULL) ! 128: { if ((nf2 = find_nke(np->nke_where)) == NULL) ! 129: { /* ??? */ ! 130: return(ENXIO);/* XXX */ ! 131: } ! 132: } ! 133: ! 134: if ((nf1 = find_nke(np->nke_handle)) == NULL) ! 135: { /* ??? */ ! 136: return(ENXIO);/* XXX */ ! 137: } ! 138: ! 139: kp = so->so_ext; ! 140: kp1 = NULL; ! 141: if (np->nke_flags & NFF_BEFORE) ! 142: { if (nf2) ! 143: { while (kp) ! 144: { if (kp->e_nfd == nf2) ! 145: break; ! 146: kp1 = kp; ! 147: kp = kp->e_next; ! 148: } ! 149: if (kp == NULL) ! 150: return(ENXIO);/* XXX */ ! 151: } ! 152: } else ! 153: { if (nf2) ! 154: { while (kp) ! 155: { if (kp->e_nfd == nf2) ! 156: break; ! 157: kp1 = kp; ! 158: kp = kp->e_next; ! 159: } ! 160: if (kp == NULL) ! 161: return(ENXIO);/* XXX */ ! 162: } ! 163: kp1 = kp; ! 164: } ! 165: /* ! 166: * Here with kp1 pointing to the insertion point. ! 167: * If null, this is first entry. ! 168: * Now, create and insert the descriptor. ! 169: */ ! 170: ! 171: MALLOC(kp, struct kextcb *, sizeof(*kp), M_TEMP, M_WAITOK); ! 172: if (kp == NULL) ! 173: return(ENOBUFS); /* so_free will clean up */ ! 174: bzero(kp, sizeof (*kp)); ! 175: if (kp1 == NULL) ! 176: so->so_ext = kp; ! 177: else ! 178: { kp->e_next = kp1->e_next; ! 179: kp1->e_next = kp; ! 180: } ! 181: kp->e_fcb = NULL; ! 182: kp->e_nfd = nf1; ! 183: kp->e_soif = nf1->nf_soif; ! 184: kp->e_sout = nf1->nf_soutil; ! 185: /* ! 186: * Ignore return value for create ! 187: * Everyone gets a chance at startup ! 188: */ ! 189: if (kp->e_soif && kp->e_soif->sf_socreate) ! 190: (*kp->e_soif->sf_socreate)(so, so->so_proto, kp); ! 191: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.