159 int level, int name, uint_t inlen,
160 uchar_t *invalp, uint_t *outlenp, uchar_t *outvalp,
161 void *thisdg_attrs, cred_t *cr);
162 int udp_opt_get(conn_t *connp, int level, int name,
163 uchar_t *ptr);
164 static int udp_output_connected(conn_t *connp, mblk_t *mp, cred_t *cr,
165 pid_t pid);
166 static int udp_output_lastdst(conn_t *connp, mblk_t *mp, cred_t *cr,
167 pid_t pid, ip_xmit_attr_t *ixa);
168 static int udp_output_newdst(conn_t *connp, mblk_t *data_mp, sin_t *sin,
169 sin6_t *sin6, ushort_t ipversion, cred_t *cr, pid_t,
170 ip_xmit_attr_t *ixa);
171 static mblk_t *udp_prepend_hdr(conn_t *, ip_xmit_attr_t *, const ip_pkt_t *,
172 const in6_addr_t *, const in6_addr_t *, in_port_t, uint32_t, mblk_t *,
173 int *);
174 static mblk_t *udp_prepend_header_template(conn_t *, ip_xmit_attr_t *,
175 mblk_t *, const in6_addr_t *, in_port_t, uint32_t, int *);
176 static void udp_ud_err(queue_t *q, mblk_t *mp, t_scalar_t err);
177 static void udp_ud_err_connected(conn_t *, t_scalar_t);
178 static void udp_tpi_unbind(queue_t *q, mblk_t *mp);
179 static in_port_t udp_update_next_port(udp_t *udp, in_port_t port,
180 boolean_t random);
181 static void udp_wput_other(queue_t *q, mblk_t *mp);
182 static void udp_wput_iocdata(queue_t *q, mblk_t *mp);
183 static void udp_wput_fallback(queue_t *q, mblk_t *mp);
184 static size_t udp_set_rcv_hiwat(udp_t *udp, size_t size);
185
186 static void *udp_stack_init(netstackid_t stackid, netstack_t *ns);
187 static void udp_stack_fini(netstackid_t stackid, void *arg);
188
189 /* Common routines for TPI and socket module */
190 static void udp_ulp_recv(conn_t *, mblk_t *, uint_t, ip_recv_attr_t *);
191
192 /* Common routine for TPI and socket module */
193 static conn_t *udp_do_open(cred_t *, boolean_t, int, int *);
194 static void udp_do_close(conn_t *);
195 static int udp_do_bind(conn_t *, struct sockaddr *, socklen_t, cred_t *,
196 boolean_t);
197 static int udp_do_unbind(conn_t *);
198
199 int udp_getsockname(sock_lower_handle_t,
200 struct sockaddr *, socklen_t *, cred_t *);
2636 if (error < 0)
2637 udp_err_ack(q, mp, -error, 0);
2638 else
2639 udp_err_ack(q, mp, TSYSERR, error);
2640 return;
2641 }
2642
2643 mp = mi_tpi_ok_ack_alloc(mp);
2644 ASSERT(mp != NULL);
2645 ASSERT(((struct T_ok_ack *)mp->b_rptr)->PRIM_type == T_OK_ACK);
2646 qreply(q, mp);
2647 }
2648
2649 /*
2650 * Don't let port fall into the privileged range.
2651 * Since the extra privileged ports can be arbitrary we also
2652 * ensure that we exclude those from consideration.
2653 * us->us_epriv_ports is not sorted thus we loop over it until
2654 * there are no changes.
2655 */
2656 static in_port_t
2657 udp_update_next_port(udp_t *udp, in_port_t port, boolean_t random)
2658 {
2659 int i, bump;
2660 in_port_t nextport;
2661 boolean_t restart = B_FALSE;
2662 udp_stack_t *us = udp->udp_us;
2663
2664 if (random && udp_random_anon_port != 0) {
2665 (void) random_get_pseudo_bytes((uint8_t *)&port,
2666 sizeof (in_port_t));
2667 /*
2668 * Unless changed by a sys admin, the smallest anon port
2669 * is 32768 and the largest anon port is 65535. It is
2670 * very likely (50%) for the random port to be smaller
2671 * than the smallest anon port. When that happens,
2672 * add port % (anon port range) to the smallest anon
2673 * port to get the random port. It should fall into the
2674 * valid anon port range.
2675 */
2676 if ((port < us->us_smallest_anon_port) ||
|
159 int level, int name, uint_t inlen,
160 uchar_t *invalp, uint_t *outlenp, uchar_t *outvalp,
161 void *thisdg_attrs, cred_t *cr);
162 int udp_opt_get(conn_t *connp, int level, int name,
163 uchar_t *ptr);
164 static int udp_output_connected(conn_t *connp, mblk_t *mp, cred_t *cr,
165 pid_t pid);
166 static int udp_output_lastdst(conn_t *connp, mblk_t *mp, cred_t *cr,
167 pid_t pid, ip_xmit_attr_t *ixa);
168 static int udp_output_newdst(conn_t *connp, mblk_t *data_mp, sin_t *sin,
169 sin6_t *sin6, ushort_t ipversion, cred_t *cr, pid_t,
170 ip_xmit_attr_t *ixa);
171 static mblk_t *udp_prepend_hdr(conn_t *, ip_xmit_attr_t *, const ip_pkt_t *,
172 const in6_addr_t *, const in6_addr_t *, in_port_t, uint32_t, mblk_t *,
173 int *);
174 static mblk_t *udp_prepend_header_template(conn_t *, ip_xmit_attr_t *,
175 mblk_t *, const in6_addr_t *, in_port_t, uint32_t, int *);
176 static void udp_ud_err(queue_t *q, mblk_t *mp, t_scalar_t err);
177 static void udp_ud_err_connected(conn_t *, t_scalar_t);
178 static void udp_tpi_unbind(queue_t *q, mblk_t *mp);
179 static void udp_wput_other(queue_t *q, mblk_t *mp);
180 static void udp_wput_iocdata(queue_t *q, mblk_t *mp);
181 static void udp_wput_fallback(queue_t *q, mblk_t *mp);
182 static size_t udp_set_rcv_hiwat(udp_t *udp, size_t size);
183
184 static void *udp_stack_init(netstackid_t stackid, netstack_t *ns);
185 static void udp_stack_fini(netstackid_t stackid, void *arg);
186
187 /* Common routines for TPI and socket module */
188 static void udp_ulp_recv(conn_t *, mblk_t *, uint_t, ip_recv_attr_t *);
189
190 /* Common routine for TPI and socket module */
191 static conn_t *udp_do_open(cred_t *, boolean_t, int, int *);
192 static void udp_do_close(conn_t *);
193 static int udp_do_bind(conn_t *, struct sockaddr *, socklen_t, cred_t *,
194 boolean_t);
195 static int udp_do_unbind(conn_t *);
196
197 int udp_getsockname(sock_lower_handle_t,
198 struct sockaddr *, socklen_t *, cred_t *);
2634 if (error < 0)
2635 udp_err_ack(q, mp, -error, 0);
2636 else
2637 udp_err_ack(q, mp, TSYSERR, error);
2638 return;
2639 }
2640
2641 mp = mi_tpi_ok_ack_alloc(mp);
2642 ASSERT(mp != NULL);
2643 ASSERT(((struct T_ok_ack *)mp->b_rptr)->PRIM_type == T_OK_ACK);
2644 qreply(q, mp);
2645 }
2646
2647 /*
2648 * Don't let port fall into the privileged range.
2649 * Since the extra privileged ports can be arbitrary we also
2650 * ensure that we exclude those from consideration.
2651 * us->us_epriv_ports is not sorted thus we loop over it until
2652 * there are no changes.
2653 */
2654 in_port_t
2655 udp_update_next_port(udp_t *udp, in_port_t port, boolean_t random)
2656 {
2657 int i, bump;
2658 in_port_t nextport;
2659 boolean_t restart = B_FALSE;
2660 udp_stack_t *us = udp->udp_us;
2661
2662 if (random && udp_random_anon_port != 0) {
2663 (void) random_get_pseudo_bytes((uint8_t *)&port,
2664 sizeof (in_port_t));
2665 /*
2666 * Unless changed by a sys admin, the smallest anon port
2667 * is 32768 and the largest anon port is 65535. It is
2668 * very likely (50%) for the random port to be smaller
2669 * than the smallest anon port. When that happens,
2670 * add port % (anon port range) to the smallest anon
2671 * port to get the random port. It should fall into the
2672 * valid anon port range.
2673 */
2674 if ((port < us->us_smallest_anon_port) ||
|