#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/tcpdump/print-pgm.c,v 1.4 2005-06-07 21:58:32 guy Exp $";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-pgm.c,v 1.5 2005-06-07 22:05:58 guy Exp $";
#endif
#ifdef HAVE_CONFIG_H
#include "addrtoname.h"
#include "ip.h"
+#ifdef INET6
#include "ip6.h"
+#endif
#include "ipproto.h"
/*
/* ... options */
};
+struct pgm_ack {
+ u_int32_t pgma_rx_max_seq;
+ u_int32_t pgma_bitmap;
+ /* ... options */
+};
+
struct pgm_poll {
u_int32_t pgmp_seq;
u_int16_t pgmp_round;
#define PGM_OPT_RST 0x0F
#define PGM_OPT_CR 0x10
#define PGM_OPT_CRQST 0x11
+
+#define PGM_OPT_PGMCC_DATA 0x12
+#define PGM_OPT_PGMCC_FEEDBACK 0x13
#define PGM_OPT_MASK 0x7f
int addr_size;
const void *nla;
int nla_af;
- char nla_buf[INET6_ADDRSTRLEN];
#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, offset;
ip6 = (struct ip6_hdr *)bp2;
else
ip6 = NULL;
-#endif /*INET6*/
+#else /* INET6 */
+ if (IP_V(ip) == 6) {
+ (void)printf("Can't handle IPv6");
+ return;
+ }
+#endif /* INET6 */
ch = '\0';
if (!TTEST(pgm->pgm_dport)) {
#ifdef INET6
addr_size = sizeof(struct in_addr);
nla_af = AF_INET;
break;
+#ifdef INET6
case AFI_IP6:
addr_size = sizeof(struct in6_addr);
nla_af = AF_INET6;
break;
+#endif
default:
goto trunc;
break;
addr_size = sizeof(struct in_addr);
nla_af = AF_INET;
break;
+#ifdef INET6
case AFI_IP6:
addr_size = sizeof(struct in6_addr);
nla_af = AF_INET6;
break;
+#endif
default:
goto trunc;
break;
struct pgm_nak *nak;
const void *source, *group;
int source_af, group_af;
+#ifdef INET6
char source_buf[INET6_ADDRSTRLEN], group_buf[INET6_ADDRSTRLEN];
+#else
+ char source_buf[INET_ADDRSTRLEN], group_buf[INET_ADDRSTRLEN];
+#endif
nak = (struct pgm_nak *)(pgm + 1);
TCHECK(*nak);
addr_size = sizeof(struct in_addr);
source_af = AF_INET;
break;
+#ifdef INET6
case AFI_IP6:
addr_size = sizeof(struct in6_addr);
source_af = AF_INET6;
break;
+#endif
default:
goto trunc;
break;
addr_size = sizeof(struct in_addr);
group_af = AF_INET;
break;
+#ifdef INET6
case AFI_IP6:
addr_size = sizeof(struct in6_addr);
group_af = AF_INET6;
break;
+#endif
default:
goto trunc;
break;
break;
}
+ case PGM_ACK: {
+ struct pgm_ack *ack;
+
+ ack = (struct pgm_ack *)(pgm + 1);
+ TCHECK(*ack);
+ (void)printf("ACK seq %u",
+ EXTRACT_32BITS(&ack->pgma_rx_max_seq));
+ bp = (u_char *) (ack + 1);
+ break;
+ }
+
case PGM_SPMR:
(void)printf("SPMR");
break;
addr_size = sizeof(struct in_addr);
nla_af = AF_INET;
break;
+#ifdef INET6
case AFI_IP6:
addr_size = sizeof(struct in6_addr);
nla_af = AF_INET6;
break;
+#endif
default:
goto trunc;
break;
opts_len -= 4;
break;
+ case PGM_OPT_PGMCC_DATA:
+ flags1 = *bp++;
+ flags2 = *bp++;
+ offset = EXTRACT_32BITS(bp);
+ bp += sizeof(u_int32_t);
+ switch (EXTRACT_16BITS(bp)) {
+ case AFI_IP:
+ addr_size = sizeof(struct in_addr);
+ nla_af = AF_INET;
+ break;
+#ifdef INET6
+ case AFI_IP6:
+ addr_size = sizeof(struct in6_addr);
+ nla_af = AF_INET6;
+ break;
+#endif
+ default:
+ goto trunc;
+ break;
+ }
+ bp += (2 * sizeof(u_int16_t));
+ if (opt_len != 12 + addr_size) {
+ (void)printf("[Bad OPT_PGMCC_DATA option, length %u != 12 + address size]", opt_len);
+ return;
+ }
+ TCHECK2(*bp, addr_size);
+ nla = bp;
+ bp += addr_size;
+
+ inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf));
+ (void)printf(" PGMCC DATA %u %s", offset, (char*)nla);
+ opts_len -= 16;
+ break;
+
+ case PGM_OPT_PGMCC_FEEDBACK:
+ flags1 = *bp++;
+ flags2 = *bp++;
+ offset = EXTRACT_32BITS(bp);
+ bp += sizeof(u_int32_t);
+ switch (EXTRACT_16BITS(bp)) {
+ case AFI_IP:
+ addr_size = sizeof(struct in_addr);
+ nla_af = AF_INET;
+ break;
+#ifdef INET6
+ case AFI_IP6:
+ addr_size = sizeof(struct in6_addr);
+ nla_af = AF_INET6;
+ break;
+#endif
+ default:
+ goto trunc;
+ break;
+ }
+ bp += (2 * sizeof(u_int16_t));
+ if (opt_len != 12 + addr_size) {
+ (void)printf("[Bad OPT_PGMCC_FEEDBACK option, length %u != 12 + address size]", opt_len);
+ return;
+ }
+ TCHECK2(*bp, addr_size);
+ nla = bp;
+ bp += addr_size;
+
+ inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf));
+ (void)printf(" PGMCC FEEDBACK %u %s", offset, (char*)nla);
+ opts_len -= 16;
+ break;
+
default:
(void)printf(" OPT_%02X [%d] ", opt_type, opt_len);
bp += opt_len;