1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (C) 2008 Edwin Groothuis. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 #include <sys/types.h> 29 #include <sys/socket.h> 30 #include <sys/stat.h> 31 32 #include <netinet/in.h> 33 #include <arpa/inet.h> 34 #include <arpa/tftp.h> 35 36 #include <assert.h> 37 #include <errno.h> 38 #include <poll.h> 39 #include <stddef.h> 40 #include <stdio.h> 41 #include <stdlib.h> 42 #include <string.h> 43 #include <syslog.h> 44 #include <unistd.h> 45 46 #include "tftp-file.h" 47 #include "tftp-io.h" 48 #include "tftp-utils.h" 49 #include "tftp-options.h" 50 51 struct sockaddr_storage peer_sock; 52 struct sockaddr_storage me_sock; 53 54 static int send_packet(int peer, uint16_t block, char *pkt, int size); 55 56 static struct errmsg { 57 int e_code; 58 const char *e_msg; 59 } errmsgs[] = { 60 { EUNDEF, "Undefined error code" }, 61 { ENOTFOUND, "File not found" }, 62 { EACCESS, "Access violation" }, 63 { ENOSPACE, "Disk full or allocation exceeded" }, 64 { EBADOP, "Illegal TFTP operation" }, 65 { EBADID, "Unknown transfer ID" }, 66 { EEXISTS, "File already exists" }, 67 { ENOUSER, "No such user" }, 68 { EOPTNEG, "Option negotiation" }, 69 { -1, NULL } 70 }; 71 72 #define DROPPACKET(s) \ 73 if (packetdroppercentage != 0 && \ 74 arc4random()%100 < packetdroppercentage) { \ 75 tftp_log(LOG_DEBUG, "Artificial packet drop in %s", s); \ 76 return; \ 77 } 78 #define DROPPACKETn(s,n) \ 79 if (packetdroppercentage != 0 && \ 80 arc4random()%100 < packetdroppercentage) { \ 81 tftp_log(LOG_DEBUG, "Artificial packet drop in %s", s); \ 82 return (n); \ 83 } 84 85 const char * 86 errtomsg(int error) 87 { 88 static char ebuf[40]; 89 struct errmsg *pe; 90 91 if (error == 0) 92 return ("success"); 93 for (pe = errmsgs; pe->e_code >= 0; pe++) 94 if (pe->e_code == error) 95 return (pe->e_msg); 96 snprintf(ebuf, sizeof(ebuf), "error %d", error); 97 return (ebuf); 98 } 99 100 static int 101 send_packet(int peer, uint16_t block, char *pkt, int size) 102 { 103 int i; 104 int t = 1; 105 106 for (i = 0; i < 12 ; i++) { 107 DROPPACKETn("send_packet", 0); 108 109 if (sendto(peer, pkt, size, 0, (struct sockaddr *)&peer_sock, 110 peer_sock.ss_len) == size) { 111 if (i) 112 tftp_log(LOG_ERR, 113 "%s block %d, attempt %d successful", 114 packettype(ntohs(((struct tftphdr *) 115 (pkt))->th_opcode)), block, i); 116 return (0); 117 } 118 tftp_log(LOG_ERR, 119 "%s block %d, attempt %d failed (Error %d: %s)", 120 packettype(ntohs(((struct tftphdr *)(pkt))->th_opcode)), 121 block, i, errno, strerror(errno)); 122 sleep(t); 123 if (t < 32) 124 t <<= 1; 125 } 126 tftp_log(LOG_ERR, "send_packet: %s", strerror(errno)); 127 return (1); 128 } 129 130 /* 131 * Send an ERROR packet (error message). 132 * Error code passed in is one of the 133 * standard TFTP codes, or a UNIX errno 134 * offset by 100. 135 */ 136 void 137 send_error(int peer, int error) 138 { 139 struct tftphdr *tp; 140 int length; 141 struct errmsg *pe; 142 char buf[MAXPKTSIZE]; 143 144 if (debug & DEBUG_PACKETS) 145 tftp_log(LOG_DEBUG, "Sending ERROR %d", error); 146 147 DROPPACKET("send_error"); 148 149 tp = (struct tftphdr *)buf; 150 tp->th_opcode = htons((u_short)ERROR); 151 tp->th_code = htons((u_short)error); 152 for (pe = errmsgs; pe->e_code >= 0; pe++) 153 if (pe->e_code == error) 154 break; 155 if (pe->e_code < 0) { 156 pe->e_msg = strerror(error - 100); 157 tp->th_code = EUNDEF; /* set 'undef' errorcode */ 158 } 159 snprintf(tp->th_msg, MAXPKTSIZE - 4, "%s%n", pe->e_msg, &length); 160 length += 5; /* header and terminator */ 161 162 if (debug & DEBUG_PACKETS) 163 tftp_log(LOG_DEBUG, "Sending ERROR %d: %s", error, tp->th_msg); 164 165 if (sendto(peer, buf, length, 0, 166 (struct sockaddr *)&peer_sock, peer_sock.ss_len) != length) 167 tftp_log(LOG_ERR, "send_error: %s", strerror(errno)); 168 } 169 170 /* 171 * Send an WRQ packet (write request). 172 */ 173 int 174 send_wrq(int peer, char *filename, char *mode) 175 { 176 int n; 177 struct tftphdr *tp; 178 char *bp; 179 char buf[MAXPKTSIZE]; 180 int size; 181 182 if (debug & DEBUG_PACKETS) 183 tftp_log(LOG_DEBUG, "Sending WRQ: filename: '%s', mode '%s'", 184 filename, mode 185 ); 186 187 DROPPACKETn("send_wrq", 0); 188 189 tp = (struct tftphdr *)buf; 190 tp->th_opcode = htons((u_short)WRQ); 191 size = offsetof(struct tftphdr, th_stuff); 192 193 bp = tp->th_stuff; 194 strlcpy(bp, filename, sizeof(buf) - size); 195 bp += strlen(filename); 196 *bp = 0; 197 bp++; 198 size += strlen(filename) + 1; 199 200 strlcpy(bp, mode, sizeof(buf) - size); 201 bp += strlen(mode); 202 *bp = 0; 203 bp++; 204 size += strlen(mode) + 1; 205 206 if (options_rfc_enabled) 207 size += make_options(peer, bp, sizeof(buf) - size); 208 209 n = sendto(peer, buf, size, 0, 210 (struct sockaddr *)&peer_sock, peer_sock.ss_len); 211 if (n != size) { 212 tftp_log(LOG_ERR, "send_wrq: %s", strerror(errno)); 213 return (1); 214 } 215 return (0); 216 } 217 218 /* 219 * Send an RRQ packet (write request). 220 */ 221 int 222 send_rrq(int peer, char *filename, char *mode) 223 { 224 int n; 225 struct tftphdr *tp; 226 char *bp; 227 char buf[MAXPKTSIZE]; 228 int size; 229 230 if (debug & DEBUG_PACKETS) 231 tftp_log(LOG_DEBUG, "Sending RRQ: filename: '%s', mode '%s'", 232 filename, mode 233 ); 234 235 DROPPACKETn("send_rrq", 0); 236 237 tp = (struct tftphdr *)buf; 238 tp->th_opcode = htons((u_short)RRQ); 239 size = offsetof(struct tftphdr, th_stuff); 240 241 bp = tp->th_stuff; 242 strlcpy(bp, filename, sizeof(buf) - size); 243 bp += strlen(filename); 244 *bp = 0; 245 bp++; 246 size += strlen(filename) + 1; 247 248 strlcpy(bp, mode, sizeof(buf) - size); 249 bp += strlen(mode); 250 *bp = 0; 251 bp++; 252 size += strlen(mode) + 1; 253 254 if (options_rfc_enabled) { 255 options_set_request(OPT_TSIZE, "0"); 256 size += make_options(peer, bp, sizeof(buf) - size); 257 } 258 259 n = sendto(peer, buf, size, 0, 260 (struct sockaddr *)&peer_sock, peer_sock.ss_len); 261 if (n != size) { 262 tftp_log(LOG_ERR, "send_rrq: %d %s", n, strerror(errno)); 263 return (1); 264 } 265 return (0); 266 } 267 268 /* 269 * Send an OACK packet (option acknowledgement). 270 */ 271 int 272 send_oack(int peer) 273 { 274 struct tftphdr *tp; 275 int size, i, n; 276 char *bp; 277 char buf[MAXPKTSIZE]; 278 279 if (debug & DEBUG_PACKETS) 280 tftp_log(LOG_DEBUG, "Sending OACK"); 281 282 DROPPACKETn("send_oack", 0); 283 284 /* 285 * Send back an options acknowledgement (only the ones with 286 * a reply for) 287 */ 288 tp = (struct tftphdr *)buf; 289 bp = buf + 2; 290 size = sizeof(buf) - 2; 291 tp->th_opcode = htons((u_short)OACK); 292 for (i = 0; options[i].o_type != NULL; i++) { 293 if (options[i].o_reply != NULL) { 294 n = snprintf(bp, size, "%s%c%s", options[i].o_type, 295 0, options[i].o_reply); 296 bp += n+1; 297 size -= n+1; 298 if (size < 0) { 299 tftp_log(LOG_ERR, "oack: buffer overflow"); 300 exit(1); 301 } 302 } 303 } 304 size = bp - buf; 305 306 if (sendto(peer, buf, size, 0, 307 (struct sockaddr *)&peer_sock, peer_sock.ss_len) != size) { 308 tftp_log(LOG_INFO, "send_oack: %s", strerror(errno)); 309 return (1); 310 } 311 312 return (0); 313 } 314 315 /* 316 * Send an ACK packet (acknowledgement). 317 */ 318 int 319 send_ack(int fp, uint16_t block) 320 { 321 struct tftphdr *tp; 322 int size; 323 char buf[MAXPKTSIZE]; 324 325 if (debug & DEBUG_PACKETS) 326 tftp_log(LOG_DEBUG, "Sending ACK for block %d", block); 327 328 DROPPACKETn("send_ack", 0); 329 330 tp = (struct tftphdr *)buf; 331 tp->th_opcode = htons((u_short)ACK); 332 tp->th_block = htons((u_short)block); 333 size = 4; 334 335 if (sendto(fp, buf, size, 0, 336 (struct sockaddr *)&peer_sock, peer_sock.ss_len) != size) { 337 tftp_log(LOG_INFO, "send_ack: %s", strerror(errno)); 338 return (1); 339 } 340 341 return (0); 342 } 343 344 /* 345 * Send a DATA packet 346 */ 347 int 348 send_data(int peer, uint16_t block, char *data, int size) 349 { 350 char buf[MAXPKTSIZE]; 351 struct tftphdr *pkt; 352 int n; 353 354 if (debug & DEBUG_PACKETS) 355 tftp_log(LOG_DEBUG, "Sending DATA packet %d of %d bytes", 356 block, size); 357 358 DROPPACKETn("send_data", 0); 359 360 pkt = (struct tftphdr *)buf; 361 362 pkt->th_opcode = htons((u_short)DATA); 363 pkt->th_block = htons((u_short)block); 364 memcpy(pkt->th_data, data, size); 365 366 n = send_packet(peer, block, (char *)pkt, size + 4); 367 return (n); 368 } 369 370 371 /* 372 * Receive a packet 373 * 374 * If timeout is negative, no error will be logged on timeout. 375 */ 376 int 377 receive_packet(int peer, char *data, int size, struct sockaddr_storage *from, 378 int timeout) 379 { 380 struct pollfd pfd; 381 struct tftphdr *pkt; 382 struct sockaddr_storage from_local; 383 struct sockaddr_storage *pfrom; 384 socklen_t fromlen; 385 int n; 386 387 if (debug & DEBUG_PACKETS) 388 tftp_log(LOG_DEBUG, 389 "Waiting %d seconds for packet", timeoutpacket); 390 391 pkt = (struct tftphdr *)data; 392 393 pfd.fd = peer; 394 pfd.events = POLLIN; 395 if (poll(&pfd, 1, 1000 * (timeout < 0 ? -timeout : timeout)) < 1) { 396 if (timeout > 0) 397 tftp_log(LOG_ERR, "receive_packet: timeout"); 398 return (RP_TIMEOUT); 399 } 400 401 pfrom = (from == NULL) ? &from_local : from; 402 fromlen = sizeof(*pfrom); 403 n = recvfrom(peer, data, size, 0, (struct sockaddr *)pfrom, &fromlen); 404 405 DROPPACKETn("receive_packet", RP_TIMEOUT); 406 407 if (n < 0) { 408 /* No idea what could have happened if it isn't a timeout */ 409 tftp_log(LOG_ERR, "receive_packet: %s", strerror(errno)); 410 return (RP_RECVFROM); 411 } 412 if (n < 4) { 413 tftp_log(LOG_ERR, 414 "receive_packet: packet too small (%d bytes)", n); 415 return (RP_TOOSMALL); 416 } 417 418 pkt->th_opcode = ntohs((u_short)pkt->th_opcode); 419 if (pkt->th_opcode == DATA || 420 pkt->th_opcode == ACK) 421 pkt->th_block = ntohs((u_short)pkt->th_block); 422 423 if (pkt->th_opcode == DATA && n > pktsize) { 424 tftp_log(LOG_ERR, "receive_packet: packet too big"); 425 return (RP_TOOBIG); 426 } 427 428 if (((struct sockaddr_in *)(pfrom))->sin_addr.s_addr != 429 ((struct sockaddr_in *)(&peer_sock))->sin_addr.s_addr) { 430 tftp_log(LOG_ERR, 431 "receive_packet: received packet from wrong source"); 432 return (RP_WRONGSOURCE); 433 } 434 435 if (pkt->th_opcode == ERROR) { 436 tftp_log(pkt->th_code == EUNDEF ? LOG_DEBUG : LOG_ERR, 437 "Got ERROR packet: %s", pkt->th_msg); 438 return (RP_ERROR); 439 } 440 441 if (debug & DEBUG_PACKETS) 442 tftp_log(LOG_DEBUG, "Received %d bytes in a %s packet", 443 n, packettype(pkt->th_opcode)); 444 445 return n - 4; 446 } 447