print-tftp.c revision 1.2
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#include <sys/cdefs.h> 25#ifndef lint 26#if 0 27static const char rcsid[] _U_ = 28 "@(#) Header: /tcpdump/master/tcpdump/print-tftp.c,v 1.39 2008-04-11 16:47:38 gianluca Exp (LBL)"; 29#else 30__RCSID("$NetBSD: print-tftp.c,v 1.2 2010/12/05 05:11:31 christos Exp $"); 31#endif 32#endif 33 34#ifdef HAVE_CONFIG_H 35#include "config.h" 36#endif 37 38#include <tcpdump-stdinc.h> 39 40#ifdef SEGSIZE 41#undef SEGSIZE /* SINIX sucks */ 42#endif 43 44#include <stdio.h> 45#include <string.h> 46 47#include "interface.h" 48#include "addrtoname.h" 49#include "extract.h" 50#include "tftp.h" 51 52/* op code to string mapping */ 53static struct tok op2str[] = { 54 { RRQ, "RRQ" }, /* read request */ 55 { WRQ, "WRQ" }, /* write request */ 56 { DATA, "DATA" }, /* data packet */ 57 { ACK, "ACK" }, /* acknowledgement */ 58 { TFTP_ERROR, "ERROR" }, /* error code */ 59 { OACK, "OACK" }, /* option acknowledgement */ 60 { 0, NULL } 61}; 62 63/* error code to string mapping */ 64static struct tok err2str[] = { 65 { EUNDEF, "EUNDEF" }, /* not defined */ 66 { ENOTFOUND, "ENOTFOUND" }, /* file not found */ 67 { EACCESS, "EACCESS" }, /* access violation */ 68 { ENOSPACE, "ENOSPACE" }, /* disk full or allocation exceeded */ 69 { EBADOP, "EBADOP" }, /* illegal TFTP operation */ 70 { EBADID, "EBADID" }, /* unknown transfer ID */ 71 { EEXISTS, "EEXISTS" }, /* file already exists */ 72 { ENOUSER, "ENOUSER" }, /* no such user */ 73 { 0, NULL } 74}; 75 76/* 77 * Print trivial file transfer program requests 78 */ 79void 80tftp_print(register const u_char *bp, u_int length) 81{ 82 register const struct tftphdr *tp; 83 register const char *cp; 84 register const u_char *p; 85 register int opcode, i; 86 static char tstr[] = " [|tftp]"; 87 88 tp = (const struct tftphdr *)bp; 89 90 /* Print length */ 91 printf(" %d", length); 92 93 /* Print tftp request type */ 94 TCHECK(tp->th_opcode); 95 opcode = EXTRACT_16BITS(&tp->th_opcode); 96 cp = tok2str(op2str, "tftp-#%d", opcode); 97 printf(" %s", cp); 98 /* Bail if bogus opcode */ 99 if (*cp == 't') 100 return; 101 102 switch (opcode) { 103 104 case RRQ: 105 case WRQ: 106 case OACK: 107 /* 108 * XXX Not all arpa/tftp.h's specify th_stuff as any 109 * array; use address of th_block instead 110 */ 111#ifdef notdef 112 p = (u_char *)tp->th_stuff; 113#else 114 p = (u_char *)&tp->th_block; 115#endif 116 putchar(' '); 117 /* Print filename or first option */ 118 if (opcode != OACK) 119 putchar('"'); 120 i = fn_print(p, snapend); 121 if (opcode != OACK) 122 putchar('"'); 123 124 /* Print the mode (RRQ and WRQ only) and any options */ 125 while ((p = (const u_char *)strchr((const char *)p, '\0')) != NULL) { 126 if (length <= (u_int)(p - (const u_char *)&tp->th_block)) 127 break; 128 p++; 129 if (*p != '\0') { 130 putchar(' '); 131 fn_print(p, snapend); 132 } 133 } 134 135 if (i) 136 goto trunc; 137 break; 138 139 case ACK: 140 case DATA: 141 TCHECK(tp->th_block); 142 printf(" block %d", EXTRACT_16BITS(&tp->th_block)); 143 break; 144 145 case TFTP_ERROR: 146 /* Print error code string */ 147 TCHECK(tp->th_code); 148 printf(" %s \"", tok2str(err2str, "tftp-err-#%d \"", 149 EXTRACT_16BITS(&tp->th_code))); 150 /* Print error message string */ 151 i = fn_print((const u_char *)tp->th_data, snapend); 152 putchar('"'); 153 if (i) 154 goto trunc; 155 break; 156 157 default: 158 /* We shouldn't get here */ 159 printf("(unknown #%d)", opcode); 160 break; 161 } 162 return; 163trunc: 164 fputs(tstr, stdout); 165 return; 166} 167