Use the new routines in Wiretap to make the argument to "-T" be a
[obnox/wireshark/wip.git] / editcap.c
1 /* Edit capture files.  We can delete records, or simply convert from one 
2  * format to another format.
3  *
4  * $Id: editcap.c,v 1.3 1999/12/05 01:27:14 guy Exp $
5  *
6  * Originally written by Richard Sharpe.
7  * Improved by Guy Harris.
8  */
9
10 #include <stdio.h>
11 #include <glib.h>
12 #include <unistd.h>
13 #include <sys/time.h>
14 #include "wtap.h"
15
16 /*
17  * Some globals so we can pass things to various routines
18  */
19
20 int selectfrm[100], max_selected = -1;
21 static int count = 1;
22 static int keep_em = 0;
23 static int out_file_type = WTAP_FILE_PCAP;      /* default to "libpcap" */
24 static int out_frame_type = -2;   /* Leave frame type alone */
25
26 /* Was the record selected? */
27
28 int selected(int recno)
29 {
30   int i = 0;
31
32   for (i = 0; i<= max_selected; i++) {
33
34     if (recno == selectfrm[i]) return 1;
35
36   }
37
38   return 0;
39
40 }
41
42 /* An argument to the callback routine */
43
44 typedef struct {
45         char    *filename;
46         wtap_dumper *pdh;
47 } callback_arg;
48
49 /*
50  *The callback routine that is called for each frame in the input file
51  */
52
53 static void
54 edit_callback(u_char *user, const struct wtap_pkthdr *phdr, int offset,
55     const u_char *buf) 
56 {
57   callback_arg *argp = (callback_arg *)user;
58   int err;
59
60   if ((!selected(count) && !keep_em) ||
61       (selected(count) && keep_em)) {
62
63     printf("Record: %u\n", count);
64
65     /* We simply write it, we could do other things, like modify it */
66
67     if (!wtap_dump(argp->pdh, phdr, buf, &err)) {
68
69       fprintf(stderr, "editcap: Error writing to %s: %s\n", argp->filename,
70         wtap_strerror(err));
71       exit(1);
72
73     }
74
75   }
76
77   count++;
78
79 }
80
81 void usage()
82 {
83   int i;
84   char *string;
85
86   fprintf(stderr, "Usage: editcap [-r] [-T <encap type>] [-F <capture type>] <infile> <outfile>\\\n");
87   fprintf(stderr, "                [ <record#> ... ]\n");
88   fprintf(stderr, "  where\t-r specifies that the records specified should be kept, not deleted, \n");
89   fprintf(stderr, "                           default is to delete\n");
90   fprintf(stderr, "       \t-T <encap type> specifies the encapsulation type to use:\n");
91   for (i = 0; i < WTAP_NUM_ENCAP_TYPES; i++) {
92       string = wtap_encap_short_string(i);
93       if (string != NULL)
94         fprintf(stderr, "       \t    %s - %s\n",
95           string, wtap_encap_string(i));
96   }
97   fprintf(stderr, "       \t   default is the same as the input file\n");
98   fprintf(stderr, "       \t-F <capture type> specifies the capture file type to write:\n");
99   for (i = 0; i < WTAP_NUM_FILE_TYPES; i++) {
100     if (wtap_dump_can_open(i))
101       fprintf(stderr, "       \t    %s - %s\n",
102         wtap_file_type_short_string(i), wtap_file_type_string(i));
103   }
104   fprintf(stderr, "       \t   default is libpcap\n");
105 }
106
107 int main(int argc, char *argv[])
108
109 {
110   wtap *wth;
111   int read_bytes, pcnt = 0, i, err;
112   callback_arg args;
113   extern char *optarg;
114   extern int optind, opterr, optopt;
115   char opt;
116
117   /* Process the options first */
118
119   while ((opt = getopt(argc, argv, "T:F:r")) != EOF) {
120
121     switch (opt) {
122
123     case 'T':
124       out_frame_type = wtap_short_string_to_encap(optarg);
125       if (out_frame_type < 0) {
126         fprintf(stderr, "editcap: \"%s\" is not a valid encapsulation type\n",
127             optarg);
128         exit(1);
129       }
130       break;
131       
132     case 'F':
133       out_file_type = wtap_short_string_to_file_type(optarg);
134       if (out_file_type < 0) {
135         fprintf(stderr, "editcap: \"%s\" is not a valid capture file type\n",
136             optarg);
137         exit(1);
138       }
139       break;
140
141     case 'r':
142       keep_em = !keep_em;  /* Just invert */
143       break;
144
145     case '?':              /* Bad options if GNU getopt */
146       usage();
147       exit(1);
148       break;
149
150     }
151
152   }
153
154   printf("Optind = %i, argc = %i\n", optind, argc);
155
156   if ((argc - optind) < 2) {
157
158     usage();
159     exit(1);
160
161   }
162
163   wth = wtap_open_offline(argv[optind], &err);
164
165   if (!wth) {
166
167     fprintf(stderr, "editcap: Can't open %s: %s\n", argv[optind],
168         wtap_strerror(err));
169     exit(1);
170
171   }
172
173   args.filename = argv[optind + 1];
174   if (out_frame_type == -2)
175     out_frame_type = wtap_file_encap(wth);
176
177   args.pdh = wtap_dump_open(argv[optind + 1], out_file_type,
178                 out_frame_type, wtap_snapshot_length(wth), &err);
179   if (args.pdh == NULL) {
180
181     fprintf(stderr, "editcap: Can't open or create %s: %s\n", argv[optind+1],
182         wtap_strerror(err));
183     exit(1);
184
185   }
186
187   for (i = optind + 2; i < argc; i++)
188     selectfrm[++max_selected] = atoi(argv[i]);
189
190   wtap_loop(wth, 0, edit_callback, (char *)&args, &err);
191
192   if (!wtap_dump_close(args.pdh, &err)) {
193
194     fprintf(stderr, "editcap: Error writing to %s: %s\n", argv[2],
195         wtap_strerror(err));
196     exit(1);
197
198   }
199   exit(0);
200 }
201