]> The Tcpdump Group git mirrors - tcpdump/blob - print-ssh.c
Add dissector for SSH version exchange
[tcpdump] / print-ssh.c
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
22 #include <stdio.h>
23 #include <stdlib.h>
24
25 #include "netdissect.h"
26 #include "extract.h"
27
28 static int
29 ssh_print_version(netdissect_options *ndo, const u_char *pptr, u_int len)
30 {
31 u_int idx = 0;
32 const char *pnp;
33
34 if ( GET_U_1(pptr+idx) != 'S' )
35 return 0;
36 idx++;
37 if ( GET_U_1(pptr+idx) != 'S' )
38 return 0;
39 idx++;
40 if ( GET_U_1(pptr+idx) != 'H' )
41 return 0;
42 idx++;
43 if ( GET_U_1(pptr+idx) != '-' )
44 return 0;
45 idx++;
46
47 while (idx < len) {
48 if (GET_U_1(pptr + idx) == '\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 (GET_U_1(pptr + idx) == '\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 (!isascii(GET_U_1(pptr + idx)) ||
76 !isprint(GET_U_1(pptr + idx)) ) {
77 /*
78 * Not a printable ASCII character; treat this
79 * as if it were binary data and don't print it.
80 */
81 goto trunc;
82 }
83 idx++;
84 }
85 trunc:
86 return -1;
87 print:
88 ND_PRINT(": ");
89 /* Capitalize the protocol name */
90 for (pnp = ndo->ndo_protocol; *pnp != '\0'; pnp++)
91 ND_PRINT("%c", ND_TOUPPER((u_char)*pnp));
92 ND_PRINT(": %.*s", (int)idx, pptr);
93 return idx;
94 }
95
96 void
97 ssh_print(netdissect_options *ndo, const u_char *pptr, u_int len)
98 {
99 ndo->ndo_protocol = "ssh";
100
101 ssh_print_version(ndo, pptr, len);
102 }