X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/b46194277a029332c9d1b0ba38110cabc179210f..07953b6a4d5f46af83c53a85a6ee7e5d3d51c0b8:/print-tftp.c diff --git a/print-tftp.c b/print-tftp.c index 5f47d476..69bc601f 100644 --- a/print-tftp.c +++ b/print-tftp.c @@ -17,20 +17,19 @@ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Format and print trivial file transfer protocol packets. */ -#define NETDISSECT_REWORKED +/* \summary: Trivial File Transfer Protocol (TFTP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include -#include "interface.h" +#include "netdissect.h" #include "extract.h" /* @@ -110,7 +109,8 @@ tftp_print(netdissect_options *ndo, register const struct tftphdr *tp; register const char *cp; register const u_char *p; - register int opcode, i; + register int opcode; + u_int ui; tp = (const struct tftphdr *)bp; @@ -118,9 +118,12 @@ tftp_print(netdissect_options *ndo, ND_PRINT((ndo, " %d", length)); /* Print tftp request type */ + if (length < 2) + goto trunc; ND_TCHECK(tp->th_opcode); opcode = EXTRACT_16BITS(&tp->th_opcode); cp = tok2str(op2str, "tftp-#%d", opcode); + length -= 2; ND_PRINT((ndo, " %s", cp)); /* Bail if bogus opcode */ if (*cp == 't') @@ -130,46 +133,80 @@ tftp_print(netdissect_options *ndo, case RRQ: case WRQ: - case OACK: - p = (u_char *)tp->th_stuff; + p = (const u_char *)tp->th_stuff; + if (length == 0) + goto trunc; + ND_PRINT((ndo, " ")); + /* Print filename */ + ND_PRINT((ndo, "\"")); + ui = fn_printztn(ndo, p, length, ndo->ndo_snapend); + ND_PRINT((ndo, "\"")); + if (ui == 0) + goto trunc; + p += ui; + length -= ui; + + /* Print the mode - RRQ and WRQ only */ + if (length == 0) + goto trunc; /* no mode */ ND_PRINT((ndo, " ")); - /* Print filename or first option */ - if (opcode != OACK) - ND_PRINT((ndo, "\"")); - i = fn_print(p, ndo->ndo_snapend); - if (opcode != OACK) - ND_PRINT((ndo, "\"")); - - /* Print the mode (RRQ and WRQ only) and any options */ - while ((p = (const u_char *)strchr((const char *)p, '\0')) != NULL) { - if (length <= (u_int)(p - (const u_char *)&tp->th_block)) - break; - p++; - if (*p != '\0') { + ui = fn_printztn(ndo, p, length, ndo->ndo_snapend); + if (ui == 0) + goto trunc; + p += ui; + length -= ui; + + /* Print options, if any */ + while (length != 0) { + ND_TCHECK(*p); + if (*p != '\0') ND_PRINT((ndo, " ")); - fn_print(p, ndo->ndo_snapend); - } + ui = fn_printztn(ndo, p, length, ndo->ndo_snapend); + if (ui == 0) + goto trunc; + p += ui; + length -= ui; } + break; - if (i) - goto trunc; + case OACK: + p = (const u_char *)tp->th_stuff; + /* Print options */ + while (length != 0) { + ND_TCHECK(*p); + if (*p != '\0') + ND_PRINT((ndo, " ")); + ui = fn_printztn(ndo, p, length, ndo->ndo_snapend); + if (ui == 0) + goto trunc; + p += ui; + length -= ui; + } break; case ACK: case DATA: + if (length < 2) + goto trunc; /* no block number */ ND_TCHECK(tp->th_block); ND_PRINT((ndo, " block %d", EXTRACT_16BITS(&tp->th_block))); break; case TFTP_ERROR: /* Print error code string */ + if (length < 2) + goto trunc; /* no error code */ ND_TCHECK(tp->th_code); - ND_PRINT((ndo, " %s \"", tok2str(err2str, "tftp-err-#%d \"", + ND_PRINT((ndo, " %s", tok2str(err2str, "tftp-err-#%d \"", EXTRACT_16BITS(&tp->th_code)))); + length -= 2; /* Print error message string */ - i = fn_print((const u_char *)tp->th_data, ndo->ndo_snapend); + if (length == 0) + goto trunc; /* no error message */ + ND_PRINT((ndo, " \"")); + ui = fn_printztn(ndo, (const u_char *)tp->th_data, length, ndo->ndo_snapend); ND_PRINT((ndo, "\"")); - if (i) + if (ui == 0) goto trunc; break;