print-tftp.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /*
  2. * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997
  3. * The Regents of the University of California. All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that: (1) source code distributions
  7. * retain the above copyright notice and this paragraph in its entirety, (2)
  8. * distributions including binary code include the above copyright notice and
  9. * this paragraph in its entirety in the documentation or other materials
  10. * provided with the distribution, and (3) all advertising materials mentioning
  11. * features or use of this software display the following acknowledgement:
  12. * ``This product includes software developed by the University of California,
  13. * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  14. * the University nor the names of its contributors may be used to endorse
  15. * or promote products derived from this software without specific prior
  16. * written permission.
  17. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  18. * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  19. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  20. */
  21. /* \summary: Trivial File Transfer Protocol (TFTP) printer */
  22. #ifdef HAVE_CONFIG_H
  23. #include "config.h"
  24. #endif
  25. #include <netdissect-stdinc.h>
  26. #include <string.h>
  27. #include "netdissect.h"
  28. #include "extract.h"
  29. /*
  30. * Trivial File Transfer Protocol (IEN-133)
  31. */
  32. /*
  33. * Packet types.
  34. */
  35. #define RRQ 01 /* read request */
  36. #define WRQ 02 /* write request */
  37. #define DATA 03 /* data packet */
  38. #define ACK 04 /* acknowledgement */
  39. #define TFTP_ERROR 05 /* error code */
  40. #define OACK 06 /* option acknowledgement */
  41. /*
  42. * Error codes.
  43. */
  44. #define EUNDEF 0 /* not defined */
  45. #define ENOTFOUND 1 /* file not found */
  46. #define EACCESS 2 /* access violation */
  47. #define ENOSPACE 3 /* disk full or allocation exceeded */
  48. #define EBADOP 4 /* illegal TFTP operation */
  49. #define EBADID 5 /* unknown transfer ID */
  50. #define EEXISTS 6 /* file already exists */
  51. #define ENOUSER 7 /* no such user */
  52. static const char tstr[] = " [|tftp]";
  53. /* op code to string mapping */
  54. static const struct tok op2str[] = {
  55. { RRQ, "RRQ" }, /* read request */
  56. { WRQ, "WRQ" }, /* write request */
  57. { DATA, "DATA" }, /* data packet */
  58. { ACK, "ACK" }, /* acknowledgement */
  59. { TFTP_ERROR, "ERROR" }, /* error code */
  60. { OACK, "OACK" }, /* option acknowledgement */
  61. { 0, NULL }
  62. };
  63. /* error code to string mapping */
  64. static const struct tok err2str[] = {
  65. { EUNDEF, "EUNDEF" }, /* not defined */
  66. { ENOTFOUND, "ENOTFOUND" }, /* file not found */
  67. { EACCESS, "EACCESS" }, /* access violation */
  68. { ENOSPACE, "ENOSPACE" }, /* disk full or allocation exceeded */
  69. { EBADOP, "EBADOP" }, /* illegal TFTP operation */
  70. { EBADID, "EBADID" }, /* unknown transfer ID */
  71. { EEXISTS, "EEXISTS" }, /* file already exists */
  72. { ENOUSER, "ENOUSER" }, /* no such user */
  73. { 0, NULL }
  74. };
  75. /*
  76. * Print trivial file transfer program requests
  77. */
  78. void
  79. tftp_print(netdissect_options *ndo,
  80. register const u_char *bp, u_int length)
  81. {
  82. register const char *cp;
  83. register int opcode;
  84. u_int ui;
  85. /* Print length */
  86. ND_PRINT((ndo, " %d", length));
  87. /* Print tftp request type */
  88. if (length < 2)
  89. goto trunc;
  90. ND_TCHECK_16BITS(bp);
  91. opcode = EXTRACT_16BITS(bp);
  92. cp = tok2str(op2str, "tftp-#%d", opcode);
  93. ND_PRINT((ndo, " %s", cp));
  94. /* Bail if bogus opcode */
  95. if (*cp == 't')
  96. return;
  97. bp += 2;
  98. length -= 2;
  99. switch (opcode) {
  100. case RRQ:
  101. case WRQ:
  102. if (length == 0)
  103. goto trunc;
  104. ND_PRINT((ndo, " "));
  105. /* Print filename */
  106. ND_PRINT((ndo, "\""));
  107. ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
  108. ND_PRINT((ndo, "\""));
  109. if (ui == 0)
  110. goto trunc;
  111. bp += ui;
  112. length -= ui;
  113. /* Print the mode - RRQ and WRQ only */
  114. if (length == 0)
  115. goto trunc; /* no mode */
  116. ND_PRINT((ndo, " "));
  117. ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
  118. if (ui == 0)
  119. goto trunc;
  120. bp += ui;
  121. length -= ui;
  122. /* Print options, if any */
  123. while (length != 0) {
  124. ND_TCHECK(*bp);
  125. if (*bp != '\0')
  126. ND_PRINT((ndo, " "));
  127. ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
  128. if (ui == 0)
  129. goto trunc;
  130. bp += ui;
  131. length -= ui;
  132. }
  133. break;
  134. case OACK:
  135. /* Print options */
  136. while (length != 0) {
  137. ND_TCHECK(*bp);
  138. if (*bp != '\0')
  139. ND_PRINT((ndo, " "));
  140. ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
  141. if (ui == 0)
  142. goto trunc;
  143. bp += ui;
  144. length -= ui;
  145. }
  146. break;
  147. case ACK:
  148. case DATA:
  149. if (length < 2)
  150. goto trunc; /* no block number */
  151. ND_TCHECK_16BITS(bp);
  152. ND_PRINT((ndo, " block %d", EXTRACT_16BITS(bp)));
  153. break;
  154. case TFTP_ERROR:
  155. /* Print error code string */
  156. if (length < 2)
  157. goto trunc; /* no error code */
  158. ND_TCHECK_16BITS(bp);
  159. ND_PRINT((ndo, " %s", tok2str(err2str, "tftp-err-#%d \"",
  160. EXTRACT_16BITS(bp))));
  161. bp += 2;
  162. length -= 2;
  163. /* Print error message string */
  164. if (length == 0)
  165. goto trunc; /* no error message */
  166. ND_PRINT((ndo, " \""));
  167. ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
  168. ND_PRINT((ndo, "\""));
  169. if (ui == 0)
  170. goto trunc;
  171. break;
  172. default:
  173. /* We shouldn't get here */
  174. ND_PRINT((ndo, "(unknown #%d)", opcode));
  175. break;
  176. }
  177. return;
  178. trunc:
  179. ND_PRINT((ndo, "%s", tstr));
  180. return;
  181. }