Projet

Général

Profil

Télécharger (7,87 ko) Statistiques
| Branche: | Révision:

univnautes-tools / pfPorts / filterlog / files / print-ip.c @ 8135339c

1
/*
2
 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
3
 *	The Regents of the University of California.  All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that: (1) source code distributions
7
 * retain the above copyright notice and this paragraph in its entirety, (2)
8
 * distributions including binary code include the above copyright notice and
9
 * this paragraph in its entirety in the documentation or other materials
10
 * provided with the distribution, and (3) all advertising materials mentioning
11
 * features or use of this software display the following acknowledgement:
12
 * ``This product includes software developed by the University of California,
13
 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14
 * the University nor the names of its contributors may be used to endorse
15
 * or promote products derived from this software without specific prior
16
 * written permission.
17
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20
 *
21
 * $FreeBSD$
22
 */
23

    
24
#include <sys/types.h>
25
#include <sys/socket.h>
26

    
27
#include <netinet/in.h>
28
#include <arpa/inet.h>
29
#include <netinet/ip.h>
30

    
31
#include <netinet/udp.h>
32

    
33
#include <stdio.h>
34
#include <stdlib.h>
35
#include <string.h>
36
#include <netdb.h>
37

    
38
#include <pcap/pcap.h>
39

    
40
#include "common.h"
41

    
42
#define IP_RES 0x8000
43

    
44
static struct tok ip_frag_values[] = {
45
        { IP_MF,        "+" },
46
        { IP_DF,        "DF" },
47
	{ IP_RES,       "rsvd" }, /* The RFC3514 evil ;-) bit */
48
        { 0,            NULL }
49
};
50

    
51
struct ip_print_demux_state {
52
	const struct ip *ip;
53
	const u_char *cp;
54
	u_int   len, off;
55
	u_char  nh;
56
	int     advance;
57
};
58

    
59
static void
60
ip_print_demux(struct sbuf *sbuf,
61
	       struct ip_print_demux_state *ipds)
