root/usr/src/uts/common/netinet/sctp.h
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef _NETINET_SCTP_H
#define _NETINET_SCTP_H

#ifdef __cplusplus
extern "C" {
#endif

#include <sys/types.h>

/*
 * This file contains the structure defintions and function prototypes
 * described in the IETF SCTP socket API document.
 */

/* SCTP association ID type. */
typedef int     sctp_assoc_t;
typedef int32_t sctp_assoc32_t;

/*
 * SCTP socket options
 */
#define SCTP_RTOINFO                    1
#define SCTP_ASSOCINFO                  2
#define SCTP_INITMSG                    3
#define SCTP_NODELAY                    4
#define SCTP_AUTOCLOSE                  5
#define SCTP_SET_PEER_PRIMARY_ADDR      6
#define SCTP_PRIMARY_ADDR               7
#define SCTP_ADAPTATION_LAYER           8
#define SCTP_DISABLE_FRAGMENTS          9
#define SCTP_PEER_ADDR_PARAMS           10
#define SCTP_DEFAULT_SEND_PARAM         11
#define SCTP_EVENTS                     12
#define SCTP_I_WANT_MAPPED_V4_ADDR      13
#define SCTP_MAXSEG                     14
#define SCTP_STATUS                     15
#define SCTP_GET_PEER_ADDR_INFO         16

/*
 * Private socket options
 */
#define SCTP_GET_NLADDRS                17
#define SCTP_GET_LADDRS                 18
#define SCTP_GET_NPADDRS                19
#define SCTP_GET_PADDRS                 20
#define SCTP_ADD_ADDR                   21
#define SCTP_REM_ADDR                   22

/*
 * Additional SCTP socket options. This socket option is used to enable or
 * disable PR-SCTP support prior to establishing an association. By default,
 * PR-SCTP support is disabled.
 */
#define SCTP_PRSCTP                     23

/*
 * SCTP socket option used to read per endpoint association statistics.
 */
#define SCTP_GET_ASSOC_STATS            24

/*
 * Ancillary data identifiers
 */
#define SCTP_SNDRCV             0x100
#define SCTP_INIT               0x101

/*
 * Notification types
 */
#define SCTP_ASSOC_CHANGE               1
#define SCTP_PEER_ADDR_CHANGE           2
#define SCTP_REMOTE_ERROR               3
#define SCTP_SEND_FAILED                4
#define SCTP_SHUTDOWN_EVENT             5
#define SCTP_ADAPTATION_INDICATION      6
#define SCTP_PARTIAL_DELIVERY_EVENT     7

/*
 * SCTP Ancillary Data Definitions
 */

/*
 * sctp_initmsg structure provides information for initializing new SCTP
 * associations with sendmsg().  The SCTP_INITMSG socket option uses
 * this same data structure.
 */
struct sctp_initmsg {
        uint16_t        sinit_num_ostreams;
        uint16_t        sinit_max_instreams;
        uint16_t        sinit_max_attempts;
        uint16_t        sinit_max_init_timeo;
};

/*
 * sctp_sndrcvinfo structure specifies SCTP options for sendmsg() and
 * describes SCTP header information about a received message through
 * recvmsg().
 */
struct sctp_sndrcvinfo {
        uint16_t        sinfo_stream;
        uint16_t        sinfo_ssn;
        uint16_t        sinfo_flags;
        uint32_t        sinfo_ppid;
        uint32_t        sinfo_context;
        uint32_t        sinfo_timetolive;
        uint32_t        sinfo_tsn;
        uint32_t        sinfo_cumtsn;
        sctp_assoc_t    sinfo_assoc_id;
};

/* sinfo_flags */
#define MSG_UNORDERED   0x01            /* Unordered data */
#define MSG_ABORT       0x02            /* Abort the connection */
#define MSG_EOF         0x04            /* Shutdown the connection */

/*
 * Use destination addr passed as parameter, not the association primary one.
 */
#define MSG_ADDR_OVER   0x08
/*
 * This flag when set in sinfo_flags is used alongwith sinfo_timetolive to
 * implement the "timed reliability" service discussed in RFC 3758.
 */
#define MSG_PR_SCTP     0x10
/*
 * SCTP notification definitions
 */

/*
 * To receive any ancillary data or notifications, the application can
 * register it's interest by calling the SCTP_EVENTS setsockopt() with
 * the sctp_event_subscribe structure.
 */
struct sctp_event_subscribe {
        uint8_t sctp_data_io_event;
        uint8_t sctp_association_event;
        uint8_t sctp_address_event;
        uint8_t sctp_send_failure_event;
        uint8_t sctp_peer_error_event;
        uint8_t sctp_shutdown_event;
        uint8_t sctp_partial_delivery_event;
        uint8_t sctp_adaptation_layer_event;
};

/* Association events used in sctp_assoc_change structure */
#define SCTP_COMM_UP            0
#define SCTP_COMM_LOST          1
#define SCTP_RESTART            2
#define SCTP_SHUTDOWN_COMP      3
#define SCTP_CANT_STR_ASSOC     4

/*
 * Association flags. This flags is filled in the sac_flags for a SCTP_COMM_UP
 * event if the association supports PR-SCTP.
 */
#define SCTP_PRSCTP_CAPABLE     0x01

/*
 * sctp_assoc_change notification informs the socket that an SCTP association
 * has either begun or ended.  The identifier for a new association is
 * provided by this notification.
 */
struct sctp_assoc_change {
        uint16_t        sac_type;
        uint16_t        sac_flags;
        uint32_t        sac_length;
        uint16_t        sac_state;
        uint16_t        sac_error;
        uint16_t        sac_outbound_streams;
        uint16_t        sac_inbound_streams;
        sctp_assoc_t    sac_assoc_id;
        /*
         * The assoc ID can be followed by the ABORT chunk if available.
         */
};

/*
 * A remote peer may send an Operational Error message to its peer. This
 * message indicates a variety of error conditions on an association.
 * The entire ERROR chunk as it appears on the wire is included in a
 * SCTP_REMOTE_ERROR event.  Refer to the SCTP specification RFC2960
 * and any extensions for a list of possible error formats.
 */
struct sctp_remote_error {
        uint16_t        sre_type;
        uint16_t        sre_flags;
        uint32_t        sre_length;
        uint16_t        sre_error;
        sctp_assoc_t    sre_assoc_id;
        /*
         * The assoc ID is followed by the actual error chunk.
         */
};

/*
 * Note:
 *
 * In order to keep the offsets and size of the structure having a
 * struct sockaddr_storage field the same between a 32-bit application
 * and a 64-bit amd64 kernel, we use a #pragma pack(4) for those
 * structures.
 */
#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
#pragma pack(4)
#endif

/* Address change event state */
#define SCTP_ADDR_AVAILABLE     0
#define SCTP_ADDR_UNREACHABLE   1
#define SCTP_ADDR_REMOVED       2
#define SCTP_ADDR_ADDED         3
#define SCTP_ADDR_MADE_PRIM     4

/*
 * When a destination address on a multi-homed peer encounters a change,
 * an interface details event, sctp_paddr_change, is sent to the socket.
 */
struct sctp_paddr_change {
        uint16_t        spc_type;
        uint16_t        spc_flags;
        uint32_t        spc_length;
        struct sockaddr_storage spc_aaddr;
        int             spc_state;
        int             spc_error;
        sctp_assoc_t    spc_assoc_id;
};

#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
#pragma pack()
#endif

/* flags used in sctp_send_failed notification. */
#define SCTP_DATA_UNSENT        1
#define SCTP_DATA_SENT          2

/*
 * If SCTP cannot deliver a message it may return the message as a
 * notification using the following structure.
 */
struct sctp_send_failed {
        uint16_t        ssf_type;
        uint16_t        ssf_flags;
        uint32_t        ssf_length;
        uint32_t        ssf_error;
        struct sctp_sndrcvinfo ssf_info;
        sctp_assoc_t    ssf_assoc_id;
        /*
         * The assoc ID is followed by the failed message.
         */
};

/*
 * When a peer sends a SHUTDOWN, SCTP delivers the sctp_shutdown_event
 * notification to inform the socket user that it should cease sending data.
 */
struct sctp_shutdown_event {
        uint16_t        sse_type;
        uint16_t        sse_flags;
        uint16_t        sse_length;
        sctp_assoc_t    sse_assoc_id;
};

/*
 * When a peer sends an Adaptation Layer Indication parameter, SCTP
 * delivers the sctp_adaptation_event notification to inform the socket
 * user the peer's requested adaptation layer.
 */
struct sctp_adaptation_event {
        uint16_t        sai_type;
        uint16_t        sai_flags;
        uint32_t        sai_length;
        uint32_t        sai_adaptation_ind;
        sctp_assoc_t    sai_assoc_id;
};

/* Possible values in pdapi_indication for sctp_pdapi_event notification. */
#define SCTP_PARTIAL_DELIVERY_ABORTED   1

/*
 * When a receiver is engaged in a partial delivery of a message the
 * sctp_pdapi_event notification is used to indicate various events.
 */
struct sctp_pdapi_event {
        uint16_t        pdapi_type;
        uint16_t        pdapi_flags;
        uint32_t        pdapi_length;
        uint32_t        pdapi_indication;
        sctp_assoc_t    pdapi_assoc_id;
};

/*
 * The sctp_notification structure is defined as the union of all
 * notification types defined above.
 */
union sctp_notification {
        struct {
                uint16_t                sn_type; /* Notification type. */
                uint16_t                sn_flags;
                uint32_t                sn_length;
        } sn_header;
        struct sctp_assoc_change        sn_assoc_change;
        struct sctp_paddr_change        sn_paddr_change;
        struct sctp_remote_error        sn_remote_error;
        struct sctp_send_failed         sn_send_failed;
        struct sctp_shutdown_event      sn_shutdown_event;
        struct sctp_adaptation_event    sn_adaptation_event;
        struct sctp_pdapi_event         sn_pdapi_event;
};

/*
 * sctp_opt_info() option definitions
 */

/*
 * The protocol parameters used to initialize and bound retransmission
 * timeout (RTO) are tunable.  See RFC2960 for more information on
 * how these parameters are used in RTO calculation.
 *
 * The sctp_rtoinfo structure is used to access and modify these
 * parameters.
 */
struct sctp_rtoinfo {
        sctp_assoc_t    srto_assoc_id;
        uint32_t        srto_initial;
        uint32_t        srto_max;
        uint32_t        srto_min;
};

/*
 * The sctp_assocparams option is used to both examine and set various
 * association and endpoint parameters.  See RFC2960 for more information
 * on how this parameter is used.  The peer address parameter is ignored
 * for one-to-one style socket.
 */
struct sctp_assocparams {
        sctp_assoc_t    sasoc_assoc_id;
        uint16_t        sasoc_asocmaxrxt;
        uint16_t        sasoc_number_peer_destinations;
        uint32_t        sasoc_peer_rwnd;
        uint32_t        sasoc_local_rwnd;
        uint32_t        sasoc_cookie_life;
};

#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
#pragma pack(4)
#endif

/* sctp_paddrinfo reachability state. */
#define SCTP_INACTIVE   1
#define SCTP_ACTIVE     2

/*
 * Applications can retrieve information about a specific peer address
 * of an association, including its reachability state, congestion
 * window, and retransmission timer values.  This information is
 * read-only. The sctp_paddrinfo structure is used to access this
 * information:
 */
struct sctp_paddrinfo {
        sctp_assoc_t    spinfo_assoc_id;
        struct sockaddr_storage spinfo_address;
        int32_t         spinfo_state;
        uint32_t        spinfo_cwnd;
        uint32_t        spinfo_srtt;
        uint32_t        spinfo_rto;
        uint32_t        spinfo_mtu;
};

/*
 * Applications can enable or disable heartbeats for any peer address of
 * an association, modify an address's heartbeat interval, force a
 * heartbeat to be sent immediately, and adjust the address's maximum
 * number of retransmissions sent before an address is considered
 * unreachable.  The sctp_paddrparams structure is used to access and modify
 * an address' parameters.
 */
struct sctp_paddrparams {
        sctp_assoc_t            spp_assoc_id;
        struct sockaddr_storage spp_address;
        uint32_t                spp_hbinterval;
        uint16_t                spp_pathmaxrxt;
};

/*
 * A socket user can request that the peer mark the enclosed address as the
 * association's primary.  The enclosed address must be one of the
 * association's locally bound addresses. The sctp_setpeerprim structure is
 * used to make such request.
 */
struct sctp_setpeerprim {
        sctp_assoc_t            sspp_assoc_id;
        struct sockaddr_storage sspp_addr;
};

/*
 * A socket user can request that the local SCTP stack use the enclosed peer
 * address as the association primary.  The enclosed address must be one of
 * the association peer's addresses.  The sctp_setprim structure is used to
 * make such request.
 */
struct sctp_setprim {
        sctp_assoc_t            ssp_assoc_id;
        struct sockaddr_storage ssp_addr;
};

#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
#pragma pack()
#endif

/* SCTP association states */
#define SCTPS_IDLE              -5      /* idle (opened, but not bound) */
#define SCTPS_BOUND             -4      /* bound, ready to connect or accept */
#define SCTPS_LISTEN            -3      /* listening for connection */
#define SCTPS_COOKIE_WAIT       -2
#define SCTPS_COOKIE_ECHOED     -1
/* states < SCTPS_ESTABLISHED are those where connections not established */
#define SCTPS_ESTABLISHED       0       /* established */
#define SCTPS_SHUTDOWN_PENDING  1
#define SCTPS_SHUTDOWN_SENT     2
#define SCTPS_SHUTDOWN_RECEIVED 3
#define SCTPS_SHUTDOWN_ACK_SENT 4

/*
 * Applications can retrieve current status information about an
 * association, including association state, peer receiver window size,
 * number of unacked data chunks, and number of data chunks pending
 * receipt.  This information is read-only.  The sctp_status structure is
 * used to access this information:
 */
struct sctp_status {
        sctp_assoc_t            sstat_assoc_id;
        int32_t                 sstat_state;
        uint32_t                sstat_rwnd;
        uint16_t                sstat_unackdata;
        uint16_t                sstat_penddata;
        uint16_t                sstat_instrms;
        uint16_t                sstat_outstrms;
        uint32_t                sstat_fragmentation_point;
        struct sctp_paddrinfo   sstat_primary;
};

/* Possible values for sstat_state */
#define SCTP_CLOSED             SCTPS_IDLE
#define SCTP_BOUND              SCTPS_BOUND
#define SCTP_LISTEN             SCTPS_LISTEN
#define SCTP_COOKIE_WAIT        SCTPS_COOKIE_WAIT
#define SCTP_COOKIE_ECHOED      SCTPS_COOKIE_ECHOED
#define SCTP_ESTABLISHED        SCTPS_ESTABLISHED
#define SCTP_SHUTDOWN_PENDING   SCTPS_SHUTDOWN_PENDING
#define SCTP_SHUTDOWN_SENT      SCTPS_SHUTDOWN_SENT
#define SCTP_SHUTDOWN_RECEIVED  SCTPS_SHUTDOWN_RECEIVED
#define SCTP_SHUTDOWN_ACK_SENT  SCTPS_SHUTDOWN_ACK_SENT

/*
 * A socket user can request that the local endpoint set the specified
 * Adaptation Layer Indication parameter for all future INIT and INIT-ACK
 * exchanges.  The sctp_setadaptation structure is used to make such request.
 */
struct sctp_setadaptation {
        uint32_t   ssb_adaptation_ind;
};

/*
 * A socket user request reads local per endpoint association stats.
 * All stats are counts except sas_maxrto, which is the max value
 * since the last user request for stats on this endpoint.
 */
typedef struct sctp_assoc_stats {
        uint64_t        sas_rtxchunks; /* Retransmitted Chunks */
        uint64_t        sas_gapcnt; /* Gap Acknowledgements Received */
        uint64_t        sas_maxrto; /* Maximum Observed RTO this period */
        uint64_t        sas_outseqtsns; /* TSN received > next expected */
        uint64_t        sas_osacks; /* SACKs sent */
        uint64_t        sas_isacks; /* SACKs received */
        uint64_t        sas_octrlchunks; /* Control chunks sent - no dups */
        uint64_t        sas_ictrlchunks; /* Control chunks received - no dups */
        uint64_t        sas_oodchunks; /* Ordered data chunks sent */
        uint64_t        sas_iodchunks; /* Ordered data chunks received */
        uint64_t        sas_ouodchunks; /* Unordered data chunks sent */
        uint64_t        sas_iuodchunks; /* Unordered data chunks received */
        uint64_t        sas_idupchunks; /* Dups received (ordered+unordered) */
} sctp_assoc_stats_t;

/*
 * Private ioctl option structure
 */
struct sctpopt {
        sctp_assoc_t    sopt_aid;
        int             sopt_name;
        uint_t          sopt_len;
        caddr_t         sopt_val;
};

#if defined(_SYSCALL32)
struct sctpopt32 {
        sctp_assoc32_t  sopt_aid;
        int32_t         sopt_name;
        uint32_t        sopt_len;
        caddr32_t       sopt_val;
};
#endif  /* _SYSCALL32 */

/* Forward Cumulative TSN chunk entry. */
typedef struct ftsn_entry_s {
        uint16_t        ftsn_sid;
        uint16_t        ftsn_ssn;
} ftsn_entry_t;

/*
 * New socket functions for SCTP
 */

/* sctp_bindx() operations. */
#define SCTP_BINDX_ADD_ADDR     1
#define SCTP_BINDX_REM_ADDR     2

#if !defined(_KERNEL) || defined(_BOOT)
#ifdef  __STDC__
extern int sctp_bindx(int, void *, int, int);
extern void sctp_freeladdrs(void *);
extern void sctp_freepaddrs(void *);
extern int sctp_getladdrs(int, sctp_assoc_t, void **);
extern int sctp_getpaddrs(int, sctp_assoc_t, void **);
extern int sctp_opt_info(int, sctp_assoc_t, int, void *, socklen_t *);
extern int sctp_peeloff(int, sctp_assoc_t);
extern ssize_t sctp_recvmsg(int, void *, size_t, struct sockaddr *,
    socklen_t *, struct sctp_sndrcvinfo *, int *msg_flags);
extern ssize_t sctp_send(int, const void *, size_t,
    const struct sctp_sndrcvinfo *, int);
extern ssize_t sctp_sendmsg(int, const void *, size_t, const struct sockaddr *,
    socklen_t, uint32_t, uint32_t, uint16_t, uint32_t, uint32_t);
#else   /* __STDC__ */
extern int sctp_bindx();
extern void sctp_freeladdrs();
extern void sctp_freepaddrs();
extern int sctp_getladdrs();
extern int sctp_getpaddrs();
extern int sctp_opt_info();
extern int sctp_peeloff();
extern ssize_t sctp_recvmsg();
extern ssize_t sctp_send();
extern ssize_t sctp_sendmsg();
#endif  /* __STDC__ */
#endif  /* !defined(_KERNEL) || defined(_BOOT) */


/*
 * SCTP protocol related elements.
 */

/* All SCTP chunks and parameters are 32-bit aligned */
#define SCTP_ALIGN      4

/*
 * SCTP association optional parameter handling. The top two bits
 * of the parameter type define how this and further parameters in
 * the received chunk should be handled.
 */
#define SCTP_UNREC_PARAM_MASK   0xc000
/* Continue processing parameters after an unrecognized optional param? */
#define SCTP_CONT_PROC_PARAMS   0x8000
/* Report this unreconized optional parameter or silently ignore it? */
#define SCTP_REPORT_THIS_PARAM  0x4000

/*
 * Data chunk bit manipulations
 */
#define SCTP_DATA_EBIT  0x01
#define SCTP_TBIT       0x01
#define SCTP_DATA_BBIT  0x02
#define SCTP_DATA_UBIT  0x04

#define SCTP_DATA_GET_BBIT(sdc) ((sdc)->sdh_flags & SCTP_DATA_BBIT)
#define SCTP_GET_TBIT(cp)       ((cp)->sch_flags & SCTP_TBIT)
#define SCTP_DATA_GET_EBIT(sdc) ((sdc)->sdh_flags & SCTP_DATA_EBIT)
#define SCTP_DATA_GET_UBIT(sdc) ((sdc)->sdh_flags & SCTP_DATA_UBIT)

#define SCTP_DATA_SET_BBIT(sdc) ((sdc)->sdh_flags |= SCTP_DATA_BBIT)
#define SCTP_SET_TBIT(cp)       ((cp)->sch_flags |= SCTP_TBIT)
#define SCTP_DATA_SET_EBIT(sdc) ((sdc)->sdh_flags |= SCTP_DATA_EBIT)
#define SCTP_DATA_SET_UBIT(sdc) ((sdc)->sdh_flags |=  SCTP_DATA_UBIT)

/* SCTP common header */
typedef struct sctp_hdr {
        uint16_t        sh_sport;
        uint16_t        sh_dport;
        uint32_t        sh_verf;
        uint32_t        sh_chksum;
} sctp_hdr_t;

/* Chunk IDs */
typedef enum {
        CHUNK_DATA,
        CHUNK_INIT,
        CHUNK_INIT_ACK,
        CHUNK_SACK,
        CHUNK_HEARTBEAT,
        CHUNK_HEARTBEAT_ACK,
        CHUNK_ABORT,
        CHUNK_SHUTDOWN,
        CHUNK_SHUTDOWN_ACK,
        CHUNK_ERROR,
        CHUNK_COOKIE,
        CHUNK_COOKIE_ACK,
        CHUNK_ECNE,
        CHUNK_CWR,
        CHUNK_SHUTDOWN_COMPLETE,
        CHUNK_ASCONF_ACK = 128,
        CHUNK_FORWARD_TSN = 192,
        CHUNK_ASCONF = 193
} sctp_chunk_id_t;

/* Common chunk header */
typedef struct sctp_chunk_hdr {
        uint8_t         sch_id;
        uint8_t         sch_flags;
        uint16_t        sch_len;
} sctp_chunk_hdr_t;

/* INIT chunk data definition */
typedef struct sctp_init_chunk {
        uint32_t        sic_inittag;
        uint32_t        sic_a_rwnd;
        uint16_t        sic_outstr;
        uint16_t        sic_instr;
        uint32_t        sic_inittsn;
} sctp_init_chunk_t;

/* SCTP DATA chunk */
typedef struct sctp_data_chunk {
        uint32_t        sdc_tsn;
        uint16_t        sdc_sid;
        uint16_t        sdc_ssn;
        uint32_t        sdc_payload_id;
} sctp_data_chunk_t;

/* sctp_data_hdr includes the SCTP chunk hdr and the DATA chunk */
typedef struct sctp_data_hdr {
        sctp_chunk_hdr_t        sdh_chdr;
        sctp_data_chunk_t       sdh_data;
#define sdh_id          sdh_chdr.sch_id
#define sdh_flags       sdh_chdr.sch_flags
#define sdh_len         sdh_chdr.sch_len
#define sdh_tsn         sdh_data.sdc_tsn
#define sdh_sid         sdh_data.sdc_sid
#define sdh_ssn         sdh_data.sdc_ssn
#define sdh_payload_id  sdh_data.sdc_payload_id
} sctp_data_hdr_t;

typedef struct sctp_sack_chunk {
        uint32_t        ssc_cumtsn;
        uint32_t        ssc_a_rwnd;
        uint16_t        ssc_numfrags;
        uint16_t        ssc_numdups;
} sctp_sack_chunk_t;

typedef struct sctp_sack_frag {
        uint16_t        ssf_start;
        uint16_t        ssf_end;
} sctp_sack_frag_t;

/* Parameter types */
#define PARM_UNKNOWN            0
#define PARM_HBINFO             1
#define PARM_ADDR4              5
#define PARM_ADDR6              6
#define PARM_COOKIE             7
#define PARM_UNRECOGNIZED       8
#define PARM_COOKIE_PRESERVE    9
#define PARM_ADDR_HOST_NAME     11
#define PARM_SUPP_ADDRS         12
#define PARM_ECN                0x8000
#define PARM_ECN_CAPABLE        PARM_ECN
#define PARM_FORWARD_TSN        0xc000
#define PARM_ADD_IP             0xc001
#define PARM_DEL_IP             0xc002
#define PARM_ERROR_IND          0xc003
#define PARM_ASCONF_ERROR       PARM_ERROR_IND
#define PARM_SET_PRIMARY        0xc004
#define PARM_PRIMARY_ADDR       PARM_SET_PRIMARY
#define PARM_SUCCESS            0xc005
#define PARM_ASCONF_SUCCESS     PARM_SUCCESS
#define PARM_ADAPT_LAYER_IND    0xc006


/* Lengths from SCTP spec */
#define PARM_ADDR4_LEN          8
#define PARM_ADDR6_LEN          20

/* Parameter header */
typedef struct sctp_parm_hdr {
        uint16_t        sph_type;
        uint16_t        sph_len;
} sctp_parm_hdr_t;

/*
 * The following extend sctp_parm_hdr_t
 * with cause-specfic content used to fill
 * CAUSE blocks in ABORT or ERROR chunks.
 * The overall size of the CAUSE block will
 * be sizeof (sctp_parm_hdr_t) plus the size
 * of the extended cause structure,
 */

/*
 * Invalid stream-identifier extended cause.
 * SCTP_ERR_BAD_SID
 */
typedef struct sctp_bsc {
        uint16_t        bsc_sid;
        uint16_t        bsc_pad; /* RESV = 0 */
} sctp_bsc_t;

/*
 * Missing parameter extended cause, currently
 * only one missing parameter is supported.
 * SCTP_ERR_MISSING_PARM
 */
typedef struct sctp_mpc {
        uint32_t        mpc_num;
        uint16_t        mpc_param;
        uint16_t        mpc_pad;
} sctp_mpc_t;

/* Error causes */
#define SCTP_ERR_UNKNOWN                0
#define SCTP_ERR_BAD_SID                1
#define SCTP_ERR_MISSING_PARM           2
#define SCTP_ERR_STALE_COOKIE           3
#define SCTP_ERR_NO_RESOURCES           4
#define SCTP_ERR_BAD_ADDR               5
#define SCTP_ERR_UNREC_CHUNK            6
#define SCTP_ERR_BAD_MANDPARM           7
#define SCTP_ERR_UNREC_PARM             8
#define SCTP_ERR_NO_USR_DATA            9
#define SCTP_ERR_COOKIE_SHUT            10
#define SCTP_ERR_RESTART_NEW_ADDRS      11
#define SCTP_ERR_USER_ABORT             12
#define SCTP_ERR_DELETE_LASTADDR        256
#define SCTP_ERR_RESOURCE_SHORTAGE      257
#define SCTP_ERR_DELETE_SRCADDR         258
#define SCTP_ERR_AUTH_ERR               260

/*
 * Extensions
 */

/* Extended Chunk Types */
#define CHUNK_ASCONF            0xc1
#define CHUNK_ASCONF_ACK        0x80

/* Extension Error Causes */
#define SCTP_ERR_DEL_LAST_ADDR  0x0100
#define SCTP_ERR_RES_SHORTAGE   0x0101
#define SCTP_ERR_DEL_SRC_ADDR   0x0102
#define SCTP_ERR_ILLEGAL_ACK    0x0103
#define SCTP_ERR_UNAUTHORIZED   0x0104

typedef struct sctp_addip4 {
        sctp_parm_hdr_t         sad4_addip_ph;
        uint32_t                asconf_req_cid;
        sctp_parm_hdr_t         sad4_addr4_ph;
        ipaddr_t                sad4_addr;
} sctp_addip4_t;

typedef struct sctp_addip6 {
        sctp_parm_hdr_t         sad6_addip_ph;
        uint32_t                asconf_req_cid;
        sctp_parm_hdr_t         sad6_addr6_ph;
        in6_addr_t              sad6_addr;
} sctp_addip6_t;

#ifdef __cplusplus
}
#endif

#endif  /* _NETINET_SCTP_H */