File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libnet / src / libnet_port_list.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Sep 27 11:11:38 2023 UTC (9 months ago) by misho
Branches: libnet, MAIN
CVS tags: v1_2p1, HEAD
Version 1.2p1

    1: /*
    2:  *  $Id: libnet_port_list.c,v 1.1.1.3 2023/09/27 11:11:38 misho 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: #include "common.h"
   34: 
   35: uint16_t *all_lists;
   36: 
   37: int
   38: libnet_plist_chain_new(libnet_t *l, libnet_plist_t **plist, char *token_list)
   39: {
   40:     char libnet_plist_legal_tokens[] = "0123456789,- ";
   41:     libnet_plist_t *tmp;
   42:     char *tok;
   43:     int i, j, valid_token, cur_node;
   44:     uint16_t *all_lists_tmp;
   45:     static uint8_t cur_id;
   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,
   73:                     "libnet_build_plist_chain: illegal token # %d (%c)",
   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,
   87:                     "libnet_build_plist_chain: malloc %s", strerror(errno));
   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;
   97:     all_lists = realloc(all_lists_tmp, (sizeof(uint16_t) * (cur_id + 1)));
   98:     if (!all_lists)
   99:     {
  100:         all_lists = all_lists_tmp;
  101:         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
  102:                     "libnet_build_plist_chain: realloc %s", strerror(errno));
  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));
  123:             if (!tmp->next)
  124:             {
  125:                 snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
  126:                     "libnet_build_plist_chain: malloc %s", strerror(errno));
  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
  184: libnet_plist_chain_next_pair(libnet_plist_t *plist, uint16_t *bport,
  185:         uint16_t *eport)
  186: {
  187:     uint16_t *node_cnt;
  188:     uint16_t tmp_cnt;
  189: 
  190:     if (plist == NULL)
  191:     {
  192:         return (-1);
  193:     }
  194:     node_cnt = &(all_lists[plist->id]);
  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: {
  270:     uint16_t i;
  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: 
  288: /**
  289:  * Local Variables:
  290:  *  indent-tabs-mode: nil
  291:  *  c-file-style: "stroustrup"
  292:  * End:
  293:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>