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