Add VENDOR_ERICSSON_PKT_CORE
[obnox/wireshark/wip.git] / pcapio.c
1 /* pcapio.c
2  * Our own private code for writing libpcap files when capturing.
3  *
4  * We have these because we want a way to open a stream for output given
5  * only a file descriptor.  libpcap 0.9[.x] has "pcap_dump_fopen()", which
6  * provides that, but
7  *
8  *      1) earlier versions of libpcap doesn't have it
9  *
10  * and
11  *
12  *      2) WinPcap doesn't have it, because a file descriptor opened
13  *         by code built for one version of the MSVC++ C library
14  *         can't be used by library routines built for another version
15  *         (e.g., threaded vs. unthreaded).
16  *
17  * Libpcap's pcap_dump() also doesn't return any error indications.
18  *
19  * $Id$
20  *
21  * Wireshark - Network traffic analyzer
22  * By Gerald Combs <gerald@wireshark.org>
23  * Copyright 1998 Gerald Combs
24  *
25  * Derived from code in the Wiretap Library
26  * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
27  *
28  * This program is free software; you can redistribute it and/or
29  * modify it under the terms of the GNU General Public License
30  * as published by the Free Software Foundation; either version 2
31  * of the License, or (at your option) any later version.
32  *
33  * This program is distributed in the hope that it will be useful,
34  * but WITHOUT ANY WARRANTY; without even the implied warranty of
35  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
36  * GNU General Public License for more details.
37  *
38  * You should have received a copy of the GNU General Public License
39  * along with this program; if not, write to the Free Software
40  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
41  */
42
43 #ifdef HAVE_CONFIG_H
44 #include "config.h"
45 #endif
46
47 #ifdef HAVE_LIBPCAP
48
49 #include <stdlib.h>
50 #include <stdio.h>
51 #include <errno.h>
52 #include <string.h>
53
54 #include <pcap.h>
55
56 #include <glib.h>
57
58 #include "pcapio.h"
59
60 /* Magic numbers in "libpcap" files.
61
62    "libpcap" file records are written in the byte order of the host that
63    writes them, and the reader is expected to fix this up.
64
65    PCAP_MAGIC is the magic number, in host byte order; PCAP_SWAPPED_MAGIC
66    is a byte-swapped version of that.
67
68    PCAP_NSEC_MAGIC is for Ulf Lamping's modified "libpcap" format,
69    which uses the same common file format as PCAP_MAGIC, but the
70    timestamps are saved in nanosecond resolution instead of microseconds.
71    PCAP_SWAPPED_NSEC_MAGIC is a byte-swapped version of that. */
72 #define PCAP_MAGIC                      0xa1b2c3d4
73 #define PCAP_SWAPPED_MAGIC              0xd4c3b2a1
74 #define PCAP_NSEC_MAGIC                 0xa1b23c4d
75 #define PCAP_SWAPPED_NSEC_MAGIC         0x4d3cb2a1
76
77 /* "libpcap" file header. */
78 struct pcap_hdr {
79         guint32 magic;          /* magic number */
80         guint16 version_major;  /* major version number */
81         guint16 version_minor;  /* minor version number */
82         gint32  thiszone;       /* GMT to local correction */
83         guint32 sigfigs;        /* accuracy of timestamps */
84         guint32 snaplen;        /* max length of captured packets, in octets */
85         guint32 network;        /* data link type */
86 };
87
88 /* "libpcap" record header. */
89 struct pcaprec_hdr {
90         guint32 ts_sec;         /* timestamp seconds */
91         guint32 ts_usec;        /* timestamp microseconds (nsecs for PCAP_NSEC_MAGIC) */
92         guint32 incl_len;       /* number of octets of packet saved in file */
93         guint32 orig_len;       /* actual length of packet */
94 };
95
96 /* Magic numbers in ".pcapng" files.
97  *
98  * .pcapng file records are written in the byte order of the host that
99  * writes them, and the reader is expected to fix this up.
100  * PCAPNG_MAGIC is the magic number, in host byte order;
101  * PCAPNG_SWAPPED_MAGIC is a byte-swapped version of that.
102  */
103 #define PCAPNG_MAGIC         0x1A2B3C4D
104 #define PCAPNG_SWAPPED_MAGIC 0xD4C3B2A1
105
106 /* Currently we are only supporting the initial version of
107    the file format. */
108 #define PCAPNG_MAJOR_VERSION 1
109 #define PCAPNG_MINOR_VERSION 0
110
111 /* Section Header Block without options and trailing Block Total Length */
112 struct shb {
113         guint32 block_type;
114         guint32 block_total_length;
115         guint32 byte_order_magic;
116         guint16 major_version;
117         guint16 minor_version;
118         guint64 section_length;
119 };
120 #define SECTION_HEADER_BLOCK_TYPE 0x0A0D0D0A
121
122 /* Interface Decription Block without options and trailing Block Total Length */
123 struct idb {
124         guint32 block_type;
125         guint32 block_total_length;
126         guint16 link_type;
127         guint16 reserved;
128         guint32 snap_len;
129 };
130 #define INTERFACE_DESCRIPTION_BLOCK_TYPE 0x00000001
131
132 /* Interface Statistics Block without actual packet, options, and trailing
133    Block Total Length */
134 struct isb {
135         guint32 block_type;
136         guint32 block_total_length;
137         guint32 interface_id;
138         guint32 timestamp_high;
139         guint32 timestamp_low;
140 };
141 #define INTERFACE_STATISTICS_BLOCK_TYPE 0x00000005
142
143 /* Enhanced Packet Block without actual packet, options, and trailing
144    Block Total Length */
145 struct epb {
146         guint32 block_type;
147         guint32 block_total_length;
148         guint32 interface_id;
149         guint32 timestamp_high;
150         guint32 timestamp_low;
151         guint32 captured_len;
152         guint32 packet_len;
153 };
154 #define ENHANCED_PACKET_BLOCK_TYPE 0x00000006
155
156 struct option {
157         guint16 type;
158         guint16 value_length;
159 };
160 #define OPT_ENDOFOPT 0
161 #define OPT_COMMENT  1 /* currently not used */
162 #define SHB_HARDWARE 2 /* currently not used */
163 #define SHB_OS       3 
164 #define SHB_USERAPPL 4
165 #define IDB_NAME     2
166 #define IDB_FILTER  11
167 #define ISB_IFRECV   4
168 #define ISB_IFDROP   5
169 #define ISB_FILTERACCEPT 6
170
171 #define ADD_PADDING(x) ((((x) + 3) >> 2) << 2)
172
173 #define WRITE_DATA(file_pointer, data_pointer, data_length, written_length, error_pointer) \
174 {                                                                                          \
175         do {                                                                               \
176                 size_t nwritten;                                                           \
177                                                                                            \
178                 nwritten = fwrite(data_pointer, 1, data_length, file_pointer);             \
179                 if (nwritten != data_length) {                                             \
180                         if (nwritten == 0 && ferror(file_pointer)) {                       \
181                                 *error_pointer = errno;                                    \
182                         } else {                                                           \
183                                 *error_pointer = 0;                                        \
184                         }                                                                  \
185                         return FALSE;                                                      \
186                 }                                                                          \
187                 written_length += (long)nwritten;                                          \
188         } while (0);                                                                       \
189 }
190
191 /* Returns a FILE * to write to on success, NULL on failure */
192 FILE *
193 libpcap_fdopen(int fd, int *err)
194 {
195         FILE *fp;
196
197         fp = fdopen(fd, "wb");
198         if (fp == NULL) {
199                 *err = errno;
200         }
201         return fp;
202 }
203
204 /* Write the file header to a dump file.
205    Returns TRUE on success, FALSE on failure.
206    Sets "*err" to an error code, or 0 for a short write, on failure*/
207 gboolean
208 libpcap_write_file_header(FILE *fp, int linktype, int snaplen, long *bytes_written, int *err)
209 {
210         struct pcap_hdr file_hdr;
211         size_t nwritten;
212
213         file_hdr.magic = PCAP_MAGIC;
214         /* current "libpcap" format is 2.4 */
215         file_hdr.version_major = 2;
216         file_hdr.version_minor = 4;
217         file_hdr.thiszone = 0;  /* XXX - current offset? */
218         file_hdr.sigfigs = 0;   /* unknown, but also apparently unused */
219         file_hdr.snaplen = snaplen;
220         file_hdr.network = linktype;
221         nwritten = fwrite(&file_hdr, 1, sizeof(file_hdr), fp);
222         if (nwritten != sizeof(file_hdr)) {
223                 if (nwritten == 0 && ferror(fp))
224                         *err = errno;
225                 else
226                         *err = 0;       /* short write */
227                 return FALSE;
228         }
229         *bytes_written += sizeof(file_hdr);
230
231         return TRUE;
232 }
233
234 /* Write a record for a packet to a dump file.
235    Returns TRUE on success, FALSE on failure. */
236 gboolean
237 libpcap_write_packet(FILE *fp, const struct pcap_pkthdr *phdr, const u_char *pd,
238     long *bytes_written, int *err)
239 {
240         struct pcaprec_hdr rec_hdr;
241         size_t nwritten;
242
243         rec_hdr.ts_sec = phdr->ts.tv_sec;
244         rec_hdr.ts_usec = phdr->ts.tv_usec;
245         rec_hdr.incl_len = phdr->caplen;
246         rec_hdr.orig_len = phdr->len;
247         nwritten = fwrite(&rec_hdr, 1, sizeof rec_hdr, fp);
248         if (nwritten != sizeof rec_hdr) {
249                 if (nwritten == 0 && ferror(fp))
250                         *err = errno;
251                 else
252                         *err = 0;       /* short write */
253                 return FALSE;
254         }
255         *bytes_written += sizeof rec_hdr;
256
257         nwritten = fwrite(pd, 1, phdr->caplen, fp);
258         if (nwritten != phdr->caplen) {
259                 if (nwritten == 0 && ferror(fp))
260                         *err = errno;
261                 else
262                         *err = 0;       /* short write */
263                 return FALSE;
264         }
265         *bytes_written += phdr->caplen;
266         return TRUE;
267 }
268
269 gboolean
270 libpcap_write_session_header_block(FILE *fp,
271                                    const char *comment,
272                                    const char *hw,
273                                    const char *os,
274                                    const char *appname,
275                                    guint64 section_length,
276                                    long *bytes_written,
277                                    int *err)
278 {
279         struct shb shb;
280         struct option option;
281         guint32 block_total_length;
282         const guint32 padding = 0;
283         gboolean have_options = FALSE;
284
285         /* Size of base header */
286         block_total_length = sizeof(struct shb) +
287                              sizeof(guint32);
288         if ((comment)&&(strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) {
289                 block_total_length += sizeof(struct option) +
290                                       (guint16)(ADD_PADDING(strlen(comment) + 1));
291                 have_options = TRUE;
292         }
293         if ((hw)&&(strlen(hw) > 0) && (strlen(hw) < G_MAXUINT16)) {
294                 block_total_length += sizeof(struct option) +
295                                       (guint16)(ADD_PADDING(strlen(hw) + 1));
296                 have_options = TRUE;
297         }
298         if ((os)&&(strlen(os) > 0) && (strlen(os) < G_MAXUINT16)) {
299                 block_total_length += sizeof(struct option) +
300                                       (guint16)(ADD_PADDING(strlen(os) + 1));
301                 have_options = TRUE;
302         }
303         if ((appname)&&(strlen(appname) > 0) && (strlen(appname) < G_MAXUINT16)) {
304                 block_total_length += sizeof(struct option) +
305                                       (guint16)(ADD_PADDING(strlen(appname) + 1));
306                 have_options = TRUE;
307         }
308         /* If we have options add size of end-of-options */
309         if(have_options){
310                 block_total_length += sizeof(struct option);
311         }
312         /* write shb header */
313         shb.block_type = SECTION_HEADER_BLOCK_TYPE;
314         shb.block_total_length = block_total_length;
315         shb.byte_order_magic = PCAPNG_MAGIC;
316         shb.major_version = PCAPNG_MAJOR_VERSION;
317         shb.minor_version = PCAPNG_MINOR_VERSION;
318         shb.section_length = section_length;
319         WRITE_DATA(fp, &shb, sizeof(struct shb), *bytes_written, err);
320
321         if ((comment)&&(strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) {
322                 /* write opt_comment options */
323                 option.type = OPT_COMMENT;
324                 option.value_length = (guint16)(strlen(comment) + 1);
325                 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
326                 WRITE_DATA(fp, comment, strlen(comment) + 1, *bytes_written, err);
327                 if ((strlen(comment) + 1) % 4) {
328                         WRITE_DATA(fp, &padding, 4 - (strlen(hw) + 1) % 4, *bytes_written, err);
329                 }
330         }
331         if ((hw)&&(strlen(hw) > 0) && (strlen(hw) < G_MAXUINT16)) {
332                 /* write shb_hardware options */
333                 option.type = SHB_HARDWARE;
334                 option.value_length = (guint16)(strlen(hw) + 1);
335                 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
336                 WRITE_DATA(fp, hw, strlen(hw) + 1, *bytes_written, err);
337                 if ((strlen(hw) + 1) % 4) {
338                         WRITE_DATA(fp, &padding, 4 - (strlen(hw) + 1) % 4, *bytes_written, err);
339                 }
340         }
341         if ((os)&&(strlen(os) > 0) && (strlen(os) < G_MAXUINT16)) {
342                 /* write shb_os options */
343                 option.type = SHB_OS;
344                 option.value_length = (guint16)(strlen(os) + 1);
345                 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
346                 WRITE_DATA(fp, os, strlen(os) + 1, *bytes_written, err);
347                 if ((strlen(os) + 1) % 4) {
348                         WRITE_DATA(fp, &padding, 4 - (strlen(os) + 1) % 4, *bytes_written, err);
349                 }
350         }
351         if ((appname)&&(strlen(appname) > 0) && (strlen(appname) < G_MAXUINT16)) {
352                 /* write shb_userappl options */
353                 option.type = SHB_USERAPPL;
354                 option.value_length = (guint16)(strlen(appname) + 1);
355                 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
356                 WRITE_DATA(fp, appname, strlen(appname) + 1, *bytes_written, err);
357                 if ((strlen(appname) + 1) % 4) {
358                         WRITE_DATA(fp, &padding, 4 - (strlen(appname) + 1) % 4, *bytes_written, err);
359                 }
360         }
361         if(have_options){
362                 /* write end of options */
363                 option.type = OPT_ENDOFOPT;
364                 option.value_length = 0;
365                 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
366         }
367
368         /* write the trailing block total length */
369         WRITE_DATA(fp, &block_total_length, sizeof(guint32), *bytes_written, err);
370         return TRUE;
371 }
372
373 gboolean
374 libpcap_write_interface_description_block(FILE *fp,
375                                           const char *name,
376                                           const char *filter,
377                                           int link_type,
378                                           int snap_len,
379                                           long *bytes_written,
380                                           int *err)
381 {
382         struct idb idb;
383         struct option option;
384         guint32 block_total_length;
385         const guint32 padding = 0;
386
387         block_total_length = sizeof(struct idb) + sizeof(guint32);
388         if ((strlen(name) > 0) && (strlen(name) < G_MAXUINT16)) {
389                 block_total_length += sizeof(struct option) +
390                                       (guint16)(ADD_PADDING(strlen(name) + 1));
391         }
392         if ((strlen(filter) > 0) && (strlen(filter) < G_MAXUINT16)) {
393                 block_total_length += sizeof(struct option) +
394                                       (guint16)(ADD_PADDING(strlen(filter) + 1));
395         }
396         if (((strlen(name) > 0) && (strlen(name) < G_MAXUINT16)) ||
397             ((strlen(filter) > 0) && (strlen(filter) < G_MAXUINT16))) {
398                 block_total_length += sizeof(struct option);
399         }
400         /* write block header */
401         idb.block_type = INTERFACE_DESCRIPTION_BLOCK_TYPE;
402         idb.block_total_length = block_total_length;
403         idb.link_type = link_type;
404         idb.reserved = 0;
405         idb.snap_len = snap_len;
406         WRITE_DATA(fp, &idb, sizeof(struct idb), *bytes_written, err);
407         /* write interface name string if applicable */
408         if ((strlen(name) > 0) && (strlen(name) < G_MAXUINT16)) {
409                 option.type = IDB_NAME;
410                 option.value_length = (guint16)(strlen(name) + 1);
411                 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
412                 WRITE_DATA(fp, name, strlen(name) + 1, *bytes_written, err);
413                 if ((strlen(name) + 1) % 4) {
414                         WRITE_DATA(fp, &padding, 4 - (strlen(name) + 1) % 4 , *bytes_written, err);
415                 }
416         }
417         /* write filter string if applicable */
418         if ((strlen(filter) > 0) && (strlen(filter) < G_MAXUINT16)) {
419                 option.type = IDB_FILTER;
420                 option.value_length = (guint16)(strlen(filter) + 1);
421                 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
422                 WRITE_DATA(fp, filter, strlen(filter) + 1, *bytes_written, err);
423                 if ((strlen(filter) + 1) % 4) {
424                         WRITE_DATA(fp, &padding, 4 - (strlen(filter) + 1) % 4 , *bytes_written, err);
425                 }
426         }
427         /* write endofopt option if there were any options */
428         if (((strlen(name) > 0) && (strlen(name) < G_MAXUINT16)) ||
429             ((strlen(filter) > 0) && (strlen(filter) < G_MAXUINT16))) {
430                 option.type = OPT_ENDOFOPT;
431                 option.value_length = 0;
432                 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
433         }
434         /* write the trailing Block Total Length */
435         WRITE_DATA(fp, &block_total_length, sizeof(guint32), *bytes_written, err);
436         return TRUE;
437 }
438
439 /* Write a record for a packet to a dump file.
440    Returns TRUE on success, FALSE on failure. */
441 gboolean
442 libpcap_write_enhanced_packet_block(FILE *fp,
443                                     const struct pcap_pkthdr *phdr,
444                                     guint32 interface_id,
445                                     const u_char *pd,
446                                     long *bytes_written,
447                                     int *err)
448 {
449         struct epb epb;
450         guint32 block_total_length;
451         guint64 timestamp;
452         const guint32 padding = 0;
453
454         block_total_length = sizeof(struct epb) +
455                              ADD_PADDING(phdr->caplen) +
456                              sizeof(guint32);
457         timestamp = (guint64)(phdr->ts.tv_sec) * 1000000 +
458                     (guint64)(phdr->ts.tv_usec);
459         epb.block_type = ENHANCED_PACKET_BLOCK_TYPE;
460         epb.block_total_length = block_total_length;
461         epb.interface_id = interface_id;
462         epb.timestamp_high = (guint32)((timestamp>>32) & 0xffffffff);
463         epb.timestamp_low = (guint32)(timestamp & 0xffffffff);
464         epb.captured_len = phdr->caplen;
465         epb.packet_len = phdr->len;
466         WRITE_DATA(fp, &epb, sizeof(struct epb), *bytes_written, err);
467         WRITE_DATA(fp, pd, phdr->caplen, *bytes_written, err);
468         if (phdr->caplen % 4) {
469                 WRITE_DATA(fp, &padding, 4 - phdr->caplen % 4, *bytes_written, err);
470         }
471         WRITE_DATA(fp, &block_total_length, sizeof(guint32), *bytes_written, err);
472         return TRUE;
473 }
474
475 gboolean
476 libpcap_write_interface_statistics_block(FILE *fp,
477                                          guint32 interface_id,
478                                          pcap_t *pd,
479                                          long *bytes_written,
480                                          int *err)
481 {
482         struct isb isb;
483 #ifdef _WIN32
484         FILETIME now;
485 #else
486         struct timeval now;
487 #endif
488         struct option option;
489         struct pcap_stat stats;
490         guint32 block_total_length;
491         guint64 timestamp;
492         guint64 counter;
493         gboolean stats_retrieved;
494
495 #ifdef _WIN32
496         /*
497          * Current time, represented as 100-nanosecond intervals since
498          * January 1, 1601, 00:00:00 UTC.
499          *
500          * I think DWORD might be signed, so cast both parts of "now"
501          * to guint32 so that the sign bit doesn't get treated specially.
502          */
503         GetSystemTimeAsFileTime(&now);
504         timestamp = (((guint64)(guint32)now.dwHighDateTime) << 32) +
505                     (guint32)now.dwLowDateTime;
506
507         /*
508          * Convert to same thing but as 1-microsecond, i.e. 1000-nanosecond,
509          * intervals.
510          */
511         timestamp /= 10;
512
513         /*
514          * Subtract difference, in microseconds, between January 1, 1601
515          * 00:00:00 UTC and January 1, 1970, 00:00:00 UTC.
516          */
517         timestamp -= G_GINT64_CONSTANT(11644473600000000U);
518 #else
519         /*
520          * Current time, represented as seconds and microseconds since
521          * January 1, 1970, 00:00:00 UTC.
522          */
523         gettimeofday(&now, NULL);
524
525         /*
526          * Convert to delta in microseconds.
527          */
528         timestamp = (guint64)(now.tv_sec) * 1000000 +
529                     (guint64)(now.tv_usec);
530 #endif
531         if (pcap_stats(pd, &stats) < 0) {
532                 stats_retrieved = FALSE;
533                 g_warning("pcap_stats() failed.");
534         } else {
535                 stats_retrieved = TRUE;
536         }
537         block_total_length = sizeof(struct isb) +
538                              sizeof(guint32);
539         if (stats_retrieved) {
540                 block_total_length += 3 * sizeof(struct option) + 2 * sizeof(guint64);
541         }
542         isb.block_type = INTERFACE_STATISTICS_BLOCK_TYPE;
543         isb.block_total_length = block_total_length;
544         isb.interface_id = interface_id;
545         isb.timestamp_high = (guint32)((timestamp>>32) & 0xffffffff);
546         isb.timestamp_low = (guint32)(timestamp & 0xffffffff);
547         WRITE_DATA(fp, &isb, sizeof(struct isb), *bytes_written, err);
548         if (stats_retrieved) {
549                 /* */
550                 option.type = ISB_IFRECV;
551                 option.value_length = sizeof(guint64);
552                 counter = stats.ps_recv;
553                 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
554                 WRITE_DATA(fp, &counter, sizeof(guint64), *bytes_written, err);
555                 /* */
556                 option.type = ISB_IFDROP;
557                 option.value_length = sizeof(guint64);
558                 counter = stats.ps_drop;
559                 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
560                 WRITE_DATA(fp, &counter, sizeof(guint64), *bytes_written, err);
561                 /* last option */
562                 option.type = OPT_ENDOFOPT;
563                 option.value_length = 0;
564                 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
565         }
566         WRITE_DATA(fp, &block_total_length, sizeof(guint32), *bytes_written, err);
567
568         return TRUE;
569 }
570
571 gboolean
572 libpcap_dump_flush(FILE *pd, int *err)
573 {
574         if (fflush(pd) == EOF) {
575                 if (err != NULL)
576                         *err = errno;
577                 return FALSE;
578         }
579         return TRUE;
580 }
581
582 gboolean
583 libpcap_dump_close(FILE *pd, int *err)
584 {
585         if (fclose(pd) == EOF) {
586                 if (err != NULL)
587                         *err = errno;
588                 return FALSE;
589         }
590         return TRUE;
591 }
592
593 #endif /* HAVE_LIBPCAP */