OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [net/] [bsd_tcpip/] [current/] [src/] [sys/] [netinet6/] [esp_output.c] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      src/sys/netinet6/esp_output.c
4
//
5
//==========================================================================
6
// ####BSDCOPYRIGHTBEGIN####                                    
7
// -------------------------------------------                  
8
// This file is part of eCos, the Embedded Configurable Operating System.
9
//
10
// Portions of this software may have been derived from FreeBSD 
11
// or other sources, and if so are covered by the appropriate copyright
12
// and license included herein.                                 
13
//
14
// Portions created by the Free Software Foundation are         
15
// Copyright (C) 2002 Free Software Foundation, Inc.            
16
// -------------------------------------------                  
17
// ####BSDCOPYRIGHTEND####                                      
18
//==========================================================================
19
 
20
/*      $KAME: esp_output.c,v 1.44 2001/07/26 06:53:15 jinmei Exp $     */
21
 
22
/*
23
 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
24
 * All rights reserved.
25
 *
26
 * Redistribution and use in source and binary forms, with or without
27
 * modification, are permitted provided that the following conditions
28
 * are met:
29
 * 1. Redistributions of source code must retain the above copyright
30
 *    notice, this list of conditions and the following disclaimer.
31
 * 2. Redistributions in binary form must reproduce the above copyright
32
 *    notice, this list of conditions and the following disclaimer in the
33
 *    documentation and/or other materials provided with the distribution.
34
 * 3. Neither the name of the project nor the names of its contributors
35
 *    may be used to endorse or promote products derived from this software
36
 *    without specific prior written permission.
37
 *
38
 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
39
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
42
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
43
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
44
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
45
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
46
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
47
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48
 * SUCH DAMAGE.
49
 */
50
 
51
/*
52
 * RFC1827/2406 Encapsulated Security Payload.
53
 */
54
 
55
#include <sys/param.h>
56
#if !(defined(__FreeBSD__) && __FreeBSD__ >= 4)
57
#include <sys/malloc.h>
58
#endif
59
#include <sys/mbuf.h>
60
#include <sys/domain.h>
61
#include <sys/protosw.h>
62
#include <sys/socket.h>
63
#include <sys/socketvar.h>
64
#include <sys/errno.h>
65
#include <sys/time.h>
66
 
67
#include <net/if.h>
68
#include <net/route.h>
69
 
70
#include <netinet/in.h>
71
#include <netinet/in_systm.h>
72
#include <netinet/ip.h>
73
#include <netinet/in_var.h>
74
 
75
#ifdef INET6
76
#include <netinet/ip6.h>
77
#include <netinet6/ip6_var.h>
78
#include <netinet/icmp6.h>
79
#endif
80
 
81
#include <netinet6/ipsec.h>
82
#include <netinet6/ah.h>
83
#include <netinet6/esp.h>
84
#include <netkey/key.h>
85
#include <netkey/keydb.h>
86
 
87
static int esp_output __P((struct mbuf *, u_char *, struct mbuf *,
88
        struct ipsecrequest *, int));
89
 
90
/*
91
 * compute ESP header size.
92
 */
93
size_t
94
esp_hdrsiz(isr)
95
        struct ipsecrequest *isr;
