/* \summary: Trivial File Transfer Protocol (TFTP) printer */
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
-#include <netdissect-stdinc.h>
-
-#include <string.h>
+#include "netdissect-stdinc.h"
#include "netdissect.h"
#include "extract.h"
#define TFTP_ERROR 05 /* error code */
#define OACK 06 /* option acknowledgement */
-struct tftphdr {
- unsigned short th_opcode; /* packet type */
- union {
- unsigned short tu_block; /* block # */
- unsigned short tu_code; /* error code */
- char tu_stuff[1]; /* request packet stuff */
- } th_u;
- char th_data[1]; /* data or error string */
-};
-
-#define th_block th_u.tu_block
-#define th_code th_u.tu_code
-#define th_stuff th_u.tu_stuff
-#define th_msg th_data
-
/*
* Error codes.
*/
#define EEXISTS 6 /* file already exists */
#define ENOUSER 7 /* no such user */
-static const char tstr[] = " [|tftp]";
/* op code to string mapping */
static const struct tok op2str[] = {
*/
void
tftp_print(netdissect_options *ndo,
- register const u_char *bp, u_int length)
+ const u_char *bp, u_int length)
{
- register const struct tftphdr *tp;
- register const char *cp;
- register const u_char *p;
- register int opcode;
+ const char *cp;
+ u_int opcode;
u_int ui;
- tp = (const struct tftphdr *)bp;
+ ndo->ndo_protocol = "tftp";
+ /* Print protocol */
+ nd_print_protocol_caps(ndo);
/* Print length */
- ND_PRINT((ndo, " %d", length));
+ ND_PRINT(", length %u", 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));
+ opcode = GET_BE_U_2(bp);
+ cp = tok2str(op2str, "tftp-#%u", opcode);
+ ND_PRINT(", %s", cp);
/* Bail if bogus opcode */
if (*cp == 't')
return;
+ bp += 2;
+ length -= 2;
switch (opcode) {
case RRQ:
case WRQ:
- p = (const u_char *)tp->th_stuff;
if (length == 0)
goto trunc;
- ND_PRINT((ndo, " "));
+ ND_PRINT(" ");
/* Print filename */
- ND_PRINT((ndo, "\""));
- ui = fn_printztn(ndo, p, length, ndo->ndo_snapend);
- ND_PRINT((ndo, "\""));
+ ND_PRINT("\"");
+ ui = nd_printztn(ndo, bp, length, ndo->ndo_snapend);
+ ND_PRINT("\"");
if (ui == 0)
goto trunc;
- p += ui;
+ bp += ui;
length -= ui;
/* Print the mode - RRQ and WRQ only */
if (length == 0)
goto trunc; /* no mode */
- ND_PRINT((ndo, " "));
- ui = fn_printztn(ndo, p, length, ndo->ndo_snapend);
+ ND_PRINT(" ");
+ ui = nd_printztn(ndo, bp, length, ndo->ndo_snapend);
if (ui == 0)
goto trunc;
- p += ui;
+ bp += ui;
length -= ui;
/* Print options, if any */
while (length != 0) {
- ND_TCHECK(*p);
- if (*p != '\0')
- ND_PRINT((ndo, " "));
- ui = fn_printztn(ndo, p, length, ndo->ndo_snapend);
+ if (GET_U_1(bp) != '\0')
+ ND_PRINT(" ");
+ ui = nd_printztn(ndo, bp, length, ndo->ndo_snapend);
if (ui == 0)
goto trunc;
- p += ui;
+ bp += ui;
length -= ui;
}
break;
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 (GET_U_1(bp) != '\0')
+ ND_PRINT(" ");
+ ui = nd_printztn(ndo, bp, length, ndo->ndo_snapend);
if (ui == 0)
goto trunc;
- p += ui;
+ bp += ui;
length -= ui;
}
break;
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)));
+ ND_PRINT(" block %u", GET_BE_U_2(bp));
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 \"",
- EXTRACT_16BITS(&tp->th_code))));
+ ND_PRINT(" %s", tok2str(err2str, "tftp-err-#%u \"",
+ GET_BE_U_2(bp)));
+ bp += 2;
length -= 2;
/* Print error message string */
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, "\""));
+ ND_PRINT(" \"");
+ ui = nd_printztn(ndo, bp, length, ndo->ndo_snapend);
+ ND_PRINT("\"");
if (ui == 0)
goto trunc;
break;
default:
/* We shouldn't get here */
- ND_PRINT((ndo, "(unknown #%d)", opcode));
+ ND_PRINT("(unknown #%u)", opcode);
break;
}
return;
trunc:
- ND_PRINT((ndo, "%s", tstr));
- return;
+ nd_print_trunc(ndo);
}