]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-pgm.c
Add changes in 4.2.1.
[tcpdump] / print-pgm.c
index d7a40cb80b53dacf9a0814029bb5e5aba35f786d..2d4d7449c91b38172c1f9dce816f7e8f5856a9c0 100644 (file)
@@ -15,7 +15,7 @@
 
 #ifndef lint
 static const char rcsid[] _U_ =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-pgm.c,v 1.2 2005-05-23 21:38:06 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
@@ -33,7 +33,9 @@ static const char rcsid[] _U_ =
 #include "addrtoname.h"
 
 #include "ip.h"
+#ifdef INET6
 #include "ip6.h"
+#endif
 #include "ipproto.h"
 
 /*
@@ -55,7 +57,7 @@ struct pgm_spm {
     u_int32_t  pgms_leadseq;
     u_int16_t  pgms_nla_afi;
     u_int16_t  pgms_reserved;
-    u_int8_t   pgms_nla[0];
+    /* ... u_int8_t    pgms_nla[0]; */
     /* ... options */
 };
 
@@ -63,13 +65,19 @@ 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_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_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;
@@ -83,7 +91,7 @@ struct pgm_polr {
     u_int16_t  pgmp_subtype;
     u_int16_t  pgmp_nla_afi;
     u_int16_t  pgmp_reserved;
-    u_int8_t   pgmp_nla[0];
+    /* ... u_int8_t    pgmp_nla[0]; */
     /* ... options */
 };
 
