summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/net/if.h
blob: 924fd390c7029838959e2492c2573b90be2beda0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
/*
 * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
 */

/*
 * Copyright (c) 1982, 1986 Regents of the University of California.
 * All rights reserved.  The Berkeley software License Agreement
 * specifies the terms and conditions for redistribution.
 */

#ifndef	_NET_IF_H
#define	_NET_IF_H

/* if.h 1.26 90/05/29 SMI; from UCB 7.1 6/4/86		*/

#include <sys/feature_tests.h>

#if !defined(_XOPEN_SOURCE) || defined(__EXTENSIONS__)
#include <sys/socket.h>
#include <netinet/in.h>
#if defined(_LP64)
#include <sys/types32.h>
#endif
#endif

#ifdef	__cplusplus
extern "C" {
#endif

/*
 * Structures defining a network interface, providing a packet
 * transport mechanism (ala level 0 of the PUP protocols).
 *
 * Each interface accepts output datagrams of a specified maximum
 * length, and provides higher level routines with input datagrams
 * received from its medium.
 *
 * Output occurs when the routine if_output is called, with three parameters:
 *	(*ifp->if_output)(ifp, m, dst)
 * Here m is the mbuf chain to be sent and dst is the destination address.
 * The output routine encapsulates the supplied datagram if necessary,
 * and then transmits it on its medium.
 *
 * On input, each interface unwraps the data received by it, and either
 * places it on the input queue of a internetwork datagram routine
 * and posts the associated software interrupt, or passes the datagram to a raw
 * packet input routine.
 *
 * Routines exist for locating interfaces by their addresses
 * or for locating a interface on a certain network, as well as more general
 * routing and gateway routines maintaining information used to locate
 * interfaces.  These routines live in the files if.c and route.c
 */

#if !defined(_XOPEN_SOURCE) || defined(__EXTENSIONS__)

/*
 * Structure defining a queue for a network interface.
 *
 * (Would like to call this struct ``if'', but C isn't PL/1.)
 */
struct ifnet {
	char	*if_name;		/* name, e.g. ``en'' or ``lo'' */
	short	if_unit;		/* sub-unit for lower level driver */
	short	if_mtu;			/* maximum transmission unit */
	short	if_flags;		/* up/down, broadcast, etc. */
	short	if_timer;		/* time 'til if_watchdog called */
	ushort_t if_promisc;		/* net # of requests for promisc mode */
	int	if_metric;		/* routing metric (external only) */
	struct	ifaddr *if_addrlist;	/* linked list of addresses per if */
	struct	ifqueue {
		struct	mbuf *ifq_head;
		struct	mbuf *ifq_tail;
		int	ifq_len;
		int	ifq_maxlen;
		int	ifq_drops;
	} if_snd;			/* output queue */
/* procedure handles */
	int	(*if_init)();		/* init routine */
	int	(*if_output)();		/* output routine */
	int	(*if_ioctl)();		/* ioctl routine */
	int	(*if_reset)();		/* bus reset routine */
	int	(*if_watchdog)();	/* timer routine */
/* generic interface statistics */
	int	if_ipackets;		/* packets received on interface */
	int	if_ierrors;		/* input errors on interface */
	int	if_opackets;		/* packets sent on interface */
	int	if_oerrors;		/* output errors on interface */
	int	if_collisions;		/* collisions on csma interfaces */
/* end statistics */
	struct	ifnet *if_next;
	struct	ifnet *if_upper;	/* next layer up */
	struct	ifnet *if_lower;	/* next layer down */
	int	(*if_input)();		/* input routine */
	int	(*if_ctlin)();		/* control input routine */
	int	(*if_ctlout)();		/* control output routine */
	struct map *if_memmap;		/* rmap for interface specific memory */
};

/*
 * NOTE : These flags are not directly used within IP.
 * ip_if.h has definitions derived from this which is used within IP.
 * If you define a flag here, you need to define one in ip_if.h before
 * using the new flag in IP. Don't use these flags directly in IP.
 */
#define	IFF_UP		0x0000000001	/* address is up */
#define	IFF_BROADCAST	0x0000000002	/* broadcast address valid */
#define	IFF_DEBUG	0x0000000004	/* turn on debugging */
#define	IFF_LOOPBACK	0x0000000008	/* is a loopback net */

#define	IFF_POINTOPOINT	0x0000000010	/* interface is point-to-point link */
#define	IFF_NOTRAILERS	0x0000000020	/* avoid use of trailers */
#define	IFF_RUNNING	0x0000000040	/* resources allocated */
#define	IFF_NOARP	0x0000000080	/* no address resolution protocol */

#define	IFF_PROMISC	0x0000000100	/* receive all packets */
#define	IFF_ALLMULTI	0x0000000200	/* receive all multicast packets */
#define	IFF_INTELLIGENT	0x0000000400	/* protocol code on board */
/*
 * The IFF_MULTICAST flag indicates that the network can support the
 * transmission and reception of higher-level (e.g., IP) multicast packets.
 * It is independent of hardware support for multicasting; for example,
 * point-to-point links or pure broadcast networks may well support
 * higher-level multicasts.
 */
#define	IFF_MULTICAST	0x0000000800	/* supports multicast */

#define	IFF_MULTI_BCAST	0x0000001000	/* multicast using broadcast address */
#define	IFF_UNNUMBERED	0x0000002000	/* non-unique address */
#define	IFF_DHCPRUNNING	0x0000004000	/* DHCP controls this interface */
#define	IFF_PRIVATE	0x0000008000	/* do not advertise */

/*
 * The following flags can't be grabbed or altered by SIOC[GS]IFFLAGS.
 * Should use SIOC[GS]LIFFLAGS which has a larger flags field.
 */
#define	IFF_NOXMIT	0x0000010000	/* Do not transmit packets */
#define	IFF_NOLOCAL	0x0000020000	/* No address - just on-link subnet */
#define	IFF_DEPRECATED	0x0000040000	/* Address is deprecated */
#define	IFF_ADDRCONF	0x0000080000	/* address from stateless addrconf */

#define	IFF_ROUTER	0x0000100000	/* router on this interface */
#define	IFF_NONUD	0x0000200000	/* No NUD on this interface */
#define	IFF_ANYCAST	0x0000400000	/* Anycast address */
#define	IFF_NORTEXCH	0x0000800000	/* Do not exchange routing info */

#define	IFF_IPV4	0x0001000000	/* IPv4 interface */
#define	IFF_IPV6	0x0002000000	/* IPv6 interface */
#define	IFF_NOACCEPT	0x0004000000	/* no-accept mode VRRP ill */
#define	IFF_NOFAILOVER	0x0008000000	/* in.mpathd(8) test address */

#define	IFF_FAILED	0x0010000000	/* Interface has failed */
#define	IFF_STANDBY	0x0020000000	/* Interface is a hot-spare */
#define	IFF_INACTIVE	0x0040000000	/* Functioning but not used for data */
#define	IFF_OFFLINE	0x0080000000	/* Interface is offline */

/*
 * The IFF_XRESOLV flag is an evolving interface and is subject
 * to change without notice.
 */
#define	IFF_XRESOLV	0x0100000000ll	/* IPv6 external resolver */
#define	IFF_COS_ENABLED	0x0200000000ll	/* If interface supports CoS marking */
#define	IFF_PREFERRED	0x0400000000ll	/* Prefer as source address */
#define	IFF_TEMPORARY	0x0800000000ll	/* RFC3041 */

#define	IFF_FIXEDMTU	0x1000000000ll	/* MTU manually set with SIOCSLIFMTU */
#define	IFF_VIRTUAL	0x2000000000ll	/* Does not send or receive packets */
#define	IFF_DUPLICATE	0x4000000000ll	/* Local address already in use */
#define	IFF_IPMP	0x8000000000ll	/* IPMP IP interface */
#define	IFF_VRRP	0x10000000000ll	/* Managed by VRRP */

#define	IFF_NOLINKLOCAL	0x20000000000ll	/* No default linklocal */
#define	IFF_L3PROTECT	0x40000000000ll	/* Layer-3 protection enforced */

/* flags that cannot be changed by userland on any interface */
#define	IFF_CANTCHANGE \
	(IFF_BROADCAST | IFF_POINTOPOINT | IFF_RUNNING | IFF_PROMISC | \
	IFF_MULTICAST | IFF_MULTI_BCAST | IFF_UNNUMBERED | IFF_IPV4 | \
	IFF_IPV6 | IFF_IPMP | IFF_FIXEDMTU | IFF_VIRTUAL | \
	IFF_LOOPBACK | IFF_ALLMULTI | IFF_DUPLICATE | IFF_COS_ENABLED | \
	IFF_VRRP | IFF_NOLINKLOCAL | IFF_L3PROTECT)

/* flags that cannot be changed by userland on an IPMP interface */
#define	IFF_IPMP_CANTCHANGE 	IFF_FAILED

/* flags that can never be set on an IPMP interface */
#define	IFF_IPMP_INVALID	(IFF_STANDBY | IFF_INACTIVE | IFF_OFFLINE | \
	IFF_NOFAILOVER | IFF_NOARP | IFF_NONUD | IFF_XRESOLV | IFF_NOACCEPT)

