~ubuntu-branches/ubuntu/intrepid/tcpdump/intrepid

« back to all changes in this revision

Viewing changes to print-esp.c

  • Committer: Bazaar Package Importer
  • Author(s): Romain Francoise
  • Date: 2005-12-10 14:26:20 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20051210142620-t4ju0367w6j2x06i
Tags: 3.9.4-2
debian/patches/20_man_fixes.dpatch: Merge patch from A Costa
<agcosta@gis.net> fixing a few typos (closes: #342310).

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
 
24
24
#ifndef lint
25
25
static const char rcsid[] _U_ =
26
 
    "@(#) $Header: /tcpdump/master/tcpdump/print-esp.c,v 1.44.2.4 2003/11/19 05:36:40 guy Exp $ (LBL)";
 
26
    "@(#) $Header: /tcpdump/master/tcpdump/print-esp.c,v 1.55.2.1 2005/04/21 06:44:57 guy Exp $ (LBL)";
27
27
#endif
28
28
 
29
29
#ifdef HAVE_CONFIG_H
50
50
#include "ip6.h"
51
51
#endif
52
52
 
53
 
#if defined(__MINGW32__) || defined(__WATCOMC__)
54
 
extern char *strsep(char **stringp, const char *delim); /* Missing/strsep.c */
55
 
#endif
56
 
 
57
 
#include "interface.h"
 
53
#include "netdissect.h"
58
54
#include "addrtoname.h"
59
55
#include "extract.h"
60
56
 
79
75
        const EVP_CIPHER *evp;
80
76
        int             ivlen;
81
77
        int             authlen;
82
 
        char            secret[256];  /* is that big enough for all secrets? */
 
78
        u_char          secret[256];  /* is that big enough for all secrets? */
83
79
        int             secretlen;
84
80
};
85
81
 
86
 
static struct sa_list *sa_list_head = NULL;
87
 
static struct sa_list *sa_default = NULL;
88
 
 
89
 
static void esp_print_addsa(struct sa_list *sa, int sa_def)
 
82
static void esp_print_addsa(netdissect_options *ndo,
 
83
                            struct sa_list *sa, int sa_def)
90
84
{
91
85
        /* copy the "sa" */
92
86
 
94
88
 
95
89
        nsa = (struct sa_list *)malloc(sizeof(struct sa_list));
96
90
        if (nsa == NULL)
97
 
                error("ran out of memory to allocate sa structure");
 
91
                (*ndo->ndo_error)(ndo, "ran out of memory to allocate sa structure");
98
92
 
99
93
        *nsa = *sa;
100
94
 
101
95
        if (sa_def)
102
 
                sa_default = nsa;
 
96
                ndo->ndo_sa_default = nsa;
103
97
 
104
 
        nsa->next = sa_list_head;
105
 
        sa_list_head = nsa;
 
98
        nsa->next = ndo->ndo_sa_list_head;
 
99
        ndo->ndo_sa_list_head = nsa;
106
100
}
107
101
 
108
102
 
109
 
static int hexdigit(char hex)
 
103
static u_int hexdigit(netdissect_options *ndo, char hex)
110
104
{
111
105
        if (hex >= '0' && hex <= '9')
112
106
                return (hex - '0');
115
109
        else if (hex >= 'a' && hex <= 'f')
116
110
                return (hex - 'a' + 10);
117
111
        else {
118
 
                printf("invalid hex digit %c in espsecret\n", hex);
 
112
                (*ndo->ndo_error)(ndo, "invalid hex digit %c in espsecret\n", hex);
119
113
                return 0;
120
114
        }
121
115
}
122
116
 
123
 
static int hex2byte(char *hexstring)
 
117
static u_int hex2byte(netdissect_options *ndo, char *hexstring)
124
118
{
125
 
        int byte;
 
119
        u_int byte;
126
120
 
127
 
        byte = (hexdigit(hexstring[0]) << 4) + hexdigit(hexstring[1]);
 
121
        byte = (hexdigit(ndo, hexstring[0]) << 4) + hexdigit(ndo, hexstring[1]);
128
122
        return byte;
129
123
}
130
124
 
135
129
 * causes us to go read from this file instead.
136
130
 *
137
131
 */
138
 
static void esp_print_decode_onesecret(char *line)
 
132
static void esp_print_decode_onesecret(netdissect_options *ndo, char *line)
139
133
{
140
134
        struct sa_list sa1;
141
135
        int sa_def;
177
171
                        if (fileline[0] == '#') continue;
178
172
                        if (fileline[0] == '\0') continue;
179
173
 
180
 
                        esp_print_decode_onesecret(fileline);
 
174
                        esp_print_decode_onesecret(ndo, fileline);
181
175
                }
182
176
                fclose(secretfile);
183
177
 
196
190
 
197
191
                spino = strtoul(spistr, &foo, 0);
