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