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.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 */ 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 { 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 /* 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; 158 trunc: 159 fputs(tstr, stdout); 160 return; 161 } 162