Projet

Général

Profil

Télécharger (9,86 ko) Statistiques
| Branche: | Révision:

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

1
/*	$NetBSD: print-tcp.c,v 1.9 2007/07/26 18:15:12 plunky Exp $	*/
2

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

    
26
#include <sys/types.h>
27
#include <sys/socket.h>
28
#include <sys/sbuf.h>
29
#include <netinet/in.h>
30
#include <netinet/ip.h>
31
#include <netinet/tcp.h>
32

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

    
37
#include "common.h"
38

    
39
const struct tok ipproto_values[] = {
40
    { IPPROTO_HOPOPTS, "Options" },
41
    { IPPROTO_ICMP, "ICMP" },
42
    { IPPROTO_IGMP, "IGMP" },
43
    { IPPROTO_IPV4, "IPIP" },
44
    { IPPROTO_TCP, "TCP" },
45
    { IPPROTO_EGP, "EGP" },
46
    { IPPROTO_PIGP, "IGRP" },
47
    { IPPROTO_UDP, "UDP" },
48
    { IPPROTO_DCCP, "DCCP" },
49
    { IPPROTO_IPV6, "IPv6" },
50
    { IPPROTO_ROUTING, "Routing" },
51
    { IPPROTO_FRAGMENT, "Fragment" },
52
    { IPPROTO_RSVP, "RSVP" },
53
    { IPPROTO_GRE, "GRE" },
54
    { IPPROTO_ESP, "ESP" },
55
    { IPPROTO_AH, "AH" },
56
    { IPPROTO_MOBILE, "Mobile IP" },
57
    { IPPROTO_ICMPV6, "ICMPv6" },
58
    { IPPROTO_MOBILITY_OLD, "Mobile IP (old)" },
59
    { IPPROTO_EIGRP, "EIGRP" },
60
    { IPPROTO_OSPF, "OSPF" },
61
    { IPPROTO_PIM, "PIM" },
62
    { IPPROTO_IPCOMP, "Compressed IP" },
63
    { IPPROTO_VRRP, "VRRP" },
64
    { IPPROTO_PGM, "PGM" },
65
    { IPPROTO_SCTP, "SCTP" },
66
    { IPPROTO_MOBILITY, "Mobility" },
67
    { IPPROTO_CARP, "CARP" },
68
    { IPPROTO_PFSYNC, "pfsync" },
69
    { 0, NULL }
70
};
71

    
72
/* These tcp optinos do not have the size octet */
73
#define ZEROLENOPT(o) ((o) == TCPOPT_EOL || (o) == TCPOPT_NOP)
74
#define TCP_SIGLEN 16
75

    
76
#define TCPOPT_WSCALE           3       /* window scale factor (rfc1323) */
77
#define TCPOPT_SACKOK           4       /* selective ack ok (rfc2018) */
78
#define TCPOPT_SACK             5       /* selective ack (rfc2018) */
79
#define TCPOPT_ECHO             6       /* echo (rfc1072) */
80
#define TCPOPT_ECHOREPLY        7       /* echo (rfc1072) */
81
#define TCPOPT_TIMESTAMP        8       /* timestamp (rfc1323) */
82
#define    TCPOLEN_TIMESTAMP            10
83
#define    TCPOLEN_TSTAMP_APPA          (TCPOLEN_TIMESTAMP+2) /* appendix A */
84
#define TCPOPT_CC               11      /* T/TCP CC options (rfc1644) */
85
#define TCPOPT_CCNEW            12      /* T/TCP CC options (rfc1644) */
86
#define TCPOPT_CCECHO           13      /* T/TCP CC options (rfc1644) */
87
#define TCPOPT_SIGNATURE        19      /* Keyed MD5 (rfc2385) */
88
#define    TCPOLEN_SIGNATURE            18
89
#define TCPOPT_AUTH             20      /* Enhanced AUTH option */
90
#define TCPOPT_UTO              28      /* tcp user timeout (rfc5482) */
91

    
92
struct tok tcp_option_values[] = {
93
        { TCPOPT_EOL, "eol" },
94
        { TCPOPT_NOP, "nop" },
95
        { TCPOPT_MAXSEG, "mss" },
96
        { TCPOPT_WSCALE, "wscale" },
97
        { TCPOPT_SACKOK, "sackOK" },
98
        { TCPOPT_SACK, "sack" },
99
        { TCPOPT_ECHO, "echo" },
100
        { TCPOPT_ECHOREPLY, "echoreply" },
101
        { TCPOPT_TIMESTAMP, "TS" },
102
        { TCPOPT_CC, "cc" },
103
        { TCPOPT_CCNEW, "ccnew" },
104
        { TCPOPT_CCECHO, "" },
105
        { TCPOPT_SIGNATURE, "md5" },
106
        { TCPOPT_AUTH, "enhanced auth" },
107
        { TCPOPT_UTO, "uto" },
108
        { 0, NULL }
109
};
110

    
111
void
112
tcp_print(struct sbuf *sbuf, register const u_char *bp, register u_int length,
113
	  register const u_char *bp2)
