14edb46e9SPaul Traina /* 24644f044SBill Fenner * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997 34edb46e9SPaul Traina * The Regents of the University of California. All rights reserved. 44edb46e9SPaul Traina * 54edb46e9SPaul Traina * Redistribution and use in source and binary forms, with or without 64edb46e9SPaul Traina * modification, are permitted provided that: (1) source code distributions 74edb46e9SPaul Traina * retain the above copyright notice and this paragraph in its entirety, (2) 84edb46e9SPaul Traina * distributions including binary code include the above copyright notice and 94edb46e9SPaul Traina * this paragraph in its entirety in the documentation or other materials 104edb46e9SPaul Traina * provided with the distribution, and (3) all advertising materials mentioning 114edb46e9SPaul Traina * features or use of this software display the following acknowledgement: 124edb46e9SPaul Traina * ``This product includes software developed by the University of California, 134edb46e9SPaul Traina * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 144edb46e9SPaul Traina * the University nor the names of its contributors may be used to endorse 154edb46e9SPaul Traina * or promote products derived from this software without specific prior 164edb46e9SPaul Traina * written permission. 174edb46e9SPaul Traina * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 184edb46e9SPaul Traina * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 194edb46e9SPaul Traina * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 204edb46e9SPaul Traina * 214edb46e9SPaul Traina * Format and print trivial file transfer protocol packets. 224edb46e9SPaul Traina */ 234edb46e9SPaul Traina 244edb46e9SPaul Traina #ifndef lint 255b0fe478SBruce M Simpson static const char rcsid[] _U_ = 265b0fe478SBruce M Simpson "@(#) $Header: /tcpdump/master/tcpdump/print-tftp.c,v 1.35.2.2 2003/11/16 08:51:50 guy Exp $ (LBL)"; 27b0453382SBill Fenner #endif 28b0453382SBill Fenner 29b0453382SBill Fenner #ifdef HAVE_CONFIG_H 30b0453382SBill Fenner #include "config.h" 314edb46e9SPaul Traina #endif 324edb46e9SPaul Traina 335b0fe478SBruce M Simpson #include <tcpdump-stdinc.h> 344edb46e9SPaul Traina 354644f044SBill Fenner #ifdef SEGSIZE 364644f044SBill Fenner #undef SEGSIZE /* SINIX sucks */ 374644f044SBill Fenner #endif 384edb46e9SPaul Traina #include <arpa/tftp.h> 394edb46e9SPaul Traina 404edb46e9SPaul Traina #include <stdio.h> 414edb46e9SPaul Traina #include <string.h> 424edb46e9SPaul Traina 434edb46e9SPaul Traina #include "interface.h" 444edb46e9SPaul Traina #include "addrtoname.h" 455b0fe478SBruce M Simpson #include "extract.h" 464edb46e9SPaul Traina 474edb46e9SPaul Traina /* op code to string mapping */ 484edb46e9SPaul Traina static struct tok op2str[] = { 494edb46e9SPaul Traina { RRQ, "RRQ" }, /* read request */ 504edb46e9SPaul Traina { WRQ, "WRQ" }, /* write request */ 514edb46e9SPaul Traina { DATA, "DATA" }, /* data packet */ 524edb46e9SPaul Traina { ACK, "ACK" }, /* acknowledgement */ 534edb46e9SPaul Traina { ERROR, "ERROR" }, /* error code */ 544edb46e9SPaul Traina { 0, NULL } 554edb46e9SPaul Traina }; 564edb46e9SPaul Traina 574edb46e9SPaul Traina /* error code to string mapping */ 584edb46e9SPaul Traina static struct tok err2str[] = { 594edb46e9SPaul Traina { EUNDEF, "EUNDEF" }, /* not defined */ 604edb46e9SPaul Traina { ENOTFOUND, "ENOTFOUND" }, /* file not found */ 614edb46e9SPaul Traina { EACCESS, "EACCESS" }, /* access violation */ 624edb46e9SPaul Traina { ENOSPACE, "ENOSPACE" }, /* disk full or allocation exceeded */ 634edb46e9SPaul Traina { EBADOP, "EBADOP" }, /* illegal TFTP operation */ 644edb46e9SPaul Traina { EBADID, "EBADID" }, /* unknown transfer ID */ 654edb46e9SPaul Traina { EEXISTS, "EEXISTS" }, /* file already exists */ 664edb46e9SPaul Traina { ENOUSER, "ENOUSER" }, /* no such user */ 674edb46e9SPaul Traina { 0, NULL } 684edb46e9SPaul Traina }; 694edb46e9SPaul Traina 704edb46e9SPaul Traina /* 714edb46e9SPaul Traina * Print trivial file transfer program requests 724edb46e9SPaul Traina */ 734edb46e9SPaul Traina void 744edb46e9SPaul Traina tftp_print(register const u_char *bp, u_int length) 754edb46e9SPaul Traina { 764edb46e9SPaul Traina register const struct tftphdr *tp; 774edb46e9SPaul Traina register const char *cp; 784edb46e9SPaul Traina register const u_char *p; 794edb46e9SPaul Traina register int opcode, i; 804edb46e9SPaul Traina static char tstr[] = " [|tftp]"; 814edb46e9SPaul Traina 824edb46e9SPaul Traina tp = (const struct tftphdr *)bp; 834edb46e9SPaul Traina 844edb46e9SPaul Traina /* Print length */ 854edb46e9SPaul Traina printf(" %d", length); 864edb46e9SPaul Traina 874edb46e9SPaul Traina /* Print tftp request type */ 884edb46e9SPaul Traina TCHECK(tp->th_opcode); 895b0fe478SBruce M Simpson opcode = EXTRACT_16BITS(&tp->th_opcode); 904edb46e9SPaul Traina cp = tok2str(op2str, "tftp-#%d", opcode); 914edb46e9SPaul Traina printf(" %s", cp); 924edb46e9SPaul Traina /* Bail if bogus opcode */ 934edb46e9SPaul Traina if (*cp == 't') 944edb46e9SPaul Traina return; 954edb46e9SPaul Traina 964edb46e9SPaul Traina switch (opcode) { 974edb46e9SPaul Traina 984edb46e9SPaul Traina case RRQ: 994edb46e9SPaul Traina case WRQ: 1004edb46e9SPaul Traina /* 1014edb46e9SPaul Traina * XXX Not all arpa/tftp.h's specify th_stuff as any 1024edb46e9SPaul Traina * array; use address of th_block instead 1034edb46e9SPaul Traina */ 1044edb46e9SPaul Traina #ifdef notdef 1054edb46e9SPaul Traina p = (u_char *)tp->th_stuff; 1064edb46e9SPaul Traina #else 1074edb46e9SPaul Traina p = (u_char *)&tp->th_block; 1084edb46e9SPaul Traina #endif 1094edb46e9SPaul Traina fputs(" \"", stdout); 1104edb46e9SPaul Traina i = fn_print(p, snapend); 1114edb46e9SPaul Traina putchar('"'); 1125b0fe478SBruce M Simpson 1135b0fe478SBruce M Simpson /* Print the mode and any options */ 1145b0fe478SBruce M Simpson while ((p = (const u_char *)strchr((const char *)p, '\0')) != NULL) { 1155b0fe478SBruce M Simpson if (length <= (u_int)(p - (const u_char *)&tp->th_block)) 1165b0fe478SBruce M Simpson break; 1175b0fe478SBruce M Simpson p++; 1185b0fe478SBruce M Simpson if (*p != '\0') { 1195b0fe478SBruce M Simpson putchar(' '); 1205b0fe478SBruce M Simpson fn_print(p, snapend); 1215b0fe478SBruce M Simpson } 1225b0fe478SBruce M Simpson } 1235b0fe478SBruce M Simpson 1244edb46e9SPaul Traina if (i) 1254edb46e9SPaul Traina goto trunc; 1264edb46e9SPaul Traina break; 1274edb46e9SPaul Traina 1284edb46e9SPaul Traina case ACK: 1294edb46e9SPaul Traina case DATA: 1304edb46e9SPaul Traina TCHECK(tp->th_block); 1315b0fe478SBruce M Simpson printf(" block %d", EXTRACT_16BITS(&tp->th_block)); 1324edb46e9SPaul Traina break; 1334edb46e9SPaul Traina 1344edb46e9SPaul Traina case ERROR: 1354edb46e9SPaul Traina /* Print error code string */ 1364edb46e9SPaul Traina TCHECK(tp->th_code); 1374edb46e9SPaul Traina printf(" %s ", tok2str(err2str, "tftp-err-#%d \"", 1385b0fe478SBruce M Simpson EXTRACT_16BITS(&tp->th_code))); 1394edb46e9SPaul Traina /* Print error message string */ 1404edb46e9SPaul Traina i = fn_print((const u_char *)tp->th_data, snapend); 1414edb46e9SPaul Traina putchar('"'); 1424edb46e9SPaul Traina if (i) 1434edb46e9SPaul Traina goto trunc; 1444edb46e9SPaul Traina break; 1454edb46e9SPaul Traina 1464edb46e9SPaul Traina default: 1474edb46e9SPaul Traina /* We shouldn't get here */ 1484edb46e9SPaul Traina printf("(unknown #%d)", opcode); 1494edb46e9SPaul Traina break; 1504edb46e9SPaul Traina } 1514edb46e9SPaul Traina return; 1524edb46e9SPaul Traina trunc: 1534edb46e9SPaul Traina fputs(tstr, stdout); 1544edb46e9SPaul Traina return; 1554edb46e9SPaul Traina } 156