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 (c) 1991 by Sun Microsystems, Inc. 24 */ 25 26 #ident "%Z%%M% %I% %E% SMI" 27 28 #include <fcntl.h> 29 #include <arpa/tftp.h> 30 #include "snoop.h" 31 32 extern char *dlc_header; 33 char *tftperror(); 34 char *show_type(); 35 36 interpret_tftp(flags, tftp, fraglen) 37 int flags; 38 struct tftphdr *tftp; 39 int fraglen; 40 { 41 char *name, *mode; 42 extern int src_port, dst_port; 43 int blocksize = fraglen - 4; 44 45 switch (ntohs(tftp->th_opcode)) { 46 case RRQ: 47 case WRQ: 48 add_transient(src_port, interpret_tftp); 49 break; 50 case ERROR: 51 del_transient(src_port); 52 break; 53 } 54 55 if (flags & F_SUM) { 56 switch (ntohs(tftp->th_opcode)) { 57 case RRQ: 58 name = (char *) &tftp->th_stuff; 59 mode = name + (strlen(name) + 1); 60 (void) sprintf(get_sum_line(), 61 "TFTP Read \"%s\" (%s)", name, mode); 62 break; 63 case WRQ: 64 name = (char *) &tftp->th_stuff; 65 mode = name + (strlen(name) + 1); 66 (void) sprintf(get_sum_line(), 67 "TFTP Write \"%s\" (%s)", name, mode); 68 break; 69 case DATA: 70 (void) sprintf(get_sum_line(), 71 "TFTP Data block %d (%d bytes)%s", 72 ntohs(tftp->th_block), 73 blocksize, 74 blocksize < 512 ? " (last block)":""); 75 break; 76 case ACK: 77 (void) sprintf(get_sum_line(), 78 "TFTP Ack block %d", 79 ntohs(tftp->th_block)); 80 break; 81 case ERROR: 82 (void) sprintf(get_sum_line(), 83 "TFTP Error: %s", 84 tftperror(ntohs(tftp->th_code))); 85 break; 86 } 87 } 88 89 if (flags & F_DTAIL) { 90 91 show_header("TFTP: ", "Trivial File Transfer Protocol", fraglen); 92 show_space(); 93 (void) sprintf(get_line((char *)tftp->th_opcode - 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 *)tftp->th_block - dlc_header, 2), 116 "Data block = %d%s", 117 ntohs(tftp->th_block), 118 blocksize < 512 ? " (last block)":""); 119 (void) sprintf( 120 get_line((char *)tftp->th_data - dlc_header, blocksize), 121 "[ %d bytes of data ]", 122 blocksize); 123 break; 124 125 case ACK: 126 (void) sprintf( 127 get_line((char *)tftp->th_block - dlc_header, 2), 128 "Acknowledge block = %d", 129 ntohs(tftp->th_block)); 130 break; 131 132 case ERROR: 133 (void) sprintf( 134 get_line((char *)tftp->th_code - dlc_header, 2), 135 "Error = %d (%s)", 136 ntohs(tftp->th_code), 137 tftperror(ntohs(tftp->th_code))); 138 (void) sprintf( 139 get_line((char *)tftp->th_data - dlc_header, 140 strlen(tftp->th_data) + 1), 141 "Error string = \"%s\"", 142 tftp->th_data); 143 } 144 } 145 146 return (fraglen); 147 } 148 149 char * 150 show_type(t) 151 int t; 152 { 153 switch (t) { 154 case RRQ: return ("read request"); 155 case WRQ: return ("write request"); 156 case DATA: return ("data packet"); 157 case ACK: return ("acknowledgement"); 158 case ERROR: return ("error"); 159 } 160 return ("?"); 161 } 162 163 char * 164 tftperror(code) 165 unsigned short code; 166 { 167 static char buf[128]; 168 169 switch (code) { 170 case EUNDEF: return ("not defined"); 171 case ENOTFOUND: return ("file not found"); 172 case EACCESS: return ("access violation"); 173 case ENOSPACE: return ("disk full or allocation exceeded"); 174 case EBADOP: return ("illegal TFTP operation"); 175 case EBADID: return ("unknown transfer ID"); 176 case EEXISTS: return ("file already exists"); 177 case ENOUSER: return ("no such user"); 178 } 179 (void) sprintf(buf, "%d", code); 180 181 return (buf); 182 } 183