Annotation of embedaddon/libnet/src/libnet_port_list.c, revision 1.1
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:
! 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:
! 42: u_int16_t *all_lists;
! 43:
! 44: int
! 45: libnet_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:
! 190: int
! 191: libnet_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:
! 221: int
! 222: libnet_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:
! 244: char *
! 245: libnet_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:
! 274: int
! 275: libnet_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 */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>