Projet

Général

Profil

Télécharger (8,88 ko) Statistiques
| Branche: | Révision:

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

1
/*
2
 * Copyright (C) 1998 WIDE Project.
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice, this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright
11
 *    notice, this list of conditions and the following disclaimer in the
12
 *    documentation and/or other materials provided with the distribution.
13
 * 3. Neither the name of the project nor the names of its contributors
14
 *    may be used to endorse or promote products derived from this software
15
 *    without specific prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
18
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
21
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
 * SUCH DAMAGE.
28
 */
29

    
30
#include <sys/types.h>
31
#include <sys/socket.h>
32

    
33
#include <netinet/in.h>
34
#include <netinet/ip6.h>
35
#include <arpa/inet.h>
36

    
37
#include <netinet/udp.h>
38

    
39
#include <stdio.h>
40
#include <string.h>
41

    
42
#include "common.h"
43

    
44
/* items outside of rfc2292bis */
45
#ifndef IP6OPT_MINLEN
46
#define IP6OPT_MINLEN	2
47
#endif
48
#ifndef IP6OPT_RTALERT_LEN
49
#define IP6OPT_RTALERT_LEN	4
50
#endif
51
#ifndef IP6OPT_JUMBO_LEN
52
#define IP6OPT_JUMBO_LEN	6
53
#endif
54
#define IP6OPT_HOMEADDR_MINLEN 18
55
#define IP6OPT_BU_MINLEN       10
56
#define IP6OPT_BA_MINLEN       13
57
#define IP6OPT_BR_MINLEN        2
58
#define IP6SOPT_UI            0x2
59
#define IP6SOPT_UI_MINLEN       4
60
#define IP6SOPT_ALTCOA        0x3
61
#define IP6SOPT_ALTCOA_MINLEN  18
62
#define IP6SOPT_AUTH          0x4
63
#define IP6SOPT_AUTH_MINLEN     6
64

    
65
#define IP6OPT_BINDING_UPDATE	0xc6	/* 11 0 00110 */
66
#define IP6OPT_BINDING_ACK	0x07	/* 00 0 00111 */
67
#define IP6OPT_BINDING_REQ	0x08	/* 00 0 01000 */
68
#define IP6OPT_HOME_ADDRESS	0xc9	/* 11 0 01001 */
69
#define IP6OPT_EID		0x8a	/* 10 0 01010 */
70

    
71
#define IP6OPT_TYPE(o)		((o) & 0xC0)
72
#define IP6OPT_TYPE_SKIP	0x00
73
#define IP6OPT_TYPE_DISCARD	0x40
74
#define IP6OPT_TYPE_FORCEICMP	0x80
75
#define IP6OPT_TYPE_ICMP	0xC0
76

    
77
#define IP6OPT_MUTABLE		0x20
78

    
79
static void ip6_sopt_print(struct sbuf *, const u_char *, int);
80

    
81
static void
82
ip6_sopt_print(struct sbuf *sbuf, const u_char *bp, int len)
83
{
84
    char ip6addr[INET6_ADDRSTRLEN];
85
    int i;
86
    int optlen;
87

    
88
    for (i = 0; i < len; i += optlen) {
89
	if (bp[i] == IP6OPT_PAD1)
90
	    optlen = 1;
91
	else {
92
	    if (i + 1 < len)
93
		optlen = bp[i + 1] + 2;
94
	    else
95
		goto trunc;
96
	}
97
	if (i + optlen > len)
98
	    goto trunc;
99

    
100
	switch (bp[i]) {
101
	case IP6OPT_PAD1:
102
            sbuf_printf(sbuf, "pad1 ");
103
	    break;
104
	case IP6OPT_PADN:
105
	    if (len - i < IP6OPT_MINLEN) {
106
		sbuf_printf(sbuf, "padn=trunc ");
107
		goto trunc;
108
	    }
109
            sbuf_printf(sbuf, "padn ");
110
	    break;
111
        case IP6SOPT_UI:
112
             if (len - i < IP6SOPT_UI_MINLEN) {
113
		sbuf_printf(sbuf, "ui=trunc ");
114
		goto trunc;
115
	    }
116
            sbuf_printf(sbuf, "ui=0x%04x ", EXTRACT_16BITS(&bp[i + 2]));
117
	    break;
118
        case IP6SOPT_ALTCOA:
119
             if (len - i < IP6SOPT_ALTCOA_MINLEN) {
120
		sbuf_printf(sbuf, "altcoa=trunc ");
121
		goto trunc;
122
	    }
123
	    memset(ip6addr, 0, INET6_ADDRSTRLEN);
124
            sbuf_printf(sbuf, "alt-CoA=%s ", inet_ntop(AF_INET6, &bp[i+2], ip6addr, INET6_ADDRSTRLEN));
125
	    break;
126
        case IP6SOPT_AUTH:
127
             if (len - i < IP6SOPT_AUTH_MINLEN) {
128
		sbuf_printf(sbuf, "auth=trunc ");
129
		goto trunc;
130
	    }
131
            sbuf_printf(sbuf, "auth-spi=0x%08x ", EXTRACT_32BITS(&bp[i + 2]));
132
	    break;
133
	default:
134
	    if (len - i < IP6OPT_MINLEN) {
135
		sbuf_printf(sbuf, "sopt_type_trunc=%d)", bp[i]);
136
		goto trunc;
137
	    }
138
	    sbuf_printf(sbuf, "sopt_type=0x%02x len=%d", bp[i], bp[i + 1]);
139
	    break;
140
	}
141
    }
142
    return;
143

    
144
trunc:
145
    sbuf_printf(sbuf, "[trunc] ");
146
}
147

    
148
void
149
ip6_opt_print(struct sbuf *sbuf, const u_char *bp, int len)
150
{
151
    char ip6addr[INET6_ADDRSTRLEN];
152
    int i;
153
    int optlen = 0;
154

    
155
    if (len == 0)
156
        return;
157
    for (i = 0; i < len; i += optlen) {
158
	if (bp[i] == IP6OPT_PAD1)
159
	    optlen = 1;
160
	else {
161
	    if (i + 1 < len)
162
		optlen = bp[i + 1] + 2;
163
	    else
164
		goto trunc;
165
	}
166
	if (i + optlen > len)
167
	    goto trunc;
168

    
169
	switch (bp[i]) {
170
	case IP6OPT_PAD1:
171
            sbuf_printf(sbuf, "PAD1,");
172
	    break;
173
	case IP6OPT_PADN:
174
	    if (len - i < IP6OPT_MINLEN) {
175
		sbuf_printf(sbuf, "PADNTRUNC,");
176
		goto trunc;
177
	    }
178
            sbuf_printf(sbuf, "PADN,");
179
	    break;
180
	case IP6OPT_ROUTER_ALERT:
181
	    if (len - i < IP6OPT_RTALERT_LEN) {
182
		sbuf_printf(sbuf, "RTALERTTRUNC,");
183
		goto trunc;
184
	    }
185
	    if (bp[i + 1] != IP6OPT_RTALERT_LEN - 2) {
186
		sbuf_printf(sbuf, "RTALERTINVALID, %d,", bp[i + 1]);
187
		goto trunc;
188
	    }
189
	    sbuf_printf(sbuf, "RTALERT,0x%04x,", EXTRACT_16BITS(&bp[i + 2]));
190
	    break;
191
	case IP6OPT_JUMBO:
192
	    if (len - i < IP6OPT_JUMBO_LEN) {
193
		sbuf_printf(sbuf, "JUMBOTRUNC,");
194
		goto trunc;
195
	    }
196
	    if (bp[i + 1] != IP6OPT_JUMBO_LEN - 2) {
197
		sbuf_printf(sbuf, "JUMBOINVALID,%d,", bp[i + 1]);
198
		goto trunc;
199
	    }
200
	    sbuf_printf(sbuf, "JUMBO,%u,", EXTRACT_32BITS(&bp[i + 2]));
201
	    break;
202
        case IP6OPT_HOME_ADDRESS:
203
	    if (len - i < IP6OPT_HOMEADDR_MINLEN) {
204
		sbuf_printf(sbuf, "HOMEADDRTRUNC,");
205
		goto trunc;
206
	    }
207
	    if (bp[i + 1] < IP6OPT_HOMEADDR_MINLEN - 2) {
208
		sbuf_printf(sbuf, "HOMEADDRINVALID, %d,", bp[i + 1]);
209
		goto trunc;
210
	    }
211
	    memset(ip6addr, 0, INET6_ADDRSTRLEN);
212
	    sbuf_printf(sbuf, "HOMEADDR, %s,", inet_ntop(AF_INET6, &bp[i + 2], ip6addr, INET6_ADDRSTRLEN));
213
            if (bp[i + 1] > IP6OPT_HOMEADDR_MINLEN - 2) {
214
		ip6_sopt_print(sbuf, &bp[i + IP6OPT_HOMEADDR_MINLEN],
215
		    (optlen - IP6OPT_HOMEADDR_MINLEN));
216
	    }
217
	    break;
218
        case IP6OPT_BINDING_UPDATE:
219
	    if (len - i < IP6OPT_BU_MINLEN) {
220
		sbuf_printf(sbuf, "BINDINGUPTRUNC,");
221
		goto trunc;
222
	    }
223
	    if (bp[i + 1] < IP6OPT_BU_MINLEN - 2) {
224
		sbuf_printf(sbuf, "BINDINGUPINVALID,%d,", bp[i + 1]);
225
		goto trunc;
226
	    }
227
	    sbuf_printf(sbuf, "BINDINGUP,");
228
	    if (bp[i + 2] & 0x80)
229
		    sbuf_printf(sbuf, "A");
230
	    if (bp[i + 2] & 0x40)
231
		    sbuf_printf(sbuf, "H");
232
	    if (bp[i + 2] & 0x20)
233
		    sbuf_printf(sbuf, "S");
234
	    if (bp[i + 2] & 0x10)
235
		    sbuf_printf(sbuf, "D");
236
	    if ((bp[i + 2] & 0x0f) || bp[i + 3] || bp[i + 4])
237
		    sbuf_printf(sbuf, "r");
238
	    sbuf_printf(sbuf, ",%u,", bp[i + 5]);
239
	    sbuf_printf(sbuf, "%u,", EXTRACT_32BITS(&bp[i + 6]));
240

    
241
	    if (bp[i + 1] > IP6OPT_BU_MINLEN - 2) {
242
		ip6_sopt_print(sbuf, &bp[i + IP6OPT_BU_MINLEN],
243
		    (optlen - IP6OPT_BU_MINLEN));
244
	    }
245
	    break;
246
	case IP6OPT_BINDING_ACK:
247
	    if (len - i < IP6OPT_BA_MINLEN) {
248
		sbuf_printf(sbuf, "BINDINGACKTRUNC,");
249
		goto trunc;
250
	    }
251
	    if (bp[i + 1] < IP6OPT_BA_MINLEN - 2) {
252
		sbuf_printf(sbuf, "BINDINGACKINVALID,%d,", bp[i + 1]);
253
		goto trunc;
254
	    }
255
	    sbuf_printf(sbuf, "BINDINGACK,");
256
	    sbuf_printf(sbuf, "%u,", bp[i + 2]);
257
	    if (bp[i + 3])
258
		    sbuf_printf(sbuf, "res,");
259
	    else
260
		sbuf_printf(sbuf, ",");
261
	    sbuf_printf(sbuf, "%u,", bp[i + 4]);
262
	    sbuf_printf(sbuf, "%u,", EXTRACT_32BITS(&bp[i + 5]));
263
	    sbuf_printf(sbuf, "%u,", EXTRACT_32BITS(&bp[i + 9]));
264

    
265
	    if (bp[i + 1] > IP6OPT_BA_MINLEN - 2) {
266
		ip6_sopt_print(sbuf, &bp[i + IP6OPT_BA_MINLEN],
267
		    (optlen - IP6OPT_BA_MINLEN));
268
	    }
269
	    break;
270
        case IP6OPT_BINDING_REQ:
271
	    if (len - i < IP6OPT_BR_MINLEN) {
272
		sbuf_printf(sbuf, "BINDINGREQTRUNC,");
273
		goto trunc;
274
	    }
275
            sbuf_printf(sbuf, "BINDINGREQ,");
276
            if (bp[i + 1] > IP6OPT_BR_MINLEN - 2) {
277
		ip6_sopt_print(sbuf, &bp[i + IP6OPT_BR_MINLEN],
278
		    (optlen - IP6OPT_BR_MINLEN));
279
	    }
280
	    break;
281
	default:
282
	    if (len - i < IP6OPT_MINLEN) {
283
		sbuf_printf(sbuf, "TYPETRUNC,%d,", bp[i]);
284
		goto trunc;
285
	    }
286
	    sbuf_printf(sbuf, "TYPE,0x%02x,%d,", bp[i], bp[i + 1]);
287
	    break;
288
	}
289
    }
290

    
291
trunc:
292
    return;
293
}
294

    
295
int
296
hbhopt_print(struct sbuf *sbuf, register const u_char *bp)
297
{
298
    const struct ip6_hbh *dp = (const struct ip6_hbh *)bp;
299
    int hbhlen = 0;
300

    
301
    hbhlen = (int)((dp->ip6h_len + 1) << 3);
302
    sbuf_printf(sbuf, "HBH,");
303
    ip6_opt_print(sbuf, (const u_char *)dp + sizeof(*dp), hbhlen - sizeof(*dp));
304

    
305
    return(hbhlen);
306
}
307

    
308
int
309
dstopt_print(struct sbuf *sbuf, register const u_char *bp)
310
{
311
    const struct ip6_dest *dp = (const struct ip6_dest *)bp;
312
    int dstoptlen = 0;
313

    
314
    dstoptlen = (int)((dp->ip6d_len + 1) << 3);
315
    sbuf_printf(sbuf, "DSTOPT,");
316
	ip6_opt_print(sbuf, (const u_char *)dp + sizeof(*dp),
317
	    dstoptlen - sizeof(*dp));
318

    
319
    return(dstoptlen);
320
}
(9-9/11)