print-tftp.c revision 1.3
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.3 2013/04/06 19:33:08 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 p = (u_char *)tp->th_stuff; 108 putchar(' '); 109 /* Print filename or first option */ 110 if (opcode != OACK) 111 putchar('"'); 112 i = fn_print(p, snapend); 113 if (opcode != OACK) 114 putchar('"'); 115 116 /* Print the mode (RRQ and WRQ only) and any options */ 117 while ((p = (const u_char *)strchr((const char *)p, '\0')) != NULL) { 118 if (length <= (u_int)(p - (const u_char *)&tp->th_block)) 119 break; 120 p++; 121 if (*p != '\0') { 122 putchar(' '); 123 fn_print(p, snapend); 124 } 125 } 126 127 if (i) 128 goto trunc; 129 break; 130 131 case ACK: 132 case DATA: 133 TCHECK(tp->th_block); 134 printf(" block %d", EXTRACT_16BITS(&tp->th_block)); 135 break; 136 137 case TFTP_ERROR: 138 /* Print error code string */ 139 TCHECK(tp->th_code); 140 printf(" %s \"", tok2str(err2str, "tftp-err-#%d \"", 141 EXTRACT_16BITS(&tp->th_code))); 142 /* Print error message string */ 143 i = fn_print((const u_char *)tp->th_data, snapend); 144 putchar('"'); 145 if (i) 146 goto trunc; 147 break; 148 149 default: 150 /* We shouldn't get here */ 151 printf("(unknown #%d)", opcode); 152 break; 153 } 154 return; 155trunc: 156 fputs(tstr, stdout); 157 return; 158} 159