62
{
63
#if 0
64
	struct protoent *proto;
65
	struct cksum_vec vec[1];
66

    
67
again:
68
#endif
69
	switch (ipds->nh) {
70

    
71
#if 0
72
	case IPPROTO_AH:
73
		ipds->nh = *ipds->cp;
74
		ipds->advance = ah_print(ipds->cp);
75
		if (ipds->advance <= 0)
76
			break;
77
		ipds->cp += ipds->advance;
78
		ipds->len -= ipds->advance;
79
		goto again;
80

    
81
	case IPPROTO_ESP:
82
	{
83
		int enh, padlen;
84
		ipds->advance = esp_print(ndo, ipds->cp, ipds->len,
85
				    (const u_char *)ipds->ip,
86
				    &enh, &padlen);
87
		if (ipds->advance <= 0)
88
			break;
89
		ipds->cp += ipds->advance;
90
		ipds->len -= ipds->advance + padlen;
91
		ipds->nh = enh & 0xff;
92
		goto again;
93
	}
94

    
95
	case IPPROTO_IPCOMP:
96
	{
97
		int enh;
98
		ipds->advance = ipcomp_print(ipds->cp, &enh);
99
		if (ipds->advance <= 0)
100
			break;
101
		ipds->cp += ipds->advance;
102
		ipds->len -= ipds->advance;
103
		ipds->nh = enh & 0xff;
104
		goto again;
105
	}
106

    
107
	case IPPROTO_SCTP:
108
		sctp_print(ipds->cp, (const u_char *)ipds->ip, ipds->len);
109
		break;
110

    
111
	case IPPROTO_DCCP:
112
		dccp_print(ipds->cp, (const u_char *)ipds->ip, ipds->len);
113
		break;
114
#endif
115

    
116
	case IPPROTO_TCP:
117
		/* pass on the MF bit plus the offset to detect fragments */
118
		tcp_print(sbuf, ipds->cp, ipds->len, (const u_char *)ipds->ip);
119
		break;
120

    
121
	case IPPROTO_UDP:
122
	{
123
		const struct udphdr *up;
124

    
125
		up = (const struct udphdr *)ipds->cp;
126
		sbuf_printf(sbuf, "%d,%d,%d", EXTRACT_16BITS(&up->uh_sport), EXTRACT_16BITS(&up->uh_dport),
127
			EXTRACT_16BITS(&up->uh_ulen));
128

    
129
	}
130
		break;
131

    
132
	case IPPROTO_ICMP:
133
		/* pass on the MF bit plus the offset to detect fragments */
134
		icmp_print(sbuf, ipds->cp, ipds->len, (const u_char *)ipds->ip,
135
			   ipds->off & (IP_MF|IP_OFFMASK));
136
		break;
137

    
138
#if 0
139
	case IPPROTO_PIGP:
140
		/*
141
		 * XXX - the current IANA protocol number assignments
142
		 * page lists 9 as "any private interior gateway
143
		 * (used by Cisco for their IGRP)" and 88 as
144
		 * "EIGRP" from Cisco.
145
		 *
146
		 * Recent BSD <netinet/in.h> headers define
147
		 * IP_PROTO_PIGP as 9 and IP_PROTO_IGRP as 88.
148
		 * We define IP_PROTO_PIGP as 9 and
149
		 * IP_PROTO_EIGRP as 88; those names better
150
		 * match was the current protocol number
151
		 * assignments say.
152
		 */
153
		igrp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip);
154
		break;
155

    
156
	case IPPROTO_EIGRP:
157
		eigrp_print(ipds->cp, ipds->len);
158
		break;
159

    
160
	case IPPROTO_ND:
161
		ND_PRINT((ndo, " nd %d", ipds->len));
162
		break;
163

    
164
	case IPPROTO_EGP:
165
		egp_print(ipds->cp, ipds->len);
166
		break;
167

    
168
	case IPPROTO_OSPF:
169
		ospf_print(ipds->cp, ipds->len, (const u_char *)ipds->ip);
170
		break;
171
	case IPPROTO_IGMP:
172
		igmp_print(ipds->cp, ipds->len);
173
		break;
174
#endif
175

    
176
	case IPPROTO_IPV4:
177
		/* DVMRP multicast tunnel (ip-in-ip encapsulation) */
178
		sbuf_printf(sbuf, "IPV4-IN-IPV4,");
179
		//ip_print(sbuf, ipds->cp, ipds->len);
180
		break;
181

    
182
	case IPPROTO_IPV6:
183
		/* ip6-in-ip encapsulation */
184
		//ip6_print(sbuf, ipds->cp, ipds->len);
185
		sbuf_printf(sbuf, "IPV6-IN-IPV4,");
186
		break;
187
#if 0
188
	case IPPROTO_RSVP:
189
		rsvp_print(ipds->cp, ipds->len);
190
		break;
191

    
192
	case IPPROTO_GRE:
193
		/* do it */
194
		gre_print(ipds->cp, ipds->len);
195
		break;
196

    
197
	case IPPROTO_MOBILE:
198
		mobile_print(ipds->cp, ipds->len);
199
		break;
200

    
201
	case IPPROTO_PIM:
202
		vec[0].ptr = ipds->cp;
203
		vec[0].len = ipds->len;
204
		pim_print(ipds->cp, ipds->len, in_cksum(vec, 1));
205
		break;
206
#endif
207
	case IPPROTO_VRRP:
208
		/* Type, ttl, vhid, version, adbskew, advbase */
209
		sbuf_printf(sbuf, "%s,%d,%d,%d,%d,%d",
210
				(ipds->cp[0] & 0x0f) == 1 ? "advertise" : "unkwn",
211
				ipds->ip->ip_ttl, ipds->cp[1], (ipds->cp[0] & 0xf0) >> 4,
212
				ipds->cp[2], ipds->cp[5]);
213
		break;
214

    
215
#if 0
216
	case IPPROTO_PGM:
217
		pgm_print(ipds->cp, ipds->len, (const u_char *)ipds->ip);
218
		break;
219

    
220
	case IPPROTO_PFSYNC:
221
		pfsync_ip_print(ipds->cp, ipds->len);
222
		break;
223
#endif
224
	default:
225
		//sbuf_printf(sbuf, "ip-proto=%d ", ipds->nh);
226
		sbuf_printf(sbuf, "datalength=%d ", ipds->len);
227
		break;
228
	}
