1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2012 David Hoeppner. All rights reserved.
  14  */
  15 
  16 #ifndef _INET_DCCP_IMPL_H
  17 #define _INET_DCCP_IMPL_H
  18 
  19 #include <sys/int_types.h>
  20 #include <sys/netstack.h>
  21 #include <sys/socket.h>
  22 #include <sys/socket_proto.h>
  23 
  24 #include <netinet/in.h>
  25 #include <netinet/ip6.h>
  26 #include <netinet/dccp.h>
  27 
  28 #include <inet/common.h>
  29 #include <inet/ip.h>
  30 #include <inet/ip6.h>
  31 #include <inet/optcom.h>
  32 #include <inet/tunables.h>
  33 
  34 #include "dccp_stack.h"
  35 
  36 #ifdef  __cplusplus
  37 extern "C" {
  38 #endif
  39 
  40 #ifdef  _KERNEL
  41 
  42 #define DCCP_MOD_ID     5999 /* XXX */
  43 
  44 #define DCCP_XMIT_LOWATER       (4 * 1024)
  45 #define DCCP_XMIT_HIWATER       49152
  46 #define DCCP_RECV_LOWATER       (2 * 1024)
  47 #define DCCP_RECV_HIWATER       128000
  48 
  49 /*
  50  * Bind hash array size and hash function.
  51  */
  52 #define DCCP_BIND_FANOUT_SIZE           128
  53 #define DCCP_BIND_HASH(lport, size)     ((ntohs((uint16_t)lport)) & (size - 1))
  54 
  55 
  56 #define DCCP_HDR_LENGTH(dccph)          (dccph_t *)dccph->dh_offset
  57 #define DCCP_MAX_HDR_LENGTH             1020
  58 #define DCCP_MIN_HEADER_LENGTH          12
  59 
  60 /* Packet types (RFC 4340, Section 5.1.) */
  61 #define DCCP_PKT_REQUEST        0
  62 #define DCCP_PKT_RESPONSE       1
  63 #define DCCP_PKT_DATA           2
  64 #define DCCP_PKT_ACK            3
  65 #define DCCP_PKT_DATAACK        4
  66 #define DCCP_PKT_CLOSEREQ       5
  67 #define DCCP_PKT_CLOSE          6
  68 #define DCCP_PKT_RESET          7
  69 #define DCCP_PKT_SYNC           8
  70 #define DCCP_PKT_SYNCACK        9
  71 
  72 /* Generic protocol header (RFC 4340, Section 5.1.) */
  73 typedef struct dccphdr_s {
  74         uint8_t         dh_lport[2];
  75         uint8_t         dh_fport[2];
  76         uint8_t         dh_offset;
  77         uint8_t         dh_ccval:4,
  78                         dh_cscov:4;
  79         uint8_t         db_sum[2];
  80         uint8_t         dh_reserved:3,
  81                         dh_type:4,
  82                         dh_x:1;
  83         uint8_t         dh_res_seq;
  84         uint8_t         dh_seq[2];
  85 } dccph_t;
  86 
  87 
  88 /* Generic protocol header aligned (RFC 4340, Section 5.1.) */
  89 typedef struct dccphdra_s {
  90         in_port_t       dha_lport;              /* Source port */
  91         in_port_t       dha_fport;              /* Destination port */
  92         uint8_t         dha_offset;             /* Data offset */
  93         uint8_t         dha_ccval:4,            /* */
  94                         dha_cscov:4;            /* */
  95         uint16_t        dha_sum;                /* Checksum */
  96         uint8_t         dha_x:1,                /* Reserved */
  97                         dha_type:4,             /* Packet type */
  98                         dha_reserved:3;         /* Header type */
  99         uint8_t         dha_res_seq;
 100         uint16_t        dha_seq;                /* Partial sequence number */
 101 } dccpha_t;
 102 
 103 typedef struct dccphdra_ext_s {
 104         uint32_t        dha_ext_seq;
 105 } dccpha_ext_t;
 106 
 107 /* Acknowledgement number */
 108 typedef struct dccphdra_ack {
 109         uint16_t        dha_ack_reserved;
 110         uint16_t        dha_ack_high;
 111         uint32_t        dha_ack_low;
 112 } dccpha_ack_t;
 113 
 114 typedef struct dccphdra_srv {
 115         uint32_t        dha_srv_code;
 116 } dccpha_srv_t;
 117 
 118 typedef struct dccphdra_reset {
 119         uint8_t         dha_reset_code;
 120         uint8_t         dha_reset_data[3];
 121 } dccpha_reset_t;
 122 
 123 /* Internal DCCP structure */
 124 typedef struct dccp_s {
 125 
 126         conn_t          *dccp_connp;            /* Backpointer to conn_t */
 127         dccp_stack_t    *dccp_dccps;            /* Backpointer to dccp_stack_t */
 128 
 129         uint32_t        dccp_state;
 130 
 131         /* Bind related */
 132         struct dccp_s   *dccp_bind_hash;        /* Bind hash chain */
 133         struct dccp_s   *dccp_bind_hash_port;   /* Bound to the same port */
 134         struct dccp_s   **dccp_ptpbhn;
 135 
 136         struct dccphdra_s *dccp_dccpha;         /* Template header */
 137 
 138         mblk_t          *dccp_xmit_head;
 139 
 140         sock_connid_t   dccp_connid;
 141 } dccp_t;
 142 
 143 #define dccps_smallest_nonpriv_port     dccps_propinfo_tbl[0].prop_cur_uval
 144 #define dccps_smallest_anon_port        dccps_propinfo_tbl[1].prop_cur_uval
 145 #define dccps_largest_anon_port         dccps_propinfo_tbl[2].prop_cur_uval
 146 
 147 #define dccps_dbg                       dccps_propinfo_tbl[4].prop_cur_uval
 148 #define dccps_rst_sent_rate_enabled     dccps_propinfo_tbl[5].prop_cur_uval
 149 #define dccps_rst_sent_rate             dccps_propinfo_tbl[6].prop_cur_uval
 150 
 151 typedef struct dccp_df_s {
 152         struct dccp_s   *df_dccp;
 153         kmutex_t        df_lock;
 154         uchar_t         df_pad[TF_CACHEL_PAD - (sizeof (dccp_t *) +
 155                             sizeof (kmutex_t))];
 156 } dccp_df_t;
 157 
 158 extern struct qinit dccp_rinitv4, dccp_rinitv6;
 159 
 160 extern optdb_obj_t      dccp_opt_obj;
 161 extern uint_t           dccp_max_optsize;
 162 
 163 /*
 164  * Functions in dccp.c
 165  */
 166 extern int      dccp_build_hdrs(dccp_t *);
 167 extern conn_t   *dccp_create_common(cred_t *, boolean_t, boolean_t, int *);
 168 extern void     dccp_close_common(conn_t *);
 169 extern int      dccp_do_bind(conn_t *, struct sockaddr *, socklen_t, cred_t *,
 170                     boolean_t);
 171 extern int      dccp_do_unbind(conn_t *);
 172 extern int      dccp_do_listen(conn_t *, struct sockaddr *, socklen_t, int,
 173                     cred_t *, boolean_t);
 174 extern int      dccp_do_connect(conn_t *, const struct sockaddr *, socklen_t,
 175                     cred_t *, pid_t);
 176 extern void     dccp_init_values(dccp_t *, dccp_t *);
 177 extern void     *dccp_get_conn(void *, dccp_stack_t *);
 178 extern int      dccp_set_destination(dccp_t *dccp);
 179 
 180 /*
 181  * Bind related functions in dccp_bind.c
 182  */
 183 extern void     dccp_bind_hash_insert(dccp_df_t *, dccp_t *, int);
 184 extern void     dccp_bind_hash_remove(dccp_t *);
 185 extern int      dccp_bind_check(conn_t *, struct sockaddr *, socklen_t, cred_t *cr,
 186                     boolean_t);
 187 extern in_port_t dccp_bindi(dccp_t *, in_port_t, const in6_addr_t *, int,
 188                     boolean_t, boolean_t, boolean_t);
 189 extern in_port_t dccp_update_next_port(in_port_t, const dccp_t *, boolean_t);
 190 
 191 /*
 192  * MIB-II and kstat related functions.
 193  */
 194 extern mblk_t   *dccp_snmp_get(queue_t *, mblk_t *);
 195 
 196 /*
 197  * Socket related functions in dccp_socket.c
 198  */
 199 extern sock_lower_handle_t      dccp_create(int, int, int, sock_downcalls_t **,
 200                                     uint_t *, int *, int, cred_t *);
 201 extern int      dccp_fallback(sock_lower_handle_t, queue_t *, boolean_t,
 202                     so_proto_quiesced_cb_t, sock_quiesce_arg_t *);
 203 
 204 /*
 205  * Input path related functions in dccp_input.c
 206  */
 207 extern void     dccp_icmp_input(void *, mblk_t *, void *, ip_recv_attr_t *);
 208 extern void     dccp_input_data(void *, mblk_t *, void *, ip_recv_attr_t *);
 209 extern void     dccp_rsrv(queue_t *);
 210 extern void     dccp_input_listener_unbound(void *, mblk_t *, void *,
 211                     ip_recv_attr_t *);
 212 extern boolean_t        dccp_verifyicmp(conn_t *, void *, icmph_t *, icmp6_t *,
 213                             ip_recv_attr_t *);
 214 /*
 215  * Output path related functions in dccp_output.c
 216  */
 217 extern void     dccp_wput(queue_t *, mblk_t *);
 218 extern void     dccp_xmit_listeners_reset(mblk_t *, ip_recv_attr_t *,
 219                     ip_stack_t *, conn_t *);
 220 extern void     dccp_send_synack(void *, mblk_t *, void *, ip_recv_attr_t *);
 221 extern mblk_t   *dccp_xmit_mp(dccp_t *, mblk_t *, int32_t, int32_t *,
 222                     mblk_t **, uint32_t, boolean_t, uint32_t *, boolean_t);
 223 extern mblk_t   *dccp_generate_packet(conn_t *, mblk_t *);
 224 /*
 225  * Options related functions in dccp_opt_data.c
 226  */
 227 extern int      dccp_opt_get(conn_t *, int, int, uchar_t *);
 228 extern int      dccp_opt_set(conn_t *, uint_t, int, int, uint_t, uchar_t *,
 229                     uint_t *, uchar_t *, void *, cred_t *);
 230 
 231 /*
 232  * dccp_tpi.c
 233  */
 234 extern void     dccp_err_ack(dccp_t *, mblk_t *, int, int);
 235 extern void     dccp_tpi_connect(dccp_t *, mblk_t *);
 236 extern int      dccp_tpi_close(queue_t *, int);
 237 extern int      dccp_tpi_opt_get(queue_t *, t_scalar_t, t_scalar_t, uchar_t *);
 238 extern int      dccp_tpi_opt_set(queue_t *, uint_t, int, int, uint_t, uchar_t *,
 239                     uint_t *, uchar_t *, void *, cred_t *);
 240 
 241 #endif  /* _KERNEL */
 242 
 243 #ifdef  __cplusplus
 244 }
 245 #endif
 246 
 247 #endif  /* _INET_DCCP_IMPL_H */