/* libpcap.c
*
- * $Id: libpcap.c,v 1.113 2004/02/11 20:47:00 guy Exp $
+ * $Id$
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
#endif
/*
- * The link-layer header on ATM packets.
+ * The link-layer header on SunATM packets.
*/
struct sunatm_hdr {
guint8 flags; /* destination and traffic type */
guint16 vci; /* VCI */
};
+/*
+ * The link-layer header on Nokia IPSO ATM packets.
+ */
+struct nokiaatm_hdr {
+ guint8 flags; /* destination */
+ guint8 vpi; /* VPI */
+ guint16 vci; /* VCI */
+};
+
/*
* The fake link-layer header of IrDA packets as introduced by Jean Tourrilhes
* to libpcap.
guint16 sll_protocol; /* protocol, should be 0x0017 */
};
+/*
+ * A header containing additional MTP information.
+ */
+struct mtp2_hdr {
+ guint8 sent;
+ guint8 annex_a_used;
+ guint16 link_number;
+};
+
/* See source to the "libpcap" library for information on the "libpcap"
file format. */
static int libpcap_read_header(wtap *wth, int *err, gchar **err_info,
struct pcaprec_ss990915_hdr *hdr);
static void adjust_header(wtap *wth, struct pcaprec_hdr *hdr);
-static void libpcap_get_atm_pseudoheader(const struct sunatm_hdr *atm_phdr,
+static void libpcap_get_sunatm_pseudoheader(const struct sunatm_hdr *atm_phdr,
union wtap_pseudo_header *pseudo_header);
-static gboolean libpcap_read_atm_pseudoheader(FILE_T fh,
+static gboolean libpcap_read_sunatm_pseudoheader(FILE_T fh,
+ union wtap_pseudo_header *pseudo_header, int *err);
+static gboolean libpcap_read_nokiaatm_pseudoheader(FILE_T fh,
union wtap_pseudo_header *pseudo_header, int *err);
static gboolean libpcap_get_irda_pseudoheader(const struct irda_sll_hdr *irda_phdr,
union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info);
static gboolean libpcap_read_irda_pseudoheader(FILE_T fh,
union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info);
+static gboolean libpcap_get_mtp2_pseudoheader(const struct mtp2_hdr *mtp2_hdr,
+ union wtap_pseudo_header *pseudo_header);
+static gboolean libpcap_read_mtp2_pseudoheader(FILE_T fh,
+ union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info);
static gboolean libpcap_read_rec_data(FILE_T fh, guchar *pd, int length,
int *err);
static void libpcap_close(wtap *wth);
{ 10, WTAP_ENCAP_FDDI },
#endif
+ { 32, WTAP_ENCAP_REDBACK },
+
/*
* 50 is DLT_PPP_SERIAL in NetBSD; it appears that DLT_PPP
* on BSD (at least according to standard tcpdump) has, as
*/
{ 50, WTAP_ENCAP_PPP },
+ /*
+ * Apparently used by the Axent Raptor firewall (now Symantec
+ * Enterprise Firewall).
+ * Thanks, Axent, for not reserving that type with tcpdump.org
+ * and not telling anybody about it.
+ */
+ { 99, WTAP_ENCAP_SYMANTEC },
+
/*
* These are the values that libpcap 0.5 and later use in
* capture file headers, in an attempt to work around the
{ 121, WTAP_ENCAP_HHDLC }, /* HiPath HDLC */
{ 122, WTAP_ENCAP_IP_OVER_FC }, /* RFC 2625 IP-over-FC */
{ 123, WTAP_ENCAP_ATM_PDUS }, /* SunATM */
- { 127, WTAP_ENCAP_IEEE_802_11_WLAN_BSD }, /* 802.11 plus BSD WLAN header */
+ { 127, WTAP_ENCAP_IEEE_802_11_WLAN_RADIOTAP }, /* 802.11 plus radiotap WLAN header */
{ 128, WTAP_ENCAP_TZSP }, /* Tazmen Sniffer Protocol */
{ 129, WTAP_ENCAP_ARCNET_LINUX },
-
+ { 130, WTAP_ENCAP_JUNIPER_MLPPP }, /* Juniper MLPPP on ML-, LS-, AS- PICs */
+ { 131, WTAP_ENCAP_JUNIPER_MLFR }, /* Juniper MLFR (FRF.15) on ML-, LS-, AS- PICs */
/*
- * Values 130 thorugh 137 are reserved for use in Juniper
- * hardware.
- *
- * 138 is reserved for Apple IP-over-IEEE 1394.
+ * Values 132-134, 136 not listed here are reserved for use
+ * in Juniper hardware.
*/
+ { 135, WTAP_ENCAP_JUNIPER_ATM2 }, /* various encapsulations captured on the ATM2 PIC */
+ { 137, WTAP_ENCAP_JUNIPER_ATM1 }, /* various encapsulations captured on the ATM1 PIC */
+
+ { 138, WTAP_ENCAP_APPLE_IP_OVER_IEEE1394 },
+ /* Apple IP-over-IEEE 1394 */
+ { 139, WTAP_ENCAP_MTP2_WITH_PHDR },
{ 140, WTAP_ENCAP_MTP2 },
{ 141, WTAP_ENCAP_MTP3 },
{ 143, WTAP_ENCAP_DOCSIS },
{ 163, WTAP_ENCAP_IEEE_802_11_WLAN_AVS }, /* 802.11 plus AVS WLAN header */
+ /*
+ * 164 is reserved for Juniper-private chassis-internal
+ * meta-information such as QoS profiles, etc..
+ */
+
+ { 165, WTAP_ENCAP_BACNET_MS_TP },
+
+ /*
+ * 166 is reserved for a PPP variant in which the first byte
+ * of the 0xff03 header, the 0xff, is replaced by a direction
+ * byte. I don't know whether any captures look like that,
+ * but it is used for some Linux IP filtering (ipfilter?).
+ */
+
+ /* Ethernet PPPoE frames captured on a service PIC */
+ { 167, WTAP_ENCAP_JUNIPER_PPPOE },
+
+ /*
+ * 168 is reserved for more Juniper private-chassis-
+ * internal meta-information.
+ */
+
+ { 169, WTAP_ENCAP_GPRS_LLC },
+
+ /*
+ * 170 and 171 are reserved for ITU-T G.7041/Y.1303 Generic
+ * Framing Procedure.
+ */
+
+ /* Registered by Gcom, Inc. */
+ { 172, WTAP_GCOM_TIE1 },
+ { 173, WTAP_GCOM_SERIAL },
+
/*
* To repeat:
*
*/
{ 19, WTAP_ENCAP_LINUX_ATM_CLIP },
+ /*
+ * nettl (HP-UX) mappings to standard DLT values
+ */
+
+ { 1, WTAP_ENCAP_NETTL_ETHERNET },
+ { 6, WTAP_ENCAP_NETTL_TOKEN_RING },
+ { 10, WTAP_ENCAP_NETTL_FDDI },
+ { 101, WTAP_ENCAP_NETTL_RAW_IP },
+
/*
* To repeat:
*
gboolean aix;
int file_encap;
+
/* Read in the number that should be at the start of a "libpcap" file */
errno = WTAP_ERR_CANT_READ;
bytes_read = file_read(&magic, 1, sizeof magic, wth->fh);
a program using either standard or ss990417 libpcap. */
byte_swapped = FALSE;
modified = FALSE;
+ wth->tsprecision = WTAP_FILE_TSPREC_USEC;
break;
case PCAP_MODIFIED_MAGIC:
a program using either ss990915 or ss991029 libpcap. */
byte_swapped = FALSE;
modified = TRUE;
+ wth->tsprecision = WTAP_FILE_TSPREC_USEC;
break;
case PCAP_SWAPPED_MAGIC:
ss990417 libpcap. */
byte_swapped = TRUE;
modified = FALSE;
+ wth->tsprecision = WTAP_FILE_TSPREC_USEC;
break;
case PCAP_SWAPPED_MODIFIED_MAGIC:
or ss991029 libpcap. */
byte_swapped = TRUE;
modified = TRUE;
+ wth->tsprecision = WTAP_FILE_TSPREC_USEC;
+ break;
+
+ case PCAP_NSEC_MAGIC:
+ /* Host that wrote it has our byte order, and was running
+ a program using either standard or ss990417 libpcap. */
+ byte_swapped = FALSE;
+ modified = FALSE;
+ wth->tsprecision = WTAP_FILE_TSPREC_NSEC;
+ break;
+
+ case PCAP_SWAPPED_NSEC_MAGIC:
+ /* Host that wrote it out has a byte order opposite to
+ ours, and was running a program using either ss990915
+ or ss991029 libpcap. */
+ byte_swapped = TRUE;
+ modified = FALSE;
+ wth->tsprecision = WTAP_FILE_TSPREC_NSEC;
break;
default:
break;
}
}
+
+ /*
+ * We treat a DLT_ value of 13 specially - it appears that in
+ * Nokia libpcap format, it's some form of ATM with what I
+ * suspect is a pseudo-header (even though Nokia's IPSO is
+ * based on FreeBSD, which #defines DLT_SLIP_BSDOS as 13).
+ *
+ * We don't yet know whether this is a Nokia capture, so if
+ * "wtap_pcap_encap_to_wtap_encap()" returned WTAP_ENCAP_UNKNOWN
+ * but "hdr.network" is 13, we don't treat that as an error yet.
+ */
file_encap = wtap_pcap_encap_to_wtap_encap(hdr.network);
- if (file_encap == WTAP_ENCAP_UNKNOWN) {
+ if (file_encap == WTAP_ENCAP_UNKNOWN && hdr.network != 13) {
*err = WTAP_ERR_UNSUPPORTED_ENCAP;
*err_info = g_strdup_printf("pcap: network type %u unknown or unsupported",
hdr.network);
*
* Try the standard format first.
*/
- wth->file_type = WTAP_FILE_PCAP;
+ if(wth->tsprecision == WTAP_FILE_TSPREC_NSEC) {
+ wth->file_type = WTAP_FILE_PCAP_NSEC;
+ } else {
+ wth->file_type = WTAP_FILE_PCAP;
+ }
switch (libpcap_try(wth, err)) {
case BAD_READ:
}
}
+ if (hdr.network == 13) {
+ /*
+ * OK, if this was a Nokia capture, make it
+ * WTAP_ENCAP_ATM_PDUS, otherwise return
+ * an error.
+ */
+ if (wth->file_type == WTAP_FILE_PCAP_NOKIA)
+ wth->file_encap = WTAP_ENCAP_ATM_PDUS;
+ else {
+ *err = WTAP_ERR_UNSUPPORTED_ENCAP;
+ *err_info = g_strdup_printf("pcap: network type %u unknown or unsupported",
+ hdr.network);
+ g_free(wth->capture.pcap);
+ return -1;
+ }
+ }
+
return 1;
}
switch (wth->file_encap) {
case WTAP_ENCAP_ATM_PDUS:
- if (packet_size < sizeof (struct sunatm_hdr)) {
+ if (wth->file_type == WTAP_FILE_PCAP_NOKIA) {
/*
- * Uh-oh, the packet isn't big enough to even
- * have a pseudo-header.
+ * Nokia IPSO ATM.
*/
- *err = WTAP_ERR_BAD_RECORD;
- *err_info = g_strdup_printf("libpcap: SunATM file has a %u-byte packet, too small to have even an ATM pseudo-header\n",
- packet_size);
- return FALSE;
- }
- if (!libpcap_read_atm_pseudoheader(wth->fh, &wth->pseudo_header,
- err))
- return FALSE; /* Read error */
+ if (packet_size < sizeof (struct nokiaatm_hdr)) {
+ /*
+ * Uh-oh, the packet isn't big enough to even
+ * have a pseudo-header.
+ */
+ *err = WTAP_ERR_BAD_RECORD;
+ *err_info = g_strdup_printf("libpcap: Nokia IPSO ATM file has a %u-byte packet, too small to have even an ATM pseudo-header\n",
+ packet_size);
+ return FALSE;
+ }
+ if (!libpcap_read_nokiaatm_pseudoheader(wth->fh,
+ &wth->pseudo_header, err))
+ return FALSE; /* Read error */
- /*
- * Don't count the pseudo-header as part of the packet.
- */
- orig_size -= sizeof (struct sunatm_hdr);
- packet_size -= sizeof (struct sunatm_hdr);
- wth->data_offset += sizeof (struct sunatm_hdr);
+ /*
+ * Don't count the pseudo-header as part of the
+ * packet.
+ */
+ orig_size -= sizeof (struct nokiaatm_hdr);
+ packet_size -= sizeof (struct nokiaatm_hdr);
+ wth->data_offset += sizeof (struct nokiaatm_hdr);
+ } else {
+ /*
+ * SunATM.
+ */
+ if (packet_size < sizeof (struct sunatm_hdr)) {
+ /*
+ * Uh-oh, the packet isn't big enough to even
+ * have a pseudo-header.
+ */
+ *err = WTAP_ERR_BAD_RECORD;
+ *err_info = g_strdup_printf("libpcap: SunATM file has a %u-byte packet, too small to have even an ATM pseudo-header\n",
+ packet_size);
+ return FALSE;
+ }
+ if (!libpcap_read_sunatm_pseudoheader(wth->fh,
+ &wth->pseudo_header, err))
+ return FALSE; /* Read error */
+
+ /*
+ * Don't count the pseudo-header as part of the
+ * packet.
+ */
+ orig_size -= sizeof (struct sunatm_hdr);
+ packet_size -= sizeof (struct sunatm_hdr);
+ wth->data_offset += sizeof (struct sunatm_hdr);
+ }
break;
case WTAP_ENCAP_ETHERNET:
break;
case WTAP_ENCAP_IEEE_802_11:
+ case WTAP_ENCAP_PRISM_HEADER:
+ case WTAP_ENCAP_IEEE_802_11_WLAN_RADIOTAP:
+ case WTAP_ENCAP_IEEE_802_11_WLAN_AVS:
/*
* We don't know whether there's an FCS in this frame or not.
* XXX - are there any OSes where the capture mechanism
packet_size -= sizeof (struct irda_sll_hdr);
wth->data_offset += sizeof (struct irda_sll_hdr);
break;
+ case WTAP_ENCAP_MTP2_WITH_PHDR:
+ if (packet_size < sizeof (struct mtp2_hdr)) {
+ /*
+ * Uh-oh, the packet isn't big enough to even
+ * have a pseudo-header.
+ */
+ *err = WTAP_ERR_BAD_RECORD;
+ *err_info = g_strdup_printf("libpcap: MTP2 file has a %u-byte packet, too small to have even an MTP2 pseudo-header\n",
+ packet_size);
+ return FALSE;
+ }
+ if (!libpcap_read_mtp2_pseudoheader(wth->fh, &wth->pseudo_header,
+ err, err_info))
+ return FALSE; /* Read error */
+
+ /*
+ * Don't count the pseudo-header as part of the packet.
+ */
+ orig_size -= sizeof (struct mtp2_hdr);
+ packet_size -= sizeof (struct mtp2_hdr);
+ wth->data_offset += sizeof (struct mtp2_hdr);
+ break;
}
buffer_assure_space(wth->frame_buffer, packet_size);
return FALSE; /* Read error */
wth->data_offset += packet_size;
- wth->phdr.ts.tv_sec = hdr.hdr.ts_sec;
- wth->phdr.ts.tv_usec = hdr.hdr.ts_usec;
+ wth->phdr.ts.secs = hdr.hdr.ts_sec;
+ if(wth->tsprecision == WTAP_FILE_TSPREC_NSEC) {
+ wth->phdr.ts.nsecs = hdr.hdr.ts_usec;
+ } else {
+ wth->phdr.ts.nsecs = hdr.hdr.ts_usec * 1000;
+ }
wth->phdr.caplen = packet_size;
wth->phdr.len = orig_size;
- wth->phdr.pkt_encap = wth->file_encap;
- /*
- * If this is ATM LANE traffic, try to guess what type of LANE
- * traffic it is based on the packet contents.
- */
- if (wth->file_encap == WTAP_ENCAP_ATM_PDUS &&
- wth->pseudo_header.atm.type == TRAF_LANE) {
- atm_guess_lane_type(buffer_start_ptr(wth->frame_buffer),
- wth->phdr.caplen, &wth->pseudo_header);
+ if (wth->file_encap == WTAP_ENCAP_ATM_PDUS) {
+ if (wth->file_type == WTAP_FILE_PCAP_NOKIA) {
+ /*
+ * Nokia IPSO ATM.
+ *
+ * Guess the traffic type based on the packet
+ * contents.
+ */
+ atm_guess_traffic_type(buffer_start_ptr(wth->frame_buffer),
+ wth->phdr.caplen, &wth->pseudo_header);
+ } else {
+ /*
+ * SunATM.
+ *
+ * If this is ATM LANE traffic, try to guess what
+ * type of LANE traffic it is based on the packet
+ * contents.
+ */
+ if (wth->pseudo_header.atm.type == TRAF_LANE) {
+ atm_guess_lane_type(buffer_start_ptr(wth->frame_buffer),
+ wth->phdr.caplen, &wth->pseudo_header);
+ }
+ }
}
return TRUE;
switch (wth->file_encap) {
case WTAP_ENCAP_ATM_PDUS:
- if (!libpcap_read_atm_pseudoheader(wth->random_fh, pseudo_header,
- err)) {
- /* Read error */
- return FALSE;
+ if (wth->file_type == WTAP_FILE_PCAP_NOKIA) {
+ /*
+ * Nokia IPSO ATM.
+ */
+ if (!libpcap_read_nokiaatm_pseudoheader(wth->random_fh,
+ pseudo_header, err)) {
+ /* Read error */
+ return FALSE;
+ }
+ } else {
+ /*
+ * SunATM.
+ */
+ if (!libpcap_read_sunatm_pseudoheader(wth->random_fh,
+ pseudo_header, err)) {
+ /* Read error */
+ return FALSE;
+ }
}
break;
pseudo_header->eth.fcs_len = -1;
break;
+ case WTAP_ENCAP_IEEE_802_11:
+ case WTAP_ENCAP_PRISM_HEADER:
+ case WTAP_ENCAP_IEEE_802_11_WLAN_RADIOTAP:
+ case WTAP_ENCAP_IEEE_802_11_WLAN_AVS:
+ /*
+ * We don't know whether there's an FCS in this frame or not.
+ * XXX - are there any OSes where the capture mechanism
+ * supplies an FCS?
+ */
+ pseudo_header->ieee_802_11.fcs_len = -1;
+ break;
+
case WTAP_ENCAP_IRDA:
if (!libpcap_read_irda_pseudoheader(wth->random_fh, pseudo_header,
err, err_info)) {
return FALSE;
}
break;
+ case WTAP_ENCAP_MTP2_WITH_PHDR:
+ if (!libpcap_read_mtp2_pseudoheader(wth->random_fh, pseudo_header,
+ err, err_info)) {
+ /* Read error */
+ return FALSE;
+ }
+ break;
}
/*
if (!libpcap_read_rec_data(wth->random_fh, pd, length, err))
return FALSE; /* failed */
- /*
- * If this is ATM LANE traffic, try to guess what type of LANE
- * traffic it is based on the packet contents.
- */
- if (wth->file_encap == WTAP_ENCAP_ATM_PDUS &&
- pseudo_header->atm.type == TRAF_LANE)
- atm_guess_lane_type(pd, length, pseudo_header);
+ if (wth->file_encap == WTAP_ENCAP_ATM_PDUS) {
+ if (wth->file_type == WTAP_FILE_PCAP_NOKIA) {
+ /*
+ * Nokia IPSO ATM.
+ *
+ * Guess the traffic type based on the packet
+ * contents.
+ */
+ atm_guess_traffic_type(pd, length, pseudo_header);
+ } else {
+ /*
+ * SunATM.
+ *
+ * If this is ATM LANE traffic, try to guess what
+ * type of LANE traffic it is based on the packet
+ * contents.
+ */
+ if (pseudo_header->atm.type == TRAF_LANE)
+ atm_guess_lane_type(pd, length, pseudo_header);
+ }
+ }
return TRUE;
}
case WTAP_FILE_PCAP:
case WTAP_FILE_PCAP_AIX:
+ case WTAP_FILE_PCAP_NSEC:
bytes_to_read = sizeof (struct pcaprec_hdr);
break;
}
static void
-libpcap_get_atm_pseudoheader(const struct sunatm_hdr *atm_phdr,
+libpcap_get_sunatm_pseudoheader(const struct sunatm_hdr *atm_phdr,
union wtap_pseudo_header *pseudo_header)
{
guint8 vpi;
vpi = atm_phdr->vpi;
vci = pntohs(&atm_phdr->vci);
- /*
- * The lower 4 bits of the first byte of the header indicate
- * the type of traffic, as per the "atmioctl.h" header in
- * SunATM.
- */
switch (atm_phdr->flags & 0x0F) {
case 0x01: /* LANE */
}
static gboolean
-libpcap_read_atm_pseudoheader(FILE_T fh, union wtap_pseudo_header *pseudo_header,
- int *err)
+libpcap_read_sunatm_pseudoheader(FILE_T fh,
+ union wtap_pseudo_header *pseudo_header, int *err)
{
struct sunatm_hdr atm_phdr;
int bytes_read;
return FALSE;
}
- libpcap_get_atm_pseudoheader(&atm_phdr, pseudo_header);
+ libpcap_get_sunatm_pseudoheader(&atm_phdr, pseudo_header);
+
+ return TRUE;
+}
+
+static gboolean
+libpcap_read_nokiaatm_pseudoheader(FILE_T fh,
+ union wtap_pseudo_header *pseudo_header, int *err)
+{
+ struct nokiaatm_hdr atm_phdr;
+ int bytes_read;
+ guint8 vpi;
+ guint16 vci;
+
+ errno = WTAP_ERR_CANT_READ;
+ bytes_read = file_read(&atm_phdr, 1, sizeof (struct nokiaatm_hdr), fh);
+ if (bytes_read != sizeof (struct nokiaatm_hdr)) {
+ *err = file_error(fh);
+ if (*err == 0)
+ *err = WTAP_ERR_SHORT_READ;
+ return FALSE;
+ }
+
+ vpi = atm_phdr.vpi;
+ vci = pntohs(&atm_phdr.vci);
+
+ pseudo_header->atm.vpi = vpi;
+ pseudo_header->atm.vci = vci;
+ pseudo_header->atm.channel = (atm_phdr.flags & 0x80) ? 0 : 1;
+
+ /* We don't have this information */
+ pseudo_header->atm.flags = 0;
+ pseudo_header->atm.cells = 0;
+ pseudo_header->atm.aal5t_u2u = 0;
+ pseudo_header->atm.aal5t_len = 0;
+ pseudo_header->atm.aal5t_chksum = 0;
return TRUE;
}
err_info);
}
+static gboolean
+libpcap_get_mtp2_pseudoheader(const struct mtp2_hdr *mtp2_hdr, union wtap_pseudo_header *pseudo_header)
+{
+ pseudo_header->mtp2.sent = mtp2_hdr->sent;
+ pseudo_header->mtp2.annex_a_used = mtp2_hdr->annex_a_used;
+ pseudo_header->mtp2.link_number = pntohs(&mtp2_hdr->link_number);
+
+ return TRUE;
+}
+
+static gboolean
+libpcap_read_mtp2_pseudoheader(FILE_T fh, union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info _U_)
+{
+ struct mtp2_hdr mtp2_hdr;
+ int bytes_read;
+
+ errno = WTAP_ERR_CANT_READ;
+ bytes_read = file_read(&mtp2_hdr, 1, sizeof (struct mtp2_hdr), fh);
+ if (bytes_read != sizeof (struct mtp2_hdr)) {
+ *err = file_error(fh);
+ if (*err == 0)
+ *err = WTAP_ERR_SHORT_READ;
+ return FALSE;
+ }
+
+ return libpcap_get_mtp2_pseudoheader(&mtp2_hdr, pseudo_header);
+
+}
+
static gboolean
libpcap_read_rec_data(FILE_T fh, guchar *pd, int length, int *err)
{
case WTAP_ENCAP_FDDI:
case WTAP_ENCAP_FDDI_BITSWAPPED:
+ case WTAP_ENCAP_NETTL_FDDI:
/*
* Special-case WTAP_ENCAP_FDDI and
* WTAP_ENCAP_FDDI_BITSWAPPED; both of them get mapped
be a "struct bpf_timeval", with member sizes wired to 32
bits - and we may go that way ourselves in the future, so
copy the members individually. */
- whdr->ts.tv_sec = phdr->ts.tv_sec;
- whdr->ts.tv_usec = phdr->ts.tv_usec;
+ whdr->ts.secs = phdr->ts.tv_sec;
+ whdr->ts.nsecs = phdr->ts.tv_usec * 1000;
whdr->caplen = phdr->caplen;
whdr->len = phdr->len;
whdr->pkt_encap = linktype;
*err = WTAP_ERR_BAD_RECORD;
return NULL;
}
- libpcap_get_atm_pseudoheader((const struct sunatm_hdr *)pd,
+ libpcap_get_sunatm_pseudoheader((const struct sunatm_hdr *)pd,
pseudo_header);
/*
whdr->caplen -= sizeof (struct irda_sll_hdr);
pd += sizeof (struct irda_sll_hdr);
}
+ else if (linktype == WTAP_ENCAP_MTP2_WITH_PHDR) {
+ if (whdr->caplen < sizeof (struct mtp2_hdr)) {
+ /*
+ * Uh-oh, the packet isn't big enough to even
+ * have a pseudo-header.
+ */
+ g_message("libpcap: MTP2 capture has a %u-byte packet, too small to have even an MTP2 pseudo-header\n",
+ whdr->caplen);
+ *err = WTAP_ERR_BAD_RECORD;
+ return NULL;
+ }
+ if (!libpcap_get_mtp2_pseudoheader((const struct mtp2_hdr *)pd, pseudo_header))
+ return NULL;
+
+ /*
+ * Don't count the pseudo-header as part of the packet.
+ */
+ whdr->len -= sizeof (struct mtp2_hdr);
+ whdr->caplen -= sizeof (struct mtp2_hdr);
+ pd += sizeof (struct mtp2_hdr);
+ }
return pd;
}
#endif
case WTAP_FILE_PCAP_SS990417: /* modified, but with the old magic, sigh */
case WTAP_FILE_PCAP_NOKIA: /* Nokia libpcap of some sort */
magic = PCAP_MAGIC;
+ wdh->tsprecision = WTAP_FILE_TSPREC_USEC;
break;
case WTAP_FILE_PCAP_SS990915: /* new magic, extra crap */
case WTAP_FILE_PCAP_SS991029:
magic = PCAP_MODIFIED_MAGIC;
+ wdh->tsprecision = WTAP_FILE_TSPREC_USEC;
+ break;
+
+ case WTAP_FILE_PCAP_NSEC: /* same as WTAP_FILE_PCAP, but nsec precision */
+ magic = PCAP_NSEC_MAGIC;
+ wdh->tsprecision = WTAP_FILE_TSPREC_NSEC;
break;
default:
return FALSE;
}
- nwritten = fwrite(&magic, 1, sizeof magic, wdh->fh);
+ nwritten = wtap_dump_file_write(wdh, &magic, sizeof magic);
if (nwritten != sizeof magic) {
- if (nwritten == 0 && ferror(wdh->fh))
- *err = errno;
+ if (nwritten == 0 && wtap_dump_file_ferror(wdh))
+ *err = wtap_dump_file_ferror(wdh);
else
*err = WTAP_ERR_SHORT_WRITE;
return FALSE;
file_hdr.snaplen = (wdh->snaplen != 0) ? wdh->snaplen :
WTAP_MAX_PACKET_SIZE;
file_hdr.network = wtap_wtap_encap_to_pcap_encap(wdh->encap);
- nwritten = fwrite(&file_hdr, 1, sizeof file_hdr, wdh->fh);
+ nwritten = wtap_dump_file_write(wdh, &file_hdr, sizeof file_hdr);
if (nwritten != sizeof file_hdr) {
- if (nwritten == 0 && ferror(wdh->fh))
- *err = errno;
+ if (nwritten == 0 && wtap_dump_file_ferror(wdh))
+ *err = wtap_dump_file_ferror(wdh);
else
*err = WTAP_ERR_SHORT_WRITE;
return FALSE;
size_t nwritten;
struct sunatm_hdr atm_hdr;
struct irda_sll_hdr irda_hdr;
+ struct mtp2_hdr mtp2_hdr;
int hdrsize;
if (wdh->encap == WTAP_ENCAP_ATM_PDUS)
else
hdrsize = 0;
- rec_hdr.hdr.ts_sec = phdr->ts.tv_sec;
- rec_hdr.hdr.ts_usec = phdr->ts.tv_usec;
+ rec_hdr.hdr.ts_sec = phdr->ts.secs;
+ if(wdh->tsprecision == WTAP_FILE_TSPREC_NSEC) {
+ rec_hdr.hdr.ts_usec = phdr->ts.nsecs;
+ } else {
+ rec_hdr.hdr.ts_usec = phdr->ts.nsecs / 1000;
+ }
rec_hdr.hdr.incl_len = phdr->caplen + hdrsize;
rec_hdr.hdr.orig_len = phdr->len + hdrsize;
switch (wdh->file_type) {
case WTAP_FILE_PCAP:
+ case WTAP_FILE_PCAP_NSEC:
hdr_size = sizeof (struct pcaprec_hdr);
break;
return FALSE;
}
- nwritten = fwrite(&rec_hdr, 1, hdr_size, wdh->fh);
+ nwritten = wtap_dump_file_write(wdh, &rec_hdr, hdr_size);
if (nwritten != hdr_size) {
- if (nwritten == 0 && ferror(wdh->fh))
- *err = errno;
+ if (nwritten == 0 && wtap_dump_file_ferror(wdh))
+ *err = wtap_dump_file_ferror(wdh);
else
*err = WTAP_ERR_SHORT_WRITE;
return FALSE;
}
atm_hdr.vpi = (guint8) pseudo_header->atm.vpi;
atm_hdr.vci = phtons(&pseudo_header->atm.vci);
- nwritten = fwrite(&atm_hdr, 1, sizeof atm_hdr, wdh->fh);
+ nwritten = wtap_dump_file_write(wdh, &atm_hdr, sizeof atm_hdr);
if (nwritten != sizeof atm_hdr) {
- if (nwritten == 0 && ferror(wdh->fh))
- *err = errno;
+ if (nwritten == 0 && wtap_dump_file_ferror(wdh))
+ *err = wtap_dump_file_ferror(wdh);
else
*err = WTAP_ERR_SHORT_WRITE;
return FALSE;
memset(&irda_hdr, 0, sizeof(irda_hdr));
irda_hdr.sll_pkttype = phtons(&pseudo_header->irda.pkttype);
irda_hdr.sll_protocol = g_htons(0x0017);
- nwritten = fwrite(&irda_hdr, 1, sizeof(irda_hdr), wdh->fh);
+ nwritten = wtap_dump_file_write(wdh, &irda_hdr, sizeof(irda_hdr));
if (nwritten != sizeof(irda_hdr)) {
- if (nwritten == 0 && ferror(wdh->fh))
- *err = errno;
+ if (nwritten == 0 && wtap_dump_file_ferror(wdh))
+ *err = wtap_dump_file_ferror(wdh);
else
*err = WTAP_ERR_SHORT_WRITE;
return FALSE;
}
wdh->bytes_dumped += sizeof(irda_hdr);
}
+ else if (wdh->encap == WTAP_ENCAP_MTP2_WITH_PHDR) {
+ /*
+ * Write the MTP2 header.
+ */
+ memset(&mtp2_hdr, 0, sizeof(mtp2_hdr));
+ mtp2_hdr.sent = pseudo_header->mtp2.sent;
+ mtp2_hdr.annex_a_used = pseudo_header->mtp2.annex_a_used;
+ mtp2_hdr.link_number = phtons(&pseudo_header->mtp2.link_number);
+ nwritten = wtap_dump_file_write(wdh, &mtp2_hdr, sizeof(mtp2_hdr));
+ if (nwritten != sizeof(mtp2_hdr)) {
+ if (nwritten == 0 && wtap_dump_file_ferror(wdh))
+ *err = wtap_dump_file_ferror(wdh);
+ else
+ *err = WTAP_ERR_SHORT_WRITE;
+ return FALSE;
+ }
+ wdh->bytes_dumped += sizeof(mtp2_hdr);
+ }
- nwritten = fwrite(pd, 1, phdr->caplen, wdh->fh);
+ nwritten = wtap_dump_file_write(wdh, pd, phdr->caplen);
if (nwritten != phdr->caplen) {
- if (nwritten == 0 && ferror(wdh->fh))
- *err = errno;
+ if (nwritten == 0 && wtap_dump_file_ferror(wdh))
+ *err = wtap_dump_file_ferror(wdh);
else
*err = WTAP_ERR_SHORT_WRITE;
return FALSE;