123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 |
- /*
- * Copyright (c) 2001-2004 Aaron Turner.
- * 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.
- * 3. Neither the names of the copyright owners nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``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 AUTHORS OR COPYRIGHT HOLDERS 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.
- */
- /*
- * This file contains routines to manipulate port maps, in which
- * one port number is mapped to another.
- */
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
- #include "config.h"
- #include "tcpreplay.h"
- #include "utils.h"
- #include "err.h"
- #include "portmap.h"
- #define EBUF_SIZE 256
- PORTMAP *
- new_portmap()
- {
- PORTMAP *newportmap;
- newportmap = (PORTMAP *) malloc(sizeof(PORTMAP));
- if (newportmap == NULL)
- errx(1, "unable to malloc memory for new_portmap()");
- memset(newportmap, 0, sizeof(PORTMAP));
- return (newportmap);
- }
- /*
- * parses a string <port>:<port> and returns a new
- * PORTMAP datastruct
- */
- static PORTMAP *
- ports2PORT(char *ports)
- {
- PORTMAP *portmap = NULL;
- char *from_s, *to_s, *badchar;
- long from_l, to_l;
- char *token = NULL;
- /* first split the port numbers */
- from_s = strtok_r(ports, ":", &token);
- to_s = strtok_r(NULL, ":", &token);
- /* if there's anything left, it's a syntax error */
- if (strtok_r(NULL, ":", &token) != NULL)
- return NULL;
- /* if either of the parsed strings is NULL, we have a problem */
- if (from_s == NULL || to_s == NULL)
- return NULL;
- /* convert the strings to longs: if badchar points to anything
- * after, then it was a bad string
- */
- from_l = strtol(from_s, &badchar, 10);
- if (strlen(badchar) != 0)
- return NULL;
- to_l = strtol(to_s, &badchar, 10);
- if (strlen(badchar) != 0)
- return NULL;
- portmap = new_portmap();
- /* put the new portmap info into the new node
- * while we convert to network-byte order, b/c its better
- * to do it once now, rather then each time we have to do a lookup
- */
- portmap->from = htons(from_l);
- portmap->to = htons(to_l);
- /* return 1 for success */
- return portmap;
- }
- /*
- * Processes a string (ourstr) containing the portmap ("2000:4000" for
- * example) and places the data in **portmapdata and finally returns 1 for
- * success, 0 for fail.
- */
- int
- parse_portmap(PORTMAP ** portmap, char *ourstr)
- {
- PORTMAP *portmap_ptr;
- char *substr = NULL, *token = NULL;
- /* first iteration of input */
- substr = strtok_r(ourstr, ",", &token);
- if ((*portmap = ports2PORT(substr)) == NULL)
- return 0;
- portmap_ptr = *portmap;
- while (1) {
- substr = strtok_r(NULL, ",", &token);
- /* if that was the last one, kick out */
- if (substr == NULL)
- break;
- /* next record */
- portmap_ptr->next = ports2PORT(substr);
- portmap_ptr = portmap_ptr->next;
- }
- return 1;
- }
- /*
- * Free's all the memory associated with the given portmap chain
- */
- void
- free_portmap(PORTMAP * portmap)
- {
- /* recursively go down the portmaps */
- if (portmap->next != NULL)
- free_portmap(portmap->next);
- free(portmap);
- }
- /* This function takes a pointer to a portmap list and prints each node */
- void
- print_portmap(PORTMAP *portmap_data)
- {
- PORTMAP *portmap_ptr;
- portmap_ptr = portmap_data;
- while (portmap_ptr != NULL) {
- printf("from: %ld to: %ld\n", portmap_ptr->from, portmap_ptr->to);
- portmap_ptr = portmap_ptr->next;
- }
- printf("\n");
- }
- /* This function takes a portmap and a port, and returns the mapped port,
- * or the original port if it isn't mapped to anything.
- */
- long
- map_port(PORTMAP *portmap_data, long port)
- {
- PORTMAP *portmap_ptr;
- long newport;
- portmap_ptr = portmap_data;
- newport = port;
- /* step through the nodes, resetting newport if a match is found */
- while (portmap_ptr != NULL) {
- if (portmap_ptr->from == port)
- newport = portmap_ptr->to;
- portmap_ptr = portmap_ptr->next;
- }
- return(newport);
- }
- /*
- * rewrites the TCP or UDP ports based on a portmap
- * returns 1 for changes made or 0 for none
- */
- int
- rewrite_ports(PORTMAP * portmap, ip_hdr_t **ip_hdr)
- {
- tcp_hdr_t *tcp_hdr = NULL;
- udp_hdr_t *udp_hdr = NULL;
- int changes = 0;
- u_int16_t newport;
- if (*ip_hdr == NULL) {
- return 0;
- } else if ((*ip_hdr)->ip_p == IPPROTO_TCP) {
- tcp_hdr = (tcp_hdr_t *)get_layer4(*ip_hdr);
- /* check if we need to remap the destination port */
- newport = map_port(portmap, tcp_hdr->th_dport);
- if (newport != tcp_hdr->th_dport) {
- tcp_hdr->th_dport = newport;
- changes ++;
- }
- /* check if we need to remap the source port */
- newport = map_port(portmap, tcp_hdr->th_sport);
- if (newport != tcp_hdr->th_sport) {
- tcp_hdr->th_sport = newport;
- changes ++;
- }
-
- } else if ((*ip_hdr)->ip_p == IPPROTO_UDP) {
- udp_hdr = (udp_hdr_t *)get_layer4(*ip_hdr);
- /* check if we need to remap the destination port */
- newport = map_port(portmap, udp_hdr->uh_dport);
- if (newport != udp_hdr->uh_dport) {
- udp_hdr->uh_dport = newport;
- changes ++;
- }
- /* check if we need to remap the source port */
- newport = map_port(portmap, udp_hdr->uh_sport);
- if (newport != udp_hdr->uh_sport) {
- udp_hdr->uh_sport = newport;
- changes ++;
- }
-
- }
- return changes;
- }
|