Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / common / vera / niu_ippktgen / C / libnet / src / libnet_port_list.c
CommitLineData
86530b38
AT
1/*
2 * $Id: libnet_port_list.c,v 1.20 2005/11/29 22:28:44 carlosc Exp $
3 *
4 * libnet
5 * libnet_port_list.c - transport layer port list chaining code
6 *
7 * Copyright (c) 1998 - 2004 Mike D. Schiffman <mike@infonexus.com>
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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
33#if (HAVE_CONFIG_H)
34#include "../include/config.h"
35#endif
36#if (!(_WIN32) || (__CYGWIN__))
37#include "../include/libnet.h"
38#else
39#include "../include/win32/libnet.h"
40#endif
41
42u_int16_t *all_lists;
43
44int
45libnet_plist_chain_new(libnet_t *l, libnet_plist_t **plist, char *token_list)
46{
47 int8_t libnet_plist_legal_tokens[] = "0123456789,- ";
48 libnet_plist_t *tmp;
49 int8_t *tok;
50 int i, j, valid_token, cur_node;
51 u_int16_t *all_lists_tmp;
52 static u_int8_t cur_id;
53
54 if (l == NULL)
55 {
56 return (-1);
57 }
58
59 if (token_list == NULL)
60 {
61 return (-1);
62 }
63
64 /*
65 * Make sure we have legal tokens.
66 */
67 for (i = 0; token_list[i]; i++)
68 {
69 for (j = 0, valid_token = 0; libnet_plist_legal_tokens[j]; j++)
70 {
71 if (libnet_plist_legal_tokens[j] == token_list[i])
72 {
73 valid_token = 1;
74 break;
75 }
76 }
77 if (!valid_token)
78 {
79 snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
80 "libnet_build_plist_chain: illegal token # %d (%c)\n",
81 i + 1,
82 token_list[i]);
83 *plist = NULL;
84 return (-1);
85 }
86 }
87
88 /* head node */
89 *plist = malloc(sizeof (libnet_plist_t));
90
91 if (!(*plist))
92 {
93 snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
94 "libnet_build_plist_chain: malloc %s\n", strerror(errno));
95 *plist = NULL;
96 return (-1);
97 }
98
99 tmp = *plist;
100 tmp->node = cur_node = 0;
101 tmp->next = NULL;
102 tmp->id = cur_id;
103 all_lists_tmp = all_lists;
104 all_lists = realloc(all_lists_tmp, (sizeof(u_int16_t) * (cur_id + 1)));
105 if (!all_lists)
106 {
107 all_lists = all_lists_tmp;
108 snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
109 "libnet_build_plist_chain: realloc %s\n", strerror(errno));
110 *plist = NULL;
111 return(-1);
112 }
113
114 all_lists[cur_id++] = 0;
115
116 /*
117 * Using strtok successively proved problematic. We solve this by
118 * calling it once, then manually extracting the elements from the token.
119 * In the case of bport > eport, we swap them.
120 */
121 for (i = 0; (tok = strtok(!i ? token_list : NULL, ",")); i = 1, cur_node++)
122 {
123 /*
124 * The first iteration we will have a head node allocated so we don't
125 * need to malloc().
126 */
127 if (i)
128 {
129 tmp->next = malloc(sizeof (libnet_plist_t));
130 if (!tmp)
131 {
132 snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
133 "libnet_build_plist_chain: malloc %s\n", strerror(errno));
134 /*
135 * XXX - potential memory leak if other nodes are allocated
136 * but not freed.
137 */
138 *plist = NULL;
139 return(-1);
140 }
141 tmp = tmp->next;
142 tmp->node = cur_node;
143 tmp->next = NULL;
144 }
145 tmp->bport = atoi(tok);
146
147 /*
148 * Step past this port number.
149 */
150 j = 0;
151 while (isdigit((int)tok[j]))
152 {
153 j++;
154 }
155
156 /*
157 * If we have a delimiting dash and are NOT at the end of the token
158 * array, we can assume it's the end port, otherwise if we just have
159 * a dash, we consider it int16_thand for `inclusive of all ports up to
160 * 65535. Finally, if we have no dash, we assume this token is a
161 * single port only.
162 */
163 if (tok[j] == '-')
164 {
165 tmp->eport = (++j != strlen(tok)) ? atoi(&tok[j]) : 65535;
166 }
167 else
168 {
169 tmp->eport = tmp->bport;
170 }
171
172 /*
173 * Do we need to swap the values?
174 */
175 if (tmp->bport > tmp->eport)
176 {
177 tmp->bport ^= tmp->eport;
178 tmp->eport ^= tmp->bport;
179 tmp->bport ^= tmp->eport;
180 }
181 }
182
183 /*
184 * The head node needs to hold the total node count.
185 */
186 (*plist)->node = cur_node;
187 return (1);
188}
189
190int
191libnet_plist_chain_next_pair(libnet_plist_t *plist, u_int16_t *bport,
192 u_int16_t *eport)
193{
194 u_int16_t *node_cnt;
195 u_int16_t tmp_cnt;
196
197 node_cnt = &(all_lists[plist->id]);
198 if (plist == NULL)
199 {
200 return (-1);
201 }
202
203 /*
204 * We are at the end of the list.
205 */
206 if (*node_cnt == plist->node)
207 {
208 *node_cnt = 0;
209 *bport = 0;
210 *eport = 0;
211 return (0);
212 }
213
214 for (tmp_cnt = *node_cnt; tmp_cnt; tmp_cnt--, plist = plist->next) ;
215 *bport = plist->bport;
216 *eport = plist->eport;
217 *node_cnt += 1;
218 return (1);
219}
220
221int
222libnet_plist_chain_dump(libnet_plist_t *plist)
223{
224 if (plist == NULL)
225 {
226 return (-1);
227 }
228
229 for (; plist; plist = plist->next)
230 {
231 if (plist->bport == plist->eport)
232 {
233 fprintf(stdout, "%d ", plist->bport);
234 }
235 else
236 {
237 fprintf(stdout, "%d-%d ", plist->bport, plist->eport);
238 }
239 }
240 fprintf(stdout, "\n");
241 return (1);
242}
243
244char *
245libnet_plist_chain_dump_string(libnet_plist_t *plist)
246{
247 char buf[BUFSIZ] = {0};
248 int i, j;
249
250 if (plist == NULL)
251 {
252 return (NULL);
253 }
254
255 for (i = 0, j = 0; plist; plist = plist->next)
256 {
257 if (plist->bport == plist->eport)
258 {
259 i = snprintf(&buf[j], BUFSIZ, "%d", plist->bport);
260 }
261 else
262 {
263 i = snprintf(&buf[j], BUFSIZ, "%d-%d", plist->bport, plist->eport);
264 }
265 j += i;
266 if (plist->next)
267 {
268 snprintf(&buf[j++], BUFSIZ, ",");
269 }
270 }
271 return (strdup(buf)); /* XXX - reentrancy == no */
272}
273
274int
275libnet_plist_chain_free(libnet_plist_t *plist)
276{
277 u_int16_t i;
278 libnet_plist_t *tmp;
279
280 if (plist == NULL)
281 {
282 return (-1);
283 }
284
285 for (i = plist->node; i; i--)
286 {
287 tmp = plist;
288 plist = plist->next;
289 free(tmp);
290 }
291 plist = NULL;
292 return (1);
293}
294
295/* EOF */