* $Id: libnet_port_list.c,v 1.20 2005/11/29 22:28:44 carlosc Exp $
* libnet_port_list.c - transport layer port list chaining code
* Copyright (c) 1998 - 2004 Mike D. Schiffman <mike@infonexus.com>
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 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
#include "../include/config.h"
#if (!(_WIN32) || (__CYGWIN__))
#include "../include/libnet.h"
#include "../include/win32/libnet.h"
libnet_plist_chain_new(libnet_t
*l
, libnet_plist_t
**plist
, char *token_list
)
int8_t libnet_plist_legal_tokens
[] = "0123456789,- ";
int i
, j
, valid_token
, cur_node
;
u_int16_t
*all_lists_tmp
;
* 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
])
snprintf(l
->err_buf
, LIBNET_ERRBUF_SIZE
,
"libnet_build_plist_chain: illegal token # %d (%c)\n",
*plist
= malloc(sizeof (libnet_plist_t
));
snprintf(l
->err_buf
, LIBNET_ERRBUF_SIZE
,
"libnet_build_plist_chain: malloc %s\n", strerror(errno
));
tmp
->node
= cur_node
= 0;
all_lists_tmp
= all_lists
;
all_lists
= realloc(all_lists_tmp
, (sizeof(u_int16_t
) * (cur_id
+ 1)));
all_lists
= all_lists_tmp
;
snprintf(l
->err_buf
, LIBNET_ERRBUF_SIZE
,
"libnet_build_plist_chain: realloc %s\n", strerror(errno
));
* 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
tmp
->next
= malloc(sizeof (libnet_plist_t
));
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
* Step past this port number.
while (isdigit((int)tok
[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
tmp
->eport
= (++j
!= strlen(tok
)) ? atoi(&tok
[j
]) : 65535;
* 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
;
libnet_plist_chain_next_pair(libnet_plist_t
*plist
, u_int16_t
*bport
,
node_cnt
= &(all_lists
[plist
->id
]);
* We are at the end of the list.
if (*node_cnt
== plist
->node
)
for (tmp_cnt
= *node_cnt
; tmp_cnt
; tmp_cnt
--, plist
= plist
->next
) ;
libnet_plist_chain_dump(libnet_plist_t
*plist
)
for (; plist
; plist
= plist
->next
)
if (plist
->bport
== plist
->eport
)
fprintf(stdout
, "%d ", plist
->bport
);
fprintf(stdout
, "%d-%d ", plist
->bport
, plist
->eport
);
libnet_plist_chain_dump_string(libnet_plist_t
*plist
)
for (i
= 0, j
= 0; plist
; plist
= plist
->next
)
if (plist
->bport
== plist
->eport
)
i
= snprintf(&buf
[j
], BUFSIZ
, "%d", plist
->bport
);
i
= snprintf(&buf
[j
], BUFSIZ
, "%d-%d", plist
->bport
, plist
->eport
);
snprintf(&buf
[j
++], BUFSIZ
, ",");
return (strdup(buf
)); /* XXX - reentrancy == no */
libnet_plist_chain_free(libnet_plist_t
*plist
)
for (i
= plist
->node
; i
; i
--)