1/*
2 * Redistribution and use in source and binary forms, with or without
3 * modification, are permitted provided that: (1) source code
4 * distributions retain the above copyright notice and this paragraph
5 * in its entirety, and (2) distributions including binary code include
6 * the above copyright notice and this paragraph in its entirety in
7 * the documentation or other materials provided with the distribution.
8 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
9 * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
10 * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
11 * FOR A PARTICULAR PURPOSE.
12 */
13
14/* \summary: Secure Shell (SSH) printer */
15
16#ifdef HAVE_CONFIG_H
17#include <config.h>
18#endif
19
20#include "netdissect-stdinc.h"
21#include "netdissect-ctype.h"
22
23#include "netdissect.h"
24#include "extract.h"
25
26static int
27ssh_print_version(netdissect_options *ndo, const u_char *pptr, u_int len)
28{
29	u_int idx = 0;
30
31	if ( GET_U_1(pptr+idx) != 'S' )
32		return 0;
33	idx++;
34	if ( GET_U_1(pptr+idx) != 'S' )
35		return 0;
36	idx++;
37	if ( GET_U_1(pptr+idx) != 'H' )
38		return 0;
39	idx++;
40	if ( GET_U_1(pptr+idx) != '-' )
41		return 0;
42	idx++;
43
44	while (idx < len) {
45		u_char c;
46
47		c = GET_U_1(pptr + idx);
48		if (c == '\n') {
49			/*
50			 * LF without CR; end of line.
51			 * Skip the LF and print the line, with the
52			 * exception of the LF.
53			 */
54			goto print;
55		} else if (c == '\r') {
56			/* CR - any LF? */
57			if ((idx+1) >= len) {
58				/* not in this packet */
59				goto trunc;
60			}
61			if (GET_U_1(pptr + idx + 1) == '\n') {
62				/*
63				 * CR-LF; end of line.
64				 * Skip the CR-LF and print the line, with
65				 * the exception of the CR-LF.
66				 */
67				goto print;
68			}
69
70			/*
71			 * CR followed by something else; treat this as
72			 * if it were binary data and don't print it.
73			 */
74			goto trunc;
75		} else if (!ND_ASCII_ISPRINT(c) ) {
76			/*
77			 * Not a printable ASCII character; treat this
78			 * as if it were binary data and don't print it.
79			 */
80			goto trunc;
81		}
82		idx++;
83	}
84trunc:
85	return -1;
86print:
87	ND_PRINT(": ");
88	nd_print_protocol_caps(ndo);
89	ND_PRINT(": %.*s", (int)idx, pptr);
90	return idx;
91}
92
93void
94ssh_print(netdissect_options *ndo, const u_char *pptr, u_int len)
95{
96	ndo->ndo_protocol = "ssh";
97
98	ssh_print_version(ndo, pptr, len);
99}
100