Blame src/libnet_port_list.c

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