1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <fcntl.h> 30 #include <arpa/tftp.h> 31 #include "snoop.h" 32 33 extern char *dlc_header; 34 char *tftperror(); 35 char *show_type(); 36 37 int 38 interpret_tftp(int flags, struct tftphdr *tftp, int fraglen) 39 { 40 char *name, *mode; 41 extern int src_port, dst_port; 42 int blocksize = fraglen - 4; 43 44 switch (ntohs(tftp->th_opcode)) { 45 case RRQ: 46 case WRQ: 47 add_transient(src_port, interpret_tftp); 48 break; 49 case ERROR: 50 del_transient(src_port); 51 break; 52 } 53 54 if (flags & F_SUM) { 55 switch (ntohs(tftp->th_opcode)) { 56 case RRQ: 57 name = (char *)&tftp->th_stuff; 58 mode = name + (strlen(name) + 1); 59 (void) sprintf(get_sum_line(), 60 "TFTP Read \"%s\" (%s)", name, mode); 61 break; 62 case WRQ: 63 name = (char *)&tftp->th_stuff; 64 mode = name + (strlen(name) + 1); 65 (void) sprintf(get_sum_line(), 66 "TFTP Write \"%s\" (%s)", name, mode); 67 break; 68 case DATA: 69 (void) sprintf(get_sum_line(), 70 "TFTP Data block %d (%d bytes)%s", 71 ntohs(tftp->th_block), 72 blocksize, 73 blocksize < 512 ? " (last block)":""); 74 break; 75 case ACK: 76 (void) sprintf(get_sum_line(), 77 "TFTP Ack block %d", 78 ntohs(tftp->th_block)); 79 break; 80 case ERROR: 81 (void) sprintf(get_sum_line(), 82 "TFTP Error: %s", 83 tftperror(ntohs(tftp->th_code))); 84 break; 85 } 86 } 87 88 if (flags & F_DTAIL) { 89 90 show_header("TFTP: ", "Trivial File Transfer Protocol", fraglen); 91 show_space(); 92 (void) sprintf(get_line((char *)(uintptr_t)tftp->th_opcode - 93 dlc_header, 2), 94 "Opcode = %d (%s)", 95 ntohs(tftp->th_opcode), 96 show_type(ntohs(tftp->th_opcode))); 97 98 switch (ntohs(tftp->th_opcode)) { 99 case RRQ: 100 case WRQ: 101 name = (char *)&tftp->th_stuff; 102 mode = name + (strlen(name) + 1); 103 (void) sprintf( 104 get_line(name - dlc_header, strlen(name) + 1), 105 "File name = \"%s\"", 106 name); 107 (void) sprintf( 108 get_line(mode - dlc_header, strlen(mode) + 1), 109 "Transfer mode = %s", 110 mode); 111 break; 112 113 case DATA: 114 (void) sprintf( 115 get_line((char *)(uintptr_t)tftp->th_block - 116 dlc_header, 2), "Data block = %d%s", 117 ntohs(tftp->th_block), 118 blocksize < 512 ? " (last block)":""); 119 (void) sprintf(get_line((char *)(uintptr_t)tftp->th_data - 120 dlc_header, blocksize), 121 "[ %d bytes of data ]", 122 blocksize); 123 break; 124 125 case ACK: 126 (void) sprintf(get_line((char *)(uintptr_t)tftp->th_block - 127 dlc_header, 2), "Acknowledge block = %d", 128 ntohs(tftp->th_block)); 129 break; 130 131 case ERROR: 132 (void) sprintf(get_line((char *)(uintptr_t)tftp->th_code - 133 dlc_header, 2), "Error = %d (%s)", 134 ntohs(tftp->th_code), 135 tftperror(ntohs(tftp->th_code))); 136 (void) sprintf(get_line((char *)(uintptr_t)tftp->th_data - 137 dlc_header, strlen(tftp->th_data) + 1), 138 "Error string = \"%s\"", tftp->th_data); 139 } 140 } 141 142 return (fraglen); 143 } 144 145 char * 146 show_type(t) 147 int t; 148 { 149 switch (t) { 150 case RRQ: return ("read request"); 151 case WRQ: return ("write request"); 152 case DATA: return ("data packet"); 153 case ACK: return ("acknowledgement"); 154 case ERROR: return ("error"); 155 } 156 return ("?"); 157 } 158 159 char * 160 tftperror(code) 161 unsigned short code; 162 { 163 static char buf[128]; 164 165 switch (code) { 166 case EUNDEF: return ("not defined"); 167 case ENOTFOUND: return ("file not found"); 168 case EACCESS: return ("access violation"); 169 case ENOSPACE: return ("disk full or allocation exceeded"); 170 case EBADOP: return ("illegal TFTP operation"); 171 case EBADID: return ("unknown transfer ID"); 172 case EEXISTS: return ("file already exists"); 173 case ENOUSER: return ("no such user"); 174 } 175 (void) sprintf(buf, "%d", code); 176 177 return (buf); 178 } 179