parse_args.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. /* $Id: parse_args.c 2211 2009-02-18 02:48:04Z aturner $ */
  2. /*
  3. * Copyright (c) 2006 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. #include "config.h"
  32. #include "defines.h"
  33. #include "common.h"
  34. #include "tcpedit-int.h"
  35. #include "tcpedit_stub.h"
  36. #include "parse_args.h"
  37. #include "portmap.h"
  38. #include <string.h>
  39. #include <stdlib.h>
  40. /**
  41. * returns 0 for sucess w/o errors
  42. * returns 1 for sucess w/ warnings
  43. * returns -1 for error
  44. */
  45. int
  46. tcpedit_post_args(tcpedit_t **tcpedit_ex) {
  47. tcpedit_t *tcpedit;
  48. int rcode = 0;
  49. long ttl;
  50. assert(tcpedit_ex);
  51. tcpedit = *tcpedit_ex;
  52. assert(tcpedit);
  53. /* --pnat */
  54. if (HAVE_OPT(PNAT)) {
  55. int ct = STACKCT_OPT(PNAT);
  56. char **list = STACKLST_OPT(PNAT);
  57. int first = 1;
  58. tcpedit->rewrite_ip ++;
  59. do {
  60. char *p = *list++;
  61. if (first) {
  62. if (! parse_cidr_map(&tcpedit->cidrmap1, p)) {
  63. tcpedit_seterr(tcpedit,
  64. "Unable to parse first --pnat=%s", p);
  65. return -1;
  66. }
  67. } else {
  68. if (! parse_cidr_map(&tcpedit->cidrmap2, p)) {
  69. tcpedit_seterr(tcpedit,
  70. "Unable to parse second --pnat=%s", p);
  71. return -1;
  72. }
  73. }
  74. first = 0;
  75. } while (--ct > 0);
  76. }
  77. /* --srcipmap */
  78. if (HAVE_OPT(SRCIPMAP)) {
  79. tcpedit->rewrite_ip ++;
  80. if (! parse_cidr_map(&tcpedit->srcipmap, OPT_ARG(SRCIPMAP))) {
  81. tcpedit_seterr(tcpedit,
  82. "Unable to parse --srcipmap=%s", OPT_ARG(SRCIPMAP));
  83. return -1;
  84. }
  85. }
  86. /* --dstipmap */
  87. if (HAVE_OPT(DSTIPMAP)) {
  88. tcpedit->rewrite_ip ++;
  89. if (! parse_cidr_map(&tcpedit->dstipmap, OPT_ARG(DSTIPMAP))) {
  90. tcpedit_seterr(tcpedit,
  91. "Unable to parse --dstipmap=%s", OPT_ARG(DSTIPMAP));
  92. return -1;
  93. }
  94. }
  95. /*
  96. * If we have one and only one -N, then use the same map data
  97. * for both interfaces/files
  98. */
  99. if ((tcpedit->cidrmap1 != NULL) && (tcpedit->cidrmap2 == NULL))
  100. tcpedit->cidrmap2 = tcpedit->cidrmap1;
  101. /* --fixcsum */
  102. if (HAVE_OPT(FIXCSUM))
  103. tcpedit->fixcsum = 1;
  104. /* --efcs */
  105. if (HAVE_OPT(EFCS))
  106. tcpedit->efcs = 1;
  107. /* --ttl */
  108. if (HAVE_OPT(TTL)) {
  109. if (strchr(OPT_ARG(TTL), '+')) {
  110. tcpedit->ttl_mode = TCPEDIT_TTL_ADD;
  111. } else if (strchr(OPT_ARG(TTL), '-')) {
  112. tcpedit->ttl_mode = TCPEDIT_TTL_SUB;
  113. } else {
  114. tcpedit->ttl_mode = TCPEDIT_TTL_SET;
  115. }
  116. ttl = strtol(OPT_ARG(TTL), (char **)NULL, 10);
  117. if (ttl < 0)
  118. ttl *= -1; /* convert to positive value */
  119. if (ttl > 255)
  120. errx(-1, "Invalid --ttl value (must be 0-255): %ld", ttl);
  121. tcpedit->ttl_value = (u_int8_t)ttl;
  122. }
  123. /* --tos */
  124. if (HAVE_OPT(TOS))
  125. tcpedit->tos = OPT_VALUE_TOS;
  126. /* --mtu */
  127. if (HAVE_OPT(MTU))
  128. tcpedit->mtu = OPT_VALUE_MTU;
  129. /* --mtu-trunc */
  130. if (HAVE_OPT(MTU_TRUNC))
  131. tcpedit->mtu_truncate = 1;
  132. /* --skipbroadcast */
  133. if (HAVE_OPT(SKIPBROADCAST))
  134. tcpedit->skip_broadcast = 1;
  135. /* --fixlen */
  136. if (HAVE_OPT(FIXLEN)) {
  137. if (strcmp(OPT_ARG(FIXLEN), "pad") == 0) {
  138. tcpedit->fixlen = TCPEDIT_FIXLEN_PAD;
  139. } else if (strcmp(OPT_ARG(FIXLEN), "trunc") == 0) {
  140. tcpedit->fixlen = TCPEDIT_FIXLEN_TRUNC;
  141. } else if (strcmp(OPT_ARG(FIXLEN), "del") == 0) {
  142. tcpedit->fixlen = TCPEDIT_FIXLEN_DEL;
  143. } else {
  144. tcpedit_seterr(tcpedit, "Invalid --fixlen=%s", OPT_ARG(FIXLEN));
  145. return -1;
  146. }
  147. }
  148. /* TCP/UDP port rewriting */
  149. if (HAVE_OPT(PORTMAP)) {
  150. if (! parse_portmap(&tcpedit->portmap, OPT_ARG(PORTMAP))) {
  151. tcpedit_seterr(tcpedit,
  152. "Unable to parse --portmap=%s", OPT_ARG(PORTMAP));
  153. return -1;
  154. }
  155. }
  156. /*
  157. * IP address rewriting processing. Call srandom() then add up
  158. * 5 calls to random() as our mixer for randomizing. This should
  159. * work better since most people aren't going to write out values
  160. * close to 32bit integers.
  161. */
  162. if (HAVE_OPT(SEED)) {
  163. tcpedit->rewrite_ip = TCPEDIT_REWRITE_IP_ON;
  164. srandom(OPT_VALUE_SEED);
  165. tcpedit->seed = random() + random() + random() + random() + random();
  166. }
  167. if (HAVE_OPT(ENDPOINTS)) {
  168. tcpedit->rewrite_ip = TCPEDIT_REWRITE_IP_ON;
  169. if (! parse_endpoints(&tcpedit->cidrmap1, &tcpedit->cidrmap2,
  170. OPT_ARG(ENDPOINTS))) {
  171. tcpedit_seterr(tcpedit,
  172. "Unable to parse --endpoints=%s", OPT_ARG(ENDPOINTS));
  173. return -1;
  174. }
  175. }
  176. /*
  177. * figure out the max packet len
  178. if (tcpedit->l2.enabled) {
  179. // custom l2 header
  180. dbg(1, "Using custom L2 header to calculate max frame size\n");
  181. tcpedit->maxpacket = tcpedit->mtu + tcpedit->l2.len;
  182. }
  183. else if (tcpedit->l2.dlt == DLT_EN10MB || tcpedit->l2.dlt == DLT_VLAN) {
  184. // ethernet
  185. dbg(1, "Using Ethernet to calculate max frame size\n");
  186. tcpedit->maxpacket = tcpedit->mtu + TCPR_ETH_H;
  187. } else {
  188. // uh, wtf is this now? we'll just assume ethernet and hope things work
  189. tcpedit->maxpacket = tcpedit->mtu + TCPR_ETH_H;
  190. tcpedit_seterr(tcpedit,
  191. "Unsupported DLT type: %s. We'll just treat it as ethernet.\n"
  192. "You may need to increase the MTU (-t <size>) if you get errors\n",
  193. pcap_datalink_val_to_name(tcpedit->l2.dlt));
  194. rcode = 1;
  195. }
  196. */
  197. return rcode;
  198. }