Annotation of sys/netinet/ip_ipsp.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: ip_ipsp.c,v 1.168 2007/02/14 00:53:48 jsg Exp $ */
2: /*
3: * The authors of this code are John Ioannidis (ji@tla.org),
4: * Angelos D. Keromytis (kermit@csd.uch.gr),
5: * Niels Provos (provos@physnet.uni-hamburg.de) and
6: * Niklas Hallqvist (niklas@appli.se).
7: *
8: * The original version of this code was written by John Ioannidis
9: * for BSD/OS in Athens, Greece, in November 1995.
10: *
11: * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
12: * by Angelos D. Keromytis.
13: *
14: * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
15: * and Niels Provos.
16: *
17: * Additional features in 1999 by Angelos D. Keromytis and Niklas Hallqvist.
18: *
19: * Copyright (c) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
20: * Angelos D. Keromytis and Niels Provos.
21: * Copyright (c) 1999 Niklas Hallqvist.
22: * Copyright (c) 2001, Angelos D. Keromytis.
23: *
24: * Permission to use, copy, and modify this software with or without fee
25: * is hereby granted, provided that this entire notice is included in
26: * all copies of any software which is or includes a copy or
27: * modification of this software.
28: * You may use this code under the GNU public license if you so wish. Please
29: * contribute changes back to the authors under this freer than GPL license
30: * so that we may further the use of strong encryption without limitations to
31: * all.
32: *
33: * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
34: * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
35: * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
36: * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
37: * PURPOSE.
38: */
39:
40: #include "pf.h"
41:
42: #include <sys/param.h>
43: #include <sys/mbuf.h>
44: #include <sys/socket.h>
45: #include <sys/kernel.h>
46: #include <sys/sysctl.h>
47:
48: #include <net/if.h>
49: #include <net/route.h>
50:
51: #if NPF > 0
52: #include <net/pfvar.h>
53: #endif
54:
55: #ifdef INET
56: #include <netinet/in.h>
57: #include <netinet/in_systm.h>
58: #include <netinet/ip.h>
59: #include <netinet/in_pcb.h>
60: #endif /* INET */
61:
62: #ifdef INET6
63: #ifndef INET
64: #include <netinet/in.h>
65: #endif
66: #include <netinet6/in6_var.h>
67: #endif /* INET6 */
68:
69: #include <netinet/ip_ipsp.h>
70: #include <net/pfkeyv2.h>
71: #include <crypto/xform.h>
72: #include <dev/rndvar.h>
73:
74: #ifdef DDB
75: #include <ddb/db_output.h>
76: void tdb_hashstats(void);
77: #endif
78:
79: #ifdef ENCDEBUG
80: #define DPRINTF(x) if (encdebug) printf x
81: #else
82: #define DPRINTF(x)
83: #endif
84:
85: int ipsp_kern(int, char **, int);
86: u_int8_t get_sa_require(struct inpcb *);
87: void tdb_rehash(void);
88: void tdb_timeout(void *v);
89: void tdb_firstuse(void *v);
90: void tdb_soft_timeout(void *v);
91: void tdb_soft_firstuse(void *v);
92:
93: extern int ipsec_auth_default_level;
94: extern int ipsec_esp_trans_default_level;
95: extern int ipsec_esp_network_default_level;
96: extern int ipsec_ipcomp_default_level;
97:
98: extern int encdebug;
99: int ipsec_in_use = 0;
100: u_int64_t ipsec_last_added = 0;
101:
102: struct ipsec_policy_head ipsec_policy_head =
103: TAILQ_HEAD_INITIALIZER(ipsec_policy_head);
104: struct ipsec_acquire_head ipsec_acquire_head =
105: TAILQ_HEAD_INITIALIZER(ipsec_acquire_head);
106:
107: /*
108: * This is the proper place to define the various encapsulation transforms.
109: */
110:
111: struct xformsw xformsw[] = {
112: #ifdef IPSEC
113: { XF_IP4, 0, "IPv4 Simple Encapsulation",
114: ipe4_attach, ipe4_init, ipe4_zeroize,
115: (int (*)(struct mbuf *, struct tdb *, int, int))ipe4_input,
116: ipip_output, },
117: { XF_AH, XFT_AUTH, "IPsec AH",
118: ah_attach, ah_init, ah_zeroize,
119: ah_input, ah_output, },
120: { XF_ESP, XFT_CONF|XFT_AUTH, "IPsec ESP",
121: esp_attach, esp_init, esp_zeroize,
122: esp_input, esp_output, },
123: { XF_IPCOMP, XFT_COMP, "IPcomp",
124: ipcomp_attach, ipcomp_init, ipcomp_zeroize,
125: ipcomp_input, ipcomp_output, },
126: #endif /* IPSEC */
127: #ifdef TCP_SIGNATURE
128: { XF_TCPSIGNATURE, XFT_AUTH, "TCP MD5 Signature Option, RFC 2385",
129: tcp_signature_tdb_attach, tcp_signature_tdb_init,
130: tcp_signature_tdb_zeroize, tcp_signature_tdb_input,
131: tcp_signature_tdb_output, }
132: #endif /* TCP_SIGNATURE */
133: };
134:
135: struct xformsw *xformswNXFORMSW = &xformsw[sizeof(xformsw)/sizeof(xformsw[0])];
136:
137: unsigned char ipseczeroes[IPSEC_ZEROES_SIZE]; /* zeroes! */
138:
139: #define TDB_HASHSIZE_INIT 32
140:
141: static struct tdb **tdbh = NULL;
142: static struct tdb **tdbaddr = NULL;
143: static struct tdb **tdbsrc = NULL;
144: static u_int tdb_hashmask = TDB_HASHSIZE_INIT - 1;
145: static int tdb_count;
146:
147: /*
148: * Our hashing function needs to stir things with a non-zero random multiplier
149: * so we cannot be DoS-attacked via choosing of the data to hash.
150: */
151: int
152: tdb_hash(u_int32_t spi, union sockaddr_union *dst, u_int8_t proto)
153: {
154: static u_int32_t mult1 = 0, mult2 = 0;
155: u_int8_t *ptr = (u_int8_t *) dst;
156: int i, shift;
157: u_int64_t hash;
158: int val32 = 0;
159:
160: while (mult1 == 0)
161: mult1 = arc4random();
162: while (mult2 == 0)
163: mult2 = arc4random();
164:
165: hash = (spi ^ proto) * mult1;
166: for (i = 0; i < SA_LEN(&dst->sa); i++) {
167: val32 = (val32 << 8) | ptr[i];
168: if (i % 4 == 3) {
169: hash ^= val32 * mult2;
170: val32 = 0;
171: }
172: }
173:
174: if (i % 4 != 0)
175: hash ^= val32 * mult2;
176:
177: shift = ffs(tdb_hashmask + 1);
178: while ((hash & ~tdb_hashmask) != 0)
179: hash = (hash >> shift) ^ (hash & tdb_hashmask);
180:
181: return hash;
182: }
183:
184: /*
185: * Reserve an SPI; the SA is not valid yet though. We use 0 as
186: * an error return value.
187: */
188: u_int32_t
189: reserve_spi(u_int32_t sspi, u_int32_t tspi, union sockaddr_union *src,
190: union sockaddr_union *dst, u_int8_t sproto, int *errval)
191: {
192: struct tdb *tdbp;
193: u_int32_t spi;
194: int nums, s;
195:
196: /* Don't accept ranges only encompassing reserved SPIs. */
197: if (sproto != IPPROTO_IPCOMP &&
198: (tspi < sspi || tspi <= SPI_RESERVED_MAX)) {
199: (*errval) = EINVAL;
200: return 0;
201: }
202: if (sproto == IPPROTO_IPCOMP && (tspi < sspi ||
203: tspi <= CPI_RESERVED_MAX ||
204: tspi >= CPI_PRIVATE_MIN)) {
205: (*errval) = EINVAL;
206: return 0;
207: }
208:
209: /* Limit the range to not include reserved areas. */
210: if (sspi <= SPI_RESERVED_MAX)
211: sspi = SPI_RESERVED_MAX + 1;
212:
213: /* For IPCOMP the CPI is only 16 bits long, what a good idea.... */
214:
215: if (sproto == IPPROTO_IPCOMP) {
216: u_int32_t t;
217: if (sspi >= 0x10000)
218: sspi = 0xffff;
219: if (tspi >= 0x10000)
220: tspi = 0xffff;
221: if (sspi > tspi) {
222: t = sspi; sspi = tspi; tspi = t;
223: }
224: }
225:
226: if (sspi == tspi) /* Asking for a specific SPI. */
227: nums = 1;
228: else
229: nums = 100; /* Arbitrarily chosen */
230:
231: while (nums--) {
232: if (sspi == tspi) /* Specific SPI asked. */
233: spi = tspi;
234: else /* Range specified */
235: spi = sspi + (arc4random() % (tspi - sspi));
236:
237: /* Don't allocate reserved SPIs. */
238: if (spi >= SPI_RESERVED_MIN && spi <= SPI_RESERVED_MAX)
239: continue;
240: else
241: spi = htonl(spi);
242:
243: /* Check whether we're using this SPI already. */
244: s = spltdb();
245: tdbp = gettdb(spi, dst, sproto);
246: splx(s);
247:
248: if (tdbp != (struct tdb *) NULL)
249: continue;
250:
251: tdbp = tdb_alloc();
252:
253: tdbp->tdb_spi = spi;
254: bcopy(&dst->sa, &tdbp->tdb_dst.sa, SA_LEN(&dst->sa));
255: bcopy(&src->sa, &tdbp->tdb_src.sa, SA_LEN(&src->sa));
256: tdbp->tdb_sproto = sproto;
257: tdbp->tdb_flags |= TDBF_INVALID; /* Mark SA invalid for now. */
258: tdbp->tdb_satype = SADB_SATYPE_UNSPEC;
259: puttdb(tdbp);
260:
261: /* Setup a "silent" expiration (since TDBF_INVALID's set). */
262: if (ipsec_keep_invalid > 0) {
263: tdbp->tdb_flags |= TDBF_TIMER;
264: tdbp->tdb_exp_timeout = ipsec_keep_invalid;
265: timeout_add(&tdbp->tdb_timer_tmo,
266: hz * ipsec_keep_invalid);
267: }
268:
269: return spi;
270: }
271:
272: (*errval) = EEXIST;
273: return 0;
274: }
275:
276: /*
277: * An IPSP SAID is really the concatenation of the SPI found in the
278: * packet, the destination address of the packet and the IPsec protocol.
279: * When we receive an IPSP packet, we need to look up its tunnel descriptor
280: * block, based on the SPI in the packet and the destination address (which
281: * is really one of our addresses if we received the packet!
282: *
283: * Caller is responsible for setting at least spltdb().
284: */
285: struct tdb *
286: gettdb(u_int32_t spi, union sockaddr_union *dst, u_int8_t proto)
287: {
288: u_int32_t hashval;
289: struct tdb *tdbp;
290:
291: if (tdbh == NULL)
292: return (struct tdb *) NULL;
293:
294: hashval = tdb_hash(spi, dst, proto);
295:
296: for (tdbp = tdbh[hashval]; tdbp != NULL; tdbp = tdbp->tdb_hnext)
297: if ((tdbp->tdb_spi == spi) && (tdbp->tdb_sproto == proto) &&
298: !bcmp(&tdbp->tdb_dst, dst, SA_LEN(&dst->sa)))
299: break;
300:
301: return tdbp;
302: }
303:
304: /*
305: * Same as gettdb() but compare SRC as well, so we
306: * use the tdbsrc[] hash table. Setting spi to 0
307: * matches all SPIs.
308: */
309: struct tdb *
310: gettdbbysrcdst(u_int32_t spi, union sockaddr_union *src,
311: union sockaddr_union *dst, u_int8_t proto)
312: {
313: u_int32_t hashval;
314: struct tdb *tdbp;
315: union sockaddr_union su_null;
316:
317: if (tdbsrc == NULL)
318: return (struct tdb *) NULL;
319:
320: hashval = tdb_hash(0, src, proto);
321:
322: for (tdbp = tdbsrc[hashval]; tdbp != NULL; tdbp = tdbp->tdb_snext)
323: if (tdbp->tdb_sproto == proto &&
324: (spi == 0 || tdbp->tdb_spi == spi) &&
325: ((tdbp->tdb_flags & TDBF_INVALID) == 0) &&
326: (tdbp->tdb_dst.sa.sa_family == AF_UNSPEC ||
327: !bcmp(&tdbp->tdb_dst, dst, SA_LEN(&dst->sa))) &&
328: !bcmp(&tdbp->tdb_src, src, SA_LEN(&src->sa)))
329: break;
330:
331: if (tdbp != NULL)
332: return (tdbp);
333:
334: bzero(&su_null, sizeof(su_null));
335: su_null.sa.sa_len = sizeof(struct sockaddr);
336: hashval = tdb_hash(0, &su_null, proto);
337:
338: for (tdbp = tdbsrc[hashval]; tdbp != NULL; tdbp = tdbp->tdb_snext)
339: if (tdbp->tdb_sproto == proto &&
340: (spi == 0 || tdbp->tdb_spi == spi) &&
341: ((tdbp->tdb_flags & TDBF_INVALID) == 0) &&
342: (tdbp->tdb_dst.sa.sa_family == AF_UNSPEC ||
343: !bcmp(&tdbp->tdb_dst, dst, SA_LEN(&dst->sa))) &&
344: tdbp->tdb_src.sa.sa_family == AF_UNSPEC)
345: break;
346:
347: return (tdbp);
348: }
349:
350: /*
351: * Check that credentials and IDs match. Return true if so. The t*
352: * range of arguments contains information from TDBs; the p*
353: * range of arguments contains information from policies or
354: * already established TDBs.
355: */
356: int
357: ipsp_aux_match(struct tdb *tdb,
358: struct ipsec_ref *psrcid,
359: struct ipsec_ref *pdstid,
360: struct ipsec_ref *plcred,
361: struct ipsec_ref *prcred,
362: struct sockaddr_encap *pfilter,
363: struct sockaddr_encap *pfiltermask)
364: {
365: if (psrcid != NULL)
366: if (tdb->tdb_srcid == NULL ||
367: !ipsp_ref_match(tdb->tdb_srcid, psrcid))
368: return 0;
369:
370: if (pdstid != NULL)
371: if (tdb->tdb_dstid == NULL ||
372: !ipsp_ref_match(tdb->tdb_dstid, pdstid))
373: return 0;
374:
375: if (plcred != NULL)
376: if (tdb->tdb_local_cred == NULL ||
377: !ipsp_ref_match(tdb->tdb_local_cred, plcred))
378: return 0;
379:
380: if (prcred != NULL)
381: if (tdb->tdb_remote_cred == NULL ||
382: !ipsp_ref_match(tdb->tdb_remote_cred, prcred))
383: return 0;
384:
385: /* Check for filter matches. */
386: if (tdb->tdb_filter.sen_type) {
387: /*
388: * XXX We should really be doing a subnet-check (see
389: * whether the TDB-associated filter is a subset
390: * of the policy's. For now, an exact match will solve
391: * most problems (all this will do is make every
392: * policy get its own SAs).
393: */
394: if (bcmp(&tdb->tdb_filter, pfilter,
395: sizeof(struct sockaddr_encap)) ||
396: bcmp(&tdb->tdb_filtermask, pfiltermask,
397: sizeof(struct sockaddr_encap)))
398: return 0;
399: }
400:
401: return 1;
402: }
403:
404: /*
405: * Get an SA given the remote address, the security protocol type, and
406: * the desired IDs.
407: */
408: struct tdb *
409: gettdbbyaddr(union sockaddr_union *dst, u_int8_t sproto,
410: struct ipsec_ref *srcid, struct ipsec_ref *dstid,
411: struct ipsec_ref *local_cred, struct mbuf *m, int af,
412: struct sockaddr_encap *filter, struct sockaddr_encap *filtermask)
413: {
414: u_int32_t hashval;
415: struct tdb *tdbp;
416:
417: if (tdbaddr == NULL)
418: return (struct tdb *) NULL;
419:
420: hashval = tdb_hash(0, dst, sproto);
421:
422: for (tdbp = tdbaddr[hashval]; tdbp != NULL; tdbp = tdbp->tdb_anext)
423: if ((tdbp->tdb_sproto == sproto) &&
424: ((tdbp->tdb_flags & TDBF_INVALID) == 0) &&
425: (!bcmp(&tdbp->tdb_dst, dst, SA_LEN(&dst->sa)))) {
426: /* Do IDs and local credentials match ? */
427: if (!ipsp_aux_match(tdbp, srcid, dstid,
428: local_cred, NULL, filter, filtermask))
429: continue;
430: break;
431: }
432:
433: return tdbp;
434: }
435:
436: /*
437: * Get an SA given the source address, the security protocol type, and
438: * the desired IDs.
439: */
440: struct tdb *
441: gettdbbysrc(union sockaddr_union *src, u_int8_t sproto,
442: struct ipsec_ref *srcid, struct ipsec_ref *dstid,
443: struct mbuf *m, int af, struct sockaddr_encap *filter,
444: struct sockaddr_encap *filtermask)
445: {
446: u_int32_t hashval;
447: struct tdb *tdbp;
448:
449: if (tdbsrc == NULL)
450: return (struct tdb *) NULL;
451:
452: hashval = tdb_hash(0, src, sproto);
453:
454: for (tdbp = tdbsrc[hashval]; tdbp != NULL; tdbp = tdbp->tdb_snext)
455: if ((tdbp->tdb_sproto == sproto) &&
456: ((tdbp->tdb_flags & TDBF_INVALID) == 0) &&
457: (!bcmp(&tdbp->tdb_src, src, SA_LEN(&src->sa)))) {
458: /* Check whether IDs match */
459: if (!ipsp_aux_match(tdbp, dstid, srcid, NULL, NULL,
460: filter, filtermask))
461: continue;
462: break;
463: }
464:
465: return tdbp;
466: }
467:
468: #if DDB
469: void
470: tdb_hashstats(void)
471: {
472: int i, cnt, buckets[16];
473: struct tdb *tdbp;
474:
475: if (tdbh == NULL) {
476: db_printf("no tdb hash table\n");
477: return;
478: }
479:
480: bzero (buckets, sizeof(buckets));
481: for (i = 0; i <= tdb_hashmask; i++) {
482: cnt = 0;
483: for (tdbp = tdbh[i]; cnt < 16 && tdbp != NULL;
484: tdbp = tdbp->tdb_hnext)
485: cnt++;
486: buckets[cnt]++;
487: }
488:
489: db_printf("tdb cnt\t\tbucket cnt\n");
490: for (i = 0; i < 16; i++)
491: if (buckets[i] > 0)
492: db_printf("%d%c\t\t%d\n", i, i == 15 ? "+" : "",
493: buckets[i]);
494: }
495: #endif /* DDB */
496:
497: /*
498: * Caller is responsible for setting at least spltdb().
499: */
500: int
501: tdb_walk(int (*walker)(struct tdb *, void *, int), void *arg)
502: {
503: int i, rval = 0;
504: struct tdb *tdbp, *next;
505:
506: if (tdbh == NULL)
507: return ENOENT;
508:
509: for (i = 0; i <= tdb_hashmask; i++)
510: for (tdbp = tdbh[i]; rval == 0 && tdbp != NULL; tdbp = next) {
511: next = tdbp->tdb_hnext;
512: if (i == tdb_hashmask && next == NULL)
513: rval = walker(tdbp, (void *)arg, 1);
514: else
515: rval = walker(tdbp, (void *)arg, 0);
516: }
517:
518: return rval;
519: }
520:
521: /*
522: * Called at splsoftclock().
523: */
524: void
525: tdb_timeout(void *v)
526: {
527: struct tdb *tdb = v;
528:
529: if (!(tdb->tdb_flags & TDBF_TIMER))
530: return;
531:
532: /* If it's an "invalid" TDB do a silent expiration. */
533: if (!(tdb->tdb_flags & TDBF_INVALID))
534: pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD);
535: tdb_delete(tdb);
536: }
537:
538: void
539: tdb_firstuse(void *v)
540: {
541: struct tdb *tdb = v;
542:
543: if (!(tdb->tdb_flags & TDBF_SOFT_FIRSTUSE))
544: return;
545:
546: /* If the TDB hasn't been used, don't renew it. */
547: if (tdb->tdb_first_use != 0)
548: pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD);
549: tdb_delete(tdb);
550: }
551:
552: void
553: tdb_soft_timeout(void *v)
554: {
555: struct tdb *tdb = v;
556:
557: if (!(tdb->tdb_flags & TDBF_SOFT_TIMER))
558: return;
559:
560: /* Soft expirations. */
561: pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT);
562: tdb->tdb_flags &= ~TDBF_SOFT_TIMER;
563: }
564:
565: void
566: tdb_soft_firstuse(void *v)
567: {
568: struct tdb *tdb = v;
569:
570: if (!(tdb->tdb_flags & TDBF_SOFT_FIRSTUSE))
571: return;
572:
573: /* If the TDB hasn't been used, don't renew it. */
574: if (tdb->tdb_first_use != 0)
575: pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT);
576: tdb->tdb_flags &= ~TDBF_SOFT_FIRSTUSE;
577: }
578:
579: /*
580: * Caller is responsible for spltdb().
581: */
582: void
583: tdb_rehash(void)
584: {
585: struct tdb **new_tdbh, **new_tdbaddr, **new_srcaddr, *tdbp, *tdbnp;
586: u_int i, old_hashmask = tdb_hashmask;
587: u_int32_t hashval;
588:
589: tdb_hashmask = (tdb_hashmask << 1) | 1;
590:
591: MALLOC(new_tdbh, struct tdb **,
592: sizeof(struct tdb *) * (tdb_hashmask + 1), M_TDB, M_WAITOK);
593: MALLOC(new_tdbaddr, struct tdb **,
594: sizeof(struct tdb *) * (tdb_hashmask + 1), M_TDB, M_WAITOK);
595: MALLOC(new_srcaddr, struct tdb **,
596: sizeof(struct tdb *) * (tdb_hashmask + 1), M_TDB, M_WAITOK);
597:
598: bzero(new_tdbh, sizeof(struct tdb *) * (tdb_hashmask + 1));
599: bzero(new_tdbaddr, sizeof(struct tdb *) * (tdb_hashmask + 1));
600: bzero(new_srcaddr, sizeof(struct tdb *) * (tdb_hashmask + 1));
601:
602: for (i = 0; i <= old_hashmask; i++) {
603: for (tdbp = tdbh[i]; tdbp != NULL; tdbp = tdbnp) {
604: tdbnp = tdbp->tdb_hnext;
605: hashval = tdb_hash(tdbp->tdb_spi, &tdbp->tdb_dst,
606: tdbp->tdb_sproto);
607: tdbp->tdb_hnext = new_tdbh[hashval];
608: new_tdbh[hashval] = tdbp;
609: }
610:
611: for (tdbp = tdbaddr[i]; tdbp != NULL; tdbp = tdbnp) {
612: tdbnp = tdbp->tdb_anext;
613: hashval = tdb_hash(0, &tdbp->tdb_dst,
614: tdbp->tdb_sproto);
615: tdbp->tdb_anext = new_tdbaddr[hashval];
616: new_tdbaddr[hashval] = tdbp;
617: }
618:
619: for (tdbp = tdbsrc[i]; tdbp != NULL; tdbp = tdbnp) {
620: tdbnp = tdbp->tdb_snext;
621: hashval = tdb_hash(0, &tdbp->tdb_src,
622: tdbp->tdb_sproto);
623: tdbp->tdb_snext = new_srcaddr[hashval];
624: new_srcaddr[hashval] = tdbp;
625: }
626: }
627:
628: FREE(tdbh, M_TDB);
629: tdbh = new_tdbh;
630:
631: FREE(tdbaddr, M_TDB);
632: tdbaddr = new_tdbaddr;
633:
634: FREE(tdbsrc, M_TDB);
635: tdbsrc = new_srcaddr;
636: }
637:
638: /*
639: * Add TDB in the hash table.
640: */
641: void
642: puttdb(struct tdb *tdbp)
643: {
644: u_int32_t hashval;
645: int s = spltdb();
646:
647: if (tdbh == NULL) {
648: MALLOC(tdbh, struct tdb **,
649: sizeof(struct tdb *) * (tdb_hashmask + 1),
650: M_TDB, M_WAITOK);
651: MALLOC(tdbaddr, struct tdb **,
652: sizeof(struct tdb *) * (tdb_hashmask + 1),
653: M_TDB, M_WAITOK);
654: MALLOC(tdbsrc, struct tdb **,
655: sizeof(struct tdb *) * (tdb_hashmask + 1),
656: M_TDB, M_WAITOK);
657:
658: bzero(tdbh, sizeof(struct tdb *) * (tdb_hashmask + 1));
659: bzero(tdbaddr, sizeof(struct tdb *) * (tdb_hashmask + 1));
660: bzero(tdbsrc, sizeof(struct tdb *) * (tdb_hashmask + 1));
661: }
662:
663: hashval = tdb_hash(tdbp->tdb_spi, &tdbp->tdb_dst, tdbp->tdb_sproto);
664:
665: /*
666: * Rehash if this tdb would cause a bucket to have more than
667: * two items and if the number of tdbs exceed 10% of the
668: * bucket count. This number is arbitratily chosen and is
669: * just a measure to not keep rehashing when adding and
670: * removing tdbs which happens to always end up in the same
671: * bucket, which is not uncommon when doing manual keying.
672: */
673: if (tdbh[hashval] != NULL && tdbh[hashval]->tdb_hnext != NULL &&
674: tdb_count * 10 > tdb_hashmask + 1) {
675: tdb_rehash();
676: hashval = tdb_hash(tdbp->tdb_spi, &tdbp->tdb_dst,
677: tdbp->tdb_sproto);
678: }
679:
680: tdbp->tdb_hnext = tdbh[hashval];
681: tdbh[hashval] = tdbp;
682:
683: hashval = tdb_hash(0, &tdbp->tdb_dst, tdbp->tdb_sproto);
684: tdbp->tdb_anext = tdbaddr[hashval];
685: tdbaddr[hashval] = tdbp;
686:
687: hashval = tdb_hash(0, &tdbp->tdb_src, tdbp->tdb_sproto);
688: tdbp->tdb_snext = tdbsrc[hashval];
689: tdbsrc[hashval] = tdbp;
690:
691: tdb_count++;
692:
693: ipsec_last_added = time_second;
694:
695: splx(s);
696: }
697:
698: /*
699: * Caller is responsible to set at least spltdb().
700: */
701: void
702: tdb_delete(struct tdb *tdbp)
703: {
704: struct tdb *tdbpp;
705: u_int32_t hashval;
706: int s;
707:
708: if (tdbh == NULL)
709: return;
710:
711: hashval = tdb_hash(tdbp->tdb_spi, &tdbp->tdb_dst, tdbp->tdb_sproto);
712:
713: s = spltdb();
714: if (tdbh[hashval] == tdbp) {
715: tdbpp = tdbp;
716: tdbh[hashval] = tdbp->tdb_hnext;
717: } else {
718: for (tdbpp = tdbh[hashval]; tdbpp != NULL;
719: tdbpp = tdbpp->tdb_hnext) {
720: if (tdbpp->tdb_hnext == tdbp) {
721: tdbpp->tdb_hnext = tdbp->tdb_hnext;
722: tdbpp = tdbp;
723: break;
724: }
725: }
726: }
727:
728: tdbp->tdb_hnext = NULL;
729:
730: hashval = tdb_hash(0, &tdbp->tdb_dst, tdbp->tdb_sproto);
731:
732: if (tdbaddr[hashval] == tdbp) {
733: tdbpp = tdbp;
734: tdbaddr[hashval] = tdbp->tdb_anext;
735: } else {
736: for (tdbpp = tdbaddr[hashval]; tdbpp != NULL;
737: tdbpp = tdbpp->tdb_anext) {
738: if (tdbpp->tdb_anext == tdbp) {
739: tdbpp->tdb_anext = tdbp->tdb_anext;
740: tdbpp = tdbp;
741: break;
742: }
743: }
744: }
745:
746: hashval = tdb_hash(0, &tdbp->tdb_src, tdbp->tdb_sproto);
747:
748: if (tdbsrc[hashval] == tdbp) {
749: tdbpp = tdbp;
750: tdbsrc[hashval] = tdbp->tdb_snext;
751: }
752: else {
753: for (tdbpp = tdbsrc[hashval]; tdbpp != NULL;
754: tdbpp = tdbpp->tdb_snext) {
755: if (tdbpp->tdb_snext == tdbp) {
756: tdbpp->tdb_snext = tdbp->tdb_snext;
757: tdbpp = tdbp;
758: break;
759: }
760: }
761: }
762:
763: tdbp->tdb_snext = NULL;
764: tdb_free(tdbp);
765: tdb_count--;
766:
767: splx(s);
768: }
769:
770: /*
771: * Allocate a TDB and initialize a few basic fields.
772: */
773: struct tdb *
774: tdb_alloc(void)
775: {
776: struct tdb *tdbp;
777:
778: MALLOC(tdbp, struct tdb *, sizeof(struct tdb), M_TDB, M_WAITOK);
779: bzero((caddr_t) tdbp, sizeof(struct tdb));
780:
781: /* Init Incoming SA-Binding Queues. */
782: TAILQ_INIT(&tdbp->tdb_inp_out);
783: TAILQ_INIT(&tdbp->tdb_inp_in);
784:
785: TAILQ_INIT(&tdbp->tdb_policy_head);
786:
787: /* Record establishment time. */
788: tdbp->tdb_established = time_second;
789:
790: /* Initialize timeouts. */
791: timeout_set(&tdbp->tdb_timer_tmo, tdb_timeout, tdbp);
792: timeout_set(&tdbp->tdb_first_tmo, tdb_firstuse, tdbp);
793: timeout_set(&tdbp->tdb_stimer_tmo, tdb_soft_timeout, tdbp);
794: timeout_set(&tdbp->tdb_sfirst_tmo, tdb_soft_firstuse, tdbp);
795:
796: return tdbp;
797: }
798:
799: void
800: tdb_free(struct tdb *tdbp)
801: {
802: struct ipsec_policy *ipo;
803: struct inpcb *inp;
804:
805: if (tdbp->tdb_xform) {
806: (*(tdbp->tdb_xform->xf_zeroize))(tdbp);
807: tdbp->tdb_xform = NULL;
808: }
809:
810: /* Cleanup inp references. */
811: for (inp = TAILQ_FIRST(&tdbp->tdb_inp_in); inp;
812: inp = TAILQ_FIRST(&tdbp->tdb_inp_in)) {
813: TAILQ_REMOVE(&tdbp->tdb_inp_in, inp, inp_tdb_in_next);
814: inp->inp_tdb_in = NULL;
815: }
816:
817: for (inp = TAILQ_FIRST(&tdbp->tdb_inp_out); inp;
818: inp = TAILQ_FIRST(&tdbp->tdb_inp_out)) {
819: TAILQ_REMOVE(&tdbp->tdb_inp_out, inp, inp_tdb_out_next);
820: inp->inp_tdb_out = NULL;
821: }
822:
823: /* Cleanup SPD references. */
824: for (ipo = TAILQ_FIRST(&tdbp->tdb_policy_head); ipo;
825: ipo = TAILQ_FIRST(&tdbp->tdb_policy_head)) {
826: TAILQ_REMOVE(&tdbp->tdb_policy_head, ipo, ipo_tdb_next);
827: ipo->ipo_tdb = NULL;
828: ipo->ipo_last_searched = 0; /* Force a re-search. */
829: }
830:
831: /* Remove expiration timeouts. */
832: tdbp->tdb_flags &= ~(TDBF_FIRSTUSE | TDBF_SOFT_FIRSTUSE | TDBF_TIMER |
833: TDBF_SOFT_TIMER);
834: timeout_del(&tdbp->tdb_timer_tmo);
835: timeout_del(&tdbp->tdb_first_tmo);
836: timeout_del(&tdbp->tdb_stimer_tmo);
837: timeout_del(&tdbp->tdb_sfirst_tmo);
838:
839: if (tdbp->tdb_local_auth) {
840: ipsp_reffree(tdbp->tdb_local_auth);
841: tdbp->tdb_local_auth = NULL;
842: }
843:
844: if (tdbp->tdb_remote_auth) {
845: ipsp_reffree(tdbp->tdb_remote_auth);
846: tdbp->tdb_remote_auth = NULL;
847: }
848:
849: if (tdbp->tdb_srcid) {
850: ipsp_reffree(tdbp->tdb_srcid);
851: tdbp->tdb_srcid = NULL;
852: }
853:
854: if (tdbp->tdb_dstid) {
855: ipsp_reffree(tdbp->tdb_dstid);
856: tdbp->tdb_dstid = NULL;
857: }
858:
859: if (tdbp->tdb_local_cred) {
860: ipsp_reffree(tdbp->tdb_local_cred);
861: tdbp->tdb_local_cred = NULL;
862: }
863:
864: if (tdbp->tdb_remote_cred) {
865: ipsp_reffree(tdbp->tdb_remote_cred);
866: tdbp->tdb_remote_cred = NULL;
867: }
868:
869: #if NPF > 0
870: if (tdbp->tdb_tag) {
871: pf_tag_unref(tdbp->tdb_tag);
872: tdbp->tdb_tag = 0;
873: }
874: #endif
875:
876: if ((tdbp->tdb_onext) && (tdbp->tdb_onext->tdb_inext == tdbp))
877: tdbp->tdb_onext->tdb_inext = NULL;
878:
879: if ((tdbp->tdb_inext) && (tdbp->tdb_inext->tdb_onext == tdbp))
880: tdbp->tdb_inext->tdb_onext = NULL;
881:
882: FREE(tdbp, M_TDB);
883: }
884:
885: /*
886: * Do further initializations of a TDB.
887: */
888: int
889: tdb_init(struct tdb *tdbp, u_int16_t alg, struct ipsecinit *ii)
890: {
891: struct xformsw *xsp;
892: int err;
893:
894: for (xsp = xformsw; xsp < xformswNXFORMSW; xsp++) {
895: if (xsp->xf_type == alg) {
896: err = (*(xsp->xf_init))(tdbp, xsp, ii);
897: return err;
898: }
899: }
900:
901: DPRINTF(("tdb_init(): no alg %d for spi %08x, addr %s, proto %d\n",
902: alg, ntohl(tdbp->tdb_spi), ipsp_address(tdbp->tdb_dst),
903: tdbp->tdb_sproto));
904:
905: return EINVAL;
906: }
907:
908: /*
909: * Check which transformations are required.
910: */
911: u_int8_t
912: get_sa_require(struct inpcb *inp)
913: {
914: u_int8_t sareq = 0;
915:
916: if (inp != NULL) {
917: sareq |= inp->inp_seclevel[SL_AUTH] >= IPSEC_LEVEL_USE ?
918: NOTIFY_SATYPE_AUTH : 0;
919: sareq |= inp->inp_seclevel[SL_ESP_TRANS] >= IPSEC_LEVEL_USE ?
920: NOTIFY_SATYPE_CONF : 0;
921: sareq |= inp->inp_seclevel[SL_ESP_NETWORK] >= IPSEC_LEVEL_USE ?
922: NOTIFY_SATYPE_TUNNEL : 0;
923: } else {
924: sareq |= ipsec_auth_default_level >= IPSEC_LEVEL_USE ?
925: NOTIFY_SATYPE_AUTH : 0;
926: sareq |= ipsec_esp_trans_default_level >= IPSEC_LEVEL_USE ?
927: NOTIFY_SATYPE_CONF : 0;
928: sareq |= ipsec_esp_network_default_level >= IPSEC_LEVEL_USE ?
929: NOTIFY_SATYPE_TUNNEL : 0;
930: }
931:
932: return (sareq);
933: }
934:
935: /*
936: * Add an inpcb to the list of inpcb which reference this tdb directly.
937: */
938: void
939: tdb_add_inp(struct tdb *tdb, struct inpcb *inp, int inout)
940: {
941: if (inout) {
942: if (inp->inp_tdb_in) {
943: if (inp->inp_tdb_in == tdb)
944: return;
945:
946: TAILQ_REMOVE(&inp->inp_tdb_in->tdb_inp_in, inp,
947: inp_tdb_in_next);
948: }
949:
950: inp->inp_tdb_in = tdb;
951: TAILQ_INSERT_TAIL(&tdb->tdb_inp_in, inp, inp_tdb_in_next);
952: } else {
953: if (inp->inp_tdb_out) {
954: if (inp->inp_tdb_out == tdb)
955: return;
956:
957: TAILQ_REMOVE(&inp->inp_tdb_out->tdb_inp_out, inp,
958: inp_tdb_out_next);
959: }
960:
961: inp->inp_tdb_out = tdb;
962: TAILQ_INSERT_TAIL(&tdb->tdb_inp_out, inp, inp_tdb_out_next);
963: }
964: }
965:
966: /* Return a printable string for the IPv4 address. */
967: char *
968: inet_ntoa4(struct in_addr ina)
969: {
970: static char buf[4][4 * sizeof "123" + 4];
971: unsigned char *ucp = (unsigned char *) &ina;
972: static int i = 3;
973:
974: i = (i + 1) % 4;
975: snprintf(buf[i], sizeof buf[0], "%d.%d.%d.%d",
976: ucp[0] & 0xff, ucp[1] & 0xff,
977: ucp[2] & 0xff, ucp[3] & 0xff);
978: return (buf[i]);
979: }
980:
981: /* Return a printable string for the address. */
982: char *
983: ipsp_address(union sockaddr_union sa)
984: {
985: switch (sa.sa.sa_family) {
986: #if INET
987: case AF_INET:
988: return inet_ntoa4(sa.sin.sin_addr);
989: #endif /* INET */
990:
991: #if INET6
992: case AF_INET6:
993: return ip6_sprintf(&sa.sin6.sin6_addr);
994: #endif /* INET6 */
995:
996: default:
997: return "(unknown address family)";
998: }
999: }
1000:
1001: /* Check whether an IP{4,6} address is unspecified. */
1002: int
1003: ipsp_is_unspecified(union sockaddr_union addr)
1004: {
1005: switch (addr.sa.sa_family) {
1006: #ifdef INET
1007: case AF_INET:
1008: if (addr.sin.sin_addr.s_addr == INADDR_ANY)
1009: return 1;
1010: else
1011: return 0;
1012: #endif /* INET */
1013:
1014: #ifdef INET6
1015: case AF_INET6:
1016: if (IN6_IS_ADDR_UNSPECIFIED(&addr.sin6.sin6_addr))
1017: return 1;
1018: else
1019: return 0;
1020: #endif /* INET6 */
1021:
1022: case 0: /* No family set. */
1023: default:
1024: return 1;
1025: }
1026: }
1027:
1028: /* Free reference-counted structure. */
1029: void
1030: ipsp_reffree(struct ipsec_ref *ipr)
1031: {
1032: #ifdef DIAGNOSTIC
1033: if (ipr->ref_count <= 0)
1034: printf("ipsp_reffree: illegal reference count %d for "
1035: "object %p (len = %d, malloctype = %d)\n",
1036: ipr->ref_count, ipr, ipr->ref_len, ipr->ref_malloctype);
1037: #endif
1038: if (--ipr->ref_count <= 0)
1039: FREE(ipr, ipr->ref_malloctype);
1040: }
1041:
1042: /* Mark a TDB as TDBF_SKIPCRYPTO. */
1043: void
1044: ipsp_skipcrypto_mark(struct tdb_ident *tdbi)
1045: {
1046: struct tdb *tdb;
1047: int s = spltdb();
1048:
1049: tdb = gettdb(tdbi->spi, &tdbi->dst, tdbi->proto);
1050: if (tdb != NULL) {
1051: tdb->tdb_flags |= TDBF_SKIPCRYPTO;
1052: tdb->tdb_last_marked = time_second;
1053: }
1054: splx(s);
1055: }
1056:
1057: /* Unmark a TDB as TDBF_SKIPCRYPTO. */
1058: void
1059: ipsp_skipcrypto_unmark(struct tdb_ident *tdbi)
1060: {
1061: struct tdb *tdb;
1062: int s = spltdb();
1063:
1064: tdb = gettdb(tdbi->spi, &tdbi->dst, tdbi->proto);
1065: if (tdb != NULL) {
1066: tdb->tdb_flags &= ~TDBF_SKIPCRYPTO;
1067: tdb->tdb_last_marked = time_second;
1068: }
1069: splx(s);
1070: }
1071:
1072: /* Return true if the two structures match. */
1073: int
1074: ipsp_ref_match(struct ipsec_ref *ref1, struct ipsec_ref *ref2)
1075: {
1076: if (ref1->ref_type != ref2->ref_type ||
1077: ref1->ref_len != ref2->ref_len ||
1078: bcmp(ref1 + 1, ref2 + 1, ref1->ref_len))
1079: return 0;
1080:
1081: return 1;
1082: }
1083:
1084: #ifdef notyet
1085: /*
1086: * Go down a chain of IPv4/IPv6/ESP/AH/IPiP chains creating an tag for each
1087: * IPsec header encountered. The offset where the first header, as well
1088: * as its type are given to us.
1089: */
1090: struct m_tag *
1091: ipsp_parse_headers(struct mbuf *m, int off, u_int8_t proto)
1092: {
1093: int ipv4sa = 0, s, esphlen = 0, trail = 0, i;
1094: SLIST_HEAD(packet_tags, m_tag) tags;
1095: unsigned char lasteight[8];
1096: struct tdb_ident *tdbi;
1097: struct m_tag *mtag;
1098: struct tdb *tdb;
1099:
1100: #ifdef INET
1101: struct ip iph;
1102: #endif /* INET */
1103:
1104: #ifdef INET6
1105: struct in6_addr ip6_dst;
1106: #endif /* INET6 */
1107:
1108: /* We have to start with a known network protocol. */
1109: if (proto != IPPROTO_IPV4 && proto != IPPROTO_IPV6)
1110: return NULL;
1111:
1112: SLIST_INIT(&tags);
1113:
1114: while (1) {
1115: switch (proto) {
1116: #ifdef INET
1117: case IPPROTO_IPV4: /* Also IPPROTO_IPIP */
1118: {
1119: /*
1120: * Save the IP header (we need both the
1121: * address and ip_hl).
1122: */
1123: m_copydata(m, off, sizeof(struct ip), (caddr_t) &iph);
1124: ipv4sa = 1;
1125: proto = iph.ip_p;
1126: off += iph.ip_hl << 2;
1127: break;
1128: }
1129: #endif /* INET */
1130:
1131: #ifdef INET6
1132: case IPPROTO_IPV6:
1133: {
1134: int nxtp, l;
1135:
1136: /* Copy the IPv6 address. */
1137: m_copydata(m, off + offsetof(struct ip6_hdr, ip6_dst),
1138: sizeof(struct ip6_hdr), (caddr_t) &ip6_dst);
1139: ipv4sa = 0;
1140:
1141: /*
1142: * Go down the chain of headers until we encounter a
1143: * non-option.
1144: */
1145: for (l = ip6_nexthdr(m, off, proto, &nxtp); l != -1;
1146: l = ip6_nexthdr(m, off, proto, &nxtp)) {
1147: off += l;
1148: proto = nxtp;
1149:
1150: /* Construct a tag. */
1151: if (nxtp == IPPROTO_AH) {
1152: mtag = m_tag_get(PACKET_TAG_IPSEC_IN_CRYPTO_DONE,
1153: sizeof(struct tdb_ident),
1154: M_NOWAIT);
1155:
1156: if (mtag == NULL)
1157: return SLIST_FIRST(&tags);
1158:
1159: tdbi = (struct tdb_ident *) (mtag + 1);
1160: bzero(tdbi, sizeof(struct tdb_ident));
1161:
1162: m_copydata(m, off + sizeof(u_int32_t),
1163: sizeof(u_int32_t),
1164: (caddr_t) &tdbi->spi);
1165:
1166: tdbi->proto = IPPROTO_AH;
1167: tdbi->dst.sin6.sin6_family = AF_INET6;
1168: tdbi->dst.sin6.sin6_len =
1169: sizeof(struct sockaddr_in6);
1170: tdbi->dst.sin6.sin6_addr = ip6_dst;
1171: SLIST_INSERT_HEAD(&tags,
1172: mtag, m_tag_link);
1173: }
1174: else
1175: if (nxtp == IPPROTO_IPV6)
1176: m_copydata(m, off +
1177: offsetof(struct ip6_hdr,
1178: ip6_dst),
1179: sizeof(struct ip6_hdr),
1180: (caddr_t) &ip6_dst);
1181: }
1182: break;
1183: }
1184: #endif /* INET6 */
1185:
1186: case IPPROTO_ESP:
1187: /* Verify that this has been decrypted. */
1188: {
1189: union sockaddr_union su;
1190: u_int32_t spi;
1191:
1192: m_copydata(m, off, sizeof(u_int32_t), (caddr_t) &spi);
1193: bzero(&su, sizeof(union sockaddr_union));
1194:
1195: s = spltdb();
1196:
1197: #ifdef INET
1198: if (ipv4sa) {
1199: su.sin.sin_family = AF_INET;
1200: su.sin.sin_len = sizeof(struct sockaddr_in);
1201: su.sin.sin_addr = iph.ip_dst;
1202: }
1203: #endif /* INET */
1204:
1205: #ifdef INET6
1206: if (!ipv4sa) {
1207: su.sin6.sin6_family = AF_INET6;
1208: su.sin6.sin6_len = sizeof(struct sockaddr_in6);
1209: su.sin6.sin6_addr = ip6_dst;
1210: }
1211: #endif /* INET6 */
1212:
1213: tdb = gettdb(spi, &su, IPPROTO_ESP);
1214: if (tdb == NULL) {
1215: splx(s);
1216: return SLIST_FIRST(&tags);
1217: }
1218:
1219: /* How large is the ESP header ? We use this later. */
1220: if (tdb->tdb_flags & TDBF_NOREPLAY)
1221: esphlen = sizeof(u_int32_t) + tdb->tdb_ivlen;
1222: else
1223: esphlen = 2 * sizeof(u_int32_t) +
1224: tdb->tdb_ivlen;
1225:
1226: /*
1227: * Verify decryption. If the SA is using
1228: * random padding (as the "old" ESP SAs were
1229: * bound to do, there's nothing we can do to
1230: * see if the payload has been decrypted.
1231: */
1232: if (tdb->tdb_flags & TDBF_RANDOMPADDING) {
1233: splx(s);
1234: return SLIST_FIRST(&tags);
1235: }
1236:
1237: /* Update the length of trailing ESP authenticators. */
1238: if (tdb->tdb_authalgxform)
1239: trail += AH_HMAC_HASHLEN;
1240:
1241: splx(s);
1242:
1243: /* Copy the last 10 bytes. */
1244: m_copydata(m, m->m_pkthdr.len - trail - 8, 8,
1245: lasteight);
1246:
1247: /* Verify the self-describing padding values. */
1248: if (lasteight[6] != 0) {
1249: if (lasteight[6] != lasteight[5])
1250: return SLIST_FIRST(&tags);
1251:
1252: for (i = 4; lasteight[i + 1] != 1 && i >= 0;
1253: i--)
1254: if (lasteight[i + 1] !=
1255: lasteight[i] + 1)
1256: return SLIST_FIRST(&tags);
1257: }
1258: }
1259: /* FALLTHROUGH */
1260: case IPPROTO_AH:
1261: mtag = m_tag_get(PACKET_TAG_IPSEC_IN_CRYPTO_DONE,
1262: sizeof(struct tdb_ident), M_NOWAIT);
1263: if (mtag == NULL)
1264: return SLIST_FIRST(&tags);
1265:
1266: tdbi = (struct tdb_ident *) (mtag + 1);
1267: bzero(tdbi, sizeof(struct tdb_ident));
1268:
1269: /* Get SPI off the relevant header. */
1270: if (proto == IPPROTO_AH)
1271: m_copydata(m, off + sizeof(u_int32_t),
1272: sizeof(u_int32_t), (caddr_t) &tdbi->spi);
1273: else /* IPPROTO_ESP */
1274: m_copydata(m, off, sizeof(u_int32_t),
1275: (caddr_t) &tdbi->spi);
1276:
1277: tdbi->proto = proto; /* AH or ESP */
1278:
1279: #ifdef INET
1280: /* Last network header was IPv4. */
1281: if (ipv4sa) {
1282: tdbi->dst.sin.sin_family = AF_INET;
1283: tdbi->dst.sin.sin_len =
1284: sizeof(struct sockaddr_in);
1285: tdbi->dst.sin.sin_addr = iph.ip_dst;
1286: }
1287: #endif /* INET */
1288:
1289: #ifdef INET6
1290: /* Last network header was IPv6. */
1291: if (!ipv4sa) {
1292: tdbi->dst.sin6.sin6_family = AF_INET6;
1293: tdbi->dst.sin6.sin6_len =
1294: sizeof(struct sockaddr_in6);
1295: tdbi->dst.sin6.sin6_addr = ip6_dst;
1296: }
1297: #endif /* INET6 */
1298:
1299: SLIST_INSERT_HEAD(&tags, mtag, m_tag_link);
1300:
1301: /* Update next protocol/header and header offset. */
1302: if (proto == IPPROTO_AH) {
1303: u_int8_t foo[2];
1304:
1305: m_copydata(m, off, 2 * sizeof(u_int8_t), foo);
1306: proto = foo[0];
1307: off += (foo[1] + 2) << 2;
1308: } else {/* IPPROTO_ESP */
1309: /* Initialized in IPPROTO_ESP case. */
1310: off += esphlen;
1311: proto = lasteight[7];
1312: }
1313: break;
1314:
1315: default:
1316: return SLIST_FIRST(&tags); /* We're done. */
1317: }
1318: }
1319: }
1320: #endif /* notyet */
CVSweb