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