print-tftp.c revision 172683
1/* 2 * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that: (1) source code distributions 7 * retain the above copyright notice and this paragraph in its entirety, (2) 8 * distributions including binary code include the above copyright notice and 9 * this paragraph in its entirety in the documentation or other materials 10 * provided with the distribution, and (3) all advertising materials mentioning 11 * features or use of this software display the following acknowledgement: 12 * ``This product includes software developed by the University of California, 13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14 * the University nor the names of its contributors may be used to endorse 15 * or promote products derived from this software without specific prior 16 * written permission. 17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20 * 21 * Format and print trivial file transfer protocol packets. 22 */ 23 24#ifndef lint 25static const char rcsid[] _U_ = 26 "@(#) $Header: /tcpdump/master/tcpdump/print-tftp.c,v 1.37.2.1 2007/09/14 01:03:12 guy Exp $ (LBL)"; 27#endif 28 29#ifdef HAVE_CONFIG_H 30#include "config.h" 31#endif 32 33#include <tcpdump-stdinc.h> 34 35#ifdef SEGSIZE 36#undef SEGSIZE /* SINIX sucks */ 37#endif 38 39#include <stdio.h> 40#include <string.h> 41 42#include "interface.h" 43#include "addrtoname.h" 44#include "extract.h" 45#include "tftp.h" 46 47/* op code to string mapping */ 48static struct tok op2str[] = { 49 { RRQ, "RRQ" }, /* read request */ 50 { WRQ, "WRQ" }, /* write request */ 51 { DATA, "DATA" }, /* data packet */ 52 { ACK, "ACK" }, /* acknowledgement */ 53 { ERROR, "ERROR" }, /* error code */ 54 { OACK, "OACK" }, /* option acknowledgement */ 55 { 0, NULL } 56}; 57 58/* error code to string mapping */ 59static struct tok err2str[] = { 60 { EUNDEF, "EUNDEF" }, /* not defined */ 61 { ENOTFOUND, "ENOTFOUND" }, /* file not found */ 62 { EACCESS, "EACCESS" }, /* access violation */ 63 { ENOSPACE, "ENOSPACE" }, /* disk full or allocation exceeded */ 64 { EBADOP, "EBADOP" }, /* illegal TFTP operation */ 65 { EBADID, "EBADID" }, /* unknown transfer ID */ 66 { EEXISTS, "EEXISTS" }, /* file already exists */ 67 { ENOUSER, "ENOUSER" }, /* no such user */ 68 { 0, NULL } 69}; 70 71/* 72 * Print trivial file transfer program requests 73 */ 74void 75tftp_print(register const u_char *bp, u_int length) 76{ 77 register const struct tftphdr *tp; 78 register const char *cp; 79 register const u_char *p; 80 register int opcode, i; 81 static char tstr[] = " [|tftp]"; 82 83 tp = (const struct tftphdr *)bp; 84 85 /* Print length */ 86 printf(" %d", length); 87 88 /* Print tftp request type */ 89 TCHECK(tp->th_opcode); 90 opcode = EXTRACT_16BITS(&tp->th_opcode); 91 cp = tok2str(op2str, "tftp-#%d", opcode); 92 printf(" %s", cp); 93 /* Bail if bogus opcode */ 94 if (*cp == 't') 95 return; 96 97 switch (opcode) { 98 99 case RRQ: 100 case WRQ: 101 case OACK: 102 /* 103 * XXX Not all arpa/tftp.h's specify th_stuff as any 104 * array; use address of th_block instead 105 */ 106#ifdef notdef 107 p = (u_char *)tp->th_stuff; 108#else 109 p = (u_char *)&tp->th_block; 110#endif 111 putchar(' '); 112 /* Print filename or first option */ 113 if (opcode != OACK) 114 putchar('"'); 115 i = fn_print(p, snapend); 116 if (opcode != OACK) 117 putchar('"'); 118 119 /* Print the mode (RRQ and WRQ only) and any options */ 120 while ((p = (const u_char *)strchr((const char *)p, '\0')) != NULL) { 121 if (length <= (u_int)(p - (const u_char *)&tp->th_block)) 122 break; 123 p++; 124 if (*p != '\0') { 125 putchar(' '); 126 fn_print(p, snapend); 127 } 128 } 129 130 if (i) 131 goto trunc; 132 break; 133 134 case ACK: 135 case DATA: 136 TCHECK(tp->th_block); 137 printf(" block %d", EXTRACT_16BITS(&tp->th_block)); 138 break; 139 140 case ERROR: 141 /* Print error code string */ 142 TCHECK(tp->th_code); 143 printf(" %s \"", tok2str(err2str, "tftp-err-#%d \"", 144 EXTRACT_16BITS(&tp->th_code))); 145 /* Print error message string */ 146 i = fn_print((const u_char *)tp->th_data, snapend); 147 putchar('"'); 148 if (i) 149 goto trunc; 150 break; 151 152 default: 153 /* We shouldn't get here */ 154 printf("(unknown #%d)", opcode); 155 break; 156 } 157 return; 158trunc: 159 fputs(tstr, stdout); 160 return; 161} 162