1 /* convert a snoop capture file to a netmon .cap file.
2 by Seiichi Tatsukawa (stat@rational.com), March 1998.
4 Based on capconvert.c by Andrew Tridgell, October 1997
6 This only works for 32 bit boxes at the moment. Change the typedefs
7 to work on other sytems
17 #include <sys/types.h>
24 /* change the following 3 lines to make things work on
25 systems with different word sizes */
27 typedef unsigned int uint32;
28 typedef unsigned short uint16;
31 /* #define _DEBUG 1 */
33 #define SNOOP_MAGIC "snoop\0\0\0"
42 uint32 tv_sec; /* seconds */
43 int32 tv_usec; /* and microseconds */
47 /* snoop file format */
48 struct snoop_file_header {
67 /* .cap file format */
68 typedef struct _systemtime {
84 systemtime_t starttime;
91 uint32 cap_time; /* milliseconds */
107 static void swap_uint32(uint32 *x)
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;
114 static void swap_int32(int32 *x)
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;
121 static void swap_uint16(uint16 *x)
123 char c, *p = (char *)x;
124 c = p[0]; p[0] = p[1]; p[1] = c;
128 static void swap_netmon_header(struct cap_header *h)
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);
143 static void swap_netmon_packet(struct cap_packet *p)
145 swap_uint32(&p->cap_time);
146 swap_uint16(&p->len);
147 swap_uint16(&p->caplen);
150 static void swap_snoop_header(struct snoop_file_header *h)
152 swap_uint16(&h->major);
153 swap_uint16(&h->minor);
154 swap_uint32(&h->linktype);
157 static void swap_snoop_packet(struct snoop_packet *p)
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));
166 int convert_snoop_to_cap(char *infile, char *outfile)
172 struct snoop_file_header snoop_header;
173 struct snoop_packet snoop_pkt;
175 struct cap_header cap_header;
176 struct cap_packet cap_pkt;
177 struct timeval tval1;
187 fd1 = open(infile, O_RDONLY | O_BINARY);
193 fd2 = open(outfile, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
199 if ((tmpf = tmpfile()) == NULL) {
209 if (read(fd1, &snoop_header, sizeof(snoop_header)) !=
210 sizeof(snoop_header)) {
211 printf("can't read snoop header\n");
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);
221 if (snoop_header.u.m[1] == 'p') {
223 swap_snoop_header(&snoop_header);
225 fprintf(stderr, "Bytes swapping snoop file.\n");
229 /* check if we are little endian. If not, we need to
230 convert the network monitor output */
232 if (((char *)&i)[0] != 1) {
235 fprintf(stderr, "Bytes swapping cap file.\n");
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; */
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));
250 /* snaplen = snoop_header.snaplen; */
253 printf("snoop-%d.%d linktype=%d\n",
254 snoop_header.major, snoop_header.minor,
255 snoop_header.linktype);
257 data = (char *)malloc(snaplen);
259 memset(pad, 0, sizeof(pad));
262 if (read(fd1, &snoop_pkt, sizeof(snoop_pkt)) !=
267 swap_snoop_packet(&snoop_pkt);
270 tval1 = snoop_pkt.ts;
272 if (read(fd1, data, snoop_pkt.caplen) != snoop_pkt.caplen)
276 fprintf(stderr, "frame %d of length=%d:%d\n",
277 i+1, snoop_pkt.caplen, snoop_pkt.len);
279 offsetlen = snoop_pkt.offset -
280 (sizeof(snoop_pkt) + snoop_pkt.caplen);
282 lseek(fd1, offsetlen, SEEK_CUR);
284 if (snoop_pkt.caplen > snoop_pkt.len)
285 snoop_pkt.caplen = snoop_pkt.len;
287 foffset = lseek(fd2, 0, SEEK_CUR);
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;
295 swap_netmon_packet(&cap_pkt);
297 write(fd2, &cap_pkt, sizeof(cap_pkt));
298 write(fd2, data, snoop_pkt.caplen);
299 write(fd3, &foffset, sizeof(foffset));
301 if (snoop_pkt.caplen % 4 != 0) {
302 write(fd2, pad, 4 - (snoop_pkt.caplen % 4));
306 fprintf(stderr, "frame %d of length=%d:%d\n",
307 i+1, snoop_pkt.caplen, snoop_pkt.len);
311 cap_header.frameoffset = lseek(fd2, 0, SEEK_CUR);
312 cap_header.framelength = i*4;
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;
326 swap_netmon_header(&cap_header);
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)");
335 swap_uint32(&foffset);
336 write(fd2, &foffset, sizeof(foffset));
339 lseek(fd2, 0, SEEK_SET);
341 write(fd2, &cap_header, sizeof(cap_header));
347 printf("converted %d frames\n", i);
352 int main(int argc, char *argv[])
355 printf("Convert a snoop capture file to a netmon .cap file\n");
356 printf("\tUsage: capconvert <infile> <outfile>\n");
360 convert_snoop_to_cap(argv[1], argv[2]);