198
192
                if (spistr == foo || !spikey) {
199
 
                        printf("print_esp: failed to decode spi# %s\n", foo);
 
193
                        (*ndo->ndo_warning)(ndo, "print_esp: failed to decode spi# %s\n", foo);
200
194
                        return;
201
195
                }
202
196
 
218
212
#endif
219
213
                        sin->sin_family = AF_INET;
220
214
                } else {
221
 
                        printf("print_esp: can not decode IP# %s\n", spikey);
 
215
                        (*ndo->ndo_warning)(ndo, "print_esp: can not decode IP# %s\n", spikey);
222
216
                        return;
223
217
                }
224
218
        }
225
219
 
226
220
        if (decode) {
227
221
                char *colon, *p;
228
 
                char  espsecret_key[256];
 
222
                u_char espsecret_key[256];
229
223
                int len;
230
224
                size_t i;
231
225
                const EVP_CIPHER *evp;
232
 
                int ivlen = 8;
233
226
                int authlen = 0;
234
227
 
235
228
                /* skip any blank spaces */
238
231
 
239
232
                colon = strchr(decode, ':');
240
233
                if (colon == NULL) {
241
 
                        printf("failed to decode espsecret: %s\n", decode);
 
234
                        (*ndo->ndo_warning)(ndo, "failed to decode espsecret: %s\n", decode);
242
235
                        return;
243
236
                }
244
237
                *colon = '\0';
258
251
                }
259
252
                evp = EVP_get_cipherbyname(decode);
260
253
                if (!evp) {
261
 
                        printf("failed to find cipher algo %s\n", decode);
 
254
                        (*ndo->ndo_warning)(ndo, "failed to find cipher algo %s\n", decode);
262
255
                        sa1.evp = NULL;
263
256
                        sa1.authlen = 0;
264
257
                        sa1.ivlen = 0;
267
260
 
268
261
                sa1.evp = evp;
269
262
                sa1.authlen = authlen;
270
 
                sa1.ivlen = ivlen;
 
263
                sa1.ivlen = EVP_CIPHER_iv_length(evp);
271
264
 
272
265
                colon++;
273
266
                if (colon[0] == '0' && colon[1] == 'x') {
276
269
                        len = strlen(colon) / 2;
277
270
 
278
271
                        if (len > 256) {
279
 
                                printf("secret is too big: %d\n", len);
 
272
                                (*ndo->ndo_warning)(ndo, "secret is too big: %d\n", len);
280
273
                                return;
281
274
                        }
282
275
 
283
276
                        i = 0;
284
277
                        while (colon[0] != '\0' && colon[1]!='\0') {
285
 
                                espsecret_key[i] = hex2byte(colon);
 
278
                                espsecret_key[i] = hex2byte(ndo, colon);
286
279
                                colon += 2;
287
280
                                i++;
288
281
                        }
302
295
                }
303
296
        }
304
297
 
305
 
        esp_print_addsa(&sa1, sa_def);
 
298
        esp_print_addsa(ndo, &sa1, sa_def);
306
299
}
307
300
 
308
 
static void esp_print_decodesecret(void)
 
