X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/65fa9cb9cadd1fedcd816c94793f311b5ab881d6..64e81f2917f6865dff8df96e18cec1b8bf2fa836:/print-rx.c diff --git a/print-rx.c b/print-rx.c index 6e5c2bd9..2fb3d2a8 100644 --- a/print-rx.c +++ b/print-rx.c @@ -13,7 +13,7 @@ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-rx.c,v 1.12 2000-07-10 04:38:25 assar Exp $"; + "@(#) $Header: /tcpdump/master/tcpdump/print-rx.c,v 1.20 2001-01-10 08:12:01 fenner Exp $"; #endif #ifdef HAVE_CONFIG_H @@ -21,6 +21,7 @@ static const char rcsid[] = #endif #include +#include #include #include #include @@ -28,8 +29,6 @@ static const char rcsid[] = #include #include #include -#include -#include #include #include "interface.h" @@ -41,6 +40,8 @@ static const char rcsid[] = #include "rx.h" +#include "ip.h" + static struct tok rx_types[] = { { RX_PACKET_TYPE_DATA, "data" }, { RX_PACKET_TYPE_ACK, "ack" }, @@ -374,9 +375,10 @@ static void rx_cache_insert(const u_char *, const struct ip *, int, int); static int rx_cache_find(const struct rx_header *, const struct ip *, int, int32_t *); +static void ack_print(const u_char *, int); static void fs_print(const u_char *, int); static void fs_reply_print(const u_char *, int, int32_t); -static void acl_print(u_char *, u_char *); +static void acl_print(u_char *, int, u_char *); static void cb_print(const u_char *, int); static void cb_reply_print(const u_char *, int, int32_t); static void prot_print(const u_char *, int); @@ -458,7 +460,9 @@ rx_print(register const u_char *bp, int length, int sport, int dport, * as well. */ - if (rxh->type == RX_PACKET_TYPE_DATA && + if (rxh->type == RX_PACKET_TYPE_ACK) + ack_print(bp, length); + else if (rxh->type == RX_PACKET_TYPE_DATA && EXTRACT_32BITS(&rxh->seq) == 1 && rxh->flags & RX_CLIENT_INITIATED) { @@ -620,9 +624,8 @@ rx_cache_find(const struct rx_header *rxh, const struct ip *ip, int sport, * These extrememly grody macros handle the printing of various AFS stuff. */ -#define TRUNC(n) if (snapend - bp + 1 <= n) goto trunc; #define FIDOUT() { unsigned long n1, n2, n3; \ - TRUNC(sizeof(int32_t) * 3); \ + TCHECK2(bp[0], sizeof(int32_t) * 3); \ n1 = EXTRACT_32BITS(bp); \ bp += sizeof(int32_t); \ n2 = EXTRACT_32BITS(bp); \ @@ -633,10 +636,10 @@ rx_cache_find(const struct rx_header *rxh, const struct ip *ip, int sport, } #define STROUT(MAX) { int i; \ - TRUNC(sizeof(int32_t)); \ + TCHECK2(bp[0], sizeof(int32_t)); \ i = (int) EXTRACT_32BITS(bp); \ bp += sizeof(int32_t); \ - TRUNC(i); \ + TCHECK2(bp[0], i); \ strncpy(s, (char *) bp, min(MAX, i)); \ s[i] = '\0'; \ printf(" \"%s\"", s); \ @@ -644,21 +647,21 @@ rx_cache_find(const struct rx_header *rxh, const struct ip *ip, int sport, } #define INTOUT() { int i; \ - TRUNC(sizeof(int32_t)); \ + TCHECK2(bp[0], sizeof(int32_t)); \ i = (int) EXTRACT_32BITS(bp); \ bp += sizeof(int32_t); \ printf(" %d", i); \ } #define UINTOUT() { unsigned long i; \ - TRUNC(sizeof(int32_t)); \ + TCHECK2(bp[0], sizeof(int32_t)); \ i = EXTRACT_32BITS(bp); \ bp += sizeof(int32_t); \ printf(" %lu", i); \ } #define DATEOUT() { time_t t; struct tm *tm; char str[256]; \ - TRUNC(sizeof(int32_t)); \ + TCHECK2(bp[0], sizeof(int32_t)); \ t = (time_t) EXTRACT_32BITS(bp); \ bp += sizeof(int32_t); \ tm = localtime(&t); \ @@ -667,7 +670,7 @@ rx_cache_find(const struct rx_header *rxh, const struct ip *ip, int sport, } #define STOREATTROUT() { unsigned long mask, i; \ - TRUNC((sizeof(int32_t)*6)); \ + TCHECK2(bp[0], (sizeof(int32_t)*6)); \ mask = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \ if (mask) printf (" StoreStatus"); \ if (mask & 1) { printf(" date"); DATEOUT(); } \ @@ -685,7 +688,7 @@ rx_cache_find(const struct rx_header *rxh, const struct ip *ip, int sport, } #define UBIK_VERSIONOUT() {int32_t epoch; int32_t counter; \ - TRUNC(sizeof(int32_t) * 2); \ + TCHECK2(bp[0], sizeof(int32_t) * 2); \ epoch = EXTRACT_32BITS(bp); \ bp += sizeof(int32_t); \ counter = EXTRACT_32BITS(bp); \ @@ -694,7 +697,7 @@ rx_cache_find(const struct rx_header *rxh, const struct ip *ip, int sport, } #define AFSUUIDOUT() {u_int32_t temp; int i; \ - TRUNC(11*sizeof(u_int32_t)); \ + TCHECK2(bp[0], 11*sizeof(u_int32_t)); \ temp = EXTRACT_32BITS(bp); \ bp += sizeof(u_int32_t); \ printf(" %08x", temp); \ @@ -717,7 +720,7 @@ rx_cache_find(const struct rx_header *rxh, const struct ip *ip, int sport, #define VECOUT(MAX) { char *sp; \ int k; \ - TRUNC(MAX * sizeof(int32_t)); \ + TCHECK2(bp[0], MAX * sizeof(int32_t)); \ sp = s; \ for (k = 0; k < MAX; k++) { \ *sp++ = (char) EXTRACT_32BITS(bp); \ @@ -727,11 +730,80 @@ rx_cache_find(const struct rx_header *rxh, const struct ip *ip, int sport, printf(" \"%s\"", s); \ } +static void +ack_print(register const u_char *bp, int length) +{ + u_char nAcks; + int i; + + if (vflag <= 1) + return; + + if (length <= sizeof(struct rx_header)) + return; + + bp += sizeof(struct rx_header); + + /* + * Packets < firstPacket are implicitly acknowledged and may + * be discarded by the sender. + * + * Packets >= firstPacket+nAcks are implicitly NOT acknowledged. + * + * No packets with sequence numbers >= firstPacket should be + * discarded by the sender (they may thrown out at any time by + * the receiver) + */ +#define RX_ACK_REASONS "RDOXSprn" + /* Requested, Duplicate, Out_of_sequence, eXceeds_window, no_Space, + * Ping, ping_Response, No_{progress, particular_reason}. + */ +#if 0 + struct rx_ackPacket { + u_short bufferSpace; /* Skip! */ + u_short maxSkew; /* Skip! */ + u_long firstPacket; + u_long previousPacket; /* Obsolete! */ + u_long serial; /* Serial that prompted the ack, */ + u_char reason; /* and the reason why. */ + u_char nAcks; + u_char acks[RX_MAXACKS]; /* Selective acks (not a bitmap). */ + }; +#endif +#define RX_ACK_TYPE_NACK 0 + + TCHECK2(bp[0], 8); /* bufferSpace and maxSkew */ + bp += 4; + printf(" fir %u", (unsigned)EXTRACT_32BITS(bp)); + bp += 4; + TCHECK2(bp[0], 8); /* previousPacket and serial */ + bp += 4; + printf(" %u", (unsigned)EXTRACT_32BITS(bp)); + bp += 4; + TCHECK2(bp[0], 1); + printf("%c", RX_ACK_REASONS[(*bp - 1) & 07u]); + bp += 1; /* reason */ + TCHECK2(bp[0], 1); + nAcks = *bp; + bp += 1; /* nAcks */ + + for (i = 0; i < nAcks; i++) { + TCHECK2(bp[0], 1); + putchar(*bp == RX_ACK_TYPE_NACK? '-' : '*'); + bp += 1; + } + + return; + +trunc: + printf(" [|ack]"); +} + /* * Handle calls to the AFS file service (fs) */ -void +static void fs_print(register const u_char *bp, int length) { int fs_op; @@ -799,15 +871,16 @@ fs_print(register const u_char *bp, int length) break; case 134: /* Store ACL */ { - char a[AFSOPAQUEMAX]; + char a[AFSOPAQUEMAX+1]; FIDOUT(); - TRUNC(4); + TCHECK2(bp[0], 4); i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); - TRUNC(i); - strncpy(a, (char *) bp, min(AFSOPAQUEMAX, i)); + TCHECK2(bp[0], i); + i = min(AFSOPAQUEMAX, i); + strncpy(a, (char *) bp, i); a[i] = '\0'; - acl_print((u_char *) a, (u_char *) a + i); + acl_print((u_char *) a, sizeof(a), (u_char *) a + i); break; } case 137: /* Create file */ @@ -856,7 +929,7 @@ fs_print(register const u_char *bp, int length) case 155: /* Bulk stat */ { unsigned long j; - TRUNC(4); + TCHECK2(bp[0], 4); j = EXTRACT_32BITS(bp); bp += sizeof(int32_t); @@ -911,14 +984,15 @@ fs_reply_print(register const u_char *bp, int length, int32_t opcode) switch (opcode) { case 131: /* Fetch ACL */ { - char a[AFSOPAQUEMAX]; - TRUNC(4); + char a[AFSOPAQUEMAX+1]; + TCHECK2(bp[0], 4); i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); - TRUNC(i); - strncpy(a, (char *) bp, min(AFSOPAQUEMAX, i)); + TCHECK2(bp[0], i); + i = min(AFSOPAQUEMAX, i); + strncpy(a, (char *) bp, i); a[i] = '\0'; - acl_print((u_char *) a, (u_char *) a + i); + acl_print((u_char *) a, sizeof(a), (u_char *) a + i); break; } case 137: /* Create file */ @@ -942,7 +1016,7 @@ fs_reply_print(register const u_char *bp, int length, int32_t opcode) /* * Otherwise, just print out the return code */ - TRUNC(sizeof(int32_t)); + TCHECK2(bp[0], sizeof(int32_t)); i = (int) EXTRACT_32BITS(bp); bp += sizeof(int32_t); @@ -972,19 +1046,22 @@ trunc: */ static void -acl_print(u_char *s, u_char *end) +acl_print(u_char *s, int maxsize, u_char *end) { int pos, neg, acl; int n, i; - char user[128]; + char *user; - if (sscanf((char *) s, "%d %d\n%n", &pos, &neg, &n) != 2) + if ((user = (char *)malloc(maxsize)) == NULL) return; + + if (sscanf((char *) s, "%d %d\n%n", &pos, &neg, &n) != 2) + goto finish; s += n; if (s > end) - return; + goto finish; /* * This wacky order preserves the order used by the "fs" command @@ -1008,25 +1085,29 @@ acl_print(u_char *s, u_char *end) for (i = 0; i < pos; i++) { if (sscanf((char *) s, "%s %d\n%n", user, &acl, &n) != 2) - return; + goto finish; s += n; printf(" +{%s ", user); ACLOUT(acl); printf("}"); if (s > end) - return; + goto finish; } for (i = 0; i < neg; i++) { if (sscanf((char *) s, "%s %d\n%n", user, &acl, &n) != 2) - return; + goto finish; s += n; printf(" -{%s ", user); ACLOUT(acl); printf("}"); if (s > end) - return; + goto finish; } + +finish: + free(user); + return; } #undef ACLOUT @@ -1068,7 +1149,7 @@ cb_print(register const u_char *bp, int length) case 204: /* Callback */ { unsigned long j, t; - TRUNC(4); + TCHECK2(bp[0], 4); j = EXTRACT_32BITS(bp); bp += sizeof(int32_t); @@ -1092,7 +1173,7 @@ cb_print(register const u_char *bp, int length) INTOUT(); printf(" expires"); DATEOUT(); - TRUNC(4); + TCHECK2(bp[0], 4); t = EXTRACT_32BITS(bp); bp += sizeof(int32_t); tok2str(cb_types, "type %d", t); @@ -1236,7 +1317,7 @@ prot_print(register const u_char *bp, int length) case 504: /* Name to ID */ { unsigned long j; - TRUNC(4); + TCHECK2(bp[0], 4); j = EXTRACT_32BITS(bp); bp += sizeof(int32_t); @@ -1258,7 +1339,7 @@ prot_print(register const u_char *bp, int length) { unsigned long j; printf(" ids:"); - TRUNC(4); + TCHECK2(bp[0], 4); i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); for (j = 0; j < i; j++) @@ -1348,7 +1429,7 @@ prot_reply_print(register const u_char *bp, int length, int32_t opcode) { unsigned long j; printf(" ids:"); - TRUNC(4); + TCHECK2(bp[0], 4); i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); for (j = 0; j < i; j++) @@ -1360,7 +1441,7 @@ prot_reply_print(register const u_char *bp, int length, int32_t opcode) case 505: /* ID to name */ { unsigned long j; - TRUNC(4); + TCHECK2(bp[0], 4); j = EXTRACT_32BITS(bp); bp += sizeof(int32_t); @@ -1385,7 +1466,7 @@ prot_reply_print(register const u_char *bp, int length, int32_t opcode) case 519: /* Get host CPS */ { unsigned long j; - TRUNC(4); + TCHECK2(bp[0], 4); j = EXTRACT_32BITS(bp); bp += sizeof(int32_t); for (i = 0; i < j; i++) { @@ -1470,7 +1551,7 @@ vldb_print(register const u_char *bp, int length) case 518: /* Get entry by ID N */ printf(" volid"); INTOUT(); - TRUNC(sizeof(int32_t)); + TCHECK2(bp[0], sizeof(int32_t)); i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); if (i <= 2) @@ -1490,7 +1571,7 @@ vldb_print(register const u_char *bp, int length) case 520: /* Replace entry N */ printf(" volid"); INTOUT(); - TRUNC(sizeof(int32_t)); + TCHECK2(bp[0], sizeof(int32_t)); i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); if (i <= 2) @@ -1560,16 +1641,16 @@ vldb_reply_print(register const u_char *bp, int length, int32_t opcode) case 504: /* Get entry by name */ { unsigned long nservers, j; VECOUT(VLNAMEMAX); - TRUNC(sizeof(int32_t)); + TCHECK2(bp[0], sizeof(int32_t)); bp += sizeof(int32_t); printf(" numservers"); - TRUNC(sizeof(int32_t)); + TCHECK2(bp[0], sizeof(int32_t)); nservers = EXTRACT_32BITS(bp); bp += sizeof(int32_t); printf(" %lu", nservers); printf(" servers"); for (i = 0; i < 8; i++) { - TRUNC(sizeof(int32_t)); + TCHECK2(bp[0], sizeof(int32_t)); if (i < nservers) printf(" %s", inet_ntoa(*((struct in_addr *) bp))); @@ -1577,7 +1658,7 @@ vldb_reply_print(register const u_char *bp, int length, int32_t opcode) } printf(" partitions"); for (i = 0; i < 8; i++) { - TRUNC(sizeof(int32_t)); + TCHECK2(bp[0], sizeof(int32_t)); j = EXTRACT_32BITS(bp); if (i < nservers && j <= 26) printf(" %c", 'a' + (int)j); @@ -1585,7 +1666,7 @@ vldb_reply_print(register const u_char *bp, int length, int32_t opcode) printf(" %lu", j); bp += sizeof(int32_t); } - TRUNC(8 * sizeof(int32_t)); + TCHECK2(bp[0], 8 * sizeof(int32_t)); bp += 8 * sizeof(int32_t); printf(" rwvol"); UINTOUT(); @@ -1610,13 +1691,13 @@ vldb_reply_print(register const u_char *bp, int length, int32_t opcode) { unsigned long nservers, j; VECOUT(VLNAMEMAX); printf(" numservers"); - TRUNC(sizeof(int32_t)); + TCHECK2(bp[0], sizeof(int32_t)); nservers = EXTRACT_32BITS(bp); bp += sizeof(int32_t); printf(" %lu", nservers); printf(" servers"); for (i = 0; i < 13; i++) { - TRUNC(sizeof(int32_t)); + TCHECK2(bp[0], sizeof(int32_t)); if (i < nservers) printf(" %s", inet_ntoa(*((struct in_addr *) bp))); @@ -1624,7 +1705,7 @@ vldb_reply_print(register const u_char *bp, int length, int32_t opcode) } printf(" partitions"); for (i = 0; i < 13; i++) { - TRUNC(sizeof(int32_t)); + TCHECK2(bp[0], sizeof(int32_t)); j = EXTRACT_32BITS(bp); if (i < nservers && j <= 26) printf(" %c", 'a' + (int)j); @@ -1632,7 +1713,7 @@ vldb_reply_print(register const u_char *bp, int length, int32_t opcode) printf(" %lu", j); bp += sizeof(int32_t); } - TRUNC(13 * sizeof(int32_t)); + TCHECK2(bp[0], 13 * sizeof(int32_t)); bp += 13 * sizeof(int32_t); printf(" rwvol"); UINTOUT(); @@ -1647,7 +1728,7 @@ vldb_reply_print(register const u_char *bp, int length, int32_t opcode) { unsigned long nservers, j; VECOUT(VLNAMEMAX); printf(" numservers"); - TRUNC(sizeof(int32_t)); + TCHECK2(bp[0], sizeof(int32_t)); nservers = EXTRACT_32BITS(bp); bp += sizeof(int32_t); printf(" %lu", nservers); @@ -1657,15 +1738,15 @@ vldb_reply_print(register const u_char *bp, int length, int32_t opcode) printf(" afsuuid"); AFSUUIDOUT(); } else { - TRUNC(44); + TCHECK2(bp[0], 44); bp += 44; } } - TRUNC(4 * 13); + TCHECK2(bp[0], 4 * 13); bp += 4 * 13; printf(" partitions"); for (i = 0; i < 13; i++) { - TRUNC(sizeof(int32_t)); + TCHECK2(bp[0], sizeof(int32_t)); j = EXTRACT_32BITS(bp); if (i < nservers && j <= 26) printf(" %c", 'a' + (int)j); @@ -1673,7 +1754,7 @@ vldb_reply_print(register const u_char *bp, int length, int32_t opcode) printf(" %lu", j); bp += sizeof(int32_t); } - TRUNC(13 * sizeof(int32_t)); + TCHECK2(bp[0], 13 * sizeof(int32_t)); bp += 13 * sizeof(int32_t); printf(" rwvol"); UINTOUT(); @@ -1763,10 +1844,10 @@ kauth_print(register const u_char *bp, int length) INTOUT(); printf(" domain"); STROUT(KANAMEMAX); - TRUNC(sizeof(int32_t)); + TCHECK2(bp[0], sizeof(int32_t)); i = (int) EXTRACT_32BITS(bp); bp += sizeof(int32_t); - TRUNC(i); + TCHECK2(bp[0], i); bp += i; printf(" principal"); STROUT(KANAMEMAX); @@ -2104,7 +2185,7 @@ ubik_print(register const u_char *bp, int length) switch (ubik_op) { case 10000: /* Beacon */ - TRUNC(4); + TCHECK2(bp[0], 4); temp = EXTRACT_32BITS(bp); bp += sizeof(int32_t); printf(" syncsite %s", temp ? "yes" : "no"); @@ -2253,7 +2334,7 @@ trunc: * Handle RX ACK packets. */ -void +static void rx_ack_print(register const u_char *bp, int length) { struct rx_ackPacket *rxa; @@ -2272,7 +2353,7 @@ rx_ack_print(register const u_char *bp, int length) * rx_ackPacket structure. */ - TRUNC(sizeof(struct rx_ackPacket) - RX_MAXACKS); + TCHECK2(bp[0], sizeof(struct rx_ackPacket) - RX_MAXACKS); rxa = (struct rx_ackPacket *) bp; bp += (sizeof(struct rx_ackPacket) - RX_MAXACKS); @@ -2311,7 +2392,7 @@ rx_ack_print(register const u_char *bp, int length) if (rxa->nAcks != 0) { - TRUNC(rxa->nAcks); + TCHECK2(bp[0], rxa->nAcks); /* * Sigh, this is gross, but it seems to work to collapse