portmap.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. /* $Id: portmap.c 1757 2007-03-22 05:38:56Z aturner $ */
  2. /*
  3. * Copyright (c) 2001-2007 Aaron Turner.
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. *
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. Neither the names of the copyright owners nor the names of its
  16. * contributors may be used to endorse or promote products derived from
  17. * this software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  20. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  21. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  22. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  23. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  24. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  25. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  26. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
  27. * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  28. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  29. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. */
  31. /*
  32. * This file contains routines to manipulate port maps, in which
  33. * one port number is mapped to another.
  34. */
  35. #include "config.h"
  36. #include "defines.h"
  37. #include "common.h"
  38. #include <stdlib.h>
  39. #include <string.h>
  40. #include <errno.h>
  41. #include "tcpreplay.h"
  42. #include "tcpedit-int.h"
  43. #include "portmap.h"
  44. tcpedit_portmap_t *
  45. new_portmap()
  46. {
  47. tcpedit_portmap_t *newportmap;
  48. newportmap = (tcpedit_portmap_t *)safe_malloc(sizeof(tcpedit_portmap_t));
  49. return (newportmap);
  50. }
  51. /*
  52. * parses a string <port>:<port> and returns a new
  53. * tcpedit_portmap_t datastruct
  54. */
  55. static tcpedit_portmap_t *
  56. ports2PORT(char *ports)
  57. {
  58. tcpedit_portmap_t *portmap = NULL;
  59. char *from_s, *to_s, *badchar;
  60. long from_l, to_l;
  61. char *token = NULL;
  62. assert(ports);
  63. /* first split the port numbers */
  64. from_s = strtok_r(ports, ":", &token);
  65. to_s = strtok_r(NULL, ":", &token);
  66. /* if there's anything left, it's a syntax error */
  67. if (strtok_r(NULL, ":", &token) != NULL)
  68. return NULL;
  69. /* if either of the parsed strings is NULL, we have a problem */
  70. if (from_s == NULL || to_s == NULL)
  71. return NULL;
  72. /* convert the strings to longs: if badchar points to anything
  73. * after, then it was a bad string
  74. */
  75. from_l = strtol(from_s, &badchar, 10);
  76. if (strlen(badchar) != 0)
  77. return NULL;
  78. to_l = strtol(to_s, &badchar, 10);
  79. if (strlen(badchar) != 0)
  80. return NULL;
  81. portmap = new_portmap();
  82. /* put the new portmap info into the new node
  83. * while we convert to network-byte order, b/c its better
  84. * to do it once now, rather then each time we have to do a lookup
  85. */
  86. portmap->from = htons(from_l);
  87. portmap->to = htons(to_l);
  88. /* return 1 for success */
  89. return portmap;
  90. }
  91. /*
  92. * Processes a string (ourstr) containing the portmap ("2000:4000" for
  93. * example) and places the data in **portmapdata and finally returns 1 for
  94. * success, 0 for fail.
  95. */
  96. int
  97. parse_portmap(tcpedit_portmap_t ** portmap, const char *ourstr)
  98. {
  99. tcpedit_portmap_t *portmap_ptr;
  100. char *substr = NULL, *ourstrcpy = NULL, *token = NULL;
  101. assert(ourstr);
  102. ourstrcpy = safe_strdup(ourstr);
  103. /* first iteration of input */
  104. substr = strtok_r(ourstrcpy, ",", &token);
  105. if ((*portmap = ports2PORT(substr)) == NULL)
  106. return 0;
  107. portmap_ptr = *portmap;
  108. while (1) {
  109. substr = strtok_r(NULL, ",", &token);
  110. /* if that was the last one, kick out */
  111. if (substr == NULL)
  112. break;
  113. /* next record */
  114. portmap_ptr->next = ports2PORT(substr);
  115. portmap_ptr = portmap_ptr->next;
  116. }
  117. return 1;
  118. }
  119. /*
  120. * Free's all the memory associated with the given portmap chain
  121. */
  122. void
  123. free_portmap(tcpedit_portmap_t * portmap)
  124. {
  125. assert(portmap);
  126. /* recursively go down the portmaps */
  127. if (portmap->next != NULL)
  128. free_portmap(portmap->next);
  129. free(portmap);
  130. }
  131. /* This function takes a pointer to a portmap list and prints each node */
  132. void
  133. print_portmap(tcpedit_portmap_t *portmap_data)
  134. {
  135. tcpedit_portmap_t *portmap_ptr;
  136. assert(portmap_data);
  137. portmap_ptr = portmap_data;
  138. while (portmap_ptr != NULL) {
  139. printf("from: %ld to: %ld\n", portmap_ptr->from, portmap_ptr->to);
  140. portmap_ptr = portmap_ptr->next;
  141. }
  142. printf("\n");
  143. }
  144. /* This function takes a portmap and a port, and returns the mapped port,
  145. * or the original port if it isn't mapped to anything.
  146. */
  147. long
  148. map_port(tcpedit_portmap_t *portmap_data, long port)
  149. {
  150. tcpedit_portmap_t *portmap_ptr;
  151. long newport;
  152. assert(portmap_data);
  153. portmap_ptr = portmap_data;
  154. newport = port;
  155. /* step through the nodes, resetting newport if a match is found */
  156. while (portmap_ptr != NULL) {
  157. if (portmap_ptr->from == port)
  158. newport = portmap_ptr->to;
  159. portmap_ptr = portmap_ptr->next;
  160. }
  161. return(newport);
  162. }
  163. /*
  164. * rewrites the TCP or UDP ports based on a portmap
  165. * returns 1 for changes made or 0 for none
  166. */
  167. int
  168. rewrite_ports(tcpedit_t *tcpedit, ipv4_hdr_t **ip_hdr)
  169. {
  170. tcp_hdr_t *tcp_hdr = NULL;
  171. udp_hdr_t *udp_hdr = NULL;
  172. int changes = 0;
  173. u_int16_t newport;
  174. tcpedit_portmap_t *portmap;
  175. assert(tcpedit);
  176. assert(tcpedit->portmap);
  177. portmap = tcpedit->portmap;
  178. if (*ip_hdr == NULL) {
  179. return 0;
  180. } else if ((*ip_hdr)->ip_p == IPPROTO_TCP) {
  181. tcp_hdr = (tcp_hdr_t *)get_layer4(*ip_hdr);
  182. /* check if we need to remap the destination port */
  183. newport = map_port(portmap, tcp_hdr->th_dport);
  184. if (newport != tcp_hdr->th_dport) {
  185. tcp_hdr->th_dport = newport;
  186. changes ++;
  187. }
  188. /* check if we need to remap the source port */
  189. newport = map_port(portmap, tcp_hdr->th_sport);
  190. if (newport != tcp_hdr->th_sport) {
  191. tcp_hdr->th_sport = newport;
  192. changes ++;
  193. }
  194. } else if ((*ip_hdr)->ip_p == IPPROTO_UDP) {
  195. udp_hdr = (udp_hdr_t *)get_layer4(*ip_hdr);
  196. /* check if we need to remap the destination port */
  197. newport = map_port(portmap, udp_hdr->uh_dport);
  198. if (newport != udp_hdr->uh_dport) {
  199. udp_hdr->uh_dport = newport;
  200. changes ++;
  201. }
  202. /* check if we need to remap the source port */
  203. newport = map_port(portmap, udp_hdr->uh_sport);
  204. if (newport != udp_hdr->uh_sport) {
  205. udp_hdr->uh_sport = newport;
  206. changes ++;
  207. }
  208. }
  209. return changes;
  210. }
  211. /*
  212. Local Variables:
  213. mode:c
  214. indent-tabs-mode:nil
  215. c-basic-offset:4
  216. End:
  217. */