/* * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code * distributions retain the above copyright notice and this paragraph * in its entirety, and (2) distributions including binary code include * the above copyright notice and this paragraph in its entirety in * the documentation or other materials provided with the distribution. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * * Original code by Andy Heffernan (ahh@juniper.net) */ #ifndef lint static const char rcsid[] _U_ = "@(#) $Header: /tcpdump/master/tcpdump/print-pgm.c,v 1.5 2005-06-07 22:05:58 guy Exp $"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "interface.h" #include "extract.h" #include "addrtoname.h" #include "ip.h" #ifdef INET6 #include "ip6.h" #endif #include "ipproto.h" /* * PGM header (RFC 3208) */ struct pgm_header { u_int16_t pgm_sport; u_int16_t pgm_dport; u_int8_t pgm_type; u_int8_t pgm_options; u_int16_t pgm_sum; u_int8_t pgm_gsid[6]; u_int16_t pgm_length; }; struct pgm_spm { u_int32_t pgms_seq; u_int32_t pgms_trailseq; u_int32_t pgms_leadseq; u_int16_t pgms_nla_afi; u_int16_t pgms_reserved; /* ... u_int8_t pgms_nla[0]; */ /* ... options */ }; struct pgm_nak { u_int32_t pgmn_seq; u_int16_t pgmn_source_afi; u_int16_t pgmn_reserved; /* ... u_int8_t pgmn_source[0]; */ /* ... u_int16_t pgmn_group_afi */ /* ... u_int16_t pgmn_reserved2; */ /* ... u_int8_t pgmn_group[0]; */ /* ... options */ }; struct pgm_poll { u_int32_t pgmp_seq; u_int16_t pgmp_round; u_int16_t pgmp_reserved; /* ... options */ }; struct pgm_polr { u_int32_t pgmp_seq; u_int16_t pgmp_round; u_int16_t pgmp_subtype; u_int16_t pgmp_nla_afi; u_int16_t pgmp_reserved; /* ... u_int8_t pgmp_nla[0]; */ /* ... options */ }; struct pgm_data { u_int32_t pgmd_seq; u_int32_t pgmd_trailseq; /* ... options */ }; typedef enum _pgm_type { PGM_SPM = 0, /* source path message */ PGM_POLL = 1, /* POLL Request */ PGM_POLR = 2, /* POLL Response */ PGM_ODATA = 4, /* original data */ PGM_RDATA = 5, /* repair data */ PGM_NAK = 8, /* NAK */ PGM_NULLNAK = 9, /* Null NAK */ PGM_NCF = 10, /* NAK Confirmation */ PGM_ACK = 11, /* ACK for congestion control */ PGM_SPMR = 12, /* SPM request */ PGM_MAX = 255 } pgm_type; #define PGM_OPT_BIT_PRESENT 0x01 #define PGM_OPT_BIT_NETWORK 0x02 #define PGM_OPT_BIT_VAR_PKTLEN 0x40 #define PGM_OPT_BIT_PARITY 0x80 #define PGM_OPT_LENGTH 0x00 #define PGM_OPT_FRAGMENT 0x01 #define PGM_OPT_NAK_LIST 0x02 #define PGM_OPT_JOIN 0x03 #define PGM_OPT_NAK_BO_IVL 0x04 #define PGM_OPT_NAK_BO_RNG 0x05 #define PGM_OPT_REDIRECT 0x07 #define PGM_OPT_PARITY_PRM 0x08 #define PGM_OPT_PARITY_GRP 0x09 #define PGM_OPT_CURR_TGSIZE 0x0A #define PGM_OPT_NBR_UNREACH 0x0B #define PGM_OPT_PATH_NLA 0x0C #define PGM_OPT_SYN 0x0D #define PGM_OPT_FIN 0x0E #define PGM_OPT_RST 0x0F #define PGM_OPT_CR 0x10 #define PGM_OPT_CRQST 0x11 #define PGM_OPT_MASK 0x7f #define PGM_OPT_END 0x80 /* end of options marker */ #define PGM_MIN_OPT_LEN 4 #ifndef AFI_IP #define AFI_IP 1 #define AFI_IP6 2 #endif void pgm_print(register const u_char *bp, register u_int length, register const u_char *bp2) { register const struct pgm_header *pgm; register const struct ip *ip; register char ch; u_int16_t sport, dport; int addr_size; const void *nla; int nla_af; #ifdef INET6 char nla_buf[INET6_ADDRSTRLEN]; register const struct ip6_hdr *ip6; #else char nla_buf[INET_ADDRSTRLEN]; #endif u_int8_t opt_type, opt_len, flags1, flags2; u_int32_t seq, opts_len, len,