#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/tcpdump/print-tftp.c,v 1.38.2.1 2008-04-11 16:44:17 gianluca Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <tcpdump-stdinc.h>
#ifdef SEGSIZE
#undef SEGSIZE
#endif
#include <stdio.h>
#include <string.h>
#include "interface.h"
#include "addrtoname.h"
#include "extract.h"
#include "tftp.h"
static struct tok op2str[] = {
{ RRQ, "RRQ" },
{ WRQ, "WRQ" },
{ DATA, "DATA" },
{ ACK, "ACK" },
{ TFTP_ERROR, "ERROR" },
{ OACK, "OACK" },
{ 0, NULL }
};
static struct tok err2str[] = {
{ EUNDEF, "EUNDEF" },
{ ENOTFOUND, "ENOTFOUND" },
{ EACCESS, "EACCESS" },
{ ENOSPACE, "ENOSPACE" },
{ EBADOP, "EBADOP" },
{ EBADID, "EBADID" },
{ EEXISTS, "EEXISTS" },
{ ENOUSER, "ENOUSER" },
{ 0, NULL }
};
void
tftp_print(register const u_char *bp, u_int length)
{
register const struct tftphdr *tp;
register const char *cp;
register const u_char *p;
register int opcode, i;
static char tstr[] = " [|tftp]";
tp = (const struct tftphdr *)bp;
printf(" %d", length);
TCHECK(tp->th_opcode);
opcode = EXTRACT_16BITS(&tp->th_opcode);
cp = tok2str(op2str, "tftp-#%d", opcode);
printf(" %s", cp);
if (*cp == 't')
return;
switch (opcode) {
case RRQ:
case WRQ:
case OACK:
#ifdef notdef
p = (u_char *)tp->th_stuff;
#else
p = (u_char *)&tp->th_block;
#endif
putchar(' ');
if (opcode != OACK)
putchar('"');
i = fn_print(p, snapend);
if (opcode != OACK)
putchar('"');
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') {
putchar(' ');
fn_print(p, snapend);
}
}
if (i)
goto trunc;
break;
case ACK:
case DATA:
TCHECK(tp->th_block);
printf(" block %d", EXTRACT_16BITS(&tp->th_block));
break;
case TFTP_ERROR:
TCHECK(tp->th_code);
printf(" %s \"", tok2str(err2str, "tftp-err-#%d \"",
EXTRACT_16BITS(&tp->th_code)));
i = fn_print((const u_char *)tp->th_data, snapend);
putchar('"');
if (i)
goto trunc;
break;
default:
printf("(unknown #%d)", opcode);
break;
}
return;
trunc:
fputs(tstr, stdout);
return;
}