summaryrefslogtreecommitdiffstats
path: root/contrib/tcpdump/print-rx.c
diff options
context:
space:
mode:
authorfenner <fenner@FreeBSD.org>2001-04-03 07:45:48 +0000
committerfenner <fenner@FreeBSD.org>2001-04-03 07:45:48 +0000
commitace14a2b50f2cc05c079d0b9137b49066dbb1206 (patch)
tree4953fdd47c44b8ec88d34a4db7b698841365e22f /contrib/tcpdump/print-rx.c
parent54c4a9c9f2aca2e032cbf41f5eb012e2e9628dd4 (diff)
downloadFreeBSD-src-ace14a2b50f2cc05c079d0b9137b49066dbb1206.zip
FreeBSD-src-ace14a2b50f2cc05c079d0b9137b49066dbb1206.tar.gz
Virgin import of tcpdump.org tcpdump v3.6.2
Diffstat (limited to 'contrib/tcpdump/print-rx.c')
-rw-r--r--contrib/tcpdump/print-rx.c611
1 files changed, 473 insertions, 138 deletions
diff --git a/contrib/tcpdump/print-rx.c b/contrib/tcpdump/print-rx.c
index 5f42ce7..aa36124 100644
--- a/contrib/tcpdump/print-rx.c
+++ b/contrib/tcpdump/print-rx.c
@@ -13,7 +13,7 @@
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/tcpdump/print-rx.c,v 1.5.2.1 2000/01/11 06:58:27 fenner 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,24 +21,27 @@ static const char rcsid[] =
#endif
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
+#include <time.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
#include <arpa/inet.h>
#include "interface.h"
#include "addrtoname.h"
+#include "extract.h"
#undef NOERROR /* Solaris sucks */
#include <arpa/nameser.h>
#include "rx.h"
+#include "ip.h"
+
static struct tok rx_types[] = {
{ RX_PACKET_TYPE_DATA, "data" },
{ RX_PACKET_TYPE_ACK, "ack" },
@@ -315,6 +318,39 @@ static struct tok ubik_lock_types[] = {
static char *voltype[] = { "read-write", "read-only", "backup" };
+static struct tok afs_fs_errors[] = {
+ { 101, "salvage volume" },
+ { 102, "no such vnode" },
+ { 103, "no such volume" },
+ { 104, "volume exist" },
+ { 105, "no service" },
+ { 106, "volume offline" },
+ { 107, "voline online" },
+ { 108, "diskfull" },
+ { 109, "diskquota exceeded" },
+ { 110, "volume busy" },
+ { 111, "volume moved" },
+ { 112, "AFS IO error" },
+ { -100, "restarting fileserver" },
+ { 0, NULL }
+};
+
+/*
+ * Reasons for acknowledging a packet
+ */
+
+static struct tok rx_ack_reasons[] = {
+ { 1, "ack requested" },
+ { 2, "duplicate packet" },
+ { 3, "out of sequence" },
+ { 4, "exceeds window" },
+ { 5, "no buffer space" },
+ { 6, "ping" },
+ { 7, "ping response" },
+ { 8, "delay" },
+ { 0, NULL },
+};
+
/*
* Cache entries we keep around so we can figure out the RX opcode
* numbers for replies. This allows us to make sense of RX reply packets.
@@ -339,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);
@@ -357,6 +394,8 @@ static void bos_reply_print(const u_char *, int, int32_t);
static void ubik_print(const u_char *, int);
static void ubik_reply_print(const u_char *, int, int32_t);
+static void rx_ack_print(const u_char *, int);
+
static int is_ubik(u_int32_t);
/*
@@ -381,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) ntohl(rxh->cid),
- (int) ntohl(rxh->callNumber),
- (int) ntohl(rxh->seq),
- (int) ntohl(rxh->serial));
+
+ 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,
- ntohs(rxh->serviceId));
- for (i = 0; i < NUM_RX_FLAGS; i++) {
- if (rxh->flags & rx_flags[i].v) {
- if (!firstflag) {
- firstflag = 1;
- printf(" ");
- } else {
- printf(",");
+ EXTRACT_16BITS(&rxh->serviceId));
+
+ 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);
}
- }
}
/*
@@ -414,7 +460,10 @@ rx_print(register const u_char *bp, int length, int sport, int dport,
* as well.
*/
- if (rxh->type == RX_PACKET_TYPE_DATA && ntohl(rxh->seq) == 1 &&
+ 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) {
/*
@@ -458,7 +507,7 @@ rx_print(register const u_char *bp, int length, int sport, int dport,
*/
} else if (((rxh->type == RX_PACKET_TYPE_DATA &&
- ntohl(rxh->seq) == 1) ||
+ EXTRACT_32BITS(&rxh->seq) == 1) ||
rxh->type == RX_PACKET_TYPE_ABORT) &&
(rxh->flags & RX_CLIENT_INITIATED) == 0 &&
rx_cache_find(rxh, (const struct ip *) bp2,
@@ -489,7 +538,15 @@ rx_print(register const u_char *bp, int length, int sport, int dport,
default:
;
}
- }
+
+ /*
+ * If it's an RX ack packet, then use the appropriate ack decoding
+ * function (there isn't any service-specific information in the
+ * ack packet, so we can use one for all AFS services)
+ */
+
+ } else if (rxh->type == RX_PACKET_TYPE_ACK)
+ rx_ack_print(bp, length);
printf(" (%d)", length);
@@ -519,7 +576,7 @@ rx_cache_insert(const u_char *bp, const struct ip *ip, int dport,
rxent->server = ip->ip_dst;
rxent->dport = dport;
rxent->serviceId = rxh->serviceId;
- rxent->opcode = ntohl(*((int *) (bp + sizeof(struct rx_header))));
+ rxent->opcode = EXTRACT_32BITS(bp + sizeof(struct rx_header));
}
/*
@@ -567,46 +624,45 @@ 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); \
- n1 = ntohl(*((int *) bp)); \
+ TCHECK2(bp[0], sizeof(int32_t) * 3); \
+ n1 = EXTRACT_32BITS(bp); \
bp += sizeof(int32_t); \
- n2 = ntohl(*((int *) bp)); \
+ n2 = EXTRACT_32BITS(bp); \
bp += sizeof(int32_t); \
- n3 = ntohl(*((int *) bp)); \
+ n3 = EXTRACT_32BITS(bp); \
bp += sizeof(int32_t); \
printf(" fid %d/%d/%d", (int) n1, (int) n2, (int) n3); \
}
#define STROUT(MAX) { int i; \
- TRUNC(sizeof(int32_t)); \
- i = (int) ntohl(*((int *) bp)); \
+ 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)); \
- i = (int) ntohl(*((int *) bp)); \
+ 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)); \
- i = ntohl(*((int *) bp)); \
+ 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)); \
- t = (time_t) ntohl(*((int *) bp)); \
+ TCHECK2(bp[0], sizeof(int32_t)); \
+ t = (time_t) EXTRACT_32BITS(bp); \
bp += sizeof(int32_t); \
tm = localtime(&t); \
strftime(str, 256, "%Y/%m/%d %T", tm); \
@@ -614,45 +670,45 @@ 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)); \
- mask = ntohl(*((int *) bp)); bp += sizeof(int32_t); \
+ 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(); } \
else bp += sizeof(int32_t); \
- i = ntohl(*((int *) bp)); bp += sizeof(int32_t); \
+ i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \
if (mask & 2) printf(" owner %lu", i); \
- i = ntohl(*((int32_t *) bp)); bp += sizeof(int32_t); \
+ i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \
if (mask & 4) printf(" group %lu", i); \
- i = ntohl(*((int32_t *) bp)); bp += sizeof(int32_t); \
+ i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \
if (mask & 8) printf(" mode %lo", i & 07777); \
- i = ntohl(*((int32_t *) bp)); bp += sizeof(int32_t); \
+ i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \
if (mask & 16) printf(" segsize %lu", i); \
/* undocumented in 3.3 docu */ \
if (mask & 1024) printf(" fsync"); \
}
#define UBIK_VERSIONOUT() {int32_t epoch; int32_t counter; \
- TRUNC(sizeof(int32_t) * 2); \
- epoch = ntohl(*((int *) bp)); \
+ TCHECK2(bp[0], sizeof(int32_t) * 2); \
+ epoch = EXTRACT_32BITS(bp); \
bp += sizeof(int32_t); \
- counter = ntohl(*((int *) bp)); \
+ counter = EXTRACT_32BITS(bp); \
bp += sizeof(int32_t); \
printf(" %d.%d", epoch, counter); \
}
#define AFSUUIDOUT() {u_int32_t temp; int i; \
- TRUNC(11*sizeof(u_int32_t)); \
- temp = ntohl(*((int *) bp)); \
+ TCHECK2(bp[0], 11*sizeof(u_int32_t)); \
+ temp = EXTRACT_32BITS(bp); \
bp += sizeof(u_int32_t); \
printf(" %08x", temp); \
- temp = ntohl(*((int *) bp)); \
+ temp = EXTRACT_32BITS(bp); \
bp += sizeof(u_int32_t); \
printf("%04x", temp); \
- temp = ntohl(*((int *) bp)); \
+ temp = EXTRACT_32BITS(bp); \
bp += sizeof(u_int32_t); \
printf("%04x", temp); \
for (i = 0; i < 8; i++) { \
- temp = ntohl(*((int *) bp)); \
+ temp = EXTRACT_32BITS(bp); \
bp += sizeof(u_int32_t); \
printf("%02x", (unsigned char) temp); \
} \
@@ -664,21 +720,90 @@ 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) ntohl(*((int *) bp)); \
+ *sp++ = (char) EXTRACT_32BITS(bp); \
bp += sizeof(int32_t); \
} \
s[MAX] = '\0'; \
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;
@@ -697,7 +822,7 @@ fs_print(register const u_char *bp, int length)
* gleaned from fsint/afsint.xg
*/
- fs_op = ntohl(*((int *) (bp + sizeof(struct rx_header))));
+ fs_op = EXTRACT_32BITS(bp + sizeof(struct rx_header));
printf(" fs call %s", tok2str(fs_req, "op#%d", fs_op));
@@ -746,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);
- i = ntohl(*((int *) bp));
+ 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 */
@@ -803,8 +929,8 @@ fs_print(register const u_char *bp, int length)
case 155: /* Bulk stat */
{
unsigned long j;
- TRUNC(4);
- j = ntohl(*((int *) bp));
+ TCHECK2(bp[0], 4);
+ j = EXTRACT_32BITS(bp);
bp += sizeof(int32_t);
for (i = 0; i < j; i++) {
@@ -854,18 +980,19 @@ fs_reply_print(register const u_char *bp, int length, int32_t opcode)
* If it was a data packet, interpret the response
*/
- if (rxh->type == RX_PACKET_TYPE_DATA)
+ if (rxh->type == RX_PACKET_TYPE_DATA) {
switch (opcode) {
case 131: /* Fetch ACL */
{
- char a[AFSOPAQUEMAX];
- TRUNC(4);
- i = ntohl(*((int *) bp));
+ 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 */
@@ -883,12 +1010,19 @@ fs_reply_print(register const u_char *bp, int length, int32_t opcode)
default:
;
}
- else {
- /*
- * Otherwise, just print out the return code
- */
- printf(" errcode");
- INTOUT();
+ } else if (rxh->type == RX_PACKET_TYPE_ABORT) {
+ int i;
+
+ /*
+ * Otherwise, just print out the return code
+ */
+ TCHECK2(bp[0], sizeof(int32_t));
+ i = (int) EXTRACT_32BITS(bp);
+ bp += sizeof(int32_t);
+
+ printf(" error %s", tok2str(afs_fs_errors, "#%d", i));
+ } else {
+ printf(" strange fs reply of type %d", rxh->type);
}
return;
@@ -912,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
@@ -948,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
@@ -993,7 +1134,7 @@ cb_print(register const u_char *bp, int length)
* gleaned from fsint/afscbint.xg
*/
- cb_op = ntohl(*((int *) (bp + sizeof(struct rx_header))));
+ cb_op = EXTRACT_32BITS(bp + sizeof(struct rx_header));
printf(" cb call %s", tok2str(cb_req, "op#%d", cb_op));
@@ -1008,8 +1149,8 @@ cb_print(register const u_char *bp, int length)
case 204: /* Callback */
{
unsigned long j, t;
- TRUNC(4);
- j = ntohl(*((int *) bp));
+ TCHECK2(bp[0], 4);
+ j = EXTRACT_32BITS(bp);
bp += sizeof(int32_t);
for (i = 0; i < j; i++) {
@@ -1021,7 +1162,7 @@ cb_print(register const u_char *bp, int length)
if (j == 0)
printf(" <none!>");
- j = ntohl(*((int *) bp));
+ j = EXTRACT_32BITS(bp);
bp += sizeof(int32_t);
if (j != 0)
@@ -1032,8 +1173,8 @@ cb_print(register const u_char *bp, int length)
INTOUT();
printf(" expires");
DATEOUT();
- TRUNC(4);
- t = ntohl(*((int *) bp));
+ TCHECK2(bp[0], 4);
+ t = EXTRACT_32BITS(bp);
bp += sizeof(int32_t);
tok2str(cb_types, "type %d", t);
}
@@ -1125,7 +1266,7 @@ prot_print(register const u_char *bp, int length)
* gleaned from ptserver/ptint.xg
*/
- pt_op = ntohl(*((int *) (bp + sizeof(struct rx_header))));
+ pt_op = EXTRACT_32BITS(bp + sizeof(struct rx_header));
printf(" pt");
@@ -1176,8 +1317,8 @@ prot_print(register const u_char *bp, int length)
case 504: /* Name to ID */
{
unsigned long j;
- TRUNC(4);
- j = ntohl(*((int *) bp));
+ TCHECK2(bp[0], 4);
+ j = EXTRACT_32BITS(bp);
bp += sizeof(int32_t);
/*
@@ -1198,8 +1339,8 @@ prot_print(register const u_char *bp, int length)
{
unsigned long j;
printf(" ids:");
- TRUNC(4);
- i = ntohl(*((int *) bp));
+ TCHECK2(bp[0], 4);
+ i = EXTRACT_32BITS(bp);
bp += sizeof(int32_t);
for (j = 0; j < i; j++)
INTOUT();
@@ -1288,8 +1429,8 @@ prot_reply_print(register const u_char *bp, int length, int32_t opcode)
{
unsigned long j;
printf(" ids:");
- TRUNC(4);
- i = ntohl(*((int *) bp));
+ TCHECK2(bp[0], 4);
+ i = EXTRACT_32BITS(bp);
bp += sizeof(int32_t);
for (j = 0; j < i; j++)
INTOUT();
@@ -1300,8 +1441,8 @@ prot_reply_print(register const u_char *bp, int length, int32_t opcode)
case 505: /* ID to name */
{
unsigned long j;
- TRUNC(4);
- j = ntohl(*((int *) bp));
+ TCHECK2(bp[0], 4);
+ j = EXTRACT_32BITS(bp);
bp += sizeof(int32_t);
/*
@@ -1325,8 +1466,8 @@ prot_reply_print(register const u_char *bp, int length, int32_t opcode)
case 519: /* Get host CPS */
{
unsigned long j;
- TRUNC(4);
- j = ntohl(*((int *) bp));
+ TCHECK2(bp[0], 4);
+ j = EXTRACT_32BITS(bp);
bp += sizeof(int32_t);
for (i = 0; i < j; i++) {
INTOUT();
@@ -1381,7 +1522,7 @@ vldb_print(register const u_char *bp, int length)
* gleaned from vlserver/vldbint.xg
*/
- vldb_op = ntohl(*((int *) (bp + sizeof(struct rx_header))));
+ vldb_op = EXTRACT_32BITS(bp + sizeof(struct rx_header));
printf(" vldb");
@@ -1410,8 +1551,8 @@ vldb_print(register const u_char *bp, int length)
case 518: /* Get entry by ID N */
printf(" volid");
INTOUT();
- TRUNC(sizeof(int32_t));
- i = ntohl(*((int *) bp));
+ TCHECK2(bp[0], sizeof(int32_t));
+ i = EXTRACT_32BITS(bp);
bp += sizeof(int32_t);
if (i <= 2)
printf(" type %s", voltype[i]);
@@ -1430,8 +1571,8 @@ vldb_print(register const u_char *bp, int length)
case 520: /* Replace entry N */
printf(" volid");
INTOUT();
- TRUNC(sizeof(int32_t));
- i = ntohl(*((int *) bp));
+ TCHECK2(bp[0], sizeof(int32_t));
+ i = EXTRACT_32BITS(bp);
bp += sizeof(int32_t);
if (i <= 2)
printf(" type %s", voltype[i]);
@@ -1500,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));
- nservers = ntohl(*((int *) bp));
+ 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)));
@@ -1517,15 +1658,15 @@ 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));
- j = ntohl(*((int *) bp));
+ TCHECK2(bp[0], sizeof(int32_t));
+ j = EXTRACT_32BITS(bp);
if (i < nservers && j <= 26)
printf(" %c", 'a' + (int)j);
else if (i < nservers)
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();
@@ -1550,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));
- nservers = ntohl(*((int *) bp));
+ 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)));
@@ -1564,15 +1705,15 @@ 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));
- j = ntohl(*((int *) bp));
+ TCHECK2(bp[0], sizeof(int32_t));
+ j = EXTRACT_32BITS(bp);
if (i < nservers && j <= 26)
printf(" %c", 'a' + (int)j);
else if (i < nservers)
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();
@@ -1587,8 +1728,8 @@ 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));
- nservers = ntohl(*((int *) bp));
+ TCHECK2(bp[0], sizeof(int32_t));
+ nservers = EXTRACT_32BITS(bp);
bp += sizeof(int32_t);
printf(" %lu", nservers);
printf(" servers");
@@ -1597,23 +1738,23 @@ 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));
- j = ntohl(*((int *) bp));
+ TCHECK2(bp[0], sizeof(int32_t));
+ j = EXTRACT_32BITS(bp);
if (i < nservers && j <= 26)
printf(" %c", 'a' + (int)j);
else if (i < nservers)
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();
@@ -1662,7 +1803,7 @@ kauth_print(register const u_char *bp, int length)
* gleaned from kauth/kauth.rg
*/
- kauth_op = ntohl(*((int *) (bp + sizeof(struct rx_header))));
+ kauth_op = EXTRACT_32BITS(bp + sizeof(struct rx_header));
printf(" kauth");
@@ -1703,10 +1844,10 @@ kauth_print(register const u_char *bp, int length)
INTOUT();
printf(" domain");
STROUT(KANAMEMAX);
- TRUNC(sizeof(int32_t));
- i = (int) ntohl(*((int *) bp));
+ 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);
@@ -1806,7 +1947,7 @@ vol_print(register const u_char *bp, int length)
* gleaned from volser/volint.xg
*/
- vol_op = ntohl(*((int *) (bp + sizeof(struct rx_header))));
+ vol_op = EXTRACT_32BITS(bp + sizeof(struct rx_header));
printf(" vol call %s", tok2str(vol_req, "op#%d", vol_op));
@@ -1889,7 +2030,7 @@ bos_print(register const u_char *bp, int length)
* gleaned from bozo/bosint.xg
*/
- bos_op = ntohl(*((int *) (bp + sizeof(struct rx_header))));
+ bos_op = EXTRACT_32BITS(bp + sizeof(struct rx_header));
printf(" bos call %s", tok2str(bos_req, "op#%d", bos_op));
@@ -2032,7 +2173,7 @@ ubik_print(register const u_char *bp, int length)
* gleaned from ubik/ubik_int.xg
*/
- ubik_op = ntohl(*((int *) (bp + sizeof(struct rx_header))));
+ ubik_op = EXTRACT_32BITS(bp + sizeof(struct rx_header));
printf(" ubik call %s", tok2str(ubik_req, "op#%d", ubik_op));
@@ -2044,8 +2185,8 @@ ubik_print(register const u_char *bp, int length)
switch (ubik_op) {
case 10000: /* Beacon */
- TRUNC(4);
- temp = ntohl(*((int *) bp));
+ TCHECK2(bp[0], 4);
+ temp = EXTRACT_32BITS(bp);
bp += sizeof(int32_t);
printf(" syncsite %s", temp ? "yes" : "no");
printf(" votestart");
@@ -2076,7 +2217,7 @@ ubik_print(register const u_char *bp, int length)
INTOUT();
printf(" length");
INTOUT();
- temp = ntohl(*((int *) bp));
+ temp = EXTRACT_32BITS(bp);
bp += sizeof(int32_t);
tok2str(ubik_lock_types, "type %d", temp);
break;
@@ -2188,3 +2329,197 @@ ubik_reply_print(register const u_char *bp, int length, int32_t opcode)
trunc:
printf(" [|ubik]");
}
+
+/*
+ * Handle RX ACK packets.
+ */
+
+static void
+rx_ack_print(register const u_char *bp, int length)
+{
+ struct rx_ackPacket *rxa;
+ int i, start, last;
+
+ if (length < sizeof(struct rx_header))
+ return;
+
+ bp += sizeof(struct rx_header);
+
+ /*
+ * This may seem a little odd .... the rx_ackPacket structure
+ * contains an array of individual packet acknowledgements
+ * (used for selective ack/nack), but since it's variable in size,
+ * we don't want to truncate based on the size of the whole
+ * rx_ackPacket structure.
+ */
+
+ TCHECK2(bp[0], sizeof(struct rx_ackPacket) - RX_MAXACKS);
+
+ rxa = (struct rx_ackPacket *) bp;
+ bp += (sizeof(struct rx_ackPacket) - RX_MAXACKS);
+
+ /*
+ * Print out a few useful things from the ack packet structure
+ */
+
+ if (vflag > 2)
+ printf(" bufspace %d maxskew %d",
+ (int) EXTRACT_16BITS(&rxa->bufferSpace),
+ (int) EXTRACT_16BITS(&rxa->maxSkew));
+
+ printf(" first %d serial %d reason %s",
+ EXTRACT_32BITS(&rxa->firstPacket), EXTRACT_32BITS(&rxa->serial),
+ tok2str(rx_ack_reasons, "#%d", (int) rxa->reason));
+
+ /*
+ * Okay, now we print out the ack array. The way _this_ works
+ * is that we start at "first", and step through the ack array.
+ * If we have a contiguous range of acks/nacks, try to
+ * collapse them into a range.
+ *
+ * If you're really clever, you might have noticed that this
+ * doesn't seem quite correct. Specifically, due to structure
+ * padding, sizeof(struct rx_ackPacket) - RX_MAXACKS won't actually
+ * yield the start of the ack array (because RX_MAXACKS is 255
+ * and the structure will likely get padded to a 2 or 4 byte
+ * boundary). However, this is the way it's implemented inside
+ * of AFS - the start of the extra fields are at
+ * sizeof(struct rx_ackPacket) - RX_MAXACKS + nAcks, which _isn't_
+ * the exact start of the ack array. Sigh. That's why we aren't
+ * using bp, but instead use rxa->acks[]. But nAcks gets added
+ * to bp after this, so bp ends up at the right spot. Go figure.
+ */
+
+ if (rxa->nAcks != 0) {
+
+ TCHECK2(bp[0], rxa->nAcks);
+
+ /*
+ * Sigh, this is gross, but it seems to work to collapse
+ * ranges correctly.
+ */
+
+ for (i = 0, start = last = -2; i < rxa->nAcks; i++)
+ if (rxa->acks[i] == RX_ACK_TYPE_ACK) {
+
+ /*
+ * I figured this deserved _some_ explanation.
+ * First, print "acked" and the packet seq
+ * number if this is the first time we've
+ * seen an acked packet.
+ */
+
+ if (last == -2) {
+ printf(" acked %d",
+ rxa->firstPacket + i);
+ start = i;
+ }
+
+ /*
+ * Otherwise, if the there is a skip in
+ * the range (such as an nacked packet in
+ * the middle of some acked packets),
+ * then print the current packet number
+ * seperated from the last number by
+ * a comma.
+ */
+
+ else if (last != i - 1) {
+ printf(",%d", rxa->firstPacket + i);
+ start = i;
+ }
+
+ /*
+ * We always set last to the value of
+ * the last ack we saw. Conversely, start
+ * is set to the value of the first ack
+ * we saw in a range.
+ */
+
+ last = i;
+
+ /*
+ * Okay, this bit a code gets executed when
+ * we hit a nack ... in _this_ case we
+ * want to print out the range of packets
+ * that were acked, so we need to print
+ * the _previous_ packet number seperated
+ * from the first by a dash (-). Since we
+ * already printed the first packet above,
+ * just print the final packet. Don't
+ * do this if there will be a single-length
+ * range.
+ */
+ } else if (last == i - 1 && start != last)
+ printf("-%d", rxa->firstPacket + i - 1);
+
+ /*
+ * So, what's going on here? We ran off the end of the
+ * ack list, and if we got a range we need to finish it up.
+ * So we need to determine if the last packet in the list
+ * was an ack (if so, then last will be set to it) and
+ * we need to see if the last range didn't start with the
+ * last packet (because if it _did_, then that would mean
+ * that the packet number has already been printed and
+ * we don't need to print it again).
+ */
+
+ if (last == i - 1 && start != last)
+ printf("-%d", rxa->firstPacket + i - 1);
+
+ /*
+ * Same as above, just without comments
+ */
+
+ for (i = 0, start = last = -2; i < rxa->nAcks; i++)
+ if (rxa->acks[i] == RX_ACK_TYPE_NACK) {
+ if (last == -2) {
+ printf(" nacked %d",
+ rxa->firstPacket + i);
+ start = i;
+ } else if (last != i - 1) {
+ printf(",%d", rxa->firstPacket + i);
+ start = i;
+ }
+ last = i;
+ } else if (last == i - 1 && start != last)
+ printf("-%d", rxa->firstPacket + i - 1);
+
+ if (last == i - 1 && start != last)
+ printf("-%d", rxa->firstPacket + i - 1);
+
+ bp += rxa->nAcks;
+ }
+
+
+ /*
+ * These are optional fields; depending on your version of AFS,
+ * you may or may not see them
+ */
+
+#define TRUNCRET(n) if (snapend - bp + 1 <= n) return;
+
+ if (vflag > 1) {
+ TRUNCRET(4);
+ printf(" ifmtu");
+ INTOUT();
+
+ TRUNCRET(4);
+ printf(" maxmtu");
+ INTOUT();
+
+ TRUNCRET(4);
+ printf(" rwind");
+ INTOUT();
+
+ TRUNCRET(4);
+ printf(" maxpackets");
+ INTOUT();
+ }
+
+ return;
+
+trunc:
+ printf(" [|ack]");
+}
+#undef TRUNCRET
OpenPOWER on IntegriCloud