2 * $Id: libnet_port_list.c,v 1.1.1.1 2000/05/25 00:28:49 route Exp $
5 * libnet_port_list.c - transport layer port list chaining code
7 * Copyright (c) 1998 - 2001 Mike D. Schiffman <mike@infonexus.com>
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
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
34 #include "../include/config.h"
36 #include "../include/libnet.h"
41 libnet_plist_chain_new(struct libnet_plist_chain **head, char *tok_list)
43 char libnet_plist_legal_tokens[] = "0123456789,- ";
44 struct libnet_plist_chain *tmp;
46 int i, j, valid_token, cur_node;
55 * Make sure we have legal tokens.
57 for (i = 0; tok_list[i]; i++)
59 for (j = 0, valid_token = 0; libnet_plist_legal_tokens[j]; j++)
61 if (libnet_plist_legal_tokens[j] == tok_list[i])
70 libnet_error(LIBNET_ERR_CRITICAL,
71 "libnet_build_plist_chain: illegal token # %d (%c)\n",
84 (struct libnet_plist_chain *)malloc(sizeof(struct libnet_plist_chain));
89 perror("libnet_build_plist_chain: malloc");
96 tmp->node = cur_node = 0;
99 all_lists = realloc(all_lists, (sizeof(u_short) * (cur_id + 1)));
103 perror("libnet_build_plist_chain: realloc");
109 all_lists[cur_id++] = 0;
112 * Using strtok successively proved problematic. We solve this by
113 * calling it once, then manually extracting the elements from the token.
114 * In the case of bport > eport, we swap them.
116 for (i = 0; (tok = strtok(!i ? tok_list : NULL, ",")); i = 1, cur_node++)
119 * The first iteration we will have a head node allocated so we don't
124 tmp->next = (struct libnet_plist_chain *)
125 malloc(sizeof(struct libnet_plist_chain));
129 perror("libnet_build_plist_chain: malloc");
132 * XXX - potential memory leak if other nodes are allocated
139 tmp->node = cur_node;
142 tmp->bport = atoi(tok);
145 * Step past this port number.
148 while (isdigit((int)tok[j]))
154 * If we have a delimiting dash and are NOT at the end of the token
155 * array, we can assume it's the end port, otherwise if we just have
156 * a dash, we consider it shorthand for `inclusive of all ports up to
157 * 65535. Finally, if we have no dash, we assume this token is a
162 tmp->eport = (++j != strlen(tok)) ? atoi(&tok[j]) : 65535;
166 tmp->eport = tmp->bport;
170 * Do we need to swap the values?
172 if (tmp->bport > tmp->eport)
174 tmp->bport ^= tmp->eport;
175 tmp->eport ^= tmp->bport;
176 tmp->bport ^= tmp->eport;
181 * The head node needs to hold the total node count.
183 (*head)->node = cur_node;
189 libnet_plist_chain_next_pair(struct libnet_plist_chain *p, u_short *bport,
195 node_cnt = &(all_lists[p->id]);
202 * We are at the end of the list.
204 if (*node_cnt == p->node)
212 for (tmp_cnt = *node_cnt; tmp_cnt; tmp_cnt--, p = p->next) ;
221 libnet_plist_chain_dump(struct libnet_plist_chain *p)
228 for (; p; p = p->next)
230 if (p->bport == p->eport)
232 fprintf(stdout, "%d ", p->bport);
236 fprintf(stdout, "%d-%d ", p->bport, p->eport);
239 fprintf(stdout, "\n");
245 libnet_plist_chain_dump_string(struct libnet_plist_chain *p)
247 u_char buf[BUFSIZ] = {0};
255 for (i = 0, j = 0; p; p = p->next)
257 if (p->bport == p->eport)
259 i = sprintf(&buf[j], "%d", p->bport);
263 i = sprintf(&buf[j], "%d-%d", p->bport, p->eport);
268 sprintf(&buf[j++], ",");
271 return (strdup(buf)); /* XXX - reentrancy == no */
276 libnet_plist_chain_free(struct libnet_plist_chain *p)
279 struct libnet_plist_chain *tmp;
286 for (i = p->node; i; i--)