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 25 static const char rcsid[] _U_ = 26 "@(#) $Header: /tcpdump/master/tcpdump/print-tftp.c,v 1.39 2008-04-11 16:47:38 gianluca 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 */ 48 static struct tok op2str[] = { 49 { RRQ, "RRQ" }, /* read request */ 50 { WRQ, "WRQ" }, /* write request */ 51 { DATA, "DATA" }, /* data packet */ 52 { ACK, "ACK" }, /* acknowledgement */ 53 { TFTP_ERROR, "ERROR" }, /* error code */ 54 { OACK, "OACK" }, /* option acknowledgement */ 55 { 0, NULL } 56 }; 57 58 /* error code to string mapping */ 59 static 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 */ 74 void 75 tftp_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 p = (u_char *)tp->th_stuff; 103 putchar(' '); 104 /* Print filename or first option */ 105 if (opcode != OACK) 106 putchar('"'); 107 i = fn_print(p, snapend); 108 if (opcode != OACK) 109 putchar('"'); 110 111 /* Print the mode (RRQ and WRQ only) and any options */ 112 while ((p = (const u_char *)strchr((const char *)p, '\0')) != NULL) { 113 if (length <= (u_int)(p - (const u_char *)&tp->th_block)) 114 break; 115 p++; 116 if (*p != '\0') { 117 putchar(' '); 118 fn_print(p, snapend); 119 } 120 } 121 122 if (i) 123 goto trunc; 124 break; 125 126 case ACK: 127 case DATA: 128 TCHECK(tp->th_block); 129 printf(" block %d", EXTRACT_16BITS(&tp->th_block)); 130 break; 131 132 case TFTP_ERROR: 133 /* Print error code string */ 134 TCHECK(tp->th_code); 135 printf(" %s \"", tok2str(err2str, "tftp-err-#%d \"", 136 EXTRACT_16BITS(&tp->th_code))); 137 /* Print error message string */ 138 i = fn_print((const u_char *)tp->th_data, snapend); 139 putchar('"'); 140 if (i) 141 goto trunc; 142 break; 143 144 default: 145 /* We shouldn't get here */ 146 printf("(unknown #%d)", opcode); 147 break; 148 } 149 return; 150 trunc: 151 fputs(tstr, stdout); 152 return; 153 } 154