print-ascii.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /* $NetBSD: print-ascii.c,v 1.1 1999/09/30 14:49:12 sjg Exp $ */
  2. /*-
  3. * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
  4. * All rights reserved.
  5. *
  6. * This code is derived from software contributed to The NetBSD Foundation
  7. * by Alan Barrett and Simon J. Gerraty.
  8. *
  9. * Redistribution and use in source and binary forms, with or without
  10. * modification, are permitted provided that the following conditions
  11. * are met:
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. * 2. Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in the
  16. * documentation and/or other materials provided with the distribution.
  17. * 3. All advertising materials mentioning features or use of this software
  18. * must display the following acknowledgement:
  19. * This product includes software developed by the NetBSD
  20. * Foundation, Inc. and its contributors.
  21. * 4. Neither the name of The NetBSD Foundation nor the names of its
  22. * contributors may be used to endorse or promote products derived
  23. * from this software without specific prior written permission.
  24. *
  25. * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
  26. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  27. * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  28. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
  29. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  30. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  31. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  32. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  33. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  34. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  35. * POSSIBILITY OF SUCH DAMAGE.
  36. */
  37. /* \summary: ASCII packet dump printer */
  38. #ifdef HAVE_CONFIG_H
  39. #include "config.h"
  40. #endif
  41. #include <netdissect-stdinc.h>
  42. #include <stdio.h>
  43. #include "netdissect.h"
  44. #define ASCII_LINELENGTH 300
  45. #define HEXDUMP_BYTES_PER_LINE 16
  46. #define HEXDUMP_SHORTS_PER_LINE (HEXDUMP_BYTES_PER_LINE / 2)
  47. #define HEXDUMP_HEXSTUFF_PER_SHORT 5 /* 4 hex digits and a space */
  48. #define HEXDUMP_HEXSTUFF_PER_LINE \
  49. (HEXDUMP_HEXSTUFF_PER_SHORT * HEXDUMP_SHORTS_PER_LINE)
  50. void
  51. ascii_print(netdissect_options *ndo,
  52. const u_char *cp, u_int length)
  53. {
  54. u_int caplength;
  55. register u_char s;
  56. caplength = (ndo->ndo_snapend >= cp) ? ndo->ndo_snapend - cp : 0;
  57. if (length > caplength)
  58. length = caplength;
  59. ND_PRINT((ndo, "\n"));
  60. while (length > 0) {
  61. s = *cp++;
  62. length--;
  63. if (s == '\r') {
  64. /*
  65. * Don't print CRs at the end of the line; they
  66. * don't belong at the ends of lines on UN*X,
  67. * and the standard I/O library will give us one
  68. * on Windows so we don't need to print one
  69. * ourselves.
  70. *
  71. * In the middle of a line, just print a '.'.
  72. */
  73. if (length > 1 && *cp != '\n')
  74. ND_PRINT((ndo, "."));
  75. } else {
  76. if (!ND_ISGRAPH(s) &&
  77. (s != '\t' && s != ' ' && s != '\n'))
  78. ND_PRINT((ndo, "."));
  79. else
  80. ND_PRINT((ndo, "%c", s));
  81. }
  82. }
  83. }
  84. void
  85. hex_and_ascii_print_with_offset(netdissect_options *ndo, register const char *ident,
  86. register const u_char *cp, register u_int length, register u_int oset)
  87. {
  88. u_int caplength;
  89. register u_int i;
  90. register int s1, s2;
  91. register int nshorts;
  92. char hexstuff[HEXDUMP_SHORTS_PER_LINE*HEXDUMP_HEXSTUFF_PER_SHORT+1], *hsp;
  93. char asciistuff[ASCII_LINELENGTH+1], *asp;
  94. caplength = (ndo->ndo_snapend >= cp) ? ndo->ndo_snapend - cp : 0;
  95. if (length > caplength)
  96. length = caplength;
  97. nshorts = length / sizeof(u_short);
  98. i = 0;
  99. hsp = hexstuff; asp = asciistuff;
  100. while (--nshorts >= 0) {
  101. s1 = *cp++;
  102. s2 = *cp++;
  103. (void)snprintf(hsp, sizeof(hexstuff) - (hsp - hexstuff),
  104. " %02x%02x", s1, s2);
  105. hsp += HEXDUMP_HEXSTUFF_PER_SHORT;
  106. *(asp++) = (ND_ISGRAPH(s1) ? s1 : '.');
  107. *(asp++) = (ND_ISGRAPH(s2) ? s2 : '.');
  108. i++;
  109. if (i >= HEXDUMP_SHORTS_PER_LINE) {
  110. *hsp = *asp = '\0';
  111. ND_PRINT((ndo, "%s0x%04x: %-*s %s",
  112. ident, oset, HEXDUMP_HEXSTUFF_PER_LINE,
  113. hexstuff, asciistuff));
  114. i = 0; hsp = hexstuff; asp = asciistuff;
  115. oset += HEXDUMP_BYTES_PER_LINE;
  116. }
  117. }
  118. if (length & 1) {
  119. s1 = *cp++;
  120. (void)snprintf(hsp, sizeof(hexstuff) - (hsp - hexstuff),
  121. " %02x", s1);
  122. hsp += 3;
  123. *(asp++) = (ND_ISGRAPH(s1) ? s1 : '.');
  124. ++i;
  125. }
  126. if (i > 0) {
  127. *hsp = *asp = '\0';
  128. ND_PRINT((ndo, "%s0x%04x: %-*s %s",
  129. ident, oset, HEXDUMP_HEXSTUFF_PER_LINE,
  130. hexstuff, asciistuff));
  131. }
  132. }
  133. void
  134. hex_and_ascii_print(netdissect_options *ndo, register const char *ident,
  135. register const u_char *cp, register u_int length)
  136. {
  137. hex_and_ascii_print_with_offset(ndo, ident, cp, length, 0);
  138. }
  139. /*
  140. * telnet_print() wants this. It is essentially default_print_unaligned()
  141. */
  142. void
  143. hex_print_with_offset(netdissect_options *ndo,
  144. const char *ident, const u_char *cp, u_int length,
  145. u_int oset)
  146. {
  147. u_int caplength;
  148. register u_int i, s;
  149. register int nshorts;
  150. caplength = (ndo->ndo_snapend >= cp) ? ndo->ndo_snapend - cp : 0;
  151. if (length > caplength)
  152. length = caplength;
  153. nshorts = (u_int) length / sizeof(u_short);
  154. i = 0;
  155. while (--nshorts >= 0) {
  156. if ((i++ % 8) == 0) {
  157. ND_PRINT((ndo,"%s0x%04x: ", ident, oset));
  158. oset += HEXDUMP_BYTES_PER_LINE;
  159. }
  160. s = *cp++;
  161. ND_PRINT((ndo," %02x%02x", s, *cp++));
  162. }
  163. if (length & 1) {
  164. if ((i % 8) == 0)
  165. ND_PRINT((ndo,"%s0x%04x: ", ident, oset));
  166. ND_PRINT((ndo," %02x", *cp));
  167. }
  168. }
  169. /*
  170. * just for completeness
  171. */
  172. void
  173. hex_print(netdissect_options *ndo,const char *ident, const u_char *cp, u_int length)
  174. {
  175. hex_print_with_offset(ndo, ident, cp, length, 0);
  176. }
  177. #ifdef MAIN
  178. int
  179. main(int argc, char *argv[])
  180. {
  181. hex_print("\n\t", "Hello, World!\n", 14);
  182. printf("\n");
  183. hex_and_ascii_print("\n\t", "Hello, World!\n", 14);
  184. printf("\n");
  185. ascii_print("Hello, World!\n", 14);
  186. printf("\n");
  187. #define TMSG "Now is the winter of our discontent...\n"
  188. hex_print_with_offset("\n\t", TMSG, sizeof(TMSG) - 1, 0x100);
  189. printf("\n");
  190. hex_and_ascii_print_with_offset("\n\t", TMSG, sizeof(TMSG) - 1, 0x100);
  191. printf("\n");
  192. exit(0);
  193. }
  194. #endif /* MAIN */