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