/*
 * Output queues (ifp->if_snd) and internetwork datagram level (pup level 1)
 * input routines have queues of messages stored on ifqueue structures
 * (defined above).  Entries are added to and deleted from these structures
 * by these macros, which should be called with ipl raised to splimp().
 */
#define	IF_QFULL(ifq)		((ifq)->ifq_len >= (ifq)->ifq_maxlen)
#define	IF_DROP(ifq)		((ifq)->ifq_drops++)
#define	IF_ENQUEUE(ifq, m) { \
	(m)->m_act = 0; \
	if ((ifq)->ifq_tail == 0) \
		(ifq)->ifq_head = m; \
	else \
		(ifq)->ifq_tail->m_act = m; \
	(ifq)->ifq_tail = m; \
	(ifq)->ifq_len++; \
}
#define	IF_PREPEND(ifq, m) { \
	(m)->m_act = (ifq)->ifq_head; \
	if ((ifq)->ifq_tail == 0) \
		(ifq)->ifq_tail = (m); \
	(ifq)->ifq_head = (m); \
	(ifq)->ifq_len++; \
}

/*
 * Packets destined for level-1 protocol input routines
 * have a pointer to the receiving interface prepended to the data.
 * IF_DEQUEUEIF extracts and returns this pointer when dequeuing the packet.
 * IF_ADJ should be used otherwise to adjust for its presence.
 */
#define	IF_ADJ(m) { \
	(m)->m_off += sizeof (struct ifnet *); \
	(m)->m_len -= sizeof (struct ifnet *); \
	if ((m)->m_len == 0) { \
		struct mbuf *n; \
		MFREE((m), n); \
		(m) = n; \
	} \
}
#define	IF_DEQUEUEIF(ifq, m, ifp) { \
	(m) = (ifq)->ifq_head; \
	if (m) { \
		if (((ifq)->ifq_head = (m)->m_act) == 0) \
			(ifq)->ifq_tail = 0; \
		(m)->m_act = 0; \
		(ifq)->ifq_len--; \
		(ifp) = *(mtod((m), struct ifnet **)); \
		IF_ADJ(m); \
	} \
}
#define	IF_DEQUEUE(ifq, m) { \
	(m) = (ifq)->ifq_head; \
	if (m) { \
		if (((ifq)->ifq_head = (m)->m_act) == 0) \
			(ifq)->ifq_tail = 0; \
		(m)->m_act = 0; \
		(ifq)->ifq_len--; \
	} \
}

#define	IFQ_MAXLEN	50
#define	IFNET_SLOWHZ	1		/* granularity is 1 second */

/*
 * The ifaddr structure contains information about one address
 * of an interface.  They are maintained by the different address families,
 * are allocated and attached when an address is set, and are linked
 * together so all addresses for an interface can be located.
 */
struct ifaddr {
	struct	sockaddr ifa_addr;	/* address of interface */
	union {
		struct	sockaddr ifu_broadaddr;
		struct	sockaddr ifu_dstaddr;
	} ifa_ifu;
#define	ifa_broadaddr	ifa_ifu.ifu_broadaddr	/* broadcast address */
#define	ifa_dstaddr	ifa_ifu.ifu_dstaddr	/* other end of p-to-p link */
	struct	ifnet *ifa_ifp;		/* back-pointer to interface */
	struct	ifaddr *ifa_next;	/* next address for interface */
};

/*
 * For SIOCLIF*ND ioctls.
 *
 * The lnr_state_* fields use the ND_* neighbor reachability states.
 * The 3 different fields are for use with SIOCLIFSETND to cover the cases
 * when
 *	A new entry is created
 *	The entry already exists and the link-layer address is the same
 *	The entry already exists and the link-layer address differs
 *
 * Use ND_UNCHANGED to not change any state.
 */
#define	ND_MAX_HDW_LEN	64
typedef struct lif_nd_req {
	struct sockaddr_storage	lnr_addr;
	uint8_t			lnr_state_create;	/* When creating */
	uint8_t			lnr_state_same_lla;	/* Update same addr */
	uint8_t			lnr_state_diff_lla;	/* Update w/ diff. */
	int			lnr_hdw_len;
	int			lnr_flags;		/* See below */
	/* padding because ia32 "long long"s are only 4-byte aligned. */
	int			lnr_pad0;
	char			lnr_hdw_addr[ND_MAX_HDW_LEN];
} lif_nd_req_t;

/*
 * Neighbor reachability states
 * Used with SIOCLIF*ND ioctls.
 */
#define	ND_UNCHANGED	0	/* For ioctls that don't modify state */
#define	ND_INCOMPLETE	1	/* addr resolution in progress */
#define	ND_REACHABLE	2	/* have recently been reachable */
#define	ND_STALE	3	/* may be unreachable, don't do anything */
#define	ND_DELAY	4	/* wait for upper layer hint */
#define	ND_PROBE	5	/* send probes */
#define	ND_UNREACHABLE	6	/* delete this route */
#define	ND_INITIAL	7	/* ipv4: arp resolution has not been sent yet */

#define	ND_STATE_VALID_MIN	0
#define	ND_STATE_VALID_MAX	7

/*
 * lnr_flags value of lif_nd_req.
 * Used with SIOCLIF*ND ioctls.
 */
#define	NDF_ISROUTER_ON		0x1
#define	NDF_ISROUTER_OFF	0x2
#define	NDF_ANYCAST_ON		0x4
#define	NDF_ANYCAST_OFF		0x8
#define	NDF_PROXY_ON		0x10
#define	NDF_PROXY_OFF		0x20
/*
 * the NDF_STATIC entry ensures that an NCE will not be deleted, and is
 * used by non-ON applications like IPv6 test suites.
 */
#define	NDF_STATIC		0x40

/* For SIOC[GS]LIFLNKINFO */
typedef struct lif_ifinfo_req {
	uint8_t		lir_maxhops;
	uint32_t	lir_reachtime;		/* Reachable time in msec */
	uint32_t	lir_reachretrans;	/* Retransmission timer msec */
	uint32_t	lir_maxmtu;
} lif_ifinfo_req_t;

#endif /* !defined(_XOPEN_SOURCE) || defined(__EXTENSIONS__) */

/*
 * Maximum lengths of interface name and IPMP group name; these are the same
 * for historical reasons.  Note that the actual maximum length of a name is
 * one byte less than these constants since the kernel always sets the final
 * byte of lifr_name and lifr_groupname to NUL.
 */
#define	_LIFNAMSIZ	32

#if !defined(_XOPEN_SOURCE) || defined(__EXTENSIONS__)

#define	LIFNAMSIZ	_LIFNAMSIZ
#define	LIFGRNAMSIZ	LIFNAMSIZ

/*
 * Interface request structure used for socket
 * ioctl's.  All interface ioctl's must have parameter
 * definitions which begin with ifr_name.  The
 * remainder may be interface specific.
 * Note: This data structure uses 64bit type uint64_t which is not
 *	 a valid type for strict ANSI/ISO C compilation for ILP32.
 *	 Applications with ioctls using this structure that insist on
 *	 building with strict ANSI/ISO C (-Xc) will need to be LP64.
 */
#if defined(_INT64_TYPE)
struct	lifreq {
	char	lifr_name[LIFNAMSIZ];		/* if name, e.g. "en0" */
	union {
		int	lifru_addrlen;		/* for subnet/token etc */
		uint_t	lifru_ppa;		/* SIOCSLIFNAME */
	} lifr_lifru1;
#define	lifr_addrlen	lifr_lifru1.lifru_addrlen
#define	lifr_ppa	lifr_lifru1.lifru_ppa	/* Driver's ppa */
	uint_t		lifr_type;		/* IFT_ETHER, ... */
	union {
		struct	sockaddr_storage lifru_addr;
		struct	sockaddr_storage lifru_dstaddr;
		struct	sockaddr_storage lifru_broadaddr;
		struct	sockaddr_storage lifru_token;	/* With lifr_addrlen */
		struct	sockaddr_storage lifru_subnet;	/* With lifr_addrlen */
		int	lifru_index;		/* interface index */
		uint64_t lifru_flags;		/* Flags for SIOC?LIFFLAGS */
		int	lifru_metric;
		uint_t	lifru_mtu;
		int	lif_muxid[2];		/* mux id's for arp and ip */
		struct lif_nd_req	lifru_nd_req; /* SIOCLIF*ND */
		struct lif_ifinfo_req	lifru_ifinfo_req;
		char	lifru_groupname[LIFGRNAMSIZ]; /* SIOC[GS]LIFGROUPNAME */
		char	lifru_binding[LIFNAMSIZ]; /* SIOCGLIFBINDING */
		zoneid_t lifru_zoneid;		/* SIOC[GS]LIFZONE */
		uint_t	lifru_dadstate;		/* SIOCGLIFDADSTATE */
	} lifr_lifru;

#define	lifr_addr	lifr_lifru.lifru_addr	/* address */
#define	lifr_dstaddr	lifr_lifru.lifru_dstaddr /* other end of p-to-p link */
#define	lifr_broadaddr	lifr_lifru.lifru_broadaddr /* broadcast address */
#define	lifr_token	lifr_lifru.lifru_token	/* address token */
#define	lifr_subnet	lifr_lifru.lifru_subnet	/* subnet prefix */
#define	lifr_index	lifr_lifru.lifru_index	/* interface index */
#define	lifr_flags	lifr_lifru.lifru_flags	/* flags */
#define	lifr_metric	lifr_lifru.lifru_metric	/* metric */
#define	lifr_mtu	lifr_lifru.lifru_mtu	/* mtu */
#define	lifr_ip_muxid	lifr_lifru.lif_muxid[0]
#define	lifr_arp_muxid	lifr_lifru.lif_muxid[1]
#define	lifr_nd		lifr_lifru.lifru_nd_req	/* SIOCLIF*ND */
#define	lifr_ifinfo	lifr_lifru.lifru_ifinfo_req /* SIOC[GS]LIFLNKINFO */
#define	lifr_groupname	lifr_lifru.lifru_groupname
#define	lifr_binding	lifr_lifru.lifru_binding
#define	lifr_zoneid	lifr_lifru.lifru_zoneid
#define	lifr_dadstate	lifr_lifru.lifru_dadstate
};
#endif /* defined(_INT64_TYPE) */

/*
 * Argument structure for SIOCT* address testing ioctls.
 */
struct sioc_addrreq {
	struct sockaddr_storage	sa_addr;	/* Address to test */
	int			sa_res;		/* Result - 0/1 */
	int			sa_pad;
};

/*
 * Argument structure used by mrouted to get src-grp pkt counts using
 * SIOCGETLSGCNT. See <netinet/ip_mroute.h>.
 */
struct sioc_lsg_req {
	struct sockaddr_storage	slr_src;
	struct sockaddr_storage	slr_grp;
	uint_t			slr_pktcnt;
	uint_t			slr_bytecnt;
	uint_t			slr_wrong_if;
	uint_t			slr_pad;
};

/* Argument structure for SIOCGLIFDADSTATE ioctl */
typedef enum {
	DAD_IN_PROGRESS	= 0x1,
	DAD_DONE	= 0x2
} glif_dad_state_t;

/*
 * OBSOLETE: Replaced by struct lifreq. Supported for compatibility.
 *
 * Interface request structure used for socket
 * ioctl's.  All interface ioctl's must have parameter
 * definitions which begin with ifr_name.  The
 * remainder may be interface specific.
 */
struct	ifreq {
#define	IFNAMSIZ	16
	char	ifr_name[IFNAMSIZ];		/* if name, e.g. "en0" */
	union {
		struct	sockaddr ifru_addr;
		struct	sockaddr ifru_dstaddr;
		char	ifru_oname[IFNAMSIZ];	/* other if name */
		struct	sockaddr ifru_broadaddr;
		int	ifru_index;		/* interface index */
		uint_t	ifru_mtu;
		short	ifru_flags;
		int	ifru_metric;
		char	ifru_data[1];		/* interface dependent data */
		char	ifru_enaddr[6];
		int	if_muxid[2];		/* mux id's for arp and ip */

		/* Struct for flags/ppa */
		struct ifr_ppaflags {
			short ifrup_flags;	/* Space of ifru_flags. */
			short ifrup_filler;
			uint_t ifrup_ppa;
		} ifru_ppaflags;

		/* Struct for FDDI ioctl's */
		struct ifr_dnld_reqs {
			uint32_t	v_addr;
			uint32_t	m_addr;
			uint32_t	ex_addr;
			uint32_t	size;
		} ifru_dnld_req;

		/* Struct for FDDI stats */
		struct ifr_fddi_stats {
			uint32_t stat_size;
			uint32_t fddi_stats;
		} ifru_fddi_stat;

		struct ifr_netmapents {
			uint32_t map_ent_size,	/* size of netmap structure */
				entry_number;	/* index into netmap list */
			uint32_t fddi_map_ent;	/* pointer to user structure */
		} ifru_netmapent;

		/* Field for generic ioctl for fddi */

		struct ifr_fddi_gen_struct {
			uint32_t ifru_fddi_gioctl; /* field for gen ioctl */
			uint32_t ifru_fddi_gaddr;  /* Generic ptr to a field */
		} ifru_fddi_gstruct;

	} ifr_ifru;

#define	ifr_addr	ifr_ifru.ifru_addr	/* address */
#define	ifr_dstaddr	ifr_ifru.ifru_dstaddr	/* other end of p-to-p link */
#define	ifr_oname	ifr_ifru.ifru_oname	/* other if name */
#define	ifr_broadaddr	ifr_ifru.ifru_broadaddr	/* broadcast address */
#define	ifr_flags	ifr_ifru.ifru_flags	/* flags */
#define	ifr_metric	ifr_ifru.ifru_metric	/* metric */
#define	ifr_data	ifr_ifru.ifru_data	/* for use by interface */
#define	ifr_enaddr	ifr_ifru.ifru_enaddr	/* ethernet address */
#define	ifr_index	ifr_ifru.ifru_index	/* interface index */
#define	ifr_mtu		ifr_ifru.ifru_mtu	/* mtu */
/* For setting ppa */
#define	ifr_ppa		ifr_ifru.ifru_ppaflags.ifrup_ppa

/* FDDI specific */
#define	ifr_dnld_req	ifr_ifru.ifru_dnld_req
#define	ifr_fddi_stat	ifr_ifru.ifru_fddi_stat
#define	ifr_fddi_netmap	ifr_ifru.ifru_netmapent	/* FDDI network map entries */
#define	ifr_fddi_gstruct ifr_ifru.ifru_fddi_gstruct

#define	ifr_ip_muxid	ifr_ifru.if_muxid[0]
#define	ifr_arp_muxid	ifr_ifru.if_muxid[1]
};

/* Used by SIOCGLIFNUM. Uses same flags as in struct lifconf */
struct lifnum {
	sa_family_t	lifn_family;
	int		lifn_flags;	/* request specific interfaces */
	int		lifn_count;	/* Result */
};

/*
 * Structure used in SIOCGLIFCONF request.
 * Used to retrieve interface configuration
 * for machine (useful for programs which
 * must know all networks accessible) for a given address family.
 * Using AF_UNSPEC will retrieve all address families.
 */
struct	lifconf {
	sa_family_t	lifc_family;
	int		lifc_flags;	/* request specific interfaces */
	int		lifc_len;	/* size of associated buffer */
	union {
		caddr_t	lifcu_buf;
		struct	lifreq *lifcu_req;
	} lifc_lifcu;
#define	lifc_buf lifc_lifcu.lifcu_buf	/* buffer address */
#define	lifc_req lifc_lifcu.lifcu_req	/* array of structures returned */
};

/*
 * Structure used in SIOCGLIFSRCOF to get the interface
 * configuration list for those interfaces that use an address
 * hosted on the interface (set in lifs_ifindex), as the source
 * address.
 */
struct lifsrcof {
	uint_t	lifs_ifindex;	/* interface of interest */
	size_t  lifs_maxlen;	/* size of buffer: input */
	size_t  lifs_len;	/* size of buffer: output */
	union {
		caddr_t	lifsu_buf;
		struct	lifreq *lifsu_req;
	} lifs_lifsu;
#define	lifs_buf lifs_lifsu.lifsu_buf /* buffer address */
#define	lifs_req lifs_lifsu.lifsu_req /* array returned */
};

/* Flags */
#define	LIFC_NOXMIT	0x01		/* Include IFF_NOXMIT interfaces */
#define	LIFC_EXTERNAL_SOURCE	0x02	/* Exclude the interfaces which can't */
					/* be used to communicate outside the */
					/* node (exclude interfaces which are */
					/* IFF_NOXMIT, IFF_NOLOCAL, */
					/* IFF_LOOPBACK, IFF_DEPRECATED, or */
					/* not IFF_UP). Has priority over */
					/* LIFC_NOXMIT. */
#define	LIFC_TEMPORARY	0x04		/* Include IFF_TEMPORARY interfaces */
#define	LIFC_ALLZONES	0x08		/* Include all zones */
					/* (must be issued from global zone) */
#define	LIFC_UNDER_IPMP	0x10		/* Include underlying IPMP interfaces */
#define	LIFC_ENABLED	0x20		/* Include only IFF_UP interfaces */

#if defined(_SYSCALL32)

struct	lifconf32 {
	sa_family_t	lifc_family;
	int		lifc_flags;	/* request specific interfaces */
	int32_t	lifc_len;		/* size of associated buffer */
	union {
		caddr32_t lifcu_buf;
		caddr32_t lifcu_req;
	} lifc_lifcu;
};

struct lifsrcof32 {
	uint_t	lifs_ifindex;	/* interface of interest */
	size32_t  lifs_maxlen;	/* size of buffer: input */
	size32_t  lifs_len;	/* size of buffer: output */
	union {
		caddr32_t lifsu_buf;
		caddr32_t lifsu_req;
	} lifs_lifsu;
};

#endif	/* _SYSCALL32 */

/*
 * IPMP group information, for use with SIOCGLIFGROUPINFO.
 */
typedef struct lifgroupinfo {
	char		gi_grname[LIFGRNAMSIZ];	/* group name (set by caller) */
	char		gi_grifname[LIFNAMSIZ];	/* IPMP meta-interface name */
	char		gi_m4ifname[LIFNAMSIZ];	/* v4 mcast interface name */
	char		gi_m6ifname[LIFNAMSIZ];	/* v6 mcast interface name */
	char		gi_bcifname[LIFNAMSIZ];	/* v4 bcast interface name */
	boolean_t	gi_v4;			/* group is plumbed for v4 */
	boolean_t	gi_v6; 			/* group is plumbed for v6 */
	uint_t		gi_nv4;			/* # of underlying v4 if's */
	uint_t		gi_nv6;			/* # of underlying v6 if's */
	uint_t		gi_mactype; 		/* DLPI mac type of group */
} lifgroupinfo_t;

/*
 * OBSOLETE: Structure used in SIOCGIFCONF request.
 * Used to retrieve interface configuration
 * for machine (useful for programs which
 * must know all networks accessible).
 */
struct	ifconf {
	int	ifc_len;		/* size of associated buffer */
	union {
		caddr_t	ifcu_buf;
		struct	ifreq *ifcu_req;
	} ifc_ifcu;
#define	ifc_buf	ifc_ifcu.ifcu_buf	/* buffer address */
#define	ifc_req	ifc_ifcu.ifcu_req	/* array of structures returned */
};

#if defined(_SYSCALL32)

struct	ifconf32 {
	int32_t	ifc_len;		/* size of associated buffer */
	union {
		caddr32_t ifcu_buf;
		caddr32_t ifcu_req;
	} ifc_ifcu;
};

#endif	/* _SYSCALL32 */

typedef struct if_data {
				/* generic interface information */
	uchar_t	ifi_type;	/* ethernet, tokenring, etc */
	uchar_t	ifi_addrlen;	/* media address length */
	uchar_t	ifi_hdrlen;	/* media header length */
	uint_t	ifi_mtu;	/* maximum transmission unit */
	uint_t	ifi_metric;	/* routing metric (external only) */
	uint_t	ifi_baudrate;	/* linespeed */
				/* volatile statistics */
	uint_t	ifi_ipackets;	/* packets received on interface */
	uint_t	ifi_ierrors;	/* input errors on interface */
	uint_t	ifi_opackets;	/* packets sent on interface */
	uint_t	ifi_oerrors;	/* output errors on interface */
	uint_t	ifi_collisions;	/* collisions on csma interfaces */
	uint_t	ifi_ibytes;	/* total number of octets received */
	uint_t	ifi_obytes;	/* total number of octets sent */
	uint_t	ifi_imcasts;	/* packets received via multicast */
	uint_t	ifi_omcasts;	/* packets sent via multicast */
	uint_t	ifi_iqdrops;	/* dropped on input, this interface */
	uint_t	ifi_noproto;	/* destined for unsupported protocol */
#if defined(_LP64)
	struct	timeval32 ifi_lastchange; /* last updated */
#else
	struct	timeval ifi_lastchange; /* last updated */
#endif
} if_data_t;

/*
 * Message format for use in obtaining information about interfaces
 * from the routing socket
 */
typedef struct if_msghdr {
	ushort_t ifm_msglen;	/* to skip over non-understood messages */
	uchar_t	ifm_version;	/* future binary compatibility */
	uchar_t	ifm_type;	/* message type */
	int	ifm_addrs;	/* like rtm_addrs */
	int	ifm_flags;	/* value of if_flags */
	ushort_t ifm_index;	/* index for associated ifp */
	struct	if_data ifm_data; /* statistics and other data about if */
} if_msghdr_t;

/*
 * Message format for use in obtaining information about interface addresses
 * from the routing socket
 */
typedef struct ifa_msghdr {
	ushort_t ifam_msglen;	/* to skip over non-understood messages */
	uchar_t	ifam_version;	/* future binary compatibility */
	uchar_t	ifam_type;	/* message type */
	int	ifam_addrs;	/* like rtm_addrs */
	int	ifam_flags;	/* route flags */
	ushort_t ifam_index;	/* index for associated ifp */
	int	ifam_metric;	/* value of ipif_metric */
} ifa_msghdr_t;

#endif /* !defined(_XOPEN_SOURCE) || defined(__EXTENSIONS__) */

/*
 * The if_nameindex structure holds the interface index value about
 * a single interface. An array of this structure is used to return
 * all interfaces and indexes.
 */
struct if_nameindex {
	unsigned 	if_index;	/* positive interface index */
	char		*if_name;	/* if name, e.g. "en0" */
};

/* Interface index identification API definitions */
extern	unsigned 		if_nametoindex(const char *);
extern	char			*if_indextoname(unsigned, char *);
extern	struct if_nameindex	*if_nameindex(void);
extern	void			if_freenameindex(struct if_nameindex *);

#define	IF_NAMESIZE	_LIFNAMSIZ
/*
 * If changing IF_MAX_INDEX to a value greater than UINT16_MAX, check if
 * struct sockaddr_dl needs to be modified as the interface index is placed
 * in this structure by the kernel.
 */
#define	IF_INDEX_MAX	UINT16_MAX

#ifdef	__cplusplus
}
#endif

#endif	/* _NET_IF_H */