]> git.saurik.com Git - apple/xnu.git/blob - bsd/netinet6/natpt_list.h
10a77de7592a1656fd656d8b699bedefb31c27e6
[apple/xnu.git] / bsd / netinet6 / natpt_list.h
1 /* $KAME: natpt_list.h,v 1.5 2000/03/25 07:23:55 sumikawa Exp $ */
2
3 /*
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32 #define CELL_FREE_MARKER ((Cell *)0xdeadface)
33 #define CELL_WEIRD_ADDR ((Cell *)0xdeadbeef)
34
35 Cell *LST_cons __P((void *, void *));
36 void LST_free __P((Cell *));
37 Cell *LST_last __P((Cell *));
38 int LST_length __P((Cell *));
39 Cell *LST_hookup __P((Cell *, void *));
40 Cell *LST_hookup_list __P((Cell **, void *));
41 Cell *LST_remove_elem __P((Cell **, void *));
42
43
44 #ifdef INCLUDE_NATPT_LIST_C
45
46 /*
47 * Typedefs and Miscellaneous definitions
48 */
49
50 #ifndef NULL
51 #define NULL 0
52 #endif
53
54 #define CELL_NUMS 64
55 #define CELL_PAGE (CELL_NUMS * sizeof(Cell))
56
57
58 /*
59 * Typedefs and Miscellaneous definitions
60 */
61
62 static int _cell_used;
63 static int _cell_free;
64 static Cell *_cell_freeList;
65 static Cell *_cell_mallBlock;
66
67 static Cell *_getCell __P((void));
68 static Cell *_getEmptyCell __P((void));
69
70
71 #ifdef KERNEL
72 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
73 static MALLOC_DEFINE(M_NATPT, "NATPT", "Network Address Translation - Protocol Translation");
74 #endif /* defined(__FreeBSD__) && __FreeBSD__ >= 3 */
75 #endif /* defined(_KERNEL) */
76
77
78 /*
79 *
80 */
81
82 Cell *
83 LST_cons(void *c_car, void *c_cdr)
84 {
85 Cell *ptr = NULL;
86
87 ptr = _getCell();
88 CAR(ptr) = c_car;
89 CDR(ptr) = c_cdr;
90
91 _cell_used++;
92 _cell_free--;
93
94 return (ptr);
95 }
96
97
98 void
99 LST_free(Cell *cell)
100 {
101 if (CAR(cell) != CELL_FREE_MARKER)
102 {
103 CAR(cell) = CELL_FREE_MARKER;
104 CDR(cell) = _cell_freeList;
105 _cell_freeList = cell;
106
107 _cell_used--;
108 _cell_free++;
109 }
110 }
111
112
113 Cell *
114 LST_last(Cell *list)
115 {
116 register Cell *ptr = NULL;
117
118 if (list == NULL)
119 ptr = NULL;
120 else
121 for (ptr = list; CDR(ptr) != NULL; ptr = CDR(ptr)) ;
122
123 return (ptr);
124 }
125
126
127 int
128 LST_length(Cell *list)
129 {
130 register int retval = 0;
131
132 if (list == NULL)
133 retval = 0;
134 else
135 {
136 register Cell *ptr;
137
138 for (ptr = list; ptr; retval++, ptr = CDR(ptr)) ;
139 }
140
141 return (retval);
142 }
143
144
145 Cell *
146 LST_hookup(Cell *list, void *elem)
147 {
148 register Cell *ptr = NULL;
149
150 if (list == NULL)
151 ptr = LST_cons(elem, NULL);
152 else
153 CDR(LST_last(list)) = LST_cons(elem, NULL);
154
155 return (ptr);
156 }
157
158
159 Cell *
160 LST_hookup_list(Cell **list, void *elem)
161 {
162 register Cell *ptr = NULL;
163
164 if (*list == NULL)
165 *list = LST_cons(elem, NULL);
166 else
167 CDR(LST_last(*list)) = LST_cons(elem, NULL);
168
169 return (ptr);
170 }
171
172
173 Cell *
174 LST_remove_elem(Cell **list, void *elem)
175 {
176 register Cell *p, *q;
177
178 if (*list == NULL)
179 return (NULL);
180
181 for (p = *list, q = NULL; p; q = p, p = CDR(p))
182 {
183 if (CAR(p) == elem)
184 {
185 if (q == NULL)
186 *list = CDR(p);
187 else
188 CDR(q) = CDR(p);
189
190 LST_free(p);
191 return (elem);
192 }
193 }
194
195 return (NULL);
196 }
197
198
199 /*
200 *
201 */
202
203 static Cell *
204 _getCell()
205 {
206 Cell *ptr = NULL;
207
208 if (_cell_freeList == NULL)
209 _cell_freeList = _getEmptyCell();
210
211 ptr = _cell_freeList;
212 _cell_freeList = CDR(_cell_freeList);
213
214 return (ptr);
215 }
216
217
218 static Cell *
219 _getEmptyCell()
220 {
221 register int iter;
222 register Cell *ptr = NULL;
223 register Cell *p;
224
225 #if (defined(KERNEL)) || (defined(_KERNEL))
226 MALLOC(ptr, Cell *, CELL_PAGE, M_NATPT, M_NOWAIT);
227 #else
228 ptr = (Cell *)malloc(CELL_PAGE);
229 #endif /* defined(KERNEL) */
230 if (ptr == NULL)
231 {
232 printf("ENOBUFS in _getEmptyCell %d\n", __LINE__);
233 return (ptr);
234 }
235
236 CAR(ptr) = (Cell *)ptr;
237 CDR(ptr) = NULL;
238
239 if (_cell_mallBlock == NULL)
240 _cell_mallBlock = ptr;
241 else
242 CDR(LST_last(_cell_mallBlock)) = ptr;
243
244 ptr++;
245 for (iter = CELL_NUMS - 2 , p = ptr; iter; iter-- , p++)
246 CAR(p) = CELL_WEIRD_ADDR, CDR(p) = p + 1;
247 CAR(p) = CELL_WEIRD_ADDR;
248 CDR(p) = NULL;
249 _cell_free += CELL_NUMS - 1;
250
251 return (ptr);
252 }
253
254 #endif /* defined(INCLUDE_NATPT_LIST_C) */