1 /* $OpenBSD: print-tftp.c,v 1.8 2007/10/07 16:41:05 deraadt Exp $ */ 2 3 /* 4 * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that: (1) source code distributions 9 * retain the above copyright notice and this paragraph in its entirety, (2) 10 * distributions including binary code include the above copyright notice and 11 * this paragraph in its entirety in the documentation or other materials 12 * provided with the distribution, and (3) all advertising materials mentioning 13 * features or use of this software display the following acknowledgement: 14 * ``This product includes software developed by the University of California, 15 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 16 * the University nor the names of its contributors may be used to endorse 17 * or promote products derived from this software without specific prior 18 * written permission. 19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 20 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 22 * 23 * Format and print trivial file transfer protocol packets. 24 */ 25 26 #ifndef lint 27 static const char rcsid[] = 28 "@(#) $Id: print-tftp.c,v 1.8 2007/10/07 16:41:05 deraadt Exp $ (LBL)"; 29 #endif 30 31 #include <sys/param.h> 32 #include <sys/time.h> 33 34 #include <netinet/in.h> 35 36 #ifdef SEGSIZE 37 #undef SEGSIZE /* SINIX sucks */ 38 #endif 39 #include <arpa/tftp.h> 40 41 #include <ctype.h> 42 #include <stdio.h> 43 #include <string.h> 44 45 #include "interface.h" 46 #include "addrtoname.h" 47 48 /* op code to string mapping */ 49 static struct tok op2str[] = { 50 { RRQ, "RRQ" }, /* read request */ 51 { WRQ, "WRQ" }, /* write request */ 52 { DATA, "DATA" }, /* data packet */ 53 { ACK, "ACK" }, /* acknowledgement */ 54 { ERROR, "ERROR" }, /* error code */ 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 = ntohs(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 /* 102 * XXX Not all arpa/tftp.h's specify th_stuff as any 103 * array; use address of th_block instead 104 */ 105 #ifdef notdef 106 p = (u_char *)tp->th_stuff; 107 #else 108 p = (u_char *)&tp->th_block; 109 #endif 110 fputs(" \"", stdout); 111 i = fn_print(p, snapend); 112 putchar('"'); 113 if (i) 114 goto trunc; 115 break; 116 117 case ACK: 118 case DATA: 119 TCHECK(tp->th_block); 120 printf(" block %d", ntohs(tp->th_block)); 121 break; 122 123 case ERROR: 124 /* Print error code string */ 125 TCHECK(tp->th_code); 126 printf(" %s ", tok2str(err2str, "tftp-err-#%d \"", 127 ntohs(tp->th_code))); 128 /* Print error message string */ 129 i = fn_print((const u_char *)tp->th_data, snapend); 130 putchar('"'); 131 if (i) 132 goto trunc; 133 break; 134 135 default: 136 /* We shouldn't get here */ 137 printf("(unknown #%d)", opcode); 138 break; 139 } 140 return; 141 trunc: 142 fputs(tstr, stdout); 143 return; 144 } 145