1238438Sdteske/* 2238438Sdteske * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997 3238438Sdteske * The Regents of the University of California. All rights reserved. 4238438Sdteske * 5238438Sdteske * Redistribution and use in source and binary forms, with or without 6238438Sdteske * modification, are permitted provided that: (1) source code distributions 7238438Sdteske * retain the above copyright notice and this paragraph in its entirety, (2) 8238438Sdteske * distributions including binary code include the above copyright notice and 9238438Sdteske * this paragraph in its entirety in the documentation or other materials 10238438Sdteske * provided with the distribution, and (3) all advertising materials mentioning 11238438Sdteske * features or use of this software display the following acknowledgement: 12238438Sdteske * ``This product includes software developed by the University of California, 13238438Sdteske * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14238438Sdteske * the University nor the names of its contributors may be used to endorse 15238438Sdteske * or promote products derived from this software without specific prior 16238438Sdteske * written permission. 17238438Sdteske * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18238438Sdteske * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19238438Sdteske * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20238438Sdteske * 21238438Sdteske * Format and print trivial file transfer protocol packets. 22238438Sdteske */ 23238438Sdteske 24238438Sdteske#ifndef lint 25238438Sdteskestatic const char rcsid[] _U_ = 26238438Sdteske "@(#) $Header: /tcpdump/master/tcpdump/print-tftp.c,v 1.39 2008-04-11 16:47:38 gianluca Exp $ (LBL)"; 27238438Sdteske#endif 28238438Sdteske 29238438Sdteske#ifdef HAVE_CONFIG_H 30238438Sdteske#include "config.h" 31238438Sdteske#endif 32238438Sdteske 33238438Sdteske#include <tcpdump-stdinc.h> 34238438Sdteske 35238438Sdteske#ifdef SEGSIZE 36238438Sdteske#undef SEGSIZE /* SINIX sucks */ 37238438Sdteske#endif 38238438Sdteske 39238438Sdteske#include <stdio.h> 40238438Sdteske#include <string.h> 41238438Sdteske 42238438Sdteske#include "interface.h" 43238438Sdteske#include "addrtoname.h" 44238438Sdteske#include "extract.h" 45238438Sdteske#include "tftp.h" 46238438Sdteske 47238438Sdteske/* op code to string mapping */ 48238438Sdteskestatic struct tok op2str[] = { 49238438Sdteske { RRQ, "RRQ" }, /* read request */ 50238438Sdteske { WRQ, "WRQ" }, /* write request */ 51238438Sdteske { DATA, "DATA" }, /* data packet */ 52238438Sdteske { ACK, "ACK" }, /* acknowledgement */ 53238438Sdteske { TFTP_ERROR, "ERROR" }, /* error code */ 54238438Sdteske { OACK, "OACK" }, /* option acknowledgement */ 55238438Sdteske { 0, NULL } 56238438Sdteske}; 57238438Sdteske 58238438Sdteske/* error code to string mapping */ 59238438Sdteskestatic struct tok err2str[] = { 60238438Sdteske { EUNDEF, "EUNDEF" }, /* not defined */ 61238438Sdteske { ENOTFOUND, "ENOTFOUND" }, /* file not found */ 62238438Sdteske { EACCESS, "EACCESS" }, /* access violation */ 63238438Sdteske { ENOSPACE, "ENOSPACE" }, /* disk full or allocation exceeded */ 64238438Sdteske { EBADOP, "EBADOP" }, /* illegal TFTP operation */ 65238438Sdteske { EBADID, "EBADID" }, /* unknown transfer ID */ 66238438Sdteske { EEXISTS, "EEXISTS" }, /* file already exists */ 67238438Sdteske { ENOUSER, "ENOUSER" }, /* no such user */ 68238438Sdteske { 0, NULL } 69238438Sdteske}; 70238438Sdteske 71238438Sdteske/* 72238438Sdteske * Print trivial file transfer program requests 73238438Sdteske */ 74238438Sdteskevoid 75238438Sdtesketftp_print(register const u_char *bp, u_int length) 76238438Sdteske{ 77238438Sdteske register const struct tftphdr *tp; 78238438Sdteske register const char *cp; 79238438Sdteske register const u_char *p; 80238438Sdteske register int opcode, i; 81238438Sdteske static char tstr[] = " [|tftp]"; 82238438Sdteske 83238438Sdteske tp = (const struct tftphdr *)bp; 84238438Sdteske 85238438Sdteske /* Print length */ 86238438Sdteske printf(" %d", length); 87238438Sdteske 88238438Sdteske /* Print tftp request type */ 89238438Sdteske TCHECK(tp->th_opcode); 90238438Sdteske opcode = EXTRACT_16BITS(&tp->th_opcode); 91238438Sdteske cp = tok2str(op2str, "tftp-#%d", opcode); 92238438Sdteske printf(" %s", cp); 93238438Sdteske /* Bail if bogus opcode */ 94238438Sdteske if (*cp == 't') 95238438Sdteske return; 96238438Sdteske 97238438Sdteske switch (opcode) { 98238438Sdteske 99238438Sdteske case RRQ: 100238438Sdteske case WRQ: 101238438Sdteske case OACK: 102238438Sdteske p = (u_char *)tp->th_stuff; 103238438Sdteske putchar(' '); 104238438Sdteske /* Print filename or first option */ 105238438Sdteske if (opcode != OACK) 106238438Sdteske putchar('"'); 107238438Sdteske i = fn_print(p, snapend); 108238438Sdteske if (opcode != OACK) 109238438Sdteske putchar('"'); 110238438Sdteske 111238438Sdteske /* Print the mode (RRQ and WRQ only) and any options */ 112238438Sdteske while ((p = (const u_char *)strchr((const char *)p, '\0')) != NULL) { 113238438Sdteske if (length <= (u_int)(p - (const u_char *)&tp->th_block)) 114238438Sdteske break; 115238438Sdteske p++; 116238438Sdteske if (*p != '\0') { 117238438Sdteske putchar(' '); 118238438Sdteske fn_print(p, snapend); 119238438Sdteske } 120238438Sdteske } 121238438Sdteske 122238438Sdteske if (i) 123238438Sdteske goto trunc; 124238438Sdteske break; 125238438Sdteske 126238438Sdteske case ACK: 127238438Sdteske case DATA: 128238438Sdteske TCHECK(tp->th_block); 129238438Sdteske printf(" block %d", EXTRACT_16BITS(&tp->th_block)); 130238438Sdteske break; 131238438Sdteske 132238438Sdteske case TFTP_ERROR: 133238438Sdteske /* Print error code string */ 134238438Sdteske TCHECK(tp->th_code); 135238438Sdteske printf(" %s \"", tok2str(err2str, "tftp-err-#%d \"", 136238438Sdteske EXTRACT_16BITS(&tp->th_code))); 137238438Sdteske /* Print error message string */ 138238438Sdteske i = fn_print((const u_char *)tp->th_data, snapend); 139238438Sdteske putchar('"'); 140238438Sdteske if (i) 141238438Sdteske goto trunc; 142238438Sdteske break; 143 144 default: 145 /* We shouldn't get here */ 146 printf("(unknown #%d)", opcode); 147 break; 148 } 149 return; 150trunc: 151 fputs(tstr, stdout); 152 return; 153} 154