2000-02-15 21:06:58 +00:00
|
|
|
/* packet-tcp.h
|
|
|
|
*
|
2004-07-18 00:24:25 +00:00
|
|
|
* $Id$
|
2000-02-15 21:06:58 +00:00
|
|
|
*
|
2006-05-21 04:49:01 +00:00
|
|
|
* Wireshark - Network traffic analyzer
|
|
|
|
* By Gerald Combs <gerald@wireshark.org>
|
2000-02-15 21:06:58 +00:00
|
|
|
* Copyright 1998 Gerald Combs
|
2002-08-28 21:04:11 +00:00
|
|
|
*
|
2000-02-15 21:06:58 +00:00
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
2002-08-28 21:04:11 +00:00
|
|
|
*
|
2000-02-15 21:06:58 +00:00
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
2002-08-28 21:04:11 +00:00
|
|
|
*
|
2000-02-15 21:06:58 +00:00
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
2000-08-11 13:37:21 +00:00
|
|
|
#ifndef __PACKET_TCP_H__
|
|
|
|
#define __PACKET_TCP_H__
|
|
|
|
|
2002-12-17 11:49:32 +00:00
|
|
|
/* TCP flags */
|
|
|
|
#define TH_FIN 0x01
|
|
|
|
#define TH_SYN 0x02
|
|
|
|
#define TH_RST 0x04
|
|
|
|
#define TH_PUSH 0x08
|
|
|
|
#define TH_ACK 0x10
|
|
|
|
#define TH_URG 0x20
|
|
|
|
#define TH_ECN 0x40
|
|
|
|
#define TH_CWR 0x80
|
|
|
|
|
|
|
|
|
|
|
|
/* the tcp header structure, passed to tap listeners */
|
|
|
|
struct tcpheader {
|
|
|
|
guint32 th_seq;
|
|
|
|
guint32 th_ack;
|
2003-05-21 06:28:03 +00:00
|
|
|
gboolean th_have_seglen; /* TRUE if th_seglen is valid */
|
2002-12-17 11:49:32 +00:00
|
|
|
guint32 th_seglen;
|
2003-09-12 05:52:38 +00:00
|
|
|
guint32 th_win; /* make it 32 bits so we can handle some scaling */
|
2002-12-17 11:49:32 +00:00
|
|
|
guint16 th_sport;
|
|
|
|
guint16 th_dport;
|
|
|
|
guint8 th_hlen;
|
|
|
|
guint8 th_flags;
|
2003-08-23 09:09:35 +00:00
|
|
|
address ip_src;
|
|
|
|
address ip_dst;
|
2002-12-17 11:49:32 +00:00
|
|
|
};
|
|
|
|
|
2001-09-30 23:14:43 +00:00
|
|
|
/*
|
2005-03-12 09:59:28 +00:00
|
|
|
* Private data passed from the TCP dissector to subdissectors. Passed to the
|
|
|
|
* subdissectors in pinfo->private_data
|
2001-09-30 23:14:43 +00:00
|
|
|
*/
|
|
|
|
struct tcpinfo {
|
Add support for reassembling RPC-over-TCP fragments, and do that in both
RPC and NDMP.
Show the RPC-over-TCP fragment header as a tree with bitfields below it.
Add a routine to show a reported bounds error as an "Unreassembled
Packet" or a "Malformed Packet" depending on whether "pinfo->fragmented"
is set, and have NBNS and RPC use that.
Add "ett_ndmp_file_stats" to the list of ett_ values to be initialized
(it wasn't in that list, and wasn't getting initialized).
When freeing up various hash tables and memory chunks in the RPC
dissector, zero out the pointers to them, just to make sure we don't try
to free them again.
Always destroy the TCP segment key and address memory chunks in
"tcp_desegment_init()", regardless of whether TCP desegmentation is
enabled - we don't *allocate* them if TCP desegmentation isn't enabled,
but we should free them even if it's not enabled. Also, when we free
them, set the pointers to them to null, so we don't double-free them.
Supply to subdissectors called from the TCP dissector the sequence
number of the first byte handed to the sub dissector.
svn path=/trunk/; revision=4753
2002-02-18 23:51:55 +00:00
|
|
|
guint32 seq; /* Sequence number of first byte in the data */
|
2003-12-30 00:03:48 +00:00
|
|
|
guint32 nxtseq; /* Sequence number of first byte after data */
|
2001-09-30 23:14:43 +00:00
|
|
|
gboolean is_reassembled; /* This is reassembled data. */
|
Add support for reassembling RPC-over-TCP fragments, and do that in both
RPC and NDMP.
Show the RPC-over-TCP fragment header as a tree with bitfields below it.
Add a routine to show a reported bounds error as an "Unreassembled
Packet" or a "Malformed Packet" depending on whether "pinfo->fragmented"
is set, and have NBNS and RPC use that.
Add "ett_ndmp_file_stats" to the list of ett_ values to be initialized
(it wasn't in that list, and wasn't getting initialized).
When freeing up various hash tables and memory chunks in the RPC
dissector, zero out the pointers to them, just to make sure we don't try
to free them again.
Always destroy the TCP segment key and address memory chunks in
"tcp_desegment_init()", regardless of whether TCP desegmentation is
enabled - we don't *allocate* them if TCP desegmentation isn't enabled,
but we should free them even if it's not enabled. Also, when we free
them, set the pointers to them to null, so we don't double-free them.
Supply to subdissectors called from the TCP dissector the sequence
number of the first byte handed to the sub dissector.
svn path=/trunk/; revision=4753
2002-02-18 23:51:55 +00:00
|
|
|
gboolean urgent; /* TRUE if "urgent_pointer" is valid */
|
2001-09-30 23:14:43 +00:00
|
|
|
guint16 urgent_pointer; /* Urgent pointer value for the current packet. */
|
|
|
|
};
|
|
|
|
|
Make a "tcp_dissect_pdus()" with the standard loop for a TCP segment,
extracting PDUs from it and possibly doing reassembly. Make the COPS,
DNS, DSI, Gryphon, and SCCP dissectors use it.
Add "set_actual_length()", "tcp_dissect_pdus()",
"decode_boolean_bitfield()", "decode_numeric_bitfield()", and
"decode_enumerated_bitfield()" to the list of routines available to
dissectors on platforms where routines in the main program aren't
available to dynamically-loaded code.
Declare routines in "to_str.h" as "extern"; as I remember, that's
necessary to allow the "decode_XXX_bitfield()" routines declared therein
to be made available to plugins as per the above.
Note that new exported routines should be added to the end of the table
if that's the only change being made to the table.
Create a new "plugin_api_decls.h" header file, used to declare both the
"p_" variables and the "p_" structure members in the routine-exporting
mechanism; this reduces the number of places you have to change to
change the list of exported routines.
svn path=/trunk/; revision=5394
2002-05-05 00:16:38 +00:00
|
|
|
/*
|
|
|
|
* Loop for dissecting PDUs within a TCP stream; assumes that a PDU
|
|
|
|
* consists of a fixed-length chunk of data that contains enough information
|
|
|
|
* to determine the length of the PDU, followed by rest of the PDU.
|
|
|
|
*
|
|
|
|
* The first three arguments are the arguments passed to the dissector
|
|
|
|
* that calls this routine.
|
|
|
|
*
|
|
|
|
* "proto_desegment" is the dissector's flag controlling whether it should
|
|
|
|
* desegment PDUs that cross TCP segment boundaries.
|
|
|
|
*
|
|
|
|
* "fixed_len" is the length of the fixed-length part of the PDU.
|
|
|
|
*
|
|
|
|
* "get_pdu_len()" is a routine called to get the length of the PDU from
|
2006-11-21 14:18:46 +00:00
|
|
|
* the fixed-length part of the PDU; it's passed "pinfo", "tvb" and "offset".
|
Make a "tcp_dissect_pdus()" with the standard loop for a TCP segment,
extracting PDUs from it and possibly doing reassembly. Make the COPS,
DNS, DSI, Gryphon, and SCCP dissectors use it.
Add "set_actual_length()", "tcp_dissect_pdus()",
"decode_boolean_bitfield()", "decode_numeric_bitfield()", and
"decode_enumerated_bitfield()" to the list of routines available to
dissectors on platforms where routines in the main program aren't
available to dynamically-loaded code.
Declare routines in "to_str.h" as "extern"; as I remember, that's
necessary to allow the "decode_XXX_bitfield()" routines declared therein
to be made available to plugins as per the above.
Note that new exported routines should be added to the end of the table
if that's the only change being made to the table.
Create a new "plugin_api_decls.h" header file, used to declare both the
"p_" variables and the "p_" structure members in the routine-exporting
mechanism; this reduces the number of places you have to change to
change the list of exported routines.
svn path=/trunk/; revision=5394
2002-05-05 00:16:38 +00:00
|
|
|
*
|
|
|
|
* "dissect_pdu()" is the routine to dissect a PDU.
|
|
|
|
*/
|
|
|
|
extern void
|
|
|
|
tcp_dissect_pdus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
2002-05-05 00:57:59 +00:00
|
|
|
gboolean proto_desegment, guint fixed_len,
|
2006-10-31 09:29:07 +00:00
|
|
|
guint (*get_pdu_len)(packet_info *, tvbuff_t *, int),
|
2005-06-03 06:31:58 +00:00
|
|
|
dissector_t dissect_pdu);
|
2000-02-15 21:06:58 +00:00
|
|
|
|
2006-01-26 22:50:16 +00:00
|
|
|
|
|
|
|
typedef struct _tcp_unacked_t {
|
|
|
|
struct _tcp_unacked_t *next;
|
|
|
|
guint32 frame;
|
|
|
|
guint32 seq;
|
|
|
|
guint32 nextseq;
|
|
|
|
nstime_t ts;
|
|
|
|
} tcp_unacked_t;
|
|
|
|
|
|
|
|
struct tcp_acked {
|
|
|
|
guint32 frame_acked;
|
|
|
|
nstime_t ts;
|
|
|
|
|
|
|
|
guint32 rto_frame;
|
|
|
|
nstime_t rto_ts; /* Time since previous packet for
|
|
|
|
retransmissions. */
|
|
|
|
guint16 flags;
|
|
|
|
guint32 dupack_num; /* dup ack number */
|
|
|
|
guint32 dupack_frame; /* dup ack to frame # */
|
|
|
|
};
|
|
|
|
|
2006-04-28 09:44:02 +00:00
|
|
|
/* One instance of this structure is created for each pdu that spans across
|
|
|
|
* multiple tcp segments.
|
|
|
|
*/
|
|
|
|
struct tcp_multisegment_pdu {
|
2006-01-26 22:50:16 +00:00
|
|
|
guint32 seq;
|
|
|
|
guint32 nxtpdu;
|
|
|
|
guint32 first_frame;
|
|
|
|
guint32 last_frame;
|
|
|
|
nstime_t last_frame_time;
|
2006-11-07 13:19:31 +00:00
|
|
|
guint32 flags;
|
|
|
|
#define MSP_FLAGS_REASSEMBLE_ENTIRE_SEGMENT 0x00000001
|
2006-01-26 22:50:16 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct _tcp_flow_t {
|
|
|
|
guint32 base_seq; /* base seq number (used by relative sequence numbers)
|
|
|
|
* or 0 if not yet known.
|
|
|
|
*/
|
|
|
|
tcp_unacked_t *segments;
|
|
|
|
guint32 lastack; /* last seen ack */
|
|
|
|
nstime_t lastacktime; /* Time of the last ack packet */
|
|
|
|
guint32 lastnondupack; /* frame number of last seen non dupack */
|
|
|
|
guint32 dupacknum; /* dupack number */
|
|
|
|
guint32 nextseq; /* highest seen nextseq */
|
|
|
|
guint32 nextseqframe; /* frame number for segment with highest
|
|
|
|
* sequence number
|
|
|
|
*/
|
|
|
|
nstime_t nextseqtime; /* Time of the nextseq packet so we can
|
|
|
|
* distinguish between retransmission,
|
|
|
|
* fast retransmissions and outoforder
|
|
|
|
*/
|
|
|
|
guint32 window; /* last seen window */
|
|
|
|
gint16 win_scale; /* -1 is we dont know */
|
2006-09-10 14:03:08 +00:00
|
|
|
/* This tcp flow/session contains only one single PDU and should
|
|
|
|
* be reassembled until the final FIN segment.
|
|
|
|
*/
|
|
|
|
#define TCP_FLOW_REASSEMBLE_UNTIL_FIN 0x0001
|
|
|
|
guint16 flags;
|
2006-01-26 22:50:16 +00:00
|
|
|
guint32 lastsegmentflags;
|
|
|
|
|
2006-04-28 09:44:02 +00:00
|
|
|
/* This tree is indexed by sequence number and keeps track of all
|
|
|
|
* all pdus spanning multiple segments for this flow.
|
|
|
|
*/
|
2006-08-14 08:29:29 +00:00
|
|
|
emem_tree_t *multisegment_pdus;
|
2006-01-26 22:50:16 +00:00
|
|
|
} tcp_flow_t;
|
|
|
|
|
|
|
|
|
|
|
|
struct tcp_analysis {
|
|
|
|
/* These two structs are managed based on comparing the source
|
|
|
|
* and destination addresses and, if they're equal, comparing
|
|
|
|
* the source and destination ports.
|
|
|
|
*
|
|
|
|
* If the source is greater than the destination, then stuff
|
|
|
|
* sent from src is in ual1.
|
|
|
|
*
|
|
|
|
* If the source is less than the destination, then stuff
|
|
|
|
* sent from src is in ual2.
|
|
|
|
*
|
|
|
|
* XXX - if the addresses and ports are equal, we don't guarantee
|
|
|
|
* the behavior.
|
|
|
|
*/
|
|
|
|
tcp_flow_t flow1;
|
|
|
|
tcp_flow_t flow2;
|
|
|
|
|
|
|
|
/* These pointers are set by get_tcp_conversation_data()
|
|
|
|
* fwd point in the same direction as the current packet
|
|
|
|
* and rev in the reverse direction
|
|
|
|
*/
|
|
|
|
tcp_flow_t *fwd;
|
|
|
|
tcp_flow_t *rev;
|
2006-03-02 09:33:49 +00:00
|
|
|
|
|
|
|
/* This pointer is NULL or points to a tcp_acked struct if this
|
|
|
|
* packet has "interesting" properties such as being a KeepAlive or
|
|
|
|
* similar
|
|
|
|
*/
|
|
|
|
struct tcp_acked *ta;
|
2006-03-20 10:52:53 +00:00
|
|
|
/* This structure contains a tree containing all the various ta's
|
|
|
|
* keyed by frame number.
|
|
|
|
*/
|
2006-08-14 08:29:29 +00:00
|
|
|
emem_tree_t *acked_table;
|
2006-01-26 22:50:16 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2003-12-30 00:03:48 +00:00
|
|
|
extern void dissect_tcp_payload(tvbuff_t *tvb, packet_info *pinfo, int offset,
|
|
|
|
guint32 seq, guint32 nxtseq, guint32 sport,
|
|
|
|
guint32 dport, proto_tree *tree,
|
2006-01-26 22:50:16 +00:00
|
|
|
proto_tree *tcp_tree,
|
|
|
|
struct tcp_analysis *tcpd);
|
|
|
|
|
|
|
|
extern struct tcp_analysis *get_tcp_conversation_data(packet_info *pinfo);
|
2003-12-30 00:03:48 +00:00
|
|
|
|
2006-03-02 09:33:49 +00:00
|
|
|
extern gboolean decode_tcp_ports(tvbuff_t *, int, packet_info *, proto_tree *, int, int, struct tcp_analysis *);
|
|
|
|
|
|
|
|
|
2000-08-11 13:37:21 +00:00
|
|
|
#endif
|