96
{
97
        struct secasvar *sav;
98
        const struct esp_algorithm *algo;
99
        const struct ah_algorithm *aalgo;
100
        size_t ivlen;
101
        size_t authlen;
102
        size_t hdrsiz;
103
 
104
        /* sanity check */
105
        if (isr == NULL)
106
                panic("esp_hdrsiz: NULL was passed.\n");
107
 
108
        sav = isr->sav;
109
 
110
        if (isr->saidx.proto != IPPROTO_ESP)
111
                panic("unsupported mode passed to esp_hdrsiz");
112
 
113
        if (sav == NULL)
114
                goto estimate;
115
        if (sav->state != SADB_SASTATE_MATURE
116
         && sav->state != SADB_SASTATE_DYING)
117
                goto estimate;
118
 
119
        /* we need transport mode ESP. */
120
        algo = esp_algorithm_lookup(sav->alg_enc);
121
        if (!algo)
122
                goto estimate;
123
        ivlen = sav->ivlen;
124
        if (ivlen < 0)
125
                goto estimate;
126
 
127
        /*
128
         * XXX
129
         * right now we don't calcurate the padding size.  simply
130
         * treat the padding size as constant, for simplicity.
131
         *
132
         * XXX variable size padding support
133
         */
134
        if (sav->flags & SADB_X_EXT_OLD) {
135
                /* RFC 1827 */
136
                hdrsiz = sizeof(struct esp) + ivlen + 9;
137
        } else {
138
                /* RFC 2406 */
139
                aalgo = ah_algorithm_lookup(sav->alg_auth);
140
                if (aalgo && sav->replay && sav->key_auth)
141
                        authlen = (aalgo->sumsiz)(sav);
142
                else
143
                        authlen = 0;
144
                hdrsiz = sizeof(struct newesp) + ivlen + 9 + authlen;
145
        }
146
 
147
        return hdrsiz;
148
 
149
   estimate:
150
        /*
151
         * ASSUMING:
152
         *      sizeof(struct newesp) > sizeof(struct esp).
153
         *      esp_max_ivlen() = max ivlen for CBC mode
154
         *      9 = (maximum padding length without random padding length)
155
         *         + (Pad Length field) + (Next Header field).
156
         *      16 = maximum ICV we support.
157
         */
158
        return sizeof(struct newesp) + esp_max_ivlen() + 9 + 16;
159
}
160
 
161
/*
162
 * Modify the packet so that the payload is encrypted.
163
 * The mbuf (m) must start with IPv4 or IPv6 header.
164
 * On failure, free the given mbuf and return NULL.
165
 *
166
 * on invocation:
167
 *      m   nexthdrp md
168
 *      v   v        v
169
 *      IP ......... payload
170
 * during the encryption:
171
 *      m   nexthdrp mprev md
172
 *      v   v        v     v
173
 *      IP ............... esp iv payload pad padlen nxthdr
174
 *                         <--><-><------><--------------->
175
 *                         esplen plen    extendsiz
176
 *                             ivlen
177
 *                         <-----> esphlen
178
 *      <-> hlen
179
 *      <-----------------> espoff
180
 */
181
static int
182
esp_output(m, nexthdrp, md, isr, af)
183
        struct mbuf *m;
184
        u_char *nexthdrp;
185
        struct mbuf *md;
186
        struct ipsecrequest *isr;
187
        int af;
