1/* $Id$ */
2
3/*
4 *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
5 *   Copyright (c) 2013-2018 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
6 *
7 *   The Tcpreplay Suite of tools is free software: you can redistribute it
8 *   and/or modify it under the terms of the GNU General Public License as
9 *   published by the Free Software Foundation, either version 3 of the
10 *   License, or with the authors permission any later version.
11 *
12 *   The Tcpreplay Suite is distributed in the hope that it will be useful,
13 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 *   GNU General Public License for more details.
16 *
17 *   You should have received a copy of the GNU General Public License
18 *   along with the Tcpreplay Suite.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21autogen definitions options;
22
23copyright = {
24    date        = "2000-2018";
25    owner       = "Aaron Turner and Fred Klassen";
26    eaddr       = "tcpreplay-users@lists.sourceforge.net";
27    type        = gpl;
28    author      = <<- EOText
29Copyright 2013-2018 Fred Klassen - AppNeta
30
31Copyright 2000-2012 Aaron Turner
32
33For support please use the tcpreplay-users@lists.sourceforge.net mailing list.
34
35The latest version of this software is always available from:
36http://tcpreplay.appneta.com/
37EOText;
38};
39
40package         = "tcpprep";
41prog-name       = "tcpprep";
42prog-title      = "Create a tcpreplay cache cache file from a pcap file.";
43long-opts;
44gnu-usage;
45help-value      = "H";
46save-opts-value = "";
47load-opts-value = "";
48
49config-header   = "config.h";
50include         = "#include \"defines.h\"\n"
51                "#include \"common.h\"\n"
52                "#include \"config.h\"\n"
53                "#include \"tcpprep.h\"\n"
54                "#include <stdlib.h>\n"
55                "#include <string.h>\n"
56                "#include \"tcpprep_api.h\"\n"
57                "extern tcpprep_t *tcpprep;\n";
58
59homerc          = "$$/";
60
61explain = <<- EOExplain
62tcpprep is a @file{pcap(3)} file pre-processor which creates a cache
63file which provides "rules" for @file{tcprewrite(1)} and @file{tcpreplay(1)}
64on how to process and send packets.
65EOExplain;
66
67detail = <<- EODetail
68The basic operation of tcpreplay is to resend all packets from the
69input file(s) out a single file.  Tcpprep processes a pcap file and
70applies a set of user-specified rules to create a cache file which
71tells tcpreplay whether or not to send each packet and which interface the
72packet should be sent out of.
73
74For more details, please see the Tcpreplay Manual at:
75http://tcpreplay.appneta.com
76EODetail;
77
78man-doc = <<- EOMan
79.SH "SEE ALSO"
80tcpdump(1), tcpbridge(1), tcprewrite(1), tcpreplay(1), tcpcapinfo(1)
81EOMan;
82
83
84flag = {
85    ifdef       = DEBUG;
86    name        = dbug;
87    value       = d;
88    arg-type    = number;
89    max         = 1;
90    immediate;
91    arg-range   = "0->5";
92    arg-default = 0;
93    descrip     = "Enable debugging output";
94    doc         = <<- EOText
95If configured with --enable-debug, then you can specify a verbosity
96level for debugging output.  Higher numbers increase verbosity.
97EOText;
98};
99
100
101/* Modes: -a bridge/router/client/server, -c (cidr) */
102flag = {
103    name        = auto;
104    value       = a;
105    descrip     = "Auto-split mode";
106    arg-type    = string;
107    max         = 1;
108    flags-cant  = cidr;
109    flags-cant  = port;
110    flags-cant  = regex;
111    flags-cant  = mac;
112    flag-code   = <<- EOAuto
113
114    tcpprep->options->mode = AUTO_MODE;
115    if (strcmp(OPT_ARG(AUTO), "bridge") == 0) {
116        tcpprep->options->automode = BRIDGE_MODE;
117    }
118    else if (strcmp(OPT_ARG(AUTO), "router") == 0) {
119        tcpprep->options->automode = ROUTER_MODE;
120    }
121    else if (strcmp(OPT_ARG(AUTO), "client") == 0) {
122        tcpprep->options->automode = CLIENT_MODE;
123    }
124    else if (strcmp(OPT_ARG(AUTO), "server") == 0) {
125        tcpprep->options->automode = SERVER_MODE;
126    }
127    else if (strcmp(OPT_ARG(AUTO), "first") == 0) {
128        tcpprep->options->automode = FIRST_MODE;
129    }
130    else {
131        errx(-1, "Invalid auto mode type: %s", OPT_ARG(AUTO));
132    }
133EOAuto;
134    doc         = <<- EOText
135Tcpprep will try to automatically determine the primary function of hosts
136based on the traffic captured and classify each host as client or server.
137In order to do so, you must provide a hint to tcpprep as to how to search
138for clients and servers.  Valid hints are:
139
140@table @bullet
141@item
142@var{bridge}
143Bridge mode processes each packet to try to determine if the sender is a
144client or server.  Once all the packets are processed, the results are weighed
145according to the server/client ratio (@samp{--ratio}) and systems are assigned an
146interface.  If tcpprep is unable to determine what role a system plays, tcpprep
147will abort.
148@item
149@var{router}
150Router mode works just like bridge mode, except that after weighing is done,
151systems which are undetermined are considered a server if they fall inside a
152network known to contain other servers.  Router has a greater chance of
153successfully splitting clients and servers but is not 100% foolproof.
154@item
155@var{client}
156Client mode works just like bridge mode, except that unclassified systems are
157treated as clients.  Client mode should always complete successfully.
158@item
159@var{server}
160Server mode works just like bridge mode, except that unclassified systems are
161treated as servers.  Server mode should always complete successfully.
162@item
163@var{first}
164First mode works by looking at the first time each IP is seen in the SRC and DST
165fields in the IP header.  If the host is first seen in the SRC field, it is a
166client and if it's first seen in the DST field, it is marked as a server.   This
167effectively replicates the processing of the tomahawk test tool.  First
168mode should always complete successfully.
169@end table
170EOText;
171};
172
173
174flag = {
175    name        = cidr;
176    value       = c;
177    descrip     = "CIDR-split mode";
178    arg-type    = string;
179    max         = 1;
180    flags-cant  = auto;
181    flags-cant  = port;
182    flags-cant  = regex;
183    flags-cant  = mac;
184    flag-code   = <<- EOCidr
185
186    char *cidr = safe_strdup(OPT_ARG(CIDR));
187    tcpprep->options->mode = CIDR_MODE;
188    if (!parse_cidr(&tcpprep->options->cidrdata, cidr, ","))
189        errx(-1, "Unable to parse CIDR map: %s", OPT_ARG(CIDR));
190    free(cidr);
191
192EOCidr;
193    doc         = <<- EOText
194Specify a comma delimited list of CIDR netblocks to match against
195the source IP of each packet.  Packets matching any of the CIDR's
196are classified as servers.
197
198IPv4 Example:
199@example
200--cidr=192.168.0.0/16,172.16.0.0/12,10.0.0.0/8
201@end example
202IPv6 Example:
203@example
204--cidr=[::ffff:0:0/96],[fe80::/16]
205@end example
206EOText;
207};
208
209flag = {
210    name        = regex;
211    value       = r;
212    descrip     = "Regex-split mode";
213    arg-type    = string;
214    max         = 1;
215    flags-cant  = auto;
216    flags-cant  = port;
217    flags-cant  = cidr;
218    flags-cant  = mac;
219    flag-code   = <<- EORegex
220
221    int regex_error;
222    char ebuf[EBUF_SIZE];
223
224    tcpprep->options->mode = REGEX_MODE;
225    if ((regex_error = regcomp(&tcpprep->options->preg, OPT_ARG(REGEX),
226        REG_EXTENDED|REG_NOSUB))) {
227        regerror(regex_error, &tcpprep->options->preg, ebuf, EBUF_SIZE);
228        errx(-1, "Unable to compile regex: %s", ebuf);
229    }
230
231EORegex;
232    doc         = <<- EOText
233Specify a regular expression to match against the source IP of each
234packet.  Packets matching the regex are classified as servers.
235EOText;
236};
237
238flag = {
239    name        = port;
240    value       = p;
241    descrip     = "Port-split mode";
242    max         = 1;
243    flags-cant  = auto;
244    flags-cant  = regex;
245    flags-cant  = cidr;
246    flags-cant  = mac;
247    flag-code   = <<- EOPort
248
249    tcpprep->options->mode = PORT_MODE;
250
251EOPort;
252    doc         = <<- EOText
253Specifies that TCP and UDP traffic over IPv4 and IPv6 should be classified
254as client or server based upon the destination port of the header.
255EOText;
256};
257
258flag = {
259    name        = mac;
260    value       = e;
261    arg-type    = string;
262    max         = 1;
263    descrip     = "Source MAC split mode";
264    flags-cant  = auto;
265    flags-cant  = regex;
266    flags-cant  = cidr;
267    flags-cant  = port;
268    flag-code   = <<- EOMac
269
270    tcpprep->options->mode = MAC_MODE;
271    tcpprep->options->maclist = safe_strdup(OPT_ARG(MAC));
272EOMac;
273
274    doc          = <<- EOText
275Specify a list of MAC addresses to match against the source MAC
276of each packet.  Packets matching one of the values are classified
277as servers.
278EOText;
279};
280
281flag = {
282    name        = reverse;
283    max         = 1;
284    descrip     = "Matches to be client instead of server";
285    doc         = <<- EOText
286Normally the @samp{--mac}, @samp{--regex} and @samp{--cidr} flags specify are used to specify
287the servers and non-IP packets are classified as clients.  By using @samp{--reverse}, these
288features are reversed so that the flags specify clients and non-IP packets are classified as
289servers.
290EOText;
291};
292
293flag = {
294    name        = comment;
295    value       = C;
296    arg-type    = string;
297    max         = 1;
298    descrip     = "Embedded cache file comment";
299    flag-code   = <<- EOComment
300
301    /* our comment_len is only 16bit - myargs[] */
302    if (strlen(OPT_ARG(COMMENT)) > ((1 << 16) - 1 - MYARGS_LEN))
303                errx(-1, "Comment length %zu is longer then max allowed (%d)",
304                strlen(OPT_ARG(COMMENT)), (1 << 16) - 1 - MYARGS_LEN);
305
306    /* save the comment */
307    tcpprep->options->comment = (char *)safe_malloc(strlen(OPT_ARG(COMMENT)) + 1);
308    strcpy(tcpprep->options->comment, OPT_ARG(COMMENT));
309
310EOComment;
311    doc         = <<- EOText
312Specify a comment to be imbedded within the output cache file and later
313viewed.
314EOText;
315};
316
317flag = {
318    name      = no-arg-comment;
319    max       = 1;
320    descrip   = "Do not embed any cache file comment";
321    flag-code = <<- EOCode
322
323tcpprep->options->nocomment = 1;
324EOCode;
325    doc       = <<- EOText
326By default, tcpprep includes the arguments passed on the command line
327in the cache file comment (in addition to any user specified --comment).
328If for some reason you do not wish to include this, specify this option.
329EOText;
330};
331
332
333/* Include/Exclude */
334flag = {
335    name        = include;
336    value       = x;
337    arg-type    = string;
338    max         = 1;
339    descrip     = "Include only packets matching rule";
340    flags-cant  = exclude;
341    flag-code   = <<- EOInclude
342
343    char *include;
344
345    include = safe_strdup(OPT_ARG(INCLUDE));
346    tcpprep->options->xX.mode = xX_MODE_INCLUDE;
347
348    if ((tcpprep->options->xX.mode = parse_xX_str(&tcpprep->options->xX, include, &tcpprep->options->bpf)) == xXError)
349        errx(-1, "Unable to parse include/exclude rule: %s", OPT_ARG(INCLUDE));
350
351    free(include);
352
353EOInclude;
354    doc         = <<- EOText
355Override default of processing all packets stored in the capture file and only
356send/edit packets which match the provided rule.  Rules can be one of:
357
358@table @bullet
359@item S:<CIDR1>,...
360- Source IP must match specified IPv4/v6 CIDR(s)
361@item D:<CIDR1>,...
362- Destination IP must match specified IPv4/v6 CIDR(s)
363@item B:<CIDR1>,...
364- Both source and destination IP must match specified IPv4/v6 CIDR(s)
365@item E:<CIDR1>,...
366- Either IP must match specified IPv4/v6 CIDR(s)
367@item P:<LIST>
368- Must be one of the listed packets where the list
369corresponds to the packet number in the capture file.
370@example
371-x P:1-5,9,15,72-
372@end example
373would process packets 1 through 5, the 9th and 15th packet, and packets 72 until the
374end of the file
375@item F:'<bpf>'
376- BPF filter.  See the @file{tcpdump(8)} man page for syntax.
377@end table
378EOText;
379};
380
381flag = {
382    name        = exclude;
383    value       = X;
384    arg-type    = string;
385    max         = 1;
386    descrip     = "Exclude any packet matching this rule";
387    flags-cant  = include;
388    flag-code   = <<- EOExclude
389
390    char *exclude;
391
392    exclude = safe_strdup(OPT_ARG(EXCLUDE));
393    tcpprep->options->xX.mode = xX_MODE_EXCLUDE;
394
395    if ((tcpprep->options->xX.mode = parse_xX_str(&tcpprep->options->xX, exclude, &tcpprep->options->bpf)) == xXError)
396        errx(-1, "Unable to parse include/exclude rule: %s", OPT_ARG(EXCLUDE));
397
398    free(exclude);
399
400EOExclude;
401    doc         = <<- EOText
402Override default of processing all packets stored in the capture file and only
403send/edit packets which do NOT match the provided rule.  Rules can be one of:
404
405@table @bullet
406@item S:<CIDR1>,...
407- Source IP must not match specified IPv4/v6 CIDR(s)
408@item D:<CIDR1>,...
409- Destination IP must not match specified IPv4/v6 CIDR(s)
410@item B:<CIDR1>,...
411- Both source and destination IP must not match specified IPv4/v6 CIDR(s)
412@item E:<CIDR1>,...
413- Either IP must not match specified IPv4/v6 CIDR(s)
414@item P:<LIST>
415- Must not be one of the listed packets where the list
416corresponds to the packet number in the capture file.
417@example
418-x P:1-5,9,15,72-
419@end example
420would skip packets 1 through 5, the 9th and 15th packet, and packets 72 until the
421end of the file
422@end table
423EOText;
424};
425
426flag = {
427    name        = cachefile;
428    value       = o;
429    arg-type    = string;
430    max         = 1;
431    descrip     = "Output cache file";
432    doc         = "";
433};
434
435flag = {
436    name        = pcap;
437    value       = i;
438    descrip     = "Input pcap file to process";
439    arg-type    = string;
440    max         = 1;
441    doc         = "";
442};
443
444flag = {
445    name        = print-comment;
446    value       = P;
447    arg-type    = string;
448    descrip     = "Print embedded comment in the specified cache file";
449    max         = 1;
450    doc         = "";
451};
452
453flag = {
454    name        = print-info;
455    value       = I;
456    arg-type    = string;
457    descrip     = "Print basic info from the specified cache file";
458    max         = 1;
459    doc         = "";
460};
461
462flag = {
463    name     = print-stats;
464    value    = S;
465    arg-type = string;
466    descrip  = "Print statistical information about the specified cache file";
467    max      = 1;
468    doc      = "";
469};
470
471flag = {
472    name        = services;
473    value       = s;
474    descrip     = "Load services file for server ports";
475    flags-must  = port;
476    max         = 1;
477    arg-type    = string;
478    doc         = <<- EOText
479Uses a list of ports used by servers in the same format as of /etc/services:
480<service_name>        <port>/<protocol> # comment
481
482Example:
483http            80/tcp
484EOText;
485    flag-code   = <<- EOServices
486    parse_services(OPT_ARG(SERVICES), &tcpprep->options->services);
487
488EOServices;
489};
490
491flag = {
492    name        = nonip;
493    value       = N;
494    descrip     = "Send non-IP traffic out server interface";
495    max         = 1;
496    flag-code   = <<- EONonip
497
498    tcpprep->options->nonip = DIR_SERVER;
499
500EONonip;
501    doc         = <<- EOText
502By default, non-IP traffic which can not be classified as client
503or server is classified as "client".  Specifying @samp{--nonip}
504will reclassify non-IP traffic as "server".  Note that the meaning
505of this flag is reversed if @samp{--reverse} is used.
506EOText;
507};
508
509
510flag = {
511    name        = ratio;
512    value       = R;
513    arg-type    = string;
514    max         = 1;
515    flags-must  = auto;
516    arg_default = "2.0";
517    descrip     = "Ratio of client to server packets";
518    doc         = <<- EOText
519Since a given host may have both client and server traffic being sent
520to/from it, tcpprep uses a ratio to weigh these packets.  If you would
521like to override the default of 2:1 server to client packets required for
522a host to be classified as a server, specify it as a floating point value.
523EOText;
524};
525
526
527flag = {
528    name        = minmask;
529    value       = m;
530    descrip     = "Minimum network mask length in auto mode";
531    flags-must  = auto;
532    max         = 1;
533    arg-type    = number;
534    arg-range   = "0->32";
535    arg_default = 30;
536    doc         = <<- EOText
537By default, auto modes use a minimum network mask length of 30 bits
538to build networks containing clients and servers.  This allows you
539to override this value.  Larger values will increase performance but
540may provide inaccurate results.
541EOText;
542};
543
544flag = {
545    name        = maxmask;
546    value       = M;
547    descrip     = "Maximum network mask length in auto mode";
548    flags-must  = auto;
549    max         = 1;
550    arg-type    = number;
551    arg-range   = "0->32";
552    arg_default = 8;
553    doc         = <<- EOText
554By default, auto modes use a maximum network mask length of 8 bits
555to build networks containing clients and servers.  This allows you
556to override this value.  Larger values will decrease performance
557and accuracy but will provide greater chance of success.
558EOText;
559};
560
561flag = {
562    ifdef       = ENABLE_VERBOSE;
563    name        = verbose;
564    value       = v;
565    max         = 1;
566    immediate;
567    descrip     = "Print decoded packets via tcpdump to STDOUT";
568    settable;
569    doc         = "";
570};
571
572flag = {
573    ifdef       = ENABLE_VERBOSE;
574    name        = decode;
575    flags-must  = verbose;
576    value       = A;
577    arg-type    = string;
578    max         = 1;
579    descrip     = "Arguments passed to tcpdump decoder";
580    doc         = <<- EOText
581When enabling verbose mode (@samp{-v}) you may also specify one or
582more additional arguments to pass to @code{tcpdump} to modify
583the way packets are decoded.  By default, -n and -l are used.
584Be sure to quote the arguments so that they are not interpreted
585by tcprewrite.  The following arguments are valid:
586    [ -aAeNqRStuvxX ]
587    [ -E spi@ipaddr algo:secret,... ]
588    [ -s snaplen ]
589EOText;
590};
591
592
593flag = {
594    name        = version;
595    value       = V;
596    descrip     = "Print version information";
597    flag-code   = <<- EOVersion
598
599    fprintf(stderr, "tcpprep version: %s (build %s)", VERSION, git_version());
600#ifdef DEBUG
601    fprintf(stderr, " (debug)");
602#endif
603    fprintf(stderr, "\n");
604    fprintf(stderr, "Copyright 2013-2018 by Fred Klassen <tcpreplay at appneta dot com> - AppNeta\n");
605    fprintf(stderr, "Copyright 2000-2012 by Aaron Turner <aturner at synfin dot net>\n");
606    fprintf(stderr, "The entire Tcpreplay Suite is licensed under the GPLv3\n");
607    fprintf(stderr, "Cache file supported: %s\n", CACHEVERSION);
608#ifdef HAVE_LIBDNET
609    fprintf(stderr, "Compiled against libdnet: %s\n", LIBDNET_VERSION);
610#else
611    fprintf(stderr, "Not compiled with libdnet.\n");
612#endif
613#ifdef HAVE_WINPCAP
614    fprintf(stderr, "Compiled against winpcap: %s\n", get_pcap_version());
615#elif defined HAVE_PF_RING_PCAP
616    fprintf(stderr, "Compiled against PF_RING libpcap: %s\n", get_pcap_version());
617#else
618    fprintf(stderr, "Compiled against libpcap: %s\n", get_pcap_version());
619#endif
620#ifdef ENABLE_64BITS
621    fprintf(stderr, "64 bit packet counters: enabled\n");
622#else
623    fprintf(stderr, "64 bit packet counters: disabled\n");
624#endif
625#ifdef ENABLE_VERBOSE
626    fprintf(stderr, "Verbose printing via tcpdump: enabled\n");
627#else
628    fprintf(stderr, "Verbose printing via tcpdump: disabled\n");
629#endif
630    exit(0);
631
632EOVersion;
633    doc         = "";
634};
635
636flag = {
637    name        = less-help;
638    value       = "h";
639    immediate;
640    descrip     = "Display less usage information and exit";
641    flag-code   = <<- EOHelp
642
643    USAGE(EXIT_FAILURE);
644
645EOHelp;
646};
647