📄 print-rx.c
字号:
*/ printf(" kauth"); if (is_ubik(opcode)) { ubik_reply_print(bp, length, opcode); return; } printf(" reply %s", tok2str(kauth_req, "op#%d", opcode)); bp += sizeof(struct rx_header); /* * If it was a data packet, interpret the response. */ if (rxh->type == RX_PACKET_TYPE_DATA) /* Well, no, not really. Leave this for later */ ; else { /* * Otherwise, just print out the return code */ printf(" errcode"); INTOUT(); } return;trunc: printf(" [|kauth]");}/* * Handle calls to the AFS Volume location service */static voidvol_print(register const u_char *bp, int length){ int vol_op; if (length <= sizeof(struct rx_header)) return; if (snapend - bp + 1 <= sizeof(struct rx_header) + sizeof(int32_t)) { goto trunc; } /* * Print out the afs call we're invoking. The table used here was * gleaned from volser/volint.xg */ vol_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); printf(" vol call %s", tok2str(vol_req, "op#%d", vol_op)); /* * Normally there would be a switch statement here to decode the * arguments to the AFS call, but since I don't have access to * an AFS server (yet) and I'm not an AFS admin, I can't * test any of these calls. Leave this blank for now. */ return;trunc: printf(" [|vol]");}/* * Handle replies to the AFS Volume Service */static voidvol_reply_print(register const u_char *bp, int length, int32_t opcode){ struct rx_header *rxh; if (length <= sizeof(struct rx_header)) return; rxh = (struct rx_header *) bp; /* * Print out the afs call we're invoking. The table used here was * gleaned from volser/volint.xg */ printf(" vol reply %s", tok2str(vol_req, "op#%d", opcode)); bp += sizeof(struct rx_header); /* * If it was a data packet, interpret the response. */ if (rxh->type == RX_PACKET_TYPE_DATA) /* Well, no, not really. Leave this for later */ ; else { /* * Otherwise, just print out the return code */ printf(" errcode"); INTOUT(); } return;trunc: printf(" [|vol]");}/* * Handle calls to the AFS BOS service */static voidbos_print(register const u_char *bp, int length){ int bos_op; char s[BOSNAMEMAX]; if (length <= sizeof(struct rx_header)) return; if (snapend - bp + 1 <= sizeof(struct rx_header) + sizeof(int32_t)) { goto trunc; } /* * Print out the afs call we're invoking. The table used here was * gleaned from bozo/bosint.xg */ bos_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); printf(" bos call %s", tok2str(bos_req, "op#%d", bos_op)); /* * Decode some of the arguments to the BOS calls */ bp += sizeof(struct rx_header) + 4; switch (bos_op) { case 80: /* Create B node */ printf(" type"); STROUT(BOSNAMEMAX); printf(" instance"); STROUT(BOSNAMEMAX); break; case 81: /* Delete B node */ case 83: /* Get status */ case 85: /* Get instance info */ case 87: /* Add super user */ case 88: /* Delete super user */ case 93: /* Set cell name */ case 96: /* Add cell host */ case 97: /* Delete cell host */ case 104: /* Restart */ case 106: /* Uninstall */ case 108: /* Exec */ case 112: /* Getlog */ case 114: /* Get instance strings */ STROUT(BOSNAMEMAX); break; case 82: /* Set status */ case 98: /* Set T status */ STROUT(BOSNAMEMAX); printf(" status"); INTOUT(); break; case 86: /* Get instance parm */ STROUT(BOSNAMEMAX); printf(" num"); INTOUT(); break; case 84: /* Enumerate instance */ case 89: /* List super users */ case 90: /* List keys */ case 91: /* Add key */ case 92: /* Delete key */ case 95: /* Get cell host */ INTOUT(); break; case 105: /* Install */ STROUT(BOSNAMEMAX); printf(" size"); INTOUT(); printf(" flags"); INTOUT(); printf(" date"); INTOUT(); break; default: ; } return;trunc: printf(" [|bos]");}/* * Handle replies to the AFS BOS Service */static voidbos_reply_print(register const u_char *bp, int length, int32_t opcode){ struct rx_header *rxh; if (length <= sizeof(struct rx_header)) return; rxh = (struct rx_header *) bp; /* * Print out the afs call we're invoking. The table used here was * gleaned from volser/volint.xg */ printf(" bos reply %s", tok2str(bos_req, "op#%d", opcode)); bp += sizeof(struct rx_header); /* * If it was a data packet, interpret the response. */ if (rxh->type == RX_PACKET_TYPE_DATA) /* Well, no, not really. Leave this for later */ ; else { /* * Otherwise, just print out the return code */ printf(" errcode"); INTOUT(); } return;trunc: printf(" [|bos]");}/* * Check to see if this is a Ubik opcode. */static intis_ubik(u_int32_t opcode){ if ((opcode >= VOTE_LOW && opcode <= VOTE_HIGH) || (opcode >= DISK_LOW && opcode <= DISK_HIGH)) return(1); else return(0);}/* * Handle Ubik opcodes to any one of the replicated database services */static voidubik_print(register const u_char *bp, int length){ int ubik_op; int32_t temp; /* * Print out the afs call we're invoking. The table used here was * gleaned from ubik/ubik_int.xg */ ubik_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); printf(" ubik call %s", tok2str(ubik_req, "op#%d", ubik_op)); /* * Decode some of the arguments to the Ubik calls */ bp += sizeof(struct rx_header) + 4; switch (ubik_op) { case 10000: /* Beacon */ TCHECK2(bp[0], 4); temp = EXTRACT_32BITS(bp); bp += sizeof(int32_t); printf(" syncsite %s", temp ? "yes" : "no"); printf(" votestart"); DATEOUT(); printf(" dbversion"); UBIK_VERSIONOUT(); printf(" tid"); UBIK_VERSIONOUT(); break; case 10003: /* Get sync site */ printf(" site"); UINTOUT(); break; case 20000: /* Begin */ case 20001: /* Commit */ case 20007: /* Abort */ case 20008: /* Release locks */ case 20010: /* Writev */ printf(" tid"); UBIK_VERSIONOUT(); break; case 20002: /* Lock */ printf(" tid"); UBIK_VERSIONOUT(); printf(" file"); INTOUT(); printf(" pos"); INTOUT(); printf(" length"); INTOUT(); temp = EXTRACT_32BITS(bp); bp += sizeof(int32_t); tok2str(ubik_lock_types, "type %d", temp); break; case 20003: /* Write */ printf(" tid"); UBIK_VERSIONOUT(); printf(" file"); INTOUT(); printf(" pos"); INTOUT(); break; case 20005: /* Get file */ printf(" file"); INTOUT(); break; case 20006: /* Send file */ printf(" file"); INTOUT(); printf(" length"); INTOUT(); printf(" dbversion"); UBIK_VERSIONOUT(); break; case 20009: /* Truncate */ printf(" tid"); UBIK_VERSIONOUT(); printf(" file"); INTOUT(); printf(" length"); INTOUT(); break; case 20012: /* Set version */ printf(" tid"); UBIK_VERSIONOUT(); printf(" oldversion"); UBIK_VERSIONOUT(); printf(" newversion"); UBIK_VERSIONOUT(); break; default: ; } return;trunc: printf(" [|ubik]");}/* * Handle Ubik replies to any one of the replicated database services */static voidubik_reply_print(register const u_char *bp, int length, int32_t opcode){ struct rx_header *rxh; if (length < sizeof(struct rx_header)) return; rxh = (struct rx_header *) bp; /* * Print out the ubik call we're invoking. This table was gleaned * from ubik/ubik_int.xg */ printf(" ubik reply %s", tok2str(ubik_req, "op#%d", opcode)); bp += sizeof(struct rx_header); /* * If it was a data packet, print out the arguments to the Ubik calls */ if (rxh->type == RX_PACKET_TYPE_DATA) switch (opcode) { case 10000: /* Beacon */ printf(" vote no"); break; case 20004: /* Get version */ printf(" dbversion"); UBIK_VERSIONOUT(); break; default: ; } /* * Otherwise, print out "yes" it it was a beacon packet (because * that's how yes votes are returned, go figure), otherwise * just print out the error code. */ else switch (opcode) { case 10000: /* Beacon */ printf(" vote yes until"); DATEOUT(); break; default: printf(" errcode"); INTOUT(); } return;trunc: printf(" [|ubik]");}/* * Handle RX ACK packets. */static voidrx_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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -