xref: /titanic_44/usr/src/uts/common/inet/udp/udp.c (revision 8eea8e29cc4374d1ee24c25a07f45af132db3499)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 /* Copyright (c) 1990 Mentat Inc. */
27 
28 #pragma ident	"%Z%%M%	%I%	%E% SMI"
29 
30 const char udp_version[] = "%Z%%M%	%I%	%E% SMI";
31 
32 #include <sys/types.h>
33 #include <sys/stream.h>
34 #include <sys/stropts.h>
35 #include <sys/strlog.h>
36 #include <sys/strsun.h>
37 #define	_SUN_TPI_VERSION 2
38 #include <sys/tihdr.h>
39 #include <sys/timod.h>
40 #include <sys/tiuser.h>
41 #include <sys/ddi.h>
42 #include <sys/sunddi.h>
43 #include <sys/strsubr.h>
44 #include <sys/suntpi.h>
45 #include <sys/xti_inet.h>
46 #include <sys/cmn_err.h>
47 #include <sys/kmem.h>
48 #include <sys/policy.h>
49 #include <sys/ucred.h>
50 #include <sys/zone.h>
51 
52 #include <sys/socket.h>
53 #include <sys/vtrace.h>
54 #include <sys/debug.h>
55 #include <sys/isa_defs.h>
56 #include <sys/random.h>
57 #include <netinet/in.h>
58 #include <netinet/ip6.h>
59 #include <netinet/icmp6.h>
60 #include <netinet/udp.h>
61 #include <net/if.h>
62 
63 #include <inet/common.h>
64 #include <inet/ip.h>
65 #include <inet/ip6.h>
66 #include <inet/ip_ire.h>
67 #include <inet/mi.h>
68 #include <inet/mib2.h>
69 #include <inet/nd.h>
70 #include <inet/optcom.h>
71 #include <inet/snmpcom.h>
72 #include <inet/kstatcom.h>
73 #include <inet/udp_impl.h>
74 
75 /*
76  * The ipsec_info.h header file is here since it has the defination for the
77  * M_CTL message types used by IP to convey information to the ULP. The
78  * ipsec_info.h needs the pfkeyv2.h, hence the latters presence.
79  */
80 #include <net/pfkeyv2.h>
81 #include <inet/ipsec_info.h>
82 
83 /*
84  * Object to represent database of options to search passed to
85  * {sock,tpi}optcom_req() interface routine to take care of option
86  * management and associated methods.
87  * XXX. These and other externs should really move to a udp header file.
88  */
89 extern optdb_obj_t	udp_opt_obj;
90 extern uint_t		udp_max_optsize;
91 
92 
93 /*
94  * Synchronization notes:
95  *
96  * UDP uses a combination of the queue-pair STREAMS perimeter, a global
97  * lock and a set of bind hash locks to protect its data structures.
98  *
99  * The queue-pair perimeter is not acquired exclusively in the put
100  * procedures thus when udp_rput or udp_wput needs exclusive access to
101  * the udp_t instance structure it will use qwriter(..., PERIM_INNER) to
102  * asynchronously acquire exclusive access to the udp_t instance.
103  *
104  * When UDP global data needs to be modified the udp_g_lock mutex is acquired.
105  * Currently, udp_g_head and udp_g_epriv_ports[] are protected by it.
106  *
107  * When an UDP endpoint is bound to a local port, it is inserted into
108  * a bind hash list.  The list consists of an array of udp_fanout_t buckets.
109  * The size of the array is controlled by the udp_bind_fanout_size variable.
110  * This variable can be changed in /etc/system if the default value is
111  * not large enough.  Each bind hash bucket is protected by a per bucket lock.
112  * It protects the udp_bind_hash and udp_ptpbhn fields in the udp_t
113  * structure.  An UDP endpoint is removed from the bind hash list only
114  * when it is being unbound or being closed.  The per bucket lock also
115  * protects an UDP endpoint's state changes.
116  */
117 
118 /*
119  * Bind hash list size and hash function.  It has to be a power of 2 for
120  * hashing.
121  */
122 #define	UDP_BIND_FANOUT_SIZE	512
123 #define	UDP_BIND_HASH(lport) \
124 	((ntohs((uint16_t)lport)) & (udp_bind_fanout_size - 1))
125 
126 /* UDP bind fanout hash structure. */
127 typedef struct udp_fanout_s {
128 	udp_t *uf_udp;
129 	kmutex_t uf_lock;
130 #if defined(_LP64) || defined(_I32LPx)
131 	char	uf_pad[48];
132 #else
133 	char	uf_pad[56];
134 #endif
135 } udp_fanout_t;
136 
137 uint_t udp_bind_fanout_size = UDP_BIND_FANOUT_SIZE;
138 /* udp_fanout_t *udp_bind_fanout. */
139 static udp_fanout_t *udp_bind_fanout;
140 
141 /*
142  * This controls the rate some ndd info report functions can be used
143  * by non-priviledged users.  It stores the last time such info is
144  * requested.  When those report functions are called again, this
145  * is checked with the current time and compare with the ndd param
146  * udp_ndd_get_info_interval.
147  */
148 static clock_t udp_last_ndd_get_info_time;
149 #define	NDD_TOO_QUICK_MSG \
150 	"ndd get info rate too high for non-priviledged users, try again " \
151 	"later.\n"
152 #define	NDD_OUT_OF_BUF_MSG	"<< Out of buffer >>\n"
153 
154 /* Named Dispatch Parameter Management Structure */
155 typedef struct udpparam_s {
156 	uint32_t udp_param_min;
157 	uint32_t udp_param_max;
158 	uint32_t udp_param_value;
159 	char	*udp_param_name;
160 } udpparam_t;
161 
162 static void	udp_addr_req(queue_t *q, mblk_t *mp);
163 static void	udp_bind(queue_t *q, mblk_t *mp);
164 static void	udp_bind_hash_insert(udp_fanout_t *uf, udp_t *udp);
165 static void	udp_bind_hash_remove(udp_t *udp, boolean_t caller_holds_lock);
166 static int	udp_build_hdrs(queue_t *q, udp_t *udp);
167 static void	udp_capability_req(queue_t *q, mblk_t *mp);
168 static int	udp_close(queue_t *q);
169 static void	udp_connect(queue_t *q, mblk_t *mp);
170 static void	udp_disconnect(queue_t *q, mblk_t *mp);
171 static void	udp_err_ack(queue_t *q, mblk_t *mp, t_scalar_t t_error,
172 		    int sys_error);
173 static void	udp_err_ack_prim(queue_t *q, mblk_t *mp, int primitive,
174 		    t_scalar_t tlierr, int unixerr);
175 static int	udp_extra_priv_ports_get(queue_t *q, mblk_t *mp, caddr_t cp,
176 		    cred_t *cr);
177 static int	udp_extra_priv_ports_add(queue_t *q, mblk_t *mp,
178 		    char *value, caddr_t cp, cred_t *cr);
179 static int	udp_extra_priv_ports_del(queue_t *q, mblk_t *mp,
180 		    char *value, caddr_t cp, cred_t *cr);
181 static void	udp_icmp_error(queue_t *q, mblk_t *mp);
182 static void	udp_icmp_error_ipv6(queue_t *q, mblk_t *mp);
183 static void	udp_info_req(queue_t *q, mblk_t *mp);
184 static mblk_t	*udp_ip_bind_mp(udp_t *udp, t_scalar_t bind_prim,
185 		    t_scalar_t addr_length);
186 static int	udp_open(queue_t *q, dev_t *devp, int flag, int sflag,
187 		    cred_t *credp);
188 static  int	udp_unitdata_opt_process(queue_t *q, mblk_t *mp,
189 		    int *errorp, void *thisdg_attrs);
190 static boolean_t udp_opt_allow_udr_set(t_scalar_t level, t_scalar_t name);
191 int		udp_opt_default(queue_t *q, t_scalar_t level, t_scalar_t name,
192 		    uchar_t *ptr);
193 int		udp_opt_get(queue_t *q, t_scalar_t level, t_scalar_t name,
194 		    uchar_t *ptr);
195 int		udp_opt_set(queue_t *q, uint_t optset_context,
196 		    int level, int name,
197 		    uint_t inlen, uchar_t *invalp,
198 		    uint_t *outlenp, uchar_t *outvalp,
199 		    void *thisdg_attrs, cred_t *cr, mblk_t *mblk);
200 static int	udp_param_get(queue_t *q, mblk_t *mp, caddr_t cp, cred_t *cr);
201 static boolean_t udp_param_register(udpparam_t *udppa, int cnt);
202 static int	udp_param_set(queue_t *q, mblk_t *mp, char *value, caddr_t cp,
203 		    cred_t *cr);
204 static int	udp_pkt_set(uchar_t *invalp, uint_t inlen, boolean_t sticky,
205 		    uchar_t **optbufp, uint_t *optlenp);
206 static void	udp_report_item(mblk_t *mp, udp_t *udp);
207 static void	udp_rput(queue_t *q, mblk_t *mp);
208 static	void	udp_rput_bind_ack(queue_t *q, mblk_t *mp);
209 static void	udp_rput_other(queue_t *q, mblk_t *mp);
210 static int	udp_snmp_get(queue_t *q, mblk_t *mpctl);
211 static int	udp_snmp_set(queue_t *q, t_scalar_t level, t_scalar_t name,
212 		    uchar_t *ptr, int len);
213 static int	udp_status_report(queue_t *q, mblk_t *mp, caddr_t cp,
214 		    cred_t *cr);
215 static void	udp_ud_err(queue_t *q, mblk_t *mp, t_scalar_t err);
216 static void	udp_unbind(queue_t *q, mblk_t *mp);
217 static in_port_t udp_update_next_port(in_port_t port, boolean_t random);
218 static void	udp_wput(queue_t *q, mblk_t *mp);
219 static void	udp_wput_ipv6(queue_t *q, mblk_t *mp, sin6_t *sin6,
220 		    t_scalar_t tudr_optlen);
221 static void	udp_wput_other(queue_t *q, mblk_t *mp);
222 static void	udp_wput_iocdata(queue_t *q, mblk_t *mp);
223 
224 static void	udp_kstat_init(void);
225 static void	udp_kstat_fini(void);
226 static int	udp_kstat_update(kstat_t *kp, int rw);
227 
228 major_t UDP6_MAJ;
229 #define		UDP6		"udp6"
230 
231 #define		UDP_MAXPACKET_IPV4	\
232 	(IP_MAXPACKET - UDPH_SIZE - IP_SIMPLE_HDR_LENGTH)
233 #define		UDP_MAXPACKET_IPV6	\
234 	(IP_MAXPACKET - UDPH_SIZE - IPV6_HDR_LEN)
235 
236 static struct module_info info =  {
237 	5607, "udp", 1, INFPSZ, 512, 128
238 };
239 
240 static struct qinit rinit = {
241 	(pfi_t)udp_rput, NULL, udp_open, udp_close, NULL, &info
242 };
243 
244 static struct qinit winit = {
245 	(pfi_t)udp_wput, NULL, NULL, NULL, NULL, &info
246 };
247 
248 struct streamtab udpinfo = {
249 	&rinit, &winit
250 };
251 
252 static	sin_t	sin_null;	/* Zero address for quick clears */
253 static	sin6_t	sin6_null;	/* Zero address for quick clears */
254 
255 /* Protected by udp_g_lock */
256 static void	*udp_g_head;	/* Head for list of open udp streams. */
257 kmutex_t	udp_g_lock;	/* Protects the above variable */
258 
259 /* Hint not protected by any lock */
260 static in_port_t	udp_g_next_port_to_try;
261 
262 /*
263  * Extra privileged ports. In host byte order. Protected by udp_g_lock.
264  */
265 #define	UDP_NUM_EPRIV_PORTS	64
266 static int	udp_g_num_epriv_ports = UDP_NUM_EPRIV_PORTS;
267 static in_port_t udp_g_epriv_ports[UDP_NUM_EPRIV_PORTS] = { 2049, 4045 };
268 
269 /* Only modified during _init and _fini thus no locking is needed. */
270 static IDP	udp_g_nd;	/* Points to table of UDP ND variables. */
271 
272 /* MIB-2 stuff for SNMP */
273 static mib2_udp_t	udp_mib;	/* SNMP fixed size info */
274 static kstat_t		*udp_mibkp;	/* kstat exporting udp_mib data */
275 
276 
277 /* Default structure copied into T_INFO_ACK messages */
278 static struct T_info_ack udp_g_t_info_ack_ipv4 = {
279 	T_INFO_ACK,
280 	UDP_MAXPACKET_IPV4,	/* TSDU_size. Excl. headers */
281 	T_INVALID,	/* ETSU_size.  udp does not support expedited data. */
282 	T_INVALID,	/* CDATA_size. udp does not support connect data. */
283 	T_INVALID,	/* DDATA_size. udp does not support disconnect data. */
284 	sizeof (sin_t),	/* ADDR_size. */
285 	0,		/* OPT_size - not initialized here */
286 	UDP_MAXPACKET_IPV4,	/* TIDU_size.  Excl. headers */
287 	T_CLTS,		/* SERV_type.  udp supports connection-less. */
288 	TS_UNBND,	/* CURRENT_state.  This is set from udp_state. */
289 	(XPG4_1|SENDZERO) /* PROVIDER_flag */
290 };
291 
292 static	struct T_info_ack udp_g_t_info_ack_ipv6 = {
293 	T_INFO_ACK,
294 	UDP_MAXPACKET_IPV6,	/* TSDU_size.  Excl. headers */
295 	T_INVALID,	/* ETSU_size.  udp does not support expedited data. */
296 	T_INVALID,	/* CDATA_size. udp does not support connect data. */
297 	T_INVALID,	/* DDATA_size. udp does not support disconnect data. */
298 	sizeof (sin6_t), /* ADDR_size. */
299 	0,		/* OPT_size - not initialized here */
300 	UDP_MAXPACKET_IPV6,	/* TIDU_size. Excl. headers */
301 	T_CLTS,		/* SERV_type.  udp supports connection-less. */
302 	TS_UNBND,	/* CURRENT_state.  This is set from udp_state. */
303 	(XPG4_1|SENDZERO) /* PROVIDER_flag */
304 };
305 
306 /* largest UDP port number */
307 #define	UDP_MAX_PORT	65535
308 
309 /*
310  * Table of ND variables supported by udp.  These are loaded into udp_g_nd
311  * in udp_open.
312  * All of these are alterable, within the min/max values given, at run time.
313  */
314 static udpparam_t	udp_param_arr[] = {
315 	/* min	max		value		name */
316 	{ 0L,	256,		32,		"udp_wroff_extra" },
317 	{ 1L,	255,		255,		"udp_ipv4_ttl" },
318 	{ 0, IPV6_MAX_HOPS, IPV6_DEFAULT_HOPS,	"udp_ipv6_hoplimit"},
319 	{ 1024,	(32 * 1024),	1024,		"udp_smallest_nonpriv_port" },
320 	{ 0,	1,		1,		"udp_do_checksum" },
321 	{ 1024,	UDP_MAX_PORT,	(32 * 1024),	"udp_smallest_anon_port" },
322 	{ 1024,	UDP_MAX_PORT,	UDP_MAX_PORT,	"udp_largest_anon_port" },
323 	{ 4096,	1024*1024,	56*1024,	"udp_xmit_hiwat"},
324 	{ 0,	1024*1024,	1024,		"udp_xmit_lowat"},
325 	{ 4096,	1024*1024,	56*1024,	"udp_recv_hiwat"},
326 	{ 65536, 1024*1024*1024, 2*1024*1024,	"udp_max_buf"},
327 	{ 100,	60000,		1000,		"udp_ndd_get_info_interval"},
328 };
329 #define	udp_wroff_extra			udp_param_arr[0].udp_param_value
330 #define	udp_ipv4_ttl			udp_param_arr[1].udp_param_value
331 #define	udp_ipv6_hoplimit		udp_param_arr[2].udp_param_value
332 #define	udp_smallest_nonpriv_port	udp_param_arr[3].udp_param_value
333 #define	udp_do_checksum			udp_param_arr[4].udp_param_value
334 #define	udp_smallest_anon_port		udp_param_arr[5].udp_param_value
335 #define	udp_largest_anon_port		udp_param_arr[6].udp_param_value
336 #define	udp_xmit_hiwat			udp_param_arr[7].udp_param_value
337 #define	udp_xmit_lowat			udp_param_arr[8].udp_param_value
338 #define	udp_recv_hiwat			udp_param_arr[9].udp_param_value
339 #define	udp_max_buf			udp_param_arr[10].udp_param_value
340 #define	udp_ndd_get_info_interval	udp_param_arr[11].udp_param_value
341 
342 /*
343  * The smallest anonymous port in the priviledged port range which UDP
344  * looks for free port.  Use in the option UDP_ANONPRIVBIND.
345  */
346 static in_port_t udp_min_anonpriv_port = 512;
347 
348 /* If set to 0, pick ephemeral port sequentially; otherwise randomly. */
349 uint32_t udp_random_anon_port = 1;
350 
351 /*
352  * Hook functions to enable cluster networking.
353  * On non-clustered systems these vectors must always be NULL
354  */
355 
356 void (*cl_inet_bind)(uchar_t protocol, sa_family_t addr_family,
357 			uint8_t *laddrp, in_port_t lport) = NULL;
358 void (*cl_inet_unbind)(uint8_t protocol, sa_family_t addr_family,
359 			uint8_t *laddrp, in_port_t lport) = NULL;
360 
361 /*
362  * Return the next anonymous port in the priviledged port range for
363  * bind checking.
364  */
365 static in_port_t
366 udp_get_next_priv_port(void)
367 {
368 	static in_port_t next_priv_port = IPPORT_RESERVED - 1;
369 
370 	if (next_priv_port < udp_min_anonpriv_port) {
371 		next_priv_port = IPPORT_RESERVED - 1;
372 	}
373 	return (next_priv_port--);
374 }
375 
376 /* UDP bind hash report triggered via the Named Dispatch mechanism. */
377 /* ARGSUSED */
378 static int
379 udp_bind_hash_report(queue_t *q, mblk_t *mp, caddr_t cp, cred_t *cr)
380 {
381 	udp_fanout_t	*udpf;
382 	udp_t		*udp;
383 	int		i;
384 	zoneid_t	zoneid;
385 
386 	/* Refer to comments in udp_status_report(). */
387 	if (cr == NULL || secpolicy_net_config(cr, B_TRUE) != 0) {
388 		if (ddi_get_lbolt() - udp_last_ndd_get_info_time <
389 		    drv_usectohz(udp_ndd_get_info_interval * 1000)) {
390 			(void) mi_mpprintf(mp, NDD_TOO_QUICK_MSG);
391 			return (0);
392 		}
393 	}
394 	if ((mp->b_cont = allocb(ND_MAX_BUF_LEN, BPRI_HI)) == NULL) {
395 		/* The following may work even if we cannot get a large buf. */
396 		(void) mi_mpprintf(mp, NDD_OUT_OF_BUF_MSG);
397 		return (0);
398 	}
399 
400 	(void) mi_mpprintf(mp,
401 	    "UDP     " MI_COL_HDRPAD_STR
402 	/*   12345678[89ABCDEF] */
403 	    " zone lport src addr        dest addr       port  state");
404 	/*    1234 12345 xxx.xxx.xxx.xxx xxx.xxx.xxx.xxx 12345 UNBOUND */
405 
406 	udp = (udp_t *)q->q_ptr;
407 	zoneid = udp->udp_zoneid;
408 
409 	for (i = 0; i < udp_bind_fanout_size; i++) {
410 		udpf = &udp_bind_fanout[i];
411 		mutex_enter(&udpf->uf_lock);
412 
413 		/* Print the hash index. */
414 		udp = udpf->uf_udp;
415 		if (zoneid != GLOBAL_ZONEID) {
416 			/* skip to first entry in this zone; might be none */
417 			while (udp != NULL &&
418 			    udp->udp_zoneid != zoneid)
419 				udp = udp->udp_bind_hash;
420 		}
421 		if (udp != NULL) {
422 			uint_t print_len, buf_len;
423 
424 			buf_len = mp->b_cont->b_datap->db_lim -
425 			    mp->b_cont->b_wptr;
426 			print_len = snprintf((char *)mp->b_cont->b_wptr,
427 			    buf_len, "%d\n", i);
428 			if (print_len < buf_len) {
429 				mp->b_cont->b_wptr += print_len;
430 			} else {
431 				mp->b_cont->b_wptr += buf_len;
432 			}
433 			for (; udp != NULL; udp = udp->udp_bind_hash) {
434 				if (zoneid == GLOBAL_ZONEID ||
435 				    zoneid == udp->udp_zoneid)
436 					udp_report_item(mp->b_cont, udp);
437 			}
438 		}
439 		mutex_exit(&udpf->uf_lock);
440 	}
441 	udp_last_ndd_get_info_time = ddi_get_lbolt();
442 	return (0);
443 }
444 
445 /*
446  * Hash list removal routine for udp_t structures.
447  */
448 static void
449 udp_bind_hash_remove(udp_t *udp, boolean_t caller_holds_lock)
450 {
451 	udp_t	*udpnext;
452 	kmutex_t *lockp;
453 
454 	if (udp->udp_ptpbhn == NULL)
455 		return;
456 
457 	/*
458 	 * Extract the lock pointer in case there are concurrent
459 	 * hash_remove's for this instance.
460 	 */
461 	ASSERT(udp->udp_port != 0);
462 	if (!caller_holds_lock) {
463 		lockp = &udp_bind_fanout[UDP_BIND_HASH(udp->udp_port)].uf_lock;
464 		ASSERT(lockp != NULL);
465 		mutex_enter(lockp);
466 	}
467 	if (udp->udp_ptpbhn != NULL) {
468 		udpnext = udp->udp_bind_hash;
469 		if (udpnext != NULL) {
470 			udpnext->udp_ptpbhn = udp->udp_ptpbhn;
471 			udp->udp_bind_hash = NULL;
472 		}
473 		*udp->udp_ptpbhn = udpnext;
474 		udp->udp_ptpbhn = NULL;
475 	}
476 	if (!caller_holds_lock) {
477 		mutex_exit(lockp);
478 	}
479 }
480 
481 static void
482 udp_bind_hash_insert(udp_fanout_t *uf, udp_t *udp)
483 {
484 	udp_t	**udpp;
485 	udp_t	*udpnext;
486 
487 	ASSERT(MUTEX_HELD(&uf->uf_lock));
488 	if (udp->udp_ptpbhn != NULL) {
489 		udp_bind_hash_remove(udp, B_TRUE);
490 	}
491 	udpp = &uf->uf_udp;
492 	udpnext = udpp[0];
493 	if (udpnext != NULL) {
494 		/*
495 		 * If the new udp bound to the INADDR_ANY address
496 		 * and the first one in the list is not bound to
497 		 * INADDR_ANY we skip all entries until we find the
498 		 * first one bound to INADDR_ANY.
499 		 * This makes sure that applications binding to a
500 		 * specific address get preference over those binding to
501 		 * INADDR_ANY.
502 		 */
503 		if (V6_OR_V4_INADDR_ANY(udp->udp_bound_v6src) &&
504 		    !V6_OR_V4_INADDR_ANY(udpnext->udp_bound_v6src)) {
505 			while ((udpnext = udpp[0]) != NULL &&
506 			    !V6_OR_V4_INADDR_ANY(
507 			    udpnext->udp_bound_v6src)) {
508 				udpp = &(udpnext->udp_bind_hash);
509 			}
510 			if (udpnext != NULL)
511 				udpnext->udp_ptpbhn = &udp->udp_bind_hash;
512 		} else {
513 			udpnext->udp_ptpbhn = &udp->udp_bind_hash;
514 		}
515 	}
516 	udp->udp_bind_hash = udpnext;
517 	udp->udp_ptpbhn = udpp;
518 	udpp[0] = udp;
519 }
520 
521 /*
522  * This routine is called to handle each O_T_BIND_REQ/T_BIND_REQ message
523  * passed to udp_wput.
524  * It associates a port number and local address with the stream.
525  * The O_T_BIND_REQ/T_BIND_REQ is passed downstream to ip with the UDP
526  * protocol type (IPPROTO_UDP) placed in the message following the address.
527  * A T_BIND_ACK message is passed upstream when ip acknowledges the request.
528  * (Called as writer.)
529  *
530  * Note that UDP over IPv4 and IPv6 sockets can use the same port number
531  * without setting SO_REUSEADDR. This is needed so that they
532  * can be viewed as two independent transport protocols.
533  * However, anonymouns ports are allocated from the same range to avoid
534  * duplicating the udp_g_next_port_to_try.
535  */
536 static void
537 udp_bind(queue_t *q, mblk_t *mp)
538 {
539 	sin_t		*sin;
540 	sin6_t		*sin6;
541 	mblk_t		*mp1;
542 	in_port_t	port;		/* Host byte order */
543 	in_port_t	requested_port;	/* Host byte order */
544 	struct T_bind_req *tbr;
545 	udp_t		*udp;
546 	int		count;
547 	in6_addr_t	v6src;
548 	boolean_t	bind_to_req_port_only;
549 	int		loopmax;
550 	udp_fanout_t	*udpf;
551 	in_port_t	lport;		/* Network byte order */
552 	zoneid_t	zoneid;
553 
554 	udp = (udp_t *)q->q_ptr;
555 	if ((mp->b_wptr - mp->b_rptr) < sizeof (*tbr)) {
556 		(void) mi_strlog(q, 1, SL_ERROR|SL_TRACE,
557 		    "udp_bind: bad req, len %u",
558 		    (uint_t)(mp->b_wptr - mp->b_rptr));
559 		udp_err_ack(q, mp, TPROTO, 0);
560 		return;
561 	}
562 	if (udp->udp_state != TS_UNBND) {
563 		(void) mi_strlog(q, 1, SL_ERROR|SL_TRACE,
564 		    "udp_bind: bad state, %u", udp->udp_state);
565 		udp_err_ack(q, mp, TOUTSTATE, 0);
566 		return;
567 	}
568 	/*
569 	 * Reallocate the message to make sure we have enough room for an
570 	 * address and the protocol type.
571 	 */
572 	mp1 = reallocb(mp, sizeof (struct T_bind_ack) + sizeof (sin6_t) + 1, 1);
573 	if (!mp1) {
574 		udp_err_ack(q, mp, TSYSERR, ENOMEM);
575 		return;
576 	}
577 
578 	mp = mp1;
579 	tbr = (struct T_bind_req *)mp->b_rptr;
580 	switch (tbr->ADDR_length) {
581 	case 0:			/* Request for a generic port */
582 		tbr->ADDR_offset = sizeof (struct T_bind_req);
583 		if (udp->udp_family == AF_INET) {
584 			tbr->ADDR_length = sizeof (sin_t);
585 			sin = (sin_t *)&tbr[1];
586 			*sin = sin_null;
587 			sin->sin_family = AF_INET;
588 			mp->b_wptr = (uchar_t *)&sin[1];
589 		} else {
590 			ASSERT(udp->udp_family == AF_INET6);
591 			tbr->ADDR_length = sizeof (sin6_t);
592 			sin6 = (sin6_t *)&tbr[1];
593 			*sin6 = sin6_null;
594 			sin6->sin6_family = AF_INET6;
595 			mp->b_wptr = (uchar_t *)&sin6[1];
596 		}
597 		port = 0;
598 		break;
599 
600 	case sizeof (sin_t):	/* Complete IPv4 address */
601 		sin = (sin_t *)mi_offset_param(mp, tbr->ADDR_offset,
602 		    sizeof (sin_t));
603 		if (sin == NULL || !OK_32PTR((char *)sin)) {
604 			udp_err_ack(q, mp, TSYSERR, EINVAL);
605 			return;
606 		}
607 		if (udp->udp_family != AF_INET ||
608 		    sin->sin_family != AF_INET) {
609 			udp_err_ack(q, mp, TSYSERR, EAFNOSUPPORT);
610 			return;
611 		}
612 		port = ntohs(sin->sin_port);
613 		break;
614 
615 	case sizeof (sin6_t):	/* complete IPv6 address */
616 		sin6 = (sin6_t *)mi_offset_param(mp, tbr->ADDR_offset,
617 		    sizeof (sin6_t));
618 		if (sin6 == NULL || !OK_32PTR((char *)sin6)) {
619 			udp_err_ack(q, mp, TSYSERR, EINVAL);
620 			return;
621 		}
622 		if (udp->udp_family != AF_INET6 ||
623 		    sin6->sin6_family != AF_INET6) {
624 			udp_err_ack(q, mp, TSYSERR, EAFNOSUPPORT);
625 			return;
626 		}
627 		port = ntohs(sin6->sin6_port);
628 		break;
629 
630 	default:		/* Invalid request */
631 		(void) mi_strlog(q, 1, SL_ERROR|SL_TRACE,
632 		    "udp_bind: bad ADDR_length length %u", tbr->ADDR_length);
633 		udp_err_ack(q, mp, TBADADDR, 0);
634 		return;
635 	}
636 
637 	requested_port = port;
638 
639 	if (requested_port == 0 || tbr->PRIM_type == O_T_BIND_REQ)
640 		bind_to_req_port_only = B_FALSE;
641 	else			/* T_BIND_REQ and requested_port != 0 */
642 		bind_to_req_port_only = B_TRUE;
643 
644 	if (requested_port == 0) {
645 		/*
646 		 * If the application passed in zero for the port number, it
647 		 * doesn't care which port number we bind to. Get one in the
648 		 * valid range.
649 		 */
650 		if (udp->udp_anon_priv_bind) {
651 			port = udp_get_next_priv_port();
652 		} else {
653 			port = udp_update_next_port(udp_g_next_port_to_try,
654 			    B_TRUE);
655 		}
656 	} else {
657 		/*
658 		 * If the port is in the well-known privileged range,
659 		 * make sure the caller was privileged.
660 		 */
661 		int i;
662 		boolean_t priv = B_FALSE;
663 
664 		if (port < udp_smallest_nonpriv_port) {
665 			priv = B_TRUE;
666 		} else {
667 			for (i = 0; i < udp_g_num_epriv_ports; i++) {
668 				if (port == udp_g_epriv_ports[i]) {
669 					priv = B_TRUE;
670 					break;
671 				}
672 			}
673 		}
674 
675 		if (priv) {
676 			cred_t *cr = DB_CREDDEF(mp, udp->udp_credp);
677 
678 			if (secpolicy_net_privaddr(cr, port) != 0) {
679 				udp_err_ack(q, mp, TACCES, 0);
680 				return;
681 			}
682 		}
683 	}
684 
685 	/*
686 	 * Copy the source address into our udp structure. This address
687 	 * may still be zero; if so, IP will fill in the correct address
688 	 * each time an outbound packet is passed to it.
689 	 */
690 	if (udp->udp_family == AF_INET) {
691 		ASSERT(sin != NULL);
692 		ASSERT(udp->udp_ipversion == IPV4_VERSION);
693 		udp->udp_max_hdr_len = IP_SIMPLE_HDR_LENGTH + UDPH_SIZE +
694 		    udp->udp_ip_snd_options_len;
695 		IN6_IPADDR_TO_V4MAPPED(sin->sin_addr.s_addr, &v6src);
696 	} else {
697 		ASSERT(sin6 != NULL);
698 		v6src = sin6->sin6_addr;
699 		if (IN6_IS_ADDR_V4MAPPED(&v6src)) {
700 			udp->udp_ipversion = IPV4_VERSION;
701 			udp->udp_max_hdr_len = IP_SIMPLE_HDR_LENGTH +
702 			    UDPH_SIZE + udp->udp_ip_snd_options_len;
703 		} else {
704 			udp->udp_ipversion = IPV6_VERSION;
705 			udp->udp_max_hdr_len = udp->udp_sticky_hdrs_len;
706 		}
707 	}
708 
709 	/*
710 	 * If udp_reuseaddr is not set, then we have to make sure that
711 	 * the IP address and port number the application requested
712 	 * (or we selected for the application) is not being used by
713 	 * another stream.  If another stream is already using the
714 	 * requested IP address and port, the behavior depends on
715 	 * "bind_to_req_port_only". If set the bind fails; otherwise we
716 	 * search for any an unused port to bind to the the stream.
717 	 *
718 	 * As per the BSD semantics, as modified by the Deering multicast
719 	 * changes, if udp_reuseaddr is set, then we allow multiple binds
720 	 * to the same port independent of the local IP address.
721 	 *
722 	 * This is slightly different than in SunOS 4.X which did not
723 	 * support IP multicast. Note that the change implemented by the
724 	 * Deering multicast code effects all binds - not only binding
725 	 * to IP multicast addresses.
726 	 *
727 	 * Note that when binding to port zero we ignore SO_REUSEADDR in
728 	 * order to guarantee a unique port.
729 	 */
730 
731 	count = 0;
732 	if (udp->udp_anon_priv_bind) {
733 		/* loopmax = (IPPORT_RESERVED-1) - udp_min_anonpriv_port + 1 */
734 		loopmax = IPPORT_RESERVED - udp_min_anonpriv_port;
735 	} else {
736 		loopmax = udp_largest_anon_port - udp_smallest_anon_port + 1;
737 	}
738 
739 	zoneid = udp->udp_zoneid;
740 	for (;;) {
741 		udp_t		*udp1;
742 		boolean_t	is_inaddr_any;
743 		boolean_t	found_exclbind = B_FALSE;
744 
745 		is_inaddr_any = V6_OR_V4_INADDR_ANY(v6src);
746 		/*
747 		 * Walk through the list of udp streams bound to
748 		 * requested port with the same IP address.
749 		 */
750 		lport = htons(port);
751 		udpf = &udp_bind_fanout[UDP_BIND_HASH(lport)];
752 		mutex_enter(&udpf->uf_lock);
753 		for (udp1 = udpf->uf_udp; udp1 != NULL;
754 		    udp1 = udp1->udp_bind_hash) {
755 			if (lport != udp1->udp_port ||
756 			    zoneid != udp1->udp_zoneid)
757 				continue;
758 
759 			/*
760 			 * If UDP_EXCLBIND is set for either the bound or
761 			 * binding endpoint, the semantics of bind
762 			 * is changed according to the following chart.
763 			 *
764 			 * spec = specified address (v4 or v6)
765 			 * unspec = unspecified address (v4 or v6)
766 			 * A = specified addresses are different for endpoints
767 			 *
768 			 * bound	bind to		allowed?
769 			 * -------------------------------------
770 			 * unspec	unspec		no
771 			 * unspec	spec		no
772 			 * spec		unspec		no
773 			 * spec		spec		yes if A
774 			 */
775 			if (udp1->udp_exclbind || udp->udp_exclbind) {
776 				if (V6_OR_V4_INADDR_ANY(
777 				    udp1->udp_bound_v6src) ||
778 				    is_inaddr_any ||
779 				    IN6_ARE_ADDR_EQUAL(&udp1->udp_bound_v6src,
780 				    &v6src)) {
781 					found_exclbind = B_TRUE;
782 					break;
783 				}
784 				continue;
785 			}
786 
787 			/*
788 			 * Check ipversion to allow IPv4 and IPv6 sockets to
789 			 * have disjoint port number spaces.
790 			 */
791 			if (udp->udp_ipversion != udp1->udp_ipversion)
792 				continue;
793 
794 			/*
795 			 * No difference depending on SO_REUSEADDR.
796 			 *
797 			 * If existing port is bound to a
798 			 * non-wildcard IP address and
799 			 * the requesting stream is bound to
800 			 * a distinct different IP addresses
801 			 * (non-wildcard, also), keep going.
802 			 */
803 			if (!is_inaddr_any &&
804 			    !V6_OR_V4_INADDR_ANY(udp1->udp_bound_v6src) &&
805 			    !IN6_ARE_ADDR_EQUAL(&udp1->udp_bound_v6src,
806 			    &v6src)) {
807 				continue;
808 			}
809 			break;
810 		}
811 
812 		if (!found_exclbind &&
813 		    (udp->udp_reuseaddr && requested_port != 0)) {
814 			break;
815 		}
816 
817 		if (udp1 == NULL) {
818 			/*
819 			 * No other stream has this IP address
820 			 * and port number. We can use it.
821 			 */
822 			break;
823 		}
824 		mutex_exit(&udpf->uf_lock);
825 		if (bind_to_req_port_only) {
826 			/*
827 			 * We get here only when requested port
828 			 * is bound (and only first  of the for()
829 			 * loop iteration).
830 			 *
831 			 * The semantics of this bind request
832 			 * require it to fail so we return from
833 			 * the routine (and exit the loop).
834 			 *
835 			 */
836 			udp_err_ack(q, mp, TADDRBUSY, 0);
837 			return;
838 		}
839 
840 		if (udp->udp_anon_priv_bind) {
841 			port = udp_get_next_priv_port();
842 		} else {
843 			if ((count == 0) && (requested_port != 0)) {
844 				/*
845 				 * If the application wants us to find
846 				 * a port, get one to start with. Set
847 				 * requested_port to 0, so that we will
848 				 * update udp_g_next_port_to_try below.
849 				 */
850 				port = udp_update_next_port(
851 				    udp_g_next_port_to_try, B_TRUE);
852 				requested_port = 0;
853 			} else {
854 				port = udp_update_next_port(port + 1, B_FALSE);
855 			}
856 		}
857 
858 		if (++count >= loopmax) {
859 			/*
860 			 * We've tried every possible port number and
861 			 * there are none available, so send an error
862 			 * to the user.
863 			 */
864 			udp_err_ack(q, mp, TNOADDR, 0);
865 			return;
866 		}
867 	}
868 
869 	/*
870 	 * Copy the source address into our udp structure.  This address
871 	 * may still be zero; if so, ip will fill in the correct address
872 	 * each time an outbound packet is passed to it.
873 	 * If we are binding to a broadcast or multicast address udp_rput
874 	 * will clear the source address when it receives the T_BIND_ACK.
875 	 */
876 	udp->udp_v6src = udp->udp_bound_v6src = v6src;
877 	udp->udp_port = lport;
878 	/*
879 	 * Now reset the the next anonymous port if the application requested
880 	 * an anonymous port, or we handed out the next anonymous port.
881 	 */
882 	if ((requested_port == 0) && (!udp->udp_anon_priv_bind)) {
883 		udp_g_next_port_to_try = port + 1;
884 	}
885 
886 	/* Initialize the O_T_BIND_REQ/T_BIND_REQ for ip. */
887 	if (udp->udp_family == AF_INET) {
888 		sin->sin_port = udp->udp_port;
889 	} else {
890 		int error;
891 
892 		sin6->sin6_port = udp->udp_port;
893 		/* Rebuild the header template */
894 		error = udp_build_hdrs(q, udp);
895 		if (error != 0) {
896 			mutex_exit(&udpf->uf_lock);
897 			udp_err_ack(q, mp, TSYSERR, error);
898 			return;
899 		}
900 	}
901 	udp->udp_state = TS_IDLE;
902 	udp_bind_hash_insert(udpf, udp);
903 	mutex_exit(&udpf->uf_lock);
904 
905 	if (cl_inet_bind) {
906 		/*
907 		 * Running in cluster mode - register bind information
908 		 */
909 		if (udp->udp_ipversion == IPV4_VERSION) {
910 			(*cl_inet_bind)(IPPROTO_UDP, AF_INET,
911 			    (uint8_t *)(&V4_PART_OF_V6(udp->udp_v6src)),
912 			    (in_port_t)udp->udp_port);
913 		} else {
914 			(*cl_inet_bind)(IPPROTO_UDP, AF_INET6,
915 			    (uint8_t *)&(udp->udp_v6src),
916 			    (in_port_t)udp->udp_port);
917 		}
918 
919 	}
920 
921 	/* Pass the protocol number in the message following the address. */
922 	*mp->b_wptr++ = IPPROTO_UDP;
923 	if (!V6_OR_V4_INADDR_ANY(udp->udp_v6src)) {
924 		/*
925 		 * Append a request for an IRE if udp_v6src not
926 		 * zero (IPv4 - INADDR_ANY, or IPv6 - all-zeroes address).
927 		 */
928 		mp->b_cont = allocb(sizeof (ire_t), BPRI_HI);
929 		if (!mp->b_cont) {
930 			udp_err_ack(q, mp, TSYSERR, ENOMEM);
931 			return;
932 		}
933 		mp->b_cont->b_wptr += sizeof (ire_t);
934 		mp->b_cont->b_datap->db_type = IRE_DB_REQ_TYPE;
935 	}
936 	putnext(q, mp);
937 }
938 
939 /*
940  * This routine handles each T_CONN_REQ message passed to udp.  It
941  * associates a default destination address with the stream.
942  *
943  * This routine sends down a T_BIND_REQ to IP with the following mblks:
944  *	T_BIND_REQ	- specifying local and remote address/port
945  *	IRE_DB_REQ_TYPE	- to get an IRE back containing ire_type and src
946  *	T_OK_ACK	- for the T_CONN_REQ
947  *	T_CONN_CON	- to keep the TPI user happy
948  *
949  * The connect completes in udp_rput.
950  * When a T_BIND_ACK is received information is extracted from the IRE
951  * and the two appended messages are sent to the TPI user.
952  * Should udp_rput receive T_ERROR_ACK for the T_BIND_REQ it will convert
953  * it to an error ack for the appropriate primitive.
954  */
955 static void
956 udp_connect(queue_t *q, mblk_t *mp)
957 {
958 	sin6_t	*sin6;
959 	sin_t	*sin;
960 	struct T_conn_req	*tcr;
961 	udp_t	*udp, *udp1;
962 	in6_addr_t v6dst;
963 	ipaddr_t v4dst;
964 	uint16_t dstport;
965 	uint32_t flowinfo;
966 	mblk_t	*mp1, *mp2;
967 	udp_fanout_t	*udpf;
968 
969 	udp = (udp_t *)q->q_ptr;
970 	tcr = (struct T_conn_req *)mp->b_rptr;
971 
972 	/* A bit of sanity checking */
973 	if ((mp->b_wptr - mp->b_rptr) < sizeof (struct T_conn_req)) {
974 		udp_err_ack(q, mp, TPROTO, 0);
975 		return;
976 	}
977 	/*
978 	 * This UDP must have bound to a port already before doing
979 	 * a connect.
980 	 */
981 	if (udp->udp_state == TS_UNBND) {
982 		(void) mi_strlog(q, 1, SL_ERROR|SL_TRACE,
983 		    "udp_connect: bad state, %u", udp->udp_state);
984 		udp_err_ack(q, mp, TOUTSTATE, 0);
985 		return;
986 	}
987 	ASSERT(udp->udp_port != 0 && udp->udp_ptpbhn != NULL);
988 
989 	udpf = &udp_bind_fanout[UDP_BIND_HASH(udp->udp_port)];
990 	if (udp->udp_state == TS_DATA_XFER) {
991 		/* Already connected - clear out state */
992 		mutex_enter(&udpf->uf_lock);
993 		udp->udp_v6src = udp->udp_bound_v6src;
994 		udp->udp_state = TS_IDLE;
995 		mutex_exit(&udpf->uf_lock);
996 	}
997 
998 	if (tcr->OPT_length != 0) {
999 		udp_err_ack(q, mp, TBADOPT, 0);
1000 		return;
1001 	}
1002 
1003 	/*
1004 	 * Determine packet type based on type of address passed in
1005 	 * the request should contain an IPv4 or IPv6 address.
1006 	 * Make sure that address family matches the type of
1007 	 * family of the the address passed down
1008 	 */
1009 	switch (tcr->DEST_length) {
1010 	default:
1011 		udp_err_ack(q, mp, TBADADDR, 0);
1012 		return;
1013 
1014 	case sizeof (sin_t):
1015 		sin = (sin_t *)mi_offset_param(mp, tcr->DEST_offset,
1016 		    sizeof (sin_t));
1017 		if (sin == NULL || !OK_32PTR((char *)sin)) {
1018 			udp_err_ack(q, mp, TSYSERR, EINVAL);
1019 			return;
1020 		}
1021 		if (udp->udp_family != AF_INET ||
1022 		    sin->sin_family != AF_INET) {
1023 			udp_err_ack(q, mp, TSYSERR, EAFNOSUPPORT);
1024 			return;
1025 		}
1026 		v4dst = sin->sin_addr.s_addr;
1027 		dstport = sin->sin_port;
1028 		IN6_IPADDR_TO_V4MAPPED(v4dst, &v6dst);
1029 		ASSERT(udp->udp_ipversion == IPV4_VERSION);
1030 		udp->udp_max_hdr_len = IP_SIMPLE_HDR_LENGTH + UDPH_SIZE +
1031 		    udp->udp_ip_snd_options_len;
1032 		break;
1033 
1034 	case sizeof (sin6_t):
1035 		sin6 = (sin6_t *)mi_offset_param(mp, tcr->DEST_offset,
1036 		    sizeof (sin6_t));
1037 		if (sin6 == NULL || !OK_32PTR((char *)sin6)) {
1038 			udp_err_ack(q, mp, TSYSERR, EINVAL);
1039 			return;
1040 		}
1041 		if (udp->udp_family != AF_INET6 ||
1042 		    sin6->sin6_family != AF_INET6) {
1043 			udp_err_ack(q, mp, TSYSERR, EAFNOSUPPORT);
1044 			return;
1045 		}
1046 		v6dst = sin6->sin6_addr;
1047 		if (IN6_IS_ADDR_V4MAPPED(&v6dst)) {
1048 			IN6_V4MAPPED_TO_IPADDR(&v6dst, v4dst);
1049 			udp->udp_ipversion = IPV4_VERSION;
1050 			udp->udp_max_hdr_len = IP_SIMPLE_HDR_LENGTH +
1051 			    UDPH_SIZE + udp->udp_ip_snd_options_len;
1052 			flowinfo = 0;
1053 		} else {
1054 			udp->udp_ipversion = IPV6_VERSION;
1055 			udp->udp_max_hdr_len = udp->udp_sticky_hdrs_len;
1056 			flowinfo = sin6->sin6_flowinfo;
1057 		}
1058 		dstport = sin6->sin6_port;
1059 		break;
1060 	}
1061 	if (dstport == 0) {
1062 		udp_err_ack(q, mp, TBADADDR, 0);
1063 		return;
1064 	}
1065 
1066 	/*
1067 	 * Create a default IP header with no IP options.
1068 	 */
1069 	udp->udp_dstport = dstport;
1070 	if (udp->udp_ipversion == IPV4_VERSION) {
1071 		/*
1072 		 * Interpret a zero destination to mean loopback.
1073 		 * Update the T_CONN_REQ (sin/sin6) since it is used to
1074 		 * generate the T_CONN_CON.
1075 		 */
1076 		if (v4dst == INADDR_ANY) {
1077 			v4dst = htonl(INADDR_LOOPBACK);
1078 			IN6_IPADDR_TO_V4MAPPED(v4dst, &v6dst);
1079 			if (udp->udp_family == AF_INET) {
1080 				sin->sin_addr.s_addr = v4dst;
1081 			} else {
1082 				sin6->sin6_addr = v6dst;
1083 			}
1084 		}
1085 		udp->udp_v6dst = v6dst;
1086 		udp->udp_flowinfo = 0;
1087 
1088 		/*
1089 		 * If the destination address is multicast and
1090 		 * an outgoing multicast interface has been set,
1091 		 * use the address of that interface as our
1092 		 * source address if no source address has been set.
1093 		 */
1094 		if (V4_PART_OF_V6(udp->udp_v6src) == INADDR_ANY &&
1095 		    CLASSD(v4dst) &&
1096 		    udp->udp_multicast_if_addr != INADDR_ANY) {
1097 			IN6_IPADDR_TO_V4MAPPED(udp->udp_multicast_if_addr,
1098 			    &udp->udp_v6src);
1099 		}
1100 	} else {
1101 		ASSERT(udp->udp_ipversion == IPV6_VERSION);
1102 		/*
1103 		 * Interpret a zero destination to mean loopback.
1104 		 * Update the T_CONN_REQ (sin/sin6) since it is used to
1105 		 * generate the T_CONN_CON.
1106 		 */
1107 		if (IN6_IS_ADDR_UNSPECIFIED(&v6dst)) {
1108 			v6dst = ipv6_loopback;
1109 			sin6->sin6_addr = v6dst;
1110 		}
1111 		udp->udp_v6dst = v6dst;
1112 		udp->udp_flowinfo = flowinfo;
1113 		/*
1114 		 * If the destination address is multicast and
1115 		 * an outgoing multicast interface has been set,
1116 		 * then the ip bind logic will pick the correct source
1117 		 * address (i.e. matching the outgoing multicast interface).
1118 		 */
1119 	}
1120 
1121 	/*
1122 	 * Verify that the src/port/dst/port is unique for all
1123 	 * connections in TS_DATA_XFER
1124 	 */
1125 	mutex_enter(&udpf->uf_lock);
1126 	for (udp1 = udpf->uf_udp; udp1 != NULL; udp1 = udp1->udp_bind_hash) {
1127 		if (udp1->udp_state != TS_DATA_XFER)
1128 			continue;
1129 		if (udp->udp_port != udp1->udp_port ||
1130 		    udp->udp_ipversion != udp1->udp_ipversion ||
1131 		    dstport != udp1->udp_dstport ||
1132 		    !IN6_ARE_ADDR_EQUAL(&udp->udp_v6src, &udp1->udp_v6src) ||
1133 		    !IN6_ARE_ADDR_EQUAL(&v6dst, &udp1->udp_v6dst))
1134 			continue;
1135 		mutex_exit(&udpf->uf_lock);
1136 		udp_err_ack(q, mp, TBADADDR, 0);
1137 		return;
1138 	}
1139 	udp->udp_state = TS_DATA_XFER;
1140 	mutex_exit(&udpf->uf_lock);
1141 
1142 	/*
1143 	 * Send down bind to IP to verify that there is a route
1144 	 * and to determine the source address.
1145 	 * This will come back as T_BIND_ACK with an IRE_DB_TYPE in rput.
1146 	 */
1147 	if (udp->udp_family == AF_INET)
1148 		mp1 = udp_ip_bind_mp(udp, O_T_BIND_REQ, sizeof (ipa_conn_t));
1149 	else
1150 		mp1 = udp_ip_bind_mp(udp, O_T_BIND_REQ, sizeof (ipa6_conn_t));
1151 	if (mp1 == NULL) {
1152 		udp_err_ack(q, mp, TSYSERR, ENOMEM);
1153 bind_failed:
1154 		mutex_enter(&udpf->uf_lock);
1155 		udp->udp_state = TS_IDLE;
1156 		mutex_exit(&udpf->uf_lock);
1157 		return;
1158 	}
1159 
1160 	/*
1161 	 * We also have to send a connection confirmation to
1162 	 * keep TLI happy. Prepare it for udp_rput.
1163 	 */
1164 	if (udp->udp_family == AF_INET)
1165 		mp2 = mi_tpi_conn_con(NULL, (char *)sin,
1166 		    sizeof (*sin), NULL, 0);
1167 	else
1168 		mp2 = mi_tpi_conn_con(NULL, (char *)sin6,
1169 		    sizeof (*sin6), NULL, 0);
1170 	if (mp2 == NULL) {
1171 		freemsg(mp1);
1172 		udp_err_ack(q, mp, TSYSERR, ENOMEM);
1173 		goto bind_failed;
1174 	}
1175 
1176 	mp = mi_tpi_ok_ack_alloc(mp);
1177 	if (mp == NULL) {
1178 		/* Unable to reuse the T_CONN_REQ for the ack. */
1179 		freemsg(mp2);
1180 		udp_err_ack_prim(q, mp1, T_CONN_REQ, TSYSERR, ENOMEM);
1181 		goto bind_failed;
1182 	}
1183 
1184 	/* Hang onto the T_OK_ACK and T_CONN_CON for later. */
1185 	linkb(mp1, mp);
1186 	linkb(mp1, mp2);
1187 
1188 	putnext(q, mp1);
1189 }
1190 
1191 /* This is the close routine for udp.  It frees the per-stream data. */
1192 static int
1193 udp_close(queue_t *q)
1194 {
1195 	udp_t	*udp = (udp_t *)q->q_ptr;
1196 
1197 	TRACE_1(TR_FAC_UDP, TR_UDP_CLOSE,
1198 		"udp_close: q %p", q);
1199 
1200 	qprocsoff(q);
1201 
1202 	if (cl_inet_unbind != NULL && udp->udp_state == TS_IDLE) {
1203 		/*
1204 		 * Running in cluster mode - register unbind information
1205 		 */
1206 		if (udp->udp_ipversion == IPV4_VERSION) {
1207 			(*cl_inet_unbind)(IPPROTO_UDP, AF_INET,
1208 			    (uint8_t *)(&(V4_PART_OF_V6(udp->udp_v6src))),
1209 			    (in_port_t)udp->udp_port);
1210 		} else {
1211 			(*cl_inet_unbind)(IPPROTO_UDP, AF_INET6,
1212 			    (uint8_t *)(&(udp->udp_v6src)),
1213 			    (in_port_t)udp->udp_port);
1214 		}
1215 	}
1216 
1217 	udp_bind_hash_remove(udp, B_FALSE);
1218 	mutex_enter(&udp_g_lock);
1219 	/* Unlink the udp structure and release the minor device number. */
1220 	mi_close_unlink(&udp_g_head, (IDP)udp);
1221 	mutex_exit(&udp_g_lock);
1222 	/* If there are any options associated with the stream, free them. */
1223 	if (udp->udp_ip_snd_options)
1224 		mi_free((char *)udp->udp_ip_snd_options);
1225 
1226 	if (udp->udp_ip_rcv_options)
1227 		mi_free((char *)udp->udp_ip_rcv_options);
1228 
1229 	/* Free memory associated with sticky options */
1230 	if (udp->udp_sticky_hdrs_len != 0) {
1231 		kmem_free(udp->udp_sticky_hdrs,
1232 		    udp->udp_sticky_hdrs_len);
1233 		udp->udp_sticky_hdrs = NULL;
1234 		udp->udp_sticky_hdrs_len = 0;
1235 	}
1236 	if (udp->udp_sticky_ipp.ipp_fields & IPPF_HOPOPTS) {
1237 		kmem_free(udp->udp_sticky_ipp.ipp_hopopts,
1238 		    udp->udp_sticky_ipp.ipp_hopoptslen);
1239 	}
1240 	if (udp->udp_sticky_ipp.ipp_fields & IPPF_RTDSTOPTS) {
1241 		kmem_free(udp->udp_sticky_ipp.ipp_rtdstopts,
1242 		    udp->udp_sticky_ipp.ipp_rtdstoptslen);
1243 	}
1244 	if (udp->udp_sticky_ipp.ipp_fields & IPPF_RTHDR) {
1245 		kmem_free(udp->udp_sticky_ipp.ipp_rthdr,
1246 		    udp->udp_sticky_ipp.ipp_rthdrlen);
1247 	}
1248 	if (udp->udp_sticky_ipp.ipp_fields & IPPF_DSTOPTS) {
1249 		kmem_free(udp->udp_sticky_ipp.ipp_dstopts,
1250 		    udp->udp_sticky_ipp.ipp_dstoptslen);
1251 	}
1252 	udp->udp_sticky_ipp.ipp_fields &=
1253 	    ~(IPPF_HOPOPTS|IPPF_RTDSTOPTS|IPPF_RTHDR|IPPF_DSTOPTS);
1254 
1255 	crfree(udp->udp_credp);
1256 	/* Free the data structure */
1257 	mi_close_free((IDP)udp);
1258 	q->q_ptr = WR(q)->q_ptr = NULL;
1259 	return (0);
1260 }
1261 
1262 /*
1263  * This routine handles each T_DISCON_REQ message passed to udp
1264  * as an indicating that UDP is no longer connected. This results
1265  * in sending a T_BIND_REQ to IP to restore the binding to just
1266  * the local address/port.
1267  *
1268  * This routine sends down a T_BIND_REQ to IP with the following mblks:
1269  *	T_BIND_REQ	- specifying just the local address/port
1270  *	T_OK_ACK	- for the T_DISCON_REQ
1271  *
1272  * The disconnect completes in udp_rput.
1273  * When a T_BIND_ACK is received the appended T_OK_ACK is sent to the TPI user.
1274  * Should udp_rput receive T_ERROR_ACK for the T_BIND_REQ it will convert
1275  * it to an error ack for the appropriate primitive.
1276  */
1277 static void
1278 udp_disconnect(queue_t *q, mblk_t *mp)
1279 {
1280 	udp_t	*udp;
1281 	mblk_t	*mp1;
1282 	udp_fanout_t *udpf;
1283 
1284 	udp = (udp_t *)q->q_ptr;
1285 
1286 	if (udp->udp_state != TS_DATA_XFER) {
1287 		(void) mi_strlog(q, 1, SL_ERROR|SL_TRACE,
1288 		    "udp_disconnect: bad state, %u", udp->udp_state);
1289 		udp_err_ack(q, mp, TOUTSTATE, 0);
1290 		return;
1291 	}
1292 	udpf = &udp_bind_fanout[UDP_BIND_HASH(udp->udp_port)];
1293 	mutex_enter(&udpf->uf_lock);
1294 	udp->udp_v6src = udp->udp_bound_v6src;
1295 	udp->udp_state = TS_IDLE;
1296 	mutex_exit(&udpf->uf_lock);
1297 
1298 	/*
1299 	 * Send down bind to IP to remove the full binding and revert
1300 	 * to the local address binding.
1301 	 */
1302 	if (udp->udp_family == AF_INET)
1303 		mp1 = udp_ip_bind_mp(udp, O_T_BIND_REQ, sizeof (sin_t));
1304 	else
1305 		mp1 = udp_ip_bind_mp(udp, O_T_BIND_REQ, sizeof (sin6_t));
1306 	if (mp1 == NULL) {
1307 		udp_err_ack(q, mp, TSYSERR, ENOMEM);
1308 		return;
1309 	}
1310 	mp = mi_tpi_ok_ack_alloc(mp);
1311 	if (mp == NULL) {
1312 		/* Unable to reuse the T_DISCON_REQ for the ack. */
1313 		udp_err_ack_prim(q, mp1, T_DISCON_REQ, TSYSERR, ENOMEM);
1314 		return;
1315 	}
1316 
1317 	if (udp->udp_family == AF_INET6) {
1318 		int error;
1319 
1320 		/* Rebuild the header template */
1321 		error = udp_build_hdrs(q, udp);
1322 		if (error != 0) {
1323 			udp_err_ack_prim(q, mp, T_DISCON_REQ, TSYSERR, error);
1324 			freemsg(mp1);
1325 			return;
1326 		}
1327 	}
1328 	mutex_enter(&udpf->uf_lock);
1329 	udp->udp_discon_pending = 1;
1330 	mutex_exit(&udpf->uf_lock);
1331 
1332 	/* Append the T_OK_ACK to the T_BIND_REQ for udp_rput */
1333 	linkb(mp1, mp);
1334 	putnext(q, mp1);
1335 }
1336 
1337 /* This routine creates a T_ERROR_ACK message and passes it upstream. */
1338 static void
1339 udp_err_ack(queue_t *q, mblk_t *mp, t_scalar_t t_error, int sys_error)
1340 {
1341 	if ((mp = mi_tpi_err_ack_alloc(mp, t_error, sys_error)) != NULL)
1342 		qreply(q, mp);
1343 }
1344 
1345 /* Shorthand to generate and send TPI error acks to our client */
1346 static void
1347 udp_err_ack_prim(queue_t *q, mblk_t *mp, int primitive, t_scalar_t t_error,
1348     int sys_error)
1349 {
1350 	struct T_error_ack	*teackp;
1351 
1352 	if ((mp = tpi_ack_alloc(mp, sizeof (struct T_error_ack),
1353 	    M_PCPROTO, T_ERROR_ACK)) != NULL) {
1354 		teackp = (struct T_error_ack *)mp->b_rptr;
1355 		teackp->ERROR_prim = primitive;
1356 		teackp->TLI_error = t_error;
1357 		teackp->UNIX_error = sys_error;
1358 		qreply(q, mp);
1359 	}
1360 }
1361 
1362 /*ARGSUSED*/
1363 static int
1364 udp_extra_priv_ports_get(queue_t *q, mblk_t *mp, caddr_t cp, cred_t *cr)
1365 {
1366 	int i;
1367 
1368 	for (i = 0; i < udp_g_num_epriv_ports; i++) {
1369 		if (udp_g_epriv_ports[i] != 0)
1370 			(void) mi_mpprintf(mp, "%d ", udp_g_epriv_ports[i]);
1371 	}
1372 	return (0);
1373 }
1374 
1375 /*
1376  * Hold udp_g_lock to prevent multiple threads from changing udp_g_epriv_ports
1377  * at the same time.
1378  */
1379 /* ARGSUSED */
1380 static int
1381 udp_extra_priv_ports_add(queue_t *q, mblk_t *mp, char *value, caddr_t cp,
1382     cred_t *cr)
1383 {
1384 	long	new_value;
1385 	int	i;
1386 
1387 	/*
1388 	 * Fail the request if the new value does not lie within the
1389 	 * port number limits.
1390 	 */
1391 	if (ddi_strtol(value, NULL, 10, &new_value) != 0 ||
1392 	    new_value <= 0 || new_value >= 65536) {
1393 		return (EINVAL);
1394 	}
1395 
1396 	mutex_enter(&udp_g_lock);
1397 	/* Check if the value is already in the list */
1398 	for (i = 0; i < udp_g_num_epriv_ports; i++) {
1399 		if (new_value == udp_g_epriv_ports[i]) {
1400 			mutex_exit(&udp_g_lock);
1401 			return (EEXIST);
1402 		}
1403 	}
1404 	/* Find an empty slot */
1405 	for (i = 0; i < udp_g_num_epriv_ports; i++) {
1406 		if (udp_g_epriv_ports[i] == 0)
1407 			break;
1408 	}
1409 	if (i == udp_g_num_epriv_ports) {
1410 		mutex_exit(&udp_g_lock);
1411 		return (EOVERFLOW);
1412 	}
1413 
1414 	/* Set the new value */
1415 	udp_g_epriv_ports[i] = (in_port_t)new_value;
1416 	mutex_exit(&udp_g_lock);
1417 	return (0);
1418 }
1419 
1420 /*
1421  * Hold udp_g_lock to prevent multiple threads from changing udp_g_epriv_ports
1422  * at the same time.
1423  */
1424 /* ARGSUSED */
1425 static int
1426 udp_extra_priv_ports_del(queue_t *q, mblk_t *mp, char *value, caddr_t cp,
1427     cred_t *cr)
1428 {
1429 	long	new_value;
1430 	int	i;
1431 
1432 	/*
1433 	 * Fail the request if the new value does not lie within the
1434 	 * port number limits.
1435 	 */
1436 	if (ddi_strtol(value, NULL, 10, &new_value) != 0 ||
1437 	    new_value <= 0 || new_value >= 65536) {
1438 		return (EINVAL);
1439 	}
1440 
1441 	mutex_enter(&udp_g_lock);
1442 	/* Check that the value is already in the list */
1443 	for (i = 0; i < udp_g_num_epriv_ports; i++) {
1444 		if (udp_g_epriv_ports[i] == new_value)
1445 			break;
1446 	}
1447 	if (i == udp_g_num_epriv_ports) {
1448 		mutex_exit(&udp_g_lock);
1449 		return (ESRCH);
1450 	}
1451 
1452 	/* Clear the value */
1453 	udp_g_epriv_ports[i] = 0;
1454 	mutex_exit(&udp_g_lock);
1455 	return (0);
1456 }
1457 
1458 /* At minimum we need 4 bytes of UDP header */
1459 #define	ICMP_MIN_UDP_HDR	4
1460 
1461 /*
1462  * udp_icmp_error is called by udp_rput to process ICMP msgs. passed up by IP.
1463  * Generates the appropriate T_UDERROR_IND for permanent (non-transient) errors.
1464  * Assumes that IP has pulled up everything up to and including the ICMP header.
1465  * An M_CTL could potentially come here from some other module (i.e. if UDP
1466  * is pushed on some module other than IP). Thus, if we find that the M_CTL
1467  * does not have enough ICMP information , following STREAMS conventions,
1468  * we send it upstream assuming it is an M_CTL we don't understand.
1469  */
1470 static void
1471 udp_icmp_error(queue_t *q, mblk_t *mp)
1472 {
1473 	icmph_t *icmph;
1474 	ipha_t	*ipha;
1475 	int	iph_hdr_length;
1476 	udpha_t	*udpha;
1477 	sin_t	sin;
1478 	sin6_t	sin6;
1479 	mblk_t	*mp1;
1480 	int	error = 0;
1481 	udp_t	*udp = (udp_t *)q->q_ptr;
1482 	size_t	mp_size = MBLKL(mp);
1483 
1484 	/*
1485 	 * Assume IP provides aligned packets - otherwise toss
1486 	 */
1487 	if (!OK_32PTR(mp->b_rptr)) {
1488 		freemsg(mp);
1489 		return;
1490 	}
1491 
1492 	/*
1493 	 * Verify that we have a complete IP header and the application has
1494 	 * asked for errors. If not, send it upstream.
1495 	 */
1496 	if (!udp->udp_dgram_errind || mp_size < sizeof (ipha_t)) {
1497 noticmpv4:
1498 		putnext(q, mp);
1499 		return;
1500 	}
1501 
1502 	ipha = (ipha_t *)mp->b_rptr;
1503 	/*
1504 	 * Verify IP version. Anything other than IPv4 or IPv6 packet is sent
1505 	 * upstream. ICMPv6  is handled in udp_icmp_error_ipv6.
1506 	 */
1507 	switch (IPH_HDR_VERSION(ipha)) {
1508 	case IPV6_VERSION:
1509 		udp_icmp_error_ipv6(q, mp);
1510 		return;
1511 	case IPV4_VERSION:
1512 		break;
1513 	default:
1514 		goto noticmpv4;
1515 	}
1516 
1517 	/* Skip past the outer IP and ICMP headers */
1518 	iph_hdr_length = IPH_HDR_LENGTH(ipha);
1519 	icmph = (icmph_t *)&mp->b_rptr[iph_hdr_length];
1520 	/*
1521 	 * If we don't have the correct outer IP header length or if the ULP
1522 	 * is not IPPROTO_ICMP or if we don't have a complete inner IP header
1523 	 * send the packet upstream.
1524 	 */
1525 	if (iph_hdr_length < sizeof (ipha_t) ||
1526 	    ipha->ipha_protocol != IPPROTO_ICMP ||
1527 	    (ipha_t *)&icmph[1] + 1 > (ipha_t *)mp->b_wptr) {
1528 		goto noticmpv4;
1529 	}
1530 	ipha = (ipha_t *)&icmph[1];
1531 
1532 	/* Skip past the inner IP and find the ULP header */
1533 	iph_hdr_length = IPH_HDR_LENGTH(ipha);
1534 	udpha = (udpha_t *)((char *)ipha + iph_hdr_length);
1535 	/*
1536 	 * If we don't have the correct inner IP header length or if the ULP
1537 	 * is not IPPROTO_UDP or if we don't have at least ICMP_MIN_UDP_HDR
1538 	 * bytes of UDP header, send it upstream.
1539 	 */
1540 	if (iph_hdr_length < sizeof (ipha_t) ||
1541 	    ipha->ipha_protocol != IPPROTO_UDP ||
1542 	    (uchar_t *)udpha + ICMP_MIN_UDP_HDR > mp->b_wptr) {
1543 		goto noticmpv4;
1544 	}
1545 
1546 	switch (icmph->icmph_type) {
1547 	case ICMP_DEST_UNREACHABLE:
1548 		switch (icmph->icmph_code) {
1549 		case ICMP_FRAGMENTATION_NEEDED:
1550 			/*
1551 			 * IP has already adjusted the path MTU.
1552 			 * XXX Somehow pass MTU indication to application?
1553 			 */
1554 			break;
1555 		case ICMP_PORT_UNREACHABLE:
1556 		case ICMP_PROTOCOL_UNREACHABLE:
1557 			error = ECONNREFUSED;
1558 			break;
1559 		default:
1560 			/* Transient errors */
1561 			break;
1562 		}
1563 		break;
1564 	default:
1565 		/* Transient errors */
1566 		break;
1567 	}
1568 	if (error == 0) {
1569 		freemsg(mp);
1570 		return;
1571 	}
1572 
1573 	switch (udp->udp_family) {
1574 	case AF_INET:
1575 		sin = sin_null;
1576 		sin.sin_family = AF_INET;
1577 		sin.sin_addr.s_addr = ipha->ipha_dst;
1578 		sin.sin_port = udpha->uha_dst_port;
1579 		mp1 = mi_tpi_uderror_ind((char *)&sin, sizeof (sin_t), NULL, 0,
1580 		    error);
1581 		break;
1582 	case AF_INET6:
1583 		sin6 = sin6_null;
1584 		sin6.sin6_family = AF_INET6;
1585 		IN6_IPADDR_TO_V4MAPPED(ipha->ipha_dst, &sin6.sin6_addr);
1586 		sin6.sin6_port = udpha->uha_dst_port;
1587 
1588 		mp1 = mi_tpi_uderror_ind((char *)&sin6, sizeof (sin6_t),
1589 		    NULL, 0, error);
1590 		break;
1591 	}
1592 	if (mp1)
1593 		putnext(q, mp1);
1594 	freemsg(mp);
1595 }
1596 
1597 /*
1598  * udp_icmp_error_ipv6 is called by udp_icmp_error to process ICMP for IPv6.
1599  * Generates the appropriate T_UDERROR_IND for permanent (non-transient) errors.
1600  * Assumes that IP has pulled up all the extension headers as well as the
1601  * ICMPv6 header.
1602  * An M_CTL could potentially come here from some other module (i.e. if UDP
1603  * is pushed on some module other than IP). Thus, if we find that the M_CTL
1604  * does not have enough ICMP information , following STREAMS conventions,
1605  * we send it upstream assuming it is an M_CTL we don't understand. The reason
1606  * it might get here is if the non-ICMP M_CTL accidently has 6 in the version
1607  * field (when cast to ipha_t in udp_icmp_error).
1608  */
1609 static void
1610 udp_icmp_error_ipv6(queue_t *q, mblk_t *mp)
1611 {
1612 	udp_t		*udp = (udp_t *)q->q_ptr;
1613 	icmp6_t		*icmp6;
1614 	ip6_t		*ip6h, *outer_ip6h;
1615 	uint16_t	hdr_length;
1616 	uint8_t		*nexthdrp;
1617 	udpha_t		*udpha;
1618 	sin6_t		sin6;
1619 	mblk_t		*mp1;
1620 	int		error = 0;
1621 	size_t		mp_size = MBLKL(mp);
1622 
1623 	/*
1624 	 * Verify that we have a complete IP header. If not, send it upstream.
1625 	 */
1626 	if (mp_size < sizeof (ip6_t)) {
1627 noticmpv6:
1628 		putnext(q, mp);
1629 		return;
1630 	}
1631 
1632 	outer_ip6h = (ip6_t *)mp->b_rptr;
1633 	/*
1634 	 * Verify this is an ICMPV6 packet, else send it upstream
1635 	 */
1636 	if (outer_ip6h->ip6_nxt == IPPROTO_ICMPV6) {
1637 		hdr_length = IPV6_HDR_LEN;
1638 	} else if (!ip_hdr_length_nexthdr_v6(mp, outer_ip6h, &hdr_length,
1639 	    &nexthdrp) ||
1640 	    *nexthdrp != IPPROTO_ICMPV6) {
1641 		goto noticmpv6;
1642 	}
1643 	icmp6 = (icmp6_t *)&mp->b_rptr[hdr_length];
1644 	ip6h = (ip6_t *)&icmp6[1];
1645 	/*
1646 	 * Verify we have a complete ICMP and inner IP header.
1647 	 */
1648 	if ((uchar_t *)&ip6h[1] > mp->b_wptr)
1649 		goto noticmpv6;
1650 
1651 	if (!ip_hdr_length_nexthdr_v6(mp, ip6h, &hdr_length, &nexthdrp))
1652 		goto noticmpv6;
1653 	udpha = (udpha_t *)((char *)ip6h + hdr_length);
1654 	/*
1655 	 * Validate inner header. If the ULP is not IPPROTO_UDP or if we don't
1656 	 * have at least ICMP_MIN_UDP_HDR bytes of  UDP header send the
1657 	 * packet upstream.
1658 	 */
1659 	if ((*nexthdrp != IPPROTO_UDP) ||
1660 	    ((uchar_t *)udpha + ICMP_MIN_UDP_HDR) > mp->b_wptr) {
1661 		goto noticmpv6;
1662 	}
1663 
1664 	switch (icmp6->icmp6_type) {
1665 	case ICMP6_DST_UNREACH:
1666 		switch (icmp6->icmp6_code) {
1667 		case ICMP6_DST_UNREACH_NOPORT:
1668 			error = ECONNREFUSED;
1669 			break;
1670 		case ICMP6_DST_UNREACH_ADMIN:
1671 		case ICMP6_DST_UNREACH_NOROUTE:
1672 		case ICMP6_DST_UNREACH_BEYONDSCOPE:
1673 		case ICMP6_DST_UNREACH_ADDR:
1674 			/* Transient errors */
1675 			break;
1676 		default:
1677 			break;
1678 		}
1679 		break;
1680 	case ICMP6_PACKET_TOO_BIG: {
1681 		struct T_unitdata_ind	*tudi;
1682 		struct T_opthdr		*toh;
1683 		size_t			udi_size;
1684 		mblk_t			*newmp;
1685 		t_scalar_t		opt_length = sizeof (struct T_opthdr) +
1686 		    sizeof (struct ip6_mtuinfo);
1687 		sin6_t			*sin6;
1688 		struct ip6_mtuinfo	*mtuinfo;
1689 
1690 		/*
1691 		 * If the application has requested to receive path mtu
1692 		 * information, send up an empty message containing an
1693 		 * IPV6_PATHMTU ancillary data item.
1694 		 */
1695 		if (!udp->udp_ipv6_recvpathmtu)
1696 			break;
1697 
1698 		udi_size = sizeof (struct T_unitdata_ind) + sizeof (sin6_t) +
1699 		    opt_length;
1700 		if ((newmp = allocb(udi_size, BPRI_MED)) == NULL) {
1701 			BUMP_MIB(&udp_mib, udpInErrors);
1702 			break;
1703 		}
1704 
1705 		/*
1706 		 * newmp->b_cont is left to NULL on purpose.  This is an
1707 		 * empty message containing only ancillary data.
1708 		 */
1709 		newmp->b_datap->db_type = M_PROTO;
1710 		tudi = (struct T_unitdata_ind *)newmp->b_rptr;
1711 		newmp->b_wptr = (uchar_t *)tudi + udi_size;
1712 		tudi->PRIM_type = T_UNITDATA_IND;
1713 		tudi->SRC_length = sizeof (sin6_t);
1714 		tudi->SRC_offset = sizeof (struct T_unitdata_ind);
1715 		tudi->OPT_offset = tudi->SRC_offset + sizeof (sin6_t);
1716 		tudi->OPT_length = opt_length;
1717 
1718 		sin6 = (sin6_t *)&tudi[1];
1719 		bzero(sin6, sizeof (sin6_t));
1720 		sin6->sin6_family = AF_INET6;
1721 		sin6->sin6_addr = udp->udp_v6dst;
1722 
1723 		toh = (struct T_opthdr *)&sin6[1];
1724 		toh->level = IPPROTO_IPV6;
1725 		toh->name = IPV6_PATHMTU;
1726 		toh->len = opt_length;
1727 		toh->status = 0;
1728 
1729 		mtuinfo = (struct ip6_mtuinfo *)&toh[1];
1730 		bzero(mtuinfo, sizeof (struct ip6_mtuinfo));
1731 		mtuinfo->ip6m_addr.sin6_family = AF_INET6;
1732 		mtuinfo->ip6m_addr.sin6_addr = ip6h->ip6_dst;
1733 		mtuinfo->ip6m_mtu = icmp6->icmp6_mtu;
1734 		/*
1735 		 * We've consumed everything we need from the original
1736 		 * message.  Free it, then send our empty message.
1737 		 */
1738 		freemsg(mp);
1739 		putnext(q, newmp);
1740 		return;
1741 	}
1742 	case ICMP6_TIME_EXCEEDED:
1743 		/* Transient errors */
1744 		break;
1745 	case ICMP6_PARAM_PROB:
1746 		/* If this corresponds to an ICMP_PROTOCOL_UNREACHABLE */
1747 		if (icmp6->icmp6_code == ICMP6_PARAMPROB_NEXTHEADER &&
1748 		    (uchar_t *)ip6h + icmp6->icmp6_pptr ==
1749 		    (uchar_t *)nexthdrp) {
1750 			error = ECONNREFUSED;
1751 			break;
1752 		}
1753 		break;
1754 	}
1755 	if (error == 0) {
1756 		freemsg(mp);
1757 		return;
1758 	}
1759 
1760 	sin6 = sin6_null;
1761 	sin6.sin6_family = AF_INET6;
1762 	sin6.sin6_addr = ip6h->ip6_dst;
1763 	sin6.sin6_port = udpha->uha_dst_port;
1764 	sin6.sin6_flowinfo = ip6h->ip6_vcf & ~IPV6_VERS_AND_FLOW_MASK;
1765 
1766 	mp1 = mi_tpi_uderror_ind((char *)&sin6, sizeof (sin6_t), NULL, 0,
1767 	    error);
1768 	if (mp1)
1769 		putnext(q, mp1);
1770 	freemsg(mp);
1771 }
1772 
1773 /*
1774  * This routine responds to T_ADDR_REQ messages.  It is called by udp_wput.
1775  * The local address is filled in if endpoint is bound. The remote address
1776  * is filled in if remote address has been precified ("connected endpoint")
1777  * (The concept of connected CLTS sockets is alien to published TPI
1778  *  but we support it anyway).
1779  */
1780 static void
1781 udp_addr_req(queue_t *q, mblk_t *mp)
1782 {
1783 	udp_t	*udp = (udp_t *)q->q_ptr;
1784 	sin_t	*sin;
1785 	sin6_t	*sin6;
1786 	mblk_t	*ackmp;
1787 	struct T_addr_ack *taa;
1788 
1789 	/* Make it large enough for worst case */
1790 	ackmp = reallocb(mp, sizeof (struct T_addr_ack) +
1791 	    2 * sizeof (sin6_t), 1);
1792 	if (ackmp == NULL) {
1793 		udp_err_ack(q, mp, TSYSERR, ENOMEM);
1794 		return;
1795 	}
1796 	taa = (struct T_addr_ack *)ackmp->b_rptr;
1797 
1798 	bzero(taa, sizeof (struct T_addr_ack));
1799 	ackmp->b_wptr = (uchar_t *)&taa[1];
1800 
1801 	taa->PRIM_type = T_ADDR_ACK;
1802 	ackmp->b_datap->db_type = M_PCPROTO;
1803 	/*
1804 	 * Note: Following code assumes 32 bit alignment of basic
1805 	 * data structures like sin_t and struct T_addr_ack.
1806 	 */
1807 	if (udp->udp_state != TS_UNBND) {
1808 		/*
1809 		 * Fill in local address first
1810 		 */
1811 		taa->LOCADDR_offset = sizeof (*taa);
1812 		if (udp->udp_family == AF_INET) {
1813 			taa->LOCADDR_length = sizeof (sin_t);
1814 			sin = (sin_t *)&taa[1];
1815 			/* Fill zeroes and then initialize non-zero fields */
1816 			*sin = sin_null;
1817 			sin->sin_family = AF_INET;
1818 			if (!IN6_IS_ADDR_V4MAPPED_ANY(&udp->udp_v6src) &&
1819 			    !IN6_IS_ADDR_UNSPECIFIED(&udp->udp_v6src)) {
1820 				IN6_V4MAPPED_TO_IPADDR(&udp->udp_v6src,
1821 				    sin->sin_addr.s_addr);
1822 			} else {
1823 				/*
1824 				 * INADDR_ANY
1825 				 * udp_v6src is not set, we might be bound to
1826 				 * broadcast/multicast. Use udp_bound_v6src as
1827 				 * local address instead (that could
1828 				 * also still be INADDR_ANY)
1829 				 */
1830 				IN6_V4MAPPED_TO_IPADDR(&udp->udp_bound_v6src,
1831 				    sin->sin_addr.s_addr);
1832 			}
1833 			sin->sin_port = udp->udp_port;
1834 			ackmp->b_wptr = (uchar_t *)&sin[1];
1835 			if (udp->udp_state == TS_DATA_XFER) {
1836 				/*
1837 				 * connected, fill remote address too
1838 				 */
1839 				taa->REMADDR_length = sizeof (sin_t);
1840 				/* assumed 32-bit alignment */
1841 				taa->REMADDR_offset = taa->LOCADDR_offset +
1842 				    taa->LOCADDR_length;
1843 
1844 				sin = (sin_t *)(ackmp->b_rptr +
1845 				    taa->REMADDR_offset);
1846 				/* initialize */
1847 				*sin = sin_null;
1848 				sin->sin_family = AF_INET;
1849 				sin->sin_addr.s_addr =
1850 				    V4_PART_OF_V6(udp->udp_v6dst);
1851 				sin->sin_port = udp->udp_dstport;
1852 				ackmp->b_wptr = (uchar_t *)&sin[1];
1853 			}
1854 		} else {
1855 			taa->LOCADDR_length = sizeof (sin6_t);
1856 			sin6 = (sin6_t *)&taa[1];
1857 			/* Fill zeroes and then initialize non-zero fields */
1858 			*sin6 = sin6_null;
1859 			sin6->sin6_family = AF_INET6;
1860 			if (!IN6_IS_ADDR_UNSPECIFIED(&udp->udp_v6src)) {
1861 				sin6->sin6_addr = udp->udp_v6src;
1862 			} else {
1863 				/*
1864 				 * UNSPECIFIED
1865 				 * udp_v6src is not set, we might be bound to
1866 				 * broadcast/multicast. Use udp_bound_v6src as
1867 				 * local address instead (that could
1868 				 * also still be UNSPECIFIED)
1869 				 */
1870 				sin6->sin6_addr =
1871 				    udp->udp_bound_v6src;
1872 			}
1873 			sin6->sin6_port = udp->udp_port;
1874 			ackmp->b_wptr = (uchar_t *)&sin6[1];
1875 			if (udp->udp_state == TS_DATA_XFER) {
1876 				/*
1877 				 * connected, fill remote address too
1878 				 */
1879 				taa->REMADDR_length = sizeof (sin6_t);
1880 				/* assumed 32-bit alignment */
1881 				taa->REMADDR_offset = taa->LOCADDR_offset +
1882 				    taa->LOCADDR_length;
1883 
1884 				sin6 = (sin6_t *)(ackmp->b_rptr +
1885 				    taa->REMADDR_offset);
1886 				/* initialize */
1887 				*sin6 = sin6_null;
1888 				sin6->sin6_family = AF_INET6;
1889 				sin6->sin6_addr = udp->udp_v6dst;
1890 				sin6->sin6_port =  udp->udp_dstport;
1891 				ackmp->b_wptr = (uchar_t *)&sin6[1];
1892 			}
1893 			ackmp->b_wptr = (uchar_t *)&sin6[1];
1894 		}
1895 	}
1896 	ASSERT(ackmp->b_wptr <= ackmp->b_datap->db_lim);
1897 	qreply(q, ackmp);
1898 }
1899 
1900 static void
1901 udp_copy_info(struct T_info_ack *tap, udp_t *udp)
1902 {
1903 	if (udp->udp_family == AF_INET) {
1904 		*tap = udp_g_t_info_ack_ipv4;
1905 	} else {
1906 		*tap = udp_g_t_info_ack_ipv6;
1907 	}
1908 	tap->CURRENT_state = udp->udp_state;
1909 	tap->OPT_size = udp_max_optsize;
1910 }
1911 
1912 /*
1913  * This routine responds to T_CAPABILITY_REQ messages.  It is called by
1914  * udp_wput.  Much of the T_CAPABILITY_ACK information is copied from
1915  * udp_g_t_info_ack.  The current state of the stream is copied from
1916  * udp_state.
1917  */
1918 static void
1919 udp_capability_req(queue_t *q, mblk_t *mp)
1920 {
1921 	udp_t			*udp = (udp_t *)q->q_ptr;
1922 	t_uscalar_t		cap_bits1;
1923 	struct T_capability_ack	*tcap;
1924 
1925 	cap_bits1 = ((struct T_capability_req *)mp->b_rptr)->CAP_bits1;
1926 
1927 	mp = tpi_ack_alloc(mp, sizeof (struct T_capability_ack),
1928 	    mp->b_datap->db_type, T_CAPABILITY_ACK);
1929 	if (!mp)
1930 		return;
1931 
1932 	tcap = (struct T_capability_ack *)mp->b_rptr;
1933 	tcap->CAP_bits1 = 0;
1934 
1935 	if (cap_bits1 & TC1_INFO) {
1936 		udp_copy_info(&tcap->INFO_ack, udp);
1937 		tcap->CAP_bits1 |= TC1_INFO;
1938 	}
1939 
1940 	qreply(q, mp);
1941 }
1942 
1943 /*
1944  * This routine responds to T_INFO_REQ messages.  It is called by udp_wput.
1945  * Most of the T_INFO_ACK information is copied from udp_g_t_info_ack.
1946  * The current state of the stream is copied from udp_state.
1947  */
1948 static void
1949 udp_info_req(queue_t *q, mblk_t *mp)
1950 {
1951 	udp_t	*udp = (udp_t *)q->q_ptr;
1952 
1953 	/* Create a T_INFO_ACK message. */
1954 	mp = tpi_ack_alloc(mp, sizeof (struct T_info_ack), M_PCPROTO,
1955 	    T_INFO_ACK);
1956 	if (!mp)
1957 		return;
1958 	udp_copy_info((struct T_info_ack *)mp->b_rptr, udp);
1959 	qreply(q, mp);
1960 }
1961 
1962 /*
1963  * IP recognizes seven kinds of bind requests:
1964  *
1965  * - A zero-length address binds only to the protocol number.
1966  *
1967  * - A 4-byte address is treated as a request to
1968  * validate that the address is a valid local IPv4
1969  * address, appropriate for an application to bind to.
1970  * IP does the verification, but does not make any note
1971  * of the address at this time.
1972  *
1973  * - A 16-byte address contains is treated as a request
1974  * to validate a local IPv6 address, as the 4-byte
1975  * address case above.
1976  *
1977  * - A 16-byte sockaddr_in to validate the local IPv4 address and also
1978  * use it for the inbound fanout of packets.
1979  *
1980  * - A 24-byte sockaddr_in6 to validate the local IPv6 address and also
1981  * use it for the inbound fanout of packets.
1982  *
1983  * - A 12-byte address (ipa_conn_t) containing complete IPv4 fanout
1984  * information consisting of local and remote addresses
1985  * and ports.  In this case, the addresses are both
1986  * validated as appropriate for this operation, and, if
1987  * so, the information is retained for use in the
1988  * inbound fanout.
1989  *
1990  * - A 36-byte address address (ipa6_conn_t) containing complete IPv6
1991  * fanout information, like the 12-byte case above.
1992  *
1993  * IP will also fill in the IRE request mblk with information
1994  * regarding our peer.  In all cases, we notify IP of our protocol
1995  * type by appending a single protocol byte to the bind request.
1996  */
1997 static mblk_t *
1998 udp_ip_bind_mp(udp_t *udp, t_scalar_t bind_prim, t_scalar_t addr_length)
1999 {
2000 	char	*cp;
2001 	mblk_t	*mp;
2002 	struct T_bind_req *tbr;
2003 	ipa_conn_t	*ac;
2004 	ipa6_conn_t	*ac6;
2005 	sin_t		*sin;
2006 	sin6_t		*sin6;
2007 
2008 	ASSERT(bind_prim == O_T_BIND_REQ || bind_prim == T_BIND_REQ);
2009 
2010 	mp = allocb(sizeof (*tbr) + addr_length + 1, BPRI_HI);
2011 	if (!mp)
2012 		return (mp);
2013 	mp->b_datap->db_type = M_PROTO;
2014 	tbr = (struct T_bind_req *)mp->b_rptr;
2015 	tbr->PRIM_type = bind_prim;
2016 	tbr->ADDR_offset = sizeof (*tbr);
2017 	tbr->CONIND_number = 0;
2018 	tbr->ADDR_length = addr_length;
2019 	cp = (char *)&tbr[1];
2020 	switch (addr_length) {
2021 	case sizeof (ipa_conn_t):
2022 		ASSERT(udp->udp_family == AF_INET);
2023 		/* Append a request for an IRE */
2024 		mp->b_cont = allocb(sizeof (ire_t), BPRI_HI);
2025 		if (!mp->b_cont) {
2026 			freemsg(mp);
2027 			return (NULL);
2028 		}
2029 		mp->b_cont->b_wptr += sizeof (ire_t);
2030 		mp->b_cont->b_datap->db_type = IRE_DB_REQ_TYPE;
2031 
2032 		/* cp known to be 32 bit aligned */
2033 		ac = (ipa_conn_t *)cp;
2034 		ac->ac_laddr = V4_PART_OF_V6(udp->udp_v6src);
2035 		ac->ac_faddr = V4_PART_OF_V6(udp->udp_v6dst);
2036 		ac->ac_fport = udp->udp_dstport;
2037 		ac->ac_lport = udp->udp_port;
2038 		break;
2039 
2040 	case sizeof (ipa6_conn_t):
2041 		ASSERT(udp->udp_family == AF_INET6);
2042 		/* Append a request for an IRE */
2043 		mp->b_cont = allocb(sizeof (ire_t), BPRI_HI);
2044 		if (!mp->b_cont) {
2045 			freemsg(mp);
2046 			return (NULL);
2047 		}
2048 		mp->b_cont->b_wptr += sizeof (ire_t);
2049 		mp->b_cont->b_datap->db_type = IRE_DB_REQ_TYPE;
2050 
2051 		/* cp known to be 32 bit aligned */
2052 		ac6 = (ipa6_conn_t *)cp;
2053 		ac6->ac6_laddr = udp->udp_v6src;
2054 		ac6->ac6_faddr = udp->udp_v6dst;
2055 		ac6->ac6_fport = udp->udp_dstport;
2056 		ac6->ac6_lport = udp->udp_port;
2057 		break;
2058 
2059 	case sizeof (sin_t):
2060 		ASSERT(udp->udp_family == AF_INET);
2061 		/* Append a request for an IRE */
2062 		mp->b_cont = allocb(sizeof (ire_t), BPRI_HI);
2063 		if (!mp->b_cont) {
2064 			freemsg(mp);
2065 			return (NULL);
2066 		}
2067 		mp->b_cont->b_wptr += sizeof (ire_t);
2068 		mp->b_cont->b_datap->db_type = IRE_DB_REQ_TYPE;
2069 
2070 		sin = (sin_t *)cp;
2071 		*sin = sin_null;
2072 		sin->sin_family = AF_INET;
2073 		sin->sin_addr.s_addr = V4_PART_OF_V6(udp->udp_bound_v6src);
2074 		sin->sin_port = udp->udp_port;
2075 		break;
2076 
2077 	case sizeof (sin6_t):
2078 		ASSERT(udp->udp_family == AF_INET6);
2079 		/* Append a request for an IRE */
2080 		mp->b_cont = allocb(sizeof (ire_t), BPRI_HI);
2081 		if (!mp->b_cont) {
2082 			freemsg(mp);
2083 			return (NULL);
2084 		}
2085 		mp->b_cont->b_wptr += sizeof (ire_t);
2086 		mp->b_cont->b_datap->db_type = IRE_DB_REQ_TYPE;
2087 
2088 		sin6 = (sin6_t *)cp;
2089 		*sin6 = sin6_null;
2090 		sin6->sin6_family = AF_INET6;
2091 		sin6->sin6_addr = udp->udp_bound_v6src;
2092 		sin6->sin6_port = udp->udp_port;
2093 		break;
2094 	}
2095 	/* Add protocol number to end */
2096 	cp[addr_length] = (char)IPPROTO_UDP;
2097 	mp->b_wptr = (uchar_t *)&cp[addr_length + 1];
2098 	return (mp);
2099 }
2100 
2101 /*
2102  * This is the open routine for udp.  It allocates a udp_t structure for
2103  * the stream and, on the first open of the module, creates an ND table.
2104  */
2105 static int
2106 udp_open(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *credp)
2107 {
2108 	int	err;
2109 	udp_t	*udp;
2110 
2111 	TRACE_1(TR_FAC_UDP, TR_UDP_OPEN, "udp_open: q %p", q);
2112 
2113 	/*
2114 	 * Defer the qprocson until everything is initialized since
2115 	 * we are D_MTPERQ and after qprocson the rput routine can
2116 	 * run.
2117 	 */
2118 
2119 	/* If the stream is already open, return immediately. */
2120 	if (q->q_ptr != NULL)
2121 		return (0);
2122 
2123 	/* If this is not a push of udp as a module, fail. */
2124 	if (sflag != MODOPEN)
2125 		return (EINVAL);
2126 
2127 	/*
2128 	 * Create and initialize a udp_t structure for this stream.
2129 	 */
2130 	udp = (udp_t *)mi_open_alloc_sleep(sizeof (udp_t));
2131 
2132 	/* Set the initial state of the stream and the privilege status. */
2133 	q->q_ptr = WR(q)->q_ptr = udp;
2134 	udp->udp_state = TS_UNBND;
2135 	if (getmajor(*devp) == (major_t)UDP6_MAJ) {
2136 		udp->udp_family = AF_INET6;
2137 		udp->udp_ipversion = IPV6_VERSION;
2138 		udp->udp_max_hdr_len = IPV6_HDR_LEN + UDPH_SIZE;
2139 		udp->udp_ttl = udp_ipv6_hoplimit;
2140 	} else {
2141 		udp->udp_family = AF_INET;
2142 		udp->udp_ipversion = IPV4_VERSION;
2143 		udp->udp_max_hdr_len = IP_SIMPLE_HDR_LENGTH + UDPH_SIZE;
2144 		udp->udp_ttl = udp_ipv4_ttl;
2145 	}
2146 
2147 	/*
2148 	 * The receive hiwat is only looked at on the stream head queue.
2149 	 * Store in q_hiwat in order to return on SO_RCVBUF getsockopts.
2150 	 */
2151 	q->q_hiwat = udp_recv_hiwat;
2152 
2153 	udp->udp_multicast_ttl = IP_DEFAULT_MULTICAST_TTL;
2154 	udp->udp_multicast_loop = IP_DEFAULT_MULTICAST_LOOP;
2155 	udp->udp_credp = credp;
2156 	crhold(credp);
2157 
2158 	udp->udp_zoneid = getzoneid();
2159 
2160 	/*
2161 	 * Acquire the lock and link it into the list of open streams.
2162 	 */
2163 	mutex_enter(&udp_g_lock);
2164 	err = mi_open_link(&udp_g_head, (IDP)udp, devp, flag, sflag, credp);
2165 	mutex_exit(&udp_g_lock);
2166 	if (err != 0)
2167 		goto error;
2168 
2169 	qprocson(q);
2170 
2171 	/*
2172 	 * The transmit hiwat/lowat is only looked at on IP's queue.
2173 	 * Store in q_hiwat in order to return on SO_SNDBUF
2174 	 * getsockopts.
2175 	 */
2176 	WR(q)->q_hiwat = udp_xmit_hiwat;
2177 	WR(q)->q_next->q_hiwat = WR(q)->q_hiwat;
2178 	WR(q)->q_lowat = udp_xmit_lowat;
2179 	WR(q)->q_next->q_lowat = WR(q)->q_lowat;
2180 
2181 	if (udp->udp_family == AF_INET6) {
2182 		/* Build initial header template for transmit */
2183 		if ((err = udp_build_hdrs(q, udp)) != 0) {
2184 			qprocsoff(q);
2185 			/*
2186 			 * Unlink the udp structure and release
2187 			 * the minor device number.
2188 			 */
2189 			mutex_enter(&udp_g_lock);
2190 			mi_close_unlink(&udp_g_head, (IDP)udp);
2191 			mutex_exit(&udp_g_lock);
2192 			goto error;
2193 		}
2194 	}
2195 
2196 	/* Set the Stream head write offset. */
2197 	(void) mi_set_sth_wroff(q, udp->udp_max_hdr_len + udp_wroff_extra);
2198 	(void) mi_set_sth_hiwat(q, q->q_hiwat);
2199 	return (0);
2200 
2201 error:
2202 	q->q_ptr = WR(q)->q_ptr = NULL;
2203 	crfree(credp);
2204 	mi_close_free((IDP)udp);
2205 	return (err);
2206 }
2207 
2208 /*
2209  * Which UDP options OK to set through T_UNITDATA_REQ...
2210  */
2211 /* ARGSUSED */
2212 static boolean_t
2213 udp_opt_allow_udr_set(t_scalar_t level, t_scalar_t name)
2214 {
2215 
2216 	return (B_TRUE);
2217 }
2218 
2219 /*
2220  * This routine gets default values of certain options whose default
2221  * values are maintained by protcol specific code
2222  */
2223 /* ARGSUSED */
2224 int
2225 udp_opt_default(queue_t	*q, t_scalar_t level, t_scalar_t name, uchar_t *ptr)
2226 {
2227 	int *i1 = (int *)ptr;
2228 
2229 	switch (level) {
2230 	case IPPROTO_IP:
2231 		switch (name) {
2232 		case IP_MULTICAST_TTL:
2233 			*ptr = (uchar_t)IP_DEFAULT_MULTICAST_TTL;
2234 			return (sizeof (uchar_t));
2235 		case IP_MULTICAST_LOOP:
2236 			*ptr = (uchar_t)IP_DEFAULT_MULTICAST_LOOP;
2237 			return (sizeof (uchar_t));
2238 		}
2239 		break;
2240 	case IPPROTO_IPV6:
2241 		switch (name) {
2242 		case IPV6_MULTICAST_HOPS:
2243 			*i1 = IP_DEFAULT_MULTICAST_TTL;
2244 			return (sizeof (int));
2245 		case IPV6_MULTICAST_LOOP:
2246 			*i1 = IP_DEFAULT_MULTICAST_LOOP;
2247 			return (sizeof (int));
2248 		case IPV6_UNICAST_HOPS:
2249 			*i1 = udp_ipv6_hoplimit;
2250 			return (sizeof (int));
2251 		}
2252 		break;
2253 	}
2254 	return (-1);
2255 }
2256 
2257 /*
2258  * This routine retrieves the current status of socket options.
2259  * It returns the size of the option retrieved.
2260  */
2261 int
2262 udp_opt_get(queue_t *q, t_scalar_t level, t_scalar_t name, uchar_t *ptr)
2263 {
2264 	int	*i1 = (int *)ptr;
2265 	udp_t	*udp = (udp_t *)q->q_ptr;
2266 	ip6_pkt_t	*ipp = &udp->udp_sticky_ipp;
2267 
2268 	switch (level) {
2269 	case SOL_SOCKET:
2270 		switch (name) {
2271 		case SO_DEBUG:
2272 			*i1 = udp->udp_debug;
2273 			break;	/* goto sizeof (int) option return */
2274 		case SO_REUSEADDR:
2275 			*i1 = udp->udp_reuseaddr;
2276 			break;	/* goto sizeof (int) option return */
2277 		case SO_TYPE:
2278 			*i1 = SOCK_DGRAM;
2279 			break;	/* goto sizeof (int) option return */
2280 
2281 		/*
2282 		 * The following three items are available here,
2283 		 * but are only meaningful to IP.
2284 		 */
2285 		case SO_DONTROUTE:
2286 			*i1 = udp->udp_dontroute;
2287 			break;	/* goto sizeof (int) option return */
2288 		case SO_USELOOPBACK:
2289 			*i1 = udp->udp_useloopback;
2290 			break;	/* goto sizeof (int) option return */
2291 		case SO_BROADCAST:
2292 			*i1 = udp->udp_broadcast;
2293 			break;	/* goto sizeof (int) option return */
2294 
2295 		case SO_SNDBUF:
2296 			*i1 = q->q_hiwat;
2297 			break;	/* goto sizeof (int) option return */
2298 		case SO_RCVBUF:
2299 			*i1 = RD(q)->q_hiwat;
2300 			break;	/* goto sizeof (int) option return */
2301 		case SO_DGRAM_ERRIND:
2302 			*i1 = udp->udp_dgram_errind;
2303 			break;	/* goto sizeof (int) option return */
2304 		case SO_RECVUCRED:
2305 			*i1 = udp->udp_recvucred;
2306 			break;	/* goto sizeof (int) option return */
2307 		default:
2308 			return (-1);
2309 		}
2310 		break;
2311 	case IPPROTO_IP:
2312 		if (udp->udp_family != AF_INET)
2313 			return (-1);
2314 		switch (name) {
2315 		case IP_OPTIONS:
2316 		case T_IP_OPTIONS:
2317 			if (udp->udp_ip_rcv_options_len)
2318 				bcopy(udp->udp_ip_rcv_options, ptr,
2319 				    udp->udp_ip_rcv_options_len);
2320 			return (udp->udp_ip_rcv_options_len);
2321 		case IP_TOS:
2322 		case T_IP_TOS:
2323 			*i1 = (int)udp->udp_type_of_service;
2324 			break;	/* goto sizeof (int) option return */
2325 		case IP_TTL:
2326 			*i1 = (int)udp->udp_ttl;
2327 			break;	/* goto sizeof (int) option return */
2328 		case IP_MULTICAST_IF:
2329 			/* 0 address if not set */
2330 			*(ipaddr_t *)ptr = udp->udp_multicast_if_addr;
2331 			return (sizeof (ipaddr_t));
2332 		case IP_MULTICAST_TTL:
2333 			*(uchar_t *)ptr = udp->udp_multicast_ttl;
2334 			return (sizeof (uchar_t));
2335 		case IP_MULTICAST_LOOP:
2336 			*ptr = udp->udp_multicast_loop;
2337 			return (sizeof (uint8_t));
2338 		case IP_RECVOPTS:
2339 			*i1 = udp->udp_recvopts;
2340 			break;	/* goto sizeof (int) option return */
2341 		case IP_RECVDSTADDR:
2342 			*i1 = udp->udp_recvdstaddr;
2343 			break;	/* goto sizeof (int) option return */
2344 		case IP_RECVIF:
2345 			*i1 = udp->udp_recvif;
2346 			break;	/* goto sizeof (int) option return */
2347 		case IP_RECVSLLA:
2348 			*i1 = udp->udp_recvslla;
2349 			break;	/* goto sizeof (int) option return */
2350 		case IP_RECVTTL:
2351 			*i1 = udp->udp_recvttl;
2352 			break;	/* goto sizeof (int) option return */
2353 		case IP_ADD_MEMBERSHIP:
2354 		case IP_DROP_MEMBERSHIP:
2355 		case IP_BLOCK_SOURCE:
2356 		case IP_UNBLOCK_SOURCE:
2357 		case IP_ADD_SOURCE_MEMBERSHIP:
2358 		case IP_DROP_SOURCE_MEMBERSHIP:
2359 		case MCAST_JOIN_GROUP:
2360 		case MCAST_LEAVE_GROUP:
2361 		case MCAST_BLOCK_SOURCE:
2362 		case MCAST_UNBLOCK_SOURCE:
2363 		case MCAST_JOIN_SOURCE_GROUP:
2364 		case MCAST_LEAVE_SOURCE_GROUP:
2365 		case IP_DONTFAILOVER_IF:
2366 			/* cannot "get" the value for these */
2367 			return (-1);
2368 		case IP_BOUND_IF:
2369 			/* Zero if not set */
2370 			*i1 = udp->udp_bound_if;
2371 			break;	/* goto sizeof (int) option return */
2372 		case IP_UNSPEC_SRC:
2373 			*i1 = udp->udp_unspec_source;
2374 			break;	/* goto sizeof (int) option return */
2375 		case IP_XMIT_IF:
2376 			*i1 = udp->udp_xmit_if;
2377 			break; /* goto sizeof (int) option return */
2378 		default:
2379 			return (-1);
2380 		}
2381 		break;
2382 	case IPPROTO_IPV6:
2383 		if (udp->udp_family != AF_INET6)
2384 			return (-1);
2385 		switch (name) {
2386 		case IPV6_UNICAST_HOPS:
2387 			*i1 = (unsigned int)udp->udp_ttl;
2388 			break;	/* goto sizeof (int) option return */
2389 		case IPV6_MULTICAST_IF:
2390 			/* 0 index if not set */
2391 			*i1 = udp->udp_multicast_if_index;
2392 			break;	/* goto sizeof (int) option return */
2393 		case IPV6_MULTICAST_HOPS:
2394 			*i1 = udp->udp_multicast_ttl;
2395 			break;	/* goto sizeof (int) option return */
2396 		case IPV6_MULTICAST_LOOP:
2397 			*i1 = udp->udp_multicast_loop;
2398 			break;	/* goto sizeof (int) option return */
2399 		case IPV6_JOIN_GROUP:
2400 		case IPV6_LEAVE_GROUP:
2401 		case MCAST_JOIN_GROUP:
2402 		case MCAST_LEAVE_GROUP:
2403 		case MCAST_BLOCK_SOURCE:
2404 		case MCAST_UNBLOCK_SOURCE:
2405 		case MCAST_JOIN_SOURCE_GROUP:
2406 		case MCAST_LEAVE_SOURCE_GROUP:
2407 			/* cannot "get" the value for these */
2408 			return (-1);
2409 		case IPV6_BOUND_IF:
2410 			/* Zero if not set */
2411 			*i1 = udp->udp_bound_if;
2412 			break;	/* goto sizeof (int) option return */
2413 		case IPV6_UNSPEC_SRC:
2414 			*i1 = udp->udp_unspec_source;
2415 			break;	/* goto sizeof (int) option return */
2416 		case IPV6_RECVPKTINFO:
2417 			*i1 = udp->udp_ipv6_recvpktinfo;
2418 			break;	/* goto sizeof (int) option return */
2419 		case IPV6_RECVTCLASS:
2420 			*i1 = udp->udp_ipv6_recvtclass;
2421 			break;	/* goto sizeof (int) option return */
2422 		case IPV6_RECVPATHMTU:
2423 			*i1 = udp->udp_ipv6_recvpathmtu;
2424 			break;	/* goto sizeof (int) option return */
2425 		case IPV6_RECVHOPLIMIT:
2426 			*i1 = udp->udp_ipv6_recvhoplimit;
2427 			break;	/* goto sizeof (int) option return */
2428 		case IPV6_RECVHOPOPTS:
2429 			*i1 = udp->udp_ipv6_recvhopopts;
2430 			break;	/* goto sizeof (int) option return */
2431 		case IPV6_RECVDSTOPTS:
2432 			*i1 = udp->udp_ipv6_recvdstopts;
2433 			break;	/* goto sizeof (int) option return */
2434 		case _OLD_IPV6_RECVDSTOPTS:
2435 			*i1 = udp->udp_old_ipv6_recvdstopts;
2436 			break;	/* goto sizeof (int) option return */
2437 		case IPV6_RECVRTHDRDSTOPTS:
2438 			*i1 = udp->udp_ipv6_recvrthdrdstopts;
2439 			break;	/* goto sizeof (int) option return */
2440 		case IPV6_RECVRTHDR:
2441 			*i1 = udp->udp_ipv6_recvrthdr;
2442 			break;	/* goto sizeof (int) option return */
2443 		case IPV6_PKTINFO: {
2444 			/* XXX assumes that caller has room for max size! */
2445 			struct in6_pktinfo *pkti;
2446 
2447 			pkti = (struct in6_pktinfo *)ptr;
2448 			if (ipp->ipp_fields & IPPF_IFINDEX)
2449 				pkti->ipi6_ifindex = ipp->ipp_ifindex;
2450 			else
2451 				pkti->ipi6_ifindex = 0;
2452 			if (ipp->ipp_fields & IPPF_ADDR)
2453 				pkti->ipi6_addr = ipp->ipp_addr;
2454 			else
2455 				pkti->ipi6_addr = ipv6_all_zeros;
2456 			return (sizeof (struct in6_pktinfo));
2457 		}
2458 		case IPV6_HOPLIMIT:
2459 			if (ipp->ipp_fields & IPPF_HOPLIMIT)
2460 				*i1 = ipp->ipp_hoplimit;
2461 			else
2462 				*i1 = -1; /* Not set */
2463 			break;	/* goto sizeof (int) option return */
2464 		case IPV6_TCLASS:
2465 			if (ipp->ipp_fields & IPPF_TCLASS)
2466 				*i1 = ipp->ipp_tclass;
2467 			else
2468 				*i1 = IPV6_FLOW_TCLASS(
2469 				    IPV6_DEFAULT_VERS_AND_FLOW);
2470 			break;	/* goto sizeof (int) option return */
2471 		case IPV6_NEXTHOP: {
2472 			sin6_t *sin6 = (sin6_t *)ptr;
2473 
2474 			if (!(ipp->ipp_fields & IPPF_NEXTHOP))
2475 				return (0);
2476 			*sin6 = sin6_null;
2477 			sin6->sin6_family = AF_INET6;
2478 			sin6->sin6_addr = ipp->ipp_nexthop;
2479 			return (sizeof (sin6_t));
2480 		}
2481 		case IPV6_HOPOPTS:
2482 			if (!(ipp->ipp_fields & IPPF_HOPOPTS))
2483 				return (0);
2484 			bcopy(ipp->ipp_hopopts, ptr, ipp->ipp_hopoptslen);
2485 			return (ipp->ipp_hopoptslen);
2486 		case IPV6_RTHDRDSTOPTS:
2487 			if (!(ipp->ipp_fields & IPPF_RTDSTOPTS))
2488 				return (0);
2489 			bcopy(ipp->ipp_rtdstopts, ptr, ipp->ipp_rtdstoptslen);
2490 			return (ipp->ipp_rtdstoptslen);
2491 		case IPV6_RTHDR:
2492 			if (!(ipp->ipp_fields & IPPF_RTHDR))
2493 				return (0);
2494 			bcopy(ipp->ipp_rthdr, ptr, ipp->ipp_rthdrlen);
2495 			return (ipp->ipp_rthdrlen);
2496 		case IPV6_DSTOPTS:
2497 			if (!(ipp->ipp_fields & IPPF_DSTOPTS))
2498 				return (0);
2499 			bcopy(ipp->ipp_dstopts, ptr, ipp->ipp_dstoptslen);
2500 			return (ipp->ipp_dstoptslen);
2501 		case IPV6_PATHMTU:
2502 			return (ip_fill_mtuinfo(&udp->udp_v6dst,
2503 				udp->udp_dstport, (struct ip6_mtuinfo *)ptr));
2504 		default:
2505 			return (-1);
2506 		}
2507 		break;
2508 	case IPPROTO_UDP:
2509 		switch (name) {
2510 		case UDP_ANONPRIVBIND:
2511 			*i1 = udp->udp_anon_priv_bind;
2512 			break;
2513 		case UDP_EXCLBIND:
2514 			*i1 = udp->udp_exclbind ? UDP_EXCLBIND : 0;
2515 			break;
2516 		case UDP_RCVHDR:
2517 			*i1 = udp->udp_rcvhdr ? 1 : 0;
2518 			break;
2519 		default:
2520 			return (-1);
2521 		}
2522 		break;
2523 	default:
2524 		return (-1);
2525 	}
2526 	return (sizeof (int));
2527 }
2528 
2529 /* This routine sets socket options. */
2530 /* ARGSUSED */
2531 int
2532 udp_opt_set(queue_t *q, uint_t optset_context, int level,
2533     int name, uint_t inlen, uchar_t *invalp, uint_t *outlenp,
2534     uchar_t *outvalp, void *thisdg_attrs, cred_t *cr, mblk_t *mblk)
2535 {
2536 	udp_t	*udp = (udp_t *)q->q_ptr;
2537 	int	*i1 = (int *)invalp;
2538 	boolean_t onoff = (*i1 == 0) ? 0 : 1;
2539 	boolean_t checkonly;
2540 	int	error;
2541 
2542 	switch (optset_context) {
2543 	case SETFN_OPTCOM_CHECKONLY:
2544 		checkonly = B_TRUE;
2545 		/*
2546 		 * Note: Implies T_CHECK semantics for T_OPTCOM_REQ
2547 		 * inlen != 0 implies value supplied and
2548 		 * 	we have to "pretend" to set it.
2549 		 * inlen == 0 implies that there is no
2550 		 * 	value part in T_CHECK request and just validation
2551 		 * done elsewhere should be enough, we just return here.
2552 		 */
2553 		if (inlen == 0) {
2554 			*outlenp = 0;
2555 			return (0);
2556 		}
2557 		break;
2558 	case SETFN_OPTCOM_NEGOTIATE:
2559 		checkonly = B_FALSE;
2560 		break;
2561 	case SETFN_UD_NEGOTIATE:
2562 	case SETFN_CONN_NEGOTIATE:
2563 		checkonly = B_FALSE;
2564 		/*
2565 		 * Negotiating local and "association-related" options
2566 		 * through T_UNITDATA_REQ.
2567 		 *
2568 		 * Following routine can filter out ones we do not
2569 		 * want to be "set" this way.
2570 		 */
2571 		if (!udp_opt_allow_udr_set(level, name)) {
2572 			*outlenp = 0;
2573 			return (EINVAL);
2574 		}
2575 		break;
2576 	default:
2577 		/*
2578 		 * We should never get here
2579 		 */
2580 		*outlenp = 0;
2581 		return (EINVAL);
2582 	}
2583 
2584 	ASSERT((optset_context != SETFN_OPTCOM_CHECKONLY) ||
2585 	    (optset_context == SETFN_OPTCOM_CHECKONLY && inlen != 0));
2586 
2587 	/*
2588 	 * For fixed length options, no sanity check
2589 	 * of passed in length is done. It is assumed *_optcom_req()
2590 	 * routines do the right thing.
2591 	 */
2592 
2593 	switch (level) {
2594 	case SOL_SOCKET:
2595 		switch (name) {
2596 		case SO_REUSEADDR:
2597 			if (!checkonly)
2598 				udp->udp_reuseaddr = onoff;
2599 			break;
2600 		case SO_DEBUG:
2601 			if (!checkonly)
2602 				udp->udp_debug = onoff;
2603 			break;
2604 		/*
2605 		 * The following three items are available here,
2606 		 * but are only meaningful to IP.
2607 		 */
2608 		case SO_DONTROUTE:
2609 			if (!checkonly)
2610 				udp->udp_dontroute = onoff;
2611 			break;
2612 		case SO_USELOOPBACK:
2613 			if (!checkonly)
2614 				udp->udp_useloopback = onoff;
2615 			break;
2616 		case SO_BROADCAST:
2617 			if (!checkonly)
2618 				udp->udp_broadcast = onoff;
2619 			break;
2620 
2621 		case SO_SNDBUF:
2622 			if (*i1 > udp_max_buf) {
2623 				*outlenp = 0;
2624 				return (ENOBUFS);
2625 			}
2626 			if (!checkonly) {
2627 				q->q_hiwat = *i1;
2628 				q->q_next->q_hiwat = *i1;
2629 			}
2630 			break;
2631 		case SO_RCVBUF:
2632 			if (*i1 > udp_max_buf) {
2633 				*outlenp = 0;
2634 				return (ENOBUFS);
2635 			}
2636 			if (!checkonly) {
2637 				RD(q)->q_hiwat = *i1;
2638 				(void) mi_set_sth_hiwat(RD(q), *i1);
2639 			}
2640 			break;
2641 		case SO_DGRAM_ERRIND:
2642 			if (!checkonly)
2643 				udp->udp_dgram_errind = onoff;
2644 			break;
2645 		case SO_RECVUCRED:
2646 			if (!checkonly)
2647 				udp->udp_recvucred = onoff;
2648 			break;
2649 		default:
2650 			*outlenp = 0;
2651 			return (EINVAL);
2652 		}
2653 		break;
2654 	case IPPROTO_IP:
2655 		if (udp->udp_family != AF_INET) {
2656 			*outlenp = 0;
2657 			return (ENOPROTOOPT);
2658 		}
2659 		switch (name) {
2660 		case IP_OPTIONS:
2661 		case T_IP_OPTIONS:
2662 			/* Save options for use by IP. */
2663 			if (inlen & 0x3) {
2664 				*outlenp = 0;
2665 				return (EINVAL);
2666 			}
2667 			if (checkonly)
2668 				break;
2669 
2670 			if (udp->udp_ip_snd_options) {
2671 				mi_free((char *)udp->udp_ip_snd_options);
2672 				udp->udp_ip_snd_options_len = 0;
2673 				udp->udp_ip_snd_options = NULL;
2674 			}
2675 			if (inlen) {
2676 				udp->udp_ip_snd_options =
2677 					(uchar_t *)mi_alloc(inlen, BPRI_HI);
2678 				if (udp->udp_ip_snd_options) {
2679 					bcopy(invalp, udp->udp_ip_snd_options,
2680 					    inlen);
2681 					udp->udp_ip_snd_options_len = inlen;
2682 				}
2683 			}
2684 			udp->udp_max_hdr_len = IP_SIMPLE_HDR_LENGTH +
2685 			    UDPH_SIZE + udp->udp_ip_snd_options_len;
2686 			(void) mi_set_sth_wroff(RD(q), udp->udp_max_hdr_len +
2687 			    udp_wroff_extra);
2688 			break;
2689 		case IP_TTL:
2690 			if (!checkonly) {
2691 				udp->udp_ttl = (uchar_t)*i1;
2692 			}
2693 			break;
2694 		case IP_TOS:
2695 		case T_IP_TOS:
2696 			if (!checkonly) {
2697 				udp->udp_type_of_service = (uchar_t)*i1;
2698 			}
2699 			break;
2700 		case IP_MULTICAST_IF: {
2701 			/*
2702 			 * TODO should check OPTMGMT reply and undo this if
2703 			 * there is an error.
2704 			 */
2705 			struct in_addr *inap = (struct in_addr *)invalp;
2706 			if (!checkonly) {
2707 				udp->udp_multicast_if_addr =
2708 				    inap->s_addr;
2709 			}
2710 			break;
2711 		}
2712 		case IP_MULTICAST_TTL:
2713 			if (!checkonly)
2714 				udp->udp_multicast_ttl = *invalp;
2715 			break;
2716 		case IP_MULTICAST_LOOP:
2717 			if (!checkonly)
2718 				udp->udp_multicast_loop = *invalp;
2719 			break;
2720 		case IP_RECVOPTS:
2721 			if (!checkonly)
2722 				udp->udp_recvopts = onoff;
2723 			break;
2724 		case IP_RECVDSTADDR:
2725 			if (!checkonly)
2726 				udp->udp_recvdstaddr = onoff;
2727 			break;
2728 		case IP_RECVIF:
2729 			if (!checkonly)
2730 				udp->udp_recvif = onoff;
2731 			break;
2732 		case IP_RECVSLLA:
2733 			if (!checkonly)
2734 				udp->udp_recvslla = onoff;
2735 			break;
2736 		case IP_RECVTTL:
2737 			if (!checkonly)
2738 				udp->udp_recvttl = onoff;
2739 			break;
2740 		case IP_ADD_MEMBERSHIP:
2741 		case IP_DROP_MEMBERSHIP:
2742 		case IP_BLOCK_SOURCE:
2743 		case IP_UNBLOCK_SOURCE:
2744 		case IP_ADD_SOURCE_MEMBERSHIP:
2745 		case IP_DROP_SOURCE_MEMBERSHIP:
2746 		case MCAST_JOIN_GROUP:
2747 		case MCAST_LEAVE_GROUP:
2748 		case MCAST_BLOCK_SOURCE:
2749 		case MCAST_UNBLOCK_SOURCE:
2750 		case MCAST_JOIN_SOURCE_GROUP:
2751 		case MCAST_LEAVE_SOURCE_GROUP:
2752 		case IP_SEC_OPT:
2753 			/*
2754 			 * "soft" error (negative)
2755 			 * option not handled at this level
2756 			 * Do not modify *outlenp.
2757 			 */
2758 			return (-EINVAL);
2759 		case IP_BOUND_IF:
2760 			if (!checkonly)
2761 				udp->udp_bound_if = *i1;
2762 			break;
2763 		case IP_UNSPEC_SRC:
2764 			if (!checkonly)
2765 				udp->udp_unspec_source = onoff;
2766 			break;
2767 		case IP_XMIT_IF:
2768 			if (!checkonly)
2769 				udp->udp_xmit_if = *i1;
2770 			break;
2771 		default:
2772 			*outlenp = 0;
2773 			return (EINVAL);
2774 		}
2775 		break;
2776 	case IPPROTO_IPV6: {
2777 		ip6_pkt_t		*ipp;
2778 		boolean_t		sticky;
2779 
2780 		if (udp->udp_family != AF_INET6) {
2781 			*outlenp = 0;
2782 			return (ENOPROTOOPT);
2783 		}
2784 		/*
2785 		 * Deal with both sticky options and ancillary data
2786 		 */
2787 		if (thisdg_attrs == NULL) {
2788 			/* sticky options, or none */
2789 			ipp = &udp->udp_sticky_ipp;
2790 			sticky = B_TRUE;
2791 		} else {
2792 			/* ancillary data */
2793 			ipp = (ip6_pkt_t *)thisdg_attrs;
2794 			sticky = B_FALSE;
2795 		}
2796 
2797 		switch (name) {
2798 		case IPV6_MULTICAST_IF:
2799 			if (!checkonly)
2800 				udp->udp_multicast_if_index = *i1;
2801 			break;
2802 		case IPV6_UNICAST_HOPS:
2803 			/* -1 means use default */
2804 			if (*i1 < -1 || *i1 > IPV6_MAX_HOPS) {
2805 				*outlenp = 0;
2806 				return (EINVAL);
2807 			}
2808 			if (!checkonly) {
2809 				if (*i1 == -1) {
2810 					udp->udp_ttl = ipp->ipp_hoplimit =
2811 					    udp_ipv6_hoplimit;
2812 					ipp->ipp_fields &= ~IPPF_HOPLIMIT;
2813 					/* Pass modified value to IP. */
2814 					*i1 = udp->udp_ttl;
2815 				} else {
2816 					udp->udp_ttl = ipp->ipp_hoplimit =
2817 					    (uint8_t)*i1;
2818 					ipp->ipp_fields |= IPPF_HOPLIMIT;
2819 				}
2820 				/* Rebuild the header template */
2821 				error = udp_build_hdrs(q, udp);
2822 				if (error != 0) {
2823 					*outlenp = 0;
2824 					return (error);
2825 				}
2826 			}
2827 			break;
2828 		case IPV6_MULTICAST_HOPS:
2829 			/* -1 means use default */
2830 			if (*i1 < -1 || *i1 > IPV6_MAX_HOPS) {
2831 				*outlenp = 0;
2832 				return (EINVAL);
2833 			}
2834 			if (!checkonly) {
2835 				if (*i1 == -1) {
2836 					udp->udp_multicast_ttl =
2837 					    ipp->ipp_multi_hoplimit =
2838 					    IP_DEFAULT_MULTICAST_TTL;
2839 					ipp->ipp_fields &= ~IPPF_MULTI_HOPLIMIT;
2840 					/* Pass modified value to IP. */
2841 					*i1 = udp->udp_multicast_ttl;
2842 				} else {
2843 					udp->udp_multicast_ttl =
2844 					    ipp->ipp_multi_hoplimit =
2845 					    (uint8_t)*i1;
2846 					ipp->ipp_fields |= IPPF_MULTI_HOPLIMIT;
2847 				}
2848 				/* Rebuild the header template */
2849 				error = udp_build_hdrs(q, udp);
2850 				if (error != 0) {
2851 					*outlenp = 0;
2852 					return (error);
2853 				}
2854 			}
2855 			break;
2856 		case IPV6_MULTICAST_LOOP:
2857 			if (*i1 != 0 && *i1 != 1) {
2858 				*outlenp = 0;
2859 				return (EINVAL);
2860 			}
2861 			if (!checkonly)
2862 				udp->udp_multicast_loop = *i1;
2863 			break;
2864 		case IPV6_JOIN_GROUP:
2865 		case IPV6_LEAVE_GROUP:
2866 		case MCAST_JOIN_GROUP:
2867 		case MCAST_LEAVE_GROUP:
2868 		case MCAST_BLOCK_SOURCE:
2869 		case MCAST_UNBLOCK_SOURCE:
2870 		case MCAST_JOIN_SOURCE_GROUP:
2871 		case MCAST_LEAVE_SOURCE_GROUP:
2872 			/*
2873 			 * "soft" error (negative)
2874 			 * option not handled at this level
2875 			 * Note: Do not modify *outlenp
2876 			 */
2877 			return (-EINVAL);
2878 		case IPV6_BOUND_IF:
2879 			if (!checkonly)
2880 				udp->udp_bound_if = *i1;
2881 			break;
2882 		case IPV6_UNSPEC_SRC:
2883 			if (!checkonly)
2884 				udp->udp_unspec_source = onoff;
2885 			break;
2886 		/*
2887 		 * Set boolean switches for ancillary data delivery
2888 		 */
2889 		case IPV6_RECVPKTINFO:
2890 			if (!checkonly)
2891 				udp->udp_ipv6_recvpktinfo = onoff;
2892 			break;
2893 		case IPV6_RECVTCLASS:
2894 			if (!checkonly) {
2895 				udp->udp_ipv6_recvtclass = onoff;
2896 			}
2897 			break;
2898 		case IPV6_RECVPATHMTU:
2899 			if (!checkonly) {
2900 				udp->udp_ipv6_recvpathmtu = onoff;
2901 			}
2902 			break;
2903 		case IPV6_RECVHOPLIMIT:
2904 			if (!checkonly)
2905 				udp->udp_ipv6_recvhoplimit = onoff;
2906 			break;
2907 		case IPV6_RECVHOPOPTS:
2908 			if (!checkonly)
2909 				udp->udp_ipv6_recvhopopts = onoff;
2910 			break;
2911 		case IPV6_RECVDSTOPTS:
2912 			if (!checkonly)
2913 				udp->udp_ipv6_recvdstopts = onoff;
2914 			break;
2915 		case _OLD_IPV6_RECVDSTOPTS:
2916 			if (!checkonly)
2917 				udp->udp_old_ipv6_recvdstopts = onoff;
2918 			break;
2919 		case IPV6_RECVRTHDRDSTOPTS:
2920 			if (!checkonly)
2921 				udp->udp_ipv6_recvrthdrdstopts = onoff;
2922 			break;
2923 		case IPV6_RECVRTHDR:
2924 			if (!checkonly)
2925 				udp->udp_ipv6_recvrthdr = onoff;
2926 			break;
2927 		/*
2928 		 * Set sticky options or ancillary data.
2929 		 * If sticky options, (re)build any extension headers
2930 		 * that might be needed as a result.
2931 		 */
2932 		case IPV6_PKTINFO:
2933 			/*
2934 			 * The source address and ifindex are verified
2935 			 * in ip_opt_set(). For ancillary data the
2936 			 * source address is checked in ip_wput_v6.
2937 			 */
2938 			if (inlen != 0 && inlen != sizeof (struct in6_pktinfo))
2939 				return (EINVAL);
2940 			if (checkonly)
2941 				break;
2942 
2943 			if (inlen == 0) {
2944 				ipp->ipp_fields &= ~(IPPF_IFINDEX|IPPF_ADDR);
2945 				ipp->ipp_sticky_ignored |=
2946 				    (IPPF_IFINDEX|IPPF_ADDR);
2947 			} else {
2948 				struct in6_pktinfo *pkti;
2949 
2950 				pkti = (struct in6_pktinfo *)invalp;
2951 				ipp->ipp_ifindex = pkti->ipi6_ifindex;
2952 				ipp->ipp_addr = pkti->ipi6_addr;
2953 				if (ipp->ipp_ifindex != 0)
2954 					ipp->ipp_fields |= IPPF_IFINDEX;
2955 				else
2956 					ipp->ipp_fields &= ~IPPF_IFINDEX;
2957 				if (!IN6_IS_ADDR_UNSPECIFIED(
2958 				    &ipp->ipp_addr))
2959 					ipp->ipp_fields |= IPPF_ADDR;
2960 				else
2961 					ipp->ipp_fields &= ~IPPF_ADDR;
2962 			}
2963 			if (sticky) {
2964 				error = udp_build_hdrs(q, udp);
2965 				if (error != 0)
2966 					return (error);
2967 			}
2968 			break;
2969 		case IPV6_HOPLIMIT:
2970 			if (inlen != 0 && inlen != sizeof (int))
2971 				return (EINVAL);
2972 			if (checkonly)
2973 				break;
2974 
2975 			if (inlen == 0) {
2976 				ipp->ipp_fields &= ~IPPF_HOPLIMIT;
2977 				ipp->ipp_sticky_ignored |= IPPF_HOPLIMIT;
2978 			} else {
2979 				if (*i1 > 255 || *i1 < -1)
2980 					return (EINVAL);
2981 				if (*i1 == -1)
2982 					ipp->ipp_hoplimit = udp_ipv6_hoplimit;
2983 				else
2984 					ipp->ipp_hoplimit = *i1;
2985 				ipp->ipp_fields |= IPPF_HOPLIMIT;
2986 			}
2987 			if (sticky) {
2988 				error = udp_build_hdrs(q, udp);
2989 				if (error != 0)
2990 					return (error);
2991 			}
2992 			break;
2993 		case IPV6_TCLASS:
2994 			if (inlen != 0 && inlen != sizeof (int))
2995 				return (EINVAL);
2996 			if (checkonly)
2997 				break;
2998 
2999 			if (inlen == 0) {
3000 				ipp->ipp_fields &= ~IPPF_TCLASS;
3001 				ipp->ipp_sticky_ignored |= IPPF_TCLASS;
3002 			} else {
3003 				if (*i1 > 255 || *i1 < -1)
3004 					return (EINVAL);
3005 				if (*i1 == -1)
3006 					ipp->ipp_tclass = 0;
3007 				else
3008 					ipp->ipp_tclass = *i1;
3009 				ipp->ipp_fields |= IPPF_TCLASS;
3010 			}
3011 			if (sticky) {
3012 				error = udp_build_hdrs(q, udp);
3013 				if (error != 0)
3014 					return (error);
3015 			}
3016 			break;
3017 		case IPV6_NEXTHOP:
3018 			/*
3019 			 * IP will verify that the nexthop is reachable
3020 			 * and fail for sticky options.
3021 			 */
3022 			if (inlen != 0 && inlen != sizeof (sin6_t))
3023 				return (EINVAL);
3024 			if (checkonly)
3025 				break;
3026 
3027 			if (inlen == 0) {
3028 				ipp->ipp_fields &= ~IPPF_NEXTHOP;
3029 				ipp->ipp_sticky_ignored |= IPPF_NEXTHOP;
3030 			} else {
3031 				sin6_t *sin6 = (sin6_t *)invalp;
3032 
3033 				if (sin6->sin6_family != AF_INET6)
3034 					return (EAFNOSUPPORT);
3035 				if (IN6_IS_ADDR_V4MAPPED(
3036 				    &sin6->sin6_addr))
3037 					return (EADDRNOTAVAIL);
3038 				ipp->ipp_nexthop = sin6->sin6_addr;
3039 				if (!IN6_IS_ADDR_UNSPECIFIED(
3040 				    &ipp->ipp_nexthop))
3041 					ipp->ipp_fields |= IPPF_NEXTHOP;
3042 				else
3043 					ipp->ipp_fields &= ~IPPF_NEXTHOP;
3044 			}
3045 			if (sticky) {
3046 				error = udp_build_hdrs(q, udp);
3047 				if (error != 0)
3048 					return (error);
3049 			}
3050 			break;
3051 		case IPV6_HOPOPTS: {
3052 			ip6_hbh_t *hopts = (ip6_hbh_t *)invalp;
3053 			/*
3054 			 * Sanity checks - minimum size, size a multiple of
3055 			 * eight bytes, and matching size passed in.
3056 			 */
3057 			if (inlen != 0 &&
3058 			    inlen != (8 * (hopts->ip6h_len + 1)))
3059 				return (EINVAL);
3060 
3061 			if (checkonly)
3062 				break;
3063 
3064 			if (inlen == 0) {
3065 				if (sticky &&
3066 				    (ipp->ipp_fields & IPPF_HOPOPTS) != 0) {
3067 					kmem_free(ipp->ipp_hopopts,
3068 					    ipp->ipp_hopoptslen);
3069 					ipp->ipp_hopopts = NULL;
3070 					ipp->ipp_hopoptslen = 0;
3071 				}
3072 				ipp->ipp_fields &= ~IPPF_HOPOPTS;
3073 				ipp->ipp_sticky_ignored |= IPPF_HOPOPTS;
3074 			} else {
3075 				error = udp_pkt_set(invalp, inlen, sticky,
3076 				    (uchar_t **)&ipp->ipp_hopopts,
3077 				    &ipp->ipp_hopoptslen);
3078 				if (error != 0)
3079 					return (error);
3080 				ipp->ipp_fields |= IPPF_HOPOPTS;
3081 			}
3082 			if (sticky) {
3083 				error = udp_build_hdrs(q, udp);
3084 				if (error != 0)
3085 					return (error);
3086 			}
3087 			break;
3088 		}
3089 		case IPV6_RTHDRDSTOPTS: {
3090 			ip6_dest_t *dopts = (ip6_dest_t *)invalp;
3091 
3092 			/*
3093 			 * Sanity checks - minimum size, size a multiple of
3094 			 * eight bytes, and matching size passed in.
3095 			 */
3096 			if (inlen != 0 &&
3097 			    inlen != (8 * (dopts->ip6d_len + 1)))
3098 				return (EINVAL);
3099 
3100 			if (checkonly)
3101 				break;
3102 
3103 			if (inlen == 0) {
3104 				if (sticky &&
3105 				    (ipp->ipp_fields & IPPF_RTDSTOPTS) != 0) {
3106 					kmem_free(ipp->ipp_rtdstopts,
3107 					    ipp->ipp_rtdstoptslen);
3108 					ipp->ipp_rtdstopts = NULL;
3109 					ipp->ipp_rtdstoptslen = 0;
3110 				}
3111 				ipp->ipp_fields &= ~IPPF_RTDSTOPTS;
3112 				ipp->ipp_sticky_ignored |= IPPF_RTDSTOPTS;
3113 			} else {
3114 				error = udp_pkt_set(invalp, inlen, sticky,
3115 				    (uchar_t **)&ipp->ipp_rtdstopts,
3116 				    &ipp->ipp_rtdstoptslen);
3117 				if (error != 0)
3118 					return (error);
3119 				ipp->ipp_fields |= IPPF_RTDSTOPTS;
3120 			}
3121 			if (sticky) {
3122 				error = udp_build_hdrs(q, udp);
3123 				if (error != 0)
3124 					return (error);
3125 			}
3126 			break;
3127 		}
3128 		case IPV6_DSTOPTS: {
3129 			ip6_dest_t *dopts = (ip6_dest_t *)invalp;
3130 
3131 			/*
3132 			 * Sanity checks - minimum size, size a multiple of
3133 			 * eight bytes, and matching size passed in.
3134 			 */
3135 			if (inlen != 0 &&
3136 			    inlen != (8 * (dopts->ip6d_len + 1)))
3137 				return (EINVAL);
3138 
3139 			if (checkonly)
3140 				break;
3141 
3142 			if (inlen == 0) {
3143 				if (sticky &&
3144 				    (ipp->ipp_fields & IPPF_DSTOPTS) != 0) {
3145 					kmem_free(ipp->ipp_dstopts,
3146 					    ipp->ipp_dstoptslen);
3147 					ipp->ipp_dstopts = NULL;
3148 					ipp->ipp_dstoptslen = 0;
3149 				}
3150 				ipp->ipp_fields &= ~IPPF_DSTOPTS;
3151 				ipp->ipp_sticky_ignored |= IPPF_DSTOPTS;
3152 			} else {
3153 				error = udp_pkt_set(invalp, inlen, sticky,
3154 				    (uchar_t **)&ipp->ipp_dstopts,
3155 				    &ipp->ipp_dstoptslen);
3156 				if (error != 0)
3157 					return (error);
3158 				ipp->ipp_fields |= IPPF_DSTOPTS;
3159 			}
3160 			if (sticky) {
3161 				error = udp_build_hdrs(q, udp);
3162 				if (error != 0)
3163 					return (error);
3164 			}
3165 			break;
3166 		}
3167 		case IPV6_RTHDR: {
3168 			ip6_rthdr_t *rt = (ip6_rthdr_t *)invalp;
3169 
3170 			/*
3171 			 * Sanity checks - minimum size, size a multiple of
3172 			 * eight bytes, and matching size passed in.
3173 			 */
3174 			if (inlen != 0 &&
3175 			    inlen != (8 * (rt->ip6r_len + 1)))
3176 				return (EINVAL);
3177 
3178 			if (checkonly)
3179 				break;
3180 
3181 			if (inlen == 0) {
3182 				if (sticky &&
3183 				    (ipp->ipp_fields & IPPF_RTHDR) != 0) {
3184 					kmem_free(ipp->ipp_rthdr,
3185 					    ipp->ipp_rthdrlen);
3186 					ipp->ipp_rthdr = NULL;
3187 					ipp->ipp_rthdrlen = 0;
3188 				}
3189 				ipp->ipp_fields &= ~IPPF_RTHDR;
3190 				ipp->ipp_sticky_ignored |= IPPF_RTHDR;
3191 			} else {
3192 				error = udp_pkt_set(invalp, inlen, sticky,
3193 				    (uchar_t **)&ipp->ipp_rthdr,
3194 				    &ipp->ipp_rthdrlen);
3195 				if (error != 0)
3196 					return (error);
3197 				ipp->ipp_fields |= IPPF_RTHDR;
3198 			}
3199 			if (sticky) {
3200 				error = udp_build_hdrs(q, udp);
3201 				if (error != 0)
3202 					return (error);
3203 			}
3204 			break;
3205 		}
3206 
3207 		case IPV6_DONTFRAG:
3208 			if (checkonly)
3209 				break;
3210 
3211 			if (onoff) {
3212 				ipp->ipp_fields |= IPPF_DONTFRAG;
3213 			} else {
3214 				ipp->ipp_fields &= ~IPPF_DONTFRAG;
3215 			}
3216 			break;
3217 
3218 		case IPV6_USE_MIN_MTU:
3219 			if (inlen != sizeof (int))
3220 				return (EINVAL);
3221 
3222 			if (*i1 < -1 || *i1 > 1)
3223 				return (EINVAL);
3224 
3225 			if (checkonly)
3226 				break;
3227 
3228 			ipp->ipp_fields |= IPPF_USE_MIN_MTU;
3229 			ipp->ipp_use_min_mtu = *i1;
3230 			break;
3231 
3232 		case IPV6_BOUND_PIF:
3233 		case IPV6_SEC_OPT:
3234 		case IPV6_DONTFAILOVER_IF:
3235 		case IPV6_SRC_PREFERENCES:
3236 		case IPV6_V6ONLY:
3237 			/* Handled at the IP level */
3238 			return (-EINVAL);
3239 		default:
3240 			*outlenp = 0;
3241 			return (EINVAL);
3242 		}
3243 		break;
3244 		}		/* end IPPROTO_IPV6 */
3245 	case IPPROTO_UDP:
3246 		switch (name) {
3247 		case UDP_ANONPRIVBIND:
3248 			if ((error = secpolicy_net_privaddr(cr, 0)) != 0) {
3249 				*outlenp = 0;
3250 				return (error);
3251 			}
3252 			if (!checkonly) {
3253 				udp->udp_anon_priv_bind = onoff;
3254 			}
3255 			break;
3256 		case UDP_EXCLBIND:
3257 			if (!checkonly)
3258 				udp->udp_exclbind = onoff;
3259 			break;
3260 		case UDP_RCVHDR:
3261 			if (!checkonly)
3262 				udp->udp_rcvhdr = onoff;
3263 			break;
3264 		default:
3265 			*outlenp = 0;
3266 			return (EINVAL);
3267 		}
3268 		break;
3269 	default:
3270 		*outlenp = 0;
3271 		return (EINVAL);
3272 	}
3273 	/*
3274 	 * Common case of OK return with outval same as inval.
3275 	 */
3276 	if (invalp != outvalp) {
3277 		/* don't trust bcopy for identical src/dst */
3278 		(void) bcopy(invalp, outvalp, inlen);
3279 	}
3280 	*outlenp = inlen;
3281 	return (0);
3282 }
3283 
3284 /*
3285  * Update udp_sticky_hdrs based on udp_sticky_ipp, udp_v6src, and udp_ttl.
3286  * The headers include ip6i_t (if needed), ip6_t, any sticky extension
3287  * headers, and the udp header.
3288  * Returns failure if can't allocate memory.
3289  */
3290 static int
3291 udp_build_hdrs(queue_t *q, udp_t *udp)
3292 {
3293 	uchar_t	*hdrs;
3294 	uint_t	hdrs_len;
3295 	ip6_t	*ip6h;
3296 	ip6i_t	*ip6i;
3297 	udpha_t	*udpha;
3298 	ip6_pkt_t *ipp = &udp->udp_sticky_ipp;
3299 
3300 	hdrs_len = ip_total_hdrs_len_v6(ipp) + UDPH_SIZE;
3301 	ASSERT(hdrs_len != 0);
3302 	if (hdrs_len != udp->udp_sticky_hdrs_len) {
3303 		/* Need to reallocate */
3304 		hdrs = kmem_alloc(hdrs_len, KM_NOSLEEP);
3305 		if (hdrs == NULL)
3306 			return (ENOMEM);
3307 
3308 		if (udp->udp_sticky_hdrs_len != 0) {
3309 			kmem_free(udp->udp_sticky_hdrs,
3310 			    udp->udp_sticky_hdrs_len);
3311 		}
3312 		udp->udp_sticky_hdrs = hdrs;
3313 		udp->udp_sticky_hdrs_len = hdrs_len;
3314 	}
3315 	ip_build_hdrs_v6(udp->udp_sticky_hdrs,
3316 	    udp->udp_sticky_hdrs_len - UDPH_SIZE, ipp, IPPROTO_UDP);
3317 
3318 	/* Set header fields not in ipp */
3319 	if (ipp->ipp_fields & IPPF_HAS_IP6I) {
3320 		ip6i = (ip6i_t *)udp->udp_sticky_hdrs;
3321 		ip6h = (ip6_t *)&ip6i[1];
3322 	} else {
3323 		ip6h = (ip6_t *)udp->udp_sticky_hdrs;
3324 	}
3325 
3326 	if (!(ipp->ipp_fields & IPPF_ADDR))
3327 		ip6h->ip6_src = udp->udp_v6src;
3328 
3329 	/*
3330 	 * If IPV6_HOPLIMIT was set in ipp, use that value.
3331 	 * For sticky options, if it does not exist use
3332 	 * the value in the udp structure.
3333 	 * All this as per RFC 2922.
3334 	 */
3335 	if (!(ipp->ipp_fields & IPPF_HOPLIMIT))
3336 		ip6h->ip6_hops = udp->udp_ttl;
3337 
3338 	udpha = (udpha_t *)(udp->udp_sticky_hdrs + hdrs_len - UDPH_SIZE);
3339 	udpha->uha_src_port = udp->udp_port;
3340 
3341 	/* Try to get everything in a single mblk */
3342 	if (hdrs_len > udp->udp_max_hdr_len) {
3343 		udp->udp_max_hdr_len = hdrs_len;
3344 		(void) mi_set_sth_wroff(RD(q), udp->udp_max_hdr_len +
3345 		    udp_wroff_extra);
3346 	}
3347 	return (0);
3348 }
3349 
3350 /*
3351  * Set optbuf and optlen for the option.
3352  * If sticky is set allocate memory (if not already present).
3353  * Otherwise just point optbuf and optlen at invalp and inlen.
3354  * Returns failure if memory can not be allocated.
3355  */
3356 static int
3357 udp_pkt_set(uchar_t *invalp, uint_t inlen, boolean_t sticky,
3358     uchar_t **optbufp, uint_t *optlenp)
3359 {
3360 	uchar_t *optbuf;
3361 
3362 	if (!sticky) {
3363 		*optbufp = invalp;
3364 		*optlenp = inlen;
3365 		return (0);
3366 	}
3367 	if (inlen == *optlenp) {
3368 		/* Unchanged length - no need to realocate */
3369 		bcopy(invalp, *optbufp, inlen);
3370 		return (0);
3371 	}
3372 	if (inlen != 0) {
3373 		/* Allocate new buffer before free */
3374 		optbuf = kmem_alloc(inlen, KM_NOSLEEP);
3375 		if (optbuf == NULL)
3376 			return (ENOMEM);
3377 	} else {
3378 		optbuf = NULL;
3379 	}
3380 	/* Free old buffer */
3381 	if (*optlenp != 0)
3382 		kmem_free(*optbufp, *optlenp);
3383 
3384 	bcopy(invalp, optbuf, inlen);
3385 	*optbufp = optbuf;
3386 	*optlenp = inlen;
3387 	return (0);
3388 }
3389 
3390 /*
3391  * This routine retrieves the value of an ND variable in a udpparam_t
3392  * structure.  It is called through nd_getset when a user reads the
3393  * variable.
3394  */
3395 /* ARGSUSED */
3396 static int
3397 udp_param_get(queue_t *q, mblk_t *mp, caddr_t cp, cred_t *cr)
3398 {
3399 	udpparam_t *udppa = (udpparam_t *)cp;
3400 
3401 	(void) mi_mpprintf(mp, "%d", udppa->udp_param_value);
3402 	return (0);
3403 }
3404 
3405 /*
3406  * Walk through the param array specified registering each element with the
3407  * named dispatch (ND) handler.
3408  */
3409 static boolean_t
3410 udp_param_register(udpparam_t *udppa, int cnt)
3411 {
3412 	for (; cnt-- > 0; udppa++) {
3413 		if (udppa->udp_param_name && udppa->udp_param_name[0]) {
3414 			if (!nd_load(&udp_g_nd, udppa->udp_param_name,
3415 			    udp_param_get, udp_param_set,
3416 			    (caddr_t)udppa)) {
3417 				nd_free(&udp_g_nd);
3418 				return (B_FALSE);
3419 			}
3420 		}
3421 	}
3422 	if (!nd_load(&udp_g_nd, "udp_extra_priv_ports",
3423 	    udp_extra_priv_ports_get, NULL, NULL)) {
3424 		nd_free(&udp_g_nd);
3425 		return (B_FALSE);
3426 	}
3427 	if (!nd_load(&udp_g_nd, "udp_extra_priv_ports_add",
3428 	    NULL, udp_extra_priv_ports_add, NULL)) {
3429 		nd_free(&udp_g_nd);
3430 		return (B_FALSE);
3431 	}
3432 	if (!nd_load(&udp_g_nd, "udp_extra_priv_ports_del",
3433 	    NULL, udp_extra_priv_ports_del, NULL)) {
3434 		nd_free(&udp_g_nd);
3435 		return (B_FALSE);
3436 	}
3437 	if (!nd_load(&udp_g_nd, "udp_status", udp_status_report, NULL,
3438 	    NULL)) {
3439 		nd_free(&udp_g_nd);
3440 		return (B_FALSE);
3441 	}
3442 	if (!nd_load(&udp_g_nd, "udp_bind_hash", udp_bind_hash_report, NULL,
3443 	    NULL)) {
3444 		nd_free(&udp_g_nd);
3445 		return (B_FALSE);
3446 	}
3447 	return (B_TRUE);
3448 }
3449 
3450 /* This routine sets an ND variable in a udpparam_t structure. */
3451 /* ARGSUSED */
3452 static int
3453 udp_param_set(queue_t *q, mblk_t *mp, char *value, caddr_t cp, cred_t *cr)
3454 {
3455 	long		new_value;
3456 	udpparam_t	*udppa = (udpparam_t *)cp;
3457 
3458 	/*
3459 	 * Fail the request if the new value does not lie within the
3460 	 * required bounds.
3461 	 */
3462 	if (ddi_strtol(value, NULL, 10, &new_value) != 0 ||
3463 	    new_value < udppa->udp_param_min ||
3464 	    new_value > udppa->udp_param_max) {
3465 		return (EINVAL);
3466 	}
3467 
3468 	/* Set the new value */
3469 	udppa->udp_param_value = new_value;
3470 	return (0);
3471 }
3472 
3473 static void
3474 udp_rput(queue_t *q, mblk_t *mp)
3475 {
3476 	struct T_unitdata_ind	*tudi;
3477 	uchar_t			*rptr;
3478 	int			hdr_length;
3479 	int			udi_size;	/* Size of T_unitdata_ind */
3480 	udp_t			*udp;
3481 	udpha_t			*udpha;
3482 	int			ipversion;
3483 	ip6_pkt_t		ipp;
3484 	ip6_t			*ip6h;
3485 	ip6i_t			*ip6i;
3486 	mblk_t			*mp1;
3487 	mblk_t			*options_mp = NULL;
3488 	in_pktinfo_t		*pinfo = NULL;
3489 	size_t			mp_size = MBLKL(mp);
3490 	cred_t			*cr = NULL;
3491 	pid_t			cpid;
3492 
3493 	TRACE_2(TR_FAC_UDP, TR_UDP_RPUT_START,
3494 	    "udp_rput_start: q %p mp %p", q, mp);
3495 
3496 	udp = (udp_t *)q->q_ptr;
3497 	rptr = mp->b_rptr;
3498 
3499 	switch (mp->b_datap->db_type) {
3500 	case M_DATA:
3501 		/*
3502 		 * M_DATA messages contain IP datagrams.  They are handled
3503 		 * after this switch.
3504 		 */
3505 		break;
3506 	case M_PROTO:
3507 	case M_PCPROTO:
3508 		/* M_PROTO messages contain some type of TPI message. */
3509 		if ((mp->b_wptr - rptr) < sizeof (t_scalar_t)) {
3510 			freemsg(mp);
3511 			TRACE_2(TR_FAC_UDP, TR_UDP_RPUT_END,
3512 				"udp_rput_end: q %p (%S)", q, "protoshort");
3513 			return;
3514 		}
3515 		qwriter(q, mp, udp_rput_other, PERIM_INNER);
3516 		TRACE_2(TR_FAC_UDP, TR_UDP_RPUT_END,
3517 			"udp_rput_end: q %p (%S)", q, "proto");
3518 		return;
3519 	case M_FLUSH:
3520 		if (*mp->b_rptr & FLUSHR)
3521 			flushq(q, FLUSHDATA);
3522 		putnext(q, mp);
3523 		TRACE_2(TR_FAC_UDP, TR_UDP_RPUT_END,
3524 			"udp_rput_end: q %p (%S)", q, "flush");
3525 		return;
3526 	case M_CTL:
3527 		if (udp->udp_recvif || udp->udp_recvslla ||
3528 		    udp->udp_ipv6_recvpktinfo) {
3529 			/*
3530 			 * IP should have prepended the options data in an M_CTL
3531 			 * Check M_CTL "type" to make sure are not here bcos of
3532 			 * a valid ICMP message
3533 			 */
3534 			if (mp_size == sizeof (in_pktinfo_t) &&
3535 			    ((in_pktinfo_t *)mp->b_rptr)->in_pkt_ulp_type ==
3536 			    IN_PKTINFO) {
3537 				pinfo = (in_pktinfo_t *)mp->b_rptr;
3538 				/*
3539 				 * Jump to normal data processing, this is not
3540 				 * an ICMP message
3541 				 */
3542 				break;
3543 			}
3544 		}
3545 		/*
3546 		 * ICMP messages.
3547 		 */
3548 		udp_icmp_error(q, mp);
3549 		TRACE_2(TR_FAC_UDP, TR_UDP_RPUT_END,
3550 			"udp_rput_end: q %p (%S)", q, "m_ctl");
3551 		return;
3552 	default:
3553 		putnext(q, mp);
3554 		TRACE_2(TR_FAC_UDP, TR_UDP_RPUT_END,
3555 			"udp_rput_end: q %p (%S)", q, "default");
3556 		return;
3557 	}
3558 
3559 	/*
3560 	 * If we are here bcos the IP_RECVIF or IP_RECVSLLA then we need to
3561 	 * extract the mblk and adjust the rptr
3562 	 */
3563 	if (pinfo != NULL) {
3564 		ASSERT(mp->b_datap->db_type == M_CTL);
3565 		options_mp = mp;
3566 		mp = mp->b_cont;
3567 		rptr = mp->b_rptr;
3568 		mp_size = MBLKL(mp);
3569 	}
3570 	/*
3571 	 * This is the inbound data path.
3572 	 * First, we check to make sure the IP version number is correct,
3573 	 * and then pull the IP and UDP headers into the first mblk.
3574 	 */
3575 	/*
3576 	 * Assume IP provides aligned packets - otherwise toss.
3577 	 * Also, check if we have a complete IP header.
3578 	 */
3579 	if (!OK_32PTR(rptr) || (mp_size < sizeof (ipha_t))) {
3580 tossit:
3581 		freemsg(mp);
3582 		if (options_mp != NULL)
3583 			freeb(options_mp);
3584 		BUMP_MIB(&udp_mib, udpInErrors);
3585 		return;
3586 	}
3587 
3588 	/* Initialize regardless if ipversion is IPv4 or IPv6 */
3589 	ipp.ipp_fields = 0;
3590 
3591 	ipversion = IPH_HDR_VERSION(rptr);
3592 	switch (ipversion) {
3593 	case IPV4_VERSION:
3594 		hdr_length = IPH_HDR_LENGTH(rptr) + UDPH_SIZE;
3595 		/* Verify this is a UDP packet */
3596 		if (((ipha_t *)rptr)->ipha_protocol != IPPROTO_UDP)
3597 			goto tossit;
3598 		if ((hdr_length > IP_SIMPLE_HDR_LENGTH + UDPH_SIZE) ||
3599 		    (udp->udp_ip_rcv_options_len)) {
3600 			/*
3601 			 * Handle IPv4 packets with options outside of the
3602 			 * main data path. Not needed for AF_INET6 sockets
3603 			 * since they don't support a getsockopt of IP_OPTIONS.
3604 			 */
3605 			if (udp->udp_family == AF_INET6)
3606 				break;
3607 			/*
3608 			 * UDP length check performed for IPv4 packets with
3609 			 * options to check whether UDP length specified in
3610 			 * the header is the same as the physical length of
3611 			 * the packet.
3612 			 */
3613 			udpha = (udpha_t *)(rptr + (hdr_length - UDPH_SIZE));
3614 			if (msgdsize(mp) != (ntohs(udpha->uha_length) +
3615 			    hdr_length - UDPH_SIZE)) {
3616 				goto tossit;
3617 			}
3618 			/*
3619 			 * Handle the case where the packet has IP options
3620 			 * and the IP_RECVSLLA & IP_RECVIF are set
3621 			 */
3622 			if (pinfo != NULL)
3623 				mp = options_mp;
3624 			qwriter(q, mp, udp_rput_other, PERIM_INNER);
3625 			TRACE_2(TR_FAC_UDP, TR_UDP_RPUT_END,
3626 				"udp_rput_end: q %p (%S)", q, "end");
3627 			return;
3628 		}
3629 
3630 		/* Handle IPV6_RECVHOPLIMIT. */
3631 		if ((udp->udp_family == AF_INET6) && (pinfo != NULL)) {
3632 			if (pinfo->in_pkt_flags & IPF_RECVIF) {
3633 				ipp.ipp_fields |= IPPF_IFINDEX;
3634 				ipp.ipp_ifindex = pinfo->in_pkt_ifindex;
3635 			}
3636 		}
3637 		break;
3638 	case IPV6_VERSION:
3639 		/*
3640 		 * IPv6 packets can only be received by applications
3641 		 * that are prepared to receive IPv6 addresses.
3642 		 * The IP fanout must ensure this.
3643 		 */
3644 		ASSERT(udp->udp_family == AF_INET6);
3645 
3646 		ip6h = (ip6_t *)rptr;
3647 		if ((uchar_t *)&ip6h[1] > mp->b_wptr)
3648 			goto tossit;
3649 
3650 		if (ip6h->ip6_nxt != IPPROTO_UDP) {
3651 			uint8_t nexthdrp;
3652 			/* Look for ifindex information */
3653 			if (ip6h->ip6_nxt == IPPROTO_RAW) {
3654 				ip6i = (ip6i_t *)ip6h;
3655 				if ((uchar_t *)&ip6i[1] > mp->b_wptr)
3656 					goto tossit;
3657 
3658 				if (ip6i->ip6i_flags & IP6I_IFINDEX) {
3659 					ASSERT(ip6i->ip6i_ifindex != 0);
3660 					ipp.ipp_fields |= IPPF_IFINDEX;
3661 					ipp.ipp_ifindex = ip6i->ip6i_ifindex;
3662 				}
3663 				rptr = (uchar_t *)&ip6i[1];
3664 				mp->b_rptr = rptr;
3665 				if (rptr == mp->b_wptr) {
3666 					mp1 = mp->b_cont;
3667 					freeb(mp);
3668 					mp = mp1;
3669 					rptr = mp->b_rptr;
3670 				}
3671 				if (MBLKL(mp) < (IPV6_HDR_LEN + UDPH_SIZE))
3672 					goto tossit;
3673 				ip6h = (ip6_t *)rptr;
3674 			}
3675 			/*
3676 			 * Find any potentially interesting extension headers
3677 			 * as well as the length of the IPv6 + extension
3678 			 * headers.
3679 			 */
3680 			hdr_length = ip_find_hdr_v6(mp, ip6h, &ipp, &nexthdrp) +
3681 			    UDPH_SIZE;
3682 			/* Verify this is a UDP packet */
3683 			if (nexthdrp != IPPROTO_UDP)
3684 				goto tossit;
3685 		} else {
3686 			hdr_length = IPV6_HDR_LEN + UDPH_SIZE;
3687 			ip6i = NULL;
3688 		}
3689 		break;
3690 	default:
3691 		TRACE_2(TR_FAC_UDP, TR_UDP_RPUT_END,
3692 			"udp_rput_end: q %p (%S)", q, "Unknown IP version");
3693 		goto tossit;
3694 	}
3695 
3696 	/*
3697 	 * IP inspected the UDP header thus all of it must be in the mblk.
3698 	 * UDP length check is performed for IPv6 packets and IPv4 packets
3699 	 * without options to check if the size of the packet as specified
3700 	 * by the header is the same as the physical size of the packet.
3701 	 */
3702 	udpha = (udpha_t *)(rptr + (hdr_length - UDPH_SIZE));
3703 	if ((MBLKL(mp) < hdr_length) ||
3704 	    (msgdsize(mp) != (ntohs(udpha->uha_length) +
3705 	    hdr_length - UDPH_SIZE))) {
3706 		goto tossit;
3707 	}
3708 
3709 	/* Walk past the headers. */
3710 	if (!udp->udp_rcvhdr)
3711 		mp->b_rptr = rptr + hdr_length;
3712 
3713 	/*
3714 	 * This is the inbound data path.  Packets are passed upstream as
3715 	 * T_UNITDATA_IND messages with full IP headers still attached.
3716 	 */
3717 	if (udp->udp_family == AF_INET) {
3718 		sin_t *sin;
3719 
3720 		ASSERT(IPH_HDR_VERSION((ipha_t *)rptr) == IPV4_VERSION);
3721 
3722 		/*
3723 		 * Normally only send up the address.
3724 		 * If IP_RECVDSTADDR is set we include the destination IP
3725 		 * address as an option. With IP_RECVOPTS we include all
3726 		 * the IP options. Only ip_rput_other() handles packets
3727 		 * that contain IP options.
3728 		 */
3729 		udi_size = sizeof (struct T_unitdata_ind) + sizeof (sin_t);
3730 		if (udp->udp_recvdstaddr) {
3731 			udi_size += sizeof (struct T_opthdr) +
3732 			    sizeof (struct in_addr);
3733 		}
3734 
3735 		/*
3736 		 * If the IP_RECVSLLA or the IP_RECVIF is set then allocate
3737 		 * space accordingly
3738 		 */
3739 		if (udp->udp_recvif && (pinfo != NULL) &&
3740 		    (pinfo->in_pkt_flags & IPF_RECVIF)) {
3741 			udi_size += sizeof (struct T_opthdr) +
3742 				sizeof (uint_t);
3743 		}
3744 
3745 		if (udp->udp_recvslla && (pinfo != NULL) &&
3746 		    (pinfo->in_pkt_flags & IPF_RECVSLLA)) {
3747 			udi_size += sizeof (struct T_opthdr) +
3748 				sizeof (struct sockaddr_dl);
3749 		}
3750 
3751 		if (udp->udp_recvucred && (cr = DB_CRED(mp)) != NULL) {
3752 			udi_size += sizeof (struct T_opthdr) + ucredsize;
3753 			cpid = DB_CPID(mp);
3754 		}
3755 		/*
3756 		 * If IP_RECVTTL is set allocate the appropriate sized buffer
3757 		 */
3758 		if (udp->udp_recvttl) {
3759 			udi_size += sizeof (struct T_opthdr) + sizeof (uint8_t);
3760 		}
3761 
3762 		ASSERT(IPH_HDR_LENGTH((ipha_t *)rptr) == IP_SIMPLE_HDR_LENGTH);
3763 
3764 		/* Allocate a message block for the T_UNITDATA_IND structure. */
3765 		mp1 = allocb(udi_size, BPRI_MED);
3766 		if (mp1 == NULL) {
3767 			freemsg(mp);
3768 			if (options_mp != NULL)
3769 				freeb(options_mp);
3770 			TRACE_2(TR_FAC_UDP, TR_UDP_RPUT_END,
3771 				"udp_rput_end: q %p (%S)", q, "allocbfail");
3772 			BUMP_MIB(&udp_mib, udpInErrors);
3773 			return;
3774 		}
3775 		mp1->b_cont = mp;
3776 		mp = mp1;
3777 		mp->b_datap->db_type = M_PROTO;
3778 		tudi = (struct T_unitdata_ind *)mp->b_rptr;
3779 		mp->b_wptr = (uchar_t *)tudi + udi_size;
3780 		tudi->PRIM_type = T_UNITDATA_IND;
3781 		tudi->SRC_length = sizeof (sin_t);
3782 		tudi->SRC_offset = sizeof (struct T_unitdata_ind);
3783 		tudi->OPT_offset = sizeof (struct T_unitdata_ind) +
3784 		    sizeof (sin_t);
3785 		udi_size -= (sizeof (struct T_unitdata_ind) + sizeof (sin_t));
3786 		tudi->OPT_length = udi_size;
3787 		sin = (sin_t *)&tudi[1];
3788 		sin->sin_addr.s_addr = ((ipha_t *)rptr)->ipha_src;
3789 		sin->sin_port =	udpha->uha_src_port;
3790 		sin->sin_family = udp->udp_family;
3791 		*(uint32_t *)&sin->sin_zero[0] = 0;
3792 		*(uint32_t *)&sin->sin_zero[4] = 0;
3793 
3794 		/*
3795 		 * Add options if IP_RECVDSTADDR, IP_RECVIF, IP_RECVSLLA or
3796 		 * IP_RECVTTL has been set.
3797 		 */
3798 		if (udi_size != 0) {
3799 			/*
3800 			 * Copy in destination address before options to avoid
3801 			 * any padding issues.
3802 			 */
3803 			char *dstopt;
3804 
3805 			dstopt = (char *)&sin[1];
3806 			if (udp->udp_recvdstaddr) {
3807 				struct T_opthdr *toh;
3808 				ipaddr_t *dstptr;
3809 
3810 				toh = (struct T_opthdr *)dstopt;
3811 				toh->level = IPPROTO_IP;
3812 				toh->name = IP_RECVDSTADDR;
3813 				toh->len = sizeof (struct T_opthdr) +
3814 				    sizeof (ipaddr_t);
3815 				toh->status = 0;
3816 				dstopt += sizeof (struct T_opthdr);
3817 				dstptr = (ipaddr_t *)dstopt;
3818 				*dstptr = ((ipha_t *)rptr)->ipha_dst;
3819 				dstopt += sizeof (ipaddr_t);
3820 				udi_size -= toh->len;
3821 			}
3822 
3823 			if (udp->udp_recvslla && (pinfo != NULL) &&
3824 			    (pinfo->in_pkt_flags & IPF_RECVSLLA)) {
3825 
3826 				struct T_opthdr *toh;
3827 				struct sockaddr_dl	*dstptr;
3828 
3829 				toh = (struct T_opthdr *)dstopt;
3830 				toh->level = IPPROTO_IP;
3831 				toh->name = IP_RECVSLLA;
3832 				toh->len = sizeof (struct T_opthdr) +
3833 					sizeof (struct sockaddr_dl);
3834 				toh->status = 0;
3835 				dstopt += sizeof (struct T_opthdr);
3836 				dstptr = (struct sockaddr_dl *)dstopt;
3837 				bcopy(&pinfo->in_pkt_slla, dstptr,
3838 				    sizeof (struct sockaddr_dl));
3839 				dstopt += sizeof (struct sockaddr_dl);
3840 				udi_size -= toh->len;
3841 			}
3842 
3843 			if (udp->udp_recvif && (pinfo != NULL) &&
3844 			    (pinfo->in_pkt_flags & IPF_RECVIF)) {
3845 
3846 				struct T_opthdr *toh;
3847 				uint_t		*dstptr;
3848 
3849 				toh = (struct T_opthdr *)dstopt;
3850 				toh->level = IPPROTO_IP;
3851 				toh->name = IP_RECVIF;
3852 				toh->len = sizeof (struct T_opthdr) +
3853 					sizeof (uint_t);
3854 				toh->status = 0;
3855 				dstopt += sizeof (struct T_opthdr);
3856 				dstptr = (uint_t *)dstopt;
3857 				*dstptr = pinfo->in_pkt_ifindex;
3858 				dstopt += sizeof (uint_t);
3859 				udi_size -= toh->len;
3860 			}
3861 
3862 			if (cr != NULL) {
3863 				struct T_opthdr *toh;
3864 
3865 				toh = (struct T_opthdr *)dstopt;
3866 				toh->level = SOL_SOCKET;
3867 				toh->name = SCM_UCRED;
3868 				toh->len = sizeof (struct T_opthdr) + ucredsize;
3869 				toh->status = 0;
3870 				(void) cred2ucred(cr, cpid, &toh[1]);
3871 				dstopt += toh->len;
3872 				udi_size -= toh->len;
3873 			}
3874 
3875 			if (udp->udp_recvttl) {
3876 				struct	T_opthdr *toh;
3877 				uint8_t	*dstptr;
3878 
3879 				toh = (struct T_opthdr *)dstopt;
3880 				toh->level = IPPROTO_IP;
3881 				toh->name = IP_RECVTTL;
3882 				toh->len = sizeof (struct T_opthdr) +
3883 				    sizeof (uint8_t);
3884 				toh->status = 0;
3885 				dstopt += sizeof (struct T_opthdr);
3886 				dstptr = (uint8_t *)dstopt;
3887 				*dstptr = ((ipha_t *)rptr)->ipha_ttl;
3888 				dstopt += sizeof (uint8_t);
3889 				udi_size -= toh->len;
3890 			}
3891 
3892 			/* Consumed all of allocated space */
3893 			ASSERT(udi_size == 0);
3894 		}
3895 	} else {
3896 		sin6_t *sin6;
3897 
3898 		/*
3899 		 * Handle both IPv4 and IPv6 packets for IPv6 sockets.
3900 		 *
3901 		 * Normally we only send up the address. If receiving of any
3902 		 * optional receive side information is enabled, we also send
3903 		 * that up as options.
3904 		 * [ Only udp_rput_other() handles packets that contain IP
3905 		 * options so code to account for does not appear immediately
3906 		 * below but elsewhere ]
3907 		 */
3908 		udi_size = sizeof (struct T_unitdata_ind) + sizeof (sin6_t);
3909 
3910 		if (ipp.ipp_fields & (IPPF_HOPOPTS|IPPF_DSTOPTS|IPPF_RTDSTOPTS|
3911 		    IPPF_RTHDR|IPPF_IFINDEX)) {
3912 			if (udp->udp_ipv6_recvhopopts &&
3913 			    (ipp.ipp_fields & IPPF_HOPOPTS)) {
3914 				udi_size += sizeof (struct T_opthdr) +
3915 				    ipp.ipp_hopoptslen;
3916 			}
3917 			if ((udp->udp_ipv6_recvdstopts ||
3918 				udp->udp_old_ipv6_recvdstopts) &&
3919 			    (ipp.ipp_fields & IPPF_DSTOPTS)) {
3920 				udi_size += sizeof (struct T_opthdr) +
3921 				    ipp.ipp_dstoptslen;
3922 			}
3923 			if (((udp->udp_ipv6_recvdstopts &&
3924 			    udp->udp_ipv6_recvrthdr &&
3925 			    (ipp.ipp_fields & IPPF_RTHDR)) ||
3926 			    udp->udp_ipv6_recvrthdrdstopts) &&
3927 			    (ipp.ipp_fields & IPPF_RTDSTOPTS)) {
3928 				udi_size += sizeof (struct T_opthdr) +
3929 				    ipp.ipp_rtdstoptslen;
3930 			}
3931 			if (udp->udp_ipv6_recvrthdr &&
3932 			    (ipp.ipp_fields & IPPF_RTHDR)) {
3933 				udi_size += sizeof (struct T_opthdr) +
3934 				    ipp.ipp_rthdrlen;
3935 			}
3936 			if (udp->udp_ipv6_recvpktinfo &&
3937 			    (ipp.ipp_fields & IPPF_IFINDEX)) {
3938 				udi_size += sizeof (struct T_opthdr) +
3939 				    sizeof (struct in6_pktinfo);
3940 			}
3941 
3942 		}
3943 		if (udp->udp_recvucred && (cr = DB_CRED(mp)) != NULL) {
3944 			udi_size += sizeof (struct T_opthdr) + ucredsize;
3945 			cpid = DB_CPID(mp);
3946 		}
3947 
3948 		if (udp->udp_ipv6_recvhoplimit)
3949 			udi_size += sizeof (struct T_opthdr) + sizeof (int);
3950 
3951 		if (udp->udp_ipv6_recvtclass)
3952 			udi_size += sizeof (struct T_opthdr) + sizeof (int);
3953 
3954 		mp1 = allocb(udi_size, BPRI_MED);
3955 		if (mp1 == NULL) {
3956 			freemsg(mp);
3957 			if (options_mp != NULL)
3958 				freeb(options_mp);
3959 			TRACE_2(TR_FAC_UDP, TR_UDP_RPUT_END,
3960 				"udp_rput_end: q %p (%S)", q, "allocbfail");
3961 			BUMP_MIB(&udp_mib, udpInErrors);
3962 			return;
3963 		}
3964 		mp1->b_cont = mp;
3965 		mp = mp1;
3966 		mp->b_datap->db_type = M_PROTO;
3967 		tudi = (struct T_unitdata_ind *)mp->b_rptr;
3968 		mp->b_wptr = (uchar_t *)tudi + udi_size;
3969 		tudi->PRIM_type = T_UNITDATA_IND;
3970 		tudi->SRC_length = sizeof (sin6_t);
3971 		tudi->SRC_offset = sizeof (struct T_unitdata_ind);
3972 		tudi->OPT_offset = sizeof (struct T_unitdata_ind) +
3973 		    sizeof (sin6_t);
3974 		udi_size -= (sizeof (struct T_unitdata_ind) + sizeof (sin6_t));
3975 		tudi->OPT_length = udi_size;
3976 		sin6 = (sin6_t *)&tudi[1];
3977 		if (ipversion == IPV4_VERSION) {
3978 			in6_addr_t v6dst;
3979 
3980 			IN6_IPADDR_TO_V4MAPPED(((ipha_t *)rptr)->ipha_src,
3981 			    &sin6->sin6_addr);
3982 			IN6_IPADDR_TO_V4MAPPED(((ipha_t *)rptr)->ipha_dst,
3983 			    &v6dst);
3984 			sin6->sin6_flowinfo = 0;
3985 			sin6->sin6_scope_id = 0;
3986 			sin6->__sin6_src_id = ip_srcid_find_addr(&v6dst,
3987 			    udp->udp_zoneid);
3988 		} else {
3989 			sin6->sin6_addr = ip6h->ip6_src;
3990 			/* No sin6_flowinfo per API */
3991 			sin6->sin6_flowinfo = 0;
3992 			/* For link-scope source pass up scope id */
3993 			if ((ipp.ipp_fields & IPPF_IFINDEX) &&
3994 			    IN6_IS_ADDR_LINKSCOPE(&ip6h->ip6_src))
3995 				sin6->sin6_scope_id = ipp.ipp_ifindex;
3996 			else
3997 				sin6->sin6_scope_id = 0;
3998 			sin6->__sin6_src_id =
3999 			    ip_srcid_find_addr(&ip6h->ip6_dst, udp->udp_zoneid);
4000 		}
4001 		sin6->sin6_port = udpha->uha_src_port;
4002 		sin6->sin6_family = udp->udp_family;
4003 
4004 		if (udi_size != 0) {
4005 			uchar_t *dstopt;
4006 
4007 			dstopt = (uchar_t *)&sin6[1];
4008 			if (udp->udp_ipv6_recvpktinfo &&
4009 			    (ipp.ipp_fields & IPPF_IFINDEX)) {
4010 				struct T_opthdr *toh;
4011 				struct in6_pktinfo *pkti;
4012 
4013 				toh = (struct T_opthdr *)dstopt;
4014 				toh->level = IPPROTO_IPV6;
4015 				toh->name = IPV6_PKTINFO;
4016 				toh->len = sizeof (struct T_opthdr) +
4017 				    sizeof (*pkti);
4018 				toh->status = 0;
4019 				dstopt += sizeof (struct T_opthdr);
4020 				pkti = (struct in6_pktinfo *)dstopt;
4021 				if (ipversion == IPV6_VERSION)
4022 					pkti->ipi6_addr = ip6h->ip6_dst;
4023 				else
4024 					IN6_IPADDR_TO_V4MAPPED(
4025 						((ipha_t *)rptr)->ipha_dst,
4026 						    &pkti->ipi6_addr);
4027 				pkti->ipi6_ifindex = ipp.ipp_ifindex;
4028 				dstopt += sizeof (*pkti);
4029 				udi_size -= toh->len;
4030 			}
4031 			if (udp->udp_ipv6_recvhoplimit) {
4032 				struct T_opthdr *toh;
4033 
4034 				toh = (struct T_opthdr *)dstopt;
4035 				toh->level = IPPROTO_IPV6;
4036 				toh->name = IPV6_HOPLIMIT;
4037 				toh->len = sizeof (struct T_opthdr) +
4038 				    sizeof (uint_t);
4039 				toh->status = 0;
4040 				dstopt += sizeof (struct T_opthdr);
4041 				if (ipversion == IPV6_VERSION)
4042 					*(uint_t *)dstopt = ip6h->ip6_hops;
4043 				else
4044 					*(uint_t *)dstopt =
4045 					    ((ipha_t *)rptr)->ipha_ttl;
4046 				dstopt += sizeof (uint_t);
4047 				udi_size -= toh->len;
4048 			}
4049 			if (udp->udp_ipv6_recvtclass) {
4050 				struct T_opthdr *toh;
4051 
4052 				toh = (struct T_opthdr *)dstopt;
4053 				toh->level = IPPROTO_IPV6;
4054 				toh->name = IPV6_TCLASS;
4055 				toh->len = sizeof (struct T_opthdr) +
4056 				    sizeof (uint_t);
4057 				toh->status = 0;
4058 				dstopt += sizeof (struct T_opthdr);
4059 				if (ipversion == IPV6_VERSION) {
4060 					*(uint_t *)dstopt =
4061 					IPV6_FLOW_TCLASS(ip6h->ip6_flow);
4062 				} else {
4063 					ipha_t *ipha = (ipha_t *)rptr;
4064 					*(uint_t *)dstopt =
4065 					    ipha->ipha_type_of_service;
4066 				}
4067 				dstopt += sizeof (uint_t);
4068 				udi_size -= toh->len;
4069 			}
4070 			if (udp->udp_ipv6_recvhopopts &&
4071 			    (ipp.ipp_fields & IPPF_HOPOPTS)) {
4072 				struct T_opthdr *toh;
4073 
4074 				toh = (struct T_opthdr *)dstopt;
4075 				toh->level = IPPROTO_IPV6;
4076 				toh->name = IPV6_HOPOPTS;
4077 				toh->len = sizeof (struct T_opthdr) +
4078 				    ipp.ipp_hopoptslen;
4079 				toh->status = 0;
4080 				dstopt += sizeof (struct T_opthdr);
4081 				bcopy(ipp.ipp_hopopts, dstopt,
4082 				    ipp.ipp_hopoptslen);
4083 				dstopt += ipp.ipp_hopoptslen;
4084 				udi_size -= toh->len;
4085 			}
4086 			if (udp->udp_ipv6_recvdstopts &&
4087 			    udp->udp_ipv6_recvrthdr &&
4088 			    (ipp.ipp_fields & IPPF_RTHDR) &&
4089 			    (ipp.ipp_fields & IPPF_RTDSTOPTS)) {
4090 				struct T_opthdr *toh;
4091 
4092 				toh = (struct T_opthdr *)dstopt;
4093 				toh->level = IPPROTO_IPV6;
4094 				toh->name = IPV6_DSTOPTS;
4095 				toh->len = sizeof (struct T_opthdr) +
4096 				    ipp.ipp_rtdstoptslen;
4097 				toh->status = 0;
4098 				dstopt += sizeof (struct T_opthdr);
4099 				bcopy(ipp.ipp_rtdstopts, dstopt,
4100 				    ipp.ipp_rtdstoptslen);
4101 				dstopt += ipp.ipp_rtdstoptslen;
4102 				udi_size -= toh->len;
4103 			}
4104 			if (udp->udp_ipv6_recvrthdr &&
4105 			    (ipp.ipp_fields & IPPF_RTHDR)) {
4106 				struct T_opthdr *toh;
4107 
4108 				toh = (struct T_opthdr *)dstopt;
4109 				toh->level = IPPROTO_IPV6;
4110 				toh->name = IPV6_RTHDR;
4111 				toh->len = sizeof (struct T_opthdr) +
4112 				    ipp.ipp_rthdrlen;
4113 				toh->status = 0;
4114 				dstopt += sizeof (struct T_opthdr);
4115 				bcopy(ipp.ipp_rthdr, dstopt, ipp.ipp_rthdrlen);
4116 				dstopt += ipp.ipp_rthdrlen;
4117 				udi_size -= toh->len;
4118 			}
4119 			if (udp->udp_ipv6_recvdstopts &&
4120 			    (ipp.ipp_fields & IPPF_DSTOPTS)) {
4121 				struct T_opthdr *toh;
4122 
4123 				toh = (struct T_opthdr *)dstopt;
4124 				toh->level = IPPROTO_IPV6;
4125 				toh->name = IPV6_DSTOPTS;
4126 				toh->len = sizeof (struct T_opthdr) +
4127 				    ipp.ipp_dstoptslen;
4128 				toh->status = 0;
4129 				dstopt += sizeof (struct T_opthdr);
4130 				bcopy(ipp.ipp_dstopts, dstopt,
4131 				    ipp.ipp_dstoptslen);
4132 				dstopt += ipp.ipp_dstoptslen;
4133 				udi_size -= toh->len;
4134 			}
4135 
4136 			if (cr != NULL) {
4137 				struct T_opthdr *toh;
4138 
4139 				toh = (struct T_opthdr *)dstopt;
4140 				toh->level = SOL_SOCKET;
4141 				toh->name = SCM_UCRED;
4142 				toh->len = sizeof (struct T_opthdr) + ucredsize;
4143 				toh->status = 0;
4144 				(void) cred2ucred(cr, cpid, &toh[1]);
4145 				dstopt += toh->len;
4146 				udi_size -= toh->len;
4147 			}
4148 			/* Consumed all of allocated space */
4149 			ASSERT(udi_size == 0);
4150 		}
4151 #undef	sin6
4152 		/* No IP_RECVDSTADDR for IPv6. */
4153 	}
4154 
4155 	BUMP_MIB(&udp_mib, udpInDatagrams);
4156 	TRACE_2(TR_FAC_UDP, TR_UDP_RPUT_END,
4157 		"udp_rput_end: q %p (%S)", q, "end");
4158 	if (options_mp != NULL)
4159 		freeb(options_mp);
4160 	putnext(q, mp);
4161 }
4162 
4163 /*
4164  * Process non-M_DATA messages as well as M_DATA messages that requires
4165  * modifications to udp_ip_rcv_options i.e. IPv4 packets with IP options.
4166  */
4167 static void
4168 udp_rput_other(queue_t *q, mblk_t *mp)
4169 {
4170 	struct T_unitdata_ind	*tudi;
4171 	mblk_t			*mp1;
4172 	uchar_t			*rptr;
4173 	uchar_t			*new_rptr;
4174 	int			hdr_length;
4175 	int			udi_size;	/* Size of T_unitdata_ind */
4176 	int			opt_len;	/* Length of IP options */
4177 	sin_t			*sin;
4178 	struct T_error_ack	*tea;
4179 	udp_t			*udp;
4180 	mblk_t			*options_mp = NULL;
4181 	in_pktinfo_t		*pinfo;
4182 	boolean_t		recv_on = B_FALSE;
4183 	cred_t			*cr = NULL;
4184 	pid_t			cpid;
4185 
4186 	TRACE_2(TR_FAC_UDP, TR_UDP_RPUT_START,
4187 	    "udp_rput_other: q %p mp %p", q, mp);
4188 
4189 	ASSERT(OK_32PTR(mp->b_rptr));
4190 	udp = (udp_t *)q->q_ptr;
4191 	rptr = mp->b_rptr;
4192 
4193 	switch (mp->b_datap->db_type) {
4194 	case M_CTL:
4195 		/*
4196 		 * We are here only if IP_RECVSLLA and/or IP_RECVIF are set
4197 		 */
4198 		recv_on = B_TRUE;
4199 		options_mp = mp;
4200 		pinfo = (in_pktinfo_t *)options_mp->b_rptr;
4201 
4202 		/*
4203 		 * The actual data is in mp->b_cont
4204 		 */
4205 		mp = mp->b_cont;
4206 		ASSERT(OK_32PTR(mp->b_rptr));
4207 		rptr = mp->b_rptr;
4208 		break;
4209 	case M_DATA:
4210 		/*
4211 		 * M_DATA messages contain IPv4 datagrams.  They are handled
4212 		 * after this switch.
4213 		 */
4214 		break;
4215 	case M_PROTO:
4216 	case M_PCPROTO:
4217 		/* M_PROTO messages contain some type of TPI message. */
4218 		ASSERT((uintptr_t)(mp->b_wptr - rptr) <= (uintptr_t)INT_MAX);
4219 		if (mp->b_wptr - rptr < sizeof (t_scalar_t)) {
4220 			freemsg(mp);
4221 			TRACE_2(TR_FAC_UDP, TR_UDP_RPUT_END,
4222 			    "udp_rput_other_end: q %p (%S)", q, "protoshort");
4223 			return;
4224 		}
4225 		tea = (struct T_error_ack *)rptr;
4226 
4227 		switch (tea->PRIM_type) {
4228 		case T_ERROR_ACK:
4229 			switch (tea->ERROR_prim) {
4230 			case O_T_BIND_REQ:
4231 			case T_BIND_REQ: {
4232 				/*
4233 				 * If our O_T_BIND_REQ/T_BIND_REQ fails,
4234 				 * clear out the associated port and source
4235 				 * address before passing the message
4236 				 * upstream. If this was caused by a T_CONN_REQ
4237 				 * revert back to bound state.
4238 				 */
4239 				udp_fanout_t	*udpf;
4240 
4241 				udpf = &udp_bind_fanout[
4242 				    UDP_BIND_HASH(udp->udp_port)];
4243 				mutex_enter(&udpf->uf_lock);
4244 				if (udp->udp_state == TS_DATA_XFER) {
4245 					/* Connect failed */
4246 					tea->ERROR_prim = T_CONN_REQ;
4247 					/* Revert back to the bound source */
4248 					udp->udp_v6src = udp->udp_bound_v6src;
4249 					udp->udp_state = TS_IDLE;
4250 					mutex_exit(&udpf->uf_lock);
4251 					if (udp->udp_family == AF_INET6)
4252 						(void) udp_build_hdrs(q, udp);
4253 					break;
4254 				}
4255 
4256 				if (udp->udp_discon_pending) {
4257 					tea->ERROR_prim = T_DISCON_REQ;
4258 					udp->udp_discon_pending = 0;
4259 				}
4260 				V6_SET_ZERO(udp->udp_v6src);
4261 				V6_SET_ZERO(udp->udp_bound_v6src);
4262 				udp->udp_state = TS_UNBND;
4263 				udp_bind_hash_remove(udp, B_TRUE);
4264 				udp->udp_port = 0;
4265 				mutex_exit(&udpf->uf_lock);
4266 				if (udp->udp_family == AF_INET6)
4267 					(void) udp_build_hdrs(q, udp);
4268 				break;
4269 			}
4270 			default:
4271 				break;
4272 			}
4273 			break;
4274 		case T_BIND_ACK:
4275 			udp_rput_bind_ack(q, mp);
4276 			return;
4277 
4278 		case T_OPTMGMT_ACK:
4279 		case T_OK_ACK:
4280 			break;
4281 		default:
4282 			freemsg(mp);
4283 			return;
4284 		}
4285 		putnext(q, mp);
4286 		return;
4287 	}
4288 
4289 	/*
4290 	 * This is the inbound data path.
4291 	 * First, we make sure the data contains both IP and UDP headers.
4292 	 *
4293 	 * This handle IPv4 packets for only AF_INET sockets.
4294 	 * AF_INET6 sockets can never access udp_ip_rcv_options thus there
4295 	 * is no need saving the options.
4296 	 */
4297 	ASSERT(IPH_HDR_VERSION((ipha_t *)rptr) == IPV4_VERSION);
4298 	hdr_length = IPH_HDR_LENGTH(rptr) + UDPH_SIZE;
4299 	if (mp->b_wptr - rptr < hdr_length) {
4300 		if (!pullupmsg(mp, hdr_length)) {
4301 			freemsg(mp);
4302 			if (options_mp != NULL)
4303 				freeb(options_mp);
4304 			BUMP_MIB(&udp_mib, udpInErrors);
4305 			TRACE_2(TR_FAC_UDP, TR_UDP_RPUT_END,
4306 			    "udp_rput_other_end: q %p (%S)", q, "hdrshort");
4307 			BUMP_MIB(&udp_mib, udpInErrors);
4308 			return;
4309 		}
4310 		rptr = mp->b_rptr;
4311 	}
4312 	/* Walk past the headers. */
4313 	new_rptr = rptr + hdr_length;
4314 	if (!udp->udp_rcvhdr)
4315 		mp->b_rptr = new_rptr;
4316 
4317 	/* Save the options if any */
4318 	opt_len = hdr_length - (IP_SIMPLE_HDR_LENGTH + UDPH_SIZE);
4319 	if (opt_len > 0) {
4320 		if (opt_len > udp->udp_ip_rcv_options_len) {
4321 			if (udp->udp_ip_rcv_options_len)
4322 				mi_free((char *)udp->udp_ip_rcv_options);
4323 			udp->udp_ip_rcv_options_len = 0;
4324 			udp->udp_ip_rcv_options =
4325 			    (uchar_t *)mi_alloc(opt_len, BPRI_HI);
4326 			if (udp->udp_ip_rcv_options)
4327 				udp->udp_ip_rcv_options_len = opt_len;
4328 		}
4329 		if (udp->udp_ip_rcv_options_len) {
4330 			bcopy(rptr + IP_SIMPLE_HDR_LENGTH,
4331 			    udp->udp_ip_rcv_options, opt_len);
4332 			/* Adjust length if we are resusing the space */
4333 			udp->udp_ip_rcv_options_len = opt_len;
4334 		}
4335 	} else if (udp->udp_ip_rcv_options_len) {
4336 		mi_free((char *)udp->udp_ip_rcv_options);
4337 		udp->udp_ip_rcv_options = NULL;
4338 		udp->udp_ip_rcv_options_len = 0;
4339 	}
4340 
4341 	/*
4342 	 * Normally only send up the address.
4343 	 * If IP_RECVDSTADDR is set we include the destination IP
4344 	 * address as an option. With IP_RECVOPTS we include all
4345 	 * the IP options.
4346 	 */
4347 	udi_size = sizeof (struct T_unitdata_ind) + sizeof (sin_t);
4348 	if (udp->udp_recvdstaddr) {
4349 		udi_size += sizeof (struct T_opthdr) + sizeof (struct in_addr);
4350 	}
4351 	if (udp->udp_recvopts && opt_len > 0)
4352 		udi_size += sizeof (struct T_opthdr) + opt_len;
4353 
4354 	/*
4355 	 * If the IP_RECVSLLA or the IP_RECVIF is set then allocate
4356 	 * space accordingly
4357 	 */
4358 	if (udp->udp_recvif && recv_on &&
4359 	    (pinfo->in_pkt_flags & IPF_RECVIF)) {
4360 		udi_size += sizeof (struct T_opthdr) +
4361 		    sizeof (uint_t);
4362 	}
4363 
4364 	if (udp->udp_recvslla && recv_on &&
4365 	    (pinfo->in_pkt_flags & IPF_RECVSLLA)) {
4366 		udi_size += sizeof (struct T_opthdr) +
4367 		    sizeof (struct sockaddr_dl);
4368 	}
4369 
4370 	if (udp->udp_recvucred && (cr = DB_CRED(mp)) != NULL) {
4371 		udi_size += sizeof (struct T_opthdr) + ucredsize;
4372 		cpid = DB_CPID(mp);
4373 	}
4374 	/*
4375 	 * If IP_RECVTTL is set allocate the appropriate sized buffer
4376 	 */
4377 	if (udp->udp_recvttl) {
4378 		udi_size += sizeof (struct T_opthdr) + sizeof (uint8_t);
4379 	}
4380 
4381 	/* Allocate a message block for the T_UNITDATA_IND structure. */
4382 	mp1 = allocb(udi_size, BPRI_MED);
4383 	if (mp1 == NULL) {
4384 		freemsg(mp);
4385 		if (options_mp != NULL)
4386 			freeb(options_mp);
4387 		TRACE_2(TR_FAC_UDP, TR_UDP_RPUT_END,
4388 			"udp_rput_other_end: q %p (%S)", q, "allocbfail");
4389 		BUMP_MIB(&udp_mib, udpInErrors);
4390 		return;
4391 	}
4392 	mp1->b_cont = mp;
4393 	mp = mp1;
4394 	mp->b_datap->db_type = M_PROTO;
4395 	tudi = (struct T_unitdata_ind *)mp->b_rptr;
4396 	mp->b_wptr = (uchar_t *)tudi + udi_size;
4397 	tudi->PRIM_type = T_UNITDATA_IND;
4398 	tudi->SRC_length = sizeof (sin_t);
4399 	tudi->SRC_offset = sizeof (struct T_unitdata_ind);
4400 	tudi->OPT_offset = sizeof (struct T_unitdata_ind) + sizeof (sin_t);
4401 	udi_size -= (sizeof (struct T_unitdata_ind) + sizeof (sin_t));
4402 	tudi->OPT_length = udi_size;
4403 
4404 	sin = (sin_t *)&tudi[1];
4405 	sin->sin_addr.s_addr = ((ipha_t *)rptr)->ipha_src;
4406 	sin->sin_port =	((in_port_t *)
4407 	    new_rptr)[-(UDPH_SIZE/sizeof (in_port_t))];
4408 	sin->sin_family = AF_INET;
4409 	*(uint32_t *)&sin->sin_zero[0] = 0;
4410 	*(uint32_t *)&sin->sin_zero[4] = 0;
4411 
4412 	/*
4413 	 * Add options if IP_RECVDSTADDR, IP_RECVIF, IP_RECVSLLA or
4414 	 * IP_RECVTTL has been set.
4415 	 */
4416 	if (udi_size != 0) {
4417 		/*
4418 		 * Copy in destination address before options to avoid any
4419 		 * padding issues.
4420 		 */
4421 		char *dstopt;
4422 
4423 		dstopt = (char *)&sin[1];
4424 		if (udp->udp_recvdstaddr) {
4425 			struct T_opthdr *toh;
4426 			ipaddr_t *dstptr;
4427 
4428 			toh = (struct T_opthdr *)dstopt;
4429 			toh->level = IPPROTO_IP;
4430 			toh->name = IP_RECVDSTADDR;
4431 			toh->len = sizeof (struct T_opthdr) + sizeof (ipaddr_t);
4432 			toh->status = 0;
4433 			dstopt += sizeof (struct T_opthdr);
4434 			dstptr = (ipaddr_t *)dstopt;
4435 			*dstptr = (((ipaddr_t *)rptr)[4]);
4436 			dstopt += sizeof (ipaddr_t);
4437 			udi_size -= toh->len;
4438 		}
4439 		if (udp->udp_recvopts && udi_size != 0) {
4440 			struct T_opthdr *toh;
4441 
4442 			toh = (struct T_opthdr *)dstopt;
4443 			toh->level = IPPROTO_IP;
4444 			toh->name = IP_RECVOPTS;
4445 			toh->len = sizeof (struct T_opthdr) + opt_len;
4446 			toh->status = 0;
4447 			dstopt += sizeof (struct T_opthdr);
4448 			bcopy(rptr + IP_SIMPLE_HDR_LENGTH, dstopt, opt_len);
4449 			dstopt += opt_len;
4450 			udi_size -= toh->len;
4451 		}
4452 
4453 		if (udp->udp_recvslla && recv_on &&
4454 		    (pinfo->in_pkt_flags & IPF_RECVSLLA)) {
4455 
4456 			struct T_opthdr *toh;
4457 			struct sockaddr_dl	*dstptr;
4458 
4459 			toh = (struct T_opthdr *)dstopt;
4460 			toh->level = IPPROTO_IP;
4461 			toh->name = IP_RECVSLLA;
4462 			toh->len = sizeof (struct T_opthdr) +
4463 			    sizeof (struct sockaddr_dl);
4464 			toh->status = 0;
4465 			dstopt += sizeof (struct T_opthdr);
4466 			dstptr = (struct sockaddr_dl *)dstopt;
4467 			bcopy(&pinfo->in_pkt_slla, dstptr,
4468 			    sizeof (struct sockaddr_dl));
4469 			dstopt += sizeof (struct sockaddr_dl);
4470 			udi_size -= toh->len;
4471 		}
4472 
4473 		if (udp->udp_recvif && recv_on &&
4474 		    (pinfo->in_pkt_flags & IPF_RECVIF)) {
4475 
4476 			struct T_opthdr *toh;
4477 			uint_t		*dstptr;
4478 
4479 			toh = (struct T_opthdr *)dstopt;
4480 			toh->level = IPPROTO_IP;
4481 			toh->name = IP_RECVIF;
4482 			toh->len = sizeof (struct T_opthdr) +
4483 			    sizeof (uint_t);
4484 			toh->status = 0;
4485 			dstopt += sizeof (struct T_opthdr);
4486 			dstptr = (uint_t *)dstopt;
4487 			*dstptr = pinfo->in_pkt_ifindex;
4488 			dstopt += sizeof (uint_t);
4489 			udi_size -= toh->len;
4490 		}
4491 
4492 		if (cr != NULL) {
4493 			struct T_opthdr *toh;
4494 
4495 			toh = (struct T_opthdr *)dstopt;
4496 			toh->level = SOL_SOCKET;
4497 			toh->name = SCM_UCRED;
4498 			toh->len = sizeof (struct T_opthdr) + ucredsize;
4499 			toh->status = 0;
4500 			(void) cred2ucred(cr, cpid, &toh[1]);
4501 			dstopt += toh->len;
4502 			udi_size -= toh->len;
4503 		}
4504 
4505 		if (udp->udp_recvttl) {
4506 			struct	T_opthdr *toh;
4507 			uint8_t	*dstptr;
4508 
4509 			toh = (struct T_opthdr *)dstopt;
4510 			toh->level = IPPROTO_IP;
4511 			toh->name = IP_RECVTTL;
4512 			toh->len = sizeof (struct T_opthdr) +
4513 			    sizeof (uint8_t);
4514 			toh->status = 0;
4515 			dstopt += sizeof (struct T_opthdr);
4516 			dstptr = (uint8_t *)dstopt;
4517 			*dstptr = ((ipha_t *)rptr)->ipha_ttl;
4518 			dstopt += sizeof (uint8_t);
4519 			udi_size -= toh->len;
4520 		}
4521 
4522 		ASSERT(udi_size == 0);	/* "Consumed" all of allocated space */
4523 	}
4524 	BUMP_MIB(&udp_mib, udpInDatagrams);
4525 	TRACE_2(TR_FAC_UDP, TR_UDP_RPUT_END,
4526 	    "udp_rput_other_end: q %p (%S)", q, "end");
4527 	if (options_mp != NULL)
4528 		freeb(options_mp);
4529 	putnext(q, mp);
4530 }
4531 
4532 /*
4533  * Process a T_BIND_ACK
4534  */
4535 static void
4536 udp_rput_bind_ack(queue_t *q, mblk_t *mp)
4537 {
4538 	udp_t	*udp = (udp_t *)q->q_ptr;
4539 	mblk_t	*mp1;
4540 	ire_t	*ire;
4541 	struct T_bind_ack *tba;
4542 	uchar_t *addrp;
4543 	ipa_conn_t	*ac;
4544 	ipa6_conn_t	*ac6;
4545 
4546 	if (udp->udp_discon_pending)
4547 		udp->udp_discon_pending = 0;
4548 
4549 	/*
4550 	 * If a broadcast/multicast address was bound set
4551 	 * the source address to 0.
4552 	 * This ensures no datagrams with broadcast address
4553 	 * as source address are emitted (which would violate
4554 	 * RFC1122 - Hosts requirements)
4555 	 *
4556 	 * Note that when connecting the returned IRE is
4557 	 * for the destination address and we only perform
4558 	 * the broadcast check for the source address (it
4559 	 * is OK to connect to a broadcast/multicast address.)
4560 	 */
4561 	mp1 = mp->b_cont;
4562 	if (mp1 != NULL && mp1->b_datap->db_type == IRE_DB_TYPE) {
4563 		ire = (ire_t *)mp1->b_rptr;
4564 
4565 		/*
4566 		 * Note: we get IRE_BROADCAST for IPv6 to "mark" a multicast
4567 		 * local address.
4568 		 */
4569 		if (ire->ire_type == IRE_BROADCAST &&
4570 		    udp->udp_state != TS_DATA_XFER) {
4571 			/* This was just a local bind to a broadcast addr */
4572 			V6_SET_ZERO(udp->udp_v6src);
4573 			if (udp->udp_family == AF_INET6)
4574 				(void) udp_build_hdrs(q, udp);
4575 		} else if (V6_OR_V4_INADDR_ANY(udp->udp_v6src)) {
4576 			/*
4577 			 * Local address not yet set - pick it from the
4578 			 * T_bind_ack
4579 			 */
4580 			tba = (struct T_bind_ack *)mp->b_rptr;
4581 			addrp = &mp->b_rptr[tba->ADDR_offset];
4582 			switch (udp->udp_family) {
4583 			case AF_INET:
4584 				if (tba->ADDR_length == sizeof (ipa_conn_t)) {
4585 					ac = (ipa_conn_t *)addrp;
4586 				} else {
4587 					ASSERT(tba->ADDR_length ==
4588 					    sizeof (ipa_conn_x_t));
4589 					ac = &((ipa_conn_x_t *)addrp)->acx_conn;
4590 				}
4591 				IN6_IPADDR_TO_V4MAPPED(ac->ac_laddr,
4592 				    &udp->udp_v6src);
4593 				break;
4594 			case AF_INET6:
4595 				if (tba->ADDR_length == sizeof (ipa6_conn_t)) {
4596 					ac6 = (ipa6_conn_t *)addrp;
4597 				} else {
4598 					ASSERT(tba->ADDR_length ==
4599 					    sizeof (ipa6_conn_x_t));
4600 					ac6 = &((ipa6_conn_x_t *)
4601 					    addrp)->ac6x_conn;
4602 				}
4603 				udp->udp_v6src = ac6->ac6_laddr;
4604 				(void) udp_build_hdrs(q, udp);
4605 				break;
4606 			}
4607 		}
4608 		mp1 = mp1->b_cont;
4609 	}
4610 	/*
4611 	 * Look for one or more appended ACK message added by
4612 	 * udp_connect or udp_disconnect.
4613 	 * If none found just send up the T_BIND_ACK.
4614 	 * udp_connect has appended a T_OK_ACK and a T_CONN_CON.
4615 	 * udp_disconnect has appended a T_OK_ACK.
4616 	 */
4617 	if (mp1 != NULL) {
4618 		if (mp->b_cont == mp1)
4619 			mp->b_cont = NULL;
4620 		else {
4621 			ASSERT(mp->b_cont->b_cont == mp1);
4622 			mp->b_cont->b_cont = NULL;
4623 		}
4624 		freemsg(mp);
4625 		mp = mp1;
4626 		while (mp != NULL) {
4627 			mp1 = mp->b_cont;
4628 			mp->b_cont = NULL;
4629 			putnext(q, mp);
4630 			mp = mp1;
4631 		}
4632 		return;
4633 	}
4634 	freemsg(mp->b_cont);
4635 	mp->b_cont = NULL;
4636 	putnext(q, mp);
4637 }
4638 
4639 /*
4640  * return SNMP stuff in buffer in mpdata
4641  */
4642 static int
4643 udp_snmp_get(queue_t *q, mblk_t *mpctl)
4644 {
4645 	mblk_t			*mpdata;
4646 	mblk_t			*mp_conn_ctl;
4647 	mblk_t			*mp6_conn_ctl;
4648 	mblk_t			*mp_conn_data;
4649 	mblk_t			*mp6_conn_data;
4650 	mblk_t			*mp_conn_tail = NULL;
4651 	mblk_t			*mp6_conn_tail = NULL;
4652 	struct opthdr		*optp;
4653 	IDP			idp;
4654 	udp_t			*udp;
4655 	mib2_udpEntry_t		ude;
4656 	mib2_udp6Entry_t	ude6;
4657 	int			state;
4658 	zoneid_t		zoneid;
4659 
4660 	if (mpctl == NULL ||
4661 	    (mpdata = mpctl->b_cont) == NULL ||
4662 	    (mp_conn_ctl = copymsg(mpctl)) == NULL ||
4663 	    (mp6_conn_ctl = copymsg(mpctl)) == NULL) {
4664 		freemsg(mp_conn_ctl);
4665 		return (0);
4666 	}
4667 
4668 	mp_conn_data = mp_conn_ctl->b_cont;
4669 	mp6_conn_data = mp6_conn_ctl->b_cont;
4670 
4671 	udp = (udp_t *)q->q_ptr;
4672 	zoneid = udp->udp_zoneid;
4673 
4674 	/* fixed length structure for IPv4 and IPv6 counters */
4675 	SET_MIB(udp_mib.udpEntrySize, sizeof (mib2_udpEntry_t));
4676 	SET_MIB(udp_mib.udp6EntrySize, sizeof (mib2_udp6Entry_t));
4677 	optp = (struct opthdr *)&mpctl->b_rptr[sizeof (struct T_optmgmt_ack)];
4678 	optp->level = MIB2_UDP;
4679 	optp->name = 0;
4680 	(void) snmp_append_data(mpdata, (char *)&udp_mib, sizeof (udp_mib));
4681 	optp->len = msgdsize(mpdata);
4682 	qreply(q, mpctl);
4683 
4684 	mutex_enter(&udp_g_lock);
4685 	for (idp = mi_first_ptr(&udp_g_head);
4686 	    (udp = (udp_t *)idp) != 0;
4687 	    idp = mi_next_ptr(&udp_g_head, idp)) {
4688 
4689 		if (zoneid != udp->udp_zoneid)
4690 			continue;
4691 
4692 		/* Note that the port numbers are sent in host byte order */
4693 
4694 		if (udp->udp_state == TS_UNBND)
4695 			state = MIB2_UDP_unbound;
4696 		else if (udp->udp_state == TS_IDLE)
4697 			state = MIB2_UDP_idle;
4698 		else if (udp->udp_state == TS_DATA_XFER)
4699 			state = MIB2_UDP_connected;
4700 		else
4701 			state = MIB2_UDP_unknown;
4702 
4703 		/*
4704 		 * Create an IPv4 table entry for IPv4 entries and also
4705 		 * any IPv6 entries which are bound to in6addr_any
4706 		 * (i.e. anything a IPv4 peer could connect/send to).
4707 		 */
4708 		if (udp->udp_ipversion == IPV4_VERSION ||
4709 		    (udp->udp_state <= TS_IDLE &&
4710 		    IN6_IS_ADDR_UNSPECIFIED(&udp->udp_v6src))) {
4711 			ude.udpEntryInfo.ue_state = state;
4712 			/* If in6addr_any this will set it to INADDR_ANY */
4713 			ude.udpLocalAddress = V4_PART_OF_V6(udp->udp_v6src);
4714 			ude.udpLocalPort = ntohs(udp->udp_port);
4715 			if (udp->udp_state == TS_DATA_XFER) {
4716 				/*
4717 				 * Can potentially get here for v6 socket
4718 				 * if another process (say, ping) has just
4719 				 * done a sendto(), changing the state
4720 				 * from the TS_IDLE above to TS_DATA_XFER
4721 				 * by the time we hit this part of the code.
4722 				 */
4723 				ude.udpEntryInfo.ue_RemoteAddress =
4724 				    V4_PART_OF_V6(udp->udp_v6dst);
4725 				ude.udpEntryInfo.ue_RemotePort =
4726 				    ntohs(udp->udp_dstport);
4727 			} else {
4728 				ude.udpEntryInfo.ue_RemoteAddress = 0;
4729 				ude.udpEntryInfo.ue_RemotePort = 0;
4730 			}
4731 			(void) snmp_append_data2(mp_conn_data, &mp_conn_tail,
4732 			    (char *)&ude, sizeof (ude));
4733 		}
4734 		if (udp->udp_ipversion == IPV6_VERSION) {
4735 			ude6.udp6EntryInfo.ue_state  = state;
4736 			ude6.udp6LocalAddress = udp->udp_v6src;
4737 			ude6.udp6LocalPort = ntohs(udp->udp_port);
4738 			ude6.udp6IfIndex = udp->udp_bound_if;
4739 			if (udp->udp_state == TS_DATA_XFER) {
4740 				ude6.udp6EntryInfo.ue_RemoteAddress =
4741 				    udp->udp_v6dst;
4742 				ude6.udp6EntryInfo.ue_RemotePort =
4743 				    ntohs(udp->udp_dstport);
4744 			} else {
4745 				ude6.udp6EntryInfo.ue_RemoteAddress =
4746 				    sin6_null.sin6_addr;
4747 				ude6.udp6EntryInfo.ue_RemotePort = 0;
4748 			}
4749 			(void) snmp_append_data2(mp6_conn_data, &mp6_conn_tail,
4750 			    (char *)&ude6, sizeof (ude6));
4751 		}
4752 	}
4753 	mutex_exit(&udp_g_lock);
4754 
4755 	/* IPv4 UDP endpoints */
4756 	optp = (struct opthdr *)&mp_conn_ctl->b_rptr[
4757 	    sizeof (struct T_optmgmt_ack)];
4758 	optp->level = MIB2_UDP;
4759 	optp->name = MIB2_UDP_ENTRY;
4760 	optp->len = msgdsize(mp_conn_data);
4761 	qreply(q, mp_conn_ctl);
4762 
4763 	/* IPv6 UDP endpoints */
4764 	optp = (struct opthdr *)&mp6_conn_ctl->b_rptr[
4765 	    sizeof (struct T_optmgmt_ack)];
4766 	optp->level = MIB2_UDP6;
4767 	optp->name = MIB2_UDP6_ENTRY;
4768 	optp->len = msgdsize(mp6_conn_data);
4769 	qreply(q, mp6_conn_ctl);
4770 
4771 	return (1);
4772 }
4773 
4774 /*
4775  * Return 0 if invalid set request, 1 otherwise, including non-udp requests.
4776  * NOTE: Per MIB-II, UDP has no writable data.
4777  * TODO:  If this ever actually tries to set anything, it needs to be
4778  * to do the appropriate locking.
4779  */
4780 /* ARGSUSED */
4781 static int
4782 udp_snmp_set(queue_t *q, t_scalar_t level, t_scalar_t name,
4783     uchar_t *ptr, int len)
4784 {
4785 	switch (level) {
4786 	case MIB2_UDP:
4787 		return (0);
4788 	default:
4789 		return (1);
4790 	}
4791 }
4792 
4793 static void
4794 udp_report_item(mblk_t *mp, udp_t *udp)
4795 {
4796 	char *state;
4797 	char addrbuf1[INET6_ADDRSTRLEN];
4798 	char addrbuf2[INET6_ADDRSTRLEN];
4799 	uint_t print_len, buf_len;
4800 
4801 	buf_len = mp->b_datap->db_lim - mp->b_wptr;
4802 	ASSERT(buf_len >= 0);
4803 	if (buf_len == 0)
4804 		return;
4805 
4806 	if (udp->udp_state == TS_UNBND)
4807 		state = "UNBOUND";
4808 	else if (udp->udp_state == TS_IDLE)
4809 		state = "IDLE";
4810 	else if (udp->udp_state == TS_DATA_XFER)
4811 		state = "CONNECTED";
4812 	else
4813 		state = "UnkState";
4814 	print_len = snprintf((char *)mp->b_wptr, buf_len,
4815 	    MI_COL_PTRFMT_STR "%4d %5u %s %s %5u %s\n",
4816 	    (void *)udp, udp->udp_zoneid, ntohs(udp->udp_port),
4817 	    inet_ntop(AF_INET6, &udp->udp_v6src,
4818 		addrbuf1, sizeof (addrbuf1)),
4819 	    inet_ntop(AF_INET6, &udp->udp_v6dst,
4820 		addrbuf2, sizeof (addrbuf2)),
4821 	    ntohs(udp->udp_dstport), state);
4822 	if (print_len < buf_len) {
4823 		mp->b_wptr += print_len;
4824 	} else {
4825 		mp->b_wptr += buf_len;
4826 	}
4827 }
4828 
4829 /* Report for ndd "udp_status" */
4830 /* ARGSUSED */
4831 static int
4832 udp_status_report(queue_t *q, mblk_t *mp, caddr_t cp, cred_t *cr)
4833 {
4834 	IDP	idp;
4835 	udp_t	*udp;
4836 	zoneid_t zoneid;
4837 
4838 	/*
4839 	 * Because of the ndd constraint, at most we can have 64K buffer
4840 	 * to put in all UDP info.  So to be more efficient, just
4841 	 * allocate a 64K buffer here, assuming we need that large buffer.
4842 	 * This may be a problem as any user can read udp_status.  Therefore
4843 	 * we limit the rate of doing this using udp_ndd_get_info_interval.
4844 	 * This should be OK as normal users should not do this too often.
4845 	 */
4846 	if (cr == NULL || secpolicy_net_config(cr, B_TRUE) != 0) {
4847 		if (ddi_get_lbolt() - udp_last_ndd_get_info_time <
4848 		    drv_usectohz(udp_ndd_get_info_interval * 1000)) {
4849 			(void) mi_mpprintf(mp, NDD_TOO_QUICK_MSG);
4850 			return (0);
4851 		}
4852 	}
4853 	if ((mp->b_cont = allocb(ND_MAX_BUF_LEN, BPRI_HI)) == NULL) {
4854 		/* The following may work even if we cannot get a large buf. */
4855 		(void) mi_mpprintf(mp, NDD_OUT_OF_BUF_MSG);
4856 		return (0);
4857 	}
4858 	(void) mi_mpprintf(mp,
4859 	    "UDP     " MI_COL_HDRPAD_STR
4860 	/*   12345678[89ABCDEF] */
4861 	    " zone lport src addr        dest addr       port  state");
4862 	/*    1234 12345 xxx.xxx.xxx.xxx xxx.xxx.xxx.xxx 12345 UNBOUND */
4863 
4864 	udp = (udp_t *)q->q_ptr;
4865 	zoneid = udp->udp_zoneid;
4866 
4867 	mutex_enter(&udp_g_lock);
4868 	for (idp = mi_first_ptr(&udp_g_head);
4869 	    (udp = (udp_t *)idp) != 0;
4870 	    idp = mi_next_ptr(&udp_g_head, idp)) {
4871 
4872 		if (zoneid != GLOBAL_ZONEID &&
4873 		    zoneid != udp->udp_zoneid)
4874 			continue;
4875 
4876 		udp_report_item(mp->b_cont, udp);
4877 	}
4878 	mutex_exit(&udp_g_lock);
4879 	udp_last_ndd_get_info_time = ddi_get_lbolt();
4880 	return (0);
4881 }
4882 
4883 /*
4884  * This routine creates a T_UDERROR_IND message and passes it upstream.
4885  * The address and options are copied from the T_UNITDATA_REQ message
4886  * passed in mp.  This message is freed.
4887  */
4888 static void
4889 udp_ud_err(queue_t *q, mblk_t *mp, t_scalar_t err)
4890 {
4891 	mblk_t	*mp1;
4892 	struct T_unitdata_req	*tudr = (struct T_unitdata_req *)mp->b_rptr;
4893 	uchar_t	*destaddr, *optaddr;
4894 
4895 	if ((mp->b_wptr < mp->b_rptr) ||
4896 	    (mp->b_wptr - mp->b_rptr) < sizeof (struct T_unitdata_req)) {
4897 		goto done;
4898 	}
4899 	destaddr = mp->b_rptr + tudr->DEST_offset;
4900 	if (destaddr < mp->b_rptr || destaddr >= mp->b_wptr ||
4901 	    destaddr + tudr->DEST_length < mp->b_rptr ||
4902 	    destaddr + tudr->DEST_length > mp->b_wptr) {
4903 		goto done;
4904 	}
4905 	optaddr = mp->b_rptr + tudr->OPT_offset;
4906 	if (optaddr < mp->b_rptr || optaddr >= mp->b_wptr ||
4907 	    optaddr + tudr->OPT_length < mp->b_rptr ||
4908 	    optaddr + tudr->OPT_length > mp->b_wptr) {
4909 		goto done;
4910 	}
4911 	mp1 = mi_tpi_uderror_ind((char *)destaddr, tudr->DEST_length,
4912 	    (char *)optaddr, tudr->OPT_length, err);
4913 	if (mp1)
4914 		qreply(q, mp1);
4915 
4916 done:
4917 	freemsg(mp);
4918 }
4919 
4920 /*
4921  * This routine removes a port number association from a stream.  It
4922  * is called by udp_wput to handle T_UNBIND_REQ messages.
4923  */
4924 static void
4925 udp_unbind(queue_t *q, mblk_t *mp)
4926 {
4927 	udp_t	*udp;
4928 
4929 	udp = (udp_t *)q->q_ptr;
4930 	/* If a bind has not been done, we can't unbind. */
4931 	if (udp->udp_state == TS_UNBND) {
4932 		udp_err_ack(q, mp, TOUTSTATE, 0);
4933 		return;
4934 	}
4935 	if (cl_inet_unbind != NULL) {
4936 		/*
4937 		 * Running in cluster mode - register unbind information
4938 		 */
4939 		if (udp->udp_ipversion == IPV4_VERSION) {
4940 			(*cl_inet_unbind)(IPPROTO_UDP, AF_INET,
4941 			    (uint8_t *)(&V4_PART_OF_V6(udp->udp_v6src)),
4942 			    (in_port_t)udp->udp_port);
4943 		} else {
4944 			(*cl_inet_unbind)(IPPROTO_UDP, AF_INET6,
4945 			    (uint8_t *)&(udp->udp_v6src),
4946 			    (in_port_t)udp->udp_port);
4947 		}
4948 	}
4949 
4950 	udp_bind_hash_remove(udp, B_FALSE);
4951 	V6_SET_ZERO(udp->udp_v6src);
4952 	V6_SET_ZERO(udp->udp_bound_v6src);
4953 	udp->udp_port = 0;
4954 	udp->udp_state = TS_UNBND;
4955 
4956 	if (udp->udp_family == AF_INET6) {
4957 		int error;
4958 
4959 		/* Rebuild the header template */
4960 		error = udp_build_hdrs(q, udp);
4961 		if (error != 0) {
4962 			udp_err_ack(q, mp, TSYSERR, error);
4963 			return;
4964 		}
4965 	}
4966 	/* Pass the unbind to IP */
4967 	putnext(q, mp);
4968 }
4969 
4970 /*
4971  * Don't let port fall into the privileged range.
4972  * Since the extra priviledged ports can be arbitrary we also
4973  * ensure that we exclude those from consideration.
4974  * udp_g_epriv_ports is not sorted thus we loop over it until
4975  * there are no changes.
4976  */
4977 static in_port_t
4978 udp_update_next_port(in_port_t port, boolean_t random)
4979 {
4980 	int i;
4981 
4982 	if (random && udp_random_anon_port != 0) {
4983 		(void) random_get_pseudo_bytes((uint8_t *)&port,
4984 		    sizeof (in_port_t));
4985 		/*
4986 		 * Unless changed by a sys admin, the smallest anon port
4987 		 * is 32768 and the largest anon port is 65535.  It is
4988 		 * very likely (50%) for the random port to be smaller
4989 		 * than the smallest anon port.  When that happens,
4990 		 * add port % (anon port range) to the smallest anon
4991 		 * port to get the random port.  It should fall into the
4992 		 * valid anon port range.
4993 		 */
4994 		if (port < udp_smallest_anon_port) {
4995 			port = udp_smallest_anon_port +
4996 			    port % (udp_largest_anon_port -
4997 			    udp_smallest_anon_port);
4998 		}
4999 	}
5000 
5001 retry:
5002 	if (port < udp_smallest_anon_port || port > udp_largest_anon_port)
5003 		port = udp_smallest_anon_port;
5004 
5005 	if (port < udp_smallest_nonpriv_port)
5006 		port = udp_smallest_nonpriv_port;
5007 
5008 	for (i = 0; i < udp_g_num_epriv_ports; i++) {
5009 		if (port == udp_g_epriv_ports[i]) {
5010 			port++;
5011 			/*
5012 			 * Make sure that the port is in the
5013 			 * valid range.
5014 			 */
5015 			goto retry;
5016 		}
5017 	}
5018 	return (port);
5019 }
5020 
5021 /*
5022  * This routine handles all messages passed downstream.  It either
5023  * consumes the message or passes it downstream; it never queues a
5024  * a message.
5025  */
5026 static void
5027 udp_wput(queue_t *q, mblk_t *mp)
5028 {
5029 	uchar_t		*rptr = mp->b_rptr;
5030 	struct 		datab *db;
5031 	ipha_t		*ipha;
5032 	udpha_t		*udpha;
5033 	mblk_t		*mp1;
5034 	int		ip_hdr_length;
5035 #define	tudr ((struct T_unitdata_req *)rptr)
5036 	uint32_t	ip_len;
5037 	udp_t		*udp;
5038 	sin6_t		*sin6;
5039 	sin_t		*sin;
5040 	ipaddr_t	v4dst;
5041 	uint16_t	port;
5042 	uint_t		srcid;
5043 
5044 	TRACE_2(TR_FAC_UDP, TR_UDP_WPUT_START,
5045 		"udp_wput_start: q %p mp %p", q, mp);
5046 
5047 	db = mp->b_datap;
5048 	switch (db->db_type) {
5049 	case M_PROTO:
5050 	case M_PCPROTO:
5051 		ASSERT((uintptr_t)(mp->b_wptr - rptr) <= (uintptr_t)INT_MAX);
5052 		if (mp->b_wptr - rptr >= sizeof (struct T_unitdata_req)) {
5053 			/* Detect valid T_UNITDATA_REQ here */
5054 			if (((union T_primitives *)rptr)->type
5055 			    == T_UNITDATA_REQ)
5056 				break;
5057 		}
5058 		/* FALLTHRU */
5059 	default:
5060 		qwriter(q, mp, udp_wput_other, PERIM_INNER);
5061 		return;
5062 	}
5063 
5064 	udp = (udp_t *)q->q_ptr;
5065 
5066 	/* Handle UNITDATA_REQ messages here */
5067 	if (udp->udp_state == TS_UNBND) {
5068 		/* If a port has not been bound to the stream, fail. */
5069 		BUMP_MIB(&udp_mib, udpOutErrors);
5070 		udp_ud_err(q, mp, EPROTO);
5071 		TRACE_2(TR_FAC_UDP, TR_UDP_WPUT_END,
5072 			"udp_wput_end: q %p (%S)", q, "outstate");
5073 		return;
5074 	}
5075 	mp1 = mp->b_cont;
5076 	if (mp1 == NULL) {
5077 		BUMP_MIB(&udp_mib, udpOutErrors);
5078 		udp_ud_err(q, mp, EPROTO);
5079 		TRACE_2(TR_FAC_UDP, TR_UDP_WPUT_END,
5080 			"udp_wput_end: q %p (%S)", q, "badaddr");
5081 		return;
5082 	}
5083 
5084 	if ((rptr + tudr->DEST_offset + tudr->DEST_length) > mp->b_wptr) {
5085 		BUMP_MIB(&udp_mib, udpOutErrors);
5086 		udp_ud_err(q, mp, EADDRNOTAVAIL);
5087 		TRACE_2(TR_FAC_UDP, TR_UDP_WPUT_END,
5088 			"udp_wput_end: q %p (%S)", q, "badaddr");
5089 		return;
5090 	}
5091 
5092 	switch (udp->udp_family) {
5093 	case AF_INET6:
5094 		sin6 = (sin6_t *)&rptr[tudr->DEST_offset];
5095 		if (!OK_32PTR((char *)sin6) ||
5096 		    tudr->DEST_length != sizeof (sin6_t) ||
5097 		    sin6->sin6_family != AF_INET6) {
5098 			BUMP_MIB(&udp_mib, udpOutErrors);
5099 			udp_ud_err(q, mp, EADDRNOTAVAIL);
5100 			TRACE_2(TR_FAC_UDP, TR_UDP_WPUT_END,
5101 				"udp_wput_end: q %p (%S)", q, "badaddr");
5102 			return;
5103 		}
5104 
5105 		if (!IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
5106 			/*
5107 			 * Destination is a non-IPv4-compatible IPv6 address.
5108 			 * Send out an IPv6 format packet.
5109 			 */
5110 			udp_wput_ipv6(q, mp, sin6, tudr->OPT_length);
5111 			TRACE_2(TR_FAC_UDP, TR_UDP_WPUT_END,
5112 				"udp_wput_end: q %p (%S)", q, "udp_wput_ipv6");
5113 			return;
5114 		}
5115 		/*
5116 		 * If the local address is not zero or a mapped address return
5117 		 * an error.
5118 		 * I would be possible to send an IPv4 packet but the
5119 		 * response would never make it back to the application
5120 		 * since it is bound to a non-mapped address.
5121 		 */
5122 		if (!IN6_IS_ADDR_V4MAPPED(&udp->udp_v6src) &&
5123 		    !IN6_IS_ADDR_UNSPECIFIED(&udp->udp_v6src)) {
5124 			BUMP_MIB(&udp_mib, udpOutErrors);
5125 			udp_ud_err(q, mp, EADDRNOTAVAIL);
5126 			TRACE_2(TR_FAC_UDP, TR_UDP_WPUT_END,
5127 				"udp_wput_end: q %p (%S)", q, "badaddr");
5128 			return;
5129 		}
5130 		/* Send IPv4 packet without modifying udp_ipversion */
5131 		/* Extract port and ipaddr */
5132 		port = sin6->sin6_port;
5133 		IN6_V4MAPPED_TO_IPADDR(&sin6->sin6_addr, v4dst);
5134 		srcid = sin6->__sin6_src_id;
5135 		break;
5136 
5137 	case AF_INET:
5138 		sin = (sin_t *)&rptr[tudr->DEST_offset];
5139 		if (!OK_32PTR((char *)sin) ||
5140 		    tudr->DEST_length != sizeof (sin_t) ||
5141 		    sin->sin_family != AF_INET) {
5142 			BUMP_MIB(&udp_mib, udpOutErrors);
5143 			udp_ud_err(q, mp, EADDRNOTAVAIL);
5144 			TRACE_2(TR_FAC_UDP, TR_UDP_WPUT_END,
5145 				"udp_wput_end: q %p (%S)", q, "badaddr");
5146 			return;
5147 		}
5148 		/* Extract port and ipaddr */
5149 		port = sin->sin_port;
5150 		v4dst = sin->sin_addr.s_addr;
5151 		srcid = 0;
5152 		break;
5153 	}
5154 
5155 
5156 	/*
5157 	 * If options passed in, feed it for verification and handling
5158 	 */
5159 	if (tudr->OPT_length != 0) {
5160 		int error;
5161 
5162 		if (udp_unitdata_opt_process(q, mp, &error, NULL) < 0) {
5163 			/* failure */
5164 			BUMP_MIB(&udp_mib, udpOutErrors);
5165 			udp_ud_err(q, mp, error);
5166 			TRACE_2(TR_FAC_UDP, TR_UDP_WPUT_END,
5167 			    "udp_wput_end: q %p (%S)", q,
5168 			    "udp_unitdata_opt_process");
5169 			return;
5170 		}
5171 		ASSERT(error == 0);
5172 		/*
5173 		 * Note: success in processing options.
5174 		 * mp option buffer represented by
5175 		 * OPT_length/offset now potentially modified
5176 		 * and contain option setting results
5177 		 */
5178 	}
5179 
5180 	/* Add an IP header */
5181 	ip_hdr_length = IP_SIMPLE_HDR_LENGTH + UDPH_SIZE +
5182 	    udp->udp_ip_snd_options_len;
5183 	ipha = (ipha_t *)&mp1->b_rptr[-ip_hdr_length];
5184 	if ((mp1->b_datap->db_ref != 1) ||
5185 	    ((uchar_t *)ipha < mp1->b_datap->db_base) ||
5186 	    !OK_32PTR(ipha)) {
5187 		uchar_t *wptr;
5188 
5189 		mp1 = allocb(ip_hdr_length + udp_wroff_extra, BPRI_LO);
5190 		if (!mp1) {
5191 			BUMP_MIB(&udp_mib, udpOutErrors);
5192 			udp_ud_err(q, mp, ENOMEM);
5193 			TRACE_2(TR_FAC_UDP, TR_UDP_WPUT_END,
5194 				"udp_wput_end: q %p (%S)", q, "allocbfail2");
5195 			return;
5196 		}
5197 		mp1->b_cont = mp->b_cont;
5198 		mp->b_cont = mp1;
5199 		wptr = mp1->b_datap->db_lim;
5200 		mp1->b_wptr = wptr;
5201 		ipha = (ipha_t *)(wptr - ip_hdr_length);
5202 	}
5203 	mp1->b_rptr = (uchar_t *)ipha;
5204 
5205 	ASSERT((uintptr_t)(mp1->b_wptr - (uchar_t *)ipha) <=
5206 	    (uintptr_t)UINT_MAX);
5207 
5208 	ip_hdr_length -= UDPH_SIZE;
5209 #ifdef	_BIG_ENDIAN
5210 	/* Set version, header length, and tos */
5211 	*(uint16_t *)&ipha->ipha_version_and_hdr_length =
5212 	    ((((IP_VERSION << 4) | (ip_hdr_length>>2)) << 8) |
5213 		udp->udp_type_of_service);
5214 	/* Set ttl and protocol */
5215 	*(uint16_t *)&ipha->ipha_ttl = (udp->udp_ttl << 8) | IPPROTO_UDP;
5216 #else
5217 	/* Set version, header length, and tos */
5218 	*(uint16_t *)&ipha->ipha_version_and_hdr_length =
5219 		((udp->udp_type_of_service << 8) |
5220 		    ((IP_VERSION << 4) | (ip_hdr_length>>2)));
5221 	/* Set ttl and protocol */
5222 	*(uint16_t *)&ipha->ipha_ttl = (IPPROTO_UDP << 8) | udp->udp_ttl;
5223 #endif
5224 	/*
5225 	 * Copy our address into the packet.  If this is zero,
5226 	 * first look at __sin6_src_id for a hint. If we leave the source
5227 	 * as INADDR_ANY then ip will fill in the real source address.
5228 	 */
5229 	IN6_V4MAPPED_TO_IPADDR(&udp->udp_v6src, ipha->ipha_src);
5230 	if (srcid != 0 && ipha->ipha_src == INADDR_ANY) {
5231 		in6_addr_t v6src;
5232 
5233 		ip_srcid_find_id(srcid, &v6src, udp->udp_zoneid);
5234 		IN6_V4MAPPED_TO_IPADDR(&v6src, ipha->ipha_src);
5235 	}
5236 
5237 	ipha->ipha_fragment_offset_and_flags = 0;
5238 	ipha->ipha_ident = 0;
5239 
5240 	/* Determine length of packet */
5241 	ip_len = (uint32_t)(mp1->b_wptr - (uchar_t *)ipha);
5242 	{
5243 		mblk_t	*mp2;
5244 		if ((mp2 = mp1->b_cont) != NULL) {
5245 			do {
5246 				ASSERT((uintptr_t)(mp2->b_wptr - mp2->b_rptr)
5247 				    <= (uintptr_t)UINT_MAX);
5248 				ip_len += (uint32_t)(mp2->b_wptr - mp2->b_rptr);
5249 			} while ((mp2 = mp2->b_cont) != NULL);
5250 		}
5251 	}
5252 	/*
5253 	 * If the size of the packet is greater than the maximum allowed by
5254 	 * ip, return an error. Passing this down could cause panics because
5255 	 * the size will have wrapped and be inconsistent with the msg size.
5256 	 */
5257 	if (ip_len > IP_MAXPACKET) {
5258 		BUMP_MIB(&udp_mib, udpOutErrors);
5259 		udp_ud_err(q, mp, EMSGSIZE);
5260 		TRACE_2(TR_FAC_UDP, TR_UDP_WPUT_END,
5261 		    "udp_wput_end: q %p (%S)", q, "IP length exceeded");
5262 		return;
5263 	}
5264 	ipha->ipha_length = htons((uint16_t)ip_len);
5265 	ip_len -= ip_hdr_length;
5266 	ip_len = htons((uint16_t)ip_len);
5267 	udpha = (udpha_t *)(((uchar_t *)ipha) + ip_hdr_length);
5268 	/*
5269 	 * Copy in the destination address and port from the T_UNITDATA
5270 	 * request
5271 	 */
5272 	if (v4dst == INADDR_ANY)
5273 		ipha->ipha_dst = htonl(INADDR_LOOPBACK);
5274 	else
5275 		ipha->ipha_dst = v4dst;
5276 
5277 	/*
5278 	 * Set ttl based on IP_MULTICAST_TTL to match IPv6 logic.
5279 	 */
5280 	if (CLASSD(v4dst))
5281 		ipha->ipha_ttl = udp->udp_multicast_ttl;
5282 
5283 	udpha->uha_dst_port = port;
5284 	udpha->uha_src_port = udp->udp_port;
5285 
5286 	if (ip_hdr_length > IP_SIMPLE_HDR_LENGTH) {
5287 		uint32_t	cksum;
5288 
5289 		bcopy(udp->udp_ip_snd_options, &ipha[1],
5290 		    udp->udp_ip_snd_options_len);
5291 		/*
5292 		 * Massage source route putting first source route in ipha_dst.
5293 		 * Ignore the destination in T_unitdata_req.
5294 		 * Create a checksum adjustment for a source route, if any.
5295 		 */
5296 		cksum = ip_massage_options(ipha);
5297 		cksum = (cksum & 0xFFFF) + (cksum >> 16);
5298 		cksum -= ((ipha->ipha_dst >> 16) & 0xFFFF) +
5299 		    (ipha->ipha_dst & 0xFFFF);
5300 		if ((int)cksum < 0)
5301 			cksum--;
5302 		cksum = (cksum & 0xFFFF) + (cksum >> 16);
5303 		/*
5304 		 * IP does the checksum if uha_checksum is non-zero,
5305 		 * We make it easy for IP to include our pseudo header
5306 		 * by putting our length in uha_checksum.
5307 		 */
5308 		cksum += ip_len;
5309 		cksum = (cksum & 0xFFFF) + (cksum >> 16);
5310 		/* There might be a carry. */
5311 		cksum = (cksum & 0xFFFF) + (cksum >> 16);
5312 #ifdef _LITTLE_ENDIAN
5313 		if (udp_do_checksum)
5314 			ip_len = (cksum << 16) | ip_len;
5315 #else
5316 		if (udp_do_checksum)
5317 			ip_len = (ip_len << 16) | cksum;
5318 		else
5319 			ip_len <<= 16;
5320 #endif
5321 	} else {
5322 		/*
5323 		 * IP does the checksum if uha_checksum is non-zero,
5324 		 * We make it easy for IP to include our pseudo header
5325 		 * by putting our length in uha_checksum.
5326 		 */
5327 		if (udp_do_checksum)
5328 			ip_len |= (ip_len << 16);
5329 #ifndef _LITTLE_ENDIAN
5330 		else
5331 			ip_len <<= 16;
5332 #endif
5333 	}
5334 	/* Set UDP length and checksum */
5335 	*((uint32_t *)&udpha->uha_length) = ip_len;
5336 
5337 	freeb(mp);
5338 
5339 	/* We're done.  Pass the packet to ip. */
5340 	BUMP_MIB(&udp_mib, udpOutDatagrams);
5341 	TRACE_2(TR_FAC_UDP, TR_UDP_WPUT_END,
5342 		"udp_wput_end: q %p (%S)", q, "end");
5343 	putnext(q, mp1);
5344 #undef tudr
5345 }
5346 
5347 /*
5348  * udp_wput_ipv6():
5349  * Assumes that udp_wput did some sanity checking on the destination
5350  * address.
5351  */
5352 static void
5353 udp_wput_ipv6(queue_t *q, mblk_t *mp, sin6_t *sin6, t_scalar_t tudr_optlen)
5354 {
5355 	ip6_t			*ip6h;
5356 	ip6i_t			*ip6i;	/* mp1->b_rptr even if no ip6i_t */
5357 	mblk_t			*mp1;
5358 	int			udp_ip_hdr_len = IPV6_HDR_LEN + UDPH_SIZE;
5359 	size_t			ip_len;
5360 	udpha_t			*udph;
5361 	udp_t			*udp;
5362 	ip6_pkt_t		ipp_s;	/* For ancillary data options */
5363 	ip6_pkt_t		*ipp = &ipp_s;
5364 	ip6_pkt_t		*tipp;	/* temporary ipp */
5365 	uint32_t		csum = 0;
5366 	uint_t			ignore = 0;
5367 	uint_t			option_exists = 0, is_sticky = 0;
5368 	uint8_t			*cp;
5369 	uint8_t			*nxthdr_ptr;
5370 
5371 	udp = (udp_t *)q->q_ptr;
5372 
5373 	/*
5374 	 * If the local address is a mapped address return
5375 	 * an error.
5376 	 * It would be possible to send an IPv6 packet but the
5377 	 * response would never make it back to the application
5378 	 * since it is bound to a mapped address.
5379 	 */
5380 	if (IN6_IS_ADDR_V4MAPPED(&udp->udp_v6src)) {
5381 		BUMP_MIB(&udp_mib, udpOutErrors);
5382 		udp_ud_err(q, mp, EADDRNOTAVAIL);
5383 		return;
5384 	}
5385 
5386 	ipp->ipp_fields = 0;
5387 	ipp->ipp_sticky_ignored = 0;
5388 
5389 	/*
5390 	 * If TPI options passed in, feed it for verification and handling
5391 	 */
5392 	if (tudr_optlen != 0) {
5393 		int 		error;
5394 
5395 		if (udp_unitdata_opt_process(q, mp, &error,
5396 		    (void *)ipp) < 0) {
5397 			/* failure */
5398 			BUMP_MIB(&udp_mib, udpOutErrors);
5399 			udp_ud_err(q, mp, error);
5400 			return;
5401 		}
5402 		ignore = ipp->ipp_sticky_ignored;
5403 		ASSERT(error == 0);
5404 	}
5405 
5406 	if (sin6->sin6_scope_id != 0 &&
5407 	    IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
5408 		/*
5409 		 * IPPF_SCOPE_ID is special.  It's neither a sticky
5410 		 * option nor ancillary data.  It needs to be
5411 		 * explicitly set in options_exists.
5412 		 */
5413 		option_exists |= IPPF_SCOPE_ID;
5414 	}
5415 
5416 	if ((udp->udp_sticky_ipp.ipp_fields == 0) &&
5417 	    (ipp->ipp_fields == 0)) {
5418 		/* No sticky options nor ancillary data. */
5419 		goto no_options;
5420 	}
5421 
5422 	/*
5423 	 * Go through the options figuring out where each is going to
5424 	 * come from and build two masks.  The first mask indicates if
5425 	 * the option exists at all.  The second mask indicates if the
5426 	 * option is sticky or ancillary.
5427 	 */
5428 	if (!(ignore & IPPF_HOPOPTS)) {
5429 		if (ipp->ipp_fields & IPPF_HOPOPTS) {
5430 			option_exists |= IPPF_HOPOPTS;
5431 			udp_ip_hdr_len += ipp->ipp_hopoptslen;
5432 		} else if (udp->udp_sticky_ipp.ipp_fields & IPPF_HOPOPTS) {
5433 			option_exists |= IPPF_HOPOPTS;
5434 			is_sticky |= IPPF_HOPOPTS;
5435 			udp_ip_hdr_len += udp->udp_sticky_ipp.ipp_hopoptslen;
5436 		}
5437 	}
5438 
5439 	if (!(ignore & IPPF_RTHDR)) {
5440 		if (ipp->ipp_fields & IPPF_RTHDR) {
5441 			option_exists |= IPPF_RTHDR;
5442 			udp_ip_hdr_len += ipp->ipp_rthdrlen;
5443 		} else if (udp->udp_sticky_ipp.ipp_fields & IPPF_RTHDR) {
5444 			option_exists |= IPPF_RTHDR;
5445 			is_sticky |= IPPF_RTHDR;
5446 			udp_ip_hdr_len += udp->udp_sticky_ipp.ipp_rthdrlen;
5447 		}
5448 	}
5449 
5450 	if (!(ignore & IPPF_RTDSTOPTS) && (option_exists & IPPF_RTHDR)) {
5451 		if (ipp->ipp_fields & IPPF_RTDSTOPTS) {
5452 			option_exists |= IPPF_RTDSTOPTS;
5453 			udp_ip_hdr_len += ipp->ipp_rtdstoptslen;
5454 		} else if (udp->udp_sticky_ipp.ipp_fields & IPPF_RTDSTOPTS) {
5455 			option_exists |= IPPF_RTDSTOPTS;
5456 			is_sticky |= IPPF_RTDSTOPTS;
5457 			udp_ip_hdr_len += udp->udp_sticky_ipp.ipp_rtdstoptslen;
5458 		}
5459 	}
5460 
5461 	if (!(ignore & IPPF_DSTOPTS)) {
5462 		if (ipp->ipp_fields & IPPF_DSTOPTS) {
5463 			option_exists |= IPPF_DSTOPTS;
5464 			udp_ip_hdr_len += ipp->ipp_dstoptslen;
5465 		} else if (udp->udp_sticky_ipp.ipp_fields & IPPF_DSTOPTS) {
5466 			option_exists |= IPPF_DSTOPTS;
5467 			is_sticky |= IPPF_DSTOPTS;
5468 			udp_ip_hdr_len += udp->udp_sticky_ipp.ipp_dstoptslen;
5469 		}
5470 	}
5471 
5472 	if (!(ignore & IPPF_IFINDEX)) {
5473 		if (ipp->ipp_fields & IPPF_IFINDEX) {
5474 			option_exists |= IPPF_IFINDEX;
5475 		} else if (udp->udp_sticky_ipp.ipp_fields & IPPF_IFINDEX) {
5476 			option_exists |= IPPF_IFINDEX;
5477 			is_sticky |= IPPF_IFINDEX;
5478 		}
5479 	}
5480 
5481 	if (!(ignore & IPPF_ADDR)) {
5482 		if (ipp->ipp_fields & IPPF_ADDR) {
5483 			option_exists |= IPPF_ADDR;
5484 		} else if (udp->udp_sticky_ipp.ipp_fields & IPPF_ADDR) {
5485 			option_exists |= IPPF_ADDR;
5486 			is_sticky |= IPPF_ADDR;
5487 		}
5488 	}
5489 
5490 	if (!(ignore & IPPF_DONTFRAG)) {
5491 		if (ipp->ipp_fields & IPPF_DONTFRAG) {
5492 			option_exists |= IPPF_DONTFRAG;
5493 		} else if (udp->udp_sticky_ipp.ipp_fields & IPPF_DONTFRAG) {
5494 			option_exists |= IPPF_DONTFRAG;
5495 			is_sticky |= IPPF_DONTFRAG;
5496 		}
5497 	}
5498 
5499 	if (!(ignore & IPPF_USE_MIN_MTU)) {
5500 		if (ipp->ipp_fields & IPPF_USE_MIN_MTU) {
5501 			option_exists |= IPPF_USE_MIN_MTU;
5502 		} else if (udp->udp_sticky_ipp.ipp_fields & IPPF_USE_MIN_MTU) {
5503 			option_exists |= IPPF_USE_MIN_MTU;
5504 			is_sticky |= IPPF_USE_MIN_MTU;
5505 		}
5506 	}
5507 
5508 	if (!(ignore & IPPF_HOPLIMIT)) {
5509 		if (ipp->ipp_fields & IPPF_HOPLIMIT) {
5510 			option_exists |= IPPF_HOPLIMIT;
5511 		} else if (udp->udp_sticky_ipp.ipp_fields & IPPF_HOPLIMIT) {
5512 			option_exists |= IPPF_HOPLIMIT;
5513 			is_sticky |= IPPF_HOPLIMIT;
5514 		}
5515 	}
5516 
5517 	if (!(ignore & IPPF_TCLASS)) {
5518 		if (ipp->ipp_fields & IPPF_TCLASS) {
5519 			option_exists |= IPPF_TCLASS;
5520 		} else if (udp->udp_sticky_ipp.ipp_fields & IPPF_TCLASS) {
5521 			option_exists |= IPPF_TCLASS;
5522 			is_sticky |= IPPF_TCLASS;
5523 		}
5524 	}
5525 
5526 no_options:
5527 
5528 	/*
5529 	 * If any options carried in the ip6i_t were specified, we
5530 	 * need to account for the ip6i_t in the data we'll be sending
5531 	 * down.
5532 	 */
5533 	if (option_exists & IPPF_HAS_IP6I)
5534 		udp_ip_hdr_len += sizeof (ip6i_t);
5535 
5536 	/* check/fix buffer config, setup pointers into it */
5537 	mp1 = mp->b_cont;
5538 	ip6h = (ip6_t *)&mp1->b_rptr[-udp_ip_hdr_len];
5539 	if ((mp1->b_datap->db_ref != 1) ||
5540 	    ((unsigned char *)ip6h < mp1->b_datap->db_base) ||
5541 	    !OK_32PTR(ip6h)) {
5542 		/* Try to get everything in a single mblk next time */
5543 		if (udp_ip_hdr_len > udp->udp_max_hdr_len) {
5544 			udp->udp_max_hdr_len = udp_ip_hdr_len;
5545 			(void) mi_set_sth_wroff(RD(q),
5546 			    udp->udp_max_hdr_len + udp_wroff_extra);
5547 		}
5548 		mp1 = allocb(udp_ip_hdr_len + udp_wroff_extra, BPRI_LO);
5549 		if (!mp1) {
5550 			BUMP_MIB(&udp_mib, udpOutErrors);
5551 			udp_ud_err(q, mp, ENOMEM);
5552 			return;
5553 		}
5554 		mp1->b_cont = mp->b_cont;
5555 		mp->b_cont = mp1;
5556 		mp1->b_wptr = mp1->b_datap->db_lim;
5557 		ip6h = (ip6_t *)(mp1->b_wptr - udp_ip_hdr_len);
5558 	}
5559 	mp1->b_rptr = (unsigned char *)ip6h;
5560 	ip6i = (ip6i_t *)ip6h;
5561 
5562 #define	ANCIL_OR_STICKY_PTR(f) ((is_sticky & f) ? &udp->udp_sticky_ipp : ipp)
5563 	if (option_exists & IPPF_HAS_IP6I) {
5564 		ip6h = (ip6_t *)&ip6i[1];
5565 		ip6i->ip6i_flags = 0;
5566 		ip6i->ip6i_vcf = IPV6_DEFAULT_VERS_AND_FLOW;
5567 
5568 		/* sin6_scope_id takes precendence over IPPF_IFINDEX */
5569 		if (option_exists & IPPF_SCOPE_ID) {
5570 			ip6i->ip6i_flags |= IP6I_IFINDEX;
5571 			ip6i->ip6i_ifindex = sin6->sin6_scope_id;
5572 		} else if (option_exists & IPPF_IFINDEX) {
5573 			tipp = ANCIL_OR_STICKY_PTR(IPPF_IFINDEX);
5574 			ASSERT(tipp->ipp_ifindex != 0);
5575 			ip6i->ip6i_flags |= IP6I_IFINDEX;
5576 			ip6i->ip6i_ifindex = tipp->ipp_ifindex;
5577 		}
5578 
5579 		if (option_exists & IPPF_ADDR) {
5580 			/*
5581 			 * Enable per-packet source address verification if
5582 			 * IPV6_PKTINFO specified the source address.
5583 			 * ip6_src is set in the transport's _wput function.
5584 			 */
5585 			ip6i->ip6i_flags |= IP6I_VERIFY_SRC;
5586 		}
5587 
5588 		if (option_exists & IPPF_DONTFRAG) {
5589 			ip6i->ip6i_flags |= IP6I_DONTFRAG;
5590 		}
5591 
5592 		if (option_exists & IPPF_USE_MIN_MTU) {
5593 			ip6i->ip6i_flags = IP6I_API_USE_MIN_MTU(
5594 			    ip6i->ip6i_flags, ipp->ipp_use_min_mtu);
5595 		}
5596 
5597 		if (option_exists & IPPF_NEXTHOP) {
5598 			tipp = ANCIL_OR_STICKY_PTR(IPPF_NEXTHOP);
5599 			ASSERT(!IN6_IS_ADDR_UNSPECIFIED(&tipp->ipp_nexthop));
5600 			ip6i->ip6i_flags |= IP6I_NEXTHOP;
5601 			ip6i->ip6i_nexthop = tipp->ipp_nexthop;
5602 		}
5603 
5604 		/*
5605 		 * tell IP this is an ip6i_t private header
5606 		 */
5607 		ip6i->ip6i_nxt = IPPROTO_RAW;
5608 	}
5609 
5610 	/* Initialize IPv6 header */
5611 	ip6h->ip6_vcf = IPV6_DEFAULT_VERS_AND_FLOW;
5612 	bzero(&ip6h->ip6_src, sizeof (ip6h->ip6_src));
5613 
5614 	if (option_exists & IPPF_HOPLIMIT) {
5615 		tipp = ANCIL_OR_STICKY_PTR(IPPF_HOPLIMIT);
5616 		ip6h->ip6_hops = tipp->ipp_hoplimit;
5617 	} else if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr) &&
5618 	    (udp->udp_sticky_ipp.ipp_fields & IPPF_MULTI_HOPLIMIT)) {
5619 		ip6h->ip6_hops = udp->udp_multicast_ttl;
5620 		ip6i->ip6i_flags |= IP6I_HOPLIMIT;
5621 	} else {
5622 		ip6h->ip6_hops = udp->udp_ttl;
5623 	}
5624 
5625 	if (option_exists & IPPF_ADDR) {
5626 		tipp = ANCIL_OR_STICKY_PTR(IPPF_ADDR);
5627 		ASSERT(!IN6_IS_ADDR_UNSPECIFIED(&tipp->ipp_addr));
5628 		ip6h->ip6_src = tipp->ipp_addr;
5629 	} else {
5630 		/*
5631 		 * The source address was not set using IPV6_PKTINFO.
5632 		 * First look at the bound source.
5633 		 * If unspecified fallback to __sin6_src_id.
5634 		 */
5635 		ip6h->ip6_src = udp->udp_v6src;
5636 		if (sin6->__sin6_src_id != 0 &&
5637 		    IN6_IS_ADDR_UNSPECIFIED(&ip6h->ip6_src)) {
5638 			ip_srcid_find_id(sin6->__sin6_src_id,
5639 			    &ip6h->ip6_src, udp->udp_zoneid);
5640 		}
5641 	}
5642 
5643 	nxthdr_ptr = (uint8_t *)&ip6h->ip6_nxt;
5644 	cp = (uint8_t *)&ip6h[1];
5645 
5646 	/*
5647 	 * Here's where we have to start stringing together
5648 	 * any extension headers in the right order:
5649 	 * Hop-by-hop, destination, routing, and final destination opts.
5650 	 */
5651 	if (option_exists & IPPF_HOPOPTS) {
5652 		/* Hop-by-hop options */
5653 		ip6_hbh_t *hbh = (ip6_hbh_t *)cp;
5654 		tipp = ANCIL_OR_STICKY_PTR(IPPF_HOPOPTS);
5655 
5656 		*nxthdr_ptr = IPPROTO_HOPOPTS;
5657 		nxthdr_ptr = &hbh->ip6h_nxt;
5658 
5659 		bcopy(tipp->ipp_hopopts, cp, tipp->ipp_hopoptslen);
5660 		cp += tipp->ipp_hopoptslen;
5661 	}
5662 	/*
5663 	 * En-route destination options
5664 	 * Only do them if there's a routing header as well
5665 	 */
5666 	if (option_exists & IPPF_RTDSTOPTS) {
5667 		ip6_dest_t *dst = (ip6_dest_t *)cp;
5668 		tipp = ANCIL_OR_STICKY_PTR(IPPF_RTDSTOPTS);
5669 
5670 		*nxthdr_ptr = IPPROTO_DSTOPTS;
5671 		nxthdr_ptr = &dst->ip6d_nxt;
5672 
5673 		bcopy(tipp->ipp_rtdstopts, cp, tipp->ipp_rtdstoptslen);
5674 		cp += tipp->ipp_rtdstoptslen;
5675 	}
5676 	/*
5677 	 * Routing header next
5678 	 */
5679 	if (option_exists & IPPF_RTHDR) {
5680 		ip6_rthdr_t *rt = (ip6_rthdr_t *)cp;
5681 		tipp = ANCIL_OR_STICKY_PTR(IPPF_RTHDR);
5682 
5683 		*nxthdr_ptr = IPPROTO_ROUTING;
5684 		nxthdr_ptr = &rt->ip6r_nxt;
5685 
5686 		bcopy(tipp->ipp_rthdr, cp, tipp->ipp_rthdrlen);
5687 		cp += tipp->ipp_rthdrlen;
5688 	}
5689 	/*
5690 	 * Do ultimate destination options
5691 	 */
5692 	if (option_exists & IPPF_DSTOPTS) {
5693 		ip6_dest_t *dest = (ip6_dest_t *)cp;
5694 		tipp = ANCIL_OR_STICKY_PTR(IPPF_DSTOPTS);
5695 
5696 		*nxthdr_ptr = IPPROTO_DSTOPTS;
5697 		nxthdr_ptr = &dest->ip6d_nxt;
5698 
5699 		bcopy(tipp->ipp_dstopts, cp, tipp->ipp_dstoptslen);
5700 		cp += tipp->ipp_dstoptslen;
5701 	}
5702 	/*
5703 	 * Now set the last header pointer to the proto passed in
5704 	 */
5705 	ASSERT((int)(cp - (uint8_t *)ip6i) == (udp_ip_hdr_len - UDPH_SIZE));
5706 	*nxthdr_ptr = IPPROTO_UDP;
5707 
5708 	/* Update UDP header */
5709 	udph = (udpha_t *)((uchar_t *)ip6i + udp_ip_hdr_len - UDPH_SIZE);
5710 	udph->uha_dst_port = sin6->sin6_port;
5711 	udph->uha_src_port = udp->udp_port;
5712 
5713 	/*
5714 	 * Copy in the destination address
5715 	 */
5716 	if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
5717 		ip6h->ip6_dst = ipv6_loopback;
5718 	else
5719 		ip6h->ip6_dst = sin6->sin6_addr;
5720 
5721 	ip6h->ip6_vcf =
5722 	    (IPV6_DEFAULT_VERS_AND_FLOW & IPV6_VERS_AND_FLOW_MASK) |
5723 	    (sin6->sin6_flowinfo & ~IPV6_VERS_AND_FLOW_MASK);
5724 
5725 	if (option_exists & IPPF_TCLASS) {
5726 		tipp = ANCIL_OR_STICKY_PTR(IPPF_TCLASS);
5727 		ip6h->ip6_vcf = IPV6_TCLASS_FLOW(ip6h->ip6_vcf,
5728 		    tipp->ipp_tclass);
5729 	}
5730 
5731 	if (option_exists & IPPF_RTHDR) {
5732 		ip6_rthdr_t	*rth;
5733 
5734 		/*
5735 		 * Perform any processing needed for source routing.
5736 		 * We know that all extension headers will be in the same mblk
5737 		 * as the IPv6 header.
5738 		 */
5739 		rth = ip_find_rthdr_v6(ip6h, mp1->b_wptr);
5740 		if (rth != NULL && rth->ip6r_segleft != 0) {
5741 			if (rth->ip6r_type != IPV6_RTHDR_TYPE_0) {
5742 				/*
5743 				 * Drop packet - only support Type 0 routing.
5744 				 * Notify the application as well.
5745 				 */
5746 				udp_ud_err(q, mp, EPROTO);
5747 				BUMP_MIB(&udp_mib, udpOutErrors);
5748 				return;
5749 			}
5750 
5751 			/*
5752 			 * rth->ip6r_len is twice the number of
5753 			 * addresses in the header. Thus it must be even.
5754 			 */
5755 			if (rth->ip6r_len & 0x1) {
5756 				udp_ud_err(q, mp, EPROTO);
5757 				BUMP_MIB(&udp_mib, udpOutErrors);
5758 				return;
5759 			}
5760 			/*
5761 			 * Shuffle the routing header and ip6_dst
5762 			 * addresses, and get the checksum difference
5763 			 * between the first hop (in ip6_dst) and
5764 			 * the destination (in the last routing hdr entry).
5765 			 */
5766 			csum = ip_massage_options_v6(ip6h, rth);
5767 			/*
5768 			 * Verify that the first hop isn't a mapped address.
5769 			 * Routers along the path need to do this verification
5770 			 * for subsequent hops.
5771 			 */
5772 			if (IN6_IS_ADDR_V4MAPPED(&ip6h->ip6_dst)) {
5773 				udp_ud_err(q, mp, EADDRNOTAVAIL);
5774 				BUMP_MIB(&udp_mib, udpOutErrors);
5775 				return;
5776 			}
5777 
5778 			cp += (rth->ip6r_len + 1)*8;
5779 		}
5780 	}
5781 
5782 	/* count up length of UDP packet */
5783 	ip_len = (mp1->b_wptr - (unsigned char *)ip6h) - IPV6_HDR_LEN;
5784 	{
5785 		mblk_t *mp2;
5786 
5787 		if ((mp2 = mp1->b_cont) != NULL) {
5788 			do {
5789 				ip_len += mp2->b_wptr - mp2->b_rptr;
5790 			} while ((mp2 = mp2->b_cont) != NULL);
5791 		}
5792 	}
5793 
5794 	/*
5795 	 * If the size of the packet is greater than the maximum allowed by
5796 	 * ip, return an error. Passing this down could cause panics because
5797 	 * the size will have wrapped and be inconsistent with the msg size.
5798 	 */
5799 	if (ip_len > IP_MAXPACKET) {
5800 		BUMP_MIB(&udp_mib, udpOutErrors);
5801 		udp_ud_err(q, mp, EMSGSIZE);
5802 		return;
5803 	}
5804 
5805 	/* Store the UDP length. Subtract length of extension hdrs */
5806 	udph->uha_length = htons(ip_len + IPV6_HDR_LEN -
5807 	    (int)((uchar_t *)udph - (uchar_t *)ip6h));
5808 
5809 	/*
5810 	 * We make it easy for IP to include our pseudo header
5811 	 * by putting our length in uh_checksum, modified (if
5812 	 * we have a routing header) by the checksum difference
5813 	 * between the ultimate destination and first hop addresses.
5814 	 * Note: UDP over IPv6 must always checksum the packet.
5815 	 */
5816 	csum += udph->uha_length;
5817 	csum = (csum & 0xFFFF) + (csum >> 16);
5818 	udph->uha_checksum = (uint16_t)csum;
5819 
5820 #ifdef _LITTLE_ENDIAN
5821 	ip_len = htons(ip_len);
5822 #endif
5823 	ip6h->ip6_plen = ip_len;
5824 
5825 	freeb(mp);
5826 
5827 	/* We're done. Pass the packet to IP */
5828 	BUMP_MIB(&udp_mib, udpOutDatagrams);
5829 	putnext(q, mp1);
5830 }
5831 
5832 static void
5833 udp_wput_other(queue_t *q, mblk_t *mp)
5834 {
5835 	uchar_t	*rptr = mp->b_rptr;
5836 	struct datab *db;
5837 	struct iocblk *iocp;
5838 	udp_t	*udp;
5839 	cred_t	*cr;
5840 
5841 	TRACE_1(TR_FAC_UDP, TR_UDP_WPUT_OTHER_START,
5842 		"udp_wput_other_start: q %p", q);
5843 
5844 	udp = (udp_t *)q->q_ptr;
5845 	db = mp->b_datap;
5846 
5847 	cr = DB_CREDDEF(mp, udp->udp_credp);
5848 
5849 	switch (db->db_type) {
5850 	case M_DATA:
5851 		/* Not connected */
5852 		BUMP_MIB(&udp_mib, udpOutErrors);
5853 		freemsg(mp);
5854 		TRACE_2(TR_FAC_UDP, TR_UDP_WPUT_OTHER_END,
5855 			"udp_wput_other_end: q %p (%S)",
5856 			q, "not-connected");
5857 		return;
5858 	case M_PROTO:
5859 	case M_PCPROTO:
5860 		if (mp->b_wptr - rptr < sizeof (t_scalar_t)) {
5861 			freemsg(mp);
5862 			TRACE_2(TR_FAC_UDP, TR_UDP_WPUT_OTHER_END,
5863 				"udp_wput_other_end: q %p (%S)",
5864 				q, "protoshort");
5865 			return;
5866 		}
5867 		switch (((union T_primitives *)rptr)->type) {
5868 		case T_ADDR_REQ:
5869 			udp_addr_req(q, mp);
5870 			TRACE_2(TR_FAC_UDP, TR_UDP_WPUT_OTHER_END,
5871 				"udp_wput_other_end: q %p (%S)", q, "addrreq");
5872 			return;
5873 		case O_T_BIND_REQ:
5874 		case T_BIND_REQ:
5875 			udp_bind(q, mp);
5876 			TRACE_2(TR_FAC_UDP, TR_UDP_WPUT_OTHER_END,
5877 				"udp_wput_other_end: q %p (%S)", q, "bindreq");
5878 			return;
5879 		case T_CONN_REQ:
5880 			udp_connect(q, mp);
5881 			TRACE_2(TR_FAC_UDP, TR_UDP_WPUT_OTHER_END,
5882 				"udp_wput_other_end: q %p (%S)", q, "connreq");
5883 			return;
5884 		case T_CAPABILITY_REQ:
5885 			udp_capability_req(q, mp);
5886 			TRACE_2(TR_FAC_UDP, TR_UDP_WPUT_OTHER_END,
5887 				"udp_wput_other_end: q %p (%S)", q, "capabreq");
5888 			return;
5889 		case T_INFO_REQ:
5890 			udp_info_req(q, mp);
5891 			TRACE_2(TR_FAC_UDP, TR_UDP_WPUT_OTHER_END,
5892 				"udp_wput_other_end: q %p (%S)", q, "inforeq");
5893 			return;
5894 		case T_UNITDATA_REQ:
5895 			/*
5896 			 * If a T_UNITDATA_REQ gets here, the address must
5897 			 * be bad.  Valid T_UNITDATA_REQs are handled
5898 			 * in udp_wput.
5899 			 */
5900 			udp_ud_err(q, mp, EADDRNOTAVAIL);
5901 			TRACE_2(TR_FAC_UDP, TR_UDP_WPUT_OTHER_END,
5902 				"udp_wput_other_end: q %p (%S)",
5903 				q, "unitdatareq");
5904 			return;
5905 		case T_UNBIND_REQ:
5906 			udp_unbind(q, mp);
5907 			TRACE_2(TR_FAC_UDP, TR_UDP_WPUT_OTHER_END,
5908 			    "udp_wput_other_end: q %p (%S)", q, "unbindreq");
5909 			return;
5910 		case T_SVR4_OPTMGMT_REQ:
5911 			if (!snmpcom_req(q, mp, udp_snmp_set, udp_snmp_get, cr))
5912 				(void) svr4_optcom_req(q, mp, cr, &udp_opt_obj);
5913 			TRACE_2(TR_FAC_UDP, TR_UDP_WPUT_OTHER_END,
5914 			    "udp_wput_other_end: q %p (%S)",
5915 			    q, "optmgmtreq");
5916 			return;
5917 
5918 		case T_OPTMGMT_REQ:
5919 			(void) tpi_optcom_req(q, mp, cr, &udp_opt_obj);
5920 			TRACE_2(TR_FAC_UDP, TR_UDP_WPUT_OTHER_END,
5921 				"udp_wput_other_end: q %p (%S)",
5922 				q, "optmgmtreq");
5923 			return;
5924 
5925 		case T_DISCON_REQ:
5926 			udp_disconnect(q, mp);
5927 			TRACE_2(TR_FAC_UDP, TR_UDP_WPUT_OTHER_END,
5928 				"udp_wput_other_end: q %p (%S)",
5929 				q, "disconreq");
5930 			return;
5931 
5932 		/* The following TPI message is not supported by udp. */
5933 		case O_T_CONN_RES:
5934 		case T_CONN_RES:
5935 			udp_err_ack(q, mp, TNOTSUPPORT, 0);
5936 			TRACE_2(TR_FAC_UDP, TR_UDP_WPUT_OTHER_END,
5937 				"udp_wput_other_end: q %p (%S)",
5938 				q, "connres/disconreq");
5939 			return;
5940 
5941 		/* The following 3 TPI messages are illegal for udp. */
5942 		case T_DATA_REQ:
5943 		case T_EXDATA_REQ:
5944 		case T_ORDREL_REQ:
5945 			udp_err_ack(q, mp, TNOTSUPPORT, 0);
5946 			TRACE_2(TR_FAC_UDP, TR_UDP_WPUT_OTHER_END,
5947 				"udp_wput_other_end: q %p (%S)",
5948 				q, "data/exdata/ordrel");
5949 			return;
5950 		default:
5951 			break;
5952 		}
5953 		break;
5954 	case M_FLUSH:
5955 		if (*rptr & FLUSHW)
5956 			flushq(q, FLUSHDATA);
5957 		break;
5958 	case M_IOCTL:
5959 		iocp = (struct iocblk *)mp->b_rptr;
5960 		switch (iocp->ioc_cmd) {
5961 		case TI_GETPEERNAME:
5962 			if (udp->udp_state != TS_DATA_XFER) {
5963 				/*
5964 				 * If a default destination address has not
5965 				 * been associated with the stream, then we
5966 				 * don't know the peer's name.
5967 				 */
5968 				iocp->ioc_error = ENOTCONN;
5969 err_ret:;
5970 				iocp->ioc_count = 0;
5971 				mp->b_datap->db_type = M_IOCACK;
5972 				qreply(q, mp);
5973 				TRACE_2(TR_FAC_UDP, TR_UDP_WPUT_OTHER_END,
5974 					"udp_wput_other_end: q %p (%S)",
5975 					q, "getpeername");
5976 				return;
5977 			}
5978 			/* FALLTHRU */
5979 		case TI_GETMYNAME: {
5980 			/*
5981 			 * For TI_GETPEERNAME and TI_GETMYNAME, we first
5982 			 * need to copyin the user's strbuf structure.
5983 			 * Processing will continue in the M_IOCDATA case
5984 			 * below.
5985 			 */
5986 			mi_copyin(q, mp, NULL,
5987 			    SIZEOF_STRUCT(strbuf, iocp->ioc_flag));
5988 			TRACE_2(TR_FAC_UDP, TR_UDP_WPUT_OTHER_END,
5989 				"udp_wput_other_end: q %p (%S)",
5990 				q, "getmyname");
5991 			return;
5992 			}
5993 		case ND_SET:
5994 			/* nd_getset performs the necessary checking */
5995 		case ND_GET:
5996 			if (nd_getset(q, udp_g_nd, mp)) {
5997 				qreply(q, mp);
5998 				TRACE_2(TR_FAC_UDP, TR_UDP_WPUT_OTHER_END,
5999 					"udp_wput_other_end: q %p (%S)",
6000 					q, "get");
6001 				return;
6002 			}
6003 			break;
6004 		default:
6005 			break;
6006 		}
6007 		break;
6008 	case M_IOCDATA:
6009 		udp_wput_iocdata(q, mp);
6010 		TRACE_2(TR_FAC_UDP, TR_UDP_WPUT_OTHER_END,
6011 			"udp_wput_other_end: q %p (%S)", q, "iocdata");
6012 		return;
6013 	default:
6014 		/* Unrecognized messages are passed through without change. */
6015 		break;
6016 	}
6017 	TRACE_2(TR_FAC_UDP, TR_UDP_WPUT_OTHER_END,
6018 		"udp_wput_other_end: q %p (%S)", q, "end");
6019 	putnext(q, mp);
6020 }
6021 
6022 /*
6023  * udp_wput_iocdata is called by udp_wput_other to handle all M_IOCDATA
6024  * messages.
6025  */
6026 static void
6027 udp_wput_iocdata(queue_t *q, mblk_t *mp)
6028 {
6029 	mblk_t	*mp1;
6030 	STRUCT_HANDLE(strbuf, sb);
6031 	uint16_t port;
6032 	udp_t	*udp;
6033 	in6_addr_t	v6addr;
6034 	ipaddr_t	v4addr;
6035 	uint32_t	flowinfo = 0;
6036 	int		addrlen;
6037 
6038 	/* Make sure it is one of ours. */
6039 	switch (((struct iocblk *)mp->b_rptr)->ioc_cmd) {
6040 	case TI_GETMYNAME:
6041 	case TI_GETPEERNAME:
6042 		break;
6043 	default:
6044 		putnext(q, mp);
6045 		return;
6046 	}
6047 	switch (mi_copy_state(q, mp, &mp1)) {
6048 	case -1:
6049 		return;
6050 	case MI_COPY_CASE(MI_COPY_IN, 1):
6051 		break;
6052 	case MI_COPY_CASE(MI_COPY_OUT, 1):
6053 		/*
6054 		 * The address has been copied out, so now
6055 		 * copyout the strbuf.
6056 		 */
6057 		mi_copyout(q, mp);
6058 		return;
6059 	case MI_COPY_CASE(MI_COPY_OUT, 2):
6060 		/*
6061 		 * The address and strbuf have been copied out.
6062 		 * We're done, so just acknowledge the original
6063 		 * M_IOCTL.
6064 		 */
6065 		mi_copy_done(q, mp, 0);
6066 		return;
6067 	default:
6068 		/*
6069 		 * Something strange has happened, so acknowledge
6070 		 * the original M_IOCTL with an EPROTO error.
6071 		 */
6072 		mi_copy_done(q, mp, EPROTO);
6073 		return;
6074 	}
6075 
6076 	/*
6077 	 * Now we have the strbuf structure for TI_GETMYNAME
6078 	 * and TI_GETPEERNAME.  Next we copyout the requested
6079 	 * address and then we'll copyout the strbuf.
6080 	 */
6081 	STRUCT_SET_HANDLE(sb, ((struct iocblk *)mp->b_rptr)->ioc_flag,
6082 	    (void *)mp1->b_rptr);
6083 	udp = (udp_t *)q->q_ptr;
6084 	if (udp->udp_family == AF_INET)
6085 		addrlen = sizeof (sin_t);
6086 	else
6087 		addrlen = sizeof (sin6_t);
6088 
6089 	if (STRUCT_FGET(sb, maxlen) < addrlen) {
6090 		mi_copy_done(q, mp, EINVAL);
6091 		return;
6092 	}
6093 	switch (((struct iocblk *)mp->b_rptr)->ioc_cmd) {
6094 	case TI_GETMYNAME:
6095 		if (udp->udp_family == AF_INET) {
6096 			ASSERT(udp->udp_ipversion == IPV4_VERSION);
6097 			if (!IN6_IS_ADDR_V4MAPPED_ANY(&udp->udp_v6src) &&
6098 			    !IN6_IS_ADDR_UNSPECIFIED(&udp->udp_v6src)) {
6099 				v4addr = V4_PART_OF_V6(udp->udp_v6src);
6100 			} else {
6101 				/*
6102 				 * INADDR_ANY
6103 				 * udp_v6src is not set, we might be bound to
6104 				 * broadcast/multicast. Use udp_bound_v6src as
6105 				 * local address instead (that could
6106 				 * also still be INADDR_ANY)
6107 				 */
6108 				v4addr = V4_PART_OF_V6(udp->udp_bound_v6src);
6109 			}
6110 		} else {
6111 			/* udp->udp_family == AF_INET6 */
6112 			if (!IN6_IS_ADDR_UNSPECIFIED(&udp->udp_v6src)) {
6113 				v6addr = udp->udp_v6src;
6114 			} else {
6115 				/*
6116 				 * UNSPECIFIED
6117 				 * udp_v6src is not set, we might be bound to
6118 				 * broadcast/multicast. Use udp_bound_v6src as
6119 				 * local address instead (that could
6120 				 * also still be UNSPECIFIED)
6121 				 */
6122 				v6addr = udp->udp_bound_v6src;
6123 			}
6124 		}
6125 		port = udp->udp_port;
6126 		break;
6127 	case TI_GETPEERNAME:
6128 		if (udp->udp_family == AF_INET) {
6129 			ASSERT(udp->udp_ipversion == IPV4_VERSION);
6130 			v4addr = V4_PART_OF_V6(udp->udp_v6dst);
6131 		} else {
6132 			/* udp->udp_family == AF_INET6) */
6133 			v6addr = udp->udp_v6dst;
6134 			flowinfo = udp->udp_flowinfo;
6135 		}
6136 		port = udp->udp_dstport;
6137 		break;
6138 	default:
6139 		mi_copy_done(q, mp, EPROTO);
6140 		return;
6141 	}
6142 	mp1 = mi_copyout_alloc(q, mp, STRUCT_FGETP(sb, buf), addrlen, B_TRUE);
6143 	if (!mp1)
6144 		return;
6145 
6146 	if (udp->udp_family == AF_INET) {
6147 		sin_t *sin;
6148 
6149 		STRUCT_FSET(sb, len, (int)sizeof (sin_t));
6150 		sin = (sin_t *)mp1->b_rptr;
6151 		mp1->b_wptr = (uchar_t *)&sin[1];
6152 		*sin = sin_null;
6153 		sin->sin_family = AF_INET;
6154 		sin->sin_addr.s_addr = v4addr;
6155 		sin->sin_port = port;
6156 	} else {
6157 		/* udp->udp_family == AF_INET6 */
6158 		sin6_t *sin6;
6159 
6160 		STRUCT_FSET(sb, len, (int)sizeof (sin6_t));
6161 		sin6 = (sin6_t *)mp1->b_rptr;
6162 		mp1->b_wptr = (uchar_t *)&sin6[1];
6163 		*sin6 = sin6_null;
6164 		sin6->sin6_family = AF_INET6;
6165 		sin6->sin6_flowinfo = flowinfo;
6166 		sin6->sin6_addr = v6addr;
6167 		sin6->sin6_port = port;
6168 	}
6169 	/* Copy out the address */
6170 	mi_copyout(q, mp);
6171 }
6172 
6173 
6174 static int
6175 udp_unitdata_opt_process(queue_t *q, mblk_t *mp, int *errorp,
6176     void *thisdg_attrs)
6177 {
6178 	udp_t	*udp;
6179 	struct T_unitdata_req *udreqp;
6180 	int is_absreq_failure;
6181 	cred_t *cr;
6182 
6183 	ASSERT(((union T_primitives *)mp->b_rptr)->type);
6184 
6185 	udp = (udp_t *)q->q_ptr;
6186 
6187 	cr = DB_CREDDEF(mp, udp->udp_credp);
6188 
6189 	udreqp = (struct T_unitdata_req *)mp->b_rptr;
6190 	*errorp = 0;
6191 
6192 	*errorp = tpi_optcom_buf(q, mp, &udreqp->OPT_length,
6193 	    udreqp->OPT_offset, cr, &udp_opt_obj,
6194 	    thisdg_attrs, &is_absreq_failure);
6195 
6196 	if (*errorp != 0) {
6197 		/*
6198 		 * Note: No special action needed in this
6199 		 * module for "is_absreq_failure"
6200 		 */
6201 		return (-1);		/* failure */
6202 	}
6203 	ASSERT(is_absreq_failure == 0);
6204 	return (0);	/* success */
6205 }
6206 
6207 void
6208 udp_ddi_init(void)
6209 {
6210 	int i;
6211 
6212 	UDP6_MAJ = ddi_name_to_major(UDP6);
6213 	mutex_init(&udp_g_lock, NULL, MUTEX_DEFAULT, NULL);
6214 
6215 	udp_max_optsize = optcom_max_optsize(udp_opt_obj.odb_opt_des_arr,
6216 	    udp_opt_obj.odb_opt_arr_cnt);
6217 
6218 	if (udp_bind_fanout_size & (udp_bind_fanout_size - 1)) {
6219 		/* Not a power of two. Round up to nearest power of two */
6220 		for (i = 0; i < 31; i++) {
6221 			if (udp_bind_fanout_size < (1 << i))
6222 				break;
6223 		}
6224 		udp_bind_fanout_size = 1 << i;
6225 	}
6226 	udp_bind_fanout = kmem_zalloc(udp_bind_fanout_size *
6227 	    sizeof (udp_fanout_t), KM_SLEEP);
6228 	for (i = 0; i < udp_bind_fanout_size; i++) {
6229 		mutex_init(&udp_bind_fanout[i].uf_lock, NULL, MUTEX_DEFAULT,
6230 		    NULL);
6231 	}
6232 	(void) udp_param_register(udp_param_arr, A_CNT(udp_param_arr));
6233 	udp_kstat_init();
6234 }
6235 
6236 void
6237 udp_ddi_destroy(void)
6238 {
6239 	int i;
6240 
6241 	nd_free(&udp_g_nd);
6242 
6243 	mutex_destroy(&udp_g_lock);
6244 	for (i = 0; i < udp_bind_fanout_size; i++) {
6245 		mutex_destroy(&udp_bind_fanout[i].uf_lock);
6246 	}
6247 	kmem_free(udp_bind_fanout, udp_bind_fanout_size *
6248 	    sizeof (udp_fanout_t));
6249 	udp_kstat_fini();
6250 
6251 }
6252 
6253 static void
6254 udp_kstat_init(void)
6255 {
6256 	udp_named_kstat_t template = {
6257 		{ "inDatagrams",	KSTAT_DATA_UINT32, 0 },
6258 		{ "inErrors",		KSTAT_DATA_UINT32, 0 },
6259 		{ "outDatagrams",	KSTAT_DATA_UINT32, 0 },
6260 		{ "entrySize",		KSTAT_DATA_INT32, 0 },
6261 		{ "entry6Size",		KSTAT_DATA_INT32, 0 },
6262 		{ "outErrors",		KSTAT_DATA_UINT32, 0 },
6263 	};
6264 
6265 	udp_mibkp = kstat_create("udp", 0, "udp", "mib2", KSTAT_TYPE_NAMED,
6266 					NUM_OF_FIELDS(udp_named_kstat_t),
6267 					0);
6268 	if (udp_mibkp == NULL)
6269 		return;
6270 
6271 	template.entrySize.value.ui32 = sizeof (mib2_udpEntry_t);
6272 	template.entry6Size.value.ui32 = sizeof (mib2_udp6Entry_t);
6273 
6274 	bcopy(&template, udp_mibkp->ks_data, sizeof (template));
6275 
6276 	udp_mibkp->ks_update = udp_kstat_update;
6277 
6278 	kstat_install(udp_mibkp);
6279 }
6280 
6281 static void
6282 udp_kstat_fini(void)
6283 {
6284 	if (udp_mibkp) {
6285 		kstat_delete(udp_mibkp);
6286 		udp_mibkp = NULL;
6287 	}
6288 }
6289 
6290 static int
6291 udp_kstat_update(kstat_t *kp, int rw)
6292 {
6293 	udp_named_kstat_t *udpkp;
6294 
6295 	if ((kp == NULL) || (kp->ks_data == NULL))
6296 		return (EIO);
6297 
6298 	if (rw == KSTAT_WRITE)
6299 		return (EACCES);
6300 
6301 	udpkp = (udp_named_kstat_t *)kp->ks_data;
6302 
6303 	udpkp->inDatagrams.value.ui32 =	udp_mib.udpInDatagrams;
6304 	udpkp->inErrors.value.ui32 =	udp_mib.udpInErrors;
6305 	udpkp->outDatagrams.value.ui32 = udp_mib.udpOutDatagrams;
6306 	udpkp->outErrors.value.ui32 =	udp_mib.udpOutErrors;
6307 
6308 	return (0);
6309 }
6310 
6311 /*
6312  * Little helper for IPsec's NAT-T processing.
6313  */
6314 boolean_t
6315 udp_compute_checksum(void)
6316 {
6317 	return (udp_do_checksum);
6318 }
6319