301
static void esp_print_decodesecret(netdissect_options *ndo)
309
302
{
310
303
        char *line;
311
304
        char *p;
312
305
 
313
 
        p = espsecret;
 
306
        p = ndo->ndo_espsecret;
314
307
 
315
 
        while (espsecret && espsecret[0] != '\0') {
 
308
        while (ndo->ndo_espsecret && ndo->ndo_espsecret[0] != '\0') {
316
309
                /* pick out the first line or first thing until a comma */
317
 
                if ((line = strsep(&espsecret, "\n,")) == NULL) {
318
 
                        line = espsecret;
319
 
                        espsecret = NULL;
 
310
                if ((line = strsep(&ndo->ndo_espsecret, "\n,")) == NULL) {
 
311
                        line = ndo->ndo_espsecret;
 
312
                        ndo->ndo_espsecret = NULL;
320
313
                }
321
314
 
322
 
                esp_print_decode_onesecret(line);
 
315
                esp_print_decode_onesecret(ndo, line);
323
316
        }
324
317
}
325
318
 
326
 
static void esp_init(void)
 
319
static void esp_init(netdissect_options *ndo _U_)
327
320
{
328
321
 
329
322
        OpenSSL_add_all_algorithms();
332
325
#endif
333
326
 
334
327
int
335
 
esp_print(const u_char *bp, const u_char *bp2
 
328
esp_print(netdissect_options *ndo,
 
329
          const u_char *bp, const int length, const u_char *bp2
336
330
#ifndef HAVE_LIBCRYPTO
337
331
        _U_
338
332
#endif
359
353
#endif
360
354
        int advance;
361
355
        int len;
362
 
        char *secret;
 
356
        u_char *secret;
363
357
        int ivlen = 0;
364
358
        u_char *ivoff;
365
 
        const u_char *p;
 
359
        u_char *p;
366
360
        EVP_CIPHER_CTX ctx;
367
361
        int blocksz;
368
362
        static int initialized = 0;
375
369
        advance = 0;
376
370
 
377
371
        if (!initialized) {
378
 
                esp_init();
 
372
                esp_init(ndo);
379
373
                initialized = 1;
380
374
        }
381
375
#endif
386
380
#endif
387
381
 
388
382
        /* 'ep' points to the end of available data. */
389
 
        ep = snapend;
 
383
        ep = ndo->ndo_snapend;
390
384
 
391
385
        if ((u_char *)(esp + 1) >= ep) {
392
386
                fputs("[|ESP]", stdout);
393
387
                goto fail;
394
388
        }
395
 
        printf("ESP(spi=0x%08x", EXTRACT_32BITS(&esp->esp_spi));
396
 
        printf(",seq=0x%x", EXTRACT_32BITS(&esp->esp_seq));
397
 
        printf(")");
 
389
        (*ndo->ndo_printf)(ndo, "ESP(spi=0x%08x", EXTRACT_32BITS(&esp->esp_spi));
 
390
        (*ndo->ndo_printf)(ndo, ",seq=0x%x)", EXTRACT_32BITS(&esp->esp_seq));
 
391
        (*ndo->ndo_printf)(ndo, ", length %u", length);
398
392
 
399
393
#ifndef HAVE_LIBCRYPTO
400
394
        goto fail;
401
395
#else
402
396
        /* initiailize SAs */
403
 
        if (sa_list_head == NULL) {
404
 
                if (!espsecret)
 
397
        if (ndo->ndo_sa_list_head == NULL) {
 
398
                if (!ndo->ndo_espsecret)
405
399
                        goto fail;
406
400
 
407
 
                esp_print_decodesecret();
 
401
                esp_print_decodesecret(ndo);
408
402
        }
409
403
 
410
 
        if (sa_list_head == NULL)
 
404
        if (ndo->ndo_sa_list_head == NULL)
411
405
                goto fail;
412
406
 
413
407
        ip = (struct ip *)bp2;
422
416
                len = sizeof(struct ip6_hdr) + EXTRACT_16BITS(&ip6->ip6_plen);
423
417
 
424
418
                /* see if we can find the SA, and if so, decode it */
425
 
                for (sa = sa_list_head; sa != NULL; sa = sa->next) {
 
419
                for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) {
426
420
                        struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&sa->daddr;
427
421
                        if (sa->spi == ntohl(esp->esp_spi) &&
428
422
                            sin6->sin6_family == AF_INET6 &&
440
434
                len = EXTRACT_16BITS(&ip->ip_len);
441
435
 
442
436
                /* see if we can find the SA, and if so, decode it */
443
 
                for (sa = sa_list_head; sa != NULL; sa = sa->next) {
 
437
                for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) {
444
438
                        struct sockaddr_in *sin = (struct sockaddr_in *)&sa->daddr;
445
439
                        if (sa->spi == ntohl(esp->esp_spi) &&
446
440
                            sin->sin_family == AF_INET &&
457
451
         * an unspecified one.
458
452
         */
459
453
        if (sa == NULL)
460
 
                sa = sa_default;
 
454
                sa = ndo->ndo_sa_default;
461
455
        
462
456
        /* if not found fail */
463
457
        if (sa == NULL)
475
469
        ivlen = sa->ivlen;
476
470
        secret = sa->secret;
477
471
        espsecret_keylen = sa->secretlen;
 
472
        ep = ep - sa->authlen;
478
473
 
479
474
        if (sa->evp) {
480
475
                memset(&ctx, 0, sizeof(ctx));
481
476
                if (EVP_CipherInit(&ctx, sa->evp, secret, NULL, 0) < 0)
482
 
                        printf("espkey init failed");
 
477
                        (*ndo->ndo_warning)(ndo, "espkey init failed");
483
478
 
484
479
                blocksz = EVP_CIPHER_CTX_block_size(&ctx);
485
480
 
490
485
        } else
491
486
                advance = sizeof(struct newesp);
492
487
 
493
 
        ep = ep - sa->authlen;
494
488
        /* sanity check for pad length */
495
489
        if (ep - bp < *(ep - 2))
496
490
                goto fail;
501
495
        if (nhdr)
502
496
                *nhdr = *(ep - 1);
503
497
 
504
 
        printf(": ");
 
498
        (ndo->ndo_printf)(ndo, ": ");
505
499
        return advance;
506
500
#endif
507
501
 
508
502
fail:
509
503
        return -1;
510
504
}
 
505
 
 
506
/*
 
507
 * Local Variables:
 
508
 * c-style: whitesmith
 
509
 * c-basic-offset: 8
 
510
 * End:
 
511
 */