xref: /minix3/external/bsd/tcpdump/dist/print-cnfp.c (revision b636d99d91c3d54204248f643c14627405d4afd1)
1*b636d99dSDavid van Moolenbroek /*	$OpenBSD: print-cnfp.c,v 1.2 1998/06/25 20:26:59 mickey Exp $	*/
2*b636d99dSDavid van Moolenbroek 
3*b636d99dSDavid van Moolenbroek /*
4*b636d99dSDavid van Moolenbroek  * Copyright (c) 1998 Michael Shalayeff
5*b636d99dSDavid van Moolenbroek  * All rights reserved.
6*b636d99dSDavid van Moolenbroek  *
7*b636d99dSDavid van Moolenbroek  * Redistribution and use in source and binary forms, with or without
8*b636d99dSDavid van Moolenbroek  * modification, are permitted provided that the following conditions
9*b636d99dSDavid van Moolenbroek  * are met:
10*b636d99dSDavid van Moolenbroek  * 1. Redistributions of source code must retain the above copyright
11*b636d99dSDavid van Moolenbroek  *    notice, this list of conditions and the following disclaimer.
12*b636d99dSDavid van Moolenbroek  * 2. Redistributions in binary form must reproduce the above copyright
13*b636d99dSDavid van Moolenbroek  *    notice, this list of conditions and the following disclaimer in the
14*b636d99dSDavid van Moolenbroek  *    documentation and/or other materials provided with the distribution.
15*b636d99dSDavid van Moolenbroek  *
16*b636d99dSDavid van Moolenbroek  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17*b636d99dSDavid van Moolenbroek  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18*b636d99dSDavid van Moolenbroek  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19*b636d99dSDavid van Moolenbroek  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20*b636d99dSDavid van Moolenbroek  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21*b636d99dSDavid van Moolenbroek  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22*b636d99dSDavid van Moolenbroek  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23*b636d99dSDavid van Moolenbroek  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24*b636d99dSDavid van Moolenbroek  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25*b636d99dSDavid van Moolenbroek  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*b636d99dSDavid van Moolenbroek  */
27*b636d99dSDavid van Moolenbroek 
28*b636d99dSDavid van Moolenbroek /*
29*b636d99dSDavid van Moolenbroek  * Cisco NetFlow protocol
30*b636d99dSDavid van Moolenbroek  *
31*b636d99dSDavid van Moolenbroek  * See
32*b636d99dSDavid van Moolenbroek  *
33*b636d99dSDavid van Moolenbroek  *    http://www.cisco.com/c/en/us/td/docs/net_mgmt/netflow_collection_engine/3-6/user/guide/format.html#wp1005892
34*b636d99dSDavid van Moolenbroek  */
35*b636d99dSDavid van Moolenbroek 
36*b636d99dSDavid van Moolenbroek #include <sys/cdefs.h>
37*b636d99dSDavid van Moolenbroek #ifndef lint
38*b636d99dSDavid van Moolenbroek __RCSID("$NetBSD: print-cnfp.c,v 1.5 2015/03/31 21:59:35 christos Exp $");
39*b636d99dSDavid van Moolenbroek #endif
40*b636d99dSDavid van Moolenbroek 
41*b636d99dSDavid van Moolenbroek #define NETDISSECT_REWORKED
42*b636d99dSDavid van Moolenbroek #ifdef HAVE_CONFIG_H
43*b636d99dSDavid van Moolenbroek #include "config.h"
44*b636d99dSDavid van Moolenbroek #endif
45*b636d99dSDavid van Moolenbroek 
46*b636d99dSDavid van Moolenbroek #include <tcpdump-stdinc.h>
47*b636d99dSDavid van Moolenbroek 
48*b636d99dSDavid van Moolenbroek #include <stdio.h>
49*b636d99dSDavid van Moolenbroek #include <string.h>
50*b636d99dSDavid van Moolenbroek 
51*b636d99dSDavid van Moolenbroek #include "interface.h"
52*b636d99dSDavid van Moolenbroek #include "addrtoname.h"
53*b636d99dSDavid van Moolenbroek #include "extract.h"
54*b636d99dSDavid van Moolenbroek 
55*b636d99dSDavid van Moolenbroek #include "tcp.h"
56*b636d99dSDavid van Moolenbroek #include "ipproto.h"
57*b636d99dSDavid van Moolenbroek 
58*b636d99dSDavid van Moolenbroek struct nfhdr_v1 {
59*b636d99dSDavid van Moolenbroek 	uint16_t	version;	/* version number */
60*b636d99dSDavid van Moolenbroek 	uint16_t	count;		/* # of records */
61*b636d99dSDavid van Moolenbroek 	uint32_t	msys_uptime;
62*b636d99dSDavid van Moolenbroek 	uint32_t	utc_sec;
63*b636d99dSDavid van Moolenbroek 	uint32_t	utc_nsec;
64*b636d99dSDavid van Moolenbroek };
65*b636d99dSDavid van Moolenbroek 
66*b636d99dSDavid van Moolenbroek struct nfrec_v1 {
67*b636d99dSDavid van Moolenbroek 	struct in_addr	src_ina;
68*b636d99dSDavid van Moolenbroek 	struct in_addr	dst_ina;
69*b636d99dSDavid van Moolenbroek 	struct in_addr	nhop_ina;
70*b636d99dSDavid van Moolenbroek 	uint16_t	input;		/* SNMP index of input interface */
71*b636d99dSDavid van Moolenbroek 	uint16_t	output;		/* SNMP index of output interface */
72*b636d99dSDavid van Moolenbroek 	uint32_t	packets;	/* packets in the flow */
73*b636d99dSDavid van Moolenbroek 	uint32_t	octets;		/* layer 3 octets in the packets of the flow */
74*b636d99dSDavid van Moolenbroek 	uint32_t	start_time;	/* sys_uptime value at start of flow */
75*b636d99dSDavid van Moolenbroek 	uint32_t	last_time;	/* sys_uptime value when last packet of flow was received */
76*b636d99dSDavid van Moolenbroek 	uint16_t	srcport;	/* TCP/UDP source port or equivalent */
77*b636d99dSDavid van Moolenbroek 	uint16_t	dstport;	/* TCP/UDP source port or equivalent */
78*b636d99dSDavid van Moolenbroek 	uint16_t	pad1;		/* pad */
79*b636d99dSDavid van Moolenbroek 	uint8_t		proto;		/* IP protocol type */
80*b636d99dSDavid van Moolenbroek 	uint8_t		tos;		/* IP type of service */
81*b636d99dSDavid van Moolenbroek 	uint8_t		tcp_flags;	/* cumulative OR of TCP flags */
82*b636d99dSDavid van Moolenbroek 	uint8_t		pad[3];		/* padding */
83*b636d99dSDavid van Moolenbroek 	uint32_t	reserved;	/* unused */
84*b636d99dSDavid van Moolenbroek };
85*b636d99dSDavid van Moolenbroek 
86*b636d99dSDavid van Moolenbroek struct nfhdr_v5 {
87*b636d99dSDavid van Moolenbroek 	uint16_t	version;	/* version number */
88*b636d99dSDavid van Moolenbroek 	uint16_t	count;		/* # of records */
89*b636d99dSDavid van Moolenbroek 	uint32_t	msys_uptime;
90*b636d99dSDavid van Moolenbroek 	uint32_t	utc_sec;
91*b636d99dSDavid van Moolenbroek 	uint32_t	utc_nsec;
92*b636d99dSDavid van Moolenbroek 	uint32_t	sequence;	/* flow sequence number */
93*b636d99dSDavid van Moolenbroek 	uint8_t		engine_type;	/* type of flow-switching engine */
94*b636d99dSDavid van Moolenbroek 	uint8_t		engine_id;	/* slot number of the flow-switching engine */
95*b636d99dSDavid van Moolenbroek 	uint16_t	sampling_interval; /* sampling mode and interval */
96*b636d99dSDavid van Moolenbroek };
97*b636d99dSDavid van Moolenbroek 
98*b636d99dSDavid van Moolenbroek struct nfrec_v5 {
99*b636d99dSDavid van Moolenbroek 	struct in_addr	src_ina;
100*b636d99dSDavid van Moolenbroek 	struct in_addr	dst_ina;
101*b636d99dSDavid van Moolenbroek 	struct in_addr	nhop_ina;
102*b636d99dSDavid van Moolenbroek 	uint16_t	input;		/* SNMP index of input interface */
103*b636d99dSDavid van Moolenbroek 	uint16_t	output;		/* SNMP index of output interface */
104*b636d99dSDavid van Moolenbroek 	uint32_t	packets;	/* packets in the flow */
105*b636d99dSDavid van Moolenbroek 	uint32_t	octets;		/* layer 3 octets in the packets of the flow */
106*b636d99dSDavid van Moolenbroek 	uint32_t	start_time;	/* sys_uptime value at start of flow */
107*b636d99dSDavid van Moolenbroek 	uint32_t	last_time;	/* sys_uptime value when last packet of flow was received */
108*b636d99dSDavid van Moolenbroek 	uint16_t	srcport;	/* TCP/UDP source port or equivalent */
109*b636d99dSDavid van Moolenbroek 	uint16_t	dstport;	/* TCP/UDP source port or equivalent */
110*b636d99dSDavid van Moolenbroek 	uint8_t		pad1;		/* pad */
111*b636d99dSDavid van Moolenbroek 	uint8_t		tcp_flags;	/* cumulative OR of TCP flags */
112*b636d99dSDavid van Moolenbroek 	uint8_t		proto;		/* IP protocol type */
113*b636d99dSDavid van Moolenbroek 	uint8_t		tos;		/* IP type of service */
114*b636d99dSDavid van Moolenbroek 	uint16_t	src_as;		/* AS number of the source */
115*b636d99dSDavid van Moolenbroek 	uint16_t	dst_as;		/* AS number of the destination */
116*b636d99dSDavid van Moolenbroek 	uint8_t		src_mask;	/* source address mask bits */
117*b636d99dSDavid van Moolenbroek 	uint8_t		dst_mask;	/* destination address prefix mask bits */
118*b636d99dSDavid van Moolenbroek 	uint16_t	pad2;
119*b636d99dSDavid van Moolenbroek 	struct in_addr	peer_nexthop;	/* v6: IP address of the nexthop within the peer (FIB)*/
120*b636d99dSDavid van Moolenbroek };
121*b636d99dSDavid van Moolenbroek 
122*b636d99dSDavid van Moolenbroek struct nfhdr_v6 {
123*b636d99dSDavid van Moolenbroek 	uint16_t	version;	/* version number */
124*b636d99dSDavid van Moolenbroek 	uint16_t	count;		/* # of records */
125*b636d99dSDavid van Moolenbroek 	uint32_t	msys_uptime;
126*b636d99dSDavid van Moolenbroek 	uint32_t	utc_sec;
127*b636d99dSDavid van Moolenbroek 	uint32_t	utc_nsec;
128*b636d99dSDavid van Moolenbroek 	uint32_t	sequence;	/* v5 flow sequence number */
129*b636d99dSDavid van Moolenbroek 	uint32_t	reserved;	/* v5 only */
130*b636d99dSDavid van Moolenbroek };
131*b636d99dSDavid van Moolenbroek 
132*b636d99dSDavid van Moolenbroek struct nfrec_v6 {
133*b636d99dSDavid van Moolenbroek 	struct in_addr	src_ina;
134*b636d99dSDavid van Moolenbroek 	struct in_addr	dst_ina;
135*b636d99dSDavid van Moolenbroek 	struct in_addr	nhop_ina;
136*b636d99dSDavid van Moolenbroek 	uint16_t	input;		/* SNMP index of input interface */
137*b636d99dSDavid van Moolenbroek 	uint16_t	output;		/* SNMP index of output interface */
138*b636d99dSDavid van Moolenbroek 	uint32_t	packets;	/* packets in the flow */
139*b636d99dSDavid van Moolenbroek 	uint32_t	octets;		/* layer 3 octets in the packets of the flow */
140*b636d99dSDavid van Moolenbroek 	uint32_t	start_time;	/* sys_uptime value at start of flow */
141*b636d99dSDavid van Moolenbroek 	uint32_t	last_time;	/* sys_uptime value when last packet of flow was received */
142*b636d99dSDavid van Moolenbroek 	uint16_t	srcport;	/* TCP/UDP source port or equivalent */
143*b636d99dSDavid van Moolenbroek 	uint16_t	dstport;	/* TCP/UDP source port or equivalent */
144*b636d99dSDavid van Moolenbroek 	uint8_t		pad1;		/* pad */
145*b636d99dSDavid van Moolenbroek 	uint8_t		tcp_flags;	/* cumulative OR of TCP flags */
146*b636d99dSDavid van Moolenbroek 	uint8_t		proto;		/* IP protocol type */
147*b636d99dSDavid van Moolenbroek 	uint8_t		tos;		/* IP type of service */
148*b636d99dSDavid van Moolenbroek 	uint16_t	src_as;		/* AS number of the source */
149*b636d99dSDavid van Moolenbroek 	uint16_t	dst_as;		/* AS number of the destination */
150*b636d99dSDavid van Moolenbroek 	uint8_t		src_mask;	/* source address mask bits */
151*b636d99dSDavid van Moolenbroek 	uint8_t		dst_mask;	/* destination address prefix mask bits */
152*b636d99dSDavid van Moolenbroek 	uint16_t	flags;
153*b636d99dSDavid van Moolenbroek 	struct in_addr	peer_nexthop;	/* v6: IP address of the nexthop within the peer (FIB)*/
154*b636d99dSDavid van Moolenbroek };
155*b636d99dSDavid van Moolenbroek 
156*b636d99dSDavid van Moolenbroek static void
cnfp_v1_print(netdissect_options * ndo,const u_char * cp)157*b636d99dSDavid van Moolenbroek cnfp_v1_print(netdissect_options *ndo, const u_char *cp)
158*b636d99dSDavid van Moolenbroek {
159*b636d99dSDavid van Moolenbroek 	register const struct nfhdr_v1 *nh;
160*b636d99dSDavid van Moolenbroek 	register const struct nfrec_v1 *nr;
161*b636d99dSDavid van Moolenbroek 	struct protoent *pent;
162*b636d99dSDavid van Moolenbroek 	int nrecs, ver;
163*b636d99dSDavid van Moolenbroek #if 0
164*b636d99dSDavid van Moolenbroek 	time_t t;
165*b636d99dSDavid van Moolenbroek #endif
166*b636d99dSDavid van Moolenbroek 
167*b636d99dSDavid van Moolenbroek 	nh = (const struct nfhdr_v1 *)cp;
168*b636d99dSDavid van Moolenbroek 	ND_TCHECK(*nh);
169*b636d99dSDavid van Moolenbroek 
170*b636d99dSDavid van Moolenbroek 	ver = EXTRACT_16BITS(&nh->version);
171*b636d99dSDavid van Moolenbroek 	nrecs = EXTRACT_32BITS(&nh->count);
172*b636d99dSDavid van Moolenbroek #if 0
173*b636d99dSDavid van Moolenbroek 	/*
174*b636d99dSDavid van Moolenbroek 	 * This is seconds since the UN*X epoch, and is followed by
175*b636d99dSDavid van Moolenbroek 	 * nanoseconds.  XXX - format it, rather than just dumping the
176*b636d99dSDavid van Moolenbroek 	 * raw seconds-since-the-Epoch.
177*b636d99dSDavid van Moolenbroek 	 */
178*b636d99dSDavid van Moolenbroek 	t = EXTRACT_32BITS(&nh->utc_sec);
179*b636d99dSDavid van Moolenbroek #endif
180*b636d99dSDavid van Moolenbroek 
181*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "NetFlow v%x, %u.%03u uptime, %u.%09u, ", ver,
182*b636d99dSDavid van Moolenbroek 	       EXTRACT_32BITS(&nh->msys_uptime)/1000,
183*b636d99dSDavid van Moolenbroek 	       EXTRACT_32BITS(&nh->msys_uptime)%1000,
184*b636d99dSDavid van Moolenbroek 	       EXTRACT_32BITS(&nh->utc_sec), EXTRACT_32BITS(&nh->utc_nsec)));
185*b636d99dSDavid van Moolenbroek 
186*b636d99dSDavid van Moolenbroek 	nr = (const struct nfrec_v1 *)&nh[1];
187*b636d99dSDavid van Moolenbroek 
188*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "%2u recs", nrecs));
189*b636d99dSDavid van Moolenbroek 
190*b636d99dSDavid van Moolenbroek 	for (; nrecs != 0; nr++, nrecs--) {
191*b636d99dSDavid van Moolenbroek 		char buf[20];
192*b636d99dSDavid van Moolenbroek 		char asbuf[20];
193*b636d99dSDavid van Moolenbroek 
194*b636d99dSDavid van Moolenbroek 		/*
195*b636d99dSDavid van Moolenbroek 		 * Make sure we have the entire record.
196*b636d99dSDavid van Moolenbroek 		 */
197*b636d99dSDavid van Moolenbroek 		ND_TCHECK(*nr);
198*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "\n  started %u.%03u, last %u.%03u",
199*b636d99dSDavid van Moolenbroek 		       EXTRACT_32BITS(&nr->start_time)/1000,
200*b636d99dSDavid van Moolenbroek 		       EXTRACT_32BITS(&nr->start_time)%1000,
201*b636d99dSDavid van Moolenbroek 		       EXTRACT_32BITS(&nr->last_time)/1000,
202*b636d99dSDavid van Moolenbroek 		       EXTRACT_32BITS(&nr->last_time)%1000));
203*b636d99dSDavid van Moolenbroek 
204*b636d99dSDavid van Moolenbroek 		asbuf[0] = buf[0] = '\0';
205*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "\n    %s%s%s:%u ", intoa(nr->src_ina.s_addr), buf, asbuf,
206*b636d99dSDavid van Moolenbroek 			EXTRACT_16BITS(&nr->srcport)));
207*b636d99dSDavid van Moolenbroek 
208*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "> %s%s%s:%u ", intoa(nr->dst_ina.s_addr), buf, asbuf,
209*b636d99dSDavid van Moolenbroek 			EXTRACT_16BITS(&nr->dstport)));
210*b636d99dSDavid van Moolenbroek 
211*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ">> %s\n    ", intoa(nr->nhop_ina.s_addr)));
212*b636d99dSDavid van Moolenbroek 
213*b636d99dSDavid van Moolenbroek 		pent = getprotobynumber(nr->proto);
214*b636d99dSDavid van Moolenbroek 		if (!pent || ndo->ndo_nflag)
215*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "%u ", nr->proto));
216*b636d99dSDavid van Moolenbroek 		else
217*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "%s ", pent->p_name));
218*b636d99dSDavid van Moolenbroek 
219*b636d99dSDavid van Moolenbroek 		/* tcp flags for tcp only */
220*b636d99dSDavid van Moolenbroek 		if (pent && pent->p_proto == IPPROTO_TCP) {
221*b636d99dSDavid van Moolenbroek 			int flags;
222*b636d99dSDavid van Moolenbroek 			flags = nr->tcp_flags;
223*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "%s%s%s%s%s%s%s",
224*b636d99dSDavid van Moolenbroek 				flags & TH_FIN  ? "F" : "",
225*b636d99dSDavid van Moolenbroek 				flags & TH_SYN  ? "S" : "",
226*b636d99dSDavid van Moolenbroek 				flags & TH_RST  ? "R" : "",
227*b636d99dSDavid van Moolenbroek 				flags & TH_PUSH ? "P" : "",
228*b636d99dSDavid van Moolenbroek 				flags & TH_ACK  ? "A" : "",
229*b636d99dSDavid van Moolenbroek 				flags & TH_URG  ? "U" : "",
230*b636d99dSDavid van Moolenbroek 				flags           ? " " : ""));
231*b636d99dSDavid van Moolenbroek 		}
232*b636d99dSDavid van Moolenbroek 
233*b636d99dSDavid van Moolenbroek 		buf[0]='\0';
234*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "tos %u, %u (%u octets) %s",
235*b636d99dSDavid van Moolenbroek 		       nr->tos,
236*b636d99dSDavid van Moolenbroek 		       EXTRACT_32BITS(&nr->packets),
237*b636d99dSDavid van Moolenbroek 		       EXTRACT_32BITS(&nr->octets), buf));
238*b636d99dSDavid van Moolenbroek 	}
239*b636d99dSDavid van Moolenbroek 	return;
240*b636d99dSDavid van Moolenbroek 
241*b636d99dSDavid van Moolenbroek trunc:
242*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "[|cnfp]"));
243*b636d99dSDavid van Moolenbroek 	return;
244*b636d99dSDavid van Moolenbroek }
245*b636d99dSDavid van Moolenbroek 
246*b636d99dSDavid van Moolenbroek static void
cnfp_v5_print(netdissect_options * ndo,const u_char * cp)247*b636d99dSDavid van Moolenbroek cnfp_v5_print(netdissect_options *ndo, const u_char *cp)
248*b636d99dSDavid van Moolenbroek {
249*b636d99dSDavid van Moolenbroek 	register const struct nfhdr_v5 *nh;
250*b636d99dSDavid van Moolenbroek 	register const struct nfrec_v5 *nr;
251*b636d99dSDavid van Moolenbroek 	struct protoent *pent;
252*b636d99dSDavid van Moolenbroek 	int nrecs, ver;
253*b636d99dSDavid van Moolenbroek #if 0
254*b636d99dSDavid van Moolenbroek 	time_t t;
255*b636d99dSDavid van Moolenbroek #endif
256*b636d99dSDavid van Moolenbroek 
257*b636d99dSDavid van Moolenbroek 	nh = (const struct nfhdr_v5 *)cp;
258*b636d99dSDavid van Moolenbroek 	ND_TCHECK(*nh);
259*b636d99dSDavid van Moolenbroek 
260*b636d99dSDavid van Moolenbroek 	ver = EXTRACT_16BITS(&nh->version);
261*b636d99dSDavid van Moolenbroek 	nrecs = EXTRACT_32BITS(&nh->count);
262*b636d99dSDavid van Moolenbroek #if 0
263*b636d99dSDavid van Moolenbroek 	/*
264*b636d99dSDavid van Moolenbroek 	 * This is seconds since the UN*X epoch, and is followed by
265*b636d99dSDavid van Moolenbroek 	 * nanoseconds.  XXX - format it, rather than just dumping the
266*b636d99dSDavid van Moolenbroek 	 * raw seconds-since-the-Epoch.
267*b636d99dSDavid van Moolenbroek 	 */
268*b636d99dSDavid van Moolenbroek 	t = EXTRACT_32BITS(&nh->utc_sec);
269*b636d99dSDavid van Moolenbroek #endif
270*b636d99dSDavid van Moolenbroek 
271*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "NetFlow v%x, %u.%03u uptime, %u.%09u, ", ver,
272*b636d99dSDavid van Moolenbroek 	       EXTRACT_32BITS(&nh->msys_uptime)/1000,
273*b636d99dSDavid van Moolenbroek 	       EXTRACT_32BITS(&nh->msys_uptime)%1000,
274*b636d99dSDavid van Moolenbroek 	       EXTRACT_32BITS(&nh->utc_sec), EXTRACT_32BITS(&nh->utc_nsec)));
275*b636d99dSDavid van Moolenbroek 
276*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "#%u, ", EXTRACT_32BITS(&nh->sequence)));
277*b636d99dSDavid van Moolenbroek 	nr = (const struct nfrec_v5 *)&nh[1];
278*b636d99dSDavid van Moolenbroek 
279*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "%2u recs", nrecs));
280*b636d99dSDavid van Moolenbroek 
281*b636d99dSDavid van Moolenbroek 	for (; nrecs != 0; nr++, nrecs--) {
282*b636d99dSDavid van Moolenbroek 		char buf[20];
283*b636d99dSDavid van Moolenbroek 		char asbuf[20];
284*b636d99dSDavid van Moolenbroek 
285*b636d99dSDavid van Moolenbroek 		/*
286*b636d99dSDavid van Moolenbroek 		 * Make sure we have the entire record.
287*b636d99dSDavid van Moolenbroek 		 */
288*b636d99dSDavid van Moolenbroek 		ND_TCHECK(*nr);
289*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "\n  started %u.%03u, last %u.%03u",
290*b636d99dSDavid van Moolenbroek 		       EXTRACT_32BITS(&nr->start_time)/1000,
291*b636d99dSDavid van Moolenbroek 		       EXTRACT_32BITS(&nr->start_time)%1000,
292*b636d99dSDavid van Moolenbroek 		       EXTRACT_32BITS(&nr->last_time)/1000,
293*b636d99dSDavid van Moolenbroek 		       EXTRACT_32BITS(&nr->last_time)%1000));
294*b636d99dSDavid van Moolenbroek 
295*b636d99dSDavid van Moolenbroek 		asbuf[0] = buf[0] = '\0';
296*b636d99dSDavid van Moolenbroek 		snprintf(buf, sizeof(buf), "/%u", nr->src_mask);
297*b636d99dSDavid van Moolenbroek 		snprintf(asbuf, sizeof(asbuf), ":%u",
298*b636d99dSDavid van Moolenbroek 			EXTRACT_16BITS(&nr->src_as));
299*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "\n    %s%s%s:%u ", intoa(nr->src_ina.s_addr), buf, asbuf,
300*b636d99dSDavid van Moolenbroek 			EXTRACT_16BITS(&nr->srcport)));
301*b636d99dSDavid van Moolenbroek 
302*b636d99dSDavid van Moolenbroek 		snprintf(buf, sizeof(buf), "/%d", nr->dst_mask);
303*b636d99dSDavid van Moolenbroek 		snprintf(asbuf, sizeof(asbuf), ":%u",
304*b636d99dSDavid van Moolenbroek 			 EXTRACT_16BITS(&nr->dst_as));
305*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "> %s%s%s:%u ", intoa(nr->dst_ina.s_addr), buf, asbuf,
306*b636d99dSDavid van Moolenbroek 			EXTRACT_16BITS(&nr->dstport)));
307*b636d99dSDavid van Moolenbroek 
308*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ">> %s\n    ", intoa(nr->nhop_ina.s_addr)));
309*b636d99dSDavid van Moolenbroek 
310*b636d99dSDavid van Moolenbroek 		pent = getprotobynumber(nr->proto);
311*b636d99dSDavid van Moolenbroek 		if (!pent || ndo->ndo_nflag)
312*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "%u ", nr->proto));
313*b636d99dSDavid van Moolenbroek 		else
314*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "%s ", pent->p_name));
315*b636d99dSDavid van Moolenbroek 
316*b636d99dSDavid van Moolenbroek 		/* tcp flags for tcp only */
317*b636d99dSDavid van Moolenbroek 		if (pent && pent->p_proto == IPPROTO_TCP) {
318*b636d99dSDavid van Moolenbroek 			int flags;
319*b636d99dSDavid van Moolenbroek 			flags = nr->tcp_flags;
320*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "%s%s%s%s%s%s%s",
321*b636d99dSDavid van Moolenbroek 				flags & TH_FIN  ? "F" : "",
322*b636d99dSDavid van Moolenbroek 				flags & TH_SYN  ? "S" : "",
323*b636d99dSDavid van Moolenbroek 				flags & TH_RST  ? "R" : "",
324*b636d99dSDavid van Moolenbroek 				flags & TH_PUSH ? "P" : "",
325*b636d99dSDavid van Moolenbroek 				flags & TH_ACK  ? "A" : "",
326*b636d99dSDavid van Moolenbroek 				flags & TH_URG  ? "U" : "",
327*b636d99dSDavid van Moolenbroek 				flags           ? " " : ""));
328*b636d99dSDavid van Moolenbroek 		}
329*b636d99dSDavid van Moolenbroek 
330*b636d99dSDavid van Moolenbroek 		buf[0]='\0';
331*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "tos %u, %u (%u octets) %s",
332*b636d99dSDavid van Moolenbroek 		       nr->tos,
333*b636d99dSDavid van Moolenbroek 		       EXTRACT_32BITS(&nr->packets),
334*b636d99dSDavid van Moolenbroek 		       EXTRACT_32BITS(&nr->octets), buf));
335*b636d99dSDavid van Moolenbroek 	}
336*b636d99dSDavid van Moolenbroek 	return;
337*b636d99dSDavid van Moolenbroek 
338*b636d99dSDavid van Moolenbroek trunc:
339*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "[|cnfp]"));
340*b636d99dSDavid van Moolenbroek 	return;
341*b636d99dSDavid van Moolenbroek }
342*b636d99dSDavid van Moolenbroek 
343*b636d99dSDavid van Moolenbroek static void
cnfp_v6_print(netdissect_options * ndo,const u_char * cp)344*b636d99dSDavid van Moolenbroek cnfp_v6_print(netdissect_options *ndo, const u_char *cp)
345*b636d99dSDavid van Moolenbroek {
346*b636d99dSDavid van Moolenbroek 	register const struct nfhdr_v6 *nh;
347*b636d99dSDavid van Moolenbroek 	register const struct nfrec_v6 *nr;
348*b636d99dSDavid van Moolenbroek 	struct protoent *pent;
349*b636d99dSDavid van Moolenbroek 	int nrecs, ver;
350*b636d99dSDavid van Moolenbroek #if 0
351*b636d99dSDavid van Moolenbroek 	time_t t;
352*b636d99dSDavid van Moolenbroek #endif
353*b636d99dSDavid van Moolenbroek 
354*b636d99dSDavid van Moolenbroek 	nh = (const struct nfhdr_v6 *)cp;
355*b636d99dSDavid van Moolenbroek 	ND_TCHECK(*nh);
356*b636d99dSDavid van Moolenbroek 
357*b636d99dSDavid van Moolenbroek 	ver = EXTRACT_16BITS(&nh->version);
358*b636d99dSDavid van Moolenbroek 	nrecs = EXTRACT_32BITS(&nh->count);
359*b636d99dSDavid van Moolenbroek #if 0
360*b636d99dSDavid van Moolenbroek 	/*
361*b636d99dSDavid van Moolenbroek 	 * This is seconds since the UN*X epoch, and is followed by
362*b636d99dSDavid van Moolenbroek 	 * nanoseconds.  XXX - format it, rather than just dumping the
363*b636d99dSDavid van Moolenbroek 	 * raw seconds-since-the-Epoch.
364*b636d99dSDavid van Moolenbroek 	 */
365*b636d99dSDavid van Moolenbroek 	t = EXTRACT_32BITS(&nh->utc_sec);
366*b636d99dSDavid van Moolenbroek #endif
367*b636d99dSDavid van Moolenbroek 
368*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "NetFlow v%x, %u.%03u uptime, %u.%09u, ", ver,
369*b636d99dSDavid van Moolenbroek 	       EXTRACT_32BITS(&nh->msys_uptime)/1000,
370*b636d99dSDavid van Moolenbroek 	       EXTRACT_32BITS(&nh->msys_uptime)%1000,
371*b636d99dSDavid van Moolenbroek 	       EXTRACT_32BITS(&nh->utc_sec), EXTRACT_32BITS(&nh->utc_nsec)));
372*b636d99dSDavid van Moolenbroek 
373*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "#%u, ", EXTRACT_32BITS(&nh->sequence)));
374*b636d99dSDavid van Moolenbroek 	nr = (const struct nfrec_v6 *)&nh[1];
375*b636d99dSDavid van Moolenbroek 
376*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "%2u recs", nrecs));
377*b636d99dSDavid van Moolenbroek 
378*b636d99dSDavid van Moolenbroek 	for (; nrecs != 0; nr++, nrecs--) {
379*b636d99dSDavid van Moolenbroek 		char buf[20];
380*b636d99dSDavid van Moolenbroek 		char asbuf[20];
381*b636d99dSDavid van Moolenbroek 
382*b636d99dSDavid van Moolenbroek 		/*
383*b636d99dSDavid van Moolenbroek 		 * Make sure we have the entire record.
384*b636d99dSDavid van Moolenbroek 		 */
385*b636d99dSDavid van Moolenbroek 		ND_TCHECK(*nr);
386*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "\n  started %u.%03u, last %u.%03u",
387*b636d99dSDavid van Moolenbroek 		       EXTRACT_32BITS(&nr->start_time)/1000,
388*b636d99dSDavid van Moolenbroek 		       EXTRACT_32BITS(&nr->start_time)%1000,
389*b636d99dSDavid van Moolenbroek 		       EXTRACT_32BITS(&nr->last_time)/1000,
390*b636d99dSDavid van Moolenbroek 		       EXTRACT_32BITS(&nr->last_time)%1000));
391*b636d99dSDavid van Moolenbroek 
392*b636d99dSDavid van Moolenbroek 		asbuf[0] = buf[0] = '\0';
393*b636d99dSDavid van Moolenbroek 		snprintf(buf, sizeof(buf), "/%u", nr->src_mask);
394*b636d99dSDavid van Moolenbroek 		snprintf(asbuf, sizeof(asbuf), ":%u",
395*b636d99dSDavid van Moolenbroek 			EXTRACT_16BITS(&nr->src_as));
396*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "\n    %s%s%s:%u ", intoa(nr->src_ina.s_addr), buf, asbuf,
397*b636d99dSDavid van Moolenbroek 			EXTRACT_16BITS(&nr->srcport)));
398*b636d99dSDavid van Moolenbroek 
399*b636d99dSDavid van Moolenbroek 		snprintf(buf, sizeof(buf), "/%d", nr->dst_mask);
400*b636d99dSDavid van Moolenbroek 		snprintf(asbuf, sizeof(asbuf), ":%u",
401*b636d99dSDavid van Moolenbroek 			 EXTRACT_16BITS(&nr->dst_as));
402*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "> %s%s%s:%u ", intoa(nr->dst_ina.s_addr), buf, asbuf,
403*b636d99dSDavid van Moolenbroek 			EXTRACT_16BITS(&nr->dstport)));
404*b636d99dSDavid van Moolenbroek 
405*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ">> %s\n    ", intoa(nr->nhop_ina.s_addr)));
406*b636d99dSDavid van Moolenbroek 
407*b636d99dSDavid van Moolenbroek 		pent = getprotobynumber(nr->proto);
408*b636d99dSDavid van Moolenbroek 		if (!pent || ndo->ndo_nflag)
409*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "%u ", nr->proto));
410*b636d99dSDavid van Moolenbroek 		else
411*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "%s ", pent->p_name));
412*b636d99dSDavid van Moolenbroek 
413*b636d99dSDavid van Moolenbroek 		/* tcp flags for tcp only */
414*b636d99dSDavid van Moolenbroek 		if (pent && pent->p_proto == IPPROTO_TCP) {
415*b636d99dSDavid van Moolenbroek 			int flags;
416*b636d99dSDavid van Moolenbroek 			flags = nr->tcp_flags;
417*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "%s%s%s%s%s%s%s",
418*b636d99dSDavid van Moolenbroek 				flags & TH_FIN  ? "F" : "",
419*b636d99dSDavid van Moolenbroek 				flags & TH_SYN  ? "S" : "",
420*b636d99dSDavid van Moolenbroek 				flags & TH_RST  ? "R" : "",
421*b636d99dSDavid van Moolenbroek 				flags & TH_PUSH ? "P" : "",
422*b636d99dSDavid van Moolenbroek 				flags & TH_ACK  ? "A" : "",
423*b636d99dSDavid van Moolenbroek 				flags & TH_URG  ? "U" : "",
424*b636d99dSDavid van Moolenbroek 				flags           ? " " : ""));
425*b636d99dSDavid van Moolenbroek 		}
426*b636d99dSDavid van Moolenbroek 
427*b636d99dSDavid van Moolenbroek 		buf[0]='\0';
428*b636d99dSDavid van Moolenbroek 		snprintf(buf, sizeof(buf), "(%u<>%u encaps)",
429*b636d99dSDavid van Moolenbroek 			 (EXTRACT_16BITS(&nr->flags) >> 8) & 0xff,
430*b636d99dSDavid van Moolenbroek 			 (EXTRACT_16BITS(&nr->flags)) & 0xff);
431*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "tos %u, %u (%u octets) %s",
432*b636d99dSDavid van Moolenbroek 		       nr->tos,
433*b636d99dSDavid van Moolenbroek 		       EXTRACT_32BITS(&nr->packets),
434*b636d99dSDavid van Moolenbroek 		       EXTRACT_32BITS(&nr->octets), buf));
435*b636d99dSDavid van Moolenbroek 	}
436*b636d99dSDavid van Moolenbroek 	return;
437*b636d99dSDavid van Moolenbroek 
438*b636d99dSDavid van Moolenbroek trunc:
439*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "[|cnfp]"));
440*b636d99dSDavid van Moolenbroek 	return;
441*b636d99dSDavid van Moolenbroek }
442*b636d99dSDavid van Moolenbroek 
443*b636d99dSDavid van Moolenbroek void
cnfp_print(netdissect_options * ndo,const u_char * cp)444*b636d99dSDavid van Moolenbroek cnfp_print(netdissect_options *ndo, const u_char *cp)
445*b636d99dSDavid van Moolenbroek {
446*b636d99dSDavid van Moolenbroek 	int ver;
447*b636d99dSDavid van Moolenbroek 
448*b636d99dSDavid van Moolenbroek 	/*
449*b636d99dSDavid van Moolenbroek 	 * First 2 bytes are the version number.
450*b636d99dSDavid van Moolenbroek 	 */
451*b636d99dSDavid van Moolenbroek 	ND_TCHECK2(*cp, 2);
452*b636d99dSDavid van Moolenbroek 	ver = EXTRACT_16BITS(cp);
453*b636d99dSDavid van Moolenbroek 	switch (ver) {
454*b636d99dSDavid van Moolenbroek 
455*b636d99dSDavid van Moolenbroek 	case 1:
456*b636d99dSDavid van Moolenbroek 		cnfp_v1_print(ndo, cp);
457*b636d99dSDavid van Moolenbroek 		break;
458*b636d99dSDavid van Moolenbroek 
459*b636d99dSDavid van Moolenbroek 	case 5:
460*b636d99dSDavid van Moolenbroek 		cnfp_v5_print(ndo, cp);
461*b636d99dSDavid van Moolenbroek 		break;
462*b636d99dSDavid van Moolenbroek 
463*b636d99dSDavid van Moolenbroek 	case 6:
464*b636d99dSDavid van Moolenbroek 		cnfp_v6_print(ndo, cp);
465*b636d99dSDavid van Moolenbroek 		break;
466*b636d99dSDavid van Moolenbroek 
467*b636d99dSDavid van Moolenbroek 	default:
468*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "NetFlow v%x", ver));
469*b636d99dSDavid van Moolenbroek 		break;
470*b636d99dSDavid van Moolenbroek 	}
471*b636d99dSDavid van Moolenbroek 	return;
472*b636d99dSDavid van Moolenbroek 
473*b636d99dSDavid van Moolenbroek trunc:
474*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "[|cnfp]"));
475*b636d99dSDavid van Moolenbroek 	return;
476*b636d99dSDavid van Moolenbroek }
477