diff options
author | Guy Harris <guy@alum.mit.edu> | 2007-05-28 06:47:50 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2007-05-28 06:47:50 +0000 |
commit | e49fe5baec7fc654cb9e745f25bc21e94b3b69d7 (patch) | |
tree | c10c180e108705b62619bf05558db6427c69c72e | |
parent | 430a1de0c0e40cfefb27fcdf3d81f4dfa5501add (diff) |
Change the Wiretap code so that it doesn't dereference
possibly-unaligned pointers, and turn on -Wcast-align so at least some
future code that does that will fail to compile.
svn path=/trunk/; revision=21968
-rw-r--r-- | wiretap/configure.in | 5 | ||||
-rw-r--r-- | wiretap/csids.c | 24 | ||||
-rw-r--r-- | wiretap/libpcap.c | 288 | ||||
-rw-r--r-- | wiretap/wtap-int.h | 60 |
4 files changed, 201 insertions, 176 deletions
diff --git a/wiretap/configure.in b/wiretap/configure.in index 591c09dd8c..5a48aee475 100644 --- a/wiretap/configure.in +++ b/wiretap/configure.in @@ -35,10 +35,6 @@ AC_ARG_ENABLE(extra-gcc-checks, then AC_WIRETAP_GCC_CFLAGS_CHECK(-pedantic) AC_WIRETAP_GCC_CFLAGS_CHECK(-Wno-long-long) - #Temporarily put cast-align here waiting eradication of 'cast - #increases required alignment of target type' on the Solaris - #slave. - AC_WIRETAP_GCC_CFLAGS_CHECK(-Wcast-align) fi ],) AC_WIRETAP_GCC_CFLAGS_CHECK(-Wall -W) @@ -52,6 +48,7 @@ AC_WIRETAP_GCC_CFLAGS_CHECK(-Wshorten-64-to-32) AC_WIRETAP_GCC_CFLAGS_CHECK(-Wstrict-prototypes) AC_WIRETAP_GCC_CFLAGS_CHECK(-Wmissing-declarations) AC_WIRETAP_GCC_CFLAGS_CHECK(-Wno-pointer-sign) +AC_WIRETAP_GCC_CFLAGS_CHECK(-Wcast-align) # # If we're running gcc add '-D_U_="__attribute__((unused))"' to CFLAGS as well, diff --git a/wiretap/csids.c b/wiretap/csids.c index fc078c2129..1e0f862aa9 100644 --- a/wiretap/csids.c +++ b/wiretap/csids.c @@ -184,14 +184,10 @@ static gboolean csids_read(wtap *wth, int *err, gchar **err_info _U_, wth->phdr.ts.secs = hdr.seconds; wth->phdr.ts.nsecs = 0; - if( wth->capture.csids->byteswapped == TRUE ) { - guint16* swap = (guint16*)buf; - swap++; - *(swap) = BSWAP16(*swap); /* the ip len */ - swap++; - *(swap) = BSWAP16(*swap); /* ip id */ - swap++; - *(swap) = BSWAP16(*swap); /* ip flags and fragoff */ + if( wth->capture.csids->byteswapped ) { + PBSWAP16(buf); /* the ip len */ + PBSWAP16(buf+2); /* ip id */ + PBSWAP16(buf+4); /* ip flags and fragoff */ } return TRUE; @@ -240,14 +236,10 @@ csids_seek_read (wtap *wth, return FALSE; } - if( wth->capture.csids->byteswapped == TRUE ) { - guint16* swap = (guint16*)pd; - swap++; - *(swap) = BSWAP16(*swap); /* the ip len */ - swap++; - *(swap) = BSWAP16(*swap); /* ip id */ - swap++; - *(swap) = BSWAP16(*swap); /* ip flags and fragoff */ + if( wth->capture.csids->byteswapped ) { + PBSWAP16(pd); /* the ip len */ + PBSWAP16(pd+2); /* ip id */ + PBSWAP16(pd+4); /* ip flags and fragoff */ } return TRUE; diff --git a/wiretap/libpcap.c b/wiretap/libpcap.c index e8cf02b552..94e838b2b5 100644 --- a/wiretap/libpcap.c +++ b/wiretap/libpcap.c @@ -45,56 +45,59 @@ #endif /* + * Various pseudo-headers that appear at the beginning of packet data. + * + * We represent them as sets of offsets, as they might not be aligned on + * an appropriate structure boundary in the buffer, and as that makes them + * independent of the way the compiler might align fields. + */ + +/* * The link-layer header on SunATM packets. */ -struct sunatm_hdr { - guint8 flags; /* destination and traffic type */ - guint8 vpi; /* VPI */ - guint16 vci; /* VCI */ -}; +#define SUNATM_FLAGS 0 /* destination and traffic type - 1 byte */ +#define SUNATM_VPI 1 /* VPI - 1 byte */ +#define SUNATM_VCI 2 /* VCI - 2 bytes */ +#define SUNATM_LEN 4 /* length of the header */ /* * The link-layer header on Nokia IPSO ATM packets. */ -struct nokiaatm_hdr { - guint8 flags; /* destination */ - guint8 vpi; /* VPI */ - guint16 vci; /* VCI */ -}; +#define NOKIAATM_FLAGS 0 /* destination - 1 byte */ +#define NOKIAATM_VPI 1 /* VPI - 1 byte */ +#define NOKIAATM_VCI 2 /* VCI - 2 bytes */ +#define NOKIAATM_LEN 4 /* length of the header */ /* * The fake link-layer header of IrDA packets as introduced by Jean Tourrilhes * to libpcap. */ -struct irda_sll_hdr { - guint16 sll_pkttype; /* packet type */ - guint8 unused[12]; /* usused SLL header fields */ - guint16 sll_protocol; /* protocol, should be 0x0017 */ -}; +#define IRDA_SLL_PKTTYPE_OFFSET 0 /* packet type - 2 bytes */ +/* 12 unused bytes */ +#define IRDA_SLL_PROTOCOL_OFFSET 14 /* protocol, should be ETH_P_LAPD - 2 bytes */ +#define IRDA_SLL_LEN 16 /* length of the header */ /* * A header containing additional MTP information. */ -struct mtp2_hdr { - guint8 sent; - guint8 annex_a_used; - guint16 link_number; -}; +#define MTP2_SENT_OFFSET 0 /* 1 byte */ +#define MTP2_ANNEX_A_USED_OFFSET 1 /* 1 byte */ +#define MTP2_LINK_NUMBER_OFFSET 2 /* 2 bytes */ +#define MTP2_HDR_LEN 4 /* length of the header */ +/* + * The fake link-layer header of LAPD packets. + */ #ifndef ETH_P_LAPD #define ETH_P_LAPD 0x0030 #endif -/* - * The fake link-layer header of LAPD packets - */ -struct lapd_sll_hdr { - guint16 sll_pkttype; /* packet type */ - guint16 sll_hatype; - guint16 sll_halen; - guint8 sll_addr[8]; - guint16 sll_protocol; /* protocol, should be ETH_P_LAPD */ -}; +#define LAPD_SLL_PKTTYPE_OFFSET 0 /* packet type - 2 bytes */ +#define LAPD_SLL_HATYPE_OFFSET 2 /* hardware address type - 2 bytes */ +#define LAPD_SLL_HALEN_OFFSET 4 /* hardware address length - 2 bytes */ +#define LAPD_SLL_ADDR_OFFSET 6 /* address - 8 bytes */ +#define LAPD_SLL_PROTOCOL_OFFSET 14 /* protocol, should be ETH_P_LAPD - 2 bytes */ +#define LAPD_SLL_LEN 16 /* length of the header */ /* See source to the "libpcap" library for information on the "libpcap" file format. */ @@ -120,21 +123,21 @@ static gboolean libpcap_seek_read(wtap *wth, gint64 seek_off, 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_sunatm_pseudoheader(const struct sunatm_hdr *atm_phdr, +static void libpcap_get_sunatm_pseudoheader(const guint8 *atm_phdr, union wtap_pseudo_header *pseudo_header); 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, +static gboolean libpcap_get_irda_pseudoheader(const guint8 *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, +static gboolean libpcap_get_mtp2_pseudoheader(const guint8 *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_get_lapd_pseudoheader(const struct lapd_sll_hdr *lapd_phdr, +static gboolean libpcap_get_lapd_pseudoheader(const guint8 *lapd_phdr, union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info); static gboolean libpcap_read_lapd_pseudoheader(FILE_T fh, union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info); @@ -1221,7 +1224,7 @@ static gboolean libpcap_read(wtap *wth, int *err, gchar **err_info, /* * Nokia IPSO ATM. */ - if (packet_size < sizeof (struct nokiaatm_hdr)) { + if (packet_size < NOKIAATM_LEN) { /* * Uh-oh, the packet isn't big enough to even * have a pseudo-header. @@ -1239,14 +1242,14 @@ static gboolean libpcap_read(wtap *wth, int *err, gchar **err_info, * 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); + orig_size -= NOKIAATM_LEN; + packet_size -= NOKIAATM_LEN; + wth->data_offset += NOKIAATM_LEN; } else { /* * SunATM. */ - if (packet_size < sizeof (struct sunatm_hdr)) { + if (packet_size < SUNATM_LEN) { /* * Uh-oh, the packet isn't big enough to even * have a pseudo-header. @@ -1264,9 +1267,9 @@ static gboolean libpcap_read(wtap *wth, int *err, gchar **err_info, * 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); + orig_size -= SUNATM_LEN; + packet_size -= SUNATM_LEN; + wth->data_offset += SUNATM_LEN; } break; @@ -1293,7 +1296,7 @@ static gboolean libpcap_read(wtap *wth, int *err, gchar **err_info, break; case WTAP_ENCAP_IRDA: - if (packet_size < sizeof (struct irda_sll_hdr)) { + if (packet_size < IRDA_SLL_LEN) { /* * Uh-oh, the packet isn't big enough to even * have a pseudo-header. @@ -1310,13 +1313,13 @@ static gboolean libpcap_read(wtap *wth, int *err, gchar **err_info, /* * Don't count the pseudo-header as part of the packet. */ - orig_size -= sizeof (struct irda_sll_hdr); - packet_size -= sizeof (struct irda_sll_hdr); - wth->data_offset += sizeof (struct irda_sll_hdr); + orig_size -= IRDA_SLL_LEN; + packet_size -= IRDA_SLL_LEN; + wth->data_offset += IRDA_SLL_LEN; break; case WTAP_ENCAP_MTP2_WITH_PHDR: - if (packet_size < sizeof (struct mtp2_hdr)) { + if (packet_size < MTP2_HDR_LEN) { /* * Uh-oh, the packet isn't big enough to even * have a pseudo-header. @@ -1333,13 +1336,13 @@ static gboolean libpcap_read(wtap *wth, int *err, gchar **err_info, /* * 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); + orig_size -= MTP2_HDR_LEN; + packet_size -= MTP2_HDR_LEN; + wth->data_offset += MTP2_HDR_LEN; break; case WTAP_ENCAP_LINUX_LAPD: - if (packet_size < sizeof (struct lapd_sll_hdr)) { + if (packet_size < LAPD_SLL_LEN) { /* * Uh-oh, the packet isn't big enough to even * have a pseudo-header. @@ -1356,9 +1359,9 @@ static gboolean libpcap_read(wtap *wth, int *err, gchar **err_info, /* * Don't count the pseudo-header as part of the packet. */ - orig_size -= sizeof (struct lapd_sll_hdr); - packet_size -= sizeof (struct lapd_sll_hdr); - wth->data_offset += sizeof (struct lapd_sll_hdr); + orig_size -= LAPD_SLL_LEN; + packet_size -= LAPD_SLL_LEN; + wth->data_offset += LAPD_SLL_LEN; break; case WTAP_ENCAP_USB_LINUX: @@ -1661,16 +1664,16 @@ adjust_header(wtap *wth, struct pcaprec_hdr *hdr) } static void -libpcap_get_sunatm_pseudoheader(const struct sunatm_hdr *atm_phdr, +libpcap_get_sunatm_pseudoheader(const guint8 *atm_phdr, union wtap_pseudo_header *pseudo_header) { guint8 vpi; guint16 vci; - vpi = atm_phdr->vpi; - vci = pntohs(&atm_phdr->vci); + vpi = atm_phdr[SUNATM_VPI]; + vci = pntohs(&atm_phdr[SUNATM_VCI]); - switch (atm_phdr->flags & 0x0F) { + switch (atm_phdr[SUNATM_FLAGS] & 0x0F) { case 0x01: /* LANE */ pseudo_header->atm.aal = AAL_5; @@ -1725,7 +1728,7 @@ libpcap_get_sunatm_pseudoheader(const struct sunatm_hdr *atm_phdr, pseudo_header->atm.vpi = vpi; pseudo_header->atm.vci = vci; - pseudo_header->atm.channel = (atm_phdr->flags & 0x80) ? 0 : 1; + pseudo_header->atm.channel = (atm_phdr[SUNATM_FLAGS] & 0x80) ? 0 : 1; /* We don't have this information */ pseudo_header->atm.flags = 0; @@ -1739,19 +1742,19 @@ static gboolean libpcap_read_sunatm_pseudoheader(FILE_T fh, union wtap_pseudo_header *pseudo_header, int *err) { - struct sunatm_hdr atm_phdr; + guint8 atm_phdr[SUNATM_LEN]; int bytes_read; errno = WTAP_ERR_CANT_READ; - bytes_read = file_read(&atm_phdr, 1, sizeof (struct sunatm_hdr), fh); - if (bytes_read != sizeof (struct sunatm_hdr)) { + bytes_read = file_read(atm_phdr, 1, SUNATM_LEN, fh); + if (bytes_read != SUNATM_LEN) { *err = file_error(fh); if (*err == 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } - libpcap_get_sunatm_pseudoheader(&atm_phdr, pseudo_header); + libpcap_get_sunatm_pseudoheader(atm_phdr, pseudo_header); return TRUE; } @@ -1760,26 +1763,26 @@ static gboolean libpcap_read_nokiaatm_pseudoheader(FILE_T fh, union wtap_pseudo_header *pseudo_header, int *err) { - struct nokiaatm_hdr atm_phdr; + guint8 atm_phdr[NOKIAATM_LEN]; 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)) { + bytes_read = file_read(atm_phdr, 1, NOKIAATM_LEN, fh); + if (bytes_read != NOKIAATM_LEN) { *err = file_error(fh); if (*err == 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } - vpi = atm_phdr.vpi; - vci = pntohs(&atm_phdr.vci); + vpi = atm_phdr[NOKIAATM_VPI]; + vci = pntohs(&atm_phdr[NOKIAATM_VCI]); pseudo_header->atm.vpi = vpi; pseudo_header->atm.vci = vci; - pseudo_header->atm.channel = (atm_phdr.flags & 0x80) ? 0 : 1; + pseudo_header->atm.channel = (atm_phdr[NOKIAATM_FLAGS] & 0x80) ? 0 : 1; /* We don't have this information */ pseudo_header->atm.flags = 0; @@ -1792,17 +1795,17 @@ libpcap_read_nokiaatm_pseudoheader(FILE_T fh, } static gboolean -libpcap_get_irda_pseudoheader(const struct irda_sll_hdr *irda_phdr, +libpcap_get_irda_pseudoheader(const guint8 *irda_phdr, union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info) { - if (pntohs(&irda_phdr->sll_protocol) != 0x0017) { + if (pntohs(&irda_phdr[IRDA_SLL_PROTOCOL_OFFSET]) != 0x0017) { *err = WTAP_ERR_BAD_RECORD; if (err_info != NULL) *err_info = g_strdup("libpcap: IrDA capture has a packet with an invalid sll_protocol field\n"); return FALSE; } - pseudo_header->irda.pkttype = pntohs(&irda_phdr->sll_pkttype); + pseudo_header->irda.pkttype = pntohs(&irda_phdr[IRDA_SLL_PKTTYPE_OFFSET]); return TRUE; } @@ -1811,28 +1814,28 @@ static gboolean libpcap_read_irda_pseudoheader(FILE_T fh, union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info) { - struct irda_sll_hdr irda_phdr; + guint8 irda_phdr[IRDA_SLL_LEN]; int bytes_read; errno = WTAP_ERR_CANT_READ; - bytes_read = file_read(&irda_phdr, 1, sizeof (struct irda_sll_hdr), fh); - if (bytes_read != sizeof (struct irda_sll_hdr)) { + bytes_read = file_read(irda_phdr, 1, IRDA_SLL_LEN, fh); + if (bytes_read != IRDA_SLL_LEN) { *err = file_error(fh); if (*err == 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } - return libpcap_get_irda_pseudoheader(&irda_phdr, pseudo_header, err, + return libpcap_get_irda_pseudoheader(irda_phdr, pseudo_header, err, err_info); } static gboolean -libpcap_get_mtp2_pseudoheader(const struct mtp2_hdr *mtp2_hdr, union wtap_pseudo_header *pseudo_header) +libpcap_get_mtp2_pseudoheader(const guint8 *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); + pseudo_header->mtp2.sent = mtp2_hdr[MTP2_SENT_OFFSET]; + pseudo_header->mtp2.annex_a_used = mtp2_hdr[MTP2_ANNEX_A_USED_OFFSET]; + pseudo_header->mtp2.link_number = pntohs(&mtp2_hdr[MTP2_LINK_NUMBER_OFFSET]); return TRUE; } @@ -1840,35 +1843,35 @@ libpcap_get_mtp2_pseudoheader(const struct mtp2_hdr *mtp2_hdr, union wtap_pseudo 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; + guint8 mtp2_hdr[MTP2_HDR_LEN]; 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)) { + bytes_read = file_read(mtp2_hdr, 1, MTP2_HDR_LEN, fh); + if (bytes_read != MTP2_HDR_LEN) { *err = file_error(fh); if (*err == 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } - return libpcap_get_mtp2_pseudoheader(&mtp2_hdr, pseudo_header); + return libpcap_get_mtp2_pseudoheader(mtp2_hdr, pseudo_header); } static gboolean -libpcap_get_lapd_pseudoheader(const struct lapd_sll_hdr *lapd_phdr, +libpcap_get_lapd_pseudoheader(const guint8 *lapd_phdr, union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info) { - if (pntohs(&lapd_phdr->sll_protocol) != ETH_P_LAPD) { + if (pntohs(&lapd_phdr[LAPD_SLL_PROTOCOL_OFFSET]) != ETH_P_LAPD) { *err = WTAP_ERR_BAD_RECORD; if (err_info != NULL) *err_info = g_strdup("libpcap: LAPD capture has a packet with an invalid sll_protocol field\n"); return FALSE; } - pseudo_header->lapd.pkttype = pntohs(&lapd_phdr->sll_pkttype); - pseudo_header->lapd.we_network = !!lapd_phdr->sll_addr[0]; + pseudo_header->lapd.pkttype = pntohs(&lapd_phdr[LAPD_SLL_PKTTYPE_OFFSET]); + pseudo_header->lapd.we_network = !!lapd_phdr[LAPD_SLL_ADDR_OFFSET+0]; return TRUE; } @@ -1877,19 +1880,19 @@ static gboolean libpcap_read_lapd_pseudoheader(FILE_T fh, union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info) { - struct lapd_sll_hdr lapd_phdr; + guint8 lapd_phdr[LAPD_SLL_LEN]; int bytes_read; errno = WTAP_ERR_CANT_READ; - bytes_read = file_read(&lapd_phdr, 1, sizeof (struct lapd_sll_hdr), fh); - if (bytes_read != sizeof (struct lapd_sll_hdr)) { + bytes_read = file_read(lapd_phdr, 1, LAPD_SLL_LEN, fh); + if (bytes_read != LAPD_SLL_LEN) { *err = file_error(fh); if (*err == 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } - return libpcap_get_lapd_pseudoheader(&lapd_phdr, pseudo_header, err, + return libpcap_get_lapd_pseudoheader(lapd_phdr, pseudo_header, err, err_info); } @@ -2042,7 +2045,7 @@ wtap_process_pcap_packet(gint linktype, const struct pcap_pkthdr *phdr, switch (linktype) { case WTAP_ENCAP_ATM_PDUS: - if (whdr->caplen < sizeof (struct sunatm_hdr)) { + if (whdr->caplen < SUNATM_LEN) { /* * Uh-oh, the packet isn't big enough to even * have a pseudo-header. @@ -2052,15 +2055,14 @@ wtap_process_pcap_packet(gint linktype, const struct pcap_pkthdr *phdr, *err = WTAP_ERR_BAD_RECORD; return NULL; } - libpcap_get_sunatm_pseudoheader((const struct sunatm_hdr *)pd, - pseudo_header); + libpcap_get_sunatm_pseudoheader(pd, pseudo_header); /* * Don't count the pseudo-header as part of the packet. */ - whdr->len -= sizeof (struct sunatm_hdr); - whdr->caplen -= sizeof (struct sunatm_hdr); - pd += sizeof (struct sunatm_hdr); + whdr->len -= SUNATM_LEN; + whdr->caplen -= SUNATM_LEN; + pd += SUNATM_LEN; /* * If this is ATM LANE traffic, try to guess what type of @@ -2071,7 +2073,7 @@ wtap_process_pcap_packet(gint linktype, const struct pcap_pkthdr *phdr, break; case WTAP_ENCAP_IRDA: - if (whdr->caplen < sizeof (struct irda_sll_hdr)) { + if (whdr->caplen < IRDA_SLL_LEN) { /* * Uh-oh, the packet isn't big enough to even * have a pseudo-header. @@ -2081,20 +2083,19 @@ wtap_process_pcap_packet(gint linktype, const struct pcap_pkthdr *phdr, *err = WTAP_ERR_BAD_RECORD; return NULL; } - if (!libpcap_get_irda_pseudoheader((const struct irda_sll_hdr *)pd, - pseudo_header, err, NULL)) + if (!libpcap_get_irda_pseudoheader(pd, pseudo_header, err, NULL)) return NULL; /* * Don't count the pseudo-header as part of the packet. */ - whdr->len -= sizeof (struct irda_sll_hdr); - whdr->caplen -= sizeof (struct irda_sll_hdr); - pd += sizeof (struct irda_sll_hdr); + whdr->len -= IRDA_SLL_LEN; + whdr->caplen -= IRDA_SLL_LEN; + pd += IRDA_SLL_LEN; break; case WTAP_ENCAP_MTP2_WITH_PHDR: - if (whdr->caplen < sizeof (struct mtp2_hdr)) { + if (whdr->caplen < MTP2_HDR_LEN) { /* * Uh-oh, the packet isn't big enough to even * have a pseudo-header. @@ -2104,19 +2105,19 @@ wtap_process_pcap_packet(gint linktype, const struct pcap_pkthdr *phdr, *err = WTAP_ERR_BAD_RECORD; return NULL; } - if (!libpcap_get_mtp2_pseudoheader((const struct mtp2_hdr *)pd, pseudo_header)) + if (!libpcap_get_mtp2_pseudoheader(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); + whdr->len -= MTP2_HDR_LEN; + whdr->caplen -= MTP2_HDR_LEN; + pd += MTP2_HDR_LEN; break; case WTAP_ENCAP_LINUX_LAPD: - if (whdr->caplen < sizeof (struct lapd_sll_hdr)) { + if (whdr->caplen < LAPD_SLL_LEN) { /* * Uh-oh, the packet isn't big enough to even * have a pseudo-header. @@ -2126,16 +2127,15 @@ wtap_process_pcap_packet(gint linktype, const struct pcap_pkthdr *phdr, *err = WTAP_ERR_BAD_RECORD; return NULL; } - if (!libpcap_get_lapd_pseudoheader((const struct lapd_sll_hdr *)pd, - pseudo_header, err, NULL)) + if (!libpcap_get_lapd_pseudoheader(pd, pseudo_header, err, NULL)) return NULL; /* * Don't count the pseudo-header as part of the packet. */ - whdr->len -= sizeof (struct lapd_sll_hdr); - whdr->caplen -= sizeof (struct lapd_sll_hdr); - pd += sizeof (struct lapd_sll_hdr); + whdr->len -= LAPD_SLL_LEN; + whdr->caplen -= LAPD_SLL_LEN; + pd += LAPD_SLL_LEN; break; case WTAP_ENCAP_USB_LINUX: @@ -2268,28 +2268,28 @@ static gboolean libpcap_dump(wtap_dumper *wdh, struct pcaprec_ss990915_hdr rec_hdr; size_t hdr_size; size_t nwritten; - struct sunatm_hdr atm_hdr; - struct irda_sll_hdr irda_hdr; - struct lapd_sll_hdr lapd_hdr; - struct mtp2_hdr mtp2_hdr; + guint8 atm_hdr[SUNATM_LEN]; + guint8 irda_hdr[IRDA_SLL_LEN]; + guint8 lapd_hdr[LAPD_SLL_LEN]; + guint8 mtp2_hdr[MTP2_HDR_LEN]; int hdrsize; switch (wdh->encap) { case WTAP_ENCAP_ATM_PDUS: - hdrsize = sizeof (struct sunatm_hdr); + hdrsize = SUNATM_LEN; break; case WTAP_ENCAP_IRDA: - hdrsize = sizeof (struct irda_sll_hdr); + hdrsize = IRDA_SLL_LEN; break; case WTAP_ENCAP_MTP2_WITH_PHDR: - hdrsize = sizeof (struct mtp2_hdr); + hdrsize = MTP2_HDR_LEN; break; case WTAP_ENCAP_LINUX_LAPD: - hdrsize = sizeof (struct lapd_sll_hdr); + hdrsize = LAPD_SLL_LEN; break; case WTAP_ENCAP_USB_LINUX: @@ -2385,13 +2385,13 @@ static gboolean libpcap_dump(wtap_dumper *wdh, /* * Write the ATM header. */ - atm_hdr.flags = + atm_hdr[SUNATM_FLAGS] = (pseudo_header->atm.channel == 0) ? 0x80 : 0x00; switch (pseudo_header->atm.aal) { case AAL_SIGNALLING: /* Q.2931 */ - atm_hdr.flags |= 0x06; + atm_hdr[SUNATM_FLAGS] |= 0x06; break; case AAL_5: @@ -2399,24 +2399,24 @@ static gboolean libpcap_dump(wtap_dumper *wdh, case TRAF_LANE: /* LANE */ - atm_hdr.flags |= 0x01; + atm_hdr[SUNATM_FLAGS] |= 0x01; break; case TRAF_LLCMX: /* RFC 1483 LLC multiplexed traffic */ - atm_hdr.flags |= 0x02; + atm_hdr[SUNATM_FLAGS] |= 0x02; break; case TRAF_ILMI: /* ILMI */ - atm_hdr.flags |= 0x05; + atm_hdr[SUNATM_FLAGS] |= 0x05; break; } break; } - atm_hdr.vpi = (guint8) pseudo_header->atm.vpi; - atm_hdr.vci = phtons(&pseudo_header->atm.vci); - nwritten = wtap_dump_file_write(wdh, &atm_hdr, sizeof atm_hdr); + atm_hdr[SUNATM_VPI] = pseudo_header->atm.vpi; + phtons(&atm_hdr[SUNATM_VCI], pseudo_header->atm.vci); + nwritten = wtap_dump_file_write(wdh, atm_hdr, sizeof atm_hdr); if (nwritten != sizeof atm_hdr) { if (nwritten == 0 && wtap_dump_file_ferror(wdh)) *err = wtap_dump_file_ferror(wdh); @@ -2431,10 +2431,11 @@ static gboolean libpcap_dump(wtap_dumper *wdh, /* * Write the IrDA header. */ - memset(&irda_hdr, 0, sizeof(irda_hdr)); - irda_hdr.sll_pkttype = phtons(&pseudo_header->irda.pkttype); - irda_hdr.sll_protocol = g_htons(0x0017); - nwritten = wtap_dump_file_write(wdh, &irda_hdr, sizeof(irda_hdr)); + memset(irda_hdr, 0, sizeof(irda_hdr)); + phtons(&irda_hdr[IRDA_SLL_PKTTYPE_OFFSET], + pseudo_header->irda.pkttype); + phtons(&irda_hdr[IRDA_SLL_PROTOCOL_OFFSET], 0x0017); + nwritten = wtap_dump_file_write(wdh, irda_hdr, sizeof(irda_hdr)); if (nwritten != sizeof(irda_hdr)) { if (nwritten == 0 && wtap_dump_file_ferror(wdh)) *err = wtap_dump_file_ferror(wdh); @@ -2450,10 +2451,11 @@ static gboolean libpcap_dump(wtap_dumper *wdh, * 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)); + mtp2_hdr[MTP2_SENT_OFFSET] = pseudo_header->mtp2.sent; + mtp2_hdr[MTP2_ANNEX_A_USED_OFFSET] = pseudo_header->mtp2.annex_a_used; + phtons(&mtp2_hdr[MTP2_LINK_NUMBER_OFFSET], + 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); @@ -2469,9 +2471,11 @@ static gboolean libpcap_dump(wtap_dumper *wdh, * Write the LAPD header. */ memset(&lapd_hdr, 0, sizeof(lapd_hdr)); - lapd_hdr.sll_pkttype = phtons(&pseudo_header->lapd.pkttype); - lapd_hdr.sll_protocol = g_htons(ETH_P_LAPD); - lapd_hdr.sll_addr[0] = pseudo_header->lapd.we_network?0x01:0x00; + phtons(&lapd_hdr[LAPD_SLL_PKTTYPE_OFFSET], + pseudo_header->lapd.pkttype); + phtons(&lapd_hdr[LAPD_SLL_PROTOCOL_OFFSET], ETH_P_LAPD); + lapd_hdr[LAPD_SLL_ADDR_OFFSET + 0] = + pseudo_header->lapd.we_network?0x01:0x00; nwritten = fwrite(&lapd_hdr, 1, sizeof(lapd_hdr), wdh->fh); if (nwritten != sizeof(lapd_hdr)) { if (nwritten == 0 && ferror(wdh->fh)) diff --git a/wiretap/wtap-int.h b/wiretap/wtap-int.h index 2ccac581bf..b9739949be 100644 --- a/wiretap/wtap-int.h +++ b/wiretap/wtap-int.h @@ -289,6 +289,27 @@ extern gint wtap_num_file_types; ((((x)&0xFF00)>>8) | \ (((x)&0x00FF)<<8)) +/* Macros to byte-swap possibly-unaligned 32-bit and 16-bit quantities; + * they take a pointer to the quantity, and byte-swap it in place. + */ +#define PBSWAP32(p) \ + { \ + guint8 tmp; \ + tmp = (p)[3]; \ + (p)[3] = (p)[0]; \ + (p)[0] = tmp; \ + tmp = (p)[2]; \ + (p)[2] = (p)[1]; \ + (p)[1] = tmp; \ + } +#define PBSWAP16(p) \ + { \ + guint8 tmp; \ + tmp = (p)[1]; \ + (p)[1] = (p)[0]; \ + (p)[0] = tmp; \ + } + /* Turn host-byte-order values into little-endian values. */ #define htoles(s) GUINT16_TO_LE(s) #define htolel(l) GUINT32_TO_LE(l) @@ -297,8 +318,10 @@ extern gint wtap_num_file_types; /* Pointer versions of ntohs and ntohl. Given a pointer to a member of a * byte array, returns the value of the two or four bytes at the pointer. * The pletoh[sl] versions return the little-endian representation. - * We also provide pntohll and phtolell, which extract 64-bit integral + * We also provide pntohll and pletohll, which extract 64-bit integral * quantities. + * + * These will work regardless of the byte alignment of the pointer. */ #ifndef pntohs @@ -332,19 +355,6 @@ extern gint wtap_num_file_types; #endif -#ifndef phtons -#define phtons(p) ((guint16) \ - ((guint16)*((const guint8 *)(p)+0)<<8| \ - (guint16)*((const guint8 *)(p)+1)<<0)) -#endif - -#ifndef phtonl -#define phtonl(p) ((guint32)*((const guint8 *)(p)+0)<<24| \ - (guint32)*((const guint8 *)(p)+1)<<16| \ - (guint32)*((const guint8 *)(p)+2)<<8| \ - (guint32)*((const guint8 *)(p)+3)<<0) -#endif - #ifndef pletohs #define pletohs(p) ((guint16) \ ((guint16)*((const guint8 *)(p)+1)<<8| \ @@ -377,6 +387,28 @@ extern gint wtap_num_file_types; (guint64)*((const guint8 *)(p)+0)<<0) #endif +/* Pointer routines to put items out in a particular byte order. + * These will work regardless of the byte alignment of the pointer. + */ + +#ifndef phtons +#define phtons(p, v) \ + { \ + (p)[0] = (v) >> 8; \ + (p)[1] = (v); \ + } +#endif + +#ifndef phtonl +#define phtonl(p, v) \ + { \ + (p)[0] = ((v) >> 24); \ + (p)[1] = ((v) >> 16); \ + (p)[2] = ((v) >> 8); \ + (p)[3] = (v); \ + } +#endif + #define wtap_file_read_unknown_bytes(target, num_bytes, fh, err) \ G_STMT_START \ { \ |