ldb speed test - needs free block dev
[tridge/junkcode.git] / snoop2cap.c
1 /* convert a snoop capture file to a netmon .cap file.
2      by Seiichi Tatsukawa (stat@rational.com), March 1998.
3
4    Based on capconvert.c by Andrew Tridgell, October 1997
5
6    This only works for 32 bit boxes at the moment. Change the typedefs
7    to work on other sytems
8 */
9
10 #include <stdlib.h>
11 #ifdef WIN32
12 #include <io.h>
13 #else
14 #include <unistd.h>
15 #endif
16 #include <memory.h>
17 #include <sys/types.h>
18 #include <sys/time.h>
19 #include <time.h>
20 #include <stdio.h>
21 #include <fcntl.h>
22 #include <string.h>
23
24 /* change the following 3 lines to make things work on
25    systems with different word sizes */
26 typedef int int32;
27 typedef unsigned int uint32;
28 typedef unsigned short uint16;
29
30
31 /* #define _DEBUG 1 */
32
33 #define SNOOP_MAGIC "snoop\0\0\0"
34
35 #ifndef WIN32
36 #define O_BINARY        0
37 #else
38 #pragma pack(push)
39 #pragma pack(1)
40
41 struct timeval {
42         uint32  tv_sec;         /* seconds */
43         int32   tv_usec;        /* and microseconds */
44 };
45 #endif
46
47 /* snoop file format */
48 struct snoop_file_header {
49         union {
50                 uint32 m[2];
51                 char magic[8];
52         } u;
53         uint16 major;
54         uint16 minor;
55         uint32 linktype;
56 };
57
58 struct snoop_packet {
59         uint32 caplen;
60         uint32 len;
61         uint32 offset;
62         uint32 pad1;
63         struct timeval ts;
64 };
65
66
67 /* .cap file format */
68 typedef struct _systemtime {
69     uint16 wYear;
70     uint16 wMonth; 
71     uint16 wDayOfWeek;
72     uint16 wDay;
73     uint16 wHour;
74     uint16 wMinute; 
75     uint16 wSecond;
76     uint16 wMilliseconds;
77 } systemtime_t;
78
79 struct cap_header {
80     char             rtss[4];
81     char             minor;
82     char             major;
83     uint16           captype; 
84     systemtime_t     starttime;
85     uint32           frameoffset;
86     uint32           framelength;
87     uint32           unknown[24];
88 };
89
90 struct cap_packet {
91         uint32 cap_time; /* milliseconds */
92         uint16 len;
93         uint16 caplen;
94 };
95
96 #ifdef WIN32
97 #pragma pack(pop)
98 #endif
99
100 /* file format is:
101    header
102    frames
103    frameoffsets
104    */
105
106
107 static void swap_uint32(uint32 *x)
108 {
109         char c, *p = (char *)x;
110         c = p[0]; p[0] = p[3]; p[3] = c;
111         c = p[1]; p[1] = p[2]; p[2] = c;
112 }
113
114 static void swap_int32(int32 *x)
115 {
116         char c, *p = (char *)x;
117         c = p[0]; p[0] = p[3]; p[3] = c;
118         c = p[1]; p[1] = p[2]; p[2] = c;
119 }
120
121 static void swap_uint16(uint16 *x)
122 {
123         char c, *p = (char *)x;
124         c = p[0]; p[0] = p[1]; p[1] = c;
125 }
126
127
128 static void swap_netmon_header(struct cap_header *h)
129 {
130         swap_uint16(&h->captype);
131         swap_uint16(&h->starttime.wYear);
132         swap_uint16(&h->starttime.wMonth);
133         swap_uint16(&h->starttime.wDayOfWeek);
134         swap_uint16(&h->starttime.wDay);
135         swap_uint16(&h->starttime.wHour);
136         swap_uint16(&h->starttime.wMinute);
137         swap_uint16(&h->starttime.wSecond);
138         swap_uint16(&h->starttime.wMilliseconds);
139         swap_uint32(&h->frameoffset);
140         swap_uint32(&h->framelength);
141 }
142
143 static void swap_netmon_packet(struct cap_packet *p)
144 {
145         swap_uint32(&p->cap_time);
146         swap_uint16(&p->len);
147         swap_uint16(&p->caplen);
148 }
149
150 static void swap_snoop_header(struct snoop_file_header *h)
151 {
152         swap_uint16(&h->major);
153         swap_uint16(&h->minor);
154         swap_uint32(&h->linktype);
155 }
156
157 static void swap_snoop_packet(struct snoop_packet *p)
158 {
159         swap_uint32(&p->caplen);
160         swap_uint32(&p->len);
161         swap_uint32(&p->offset);
162         swap_uint32(&((p->ts).tv_sec));
163         swap_int32(&((p->ts).tv_usec));
164 }
165
166 int convert_snoop_to_cap(char *infile, char *outfile)
167 {
168         int i;
169         int fd1, fd2;
170         int snaplen;
171         int offsetlen;
172         struct snoop_file_header snoop_header;
173         struct snoop_packet snoop_pkt;
174         char *data;
175         struct cap_header cap_header;
176         struct cap_packet cap_pkt;
177         struct timeval tval1;
178         char pad[4];
179         int swap_snoop = 0;
180         int swap_netmon = 0;
181         struct tm *starttm;
182         uint32 foffset;
183         FILE *tmpf;
184         int fd3;
185         int j;
186
187         fd1 = open(infile, O_RDONLY | O_BINARY);
188         if (fd1 == -1) {
189                 perror(infile);
190                 exit(1);
191         }
192
193         fd2 = open(outfile, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
194         if (fd2 == -1) {
195                 perror(outfile);
196                 exit(1);
197         }
198
199         if ((tmpf = tmpfile()) == NULL) {
200                 perror("tmpfile()");
201                 exit(1);
202         }
203         fd3 = fileno(tmpf);
204         if (fd3 == -1) {
205                 perror("tmpfile()");
206                 exit(1);
207         }
208
209         if (read(fd1, &snoop_header, sizeof(snoop_header)) != 
210             sizeof(snoop_header)) {
211                 printf("can't read snoop header\n");
212                 return 0;
213         }
214
215         /* snoop files can be in either byte order. */
216         if (memcmp(snoop_header.u.magic, SNOOP_MAGIC, 8) != 0) {
217                 printf("bad magic number %x\n", snoop_header.u.magic);
218                 return 0;
219         }
220
221         if (snoop_header.u.m[1] == 'p') {
222                 swap_snoop = 1;
223                 swap_snoop_header(&snoop_header);
224 #if _DEBUG
225                 fprintf(stderr, "Bytes swapping snoop file.\n");
226 #endif
227         }
228
229         /* check if we are little endian. If not, we need to
230            convert the network monitor output */
231         i=1;
232         if (((char *)&i)[0] != 1) {
233                 swap_netmon = 1;
234 #if _DEBUG
235                 fprintf(stderr, "Bytes swapping cap file.\n");
236 #endif
237         }
238
239         /* setup the basic netmon header */
240         memset(&cap_header, 0, sizeof(cap_header));
241         strcpy(cap_header.rtss, "RTSS");
242         cap_header.minor = 1;
243         cap_header.major = 1;
244         cap_header.captype = 1; /* snoop_header.linktype; */
245         
246         /* write it out. we will have to write it again once
247            we've worked out the rest of the parameters */
248         write(fd2, &cap_header, sizeof(cap_header));
249
250         /* snaplen = snoop_header.snaplen; */
251         snaplen = 4500;
252
253         printf("snoop-%d.%d linktype=%d\n", 
254                snoop_header.major, snoop_header.minor,
255                snoop_header.linktype);
256
257         data = (char *)malloc(snaplen);
258
259         memset(pad, 0, sizeof(pad));
260         
261         for (i=0; 1 ; i++) {
262                 if (read(fd1, &snoop_pkt, sizeof(snoop_pkt)) != 
263                     sizeof(snoop_pkt))
264                         break;
265
266                 if (swap_snoop)
267                     swap_snoop_packet(&snoop_pkt);
268
269                 if (i == 0)
270                         tval1 = snoop_pkt.ts;
271
272                 if (read(fd1, data, snoop_pkt.caplen) != snoop_pkt.caplen)
273                         break;
274
275 #if _DEBUG
276                 fprintf(stderr, "frame %d of length=%d:%d\n",
277                         i+1, snoop_pkt.caplen, snoop_pkt.len);
278 #endif
279                 offsetlen = snoop_pkt.offset -
280                     (sizeof(snoop_pkt) + snoop_pkt.caplen);
281                 if (offsetlen > 0)
282                     lseek(fd1, offsetlen, SEEK_CUR);
283
284                 if (snoop_pkt.caplen > snoop_pkt.len)
285                         snoop_pkt.caplen = snoop_pkt.len;
286
287                 foffset = lseek(fd2, 0, SEEK_CUR);
288
289                 cap_pkt.cap_time = (snoop_pkt.ts.tv_sec - tval1.tv_sec)*1000 +
290                         (snoop_pkt.ts.tv_usec - tval1.tv_usec)/1000;
291                 cap_pkt.caplen = snoop_pkt.caplen;
292                 cap_pkt.len = snoop_pkt.len;
293
294                 if (swap_netmon)
295                         swap_netmon_packet(&cap_pkt);
296
297                 write(fd2, &cap_pkt, sizeof(cap_pkt));
298                 write(fd2, data, snoop_pkt.caplen);
299                 write(fd3, &foffset, sizeof(foffset));
300
301                 if (snoop_pkt.caplen % 4 != 0) {
302                         write(fd2, pad, 4 - (snoop_pkt.caplen % 4));
303                 }
304
305 #if _DEBUG
306                 fprintf(stderr, "frame %d of length=%d:%d\n",
307                         i+1, snoop_pkt.caplen, snoop_pkt.len);
308 #endif
309         }
310
311         cap_header.frameoffset = lseek(fd2, 0, SEEK_CUR);
312         cap_header.framelength = i*4;
313
314         if ((starttm = localtime((time_t *)&tval1.tv_sec)) != NULL) {
315                 cap_header.starttime.wYear = 1900 + starttm->tm_year;
316                 cap_header.starttime.wMonth = starttm->tm_mon + 1;
317                 cap_header.starttime.wDayOfWeek = starttm->tm_wday;
318                 cap_header.starttime.wDay = starttm->tm_mday;
319                 cap_header.starttime.wHour = starttm->tm_hour;
320                 cap_header.starttime.wMinute = starttm->tm_min;
321                 cap_header.starttime.wSecond = starttm->tm_sec;
322                 cap_header.starttime.wMilliseconds = tval1.tv_usec/1000;
323         }
324
325         if (swap_netmon)
326                 swap_netmon_header(&cap_header);
327
328         lseek(fd3, 0, SEEK_SET);
329         for (j = 0; j < i; j++) {
330                 if (read(fd3, &foffset, sizeof(foffset)) != sizeof(foffset)) {
331                         perror("read(tmpfile)");
332                         exit(2);
333                 }
334                 if (swap_netmon)
335                         swap_uint32(&foffset);
336                 write(fd2, &foffset, sizeof(foffset));
337         }
338
339         lseek(fd2, 0, SEEK_SET);
340
341         write(fd2, &cap_header, sizeof(cap_header));
342
343         close(fd1);
344         close(fd2);
345         fclose(tmpf);
346
347         printf("converted %d frames\n", i);
348
349         return i;
350 }
351
352 int main(int argc, char *argv[])
353 {
354         if (argc < 3) {
355                 printf("Convert a snoop capture file to a netmon .cap file\n");
356                 printf("\tUsage: capconvert <infile> <outfile>\n");
357                 exit(1);
358         }
359
360         convert_snoop_to_cap(argv[1], argv[2]);
361
362         return 0;
363 }