114
{
115
        register const struct tcphdr *tp;
116
        register const struct ip *ip;
117
        register u_char flags;
118
        register u_int hlen;
119
        register char ch;
120
        u_int16_t sport, dport, win, urp;
121
        u_int32_t seq, ack;
122
        register const struct ip6_hdr *ip6;
123

    
124
        tp = (const struct tcphdr *)bp;
125

    
126
        hlen = (tp->th_off & 0x0f) * 4;
127
        if (hlen < sizeof(*tp)) {
128
                sbuf_printf(sbuf, "errormsg='tcp %d [bad hdr length %u - too short < %lu]',",
129
                             length - hlen, hlen, (unsigned long)sizeof(*tp));
130
                return;
131
        }
132

    
133
        ip = (const struct ip *)bp2;
134
        if (IP_V(ip) == 6)
135
                ip6 = (const struct ip6_hdr *)bp2;
136
        else
137
                ip6 = NULL;
138
        ch = '\0';
139
        sport = EXTRACT_16BITS(&tp->th_sport);
140
        dport = EXTRACT_16BITS(&tp->th_dport);
141

    
142
	sbuf_printf(sbuf, "%u,%u,%d,", sport, dport, length - hlen);
143

    
144
        seq = EXTRACT_32BITS(&tp->th_seq);
145
        ack = EXTRACT_32BITS(&tp->th_ack);
146
        win = EXTRACT_16BITS(&tp->th_win);
147
        urp = EXTRACT_16BITS(&tp->th_urp);
148

    
149
        flags = tp->th_flags;
150
        sbuf_printf(sbuf, "%s%s%s", flags & TH_FIN ? "F" : "", flags & TH_SYN ? "S" : "", flags & TH_RST ? "R" : "");
151
        sbuf_printf(sbuf, "%s%s%s", flags & TH_PUSH ? "P" : "", flags & TH_ACK ? "A" : "", flags & TH_URG ? "U" : "");
152
        sbuf_printf(sbuf, "%s%s,", flags & TH_ECE ? "E" : "", flags & TH_CWR ? "C" : "");
153

    
154
        if (hlen > length) {
155
                sbuf_printf(sbuf, "errormsg='[bad hdr length %u - too long, > %u]',",
156
                             hlen, length);
157
                return;
158
        }
159

    
160
        length -= hlen;
161
        if (length > 0 || flags & (TH_SYN | TH_FIN | TH_RST)) {
162
                if (length > 0)
163
                        sbuf_printf(sbuf, "%u:%u,", seq, seq + length);
164
		else
165
			sbuf_printf(sbuf, "%u,", seq);
166
        } else
167
		sbuf_printf(sbuf, ",");
168

    
169
        if (flags & TH_ACK)
170
                sbuf_printf(sbuf, "%u,", ack);
171
	else
172
		sbuf_printf(sbuf, ",");
173

    
174
        sbuf_printf(sbuf, "%d,", win);
175

    
176
        if (flags & TH_URG)
177
                sbuf_printf(sbuf, "%d,", urp);
178
	else
179
		sbuf_printf(sbuf, ",");
180

    
181
        /*
182
         * Handle any options.
183
         */
184
        if (hlen > sizeof(*tp)) {
185
                register const u_char *cp;
186
                register u_int opt, datalen;
187
                register u_int len;
188

    
189
                hlen -= sizeof(*tp);
190
                cp = (const u_char *)tp + sizeof(*tp);
191
                while (hlen > 0) {
192
                        if (ch != '\0')
193
                                sbuf_printf(sbuf, "%c", ch);
194
                        opt = *cp++;
195
                        if (ZEROLENOPT(opt))
196
                                len = 1;
197
                        else {
198
                                len = *cp++;	/* total including type, len */
199
                                if (len < 2 || len > hlen)
200
                                        goto bad;
201
                                --hlen;		/* account for length byte */
202
                        }
203
                        --hlen;			/* account for type byte */
204
                        datalen = 0;
205

    
206
                        sbuf_printf(sbuf, "%s", code2str(tcp_option_values, "Unknown Option %u", opt));
207

    
208
			switch (opt) {
209
                        case TCPOPT_MAXSEG:
210
                                datalen = 2;
211
                                break;
212
                        case TCPOPT_WSCALE:
213
                                datalen = 1;
214
                                break;
215
                        case TCPOPT_SACK:
216
                                datalen = len - 2;
217
                                break;
218
                        case TCPOPT_CC:
219
                        case TCPOPT_CCNEW:
220
                        case TCPOPT_CCECHO:
221
                        case TCPOPT_ECHO:
222
                        case TCPOPT_ECHOREPLY:
223
                                datalen = 4;
224
                                break;
225
                        case TCPOPT_TIMESTAMP:
226
                                datalen = 8;
227
                                break;
228
                        case TCPOPT_SIGNATURE:
229
                                datalen = TCP_SIGLEN;
230
                                break;
231
                        case TCPOPT_AUTH:
232
                                datalen = len - 3;
233
                                break;
234
                        case TCPOPT_EOL:
235
                        case TCPOPT_NOP:
236
                        case TCPOPT_SACKOK:
237
                                /*
238
                                 * Nothing interesting.
239
                                 * fall through
240
                                 */
241
                                break;
242
                        case TCPOPT_UTO:
243
                                datalen = 2;
244
                                break;
245
                        default:
246
                                datalen = len - 2;
247
                                break;
248
                        }
249

    
250
                        /* Account for data printed */
251
                        cp += datalen;
252
                        hlen -= datalen;
253

    
254
                        /* Check specification against observed length */
255
                        ++datalen;			/* option octet */
256
                        if (!ZEROLENOPT(opt))
257
                                ++datalen;		/* size octet */
258
                        ch = ';';
259
                        if (opt == TCPOPT_EOL)
260
                                break;
261
                }
262
        }
263

    
264
        if (length <= 0)
265
                return;
266

    
267
        return;
268
 bad:
269
        sbuf_printf(sbuf, "[bad opt],");
270
        if (ch != '\0')
271
                sbuf_printf(sbuf, ">,");
272
        return;
273
}
(11-11/11)