/* packet-clnp.c
* Routines for ISO/OSI network and transport protocol packet disassembly
*
- * $Id: packet-clnp.c,v 1.41 2001/12/03 03:59:33 guy Exp $
+ * $Id: packet-clnp.c,v 1.53 2002/04/07 21:54:48 guy Exp $
* Laurent Deniel <deniel@worldnet.fr>
* Ralf Schneider <Ralf.Schneider@t-online.de>
*
#include <ctype.h>
#include <glib.h>
#include "prefs.h"
-#include "packet.h"
+#include <epan/packet.h>
#include "reassemble.h"
#include "packet-osi.h"
#include "packet-osi-options.h"
break;
}
- if (check_col(pinfo->fd, COL_INFO))
- col_append_fstr(pinfo->fd, COL_INFO,
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO,
"DR TPDU src-ref: 0x%04x dst-ref: 0x%04x",
src_ref, dst_ref);
break;
}
- if (check_col(pinfo->fd, COL_INFO))
- col_append_fstr(pinfo->fd, COL_INFO, "DT TPDU (%u) dst-ref: 0x%04x %s",
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO, "DT TPDU (%u) dst-ref: 0x%04x %s",
tpdu_nr,
dst_ref,
(fragment)? "(fragment)" : "");
break;
} /* li */
- if (check_col(pinfo->fd, COL_INFO))
- col_append_fstr(pinfo->fd, COL_INFO, "ED TPDU (%u) dst-ref: 0x%04x",
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO, "ED TPDU (%u) dst-ref: 0x%04x",
tpdu_nr, dst_ref);
if (tree) {
break;
}
- if (check_col(pinfo->fd, COL_INFO))
- col_append_fstr(pinfo->fd, COL_INFO, "RJ TPDU (%u) dst-ref: 0x%04x",
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO, "RJ TPDU (%u) dst-ref: 0x%04x",
tpdu_nr, dst_ref);
if (tree) {
if (class_option > 4)
return -1;
- if (check_col(pinfo->fd, COL_INFO))
- col_append_fstr(pinfo->fd, COL_INFO,
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO,
"%s TPDU src-ref: 0x%04x dst-ref: 0x%04x",
(tpdu == CR_TPDU) ? "CR" : "CC",
src_ref,
src_ref = tvb_get_ntohs(tvb, offset + P_SRC_REF);
- if (check_col(pinfo->fd, COL_INFO))
- col_append_fstr(pinfo->fd, COL_INFO,
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO,
"DC TPDU src-ref: 0x%04x dst-ref: 0x%04x",
src_ref,
dst_ref);
tpdu_nr = tvb_get_guint8(tvb, offset + P_TPDU_NR_234);
- if (check_col(pinfo->fd, COL_INFO))
- col_append_fstr(pinfo->fd, COL_INFO, "AK TPDU (%u) dst-ref: 0x%04x",
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO, "AK TPDU (%u) dst-ref: 0x%04x",
tpdu_nr, dst_ref);
if (tree) {
tpdu_nr = tvb_get_ntohl(tvb, offset + P_TPDU_NR_234);
cdt_in_ak = tvb_get_ntohs(tvb, offset + P_CDT_IN_AK);
- if (check_col(pinfo->fd, COL_INFO))
- col_append_fstr(pinfo->fd, COL_INFO, "AK TPDU (%u) dst-ref: 0x%04x",
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO, "AK TPDU (%u) dst-ref: 0x%04x",
tpdu_nr, dst_ref);
if (tree) {
break;
} /* li */
- if (check_col(pinfo->fd, COL_INFO))
- col_append_fstr(pinfo->fd, COL_INFO,
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO,
"EA TPDU (%u) dst-ref: 0x%04x", tpdu_nr, dst_ref);
if (tree) {
break;
}
- if (check_col(pinfo->fd, COL_INFO))
- col_append_fstr(pinfo->fd, COL_INFO, "ER TPDU dst-ref: 0x%04x", dst_ref);
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO, "ER TPDU dst-ref: 0x%04x", dst_ref);
if (tree) {
ti = proto_tree_add_item(tree, proto_cotp, tvb, offset, li + 1, FALSE);
} /* osi_decode_ER */
static int osi_decode_UD(tvbuff_t *tvb, int offset,
- packet_info *pinfo, proto_tree *tree,
- gboolean *subdissector_found)
+ packet_info *pinfo, proto_tree *tree)
{
proto_item *ti;
proto_tree *cltp_tree = NULL;
tvbuff_t *next_tvb;
- if (check_col(pinfo->fd, COL_INFO))
- col_append_str(pinfo->fd, COL_INFO, "UD TPDU");
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_str(pinfo->cinfo, COL_INFO, "UD TPDU");
if (tree) {
ti = proto_tree_add_item(tree, proto_cltp, tvb, offset, li + 1, FALSE);
/* Initialize the COL_INFO field; each of the TPDUs will have its
information appended. */
- if (check_col(pinfo->fd, COL_INFO))
- col_add_str(pinfo->fd, COL_INFO, "");
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_add_str(pinfo->cinfo, COL_INFO, "");
while (tvb_offset_exists(tvb, offset)) {
if (!first_tpdu) {
- if (check_col(pinfo->fd, COL_INFO))
- col_append_str(pinfo->fd, COL_INFO, ", ");
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_str(pinfo->cinfo, COL_INFO, ", ");
}
if ((li = tvb_get_guint8(tvb, offset + P_LI)) == 0) {
- if (check_col(pinfo->fd, COL_INFO))
- col_append_str(pinfo->fd, COL_INFO, "Length indicator is zero");
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_str(pinfo->cinfo, COL_INFO, "Length indicator is zero");
if (!first_tpdu)
call_dissector(data_handle,tvb_new_subset(tvb, offset,-1,tvb_reported_length_remaining(tvb,offset)), pinfo, tree);
return found_ositp;
new_offset = osi_decode_ER(tvb, offset, pinfo, tree);
break;
case UD_TPDU :
- new_offset = osi_decode_UD(tvb, offset, pinfo, tree,
- &subdissector_found);
+ new_offset = osi_decode_UD(tvb, offset, pinfo, tree);
is_cltp = TRUE;
break;
default :
- if (first_tpdu && check_col(pinfo->fd, COL_INFO))
- col_append_fstr(pinfo->fd, COL_INFO, "Unknown TPDU type (0x%x)", tpdu);
+ if (first_tpdu && check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO, "Unknown TPDU type (0x%x)", tpdu);
new_offset = -1; /* bad PDU type */
break;
}
if (first_tpdu) {
/* Well, we found at least one valid COTP or CLTP PDU, so I guess this
is either COTP or CLTP. */
- if (!subdissector_found && check_col(pinfo->fd, COL_PROTOCOL))
- col_set_str(pinfo->fd, COL_PROTOCOL, is_cltp ? "CLTP" : "COTP");
+ if (!subdissector_found && check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, is_cltp ? "CLTP" : "COTP");
found_ositp = TRUE;
}
gint len;
guint next_length;
proto_tree *discpdu_tree;
- address save_dl_src;
- address save_dl_dst;
- address save_net_src;
- address save_net_dst;
- address save_src;
- address save_dst;
+ volatile address save_dl_src;
+ volatile address save_dl_dst;
+ volatile address save_net_src;
+ volatile address save_net_dst;
+ volatile address save_src;
+ volatile address save_dst;
gboolean save_in_error_pkt;
fragment_data *fd_head;
tvbuff_t *volatile next_tvb;
- gboolean update_col_info = TRUE;
+ gboolean update_col_info = TRUE;
+ gboolean save_fragmented;
- if (check_col(pinfo->fd, COL_PROTOCOL))
- col_set_str(pinfo->fd, COL_PROTOCOL, "CLNP");
- if (check_col(pinfo->fd, COL_INFO))
- col_clear(pinfo->fd, COL_INFO);
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "CLNP");
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_clear(pinfo->cinfo, COL_INFO);
cnf_proto_id = tvb_get_guint8(tvb, P_CLNP_PROTO_ID);
if (cnf_proto_id == NLPID_NULL) {
- if (check_col(pinfo->fd, COL_INFO))
- col_set_str(pinfo->fd, COL_INFO, "Inactive subset");
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_set_str(pinfo->cinfo, COL_INFO, "Inactive subset");
if (tree) {
ti = proto_tree_add_item(tree, proto_clnp, tvb, P_CLNP_PROTO_ID, 1, FALSE);
clnp_tree = proto_item_add_subtree(ti, ett_clnp);
we set it otherwise. */
if (!tvb_bytes_exist(tvb, 0, cnf_hdr_len)) {
- if (check_col(pinfo->fd, COL_INFO))
- col_add_fstr(pinfo->fd, COL_INFO, "%s NPDU %s", pdu_type_string, flag_string);
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_add_fstr(pinfo->cinfo, COL_INFO, "%s NPDU %s", pdu_type_string, flag_string);
}
segment_length = tvb_get_ntohs(tvb, P_CLNP_SEGLEN);
dissect_osi_options( 0xff,
opt_len,
- tvb, offset, pinfo, clnp_tree );
+ tvb, offset, clnp_tree );
}
/* Length of CLNP datagram plus headers above it. */
offset = cnf_hdr_len;
- /* For now, dissect the payload of segments other than the initial
- segment as data, rather than handing them off to the transport
- protocol, just as we do with fragments other than the first
- fragment in a fragmented IP datagram; in the future, we will
- probably reassemble fragments for IP, and may reassemble segments
- for CLNP. */
- /* If clnp_reassemble is on and this is a segment, then just add the segment
- * to the hashtable.
+ /* If clnp_reassemble is on, and this is a segment, we have all the
+ * data in the segment, and the checksum is valid, then just add the
+ * segment to the hashtable.
*/
+ save_fragmented = pinfo->fragmented;
if (clnp_reassemble && (cnf_type & CNF_SEG_OK) &&
- ((cnf_type & CNF_MORE_SEGS) || segment_offset != 0)) {
- /* We're reassembling, and this is part of a segmented datagram.
- Add the segment to the hash table if the checksum is ok
- and the frame isn't truncated. */
- if (cksum_status != CKSUM_NOT_OK &&
- (tvb_reported_length(tvb) <= tvb_length(tvb))) {
- fd_head = fragment_add(tvb, offset, pinfo, du_id, clnp_segment_table,
- segment_offset, segment_length - cnf_hdr_len,
- cnf_type & CNF_MORE_SEGS);
- } else {
- fd_head=NULL;
- }
+ ((cnf_type & CNF_MORE_SEGS) || segment_offset != 0) &&
+ (tvb_reported_length(tvb) <= tvb_length(tvb)) &&
+ cksum_status != CKSUM_NOT_OK) {
+ fd_head = fragment_add(tvb, offset, pinfo, du_id, clnp_segment_table,
+ segment_offset, segment_length - cnf_hdr_len,
+ cnf_type & CNF_MORE_SEGS);
if (fd_head != NULL) {
fragment_data *fd;
proto_tree *ft=NULL;
proto_item *fi=NULL;
- /* OK, we have the complete reassembled payload. */
+ /* OK, we have the complete reassembled payload.
+ Allocate a new tvbuff, referring to the reassembled payload. */
+ next_tvb = tvb_new_real_data(fd_head->data, fd_head->datalen,
+ fd_head->datalen);
+
+ /* Add the tvbuff to the list of tvbuffs to which the tvbuff we
+ were handed refers, so it'll get cleaned up when that tvbuff
+ is cleaned up. */
+ tvb_set_child_real_data_tvbuff(tvb, next_tvb);
+
+ /* Add the defragmented data to the data source list. */
+ add_new_data_source(pinfo->fd, next_tvb, "Reassembled CLNP");
+
+ /* It's not fragmented. */
+ pinfo->fragmented = FALSE;
+
/* show all segments */
fi = proto_tree_add_item(clnp_tree, hf_clnp_segments,
- tvb, 0, 0, FALSE);
+ next_tvb, 0, -1, FALSE);
ft = proto_item_add_subtree(fi, ett_clnp_segments);
for (fd = fd_head->next; fd != NULL; fd = fd->next){
if (fd->flags & (FD_OVERLAP|FD_OVERLAPCONFLICT
hf = hf_clnp_segment;
}
fei = proto_tree_add_none_format(ft, hf,
- tvb, 0, 0,
- "Frame:%d payload:%d-%d",
+ next_tvb, fd->offset, fd->len,
+ "Frame:%u payload:%u-%u",
fd->frame,
fd->offset,
fd->offset+fd->len-1
fet = proto_item_add_subtree(fei, ett_clnp_segment);
if (fd->flags&FD_OVERLAP) {
proto_tree_add_boolean(fet,
- hf_clnp_segment_overlap, tvb, 0, 0,
+ hf_clnp_segment_overlap, next_tvb, 0, 0,
TRUE);
}
if (fd->flags&FD_OVERLAPCONFLICT) {
proto_tree_add_boolean(fet,
- hf_clnp_segment_overlap_conflict, tvb, 0, 0,
+ hf_clnp_segment_overlap_conflict, next_tvb, 0, 0,
TRUE);
}
if (fd->flags&FD_MULTIPLETAILS) {
proto_tree_add_boolean(fet,
- hf_clnp_segment_multiple_tails, tvb, 0, 0,
+ hf_clnp_segment_multiple_tails, next_tvb, 0, 0,
TRUE);
}
if (fd->flags&FD_TOOLONGFRAGMENT) {
proto_tree_add_boolean(fet,
- hf_clnp_segment_too_long_segment, tvb, 0, 0,
+ hf_clnp_segment_too_long_segment, next_tvb, 0, 0,
TRUE);
}
} else {
/* nothing of interest for this segment */
proto_tree_add_none_format(ft, hf_clnp_segment,
- tvb, 0, 0,
- "Frame:%d payload:%d-%d",
+ next_tvb, fd->offset, fd->len,
+ "Frame:%u payload:%u-%u",
fd->frame,
fd->offset,
fd->offset+fd->len-1
}
if (fd_head->flags & (FD_OVERLAPCONFLICT
|FD_MULTIPLETAILS|FD_TOOLONGFRAGMENT) ) {
- if (check_col(pinfo->fd, COL_INFO)) {
- col_set_str(pinfo->fd, COL_INFO, "[Illegal segments]");
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_set_str(pinfo->cinfo, COL_INFO, "[Illegal segments]");
update_col_info = FALSE;
}
}
-
- /* Allocate a new tvbuff, referring to the reassembled payload. */
- next_tvb = tvb_new_real_data(fd_head->data, fd_head->datalen,
- fd_head->datalen, "Reassembled");
-
- /* Add the tvbuff to the list of tvbuffs to which the tvbuff we
- were handed refers, so it'll get cleaned up when that tvbuff
- is cleaned up. */
- tvb_set_child_real_data_tvbuff(tvb, next_tvb);
-
- /* Add the defragmented data to the data source list. */
- pinfo->fd->data_src = g_slist_append(pinfo->fd->data_src, next_tvb);
-
- /* It's not fragmented. */
- pinfo->fragmented = FALSE;
} else {
/* We don't have the complete reassembled payload. */
next_tvb = NULL;
if (next_tvb == NULL) {
/* Just show this as a segment. */
- if (check_col(pinfo->fd, COL_INFO))
- col_add_fstr(pinfo->fd, COL_INFO, "Fragmented %s NPDU %s(off=%u)",
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_add_fstr(pinfo->cinfo, COL_INFO, "Fragmented %s NPDU %s(off=%u)",
pdu_type_string, flag_string, segment_offset);
/* As we haven't reassembled anything, we haven't changed "pi", so
we don't have to restore it. */
call_dissector(data_handle,tvb_new_subset(tvb, offset,-1,tvb_reported_length_remaining(tvb,offset)), pinfo, tree);
+ pinfo->fragmented = save_fragmented;
return;
}
PDU, skip that? */
if (nsel == (char)tp_nsap_selector || always_decode_transport) {
- if (dissect_ositp_internal(next_tvb, pinfo, tree, FALSE))
+ if (dissect_ositp_internal(next_tvb, pinfo, tree, FALSE)) {
+ pinfo->fragmented = save_fragmented;
return; /* yes, it appears to be COTP or CLTP */
+ }
}
break;
/* The payload is the header and "none, some, or all of the data
part of the discarded PDU", i.e. it's like an ICMP error;
dissect it as a CLNP PDU. */
- if (check_col(pinfo->fd, COL_INFO))
- col_add_fstr(pinfo->fd, COL_INFO, "%s NPDU %s", pdu_type_string, flag_string);
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_add_fstr(pinfo->cinfo, COL_INFO, "%s NPDU %s", pdu_type_string, flag_string);
if (tree) {
next_length = tvb_length_remaining(tvb, offset);
if (next_length != 0) {
Make the columns non-writable, so the packet isn't shown
in the summary based on what the discarded PDU's contents
are. */
- col_set_writable(pinfo->fd, FALSE);
+ col_set_writable(pinfo->cinfo, FALSE);
/* Also, save the current values of the addresses, and restore
them when we're finished dissecting the contained packet, so
pinfo->dst = save_dst;
}
}
+ pinfo->fragmented = save_fragmented;
return; /* we're done with this PDU */
case ERQ_NPDU:
break;
}
}
- if (check_col(pinfo->fd, COL_INFO))
- col_add_fstr(pinfo->fd, COL_INFO, "%s NPDU %s", pdu_type_string, flag_string);
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_add_fstr(pinfo->cinfo, COL_INFO, "%s NPDU %s", pdu_type_string, flag_string);
call_dissector(data_handle,next_tvb, pinfo, tree);
-
+ pinfo->fragmented = save_fragmented;
} /* dissect_clnp */
static void
clnp_handle = create_dissector_handle(dissect_clnp, proto_clnp);
dissector_add("osinl", NLPID_ISO8473_CLNP, clnp_handle);
dissector_add("osinl", NLPID_NULL, clnp_handle); /* Inactive subset */
+ dissector_add("x.25.spi", NLPID_ISO8473_CLNP, clnp_handle);
}