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
/*
* $Id: libnet_port_list.c,v 1.20 2005/11/29 22:28:44 carlosc Exp $
*
* libnet
* libnet_port_list.c - transport layer port list chaining code
*
* Copyright (c) 1998 - 2004 Mike D. Schiffman <mike@infonexus.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#if (HAVE_CONFIG_H)
#include "../include/config.h"
#endif
#if (!(_WIN32) || (__CYGWIN__))
#include "../include/libnet.h"
#else
#include "../include/win32/libnet.h"
#endif
u_int16_t *all_lists;
int
libnet_plist_chain_new(libnet_t *l, libnet_plist_t **plist, char *token_list)
{
int8_t libnet_plist_legal_tokens[] = "0123456789,- ";
libnet_plist_t *tmp;
int8_t *tok;
int i, j, valid_token, cur_node;
u_int16_t *all_lists_tmp;
static u_int8_t cur_id;
if (l == NULL)
{
return (-1);
}
if (token_list == NULL)
{
return (-1);
}
/*
* Make sure we have legal tokens.
*/
for (i = 0; token_list[i]; i++)
{
for (j = 0, valid_token = 0; libnet_plist_legal_tokens[j]; j++)
{
if (libnet_plist_legal_tokens[j] == token_list[i])
{
valid_token = 1;
break;
}
}
if (!valid_token)
{
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
"libnet_build_plist_chain: illegal token # %d (%c)\n",
i + 1,
token_list[i]);
*plist = NULL;
return (-1);
}
}
/* head node */
*plist = malloc(sizeof (libnet_plist_t));
if (!(*plist))
{
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
"libnet_build_plist_chain: malloc %s\n", strerror(errno));
*plist = NULL;
return (-1);
}
tmp = *plist;
tmp->node = cur_node = 0;
tmp->next = NULL;
tmp->id = cur_id;
all_lists_tmp = all_lists;
all_lists = realloc(all_lists_tmp, (sizeof(u_int16_t) * (cur_id + 1)));
if (!all_lists)
{
all_lists = all_lists_tmp;
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
"libnet_build_plist_chain: realloc %s\n", strerror(errno));
*plist = NULL;
return(-1);
}
all_lists[cur_id++] = 0;
/*
* Using strtok successively proved problematic. We solve this by
* calling it once, then manually extracting the elements from the token.
* In the case of bport > eport, we swap them.
*/
for (i = 0; (tok = strtok(!i ? token_list : NULL, ",")); i = 1, cur_node++)
{
/*
* The first iteration we will have a head node allocated so we don't
* need to malloc().
*/
if (i)
{
tmp->next = malloc(sizeof (libnet_plist_t));
if (!tmp)
{
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
"libnet_build_plist_chain: malloc %s\n", strerror(errno));
/*
* XXX - potential memory leak if other nodes are allocated
* but not freed.
*/
*plist = NULL;
return(-1);
}
tmp = tmp->next;
tmp->node = cur_node;
tmp->next = NULL;
}
tmp->bport = atoi(tok);
/*
* Step past this port number.
*/
j = 0;
while (isdigit((int)tok[j]))
{
j++;
}
/*
* If we have a delimiting dash and are NOT at the end of the token
* array, we can assume it's the end port, otherwise if we just have
* a dash, we consider it int16_thand for `inclusive of all ports up to
* 65535. Finally, if we have no dash, we assume this token is a
* single port only.
*/
if (tok[j] == '-')
{
tmp->eport = (++j != strlen(tok)) ? atoi(&tok[j]) : 65535;
}
else
{
tmp->eport = tmp->bport;
}
/*
* Do we need to swap the values?
*/
if (tmp->bport > tmp->eport)
{
tmp->bport ^= tmp->eport;
tmp->eport ^= tmp->bport;
tmp->bport ^= tmp->eport;
}
}
/*
* The head node needs to hold the total node count.
*/
(*plist)->node = cur_node;
return (1);
}
int
libnet_plist_chain_next_pair(libnet_plist_t *plist, u_int16_t *bport,
u_int16_t *eport)
{
u_int16_t *node_cnt;
u_int16_t tmp_cnt;
node_cnt = &(all_lists[plist->id]);
if (plist == NULL)
{
return (-1);
}
/*
* We are at the end of the list.
*/
if (*node_cnt == plist->node)
{
*node_cnt = 0;
*bport = 0;
*eport = 0;
return (0);
}
for (tmp_cnt = *node_cnt; tmp_cnt; tmp_cnt--, plist = plist->next) ;
*bport = plist->bport;
*eport = plist->eport;
*node_cnt += 1;
return (1);
}
int
libnet_plist_chain_dump(libnet_plist_t *plist)
{
if (plist == NULL)
{
return (-1);
}
for (; plist; plist = plist->next)
{
if (plist->bport == plist->eport)
{
fprintf(stdout, "%d ", plist->bport);
}
else
{
fprintf(stdout, "%d-%d ", plist->bport, plist->eport);
}
}
fprintf(stdout, "\n");
return (1);
}
char *
libnet_plist_chain_dump_string(libnet_plist_t *plist)
{
char buf[BUFSIZ] = {0};
int i, j;
if (plist == NULL)
{
return (NULL);
}
for (i = 0, j = 0; plist; plist = plist->next)
{
if (plist->bport == plist->eport)
{
i = snprintf(&buf[j], BUFSIZ, "%d", plist->bport);
}
else
{
i = snprintf(&buf[j], BUFSIZ, "%d-%d", plist->bport, plist->eport);
}
j += i;
if (plist->next)
{
snprintf(&buf[j++], BUFSIZ, ",");
}
}
return (strdup(buf)); /* XXX - reentrancy == no */
}
int
libnet_plist_chain_free(libnet_plist_t *plist)
{
u_int16_t i;
libnet_plist_t *tmp;
if (plist == NULL)
{
return (-1);
}
for (i = plist->node; i; i--)
{
tmp = plist;
plist = plist->next;
free(tmp);
}
plist = NULL;
return (1);
}
/* EOF */