229
}
230

    
231
/*
232
 * print an IP datagram.
233
 * it requires fixed length fields to be put as null always
234
 */
235
void
236
ip_print(struct sbuf *sbuf,
237
	 const u_char *bp,
238
	 u_int length)
239
{
240
	struct ip_print_demux_state  ipd;
241
	struct ip_print_demux_state *ipds=&ipd;
242
	const u_char *ipend;
243
	u_int hlen;
244

    
245
	ipds->ip = (const struct ip *)bp;
246
	sbuf_printf(sbuf, "%u,", IP_V(ipds->ip));
247

    
248
	if (ntohs(ipds->ip->ip_len) > MAXIMUM_SNAPLEN) {
249
		sbuf_printf(sbuf, "[|ip]),");
250
		return;
251
	}
252
	if (length < sizeof (struct ip)) {
253
		sbuf_printf(sbuf, "truncated-ip= %u),", length);
254
		return;
255
	}
256
	hlen = IP_HL(ipds->ip) * 4;
257
	if (hlen < sizeof (struct ip)) {
258
		sbuf_printf(sbuf, "bad-hlen=%u),", hlen);
259
		return;
260
	}
261

    
262
	ipds->len = EXTRACT_16BITS(&ipds->ip->ip_len);
263
	if (length < ipds->len)
264
		sbuf_printf(sbuf, "error='truncated-ip %u bytes missing!',",
265
			ipds->len - length);
266
	if (ipds->len < hlen) {
267
	    sbuf_printf(sbuf, "bad-len=%u,", ipds->len);
268
	    return;
269
	}
270

    
271
	/*
272
	 * Cut off the snapshot length to the end of the IP payload.
273
	 */
274
	ipend = bp + ipds->len;
275
	ipds->len -= hlen;
276
	ipds->off = EXTRACT_16BITS(&ipds->ip->ip_off);
277

    
278
	sbuf_printf(sbuf, "0x%x,", (int)ipds->ip->ip_tos);
279
	/* ECN bits */
280
	if (ipds->ip->ip_tos & 0x03) {
281
		switch (ipds->ip->ip_tos & 0x03) {
282
		case 1:
283
			sbuf_printf(sbuf, "1");
284
			break;
285
		case 2:
286
			sbuf_printf(sbuf, "0");
287
			break;
288
		case 3:
289
			sbuf_printf(sbuf, "CE");
290
			break;
291
		}
292
	}
293
	sbuf_printf(sbuf, ",%u,", ipds->ip->ip_ttl);
294

    
295
	/*
296
	 * for the firewall guys, print id, offset.
297
	 * On all but the last stick a "+" in the flags portion.
298
	 * For unfragmented datagrams, note the don't fragment flag.
299
	 */
300
	sbuf_printf(sbuf, "%u,%u,%s,%u,",
301
			 EXTRACT_16BITS(&ipds->ip->ip_id),
302
			 (ipds->off & 0x1fff) * 8,
303
			 code2str(ip_frag_values, "none", ipds->off & 0xe000),
304
			 ipds->ip->ip_p);
305

    
306
	if (getprotobynumber(ipds->ip->ip_p) != NULL)
307
		sbuf_printf(sbuf, "%s,", ((struct protoent *)getprotobynumber(ipds->ip->ip_p))->p_name);
308
	else
309
		sbuf_printf(sbuf, "%s,", 
310
		 code2str(ipproto_values, "unknown", ipds->ip->ip_p));
311
	sbuf_printf(sbuf, "%u,", EXTRACT_16BITS(&ipds->ip->ip_len));
312

    
313
	sbuf_printf(sbuf, "%s,", inet_ntoa(ipds->ip->ip_src));
314
	sbuf_printf(sbuf, "%s,", inet_ntoa(ipds->ip->ip_dst));
315
	/*
316
	 * If this is fragment zero, hand it to the next higher
317
	 * level protocol.
318
	 */
319
	if ((ipds->off & 0x1fff) == 0) {
320
		ipds->cp = (const u_char *)ipds->ip + hlen;
321
		ipds->nh = ipds->ip->ip_p;
322

    
323
		ip_print_demux(sbuf, ipds);
324
	}
325
}
(7-7/11)