wireshark/packet-pgm.h

250 lines
6.5 KiB
C
Raw Normal View History

/* packet-pgm.h
* Declarations for pgm packet disassembly
*
* $Id: packet-pgm.h,v 1.6 2001/08/06 19:05:14 guy Exp $
*
* Copyright (c) 2000 by Talarian Corp
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
* Copyright 1999 Gerald Combs
*
* 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.
*
* 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.
*
* 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.
*/
#ifndef _PACKET_PGM_H
#define _PACKET_PGM_H
There is really no need to have the BGP dissector and the LDP dissector have two independent "value_string" tables mapping RFC 1700 address family numbers to names, nor is there any need to have the BGP dissector and the PIM dissector have two independent sets of #defines for RFC 1700 address family numbers; put a single "value_string" table in "afn.c" and put a declaration of it, and #defines for the address family numbers, into "afn.h", and have the dissectors use that. Move the #define for PGM into "ipproto.h", and add an entry for it in the "value_string" table in "ipproto.c". Have the PGM dissector use the standard Ethereal mechanisms for resolving addresses, and have it use "value_string" tables for mapping option types, the OPX bits, and packet types to strings. Use "bytes_to_str()" to turn byte arrays into strings of hex digits. Pass the packet type string to "dissect_pgmopts()" as an argument, rather than making it a global. Don't use "proto_tree_add_XXX_format" routines if you can possibly just use "proto_tree_add_XXX"; give various fields the correct radix and type, and VALS() strings if necessary, to make that happen (and to make filtering on them more pleasant). Put the type, length, and total length of the options into the protocol tree as separate fields. Don't have separate type, length, and OPX fields for every type of option; one field will suffice. Don't format a string with "sprintf()" and then pass that string to "col_add_fstr()" with a format of "%s" and the string as an argument - "col_add_fstr()" can format strings itself (that's what the "f" stands for). Don't byte-swap and then un-byte-swap IPv4 address fields in the header, just leave them network byte order to start with. Use the correct fields for "proto_tree_add_XXX", rather than using the same field multiple times. Quit early if an address family identifier isn't AFNUM_INET, as that means the structure we use to dissect the header doesn't match the actual header. svn path=/trunk/; revision=3761
2001-07-21 10:27:13 +00:00
typedef guint8 nchar_t;
typedef guint16 nshort_t;
typedef guint32 nlong_t;
/* The PGM main header */
typedef struct {
nshort_t sport; /* source port */
nshort_t dport; /* destination port */
nchar_t type; /* PGM type */
nchar_t opts; /* options */
nshort_t cksum; /* checksum */
nchar_t gsi[6]; /* Global Source ID */
nshort_t tsdulen; /* TSDU length */
} pgm_type;
#define pgmhdr_ntoh(_p) \
(_p)->sport = ntohs((_p)->sport); \
(_p)->dport = ntohs((_p)->dport); \
(_p)->type = ntohs((_p)->type); \
(_p)->opts = ntohs((_p)->opts); \
(_p)->cksum = ntohs((_p)->cksum); \
(_p)->tsdulen = ntohs((_p)->tsdulen)
/* The PGM SPM header */
typedef struct {
nlong_t sqn; /* SPM's sequence number */
nlong_t trail; /* Trailing edge sequence number */
nlong_t lead; /* Leading edge sequence number */
There is really no need to have the BGP dissector and the LDP dissector have two independent "value_string" tables mapping RFC 1700 address family numbers to names, nor is there any need to have the BGP dissector and the PIM dissector have two independent sets of #defines for RFC 1700 address family numbers; put a single "value_string" table in "afn.c" and put a declaration of it, and #defines for the address family numbers, into "afn.h", and have the dissectors use that. Move the #define for PGM into "ipproto.h", and add an entry for it in the "value_string" table in "ipproto.c". Have the PGM dissector use the standard Ethereal mechanisms for resolving addresses, and have it use "value_string" tables for mapping option types, the OPX bits, and packet types to strings. Use "bytes_to_str()" to turn byte arrays into strings of hex digits. Pass the packet type string to "dissect_pgmopts()" as an argument, rather than making it a global. Don't use "proto_tree_add_XXX_format" routines if you can possibly just use "proto_tree_add_XXX"; give various fields the correct radix and type, and VALS() strings if necessary, to make that happen (and to make filtering on them more pleasant). Put the type, length, and total length of the options into the protocol tree as separate fields. Don't have separate type, length, and OPX fields for every type of option; one field will suffice. Don't format a string with "sprintf()" and then pass that string to "col_add_fstr()" with a format of "%s" and the string as an argument - "col_add_fstr()" can format strings itself (that's what the "f" stands for). Don't byte-swap and then un-byte-swap IPv4 address fields in the header, just leave them network byte order to start with. Use the correct fields for "proto_tree_add_XXX", rather than using the same field multiple times. Quit early if an address family identifier isn't AFNUM_INET, as that means the structure we use to dissect the header doesn't match the actual header. svn path=/trunk/; revision=3761
2001-07-21 10:27:13 +00:00
nshort_t path_afi; /* NLA AFI */
nshort_t res; /* reserved */
nlong_t path; /* Path NLA */
} pgm_spm_t;
const size_t PGM_SPM_SZ = sizeof(pgm_type)+sizeof(pgm_spm_t);
#define spm_ntoh(_p) \
(_p)->sqn = ntohl((_p)->sqn); \
(_p)->trail = ntohl((_p)->trail); \
(_p)->lead = ntohl((_p)->lead); \
(_p)->path_afi = ntohs((_p)->path_afi); \
There is really no need to have the BGP dissector and the LDP dissector have two independent "value_string" tables mapping RFC 1700 address family numbers to names, nor is there any need to have the BGP dissector and the PIM dissector have two independent sets of #defines for RFC 1700 address family numbers; put a single "value_string" table in "afn.c" and put a declaration of it, and #defines for the address family numbers, into "afn.h", and have the dissectors use that. Move the #define for PGM into "ipproto.h", and add an entry for it in the "value_string" table in "ipproto.c". Have the PGM dissector use the standard Ethereal mechanisms for resolving addresses, and have it use "value_string" tables for mapping option types, the OPX bits, and packet types to strings. Use "bytes_to_str()" to turn byte arrays into strings of hex digits. Pass the packet type string to "dissect_pgmopts()" as an argument, rather than making it a global. Don't use "proto_tree_add_XXX_format" routines if you can possibly just use "proto_tree_add_XXX"; give various fields the correct radix and type, and VALS() strings if necessary, to make that happen (and to make filtering on them more pleasant). Put the type, length, and total length of the options into the protocol tree as separate fields. Don't have separate type, length, and OPX fields for every type of option; one field will suffice. Don't format a string with "sprintf()" and then pass that string to "col_add_fstr()" with a format of "%s" and the string as an argument - "col_add_fstr()" can format strings itself (that's what the "f" stands for). Don't byte-swap and then un-byte-swap IPv4 address fields in the header, just leave them network byte order to start with. Use the correct fields for "proto_tree_add_XXX", rather than using the same field multiple times. Quit early if an address family identifier isn't AFNUM_INET, as that means the structure we use to dissect the header doesn't match the actual header. svn path=/trunk/; revision=3761
2001-07-21 10:27:13 +00:00
(_p)->res = ntohs((_p)->res);
/* The PGM Data (ODATA/RDATA) header */
typedef struct {
nlong_t sqn; /* Data Packet sequence number */
nlong_t trail; /* Trailing edge sequence number */
} pgm_data_t;
#define data_ntoh(_p) \
(_p)->sqn = ntohl((_p)->sqn); \
(_p)->trail = ntohl((_p)->trail)
const size_t PGM_DATA_HDR_SZ = sizeof(pgm_type)+sizeof(pgm_data_t);
/* The PGM NAK (NAK/N-NAK/NCF) header */
typedef struct {
nlong_t sqn; /* Requested sequence number */
nshort_t src_afi; /* NLA AFI for source (IPv4 is set to 1) */
nshort_t src_res; /* reserved */
nlong_t src; /* Source NLA */
nshort_t grp_afi; /* Multicast group AFI (IPv4 is set to 1) */
nshort_t grp_res; /* reserved */
nlong_t grp; /* Multicast group NLA */
} pgm_nak_t;
const size_t PGM_NAK_SZ = sizeof(pgm_type)+sizeof(pgm_nak_t);
#define nak_ntoh(_p) \
(_p)->sqn = ntohl((_p)->sqn); \
(_p)->src_afi = ntohs((_p)->src_afi); \
(_p)->src_res = ntohs((_p)->src_res); \
(_p)->grp_afi = ntohs((_p)->grp_afi); \
(_p)->grp_res = ntohs((_p)->grp_res)
/* The PGM ACK header (PGMCC) */
typedef struct {
nlong_t rx_max_sqn; /* RX_MAX sequence number */
nlong_t bitmap; /* Received Packet Bitmap */
} pgm_ack_t;
const size_t PGM_ACK_SZ = sizeof(pgm_type)+sizeof(pgm_ack_t);
#define ack_ntoh(_p) \
(_p)->rx_max_sqn = ntohl((_p)->rx_max_sqn); \
(_p)->bitmap = ntohl((_p)->bitmap)
/* constants for hdr types */
#if defined(PGM_SPEC_01_PCKTS)
/* old spec-01 types */
#define PGM_SPM_PCKT 0x00
#define PGM_ODATA_PCKT 0x10
#define PGM_RDATA_PCKT 0x11
#define PGM_NAK_PCKT 0x20
#define PGM_NNAK_PCKT 0x21
#define PGM_NCF_PCKT 0x30
#else
/* spec-02 types (as well as spec-04+) */
#define PGM_SPM_PCKT 0x00
#define PGM_ODATA_PCKT 0x04
#define PGM_RDATA_PCKT 0x05
#define PGM_NAK_PCKT 0x08
#define PGM_NNAK_PCKT 0x09
#define PGM_NCF_PCKT 0x0A
#define PGM_ACK_PCKT 0x0D
#endif /* PGM_SPEC_01_PCKTS */
/* port swapping on NAK and NNAKs or not (default is to swap) */
/* PGM_NO_PORT_SWAP */
/* option flags (main PGM header) */
#define PGM_OPT 0x01
#define PGM_OPT_NETSIG 0x02
#define PGM_OPT_VAR_PKTLEN 0x40
#define PGM_OPT_PARITY 0x80
/* option types */
#define PGM_OPT_LENGTH 0x00
#define PGM_OPT_END 0x80
#define PGM_OPT_FRAGMENT 0x01
#define PGM_OPT_NAK_LIST 0x02
#define PGM_OPT_JOIN 0x03
#define PGM_OPT_REDIRECT 0x07
#define PGM_OPT_SYN 0x0D
#define PGM_OPT_FIN 0x0E
#define PGM_OPT_RST 0x0F
#define PGM_OPT_PARITY_PRM 0x08
#define PGM_OPT_PARITY_GRP 0x09
#define PGM_OPT_CURR_TGSIZE 0x0A
#define PGM_OPT_PGMCC_DATA 0x12
#define PGM_OPT_PGMCC_FEEDBACK 0x13
const nchar_t PGM_OPT_INVALID = 0x7F;
/* OPX bit values */
There is really no need to have the BGP dissector and the LDP dissector have two independent "value_string" tables mapping RFC 1700 address family numbers to names, nor is there any need to have the BGP dissector and the PIM dissector have two independent sets of #defines for RFC 1700 address family numbers; put a single "value_string" table in "afn.c" and put a declaration of it, and #defines for the address family numbers, into "afn.h", and have the dissectors use that. Move the #define for PGM into "ipproto.h", and add an entry for it in the "value_string" table in "ipproto.c". Have the PGM dissector use the standard Ethereal mechanisms for resolving addresses, and have it use "value_string" tables for mapping option types, the OPX bits, and packet types to strings. Use "bytes_to_str()" to turn byte arrays into strings of hex digits. Pass the packet type string to "dissect_pgmopts()" as an argument, rather than making it a global. Don't use "proto_tree_add_XXX_format" routines if you can possibly just use "proto_tree_add_XXX"; give various fields the correct radix and type, and VALS() strings if necessary, to make that happen (and to make filtering on them more pleasant). Put the type, length, and total length of the options into the protocol tree as separate fields. Don't have separate type, length, and OPX fields for every type of option; one field will suffice. Don't format a string with "sprintf()" and then pass that string to "col_add_fstr()" with a format of "%s" and the string as an argument - "col_add_fstr()" can format strings itself (that's what the "f" stands for). Don't byte-swap and then un-byte-swap IPv4 address fields in the header, just leave them network byte order to start with. Use the correct fields for "proto_tree_add_XXX", rather than using the same field multiple times. Quit early if an address family identifier isn't AFNUM_INET, as that means the structure we use to dissect the header doesn't match the actual header. svn path=/trunk/; revision=3761
2001-07-21 10:27:13 +00:00
#define PGM_OPX_IGNORE 0x00
#define PGM_OPX_INVAL 0x01
#define PGM_OPX_DISCARD 0x10
/* option formats */
typedef struct {
nchar_t type;
nchar_t len;
nchar_t opx;
nchar_t res;
} pgm_opt_generic_t;
typedef struct {
nchar_t type;
nchar_t len;
nshort_t total_len;
} pgm_opt_length_t;
typedef struct {
nchar_t type;
nchar_t len;
nchar_t opx;
nchar_t res;
} pgm_opt_nak_list_t;
/*
* To squeeze the whole option into 255 bytes, we
* can only have 62 in the list
*/
#define PGM_MAX_NAK_LIST_SZ (62)
typedef struct {
nchar_t type;
nchar_t len;
nchar_t opx;
nchar_t res;
nlong_t opt_join_min;
} pgm_opt_join_t;
typedef struct {
nchar_t type;
nchar_t len;
nchar_t opx;
nchar_t po;
nlong_t prm_tgsz;
} pgm_opt_parity_prm_t;
/* OPT_PARITY_PRM P and O bits */
const nchar_t PGM_OPT_PARITY_PRM_PRO = 0x2;
const nchar_t PGM_OPT_PARITY_PRM_OND = 0x1;
typedef struct {
nchar_t type;
nchar_t len;
nchar_t opx;
nchar_t res;
nlong_t prm_grp;
} pgm_opt_parity_grp_t;
typedef struct {
nchar_t type;
nchar_t len;
nchar_t opx;
nchar_t res;
nlong_t prm_atgsz;
} pgm_opt_curr_tgsize_t;
typedef struct {
nchar_t type;
nchar_t len;
nchar_t opx;
nchar_t res;
nlong_t tsp;
nshort_t acker_afi;
nshort_t res2;
nlong_t acker;
} pgm_opt_pgmcc_data_t;
typedef struct {
nchar_t type;
nchar_t len;
nchar_t opx;
nchar_t res;
nlong_t tsp;
nshort_t acker_afi;
nshort_t loss_rate;
nlong_t acker;
} pgm_opt_pgmcc_feedback_t;
/*
* Udp port for UDP encapsulation
*/
#define DEFAULT_UDP_ENCAP_UCAST_PORT 3055
#define DEFAULT_UDP_ENCAP_MCAST_PORT 3056
#endif /* _PACKET_PGM_H */