Annotation of embedaddon/libnet/src/libnet_port_list.c, revision 1.1.1.3
1.1 misho 1: /*
2: * $Id: libnet_port_list.c,v 1.10 2004/01/28 19:45:00 mike 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:
1.1.1.3 ! misho 33: #include "common.h"
1.1 misho 34:
1.1.1.2 misho 35: uint16_t *all_lists;
1.1 misho 36:
37: int
38: libnet_plist_chain_new(libnet_t *l, libnet_plist_t **plist, char *token_list)
39: {
1.1.1.2 misho 40: char libnet_plist_legal_tokens[] = "0123456789,- ";
1.1 misho 41: libnet_plist_t *tmp;
1.1.1.2 misho 42: char *tok;
1.1 misho 43: int i, j, valid_token, cur_node;
1.1.1.2 misho 44: uint16_t *all_lists_tmp;
45: static uint8_t cur_id;
1.1 misho 46:
47: if (l == NULL)
48: {
49: return (-1);
50: }
51:
52: if (token_list == NULL)
53: {
54: return (-1);
55: }
56:
57: /*
58: * Make sure we have legal tokens.
59: */
60: for (i = 0; token_list[i]; i++)
61: {
62: for (j = 0, valid_token = 0; libnet_plist_legal_tokens[j]; j++)
63: {
64: if (libnet_plist_legal_tokens[j] == token_list[i])
65: {
66: valid_token = 1;
67: break;
68: }
69: }
70: if (!valid_token)
71: {
72: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
1.1.1.3 ! misho 73: "libnet_build_plist_chain: illegal token # %d (%c)",
1.1 misho 74: i + 1,
75: token_list[i]);
76: *plist = NULL;
77: return (-1);
78: }
79: }
80:
81: /* head node */
82: *plist = malloc(sizeof (libnet_plist_t));
83:
84: if (!(*plist))
85: {
86: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
1.1.1.3 ! misho 87: "libnet_build_plist_chain: malloc %s", strerror(errno));
1.1 misho 88: *plist = NULL;
89: return (-1);
90: }
91:
92: tmp = *plist;
93: tmp->node = cur_node = 0;
94: tmp->next = NULL;
95: tmp->id = cur_id;
96: all_lists_tmp = all_lists;
1.1.1.2 misho 97: all_lists = realloc(all_lists_tmp, (sizeof(uint16_t) * (cur_id + 1)));
1.1 misho 98: if (!all_lists)
99: {
100: all_lists = all_lists_tmp;
101: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
1.1.1.3 ! misho 102: "libnet_build_plist_chain: realloc %s", strerror(errno));
1.1 misho 103: *plist = NULL;
104: return(-1);
105: }
106:
107: all_lists[cur_id++] = 0;
108:
109: /*
110: * Using strtok successively proved problematic. We solve this by
111: * calling it once, then manually extracting the elements from the token.
112: * In the case of bport > eport, we swap them.
113: */
114: for (i = 0; (tok = strtok(!i ? token_list : NULL, ",")); i = 1, cur_node++)
115: {
116: /*
117: * The first iteration we will have a head node allocated so we don't
118: * need to malloc().
119: */
120: if (i)
121: {
122: tmp->next = malloc(sizeof (libnet_plist_t));
1.1.1.2 misho 123: if (!tmp->next)
1.1 misho 124: {
125: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
1.1.1.3 ! misho 126: "libnet_build_plist_chain: malloc %s", strerror(errno));
1.1 misho 127: /*
128: * XXX - potential memory leak if other nodes are allocated
129: * but not freed.
130: */
131: *plist = NULL;
132: return(-1);
133: }
134: tmp = tmp->next;
135: tmp->node = cur_node;
136: tmp->next = NULL;
137: }
138: tmp->bport = atoi(tok);
139:
140: /*
141: * Step past this port number.
142: */
143: j = 0;
144: while (isdigit((int)tok[j]))
145: {
146: j++;
147: }
148:
149: /*
150: * If we have a delimiting dash and are NOT at the end of the token
151: * array, we can assume it's the end port, otherwise if we just have
152: * a dash, we consider it int16_thand for `inclusive of all ports up to
153: * 65535. Finally, if we have no dash, we assume this token is a
154: * single port only.
155: */
156: if (tok[j] == '-')
157: {
158: tmp->eport = (++j != strlen(tok)) ? atoi(&tok[j]) : 65535;
159: }
160: else
161: {
162: tmp->eport = tmp->bport;
163: }
164:
165: /*
166: * Do we need to swap the values?
167: */
168: if (tmp->bport > tmp->eport)
169: {
170: tmp->bport ^= tmp->eport;
171: tmp->eport ^= tmp->bport;
172: tmp->bport ^= tmp->eport;
173: }
174: }
175:
176: /*
177: * The head node needs to hold the total node count.
178: */
179: (*plist)->node = cur_node;
180: return (1);
181: }
182:
183: int
1.1.1.2 misho 184: libnet_plist_chain_next_pair(libnet_plist_t *plist, uint16_t *bport,
185: uint16_t *eport)
1.1 misho 186: {
1.1.1.2 misho 187: uint16_t *node_cnt;
188: uint16_t tmp_cnt;
1.1 misho 189:
190: if (plist == NULL)
191: {
192: return (-1);
193: }
1.1.1.2 misho 194: node_cnt = &(all_lists[plist->id]);
1.1 misho 195:
196: /*
197: * We are at the end of the list.
198: */
199: if (*node_cnt == plist->node)
200: {
201: *node_cnt = 0;
202: *bport = 0;
203: *eport = 0;
204: return (0);
205: }
206:
207: for (tmp_cnt = *node_cnt; tmp_cnt; tmp_cnt--, plist = plist->next) ;
208: *bport = plist->bport;
209: *eport = plist->eport;
210: *node_cnt += 1;
211: return (1);
212: }
213:
214: int
215: libnet_plist_chain_dump(libnet_plist_t *plist)
216: {
217: if (plist == NULL)
218: {
219: return (-1);
220: }
221:
222: for (; plist; plist = plist->next)
223: {
224: if (plist->bport == plist->eport)
225: {
226: fprintf(stdout, "%d ", plist->bport);
227: }
228: else
229: {
230: fprintf(stdout, "%d-%d ", plist->bport, plist->eport);
231: }
232: }
233: fprintf(stdout, "\n");
234: return (1);
235: }
236:
237: char *
238: libnet_plist_chain_dump_string(libnet_plist_t *plist)
239: {
240: char buf[BUFSIZ] = {0};
241: int i, j;
242:
243: if (plist == NULL)
244: {
245: return (NULL);
246: }
247:
248: for (i = 0, j = 0; plist; plist = plist->next)
249: {
250: if (plist->bport == plist->eport)
251: {
252: i = snprintf(&buf[j], BUFSIZ, "%d", plist->bport);
253: }
254: else
255: {
256: i = snprintf(&buf[j], BUFSIZ, "%d-%d", plist->bport, plist->eport);
257: }
258: j += i;
259: if (plist->next)
260: {
261: snprintf(&buf[j++], BUFSIZ, ",");
262: }
263: }
264: return (strdup(buf)); /* XXX - reentrancy == no */
265: }
266:
267: int
268: libnet_plist_chain_free(libnet_plist_t *plist)
269: {
1.1.1.2 misho 270: uint16_t i;
1.1 misho 271: libnet_plist_t *tmp;
272:
273: if (plist == NULL)
274: {
275: return (-1);
276: }
277:
278: for (i = plist->node; i; i--)
279: {
280: tmp = plist;
281: plist = plist->next;
282: free(tmp);
283: }
284: plist = NULL;
285: return (1);
286: }
287:
1.1.1.3 ! misho 288: /**
! 289: * Local Variables:
! 290: * indent-tabs-mode: nil
! 291: * c-file-style: "stroustrup"
! 292: * End:
! 293: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>