1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/*
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * Copyright (c) 1989, 1990, 1991, 1993, 1994, 1995, 1996, 1997
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *	The Regents of the University of California.  All rights reserved.
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * Redistribution and use in source and binary forms, with or without
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * modification, are permitted provided that: (1) source code distributions
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * retain the above copyright notice and this paragraph in its entirety, (2)
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * distributions including binary code include the above copyright notice and
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * this paragraph in its entirety in the documentation or other materials
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * provided with the distribution, and (3) all advertising materials mentioning
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * features or use of this software display the following acknowledgement:
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * ``This product includes software developed by the University of California,
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * the University nor the names of its contributors may be used to endorse
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * or promote products derived from this software without specific prior
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * written permission.
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block */
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define NETDISSECT_REWORKED
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef HAVE_CONFIG_H
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "config.h"
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include <tcpdump-stdinc.h>
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "interface.h"
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "extract.h"			/* must come after interface.h */
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "ip.h"
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "tcp.h"
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "slcompress.h"
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/*
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * definitions of the pseudo- link-level header attached to slip
38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * packets grabbed by the packet filter (bpf) traffic monitor.
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block */
40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define SLIP_HDRLEN 16
41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define SLX_DIR 0
43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define SLX_CHDR 1
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CHDR_LEN 15
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define SLIPDIR_IN 0
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define SLIPDIR_OUT 1
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const char tstr[] = "[|slip]";
50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic u_int lastlen[2][256];
52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic u_int lastconn = 255;
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void sliplink_print(netdissect_options *, const u_char *, const struct ip *, u_int);
55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void compressed_sl_print(netdissect_options *, const u_char *, const struct ip *, u_int, int);
56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocku_int
58e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkesl_if_print(netdissect_options *ndo,
59e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke            const struct pcap_pkthdr *h, const u_char *p)
60e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke{
61e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke	register u_int caplen = h->caplen;
62e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke	register u_int length = h->len;
63e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke	register const struct ip *ip;
64e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
65e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke	if (caplen < SLIP_HDRLEN || length < SLIP_HDRLEN) {
66e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke		ND_PRINT((ndo, "%s", tstr));
67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		return (caplen);
68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	}
69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	length -= SLIP_HDRLEN;
71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	ip = (struct ip *)(p + SLIP_HDRLEN);
73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	if (ndo->ndo_eflag)
75d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke		sliplink_print(ndo, p, ip, length);
76d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	switch (IP_V(ip)) {
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	case 4:
79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	        ip_print(ndo, (u_char *)ip, length);
80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		break;
81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	case 6:
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		ip6_print(ndo, (u_char *)ip, length);
83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		break;
84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	default:
85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		ND_PRINT((ndo, "ip v%d", IP_V(ip)));
86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	}
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
88e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke	return (SLIP_HDRLEN);
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocku_int
92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocksl_bsdos_if_print(netdissect_options *ndo,
93e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke                  const struct pcap_pkthdr *h, const u_char *p)
94e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke{
95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	register u_int caplen = h->caplen;
96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	register u_int length = h->len;
97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	register const struct ip *ip;
98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	if (caplen < SLIP_HDRLEN) {
100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		ND_PRINT((ndo, "%s", tstr));
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		return (caplen);
102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	}
103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	length -= SLIP_HDRLEN;
105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	ip = (struct ip *)(p + SLIP_HDRLEN);
107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef notdef
109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	if (ndo->ndo_eflag)
110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		sliplink_print(ndo, p, ip, length);
111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	ip_print(ndo, (u_char *)ip, length);
114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	return (SLIP_HDRLEN);
116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void
119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocksliplink_print(netdissect_options *ndo,
120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block               register const u_char *p, register const struct ip *ip,
121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block               register u_int length)
122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block{
123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	int dir;
124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	u_int hlen;
125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	dir = p[SLX_DIR];
127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	ND_PRINT((ndo, dir == SLIPDIR_IN ? "I " : "O "));
128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	if (ndo->ndo_nflag) {
130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		/* XXX just dump the header */
131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		register int i;
132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		for (i = SLX_CHDR; i < SLX_CHDR + CHDR_LEN - 1; ++i)
134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block			ND_PRINT((ndo, "%02x.", p[i]));
135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		ND_PRINT((ndo, "%02x: ", p[SLX_CHDR + CHDR_LEN - 1]));
136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		return;
137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	}
138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	switch (p[SLX_CHDR] & 0xf0) {
139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	case TYPE_IP:
141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		ND_PRINT((ndo, "ip %d: ", length + SLIP_HDRLEN));
142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		break;
143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	case TYPE_UNCOMPRESSED_TCP:
145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		/*
146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		 * The connection id is stored in the IP protocol field.
147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		 * Get it from the link layer since sl_uncompress_tcp()
148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		 * has restored the IP header copy to IPPROTO_TCP.
149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		 */
150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		lastconn = ((struct ip *)&p[SLX_CHDR])->ip_p;
151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		hlen = IP_HL(ip);
152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		hlen += TH_OFF((struct tcphdr *)&((int *)ip)[hlen]);
153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		lastlen[dir][lastconn] = length - (hlen << 2);
154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		ND_PRINT((ndo, "utcp %d: ", lastconn));
155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		break;
156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	default:
158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		if (p[SLX_CHDR] & TYPE_COMPRESSED_TCP) {
159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block			compressed_sl_print(ndo, &p[SLX_CHDR], ip,
160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block			    length, dir);
161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block			ND_PRINT((ndo, ": "));
162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		} else
163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block			ND_PRINT((ndo, "slip-%d!: ", p[SLX_CHDR]));
164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	}
165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const u_char *
168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockprint_sl_change(netdissect_options *ndo,
169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                const char *str, register const u_char *cp)
170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block{
171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	register u_int i;
172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	if ((i = *cp++) == 0) {
174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		i = EXTRACT_16BITS(cp);
175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		cp += 2;
176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	}
177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	ND_PRINT((ndo, " %s%d", str, i));
178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	return (cp);
179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const u_char *
182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockprint_sl_winchange(netdissect_options *ndo,
183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                   register const u_char *cp)
184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block{
185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	register short i;
186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	if ((i = *cp++) == 0) {
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		i = EXTRACT_16BITS(cp);
189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		cp += 2;
190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	}
191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	if (i >= 0)
192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		ND_PRINT((ndo, " W+%d", i));
193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	else
194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		ND_PRINT((ndo, " W%d", i));
195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	return (cp);
196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void
199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockcompressed_sl_print(netdissect_options *ndo,
200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                    const u_char *chdr, const struct ip *ip,
201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                    u_int length, int dir)
202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block{
203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	register const u_char *cp = chdr;
204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	register u_int flags, hlen;
205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	flags = *cp++;
207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	if (flags & NEW_C) {
208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		lastconn = *cp++;
209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		ND_PRINT((ndo, "ctcp %d", lastconn));
210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	} else
211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		ND_PRINT((ndo, "ctcp *"));
212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	/* skip tcp checksum */
214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	cp += 2;
215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	switch (flags & SPECIALS_MASK) {
217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	case SPECIAL_I:
218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		ND_PRINT((ndo, " *SA+%d", lastlen[dir][lastconn]));
219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		break;
220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	case SPECIAL_D:
222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		ND_PRINT((ndo, " *S+%d", lastlen[dir][lastconn]));
223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		break;
224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	default:
226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		if (flags & NEW_U)
227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block			cp = print_sl_change(ndo, "U=", cp);
228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		if (flags & NEW_W)
229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block			cp = print_sl_winchange(ndo, cp);
230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		if (flags & NEW_A)
231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block			cp = print_sl_change(ndo, "A+", cp);
232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		if (flags & NEW_S)
233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block			cp = print_sl_change(ndo, "S+", cp);
234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		break;
235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	}
236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	if (flags & NEW_I)
237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block		cp = print_sl_change(ndo, "I+", cp);
238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	/*
240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	 * 'hlen' is the length of the uncompressed TCP/IP header (in words).
241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	 * 'cp - chdr' is the length of the compressed header.
242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	 * 'length - hlen' is the amount of data in the packet.
243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	 */
244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	hlen = IP_HL(ip);
245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	hlen += TH_OFF((struct tcphdr *)&((int32_t *)ip)[hlen]);
246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	lastlen[dir][lastconn] = length - (hlen << 2);
247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block	ND_PRINT((ndo, " %d (%ld)", lastlen[dir][lastconn], (long)(cp - chdr)));
248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block