/* packet.h
* Definitions for packet disassembly structures and routines
*
- * $Id: packet.h,v 1.78 1999/08/02 02:04:26 guy Exp $
+ * $Id: packet.h,v 1.136 1999/11/11 21:22:00 nneul Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
#ifndef __PACKET_H__
#define __PACKET_H__
+#ifndef __WTAP_H__
+#include "wiretap/wtap.h"
+#endif
+
#ifndef __PROTO_H__
#include "proto.h"
#endif
#define hi_nibble(b) ((b & 0xf0) >> 4)
#define lo_nibble(b) (b & 0x0f)
-/* Byte ordering */
-#ifndef BYTE_ORDER
- #define LITTLE_ENDIAN 4321
- #define BIG_ENDIAN 1234
- #ifdef WORDS_BIGENDIAN
- #define BYTE_ORDER BIG_ENDIAN
- #else
- #define BYTE_ORDER LITTLE_ENDIAN
- #endif
-#endif
-
/* Useful when you have an array whose size you can tell at compile-time */
#define array_length(x) (sizeof x / sizeof x[0])
/* Useful when highlighting regions inside a dissect_*() function. With this
* macro, you can highlight from an arbitrary offset to the end of the
- * frame. See dissect_data() for an example.
+ * packet (which may come before the end of the frame).
+ * See dissect_data() for an example.
*/
-#define END_OF_FRAME (fd->cap_len - offset)
+#define END_OF_FRAME (pi.captured_len - offset)
+
+/* Check whether the "len" bytes of data starting at "offset" is
+ * entirely inside the captured data for this packet. */
+#define BYTES_ARE_IN_FRAME(offset, len) ((offset) + (len) <= pi.captured_len)
+
+/* Check whether there's any data at all starting at "offset". */
+#define IS_DATA_IN_FRAME(offset) ((offset) < pi.captured_len)
/* To pass one of two strings, singular or plural */
#define plurality(d,s,p) ((d) == 1 ? (s) : (p))
gint *col_fmt; /* Format of column */
gboolean **fmt_matx; /* Specifies which formats apply to a column */
gint *col_width; /* Column widths to use during a "-S" capture */
+ gchar **col_title; /* Column titles */
gchar **col_data; /* Column data */
} column_info;
#define COL_MAX_LEN 256
+#define COL_MAX_INFO_LEN 4096
typedef struct _packet_counts {
gint tcp;
gint udp;
+ gint icmp;
gint ospf;
gint gre;
+ gint netbios;
gint other;
gint total;
} packet_counts;
+/* XXX - some of this stuff is used only while a packet is being dissected;
+ should we keep around a separate data structure for that, to save
+ memory?
+
+ Also, should the pseudo-header be supplied by Wiretap when you do a
+ seek-and-read, so that we don't have to save it for all frames? */
typedef struct _frame_data {
+ struct _frame_data *next; /* Next element in list */
+ struct _frame_data *prev; /* Previous element in list */
+ guint32 num; /* Frame number */
guint32 pkt_len; /* Packet length */
guint32 cap_len; /* Amount actually captured */
guint32 rel_secs; /* Relative seconds */
guint32 del_usecs; /* Delta microseconds */
long file_off; /* File offset */
column_info *cinfo; /* Column formatting information */
+ gint row; /* Row number for this packet in the display */
int lnk_t; /* Per-packet encapsulation/data-link type */
gboolean passed_dfilter; /* TRUE = display, FALSE = no display */
- guint8 flags; /* for ENCAP_LAPB : 1st bit means From DCE */
+ union pseudo_header pseudo_header; /* "pseudo-header" from wiretap */
} frame_data;
+/* Types of addresses Ethereal knows about. */
+typedef enum {
+ AT_NONE, /* no link-layer address */
+ AT_ETHER, /* MAC (Ethernet, 802.x, FDDI) address */
+ AT_IPv4, /* IPv4 */
+ AT_IPv6, /* IPv6 */
+ AT_IPX, /* IPX */
+ AT_SNA, /* SNA */
+ AT_ATALK, /* Appletalk DDP */
+ AT_VINES /* Banyan Vines */
+} address_type;
+
+typedef struct _address {
+ address_type type; /* type of address */
+ int len; /* length of address, in bytes */
+ const guint8 *data; /* bytes that constitute address */
+} address;
+
+#define SET_ADDRESS(addr, addr_type, addr_len, addr_data) { \
+ (addr)->type = (addr_type); \
+ (addr)->len = (addr_len); \
+ (addr)->data = (addr_data); \
+ }
+
+/* Types of port numbers Ethereal knows about. */
+typedef enum {
+ PT_NONE, /* no port number */
+ PT_TCP, /* TCP */
+ PT_UDP /* UDP */
+} port_type;
+
typedef struct _packet_info {
- guint32 ip_src;
- guint32 ip_dst;
+ int len;
+ int captured_len;
+ address dl_src; /* link-layer source address */
+ address dl_dst; /* link-layer destination address */
+ address net_src; /* network-layer source address */
+ address net_dst; /* network-layer destination address */
+ address src; /* source address (net if present, DL otherwise )*/
+ address dst; /* destination address (net if present, DL otherwise )*/
guint32 ipproto;
- guint32 srcport;
- guint32 destport;
+ port_type ptype; /* type of the following two port numbers */
+ guint32 srcport; /* source port */
+ guint32 destport; /* destination port */
guint32 match_port;
- int iplen;
- int iphdrlen;
- int payload;
+ int iplen;
+ int iphdrlen;
} packet_info;
+extern packet_info pi;
+
/* Struct for the match_strval function */
typedef struct _value_string {
gchar *strptr;
} value_string;
+/* Struct for boolean enumerations */
+typedef struct true_false_string {
+ char *true_string;
+ char *false_string;
+} true_false_string;
+
+
/* Many of the structs and definitions below and in packet-*.c files
* were taken from include files in the Linux distribution. */
ETT_TR_MAC,
ETT_PPP,
ETT_ARP,
+ ETT_BPDU,
ETT_FDDI,
ETT_NULL,
ETT_IP,
ETT_DNS_QD,
ETT_DNS_ANS,
ETT_DNS_RR,
+ ETT_EIGRP,
+ ETT_ICQ,
+ ETT_ICQ_DECODE,
+ ETT_ICQ_HEADER,
+ ETT_ICQ_BODY,
+ ETT_ICQ_BODY_PARTS,
ETT_ISAKMP,
ETT_ISAKMP_FLAGS,
ETT_ISAKMP_PAYLOAD,
ETT_RIP,
ETT_RIP_VEC,
+ ETT_RIPNG,
+ ETT_RIPNG_ADDR,
+ ETT_PIM,
ETT_OSPF,
ETT_OSPF_HDR,
ETT_OSPF_HELLO,
ETT_CLIP,
ETT_BOOTP,
ETT_BOOTP_OPTION,
+ ETT_BOOTPARAMS,
ETT_IPv6,
+ ETT_BGP,
+ ETT_BGP_OPEN,
+ ETT_BGP_UPDATE,
+ ETT_BGP_NOTIFICATION,
+ ETT_BGP_ATTRS,
+ ETT_BGP_ATTR,
+ ETT_BGP_ATTR_FLAGS,
+ ETT_BGP_UNFEAS,
+ ETT_BGP_NLRI,
+ ETT_BGP_MP_REACH_NLRI,
+ ETT_BGP_MP_UNREACH_NLRI,
ETT_CLNP,
ETT_COTP,
ETT_VINES_FRP,
ETT_VINES_IPC,
ETT_VINES_RTP,
ETT_VINES_SPP,
+ ETT_VLAN,
ETT_IPXRIP,
ETT_IPXSAP,
ETT_IPXSAP_SERVER,
ETT_NBNS_NAME_FLAGS,
ETT_NBNS_QRY,
ETT_NBNS_QD,
+ ETT_NETB,
+ ETT_NETB_FLAGS,
+ ETT_NETB_STATUS,
+ ETT_NETB_NAME,
ETT_NBNS_ANS,
ETT_NBNS_RR,
ETT_NBIPX,
+ ETT_NBIPX_NAME_TYPE_FLAGS,
ETT_AARP,
ETT_GIOP,
ETT_NBDGM,
ETT_CDP,
+ ETT_CDP_TLV,
ETT_HTTP,
ETT_TFTP,
ETT_AH,
ETT_ESP,
+ ETT_IPCOMP,
ETT_ICMPv6,
ETT_ICMPv6OPT,
ETT_ICMPv6FLAG,
ETT_POP,
+ ETT_IMAP,
ETT_FTP,
ETT_TELNET,
ETT_TELNET_SUBOPT,
ETT_NNTP,
+ ETT_NTP,
+ ETT_NTP_FLAGS,
ETT_SNMP,
ETT_NBSS,
ETT_NBSS_FLAGS,
+ ETT_RX,
+ ETT_RX_FLAGS,
+ ETT_AFS,
+ ETT_AFS_OP,
+ ETT_AFS_FID,
+ ETT_AFS_ACL,
+ ETT_AFS_CALLBACK,
+ ETT_AFS_UBIKVER,
ETT_SMB,
ETT_SMB_FLAGS,
ETT_SMB_FLAGS2,
ETT_SMB_FILEATTRIBUTES,
ETT_SMB_FILETYPE,
ETT_SMB_ACTION,
+ ETT_SMB_WRITEMODE,
+ ETT_SMB_LOCK_TYPE,
ETT_PPTP,
ETT_GRE,
ETT_GRE_FLAGS,
+ ETT_ICP,
+ ETT_ICP_PAYLOAD,
ETT_PPPOED,
ETT_PPPOED_TAGS,
ETT_PPPOES,
ETT_LCP,
+ ETT_LCP_OPTIONS,
+ ETT_LCP_MRU_OPT,
+ ETT_LCP_ASYNC_MAP_OPT,
+ ETT_LCP_AUTHPROT_OPT,
+ ETT_LCP_QUALPROT_OPT,
+ ETT_LCP_MAGICNUM_OPT,
+ ETT_LCP_FCS_ALTERNATIVES_OPT,
+ ETT_LCP_NUMBERED_MODE_OPT,
+ ETT_LCP_CALLBACK_OPT,
+ ETT_LCP_MULTILINK_EP_DISC_OPT,
+ ETT_LCP_INTERNATIONALIZATION_OPT,
ETT_IPCP,
+ ETT_IPCP_OPTIONS,
+ ETT_IPCP_IPADDRS_OPT,
+ ETT_IPCP_COMPRESSPROT_OPT,
ETT_RSVP,
ETT_RSVP_UNKNOWN_CLASS,
ETT_RSVP_HDR,
ETT_RADIUS,
ETT_RADIUS_AVP,
ETT_LAPB,
+ ETT_LAPD,
+ ETT_LAPD_ADDRESS,
ETT_X25,
+ ETT_XDLC_CONTROL,
+ ETT_Q931,
+ ETT_ATM,
+ ETT_ATM_LANE,
+ ETT_ATM_LANE_LC_FLAGS,
+ ETT_ATM_LANE_LC_LAN_DEST,
+ ETT_ATM_LANE_LC_LAN_DEST_RD,
+ ETT_MP,
+ ETT_MP_FLAGS,
+ ETT_IPP,
+ ETT_IPP_AS,
+ ETT_IPP_ATTR,
+ ETT_SNA,
+ ETT_SNA_TH,
+ ETT_SNA_TH_FID,
+ ETT_SNA_RH,
+ ETT_SNA_RH_0,
+ ETT_SNA_RH_1,
+ ETT_SNA_RH_2,
+ ETT_SNA_RU,
+ ETT_YHOO,
+ ETT_RPC,
+ ETT_RPC_STRING,
+ ETT_RPC_CRED,
+ ETT_RPC_VERF,
+ ETT_RPC_GIDS,
+ ETT_MOUNT,
+ ETT_NFS,
+ ETT_NFS_FHANDLE,
+ ETT_NFS_TIMEVAL,
+ ETT_NFS_MODE,
+ ETT_NFS_FATTR,
+ ETT_NFS_MODE3,
+ ETT_NFS_SPECDATA3,
+ ETT_NFS_FH3,
+ ETT_NFS_NFSTIME3,
+ ETT_NFS_FATTR3,
+ ETT_NLM,
+ ETT_PORTMAP,
+ ETT_STAT,
+ ETT_YPBIND,
+ ETT_YPSERV,
+ ETT_YPXFR,
+ ETT_DDP,
NUM_TREE_TYPES /* last item number plus one */
};
-/* The version of pcap.h that comes with some systems is missing these
- * #defines.
- */
-
-#ifndef DLT_RAW
-#define DLT_RAW 12
-#endif
-
-#ifndef DLT_SLIP_BSDOS
-#define DLT_SLIP_BSDOS 13
-#endif
-
-#ifndef DLT_PPP_BSDOS
-#define DLT_PPP_BSDOS 14
-#endif
-
+/* TRUE if subtrees of an item of the specified type are to be expanded. */
+extern gboolean tree_is_expanded[NUM_TREE_TYPES];
/* Utility routines used by packet*.c */
gchar* ether_to_str(const guint8 *);
gchar* ip_to_str(const guint8 *);
+struct e_in6_addr;
+gchar* ip6_to_str(struct e_in6_addr *);
+gchar* ipx_addr_to_str(guint32, const guint8 *);
gchar* abs_time_to_str(struct timeval*);
+gchar* rel_time_to_str(struct timeval*);
gchar* time_secs_to_str(guint32);
gchar* bytes_to_str(const guint8 *, int);
const u_char *find_line_end(const u_char *data, const u_char *dataend,
gchar* format_text(const u_char *line, int len);
gchar* val_to_str(guint32, const value_string *, const char *);
gchar* match_strval(guint32, const value_string*);
+char * decode_bitfield_value(char *buf, guint32 val, guint32 mask, int width);
const char *decode_boolean_bitfield(guint32 val, guint32 mask, int width,
const char *truedesc, const char *falsedesc);
const char *decode_enumerated_bitfield(guint32 val, guint32 mask, int width,
const char *decode_numeric_bitfield(guint32 val, guint32 mask, int width,
const char *fmt);
gint check_col(frame_data *, gint);
-void col_add_cls_time(frame_data *);
#if __GNUC__ == 2
void col_add_fstr(frame_data *, gint, gchar *, ...)
__attribute__((format (printf, 3, 4)));
void col_add_str(frame_data *, gint, const gchar *);
void col_append_str(frame_data *, gint, gchar *);
+void blank_packetinfo(void);
+
+void afs_init_protocol(void);
+void rpc_init_protocol(void);
+void smb_init_protocol(void);
void dissect_packet(const u_char *, frame_data *, proto_tree *);
+
/*
* Routines in packet-*.c
* Routines should take three args: packet data *, cap_len, packet_counts *
* packet_counts *
* They should never modify the packet data.
*/
+void capture_netbios(const u_char *, int, guint32, packet_counts *);
void capture_llc(const u_char *, int, guint32, packet_counts *);
void capture_ip(const u_char *, int, guint32, packet_counts *);
* Routines should take three args: packet data *, frame_data *, tree *
* They should never modify the packet data.
*/
+void dissect_ascend(const u_char *, frame_data *, proto_tree *);
+void dissect_atm(const u_char *, frame_data *, proto_tree *);
void dissect_clip(const u_char *, frame_data *, proto_tree *);
-void dissect_eth(const u_char *, frame_data *, proto_tree *);
-void dissect_fddi(const u_char *, frame_data *, proto_tree *);
void dissect_lapb(const u_char *, frame_data *, proto_tree *);
+void dissect_lapd(const u_char *, frame_data *, proto_tree *);
void dissect_null(const u_char *, frame_data *, proto_tree *);
void dissect_ppp(const u_char *, frame_data *, proto_tree *);
void dissect_raw(const u_char *, frame_data *, proto_tree *);
-void dissect_tr(const u_char *, frame_data *, proto_tree *);
+
+/*
+ * Routines in packet-*.c
+ * Routines should take four args: packet data *, frame_data *, tree *,
+ * gboolean
+ * They should never modify the packet data.
+ */
+void dissect_fddi(const u_char *, frame_data *, proto_tree *, gboolean);
+
+typedef void (*DissectFunc) (const u_char*, int, frame_data*, proto_tree*);
/*
* Routines in packet-*.c
*/
int dissect_ah(const u_char *, int, frame_data *, proto_tree *);
void dissect_aarp(const u_char *, int, frame_data *, proto_tree *);
+void dissect_afs(const u_char *, int, frame_data *, proto_tree *);
void dissect_arp(const u_char *, int, frame_data *, proto_tree *);
+void dissect_bgp(const u_char *, int, frame_data *, proto_tree *);
void dissect_bootp(const u_char *, int, frame_data *, proto_tree *);
+void dissect_bpdu(const u_char *, int, frame_data *, proto_tree *);
void dissect_cdp(const u_char *, int, frame_data *, proto_tree *);
void dissect_cotp(const u_char *, int, frame_data *, proto_tree *);
void dissect_data(const u_char *, int, frame_data *, proto_tree *);
void dissect_ddp(const u_char *, int, frame_data *, proto_tree *);
void dissect_dns(const u_char *, int, frame_data *, proto_tree *);
+void dissect_eigrp(const u_char *, int, frame_data *, proto_tree *);
void dissect_esp(const u_char *, int, frame_data *, proto_tree *);
+void dissect_eth(const u_char *, int, frame_data *, proto_tree *);
+void dissect_ftp(const u_char *, int, frame_data *, proto_tree *);
+void dissect_ftpdata(const u_char *, int, frame_data *, proto_tree *);
void dissect_giop(const u_char *, int, frame_data *, proto_tree *);
void dissect_http(const u_char *, int, frame_data *, proto_tree *);
void dissect_icmp(const u_char *, int, frame_data *, proto_tree *);
void dissect_icmpv6(const u_char *, int, frame_data *, proto_tree *);
void dissect_igmp(const u_char *, int, frame_data *, proto_tree *);
void dissect_ip(const u_char *, int, frame_data *, proto_tree *);
+void dissect_ipcomp(const u_char *, int, frame_data *, proto_tree *);
+void dissect_ipp(const u_char *, int, frame_data *, proto_tree *);
void dissect_ipv6(const u_char *, int, frame_data *, proto_tree *);
void dissect_ipx(const u_char *, int, frame_data *, proto_tree *);
void dissect_llc(const u_char *, int, frame_data *, proto_tree *);
void dissect_lpd(const u_char *, int, frame_data *, proto_tree *);
-void dissect_nbdgm(const u_char *, int, frame_data *, proto_tree *, int);
-void dissect_nbipx_ns(const u_char *, int, frame_data *, proto_tree *, int);
+void dissect_nbdgm(const u_char *, int, frame_data *, proto_tree *);
+void dissect_netbios(const u_char *, int, frame_data *, proto_tree *);
+void dissect_nbipx(const u_char *, int, frame_data *, proto_tree *);
void dissect_nbns(const u_char *, int, frame_data *, proto_tree *);
-void dissect_ncp(const u_char *, int, frame_data *, proto_tree *, int);
-void dissect_nwlink_dg(const u_char *, int, frame_data *, proto_tree *, int);
+void dissect_nbss(const u_char *, int, frame_data *, proto_tree *);
+void dissect_ncp(const u_char *, int, frame_data *, proto_tree *);
+void dissect_nntp(const u_char *, int, frame_data *, proto_tree *);
+void dissect_ntp(const u_char *, int, frame_data *, proto_tree *);
+void dissect_nwlink_dg(const u_char *, int, frame_data *, proto_tree *);
void dissect_osi(const u_char *, int, frame_data *, proto_tree *);
void dissect_ospf(const u_char *, int, frame_data *, proto_tree *);
void dissect_ospf_hello(const u_char *, int, frame_data *, proto_tree *);
+void dissect_pim(const u_char *, int, frame_data *, proto_tree *);
+void dissect_pop(const u_char *, int, frame_data *, proto_tree *);
void dissect_pppoed(const u_char *, int, frame_data *, proto_tree *);
void dissect_pppoes(const u_char *, int, frame_data *, proto_tree *);
+void dissect_icp(const u_char *,int, frame_data *, proto_tree *);
+void dissect_icq(const u_char *,int, frame_data *, proto_tree *);
+void dissect_imap(const u_char *,int, frame_data *, proto_tree *);
void dissect_isakmp(const u_char *, int, frame_data *, proto_tree *);
+void dissect_pim(const u_char *, int, frame_data *, proto_tree *);
+void dissect_q931(const u_char *, int, frame_data *, proto_tree *);
void dissect_radius(const u_char *, int, frame_data *, proto_tree *);
void dissect_rip(const u_char *, int, frame_data *, proto_tree *);
+void dissect_ripng(const u_char *, int, frame_data *, proto_tree *);
void dissect_rsvp(const u_char *, int, frame_data *, proto_tree *);
void dissect_rtsp(const u_char *, int, frame_data *, proto_tree *);
+void dissect_rx(const u_char *, int, frame_data *, proto_tree *);
void dissect_sdp(const u_char *, int, frame_data *, proto_tree *);
+void dissect_sna(const u_char *, int, frame_data *, proto_tree *);
void dissect_snmp(const u_char *, int, frame_data *, proto_tree *);
void dissect_tcp(const u_char *, int, frame_data *, proto_tree *);
+void dissect_telnet(const u_char *, int, frame_data *, proto_tree *);
void dissect_tftp(const u_char *, int, frame_data *, proto_tree *);
+void dissect_tr(const u_char *, int, frame_data *, proto_tree *);
void dissect_trmac(const u_char *, int, frame_data *, proto_tree *);
void dissect_udp(const u_char *, int, frame_data *, proto_tree *);
void dissect_vines(const u_char *, int, frame_data *, proto_tree *);
void dissect_vines_ipc(const u_char *, int, frame_data *, proto_tree *);
void dissect_vines_rtp(const u_char *, int, frame_data *, proto_tree *);
void dissect_vines_spp(const u_char *, int, frame_data *, proto_tree *);
+void dissect_vlan(const u_char *, int, frame_data *, proto_tree *);
void dissect_payload_ppp(const u_char *, int, frame_data *, proto_tree *);
void dissect_x25(const u_char *, int, frame_data *, proto_tree *);
+void dissect_yhoo(const u_char *, int, frame_data *, proto_tree *);
-void dissect_ftp(const u_char *, int, frame_data *, proto_tree *, int);
-void dissect_ftpdata(const u_char *, int, frame_data *, proto_tree *, int);
-void dissect_nbss(const u_char *, int, frame_data *, proto_tree *, int);
-void dissect_nntp(const u_char *, int, frame_data *, proto_tree *, int);
-void dissect_pop(const u_char *, int, frame_data *, proto_tree *, int);
void dissect_smb(const u_char *, int, frame_data *, proto_tree *, int);
-void dissect_telnet(const u_char *, int, frame_data *, proto_tree *, int);
void dissect_pptp(const u_char *, int, frame_data *, proto_tree *);
void dissect_gre(const u_char *, int, frame_data *, proto_tree *);
+void dissect_rpc(const u_char *, int, frame_data *, proto_tree *, guint32, void*);
+
+void init_dissect_rpc(void);
void init_dissect_udp(void);
void init_dissect_x25(void);
gchar *arphrdaddr_to_str(guint8 *ad, int ad_len, guint16 type);
gchar *arphrdtype_to_str(guint16 hwtype, const char *fmt);
+/* ipproto.c */
+extern const char *ipprotostr(int proto);
+
/*
* All of the possible columns in summary listing.
*