1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright (c) 1996-1998,2001 by Sun Microsystems, Inc.
24 * All rights reserved.
25 */
26
27 /*
28 * Protocol interpreter for the Hypertext Transfer Protocol (HTTP)
29 *
30 * Relevant standards:
31 * Berners-Lee, T., et al: Hypertext Transfer Protocol -- HTTP/1.0.
32 * RFC 1945, May 1996
33 * Fielding, R., et al: Hypertext Transfer Protocol -- HTTP/1.1.
34 * RFC 2068, June 1999
35 */
36
37 #include <netinet/in.h>
38 #include <stdio.h>
39 #include <string.h>
40 #include <ctype.h>
41 #include "snoop.h"
42
43 #define CR 13 /* "carriage return" character */
44 #define LF 10 /* "line feed" character */
45
46 /*
47 * Summary lines: packet contents starting with less than MINCHARS
48 * printable characters will not be printed. MAXCHARS is the maximum
49 * number of characters printed.
50 * Detail lines: NLINES is the maximum number of content lines to print
51 */
52 #define MINCHARS 10
53 #define MAXCHARS 80
54 #define NLINES 5
55
56 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
57
58 static int printable(const char *line, const char *endp);
59
60 int
interpret_http(int flags,char * line,int fraglen)61 interpret_http(int flags, char *line, int fraglen)
62 {
63 char *p, *q, *endp;
64 int c;
65 int lineno;
66
67 endp = line + fraglen;
68
69 if (flags & F_SUM) {
70 c = printable(line, endp - 1);
71 if (c < MINCHARS) {
72 (void) snprintf(get_sum_line(), MAXLINE,
73 "HTTP (body)");
74 } else {
75 (void) snprintf(get_sum_line(), MAXLINE,
76 "HTTP %.*s", MIN(c, MAXCHARS), line);
77 }
78 }
79
80 if (flags & F_DTAIL) {
81 show_header("HTTP: ", "HyperText Transfer Protocol", fraglen);
82 show_space();
83
84 lineno = 0;
85 for (p = line; p < endp && lineno < NLINES; p = q + 1) {
86 c = printable(p, endp - 1);
87
88 /* stop if no printables, except if at line end */
89 if (c == 0 && *p != CR && *p != LF)
90 break;
91
92 /*
93 * A line may be terminated either by an CR LF sequence
94 * (DOS, Mac), or by LF alone
95 */
96
97 q = memchr(p, CR, (endp - p));
98 if (q != NULL) {
99 if (q < endp - 1 && q[1] == LF)
100 ++q; /* ignore subsequent LF character */
101 } else {
102 q = memchr(p, LF, (endp - p));
103 /* no CR/LF: use end of buffer */
104 if (q == NULL)
105 q = endp - 1;
106 }
107
108 /* truncate lines containing non-printable characters */
109 (void) snprintf(get_line(0, c), get_line_remain(),
110 "%.*s", c, p);
111 ++lineno;
112 }
113
114 if (p < endp) /* there was more data to be printed */
115 (void) snprintf(get_line(0, 5), get_line_remain(),
116 "[...]");
117
118 show_space();
119 }
120
121 return (fraglen);
122 }
123
124 /*
125 * Return the length of the initial string starting with "startp" and
126 * ending with "endp" (inclusively) consisting only of printable
127 * characters.
128 */
129
130 static int
printable(const char * startp,const char * endp)131 printable(const char *startp, const char *endp)
132 {
133 const char *p = startp;
134
135 while (p <= endp && (isprint(*p) || *p == '\t'))
136 p++;
137
138 return (p - startp);
139 }
140