1 /* $OpenBSD: print-tftp.c,v 1.10 2009/10/27 23:59:57 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 #include <sys/param.h> 27 #include <sys/time.h> 28 29 #include <netinet/in.h> 30 31 #ifdef SEGSIZE 32 #undef SEGSIZE /* SINIX sucks */ 33 #endif 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 putchar('"'); 125 i = fn_print((const u_char *)tp->th_data, snapend); 126 putchar('"'); 127 if (i) 128 goto trunc; 129 break; 130 131 default: 132 /* We shouldn't get here */ 133 printf("(unknown #%d)", opcode); 134 break; 135 } 136 return; 137 trunc: 138 fputs(tstr, stdout); 139 return; 140 } 141