/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <string.h>
#include <netinet/in_systm.h>
#include <netinet/if_ether.h>
#include "snoop.h"
extern char *dlc_header;
/*
* Convert a network byte order 32 bit integer to a host order integer.
* ntohl() cannot be used because option values may not be aligned properly.
*/
static void print_tcpoptions_summary(uchar_t *, int, char *);
static void print_tcpoptions(uchar_t *, int);
static const struct {
unsigned int tf_flag;
const char *tf_name;
} tcp_flags[] = {
{ TH_SYN, "Syn" },
{ TH_FIN, "Fin" },
{ TH_RST, "Rst" },
{ TH_PUSH, "Push" },
{ TH_ECE, "ECE" },
{ TH_CWR, "CWR" },
{ 0, NULL }
};
int
{
char *data;
int sunrpc = 0;
char *pname;
unsigned int i;
if (fraglen < 0)
line = get_sum_line();
}
}
}
}
}
}
show_space();
if (sunrpc) {
pname = "(Sun RPC)";
} else {
pname = "";
} else {
}
}
"Acknowledgement number = %u",
"ECN congestion window reduced",
"No ECN congestion window reduced"));
"ECN echo", "No ECN echo"));
"Urgent pointer", "No urgent pointer"));
"Acknowledgement", "No acknowledgement"));
"Push", "No push"));
"Reset", "No reset"));
"Syn", "No Syn"));
"Fin", "No Fin"));
/* XXX need to compute checksum and print whether correct */
/* Print TCP options - if any */
show_space();
}
/* go to the next protocol layer */
}
return (tcplen);
}
static void
int optlen;
{
int len;
char *line;
int sack_len;
if (optlen <= 0) {
"No options");
return;
}
while (optlen > 0) {
switch (opt[0]) {
case TCPOPT_EOL:
return;
case TCPOPT_NOP:
len = 1;
break;
case TCPOPT_MAXSEG:
" - Maximum segment size = %d bytes",
break;
case TCPOPT_WSCALE:
break;
case TCPOPT_TSTAMP:
/* Sanity check. */
if (optlen < TCPOPT_TSTAMP_LEN) {
" - Incomplete TS option");
} else {
" - TS Val = %u, TS Echo = %u",
}
break;
case TCPOPT_SACK_PERMITTED:
break;
case TCPOPT_SACK:
/*
* Sanity check. Total length should be greater
* than just the option header length.
*/
if (len <= TCPOPT_HEADER_LEN ||
" - Incomplete SACK option");
break;
}
while (sack_len > 0) {
/*
* sack_len may not tell us the truth about
* the real length... Need to be careful
* not to step beyond the option buffer.
*/
"...incomplete SACK block");
break;
}
}
break;
default:
" - Option %d (unknown - %d bytes) %s",
opt[0],
len - 2,
break;
}
if (len <= 0) {
len);
break;
}
}
}
/*
* This function is basically the same as print_tcpoptions() except that
* all options are printed on the same line.
*/
static void
{
int len;
int sack_len;
if (optlen <= 0) {
return;
}
while (optlen > 0) {
switch (opt[0]) {
case TCPOPT_EOL:
return;
case TCPOPT_NOP:
len = 1;
break;
case TCPOPT_MAXSEG:
break;
case TCPOPT_WSCALE:
break;
case TCPOPT_TSTAMP:
/* Sanity check. */
if (optlen < TCPOPT_TSTAMP_LEN) {
} else {
}
break;
case TCPOPT_SACK_PERMITTED:
break;
case TCPOPT_SACK:
/*
* Sanity check. Total length should be greater
* than just the option header length.
*/
if (len <= TCPOPT_HEADER_LEN ||
break;
}
while (sack_len > 0) {
/*
* sack_len may not tell us the truth about
* the real length... Need to be careful
* not to step beyond the option buffer.
*/
break;
}
}
break;
default:
break;
}
if (len <= 0) {
break;
}
if (optlen > 0) {
}
}
}