* Copyright (c) 1988-1990 The Regents of the University of California.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
"@(#) $Header: print-tcp.c,v 1.18 92/05/25 14:29:04 mccanne Exp $ (LBL)";
#include <netinet/in_systm.h>
#include <netinet/ip_var.h>
#include <netinet/tcpip.h>
#define TCPOPT_WSCALE 3 /* window scale factor (rfc1072) */
#define TCPOPT_SACKOK 4 /* selective ack ok (rfc1072) */
#define TCPOPT_SACK 5 /* selective ack (rfc1072) */
#define TCPOPT_ECHO 6 /* echo (rfc1072) */
#define TCPOPT_ECHOREPLY 7 /* echo (rfc1072) */
struct tcp_seq_hash
*nxt
;
#define TSEQ_HASHSIZE 919
static struct tcp_seq_hash tcp_seq_hash
[TSEQ_HASHSIZE
];
tcp_print(tp
, length
, ip
)
register struct tcphdr
*tp
;
if ((u_char
*)(tp
+ 1) > snapend
) {
if (length
< sizeof(struct tcphdr
)) {
(void)printf("truncated-tcp %d", length
);
(void)printf("%s.%s > %s.%s: ",
ipaddr_string(&ip
->ip_src
), tcpport_string(tp
->th_sport
),
ipaddr_string(&ip
->ip_dst
), tcpport_string(tp
->th_dport
));
if ((be
= (tp
->th_sport
== X_TCP_BI_PORT
||
tp
->th_dport
== X_TCP_BI_PORT
)) ||
tp
->th_sport
== X_TCP_LI_PORT
||
tp
->th_dport
== X_TCP_LI_PORT
) {
register XReq
*xp
= (XReq
*)(tp
+ 1);
x10_print(xp
, length
- sizeof(struct tcphdr
), be
);
(void)printf("tcp %d", length
- tp
->th_off
* 4);
if ((flags
= tp
->th_flags
) & (TH_SYN
|TH_FIN
|TH_RST
|TH_PUSH
)) {
if (!Sflag
&& (flags
& TH_ACK
)) {
register struct tcp_seq_hash
*th
;
* Find (or record) the initial sequence numbers for
* this conversation. (we pick an arbitrary
* collating order so there's only one entry for
if (tp
->th_sport
< tp
->th_dport
||
(tp
->th_sport
== tp
->th_dport
&&
ip
->ip_src
.s_addr
< ip
->ip_dst
.s_addr
)) {
tha
.src
= ip
->ip_src
, tha
.dst
= ip
->ip_dst
;
tha
.port
= tp
->th_sport
<< 16 | tp
->th_dport
;
tha
.src
= ip
->ip_dst
, tha
.dst
= ip
->ip_src
;
tha
.port
= tp
->th_dport
<< 16 | tp
->th_sport
;
for (th
= &tcp_seq_hash
[tha
.port
% TSEQ_HASHSIZE
];
if (!bcmp((char *)&tha
, (char *)&th
->addr
,
if (!th
->nxt
|| flags
& TH_SYN
) {
/* didn't find it or new conversation */
th
->nxt
= (struct tcp_seq_hash
*)
th
->ack
= tp
->th_seq
, th
->seq
= tp
->th_ack
- 1;
th
->seq
= tp
->th_seq
, th
->ack
= tp
->th_ack
- 1;
tp
->th_seq
-= th
->ack
, tp
->th_ack
-= th
->seq
;
tp
->th_seq
-= th
->seq
, tp
->th_ack
-= th
->ack
;
if (length
> 0 || flags
& (TH_SYN
| TH_FIN
| TH_RST
))
(void)printf(" %lu:%lu(%d)", tp
->th_seq
, tp
->th_seq
+ length
,
(void)printf(" ack %lu", tp
->th_ack
);
(void)printf(" win %d", tp
->th_win
);
(void)printf(" urg %d", tp
->th_urp
);
if ((hlen
-= sizeof(struct tcphdr
)) > 0) {
register u_char
*cp
= (u_char
*)tp
+ sizeof(struct tcphdr
);
bcopy((char *)cp
+ 1, (char *)&mss
,
mss
= *(u_short
*)(cp
+ 1);
(void)printf("mss %d", ntohs(mss
));
(void)printf("[len %d]", *cp
);
(void)printf("wscale %d", cp
[1]);
(void)printf("[len %d]", *cp
);
(void)printf("[len %d]", *cp
);
bcopy((char *)cp
+ 1, (char *)&v
,
(void)printf("echo %lu", v
);
(void)printf("[len %d]", *cp
);
bcopy((char *)cp
+ 1, (char *)&v
,
(void)printf("echoreply %lu", v
);
(void)printf("[len %d]", *cp
);
(void)printf("opt-%d:", cp
[-1]);
for (i
= *cp
++ - 2, hlen
-= i
+ 1; i
> 0; --i
)
(void)printf("%02x", *cp
++);