X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/842143f7164cee0ca36df40412a6802f0b8e7b71..64e81f2917f6865dff8df96e18cec1b8bf2fa836:/print-rx.c diff --git a/print-rx.c b/print-rx.c index 957b3b12..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.8 2000-02-08 20:57:07 kenh 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,14 +21,14 @@ static const char rcsid[] = #endif #include +#include #include +#include #include #include #include #include #include -#include -#include #include #include "interface.h" @@ -40,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" }, @@ -373,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); @@ -417,28 +420,35 @@ rx_print(register const u_char *bp, int length, int sport, int dport, printf(" rx %s", tok2str(rx_types, "type %d", rxh->type)); - if (vflag > 1) { + if (vflag) { int firstflag = 0; - printf(" cid %08x call# %d seq %d ser %d", - (int) EXTRACT_32BITS(&rxh->cid), - (int) EXTRACT_32BITS(&rxh->callNumber), + + if (vflag > 1) + printf(" cid %08x call# %d", + (int) EXTRACT_32BITS(&rxh->cid), + (int) EXTRACT_32BITS(&rxh->callNumber)); + + printf(" seq %d ser %d", (int) EXTRACT_32BITS(&rxh->seq), (int) EXTRACT_32BITS(&rxh->serial)); + if (vflag > 2) printf(" secindex %d serviceid %hu", (int) rxh->securityIndex, EXTRACT_16BITS(&rxh->serviceId)); - for (i = 0; i < NUM_RX_FLAGS; i++) { - if (rxh->flags & rx_flags[i].v) { - if (!firstflag) { - firstflag = 1; - printf(" "); - } else { - printf(","); + + if (vflag > 1) + for (i = 0; i < NUM_RX_FLAGS; i++) { + if (rxh->flags & rx_flags[i].v) { + if (!firstflag) { + firstflag = 1; + printf(" "); + } else { + printf(","); + } + printf("<%s>", rx_flags[i].s); } - printf("<%s>", rx_flags[i].s); } - } } /* @@ -450,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) { @@ -612,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); \ @@ -625,32 +636,32 @@ 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); \ - strncpy(s, bp, min(MAX, i)); \ + TCHECK2(bp[0], i); \ + strncpy(s, (char *) bp, min(MAX, i)); \ s[i] = '\0'; \ printf(" \"%s\"", s); \ bp += ((i + sizeof(int32_t) - 1) / sizeof(int32_t)) * sizeof(int32_t); \ } #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); \ @@ -659,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(); } \ @@ -677,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); \ @@ -686,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); \ @@ -709,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); \ @@ -719,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; @@ -791,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, 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 */ @@ -848,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); @@ -903,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, 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 */ @@ -934,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); @@ -964,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 @@ -1000,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 @@ -1060,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); @@ -1084,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); @@ -1228,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); @@ -1250,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++) @@ -1340,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++) @@ -1352,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); @@ -1377,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++) { @@ -1462,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) @@ -1482,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) @@ -1552,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))); @@ -1569,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); @@ -1577,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(); @@ -1602,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))); @@ -1616,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); @@ -1624,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(); @@ -1639,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); @@ -1649,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); @@ -1665,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(); @@ -1755,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); @@ -2096,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"); @@ -2245,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; @@ -2264,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); @@ -2303,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 @@ -2357,9 +2446,11 @@ rx_ack_print(register const u_char *bp, int length) * the _previous_ packet number seperated * from the first by a dash (-). Since we * already printed the first packet above, - * just print the final packet. + * just print the final packet. Don't + * do this if there will be a single-length + * range. */ - } else if (last == i - 1) + } else if (last == i - 1 && start != last) printf("-%d", rxa->firstPacket + i - 1); /* @@ -2391,7 +2482,7 @@ rx_ack_print(register const u_char *bp, int length) start = i; } last = i; - } else if (last == i - 1) + } else if (last == i - 1 && start != last) printf("-%d", rxa->firstPacket + i - 1); if (last == i - 1 && start != last)