OSDN Git Service

2013.10.24
[uclinux-h8/uClinux-dist.git] / freeswan / pluto / packet.h
1 /* parsing packets: formats and tools
2  * Copyright (C) 1997 Angelos D. Keromytis.
3  * Copyright (C) 1998-2001  D. Hugh Redelmeier.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License as published by the
7  * Free Software Foundation; either version 2 of the License, or (at your
8  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13  * for more details.
14  *
15  * RCSID $Id: packet.h,v 1.18 2002/01/21 03:14:20 dhr Exp $
16  */
17
18 /* a struct_desc describes a structure for the struct I/O routines.
19  * This requires arrays of field_desc values to describe struct fields.
20  */
21
22 typedef const struct struct_desc {
23     const char *name;
24     const struct field_desc *fields;
25     size_t size;
26 } struct_desc;
27
28 /* Note: if an ft_af_enum field has the ISAKMP_ATTR_AF_TV bit set,
29  * the subsequent ft_lv field will be interpreted as an immediate value.
30  * This matches how attributes are encoded.
31  * See draft-ietf-ipsec-isakmp-09.txt 3.3
32  */
33
34 enum field_type {
35     ft_mbz,     /* must be zero */
36     ft_nat,     /* natural number (may be 0) */
37     ft_len,     /* length of this struct and any following crud */
38     ft_lv,      /* length/value field of attribute */
39     ft_enum,    /* value from an enumeration */
40     ft_loose_enum,      /* value from an enumeration with only some names known */
41     ft_af_enum, /* Attribute Format + value from an enumeration */
42     ft_set,     /* bits representing set */
43     ft_raw,     /* bytes to be left in network-order */
44     ft_end,     /* end of field list */
45 };
46
47 typedef const struct field_desc {
48     enum field_type field_type;
49     int size;   /* size, in bytes, of field */
50     const char *name;
51     const void *desc;   /* enum_names for enum or char *[] for bits */
52 } field_desc;
53
54 /* The formatting of input and output of packets is done
55  * through packet_byte_stream objects.
56  * These describe a stream of bytes in memory.
57  * Several routines are provided to manipulate these objects
58  * Actual packet transfer is done elsewhere.
59  */
60 typedef struct packet_byte_stream {
61     struct packet_byte_stream *container;   /* PBS of which we are part */
62     struct_desc *desc;
63     const char *name;   /* what does this PBS represent? */
64     u_int8_t
65         *start,
66         *cur,   /* current position in stream */
67         *roof;  /* byte after last in PBS (actually just a limit on output) */
68     /* For an output PBS, the length field will be filled in later so
69      * we need to record its particulars.  Note: it may not be aligned.
70      */
71     u_int8_t *lenfld;
72     field_desc *lenfld_desc;
73 } pb_stream;
74
75 /* For an input PBS, pbs_offset is amount of stream processed.
76  * For an output PBS, pbs_offset is current size of stream.
77  * For an input PBS, pbs_room is size of stream.
78  * For an output PBS, pbs_room is maximum size allowed.
79  */
80 #define pbs_offset(pbs) ((size_t)((pbs)->cur - (pbs)->start))
81 #define pbs_room(pbs) ((size_t)((pbs)->roof - (pbs)->start))
82 #define pbs_left(pbs) ((size_t)((pbs)->roof - (pbs)->cur))
83
84 extern void init_pbs(pb_stream *pbs, u_int8_t *start, size_t len, const char *name);
85
86 extern bool in_struct(void *struct_ptr, struct_desc *sd,
87     pb_stream *ins, pb_stream *obj_pbs);
88 extern bool in_raw(void *bytes, size_t len, pb_stream *ins, const char *name);
89
90 extern bool out_struct(const void *struct_ptr, struct_desc *sd,
91     pb_stream *outs, pb_stream *obj_pbs);
92 extern bool out_generic(u_int8_t np, struct_desc *sd,
93     pb_stream *outs, pb_stream *obj_pbs);
94 extern bool out_generic_raw(u_int8_t np, struct_desc *sd,
95     pb_stream *outs, const void *bytes, size_t len, const char *name);
96 #if 1
97 extern bool out_modify_previous_np(u_int8_t np, pb_stream *outs);
98 #endif
99 #define out_generic_chunk(np, sd, outs, ch, name) \
100         out_generic_raw(np, sd, outs, (ch).ptr, (ch).len, name)
101 extern bool out_zero(size_t len, pb_stream *outs, const char *name);
102 extern bool out_raw(const void *bytes, size_t len, pb_stream *outs, const char *name);
103 #define out_chunk(ch, outs, name) out_raw((ch).ptr, (ch).len, (outs), (name))
104 extern void close_output_pbs(pb_stream *pbs);
105
106 #ifdef DEBUG
107 extern void DBG_print_struct(const char *label, const void *struct_ptr,
108     struct_desc *sd, bool len_meaningful);
109 #endif
110
111 /* ISAKMP Header: for all messages
112  * layout from draft-ietf-ipsec-isakmp-09.txt section 3.1
113  *                      1                   2                   3
114  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
115  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
116  * !                          Initiator                            !
117  * !                            Cookie                             !
118  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
119  * !                          Responder                            !
120  * !                            Cookie                             !
121  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
122  * !  Next Payload ! MjVer ! MnVer ! Exchange Type !     Flags     !
123  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
124  * !                          Message ID                           !
125  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
126  * !                            Length                             !
127  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
128  * Although the drafts are a little unclear, there are a few
129  * places that specify that messages should be padded with 0x00
130  * octets (bytes) to make the length a multiple of something.
131  *
132  * RFC 2408 "ISAKMP" 3.6 specifies that all messages will be
133  * padded to be a multiple of 4 octets in length.
134  * ??? This looks vestigial, and we ignore this requirement.
135  *
136  * RFC 2409 "IKE" Appedix B specifies:
137  *     Each message should be padded up to the nearest block size
138  *     using bytes containing 0x00.
139  * ??? This does not appear to be limited to encrypted messages,
140  * but it surely must be: the block size is meant to be the encryption
141  * block size, and that is meaningless for a non-encrypted message.
142  *
143  * RFC 2409 "IKE" 5.3 specifies:
144  *     Encrypted payloads are padded up to the nearest block size.
145  *     All padding bytes, except for the last one, contain 0x00. The
146  *     last byte of the padding contains the number of the padding
147  *     bytes used, excluding the last one. Note that this means there
148  *     will always be padding.
149  * ??? This is nuts since payloads are not padded, messages are.
150  * It also contradicts Appendix B.  So we ignore it.
151  *
152  * Summary: we pad encrypted output messages with 0x00 to bring them
153  * up to a multiple of the encryption block size.  On input, we require
154  * that any encrypted portion of a message be a multiple of the encryption
155  * block size.   After any decryption, we ignore padding (any bytes after
156  * the first payload that specifies a next payload of none; we don't
157  * require them to be zero).
158  */
159
160 struct isakmp_hdr
161 {
162     u_int8_t    isa_icookie[COOKIE_SIZE];
163     u_int8_t    isa_rcookie[COOKIE_SIZE];
164     u_int8_t    isa_np;                 /* Next payload */
165     u_int8_t    isa_version;    /* high-order 4 bits: Major; low order 4: Minor */
166 #define ISA_MAJ_SHIFT   4
167 #define ISA_MIN_MASK    (~((~0u) << ISA_MAJ_SHIFT))
168     u_int8_t    isa_xchg;               /* Exchange type */
169     u_int8_t    isa_flags;
170     u_int32_t   isa_msgid;              /* Message ID (RAW) */
171     u_int32_t   isa_length;             /* Length of message */
172 };
173
174 extern struct_desc isakmp_hdr_desc;
175
176 /* Generic portion of all ISAKMP payloads.
177  * layout from draft-ietf-ipsec-isakmp-09.txt section 3.2
178  * This describes the first 32-bit chunk of all payloads.
179  * The previous next payload depends on the actual payload type.
180  *                      1                   2                   3
181  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
182  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
183  * ! Next Payload  !   RESERVED    !         Payload Length        !
184  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
185  */
186 struct isakmp_generic
187 {
188     u_int8_t    isag_np;
189     u_int8_t    isag_reserved;
190     u_int16_t   isag_length;
191 };
192
193 extern struct_desc isakmp_generic_desc;
194
195 /* ISAKMP Data Attribute (generic representation within payloads)
196  * layout from draft-ietf-ipsec-isakmp-09.txt section 3.3
197  * This is not a payload type.
198  * In TLV format, this is followed by a value field.
199  *                      1                   2                   3
200  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
201  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
202  * !A!       Attribute Type        !    AF=0  Attribute Length     !
203  * !F!                             !    AF=1  Attribute Value      !
204  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
205  * .                   AF=0  Attribute Value                       .
206  * .                   AF=1  Not Transmitted                       .
207  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
208  */
209 struct isakmp_attribute
210 {
211     /* The high order bit of isaat_af_type is the Attribute Format
212      * If it is off, the format is TLV: lv is the length of the following
213      * attribute value.
214      * If it is on, the format is TV: lv is the value of the attribute.
215      * ISAKMP_ATTR_AF_MASK is the mask in host form.
216      *
217      * The low order 15 bits of isaat_af_type is the Attribute Type.
218      * ISAKMP_ATTR_RTYPE_MASK is the mask in host form.
219      */
220     u_int16_t isaat_af_type;   /* high order bit: AF; lower 15: rtype */
221     u_int16_t isaat_lv;                 /* Length or value */
222 };
223
224 #define ISAKMP_ATTR_AF_MASK 0x8000
225 #define ISAKMP_ATTR_AF_TV ISAKMP_ATTR_AF_MASK /* value in lv */
226 #define ISAKMP_ATTR_AF_TLV 0 /* length in lv; value follows */
227
228 #define ISAKMP_ATTR_RTYPE_MASK 0x7FFF
229
230 extern struct_desc
231     isakmp_oakley_attribute_desc,
232     isakmp_ipsec_attribute_desc;
233
234 /* ISAKMP Security Association Payload
235  * layout from draft-ietf-ipsec-isakmp-09.txt section 3.4
236  * A variable length Situation follows.
237  * Previous next payload: ISAKMP_NEXT_SA
238  *                      1                   2                   3
239  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
240  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
241  * ! Next Payload  !   RESERVED    !         Payload Length        !
242  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
243  * !              Domain of Interpretation  (DOI)                  !
244  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
245  * !                                                               !
246  * ~                           Situation                           ~
247  * !                                                               !
248  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
249  */
250 struct isakmp_sa
251 {
252     u_int8_t  isasa_np;                 /* Next payload */
253     u_int8_t  isasa_reserved;
254     u_int16_t isasa_length;             /* Payload length */
255     u_int32_t isasa_doi;                /* DOI */
256 };
257
258 extern struct_desc isakmp_sa_desc;
259
260 extern struct_desc ipsec_sit_desc;
261
262 /* ISAKMP Proposal Payload
263  * layout from draft-ietf-ipsec-isakmp-09.txt section 3.5
264  * A variable length SPI follows.
265  * Previous next payload: ISAKMP_NEXT_P
266  *                      1                   2                   3
267  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
268  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
269  * ! Next Payload  !   RESERVED    !         Payload Length        !
270  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
271  * !  Proposal #   !  Protocol-Id  !    SPI Size   !# of Transforms!
272  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
273  * !                        SPI (variable)                         !
274  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
275  */
276 struct isakmp_proposal
277 {
278     u_int8_t    isap_np;
279     u_int8_t    isap_reserved;
280     u_int16_t   isap_length;
281     u_int8_t    isap_proposal;
282     u_int8_t    isap_protoid;
283     u_int8_t    isap_spisize;
284     u_int8_t    isap_notrans;           /* Number of transforms */
285 };
286
287 extern struct_desc isakmp_proposal_desc;
288
289 /* ISAKMP Transform Payload
290  * layout from draft-ietf-ipsec-isakmp-09.txt section 3.6
291  * Variable length SA Attributes follow.
292  * Previous next payload: ISAKMP_NEXT_T
293  *                      1                   2                   3
294  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
295  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
296  * ! Next Payload  !   RESERVED    !         Payload Length        !
297  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
298  * !  Transform #  !  Transform-Id !           RESERVED2           !
299  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
300  * !                                                               !
301  * ~                        SA Attributes                          ~
302  * !                                                               !
303  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
304  */
305 struct isakmp_transform
306 {
307     u_int8_t    isat_np;
308     u_int8_t    isat_reserved;
309     u_int16_t   isat_length;
310     u_int8_t    isat_transnum;          /* Number of the transform */
311     u_int8_t    isat_transid;
312     u_int16_t   isat_reserved2;
313 };
314
315 extern struct_desc
316     isakmp_isakmp_transform_desc,
317     isakmp_ah_transform_desc,
318     isakmp_esp_transform_desc,
319     isakmp_ipcomp_transform_desc;
320
321 /* ISAKMP Key Exchange Payload: no fixed fields beyond the generic ones.
322  * layout from draft-ietf-ipsec-isakmp-09.txt section 3.7
323  * Variable Key Exchange Data follow the generic fields.
324  * Previous next payload: ISAKMP_NEXT_KE
325  *                      1                   2                   3
326  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
327  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
328  * ! Next Payload  !   RESERVED    !         Payload Length        !
329  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
330  * !                                                               !
331  * ~                       Key Exchange Data                       ~
332  * !                                                               !
333  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
334  */
335 extern struct_desc isakmp_keyex_desc;
336
337 /* ISAKMP Identification Payload
338  * layout from draft-ietf-ipsec-isakmp-09.txt section 3.8
339  * See "struct identity" declared later.
340  * Variable length Identification Data follow.
341  * Previous next payload: ISAKMP_NEXT_ID
342  *                      1                   2                   3
343  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
344  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
345  * ! Next Payload  !   RESERVED    !         Payload Length        !
346  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
347  * !   ID Type     !             DOI Specific ID Data              !
348  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
349  * !                                                               !
350  * ~                   Identification Data                         ~
351  * !                                                               !
352  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
353  */
354 struct isakmp_id
355 {
356     u_int8_t    isaid_np;
357     u_int8_t    isaid_reserved;
358     u_int16_t   isaid_length;
359     u_int8_t    isaid_idtype;
360     u_int8_t    isaid_doi_specific_a;
361     u_int16_t   isaid_doi_specific_b;
362 };
363
364 extern struct_desc isakmp_identification_desc;
365
366 /* IPSEC Identification Payload Content
367  * layout from draft-ietf-ipsec-ipsec-doi-08.txt section 4.6.2
368  * See struct isakmp_id declared earlier.
369  * Note: Hashing skips the ISAKMP generic payload header
370  * Variable length Identification Data follow.
371  *                      1                   2                   3
372  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
373  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
374  * !  Next Payload !   RESERVED    !        Payload Length         !
375  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
376  * !   ID Type     !  Protocol ID  !             Port              !
377  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
378  * ~                     Identification Data                       ~
379  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
380  */
381 struct isakmp_ipsec_id
382 {
383     u_int8_t    isaiid_np;
384     u_int8_t    isaiid_reserved;
385     u_int16_t   isaiid_length;
386     u_int8_t    isaiid_idtype;
387     u_int8_t    isaiid_protoid;
388     u_int16_t   isaiid_port;
389 };
390
391 extern struct_desc isakmp_ipsec_identification_desc;
392
393 /* ISAKMP Certificate Payload: no fixed fields beyond the generic ones.
394  * layout from draft-ietf-ipsec-isakmp-09.txt section 3.9
395  * Variable length Certificate Data follow the generic fields.
396  * Previous next payload: ISAKMP_NEXT_CERT.
397  *                      1                   2                   3
398  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
399  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
400  * ! Next Payload  !   RESERVED    !         Payload Length        !
401  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
402  * ! Cert Encoding !                                               !
403  * +-+-+-+-+-+-+-+-+                                               !
404  * ~                       Certificate Data                        ~
405  * !                                                               !
406  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
407  */
408 struct isakmp_cert
409 {
410     u_int8_t    isacert_np;
411     u_int8_t    isacert_reserved;
412     u_int16_t   isacert_length;
413     u_int8_t    isacert_type;
414 };
415
416 #define ISAKMP_CERT_SIZE        5
417
418 extern struct_desc isakmp_ipsec_certificate_desc;
419
420 /* ISAKMP Certificate Request Payload: no fixed fields beyond the generic ones.
421  * layout from draft-ietf-ipsec-isakmp-09.txt section 3.10
422  * Variable length Certificate Types and Certificate Authorities follow.
423  * Previous next payload: ISAKMP_NEXT_CR.
424  *                      1                   2                   3
425  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
426  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
427  * ! Next Payload  !   RESERVED    !         Payload Length        !
428  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
429  * !  Cert. Type   !                                               !
430  * +-+-+-+-+-+-+-+-+                                               !
431  * ~                    Certificate Authority                      ~
432  * !                                                               !
433  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
434  */
435 struct isakmp_cr
436 {
437     u_int8_t    isacr_np;
438     u_int8_t    isacr_reserved;
439     u_int16_t   isacr_length;
440     u_int8_t    isacr_type;
441 };
442
443 #define ISAKMP_CR_SIZE          5
444
445 extern struct_desc isakmp_ipsec_cert_req_desc;
446
447 /* ISAKMP Hash Payload: no fixed fields beyond the generic ones.
448  * layout from draft-ietf-ipsec-isakmp-09.txt section 3.11
449  * Variable length Hash Data follow.
450  * Previous next payload: ISAKMP_NEXT_HASH.
451  *                      1                   2                   3
452  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
453  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
454  * ! Next Payload  !   RESERVED    !         Payload Length        !
455  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
456  * !                                                               !
457  * ~                           Hash Data                           ~
458  * !                                                               !
459  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
460  */
461 extern struct_desc isakmp_hash_desc;
462
463 /* ISAKMP Signature Payload: no fixed fields beyond the generic ones.
464  * layout from draft-ietf-ipsec-isakmp-09.txt section 3.12
465  * Variable length Signature Data follow.
466  * Previous next payload: ISAKMP_NEXT_SIG.
467  *                      1                   2                   3
468  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
469  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
470  * ! Next Payload  !   RESERVED    !         Payload Length        !
471  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
472  * !                                                               !
473  * ~                         Signature Data                        ~
474  * !                                                               !
475  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
476  */
477 extern struct_desc isakmp_signature_desc;
478
479 /* ISAKMP Nonce Payload: no fixed fields beyond the generic ones.
480  * layout from draft-ietf-ipsec-isakmp-09.txt section 3.13
481  * Variable length Nonce Data follow.
482  * Previous next payload: ISAKMP_NEXT_NONCE.
483  *                      1                   2                   3
484  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
485  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
486  * ! Next Payload  !   RESERVED    !         Payload Length        !
487  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
488  * !                                                               !
489  * ~                            Nonce Data                         ~
490  * !                                                               !
491  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
492  */
493 extern struct_desc isakmp_nonce_desc;
494
495 /* ISAKMP Notification Payload
496  * layout from draft-ietf-ipsec-isakmp-09.txt section 3.14
497  * This is followed by a variable length SPI
498  * and then possibly by variable length Notification Data.
499  * Previous next payload: ISAKMP_NEXT_N
500  *                      1                   2                   3
501  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
502  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
503  * ! Next Payload  !   RESERVED    !         Payload Length        !
504  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
505  * !              Domain of Interpretation  (DOI)                  !
506  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
507  * !  Protocol-ID  !   SPI Size    !      Notify Message Type      !
508  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
509  * !                                                               !
510  * ~                Security Parameter Index (SPI)                 ~
511  * !                                                               !
512  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
513  * !                                                               !
514  * ~                       Notification Data                       ~
515  * !                                                               !
516  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
517  */
518 struct isakmp_notification
519 {
520     u_int8_t    isan_np;
521     u_int8_t    isan_reserved;
522     u_int16_t   isan_length;
523     u_int32_t   isan_doi;
524     u_int8_t    isan_protoid;
525     u_int8_t    isan_spisize;
526     u_int16_t   isan_type;
527 };
528
529 extern struct_desc isakmp_notification_desc;
530
531 /* ISAKMP Delete Payload
532  * layout from draft-ietf-ipsec-isakmp-09.txt section 3.15
533  * This is followed by a variable length SPI.
534  * Previous next payload: ISAKMP_NEXT_D
535  *                      1                   2                   3
536  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
537  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
538  * ! Next Payload  !   RESERVED    !         Payload Length        !
539  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
540  * !              Domain of Interpretation  (DOI)                  !
541  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
542  * !  Protocol-Id  !   SPI Size    !           # of SPIs           !
543  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
544  * !                                                               !
545  * ~               Security Parameter Index(es) (SPI)              ~
546  * !                                                               !
547  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
548  */
549 struct isakmp_delete
550 {
551     u_int8_t    isad_np;
552     u_int8_t    isad_reserved;
553     u_int16_t   isad_length;
554     u_int32_t   isad_doi;
555     u_int8_t    isad_protoid;
556     u_int8_t    isad_spisize;
557     u_int16_t   isad_nospi;
558 };
559
560 extern struct_desc isakmp_delete_desc;
561
562 /* ISAKMP Vendor ID Payload
563  * layout from draft-ietf-ipsec-isakmp-09.txt section 3.15
564  * This is followed by a variable length VID.
565  * Previous next payload: ISAKMP_NEXT_VID
566  *                      1                   2                   3
567  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
568  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
569  * ! Next Payload  !   RESERVED    !         Payload Length        !
570  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
571  * !                                                               !
572  * ~                        Vendor ID (VID)                        ~
573  * !                                                               !
574  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
575  */
576 extern struct_desc isakmp_vendor_id_desc;
577
578 #ifdef NAT_TRAVERSAL
579 struct isakmp_nat_oa
580 {
581     u_int8_t    isanoa_np;
582     u_int8_t    isanoa_reserved_1;
583     u_int16_t   isanoa_length;
584     u_int8_t    isanoa_idtype;
585     u_int8_t    isanoa_reserved_2;
586     u_int16_t   isanoa_reserved_3;
587 };
588
589 extern struct_desc isakmp_nat_d;
590 extern struct_desc isakmp_nat_oa;
591 #endif
592
593 /* union of all payloads */
594
595 union payload {
596     struct isakmp_generic generic;
597     struct isakmp_sa sa;
598     struct isakmp_proposal proposal;
599     struct isakmp_transform transform;
600     struct isakmp_id id;    /* Main Mode */
601     struct isakmp_cert cert;
602     struct isakmp_cr cr;
603     struct isakmp_ipsec_id ipsec_id;    /* Quick Mode */
604     struct isakmp_notification notification;
605     struct isakmp_delete delete;
606 #ifdef NAT_TRAVERSAL
607     struct isakmp_nat_oa nat_oa;
608 #endif
609 };
610
611 /* descriptor for each payload type
612  *
613  * There is a slight problem in that some payloads differ, depending
614  * on the mode.  Since this is table only used for top-level payloads,
615  * Proposal and Transform payloads need not be handled.
616  * That leaves only Identification payloads as a problem.
617  * We make all these entries NULL
618  */
619 extern struct_desc *const payload_descs[ISAKMP_NEXT_ROOF];