X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/c1c3c77463d592cc576eaa491e604752044ca55a..12f66f69f7bf1ec1266ddbee90a7616cbf33696b:/print-rx.c diff --git a/print-rx.c b/print-rx.c index 9657d2bf..0d3cd375 100644 --- a/print-rx.c +++ b/print-rx.c @@ -20,6 +20,9 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ + +/* \summary: AFS RX printer */ + /* * This code unmangles RX packets. RX is the mutant form of RPC that AFS * uses to communicate between clients and servers. @@ -39,7 +42,7 @@ #include #include #include -#include +#include #include "netdissect.h" #include "addrtoname.h" @@ -72,12 +75,12 @@ #define PRSFS_ADMINISTER 64 /* Change ACL's */ struct rx_header { - uint32_t epoch; - uint32_t cid; - uint32_t callNumber; - uint32_t seq; - uint32_t serial; - uint8_t type; + nd_uint32_t epoch; + nd_uint32_t cid; + nd_uint32_t callNumber; + nd_uint32_t seq; + nd_uint32_t serial; + nd_uint8_t type; #define RX_PACKET_TYPE_DATA 1 #define RX_PACKET_TYPE_ACK 2 #define RX_PACKET_TYPE_BUSY 3 @@ -88,7 +91,7 @@ struct rx_header { #define RX_PACKET_TYPE_DEBUG 8 #define RX_PACKET_TYPE_PARAMS 9 #define RX_PACKET_TYPE_VERSION 13 - uint8_t flags; + nd_uint8_t flags; #define RX_CLIENT_INITIATED 1 #define RX_REQUEST_ACK 2 #define RX_LAST_PACKET 4 @@ -96,10 +99,10 @@ struct rx_header { #define RX_FREE_PACKET 16 #define RX_SLOW_START_OK 32 #define RX_JUMBO_PACKET 32 - uint8_t userStatus; - uint8_t securityIndex; - uint16_t spare; /* How clever: even though the AFS */ - uint16_t serviceId; /* header files indicate that the */ + nd_uint8_t userStatus; + nd_uint8_t securityIndex; + nd_uint16_t spare; /* How clever: even though the AFS */ + nd_uint16_t serviceId; /* header files indicate that the */ }; /* serviceId is first, it's really */ /* encoded _after_ the spare field */ /* I wasted a day figuring that out! */ @@ -687,11 +690,11 @@ rx_cache_insert(netdissect_options *ndo, if (++rx_cache_next >= RX_CACHE_SIZE) rx_cache_next = 0; - rxent->callnum = rxh->callNumber; - rxent->client = ip->ip_src; - rxent->server = ip->ip_dst; + rxent->callnum = EXTRACT_32BITS(&rxh->callNumber); + UNALIGNED_MEMCPY(&rxent->client, &ip->ip_src, sizeof(uint32_t)); + UNALIGNED_MEMCPY(&rxent->server, &ip->ip_dst, sizeof(uint32_t)); rxent->dport = dport; - rxent->serviceId = rxh->serviceId; + rxent->serviceId = EXTRACT_32BITS(&rxh->serviceId); rxent->opcode = EXTRACT_32BITS(bp + sizeof(struct rx_header)); } @@ -708,18 +711,21 @@ rx_cache_find(const struct rx_header *rxh, const struct ip *ip, int sport, { int i; struct rx_cache_entry *rxent; - uint32_t clip = ip->ip_dst.s_addr; - uint32_t sip = ip->ip_src.s_addr; + uint32_t clip; + uint32_t sip; + + UNALIGNED_MEMCPY(&clip, &ip->ip_dst, sizeof(uint32_t)); + UNALIGNED_MEMCPY(&sip, &ip->ip_src, sizeof(uint32_t)); /* Start the search where we last left off */ i = rx_cache_hint; do { rxent = &rx_cache[i]; - if (rxent->callnum == rxh->callNumber && + if (rxent->callnum == EXTRACT_32BITS(&rxh->callNumber) && rxent->client.s_addr == clip && rxent->server.s_addr == sip && - rxent->serviceId == rxh->serviceId && + rxent->serviceId == EXTRACT_32BITS(&rxh->serviceId) && rxent->dport == sport) { /* We got a match! */ @@ -1013,6 +1019,7 @@ fs_print(netdissect_options *ndo, } if (j == 0) ND_PRINT((ndo, " ")); + break; } case 65537: /* Fetch data 64 */ FIDOUT(); @@ -1256,6 +1263,7 @@ cb_print(netdissect_options *ndo, if (j == 0) ND_PRINT((ndo, " ")); + ND_TCHECK_32BITS(bp); j = EXTRACT_32BITS(bp); bp += sizeof(int32_t); @@ -1272,6 +1280,7 @@ cb_print(netdissect_options *ndo, bp += sizeof(int32_t); tok2str(cb_types, "type %d", t); } + break; } case 214: { ND_PRINT((ndo, " afsuuid")); @@ -1733,6 +1742,7 @@ vldb_reply_print(netdissect_options *ndo, INTOUT(); ND_PRINT((ndo, " nextindex")); INTOUT(); + /*FALLTHROUGH*/ case 503: /* Get entry by id */ case 504: /* Get entry by name */ { unsigned long nservers, j; @@ -1782,6 +1792,7 @@ vldb_reply_print(netdissect_options *ndo, INTOUT(); ND_PRINT((ndo, " nextindex")); INTOUT(); + /*FALLTHROUGH*/ case 518: /* Get entry by ID N */ case 519: /* Get entry by name N */ { unsigned long nservers, j; @@ -1918,7 +1929,7 @@ kauth_print(netdissect_options *ndo, bp += sizeof(struct rx_header) + 4; switch (kauth_op) { - case 1: /* Authenticate old */; + case 1: /* Authenticate old */ case 21: /* Authenticate */ case 22: /* Authenticate-V2 */ case 2: /* Change PW */ @@ -2527,6 +2538,10 @@ ubik_print(netdissect_options *ndo, * gleaned from ubik/ubik_int.xg */ + /* Every function that calls this function first makes a bounds check + * for (sizeof(rx_header) + 4) bytes, so long as it remains this way + * the line below will not over-read. + */ ubik_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); ND_PRINT((ndo, " ubik call %s", tok2str(ubik_req, "op#%d", ubik_op))); @@ -2571,6 +2586,7 @@ ubik_print(netdissect_options *ndo, INTOUT(); ND_PRINT((ndo, " length")); INTOUT(); + ND_TCHECK_32BITS(bp); temp = EXTRACT_32BITS(bp); bp += sizeof(int32_t); tok2str(ubik_lock_types, "type %d", temp);