188
{
189
        struct mbuf *n;
190
        struct mbuf *mprev;
191
        struct esp *esp;
192
        struct esptail *esptail;
193
        struct secasvar *sav = isr->sav;
194
        const struct esp_algorithm *algo;
195
        u_int32_t spi;
196
        u_int8_t nxt = 0;
197
        size_t plen;    /* payload length to be encrypted */
198
        size_t espoff;
199
        int ivlen;
200
        int afnumber;
201
        size_t extendsiz;
202
        int error = 0;
203
        struct ipsecstat *stat;
204
 
205
        switch (af) {
206
#ifdef INET
207
        case AF_INET:
208
                afnumber = 4;
209
                stat = &ipsecstat;
210
                break;
211
#endif
212
#ifdef INET6
213
        case AF_INET6:
214
                afnumber = 6;
215
                stat = &ipsec6stat;
216
                break;
217
#endif
218
        default:
219
                ipseclog((LOG_ERR, "esp_output: unsupported af %d\n", af));
220
                return 0;        /* no change at all */
221
        }
222
 
223
        /* some sanity check */
224
        if ((sav->flags & SADB_X_EXT_OLD) == 0 && !sav->replay) {
225
                switch (af) {
226
#ifdef INET
227
                case AF_INET:
228
                    {
229
                        struct ip *ip;
230
 
231
                        ip = mtod(m, struct ip *);
232
                        ipseclog((LOG_DEBUG, "esp4_output: internal error: "
233
                                "sav->replay is null: %x->%x, SPI=%u\n",
234
                                (u_int32_t)ntohl(ip->ip_src.s_addr),
235
                                (u_int32_t)ntohl(ip->ip_dst.s_addr),
236
                                (u_int32_t)ntohl(sav->spi)));
237
                        ipsecstat.out_inval++;
238
                        break;
239
                    }
240
#endif /* INET */
241
#ifdef INET6
242
                case AF_INET6:
243
                        ipseclog((LOG_DEBUG, "esp6_output: internal error: "
244
                                "sav->replay is null: SPI=%u\n",
245
                                (u_int32_t)ntohl(sav->spi)));
246
                        ipsec6stat.out_inval++;
247
                        break;
248
#endif /* INET6 */
249
                default:
250
                        panic("esp_output: should not reach here");
251
                }
252
                m_freem(m);
253
                return EINVAL;
254
        }
255
 
256
        algo = esp_algorithm_lookup(sav->alg_enc);
257
        if (!algo) {
258
                ipseclog((LOG_ERR, "esp_output: unsupported algorithm: "
259
                    "SPI=%u\n", (u_int32_t)ntohl(sav->spi)));
260
                m_freem(m);
261
                return EINVAL;
262
        }
263
        spi = sav->spi;
264
        ivlen = sav->ivlen;
265
        /* should be okey */
266
        if (ivlen < 0) {
267
                panic("invalid ivlen");
268
        }
269
 
270
    {
271
        /*
272
         * insert ESP header.
273
         * XXX inserts ESP header right after IPv4 header.  should
274
         * chase the header chain.
275
         * XXX sequential number
276
         */
277
#ifdef INET
278
        struct ip *ip = NULL;
279
#endif
280
#ifdef INET6
281
        struct ip6_hdr *ip6 = NULL;
282
#endif
283
        size_t esplen;  /* sizeof(struct esp/newesp) */
284
        size_t esphlen; /* sizeof(struct esp/newesp) + ivlen */
285
        size_t hlen = 0; /* ip header len */
286
 
287
        if (sav->flags & SADB_X_EXT_OLD) {
288
                /* RFC 1827 */
289
                esplen = sizeof(struct esp);
290
        } else {
291
                /* RFC 2406 */
292
                if (sav->flags & SADB_X_EXT_DERIV)
293
                        esplen = sizeof(struct esp);
294
                else
295
                        esplen = sizeof(struct newesp);
296
        }
297
        esphlen = esplen + ivlen;
298
 
299
        for (mprev = m; mprev && mprev->m_next != md; mprev = mprev->m_next)
300
                ;
301
        if (mprev == NULL || mprev->m_next != md) {
302
                ipseclog((LOG_DEBUG, "esp%d_output: md is not in chain\n",
303
                    afnumber));
304
                m_freem(m);
305
                return EINVAL;
306
        }
307
 
308
        plen = 0;
309
        for (n = md; n; n = n->m_next)
310
                plen += n->m_len;
311
 
312
        switch (af) {
313
#ifdef INET
314
        case AF_INET:
315
                ip = mtod(m, struct ip *);
316
#ifdef _IP_VHL
317
                hlen = IP_VHL_HL(ip->ip_vhl) << 2;
318
#else
319
                hlen = ip->ip_hl << 2;
320
#endif
321
                break;
322
#endif
323
#ifdef INET6
324
        case AF_INET6:
325
                ip6 = mtod(m, struct ip6_hdr *);
326
                hlen = sizeof(*ip6);
327
                break;
328
#endif
329
        }
330
 
331
        /* make the packet over-writable */
332
        mprev->m_next = NULL;
333
        if ((md = ipsec_copypkt(md)) == NULL) {
334
                m_freem(m);
335
                error = ENOBUFS;
336
                goto fail;
337
        }
338
        mprev->m_next = md;
339
 
340
        espoff = m->m_pkthdr.len - plen;
341
 
342
        /*
343
         * grow the mbuf to accomodate ESP header.
344
         * before: IP ... payload
345
         * after:  IP ... ESP IV payload
346
         */
347
        if (M_LEADINGSPACE(md) < esphlen || (md->m_flags & M_EXT) != 0) {
348
                MGET(n, M_DONTWAIT, MT_DATA);
349
                if (!n) {
350
                        m_freem(m);
351
                        error = ENOBUFS;
352
                        goto fail;
353
                }
354
                n->m_len = esphlen;
355
                mprev->m_next = n;
356
                n->m_next = md;
357
                m->m_pkthdr.len += esphlen;
358
                esp = mtod(n, struct esp *);
359
        } else {
360
                md->m_len += esphlen;
361
                md->m_data -= esphlen;
362
                m->m_pkthdr.len += esphlen;
363
                esp = mtod(md, struct esp *);
364
        }
365
 
366
        nxt = *nexthdrp;
367
        *nexthdrp = IPPROTO_ESP;
368
        switch (af) {
369
#ifdef INET
370
        case AF_INET:
371
                if (esphlen < (IP_MAXPACKET - ntohs(ip->ip_len)))
372
                        ip->ip_len = htons(ntohs(ip->ip_len) + esphlen);
373
                else {
374
                        ipseclog((LOG_ERR,
375
                            "IPv4 ESP output: size exceeds limit\n"));
376
                        ipsecstat.out_inval++;
377
                        m_freem(m);
378
                        error = EMSGSIZE;
379
                        goto fail;
380
                }
381
                break;
382
#endif
383
#ifdef INET6
384
        case AF_INET6:
385
                /* total packet length will be computed in ip6_output() */
386
                break;
387
#endif
388
        }
389
    }
390
 
391
        /* initialize esp header. */
392
        esp->esp_spi = spi;
393
        if ((sav->flags & SADB_X_EXT_OLD) == 0) {
394
                struct newesp *nesp;
395
                nesp = (struct newesp *)esp;
396
                if (sav->replay->count == ~0) {
397
                        if ((sav->flags & SADB_X_EXT_CYCSEQ) == 0) {
398
                                /* XXX Is it noisy ? */
399
                                ipseclog((LOG_WARNING,
400
                                    "replay counter overflowed. %s\n",
401
                                    ipsec_logsastr(sav)));
402
                                stat->out_inval++;
403
                                m_freem(m);
404
                                return EINVAL;
405
                        }
406
                }
407
                sav->replay->count++;
408
                /*
409
                 * XXX sequence number must not be cycled, if the SA is
410
                 * installed by IKE daemon.
411
                 */
412
                nesp->esp_seq = htonl(sav->replay->count);
413
        }
414
 
415
    {
416
        /*
417
         * find the last mbuf. make some room for ESP trailer.
418
         */
419
#ifdef INET
420
        struct ip *ip = NULL;
421
#endif
422
        size_t padbound;
423
        u_char *extend;
424
        int i;
425
        int randpadmax;
426
 
427
        if (algo->padbound)
428
                padbound = algo->padbound;
429
        else
430
                padbound = 4;
431
        /* ESP packet, including nxthdr field, must be length of 4n */
432
        if (padbound < 4)
433
                padbound = 4;
434
 
435
        extendsiz = padbound - (plen % padbound);
436
        if (extendsiz == 1)
437
                extendsiz = padbound + 1;
438
 
439
        /* random padding */
440
        switch (af) {
441
#ifdef INET
442
        case AF_INET:
443
                randpadmax = ip4_esp_randpad;
444
                break;
445
#endif
446
#ifdef INET6
447
        case AF_INET6:
448
                randpadmax = ip6_esp_randpad;
449
                break;
450
#endif
451
        default:
452
                randpadmax = -1;
453
                break;
454
        }
455
        if (randpadmax < 0 || plen + extendsiz >= randpadmax)
456
                ;
457
        else {
458
                int n;
459
 
460
                /* round */
461
                randpadmax = (randpadmax / padbound) * padbound;
462
                n = (randpadmax - plen + extendsiz) / padbound;
463
 
464
                if (n > 0)
465
                        n = (random() % n) * padbound;
466
                else
467
                        n = 0;
468
 
469
                /*
470
                 * make sure we do not pad too much.
471
                 * MLEN limitation comes from the trailer attachment
472
                 * code below.
473
                 * 256 limitation comes from sequential padding.
474
                 * also, the 1-octet length field in ESP trailer imposes
475
                 * limitation (but is less strict than sequential padding
476
                 * as length field do not count the last 2 octets).
477
                 */
478
                if (extendsiz + n <= MLEN && extendsiz + n < 256)
479
                        extendsiz += n;
480
        }
481
 
482
#ifdef DIAGNOSTIC
483
        if (extendsiz > MLEN || extendsiz >= 256)
484
                panic("extendsiz too big in esp_output");
485
#endif
486
 
487
        n = m;
488
        while (n->m_next)
489
                n = n->m_next;
490
 
491
        /*
492
         * if M_EXT, the external mbuf data may be shared among
493
         * two consequtive TCP packets, and it may be unsafe to use the
494
         * trailing space.
495
         */
496
        if (!(n->m_flags & M_EXT) && extendsiz < M_TRAILINGSPACE(n)) {
497
                extend = mtod(n, u_char *) + n->m_len;
498
                n->m_len += extendsiz;
499
                m->m_pkthdr.len += extendsiz;
500
        } else {
501
                struct mbuf *nn;
502
 
503
                MGET(nn, M_DONTWAIT, MT_DATA);
504
                if (!nn) {
505
                        ipseclog((LOG_DEBUG, "esp%d_output: can't alloc mbuf",
506
                            afnumber));
507
                        m_freem(m);
508
                        error = ENOBUFS;
509
                        goto fail;
510
                }
511
                extend = mtod(nn, u_char *);
512
                nn->m_len = extendsiz;
513
                nn->m_next = NULL;
514
                n->m_next = nn;
515
                n = nn;
516
                m->m_pkthdr.len += extendsiz;
517
        }
518
        switch (sav->flags & SADB_X_EXT_PMASK) {
519
        case SADB_X_EXT_PRAND:
520
                key_randomfill(extend, extendsiz);
521
                break;
522
        case SADB_X_EXT_PZERO:
523
                bzero(extend, extendsiz);
524
                break;
525
        case SADB_X_EXT_PSEQ:
526
                for (i = 0; i < extendsiz; i++)
527
                        extend[i] = (i + 1) & 0xff;
528
                break;
529
        }
530
 
531
        /* initialize esp trailer. */
532
        esptail = (struct esptail *)
533
                (mtod(n, u_int8_t *) + n->m_len - sizeof(struct esptail));
534
        esptail->esp_nxt = nxt;
535
        esptail->esp_padlen = extendsiz - 2;
536
 
537
        /* modify IP header (for ESP header part only) */
538
        switch (af) {
539
#ifdef INET
540
        case AF_INET:
541
                ip = mtod(m, struct ip *);
542
                if (extendsiz < (IP_MAXPACKET - ntohs(ip->ip_len)))
543
                        ip->ip_len = htons(ntohs(ip->ip_len) + extendsiz);
544
                else {
545
                        ipseclog((LOG_ERR,
546
                            "IPv4 ESP output: size exceeds limit\n"));
547
                        ipsecstat.out_inval++;
548
                        m_freem(m);
549
                        error = EMSGSIZE;
550
                        goto fail;
551
                }
552
                break;
553
#endif
554
#ifdef INET6
555
        case AF_INET6:
556
                /* total packet length will be computed in ip6_output() */
557
                break;
558
#endif
559
        }
560
    }
561
 
562
        /*
563
         * pre-compute and cache intermediate key
564
         */
565
        error = esp_schedule(algo, sav);
566
        if (error) {
567
                m_freem(m);
568
                stat->out_inval++;
569
                goto fail;
570
        }
571
 
572
        /*
573
         * encrypt the packet, based on security association
574
         * and the algorithm specified.
575
         */
576
        if (!algo->encrypt)
577
                panic("internal error: no encrypt function");
578
        if ((*algo->encrypt)(m, espoff, plen + extendsiz, sav, algo, ivlen)) {
579
                /* m is already freed */
580
                ipseclog((LOG_ERR, "packet encryption failure\n"));
581
                stat->out_inval++;
582
                error = EINVAL;
583
                goto fail;
584
        }
585
 
586
        /*
587
         * calculate ICV if required.
588
         */
589
        if (!sav->replay)
590
                goto noantireplay;
591
        if (!sav->key_auth)
592
                goto noantireplay;
593
        if (sav->key_auth == SADB_AALG_NONE)
594
                goto noantireplay;
595
 
596
    {
597
        const struct ah_algorithm *aalgo;
598
        u_char authbuf[AH_MAXSUMSIZE];
599
        struct mbuf *n;
600
        u_char *p;
601
        size_t siz;
602
#ifdef INET
603
        struct ip *ip;
604
#endif
605
 
606
        aalgo = ah_algorithm_lookup(sav->alg_auth);
607
        if (!aalgo)
608
                goto noantireplay;
609
        siz = ((aalgo->sumsiz)(sav) + 3) & ~(4 - 1);
610
        if (AH_MAXSUMSIZE < siz)
611
                panic("assertion failed for AH_MAXSUMSIZE");
612
 
613
        if (esp_auth(m, espoff, m->m_pkthdr.len - espoff, sav, authbuf)) {
614
                ipseclog((LOG_ERR, "ESP checksum generation failure\n"));
615
                m_freem(m);
616
                error = EINVAL;
617
                stat->out_inval++;
618
                goto fail;
619
        }
620
 
621
        n = m;
622
        while (n->m_next)
623
                n = n->m_next;
624
 
625
        if (!(n->m_flags & M_EXT) && siz < M_TRAILINGSPACE(n)) { /* XXX */
626
                n->m_len += siz;
627
                m->m_pkthdr.len += siz;
628
                p = mtod(n, u_char *) + n->m_len - siz;
629
        } else {
630
                struct mbuf *nn;
631
 
632
                MGET(nn, M_DONTWAIT, MT_DATA);
633
                if (!nn) {
634
                        ipseclog((LOG_DEBUG, "can't alloc mbuf in esp%d_output",
635
                            afnumber));
636
                        m_freem(m);
637
                        error = ENOBUFS;
638
                        goto fail;
639
                }
640
                nn->m_len = siz;
641
                nn->m_next = NULL;
642
                n->m_next = nn;
643
                n = nn;
644
                m->m_pkthdr.len += siz;
645
                p = mtod(nn, u_char *);
646
        }
647
        bcopy(authbuf, p, siz);
648
 
649
        /* modify IP header (for ESP header part only) */
650
        switch (af) {
651
#ifdef INET
652
        case AF_INET:
653
                ip = mtod(m, struct ip *);
654
                if (siz < (IP_MAXPACKET - ntohs(ip->ip_len)))
655
                        ip->ip_len = htons(ntohs(ip->ip_len) + siz);
656
                else {
657
                        ipseclog((LOG_ERR,
658
                            "IPv4 ESP output: size exceeds limit\n"));
659
                        ipsecstat.out_inval++;
660
                        m_freem(m);
661
                        error = EMSGSIZE;
662
                        goto fail;
663
                }
664
                break;
665
#endif
666
#ifdef INET6
667
        case AF_INET6:
668
                /* total packet length will be computed in ip6_output() */
669
                break;
670
#endif
671
        }
672
    }
673
 
674
noantireplay:
675
        if (!m) {
676
                ipseclog((LOG_ERR,
677
                    "NULL mbuf after encryption in esp%d_output", afnumber));
678
        } else
679
                stat->out_success++;
680
        stat->out_esphist[sav->alg_enc]++;
681
        key_sa_recordxfer(sav, m);
682
        return 0;
683
 
684
fail:
685
#if 1
686
        return error;
687
#else
688
        panic("something bad in esp_output");
689
#endif
690
}
691
 
692
#ifdef INET
693
int
694
esp4_output(m, isr)
695
        struct mbuf *m;
696
        struct ipsecrequest *isr;
697
{
698
        struct ip *ip;
699
        if (m->m_len < sizeof(struct ip)) {
700
                ipseclog((LOG_DEBUG, "esp4_output: first mbuf too short\n"));
701
                m_freem(m);
702
                return 0;
703
        }
704
        ip = mtod(m, struct ip *);
705
        /* XXX assumes that m->m_next points to payload */
706
        return esp_output(m, &ip->ip_p, m->m_next, isr, AF_INET);
707
}
708
#endif /* INET */
709
 
710
#ifdef INET6
711
int
712
esp6_output(m, nexthdrp, md, isr)
713
        struct mbuf *m;
714
        u_char *nexthdrp;
715
        struct mbuf *md;
716
        struct ipsecrequest *isr;
717
{
718
        if (m->m_len < sizeof(struct ip6_hdr)) {
719
                ipseclog((LOG_DEBUG, "esp6_output: first mbuf too short\n"));
720
                m_freem(m);
721
                return 0;
722
        }
723
        return esp_output(m, nexthdrp, md, isr, AF_INET6);
724
}
725
#endif /* INET6 */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.