@@ -131,6 +139,9 @@ typedef enum _pgm_type {
 #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
 
@@ -154,9 +165,11 @@ pgm_print(register const u_char *bp, register u_int length,
        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;
@@ -168,7 +181,12 @@ pgm_print(register const u_char *bp, register u_int length,
                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
@@ -246,10 +264,12 @@ pgm_print(register const u_char *bp, register u_int length,
                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;
@@ -276,6 +296,7 @@ pgm_print(register const u_char *bp, register u_int length,
            (void)printf("POLL seq %u round %u",
                         EXTRACT_32BITS(&poll->pgmp_seq),
                          EXTRACT_16BITS(&poll->pgmp_round));
+           bp = (u_char *) (poll + 1);
            break;
        }
        case PGM_POLR: {
@@ -290,10 +311,12 @@ pgm_print(register const u_char *bp, register u_int length,
                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;
@@ -306,19 +329,19 @@ pgm_print(register const u_char *bp, register u_int length,
            inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf));
 
            TCHECK2(*bp, sizeof(u_int32_t));
-           ivl = EXTRACT_32BITS(*(u_int32_t *)bp);
+           ivl = EXTRACT_32BITS(bp);
            bp += sizeof(u_int32_t);
 
            TCHECK2(*bp, sizeof(u_int32_t));
-           rnd = EXTRACT_32BITS(*(u_int32_t *)bp);
+           rnd = EXTRACT_32BITS(bp);
            bp += sizeof(u_int32_t);
 
            TCHECK2(*bp, sizeof(u_int32_t));
-           mask = EXTRACT_32BITS(*(u_int32_t *)bp);
+           mask = EXTRACT_32BITS(bp);
            bp += sizeof(u_int32_t);
 
            (void)printf("POLR seq %u round %u nla %s ivl %u rnd 0x%08x "
-                        "mask 0x%08x", EXTRACT_32BITS(polr->pgmp_seq),
+                        "mask 0x%08x", EXTRACT_32BITS(&polr->pgmp_seq),
                         EXTRACT_16BITS(&polr->pgmp_round), nla_buf, ivl, rnd, mask);
            break;
        }
@@ -328,7 +351,9 @@ pgm_print(register const u_char *bp, register u_int length,
            odata = (struct pgm_data *)(pgm + 1);
            TCHECK(*odata);
            (void)printf("ODATA trail %u seq %u",
-                        EXTRACT_32BITS(odata->pgmd_trailseq), EXTRACT_32BITS(odata->pgmd_seq));
+                        EXTRACT_32BITS(&odata->pgmd_trailseq),
+                        EXTRACT_32BITS(&odata->pgmd_seq));
+           bp = (u_char *) (odata + 1);
            break;
        }
 
@@ -338,7 +363,9 @@ pgm_print(register const u_char *bp, register u_int length,
            rdata = (struct pgm_data *)(pgm + 1);
            TCHECK(*rdata);
            (void)printf("RDATA trail %u seq %u",
-                        EXTRACT_32BITS(rdata->pgmd_trailseq), EXTRACT_32BITS(rdata->pgmd_seq));
+                        EXTRACT_32BITS(&rdata->pgmd_trailseq),
+                        EXTRACT_32BITS(&rdata->pgmd_seq));
+           bp = (u_char *) (rdata + 1);
            break;
        }
 
@@ -348,7 +375,11 @@ pgm_print(register const u_char *bp, register u_int length,
            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);
@@ -362,10 +393,12 @@ pgm_print(register const u_char *bp, register u_int length,
                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;
@@ -384,10 +417,12 @@ pgm_print(register const u_char *bp, register u_int length,
                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;
@@ -416,7 +451,18 @@ pgm_print(register const u_char *bp, register u_int length,
                     break;
            }
            (void)printf("(%s -> %s), seq %u",
-                        source_buf, group_buf, EXTRACT_32BITS(nak->pgmn_seq));
+                        source_buf, group_buf, EXTRACT_32BITS(&nak->pgmn_seq));
+           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;
        }
 
@@ -445,7 +491,7 @@ pgm_print(register const u_char *bp, register u_int length,
             */
            opt_type = *bp++;
            if ((opt_type & PGM_OPT_MASK) != PGM_OPT_LENGTH) {
-               (void)printf("[First option bad, should be PGM_OPT_LENGTH, is %u]", opt_type);
+               (void)printf("[First option bad, should be PGM_OPT_LENGTH, is %u]", opt_type & PGM_OPT_MASK);
                return;
            }
            opt_len = *bp++;
@@ -495,20 +541,20 @@ pgm_print(register const u_char *bp, register u_int length,
                    break;
 
                case PGM_OPT_FRAGMENT:
-                   if (opt_len != 12) {
-                       (void)printf("[Bad OPT_FRAGMENT option, length %u != 12]", opt_len);
+                   if (opt_len != 16) {
+                       (void)printf("[Bad OPT_FRAGMENT option, length %u != 16]", opt_len);
                        return;
                    }
                    flags1 = *bp++;
                    flags2 = *bp++;
-                   seq = EXTRACT_32BITS(*(u_int32_t *)bp);
+                   seq = EXTRACT_32BITS(bp);
                    bp += sizeof(u_int32_t);
-                   offset = EXTRACT_32BITS(*(u_int32_t *)bp);
+                   offset = EXTRACT_32BITS(bp);
                    bp += sizeof(u_int32_t);
-                   len = EXTRACT_32BITS(*(u_int32_t *)bp);
+                   len = EXTRACT_32BITS(bp);
                    bp += sizeof(u_int32_t);
                    (void)printf(" FRAG seq %u off %u len %u", seq, offset, len);
-                   opts_len -= 12;
+                   opts_len -= 16;
                    break;
 
                case PGM_OPT_NAK_LIST:
@@ -522,7 +568,7 @@ pgm_print(register const u_char *bp, register u_int length,
                            return;
                        }
                        TCHECK2(*bp, sizeof(u_int32_t));
-                       (void)printf(" %u", EXTRACT_32BITS(*(u_int32_t *)bp));
+                       (void)printf(" %u", EXTRACT_32BITS(bp));
                        bp += sizeof(u_int32_t);
                        opt_len -= sizeof(u_int32_t);
                        opts_len -= sizeof(u_int32_t);
@@ -536,7 +582,7 @@ pgm_print(register const u_char *bp, register u_int length,
                    }
                    flags1 = *bp++;
                    flags2 = *bp++;
-                   seq = EXTRACT_32BITS(*(u_int32_t *)bp);
+                   seq = EXTRACT_32BITS(bp);
                    bp += sizeof(u_int32_t);
                    (void)printf(" JOIN %u", seq);
                    opts_len -= 8;
@@ -544,14 +590,14 @@ pgm_print(register const u_char *bp, register u_int length,
 
                case PGM_OPT_NAK_BO_IVL:
                    if (opt_len != 12) {
-                       (void)printf("[Bad OPT_FRAGMENT option, length %u != 12]", opt_len);
+                       (void)printf("[Bad OPT_NAK_BO_IVL option, length %u != 12]", opt_len);
                        return;
                    }
                    flags1 = *bp++;
                    flags2 = *bp++;
-                   offset = EXTRACT_32BITS(*(u_int32_t *)bp);
+                   offset = EXTRACT_32BITS(bp);
                    bp += sizeof(u_int32_t);
-                   seq = EXTRACT_32BITS(*(u_int32_t *)bp);
+                   seq = EXTRACT_32BITS(bp);
                    bp += sizeof(u_int32_t);
                    (void)printf(" BACKOFF ivl %u ivlseq %u", offset, seq);
                    opts_len -= 12;
@@ -559,14 +605,14 @@ pgm_print(register const u_char *bp, register u_int length,
 
                case PGM_OPT_NAK_BO_RNG:
                    if (opt_len != 12) {
-                       (void)printf("[Bad OPT_FRAGMENT option, length %u != 12]", opt_len);
+                       (void)printf("[Bad OPT_NAK_BO_RNG option, length %u != 12]", opt_len);
                        return;
                    }
                    flags1 = *bp++;
                    flags2 = *bp++;
-                   offset = EXTRACT_32BITS(*(u_int32_t *)bp);
+                   offset = EXTRACT_32BITS(bp);
                    bp += sizeof(u_int32_t);
-                   seq = EXTRACT_32BITS(*(u_int32_t *)bp);
+                   seq = EXTRACT_32BITS(bp);
                    bp += sizeof(u_int32_t);
                    (void)printf(" BACKOFF max %u min %u", offset, seq);
                    opts_len -= 12;
@@ -580,10 +626,12 @@ pgm_print(register const u_char *bp, register u_int length,
                        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;
@@ -609,7 +657,7 @@ pgm_print(register const u_char *bp, register u_int length,
                    }
                    flags1 = *bp++;
                    flags2 = *bp++;
-                   len = EXTRACT_32BITS(*(u_int32_t *)bp);
+                   len = EXTRACT_32BITS(bp);
                    bp += sizeof(u_int32_t);
                    (void)printf(" PARITY MAXTGS %u", len);
                    opts_len -= 8;
@@ -622,7 +670,7 @@ pgm_print(register const u_char *bp, register u_int length,
                    }
                    flags1 = *bp++;
                    flags2 = *bp++;
-                   seq = EXTRACT_32BITS(*(u_int32_t *)bp);
+                   seq = EXTRACT_32BITS(bp);
                    bp += sizeof(u_int32_t);
                    (void)printf(" PARITY GROUP %u", seq);
                    opts_len -= 8;
@@ -630,12 +678,12 @@ pgm_print(register const u_char *bp, register u_int length,
 
                case PGM_OPT_CURR_TGSIZE:
                    if (opt_len != 8) {
-                       (void)printf("[Bad OPT_PARITY_GRP option, length %u != 8]", opt_len);
+                       (void)printf("[Bad OPT_CURR_TGSIZE option, length %u != 8]", opt_len);
                        return;
                    }
                    flags1 = *bp++;
                    flags2 = *bp++;
-                   len = EXTRACT_32BITS(*(u_int32_t *)bp);
+                   len = EXTRACT_32BITS(bp);
                    bp += sizeof(u_int32_t);
                    (void)printf(" PARITY ATGS %u", len);
                    opts_len -= 8;
@@ -671,7 +719,7 @@ pgm_print(register const u_char *bp, register u_int length,
 
                case PGM_OPT_FIN:
                    if (opt_len != 4) {
-                       (void)printf("[Bad OPT_RST option, length %u != 4]", opt_len);
+                       (void)printf("[Bad OPT_FIN option, length %u != 4]", opt_len);
                        return;
                    }
                    flags1 = *bp++;
@@ -708,6 +756,74 @@ pgm_print(register const u_char *bp, register u_int length,
                    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;